diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 23:45:22 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 23:45:22 +0000 |
commit | 5b35aa5cd29bb111d847b2a2ed18110acbfb1f44 (patch) | |
tree | c7bbaa1137528330d3c74d14056ef7016a52be72 | |
parent | 511bcd7c5924ce9e98ad1cb851988f7448dfef0f (diff) |
Merge with Linux 2.3.24.
220 files changed, 10832 insertions, 9145 deletions
diff --git a/Documentation/Configure.help b/Documentation/Configure.help index c4e59215d..1bb6e8607 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -2294,7 +2294,7 @@ CONFIG_FB_S3TRIO If you have a S3 Trio say Y. Say N for S3 Virge. ATI Mach64 display support -CONFIG_FB_ATY +CONFIG_FB_ATY (EXPERIMENTAL) This driver supports graphics boards with the ATI Mach64 chips. Say Y if you have such a graphics board. @@ -2362,7 +2362,7 @@ CONFIG_FB_COMPAT_XPMAC includes a server that supports the frame buffer device directly (XF68_FBDev). -Matrox unified accelerated driver +Matrox unified accelerated driver (EXPERIMENTAL) CONFIG_FB_MATROX Say Y here if you have Matrox Millennium, Matrox Millennium II, Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox @@ -3201,7 +3201,7 @@ CONFIG_SPX The module will be called af_spx.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -DECnet networking +DECnet networking (EXPERIMENTAL) CONFIG_DECNET The DECnet networking protocol was used in many products made by Digital (now Compaq). It provides reliable stream and sequenced @@ -3232,7 +3232,7 @@ CONFIG_DECNET_SIOCGIFCONF If unsure, say N. -DECnet Router Support +DECnet Router Support (EXPERIMENTAL) CONFIG_DECNET_ROUTER Add support for turning your DECnet Endnode into a level 1 or 2 router. This is an unfinished option for developers only. If you do @@ -3707,7 +3707,7 @@ CONFIG_SOUNDMODEM_FSK9600 can only use one protocol at a time, depending on what the other end can understand). -CCITT X.25 Packet Layer +CCITT X.25 Packet Layer (EXPERIMENTAL) CONFIG_X25 X.25 is a set of standardized network protocols, similar in scope to frame relay; the one physical line from your box to the X.25 network @@ -3757,7 +3757,7 @@ CONFIG_LAPB want), say M here and read Documentation/modules.txt. The module will be called lapb.o. If unsure, say N. -802.2 LLC (VERY EXPERIMENTAL) +802.2 LLC (EXPERIMENTAL) CONFIG_LLC This is a Logical Link Layer protocol used for X.25 connections over Ethernet, using ordinary Ethernet cards. @@ -4697,7 +4697,7 @@ CONFIG_SCSI_NCR53C8XX_MAX_TAGS There is no safe option and the default answer is recommended. -assume boards are SYMBIOS compatible +assume boards are SYMBIOS compatible (EXPERIMENTAL) CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT This option allows you to enable some features depending on GPIO wiring. These General Purpose Input/Output pins can be used for @@ -5226,7 +5226,7 @@ CONFIG_SCSI_IZIP_SLOW_CTR Generally, saying N is fine. -SCSI Debug host simulator. +SCSI Debug host simulator. (EXPERIMENTAL) CONFIG_SCSI_DEBUG This is a host adapter simulator that can be programmed to simulate a large number of conditions that could occur on a real bus. The @@ -5288,7 +5288,7 @@ CONFIG_SCSI_CUMANA_1 This enables support for the Cumana SCSI I card. If you have an Acorn system with one of these, say Y. If unsure, say N. -Cumana SCSI II support +Cumana SCSI II support (EXPERIMENTAL) CONFIG_SCSI_CUMANA_2 This enables support for the Cumana SCSI II card. If you have an Acorn system with one of these, say Y. If unsure, say N. @@ -5299,12 +5299,12 @@ CONFIG_SCSI_ECOSCSI in the Econet socket. If you have an Acorn system with one of these, say Y. If unsure, say N. -EESOX SCSI support +EESOX SCSI support (EXPERIMENTAL) CONFIG_SCSI_EESOXSCSI This enables support for the EESOX SCSI card. If you have an Acorn system with one of these, say Y, otherwise say N. -Powertec SCSI support +Powertec SCSI support (EXPERIMENTAL) CONFIG_SCSI_POWERTECSCSI This enables support for the Powertec SCSI card on Acorn systems. If you have one of these, say Y. If unsure, say N. @@ -5462,6 +5462,15 @@ CONFIG_PPP_ASYNC into and removed from the running kernel). If you want to compile it as a module, say M here and read Documentation/modules.txt. +CONFIG_PPP_SYNC_TTY + Say Y (or M) here if you want to be able to use PPP over synchronous + (HDLC) tty devices, such as the SyncLink adapter. These devices + are often used for high-speed leased lines like T1/E1. + + This code is also available as a module (code which can be inserted + into and removed from the running kernel). If you want to compile + it as a module, say M here and read Documentation/modules.txt. + PPP Deflate compression CONFIG_PPP_DEFLATE Support for the Deflate compression method for PPP, which uses the @@ -5764,7 +5773,7 @@ CONFIG_EQUALIZER module, say M here and read Documentation/modules.txt. If unsure, say N. -Ethertap network tap +Ethertap network tap (EXPERIMENTAL) CONFIG_ETHERTAP If you say Y here (and have said Y to "Kernel/User network link driver", above) and create a character special file /dev/tap0 with @@ -6279,7 +6288,7 @@ CONFIG_WANPIPE_PPP you say N, the PPP support will not be included in the driver (saves about 16 KB of kernel memory). -Cyclom 2X(tm) multiprotocol cards +Cyclom 2X(tm) multiprotocol cards (EXPERIMENTAL) CONFIG_CYCLADES_SYNC Cyclom 2X from Cyclades Corporation (http://www.cyclades.com and http://www.cyclades.com.br ) is an intelligent multiprotocol WAN @@ -6472,7 +6481,7 @@ CONFIG_NET_VENDOR_RACAL the questions about NI cards. If you say Y, you will be asked for your specific card in the following questions. -NI5010 support +NI5010 support (EXPERIMENTAL) CONFIG_NI5010 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -7077,7 +7086,7 @@ CONFIG_AC3200 module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -Mylex EISA LNE390A/LNE390B support +Mylex EISA LNE390A/LNE390B support (EXPERIMENTAL) CONFIG_LNE390 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -7089,7 +7098,7 @@ CONFIG_LNE390 module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -Novell/Eagle/Microdyne NE3210 EISA support +Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL) CONFIG_NE3210 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -7174,7 +7183,7 @@ CONFIG_EEXPRESS_PRO100 module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -ICL EtherTeam 16i/32 support +ICL EtherTeam 16i/32 support (EXPERIMENTAL) CONFIG_ETH16I If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -7216,7 +7225,7 @@ CONFIG_VIA_RHINE a module, say M here and read Documentation/modules.txt as well as Documentation/networking/net-modules.txt. -Racal-Interlan EISA ES3210 support +Racal-Interlan EISA ES3210 support (EXPERIMENTAL) CONFIG_ES3210 If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from @@ -7245,7 +7254,7 @@ CONFIG_SGISEEQ Say Y here if you have an Seeq based Ethernet network card. This is used in many Silicon Graphics machines. -Zenith Z-Note support +Zenith Z-Note support (EXPERIMENTAL) CONFIG_ZNET The Zenith Z-Note notebook computer has a built-in network (Ethernet) card, and this is the Linux driver for it. Note that the @@ -7744,7 +7753,7 @@ CONFIG_QUOTA http://metalab.unc.edu/mdw/linux.html#howto . Probably the quota support is only useful for multi user systems. If unsure, say N. -Support for USB (EXPERIMENTAL!) +Support for USB (EXPERIMENTAL) CONFIG_USB Universal Serial Bus (USB) is a specification for a serial bus system which offers higher speeds and more features than the @@ -7896,6 +7905,16 @@ CONFIG_USB_ACM The module will be called acm.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. +USB Belkin and Peracom serial support +CONFIG_USB_SERIAL + Say Y here if you want to connect a Belkin, Peracom, or eTek + single port USB to serial converter. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called usb-serial.o. If you want to compile it + as a module, say M here and read Documentation/modules.txt. + USB Printer support CONFIG_USB_PRINTER Say Y here if you want to connect a printer to your computer's USB @@ -8297,7 +8316,7 @@ CONFIG_NFSD_SUN directories that are mount points on the local filesystem (this is how nfsd behaves on Sun systems), say Y here. If unsure, say N. -OS/2 HPFS filesystem support (read only) +OS/2 HPFS filesystem support CONFIG_HPFS_FS OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS is the filesystem used for organizing files on OS/2 hard disk @@ -8324,7 +8343,7 @@ CONFIG_NTFS_FS The module will be called ntfs.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -NTFS read-write support (EXPERIMENTAL) +NTFS write support (DANGEROUS) CONFIG_NTFS_RW If you say Y here, you will (hopefully) be able to write to NTFS file systems as well as read from them. The read-write support @@ -8359,7 +8378,7 @@ CONFIG_SYSV_FS tar" or preferably "info tar"). Note also that this option has nothing whatsoever to do with the option "System V IPC". Read about the System V filesystem in Documentation/filesystems/sysv-fs.txt. - Saying Y here will enlarge your kernel by about 34 KB. + Saying Y here will enlarge your kernel by about 27 kB. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -8416,7 +8435,7 @@ CONFIG_ROMFS_FS If you don't know whether you need it, then you don't need it: answer N. -QNX filesystem support (EXPERIMENTAL) +QNX filesystem support (read only) (EXPERIMENTAL) CONFIG_QNX4FS_FS This is the filesystem used by the operating system QNX 4. Say Y if you intend to mount QNX hard disks or floppies. Unless you say Y to @@ -8430,7 +8449,7 @@ CONFIG_QNX4FS_FS If unsure, say N. -QNXFS read-write support (FOR TESTING ONLY) +QNXFS write support (DANGEROUS) CONFIG_QNX4FS_RW Say Y if you want to test write support for QNX filesystems. @@ -9383,7 +9402,7 @@ CONFIG_ESPSERIAL and read Documentation/modules.txt. The module will be called esp.o. If unsure, say N. -Multi-Tech multiport card support +Multi-Tech multiport card support (EXPERIMENTAL) CONFIG_ISI This is a driver for the Multi-Tech cards which provide several serial ports. The driver is experimental and can currently only be @@ -9553,9 +9572,9 @@ CONFIG_82C710_MOUSE PC110 digitizer pad support CONFIG_PC110_PAD - This drives the digitizer pad on the IBM PC110 palmtop (see - http://toy.cabi.net ). It can turn the digitizer pad into a PS/2 - mouse emulation with tap gestures or into an absolute pad. + This drives the digitizer pad on the IBM PC110 palmtop. It can turn + the digitizer pad into a PS/2 mouse emulation with tap gestures or + into an absolute pad. If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), @@ -10471,7 +10490,7 @@ CONFIG_SOUND I'm told that even without a sound card, you can make your computer say more than an occasional beep, by programming the PC speaker. Kernel patches and supporting utilities to do that are in the pcsp - package, available at http://www.imladris.demon.co.uk/pcsp/ . + package, available at ftp://ftp.infradead.org/pub/pcsp/. OSS sound modules CONFIG_SOUND_OSS @@ -11006,6 +11025,23 @@ CONFIG_SOUND_WAVEARTIST Say Y here to include support for the Rockwell WaveArtist sound system. This driver is mainly for the NetWinder. +VIA 82Cxxx Audio Codec +CONFIG_SOUND_VIA82CXXX + Say Y here to include support for the audio codec found on + VIA 82Cxxx-based chips. Typically these are built into a motherboard. + DO NOT select SoundBlaster or Adlib with this driver, unless you have + a SoundBlaster or Adlib card in addition to your VIA audio chip. + +NeoMagic 256AV/256ZX sound chipsets +CONFIG_SOUND_NM256 + Say M here to include audio support for the NeoMagic 256AV/256ZX + chipsets. These are the audio chipsets found in the Sony Z505S/SX/DX, + some Sony F-series, and the Dell Latitude CPi and CPt laptops. It includes + support for an AC97-compatible mixer and an apparently proprietary sound + engine. + + See Documentation/sound/NM256 for further information. + Are you using a crosscompiler CONFIG_CROSSCOMPILE Say Y here if you are compiling the kernel on a different @@ -11419,7 +11455,7 @@ CONFIG_SCSI_SUNESP This is the driver for the Sun ESP SCSI host adapter. The ESP chipset is present in most SPARC-based computers. -SPARC /dev/openprom compatibility driver +SPARC /dev/openprom compatibility driver (EXPERIMENTAL) CONFIG_SUN_OPENPROMIO This driver provides user programs with an interface to the SPARC PROM device tree. The driver implements a SunOS-compatible @@ -11517,7 +11553,7 @@ CONFIG_M68060 If you anticipate running this kernel on a computer with a MC68060 processor, say Y. Otherwise, say N. -Math emulation support +Math emulation support (EXPERIMENTAL) CONFIG_M68KFPU_EMU At some point in the future, this will cause floating-point math instructions to be emulated by the kernel on machines that lack a @@ -11576,7 +11612,7 @@ CONFIG_ZORRO Note that even if you say N here, you can still use your expansion cards. If in doubt, say Y. -Amiga 1200/600 PCMCIA support +Amiga 1200/600 PCMCIA support (EXPERIMENTAL) CONFIG_AMIGA_PCMCIA Include support in the kernel for pcmcia on Amiga 1200 and Amiga 600. If you intend to use pcmcia cards say Y; otherwise say N. @@ -11708,7 +11744,7 @@ CONFIG_BLZ1230_SCSI 1260 accelerator, and the optional SCSI module, say Y. Otherwise, say N. -Blizzard PowerUP 603e+ SCSI support +Blizzard PowerUP 603e+ SCSI support (EXPERIMENTAL) CONFIG_BLZ603EPLUS_SCSI If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+ accelerator, say Y. Otherwise, say N. @@ -11892,7 +11928,7 @@ CONFIG_ATARI_MIDI want). If you want to compile it as a module, say M here and read Documentation/modules.txt. -Atari DSP56k Digital Signal Processor support +Atari DSP56k Digital Signal Processor support (EXPERIMENTAL) CONFIG_ATARI_DSP56K If you want to be able to use the DSP56001 in Falcons, say Y. This driver is still experimental, and if you don't know what it is, or @@ -12508,7 +12544,7 @@ CONFIG_TEXT_SECTIONS enabled. Say Y unless you experience problems that you suspect may be caused by this. -Disable pgtable cache +Disable pgtable cache (EXPERIMENTAL) CONFIG_NO_PGT_CACHE Normally the kernel maintains a `quicklist' of preallocated pagetable structures in order to increase performance. On machines @@ -12531,7 +12567,7 @@ CONFIG_CMDLINE time by entering them here. As a minimum, you should specify the memory size and the root device (e.g., mem=64M root=/dev/nfs) -Hardware alignment trap +Hardware alignment trap (EXPERIMENTAL) CONFIG_ALIGNMENT_TRAP ARM processors can not fetch/store information which is not naturally aligned on the bus, i.e., a 4 byte fetch must start at an @@ -12637,7 +12673,7 @@ CONFIG_IRDA_COMPRESSION If you say Y here, you also need to say Y or M to a compression protocol below. -IrLAP Deflate Compression Protocol +IrLAP Deflate Compression Protocol (EXPERIMENTAL) CONFIG_IRDA_DEFLATE Say Y here if you want to build support for the Deflate compression protocol. The deflate compression (GZIP) is exactly @@ -12841,6 +12877,13 @@ CONFIG_BVME6000_SCSI SCSI controller chip. Almost everyone using one of these boards will want to say Y to this question. +Simple 53c710 SCSI support (Compaq, NCR machines) +CONFIG_SCSI_SIM710 + This is a driver for the NCR53C710 chip commonly found in Compaq and + NCR machines. If you are looking for 53C710 support for an Amiga or + some 680x0 based VME card then you probably want the other NCR53C710 + driver. + MVME16x Ethernet support CONFIG_MVME16x_NET This is the driver for the Ethernet interface on the Motorola diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index aa075a45c..311f713dd 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt @@ -1,5 +1,5 @@ Ioctl Numbers -10 October 1999 +19 October 1999 Michael Elizabeth Chastain <mec@shout.net> @@ -162,6 +162,8 @@ Code Seq# Include File Comments <mailto:buk@buks.ipn.de> 0xA0 all linux/sdp/sdp.h Industrial Device Project <mailto:kenji@bitgate.com> +0xA2 00-0F DVD decoder driver in development: + <http://linuxtv.org/dvd/api/> 0xA3 00-1F Philips SAA7146 dirver in development: <mailto:Andreas.Beckmann@hamburg.sc.philips.com> 0xA3 80-8F Port ACL in development: @@ -173,3 +175,5 @@ Code Seq# Include File Comments <mailto:rusty@rustcorp.com.au> 0xB0 all RATIO devices in development: <mailto:vgo@ratio.de> +0xCB 00-1F CBM serial IEC bus in development: + <mailto:michael.klein@puffin.lb.shuttle.de> diff --git a/Documentation/kbuild/config-language.txt b/Documentation/kbuild/config-language.txt index dce6086f9..50b788730 100644 --- a/Documentation/kbuild/config-language.txt +++ b/Documentation/kbuild/config-language.txt @@ -1,5 +1,5 @@ Config Language Specification -28 September 1999 +18 October 1999 Michael Elizabeth Chastain, <mailto:mec@shout.net> @@ -568,15 +568,31 @@ substitute a newline for the semicolon if you choose. /expr/ may contain the following atoms and operators. Note that, unlike shell, you must use double quotes around every atom. - "..." a literal - "$..." a variable + /atom/: + "..." a literal + "$..." a variable - /atom/ = /atom/ true if atoms have identical value - /atom/ != /atom/ true if atoms have different value + /expr/: + /atom/ = /atom/ true if atoms have identical value + /atom/ != /atom/ true if atoms have different value - /expr/ -o /expr/ true if either expression is true - /expr/ -a /expr/ true if both expressions are true - ! /expr/ true if expression is not true + /expr/: + /expr/ -o /expr/ true if either expression is true + /expr/ -a /expr/ true if both expressions are true + ! /expr/ true if expression is not true + +Note that a naked /atom/ is not a valid /expr/. If you try to use it +as such: + + # Do not do this. + if [ "$CONFIG_EXPERIMENTAL" ]; then + bool 'Bogus experimental feature' CONFIG_BOGUS + fi + +... then you will be surprised, because CONFIG_EXPERIMENTAL never has a +value of the empty string! It is always "y" or "n", and both of these +are treated as true (non-empty) by the bash-based interpreters Configure +and Menuconfig. Configure: implemented Menuconfig: implemented diff --git a/Documentation/sound/NM256 b/Documentation/sound/NM256 index edff4c1b4..7e66a3009 100644 --- a/Documentation/sound/NM256 +++ b/Documentation/sound/NM256 @@ -2,10 +2,10 @@ Documentation for the NeoMagic 256AV/256ZX sound driver ======================================================= -You're looking at version 1.0 of the driver. (Woohoo!) It has been +You're looking at version 1.1 of the driver. (Woohoo!) It has been successfully tested against the following laptop models: - Sony Z505S/Z505SX/Z505DX + Sony Z505S/Z505SX/Z505DX/Z505RX Sony F150, F160, F180, F250, F270, F280, PCG-F26 Dell Latitude CPi, CPt (various submodels) @@ -16,9 +16,14 @@ This driver was developed without any support or assistance from NeoMagic. There is no warranty, expressed, implied, or otherwise. It is free software in the public domain; feel free to use it, sell it, give it to your best friends, even claim that you wrote it (but why?!) -but don't come whining to me, NeoMagic, Sony, Dell, or anyone else +but don't go whining to me, NeoMagic, Sony, Dell, or anyone else when it blows up your computer. +Version 1.1 contains a change to try and detect non-AC97 versions of +the hardware, and not install itself appropriately. It should also +reinitialize the hardware on an APM resume event, assuming that APM +was configured into your kernel. + ============ Installation ============ @@ -42,16 +47,19 @@ hurting themselves. It works correctly if it shares an IRQ with another device (it normally shares IRQ 9 with the builtin eepro100 ethernet on the Sony Z505 laptops). -It does not run the card in any sort of compatibility mode. Thus it -almost certainly will not work on laptops that have the -SB16-compatible codec/mixer; you will want to use the standard SB16 -OSS driver with these chipsets. I cannot provide any assistance with -machines using the SB-16 compatible version. +It does not run the card in any sort of compatibility mode. It will +not work on laptops that have the SB16-compatible, AD1848-compatible +or CS4232-compatible codec/mixer; you will want to use the appropriate +compatible OSS driver with these chipsets. I cannot provide any +assistance with machines using the SB16, AD1848 or CS4232 compatible +versions. (The driver now attempts to detect the mixer version, and +will refuse to load if it believes the hardware is not not +AC97-compatible.) The sound support is very basic, but it does include simultaneous playback and record capability. The mixer support is also quite simple, although this is in keeping with the rather limited -functionality of the chipset. +functionality of the chipset. There is no hardware synthesizer available, as the Losedows OPL-3 and MIDI support is done via hardware emulation. @@ -63,8 +71,6 @@ models of laptops.) The Z505 series does not have a builtin CD-ROM, so of course the CD-ROM input doesn't work. It does work on laptops with a builtin CD-ROM drive. -Recording is mono 8-bit only. - The mixer device does not appear to have any tone controls, at least on the Z505 series. The mixer module checks for tone controls in the AC97 mixer, and will enable them if they are available. @@ -93,10 +99,11 @@ Known problems limitation. It may be possible to support other speeds in the future. * There is no support for the telephone mixer/codec. There is support - for a phonein/phoneout device if your mixer program supports it; - whether or not it does anything is anyone's guess. (Reports on this - would be appreciated.) - + for a phonein/phoneout device in the mixer driver; whether or not + it does anything is anyone's guess. (Reports on this would be + appreciated. You'll have to figure out how to get the phone to + go off-hook before it'll work, tho.) + * This driver was not written with any cooperation or support from NeoMagic. If you have any questions about this, see their website for their official stance on supporting open source drivers. @@ -118,8 +125,8 @@ This implies a few things: * Sometimes the NM256 driver has to guess at where the buffer should be placed, especially if the module is loaded after the - X server is started. It's usually correct, but it will fail on - the Sony F250. + X server is started. It's usually correct, but it will consistently + fail on the Sony F250. * Virtual screens greater than 1024x768x16 under XFree86 are problematic on laptops with only 2.5MB of screen RAM. This @@ -139,10 +146,16 @@ screen), the best fix is to On the F250, it is possible to force the driver to load properly even after the XFree86 server is started by doing: - insmod nm256.o buffertop=0x25a800 + insmod nm256 buffertop=0x25a800 This forces the audio buffers to the correct offset in screen RAM. +One user has reported a similar problem on the Sony F270, although +others apparently aren't seeing any problems. His suggested command +is + + insmod nm256 buffertop=0x272800 + ================= Official WWW site ================= @@ -154,6 +167,17 @@ The official site for the NM256 driver is: You should always be able to get the latest version of the driver there, and the driver will be supported for the foreseeable future. +============== +Z505RX and IDE +============== + +There appears to be a problem with the IDE chipset on the Z505RX; one +of the symptoms is that sound playback periodically hangs (when the +disk is accessed). The user reporting the problem also reported that +enabling all of the IDE chipset workarounds in the kernel solved the +problem, tho obviously only one of them should be needed--if someone +can give me more details I would appreciate it. + ============================== Z505S/Z505SX on-board Ethernet ============================== @@ -176,11 +200,30 @@ PCMCIA and the Z505S/Z505SX/Z505DX ================================== There is also a known problem with the Sony Z505S and Z505SX hanging -if a PCMCIA card is inserted while the ethernet driver is loaded. -This is caused by tons of spurious IRQ 9s, probably generated from the -PCMCIA or ACPI bridges. There is currently no fix for the problem, -and the only known workaround is to disable the ethernet interface -before inserting or removing a PCMCIA card. +if a PCMCIA card is inserted while the ethernet driver is loaded, or +in some cases if the laptop is suspended. This is caused by tons of +spurious IRQ 9s, probably generated from the PCMCIA or ACPI bridges. + +There is currently no fix for the problem that works in every case. +The only known workarounds are to disable the ethernet interface +before inserting or removing a PCMCIA card, or with some cards +disabling the PCMCIA card before ejecting it will also help the +problem with the laptop hanging when the card is ejected. + +One user has reported that setting the tcic's cs_irq to some value +other than 9 (like 11) fixed the problem. This doesn't work on my +Z505S, however--changing the value causes the cardmgr to stop seeing +card insertions and removals, cards don't seem to work correctly, and +I still get hangs if a card is inserted when the kernel is booted. + +Using the latest ethernet driver and pcmcia package allows me to +insert an Adaptec 1480A SlimScsi card without the laptop hanging, +although I still have to shut down the card before ejecting or +powering down the laptop. However, similar experiments with a DE-660 +ethernet card still result in hangs when the card is inserted. I am +beginning to think that the interrupts are CardBus-related, since the +Adaptec card is a CardBus card, and the DE-660 is not; however, I +don't have any other CardBus cards to test with. ====== Thanks @@ -208,6 +251,11 @@ I will be rather unfair and single out a few people, however: Jeff Garzik, for various helpful suggestions on the AC97 interface + "Mr. Bumpy" for feedback on the Z505RX + + Bill Nottingham, for generous assistance in getting the mixer ID + code working + ================= Previous versions ================= @@ -227,3 +275,6 @@ mixer module. Version 0.75 renamed all the functions and files with slightly more generic names. + +Note that previous versions of this document claimed that recording was +8-bit only; it actually has been working for 16-bits all along. diff --git a/Documentation/video4linux/bttv/CARDS b/Documentation/video4linux/bttv/CARDS index c1a479070..ff47a322a 100644 --- a/Documentation/video4linux/bttv/CARDS +++ b/Documentation/video4linux/bttv/CARDS @@ -106,7 +106,7 @@ Maxi TV Video PCI 2 card Image World ConferenceTV ------------------------ Doesn't work: - - autodetect. Use card=3D20 + - autodetect. Use card=21 - sound mute. Use the line-in volume of your soundcard - radio tuner. Since the card doesn't have an antenna, it is quite understandable ;) However, you can hear some stations if you diff --git a/Documentation/vm/locking b/Documentation/vm/locking index 6efdcec3e..20921f6e4 100644 --- a/Documentation/vm/locking +++ b/Documentation/vm/locking @@ -14,13 +14,12 @@ Page stealers hold kernel_lock to protect against a bunch of races. The vma list of the victim mm is also scanned by the stealer, and the vmlist_lock is used to preserve list sanity against the process adding/deleting to the list. This also gurantees existance -of the vma. Vma existance gurantee while invoking the driver -swapout() method in try_to_swap_out() also relies on the fact -that do_munmap() temporarily gets lock_kernel before decimating -the vma, thus the swapout() method must snapshot all the vma -fields it needs before going to sleep (which will release the -lock_kernel held by the page stealer). Currently, filemap_swapout -is the only method that depends on this shaky interlocking. +of the vma. Vma existance is not guranteed once try_to_swap_out() +drops the vmlist lock. To gurantee the existance of the underlying +file structure, a get_file is done before the swapout() method is +invoked. The page passed into swapout() is guaranteed not to be reused +for a different purpose because the page reference count due to being +present in the user's pte is not released till after swapout() returns. Any code that modifies the vmlist, or the vm_start/vm_end/ vm_flags:VM_LOCKED/vm_next of any vma *in the list* must prevent diff --git a/MAINTAINERS b/MAINTAINERS index e92c24e87..eed47b34d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -93,6 +93,13 @@ M: p_gortmaker@yahoo.com L: linux-net@vger.rutgers.edu S: Maintained +ACPI +P: Andrew Henroid +M: andy_henroid@yahoo.com +L: acpi@phobos.fs.tum.de +W: http://phobos.fs.tum.de/acpi/index.html +S: Maintained + AD1816 SOUND DRIVER P: Thorsten Knabe M: Thorsten Knabe <tek@rbg.informatik.tu-darmstadt.de> @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 23 +SUBLEVEL = 24 EXTRAVERSION = ARCH = mips @@ -332,7 +332,7 @@ endif modules: $(patsubst %, _mod_%, $(SUBDIRS)) -$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h +$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h include/config/MARKER $(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules modules_install: diff --git a/arch/arm/config.in b/arch/arm/config.in index 4271d12a6..3e0bcd0f3 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -123,7 +123,7 @@ fi endmenu -if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_EXPERIMENTAL" ]; then +if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'Enable kernel-mode alignment trap handler (EXPERIMENTAL)' CONFIG_ALIGNMENT_TRAP fi #bool 'Split text into discardable sections' CONFIG_TEXT_SECTIONS diff --git a/arch/i386/config.in b/arch/i386/config.in index b8f081e65..47b2fce5a 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -125,7 +125,6 @@ fi endmenu -source drivers/i2o/Config.in source drivers/pnp/Config.in @@ -145,6 +144,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then fi endmenu +source drivers/i2o/Config.in + if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment comment 'Network device support' diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 8b6370667..a2d091cae 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -70,16 +70,6 @@ CONFIG_BINFMT_MISC=y # CONFIG_APM is not set # -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# # Plug and Play configuration # CONFIG_PNP=y @@ -125,6 +115,7 @@ CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_DAC960 is not set CONFIG_PARIDE_PARPORT=y # CONFIG_PARIDE is not set CONFIG_BLK_DEV_IDE_MODES=y @@ -230,6 +221,16 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_ULTRASTOR is not set # +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# # Network device support # CONFIG_NETDEVICES=y diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 043132b8e..d9aa5ce58 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -37,6 +37,7 @@ EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(__io_virt_debug); EXPORT_SYMBOL(local_bh_count); EXPORT_SYMBOL(local_irq_count); EXPORT_SYMBOL(enable_irq); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 4937efec2..225246d97 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -47,8 +47,6 @@ #include <linux/irq.h> -spinlock_t semaphore_wake_lock = SPIN_LOCK_UNLOCKED; - asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); int hlt_counter=0; @@ -341,70 +339,6 @@ void show_regs(struct pt_regs * regs) } /* - * Allocation and freeing of basic task resources. - * - * NOTE! The task struct and the stack go together - * - * The task structure is a two-page thing, and as such - * not reliable to allocate using the basic page alloc - * functions. We have a small cache of structures for - * when the allocations fail.. - * - * This extra buffer essentially acts to make for less - * "jitter" in the allocations.. - * - * On SMP we don't do this right now because: - * - we aren't holding any locks when called, and we might - * as well just depend on the generic memory management - * to do proper locking for us instead of complicating it - * here. - * - if you use SMP you have a beefy enough machine that - * this shouldn't matter.. - */ -#ifndef __SMP__ -#define EXTRA_TASK_STRUCT 16 -static struct task_struct * task_struct_stack[EXTRA_TASK_STRUCT]; -static int task_struct_stack_ptr = -1; -#endif - -struct task_struct * alloc_task_struct(void) -{ -#ifndef EXTRA_TASK_STRUCT - return (struct task_struct *) __get_free_pages(GFP_KERNEL,1); -#else - int index; - struct task_struct *ret; - - index = task_struct_stack_ptr; - if (index >= EXTRA_TASK_STRUCT/2) - goto use_cache; - ret = (struct task_struct *) __get_free_pages(GFP_KERNEL,1); - if (!ret) { - index = task_struct_stack_ptr; - if (index >= 0) { -use_cache: - ret = task_struct_stack[index]; - task_struct_stack_ptr = index-1; - } - } - return ret; -#endif -} - -void free_task_struct(struct task_struct *p) -{ -#ifdef EXTRA_TASK_STRUCT - int index = task_struct_stack_ptr+1; - - if (index < EXTRA_TASK_STRUCT) { - task_struct_stack[index] = p; - task_struct_stack_ptr = index; - } else -#endif - free_pages((unsigned long) p, 1); -} - -/* * No need to lock the MM as we are the last user */ void release_segments(struct mm_struct *mm) @@ -421,19 +355,6 @@ void release_segments(struct mm_struct *mm) } } -void forget_segments(void) -{ - /* forget local segments */ - __asm__ __volatile__("movl %w0,%%fs ; movl %w0,%%gs" - : /* no outputs */ - : "r" (0)); - - /* - * Load the LDT entry of init_task. - */ - load_LDT(&init_mm); -} - /* * Create a kernel thread */ diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 31c77bb1d..029c79334 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -29,6 +29,8 @@ * Cleaned up cache-detection code * Dave Jones <dave@powertweak.com>, October 1999 * + * Added proper L2 cache detection for Coppermine + * Dragan Stancevic <visitor@valinux.com>, October 1999 */ /* @@ -695,14 +697,18 @@ void __init setup_arch(char **cmdline_p) #endif #ifdef CONFIG_BLK_DEV_INITRD -// FIXME needs to do the new bootmem alloc stuff if (LOADER_TYPE) { - initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; - initrd_end = initrd_start+INITRD_SIZE; - if (initrd_end > (max_low_pfn << PAGE_SHIFT)) { + if (INITRD_START + INITRD_SIZE < (max_low_pfn << PAGE_SHIFT)) { + reserve_bootmem(INITRD_START, INITRD_SIZE); + initrd_start = + INITRD_START ? INITRD_START + PAGE_OFFSET : 0; + initrd_end = initrd_start+INITRD_SIZE; + } + else { printk("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end,memory_end); + INITRD_START + INITRD_SIZE, + max_low_pfn << PAGE_SHIFT); initrd_start = 0; } } @@ -1233,6 +1239,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c) break; case 0x42: + case 0x82: /*Detect 256-Kbyte cache on Coppermine*/ c->x86_cache_size = 256; break; diff --git a/arch/mips/config.in b/arch/mips/config.in index 9fc20b48e..14256b262 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.34 2000/01/23 21:12:56 ralf Exp $ +# $Id: config.in,v 1.35 2000/01/26 00:07:44 ralf Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -150,8 +150,6 @@ if [ "$CONFIG_DECSTATION" = "y" ]; then endmenu fi -source drivers/i2o/Config.in - source drivers/pnp/Config.in source drivers/block/Config.in @@ -196,6 +194,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then fi endmenu +source drivers/i2o/Config.in + if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment comment 'Network device support' diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 20ff288ce..182024ce8 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.21 2000/01/27 01:05:23 ralf Exp $ +/* $Id: init.c,v 1.22 2000/01/27 23:21:57 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -259,7 +259,7 @@ extern int page_is_ram(unsigned long pagenr); void __init mem_init(void) { unsigned long codesize, reservedpages, datasize, initsize; - unsigned long tmp, nonram; + unsigned long tmp, ram; max_mapnr = num_physpages = max_low_pfn; high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); @@ -267,10 +267,10 @@ void __init mem_init(void) totalram_pages += free_all_bootmem(); totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ - reservedpages = nonram = 0; + reservedpages = ram = 0; for (tmp = 0; tmp < max_low_pfn; tmp++) if (page_is_ram(tmp)) { - nonram++; + ram++; if (PageReserved(mem_map+tmp)) reservedpages++; } @@ -282,7 +282,7 @@ void __init mem_init(void) printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " "%ldk data, %ldk init)\n", (unsigned long) nr_free_pages << (PAGE_SHIFT-10), - (max_mapnr - nonram) << (PAGE_SHIFT-10), + ram << (PAGE_SHIFT-10), codesize >> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, diff --git a/arch/mips64/config.in b/arch/mips64/config.in index ead24edff..823c375a6 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.6 2000/01/17 23:32:46 ralf Exp $ +# $Id: config.in,v 1.7 2000/01/20 23:50:27 ralf Exp $ # # For a description of the syntax of this configuration file, # see the Configure script. @@ -111,6 +111,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then fi endmenu +source drivers/i2o/Config.in + if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment comment 'Network device support' diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig index 028845a25..ab794d555 100644 --- a/arch/mips64/defconfig +++ b/arch/mips64/defconfig @@ -66,6 +66,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_DAC960 is not set CONFIG_PARIDE_PARPORT=m # CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set @@ -107,6 +108,16 @@ CONFIG_SKB_LARGE=y # CONFIG_SCSI is not set # +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# # Network device support # CONFIG_NETDEVICES=y diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22 index 1a987ef90..b270cb5dd 100644 --- a/arch/mips64/defconfig-ip22 +++ b/arch/mips64/defconfig-ip22 @@ -104,6 +104,16 @@ CONFIG_SKB_LARGE=y # CONFIG_SCSI is not set # +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# # Network device support # CONFIG_NETDEVICES=y diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27 index 028845a25..ab794d555 100644 --- a/arch/mips64/defconfig-ip27 +++ b/arch/mips64/defconfig-ip27 @@ -66,6 +66,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_DAC960 is not set CONFIG_PARIDE_PARPORT=m # CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set @@ -107,6 +108,16 @@ CONFIG_SKB_LARGE=y # CONFIG_SCSI is not set # +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# # Network device support # CONFIG_NETDEVICES=y diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c index 473e798e8..d4da03f56 100644 --- a/arch/mips64/mm/init.c +++ b/arch/mips64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.7 2000/01/27 01:05:24 ralf Exp $ +/* $Id: init.c,v 1.8 2000/01/27 23:21:57 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -354,7 +354,7 @@ extern int page_is_ram(unsigned long pagenr); void __init mem_init(void) { unsigned long codesize, reservedpages, datasize, initsize; - unsigned long tmp, nonram; + unsigned long tmp, ram; max_mapnr = num_physpages = max_low_pfn; high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); @@ -362,10 +362,10 @@ void __init mem_init(void) totalram_pages += free_all_bootmem(); totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ - reservedpages = nonram = 0; + reservedpages = ram = 0; for (tmp = 0; tmp < max_low_pfn; tmp++) if (page_is_ram(tmp)) { - nonram++; + ram++; if (PageReserved(mem_map+tmp)) reservedpages++; } @@ -377,7 +377,7 @@ void __init mem_init(void) printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " "%ldk data, %ldk init)\n", (unsigned long) nr_free_pages << (PAGE_SHIFT-10), - (max_mapnr - nonram) << (PAGE_SHIFT-10), + ram << (PAGE_SHIFT-10), codesize >> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, diff --git a/arch/mips64/sgi-ip27/ip27-setup.c b/arch/mips64/sgi-ip27/ip27-setup.c index ace1d7b8f..c97eeb8b6 100644 --- a/arch/mips64/sgi-ip27/ip27-setup.c +++ b/arch/mips64/sgi-ip27/ip27-setup.c @@ -1,4 +1,4 @@ -/* $Id$ +/* $Id: ip27-setup.c,v 1.3 2000/01/21 22:34:03 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -23,7 +23,7 @@ /* Check against user dumbness. */ #ifdef CONFIG_VT -#error "CONFIG_VT not allowed for IP27." +#error CONFIG_VT not allowed for IP27. #endif /* diff --git a/arch/ppc/boot/misc.c b/arch/ppc/boot/misc.c index aee407542..6724a8130 100644 --- a/arch/ppc/boot/misc.c +++ b/arch/ppc/boot/misc.c @@ -1,7 +1,7 @@ /* * misc.c * - * $Id: misc.c,v 1.67 1999/08/10 22:53:57 cort Exp $ + * $Id: misc.c,v 1.68 1999/10/20 22:08:08 cort Exp $ * * Adapted for PowerPC by Gary Thomas * @@ -462,6 +462,7 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, puts(" "); puthex((unsigned long)zimage_size+(unsigned long)zimage_start); puts("\n"); + avail_ram += zimage_size; } /* relocate initrd */ @@ -469,15 +470,19 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, { puts("initrd at: "); puthex(initrd_start); puts(" "); puthex(initrd_end); puts("\n"); -#ifdef OMIT - avail_ram = (char *)PAGE_ALIGN( - (unsigned long)zimage_size+(unsigned long)zimage_start); - memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE ); - initrd_start = (unsigned long)avail_ram; - initrd_end = initrd_start + INITRD_SIZE; - puts("relocated to: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); -#endif + if ( (unsigned long)initrd_start <= 0x00800000 ) + { + memcpy( (void *)avail_ram, + (void *)initrd_start, initrd_end-initrd_start ); + puts("relocated to: "); + initrd_end = (unsigned long) avail_ram + (initrd_end-initrd_start); + initrd_start = (unsigned long)avail_ram; + puthex((unsigned long)initrd_start); + puts(" "); + puthex((unsigned long)initrd_end); + puts("\n"); + } + avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end); } avail_ram = (char *)0x00400000; diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 0bcbf06aa..cebd77dfe 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -1,5 +1,5 @@ # -# Automatically generated by make menuconfig: don't edit +# Automatically generated make config: don't edit # # @@ -8,15 +8,27 @@ CONFIG_PPC=y CONFIG_6xx=y # CONFIG_PPC64 is not set +# CONFIG_82xx is not set # CONFIG_8xx is not set +# CONFIG_MPC821 is not set +# CONFIG_MPC823 is not set +# CONFIG_MPC850 is not set +# CONFIG_MPC855 is not set +# CONFIG_MPC860 is not set +# CONFIG_MPC860T is not set +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set # CONFIG_PMAC is not set # CONFIG_PREP is not set # CONFIG_CHRP is not set -CONFIG_ALL_PPC=y -# CONFIG_GEMINI is not set +# CONFIG_ALL_PPC is not set +CONFIG_GEMINI=y # CONFIG_APUS is not set -# CONFIG_MBX is not set # CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y CONFIG_6xx=y # @@ -35,63 +47,45 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set # CONFIG_PARPORT is not set -CONFIG_VGA_CONSOLE=y -CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y -CONFIG_PMAC_PBOOK=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_ADB=y -CONFIG_ADB_CUDA=y -CONFIG_ADB_MACIO=y -CONFIG_ADB_PMU=y -CONFIG_ADB_KEYBOARD=y -CONFIG_PROC_DEVICETREE=y +# CONFIG_VGA_CONSOLE is not set +# CONFIG_FB is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set +# CONFIG_ADB is not set +# CONFIG_PROC_DEVICETREE is not set # CONFIG_TOTALMP is not set -CONFIG_BOOTX_TEXT=y +# CONFIG_BOOTX_TEXT is not set # CONFIG_MOTOROLA_HOTSWAP is not set -# CONFIG_CMDLINE_BOOL is not set # # Plug and Play configuration # # CONFIG_PNP is not set -# CONFIG_ISAPNP is not set # # Block devices # -CONFIG_BLK_DEV_FD=y -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_HD_IDE is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_IDECD_SLOTS is not set -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_RZ1000 is not set -# CONFIG_BLK_DEV_IDEPCI is not set -CONFIG_BLK_DEV_SL82C105=y -CONFIG_BLK_DEV_IDE_PMAC=y -CONFIG_BLK_DEV_IDEDMA_PMAC=y -CONFIG_IDEDMA_PMAC_AUTO=y -CONFIG_BLK_DEV_IDEDMA=y -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_IDE is not set + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_ONLY is not set # CONFIG_BLK_CPQ_DA is not set -CONFIG_BLK_DEV_LOOP=y + +# +# Additional Block Devices +# +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set CONFIG_PARIDE_PARPORT=y # CONFIG_PARIDE is not set -CONFIG_BLK_DEV_IDE_MODES=y +# CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set # @@ -115,12 +109,20 @@ CONFIG_IP_MULTICAST=y # CONFIG_IP_MROUTE is not set CONFIG_IP_ALIAS=y CONFIG_SYN_COOKIES=y + +# +# (it is safe to leave these untouched) +# CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set + +# +# +# # CONFIG_IPX is not set -CONFIG_ATALK=m +# CONFIG_ATALK is not set # CONFIG_DECNET is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set @@ -140,11 +142,19 @@ CONFIG_ATALK=m # SCSI support # CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_ST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y # CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set @@ -157,11 +167,7 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set -CONFIG_SCSI_AIC7XXX=y -# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_PROC_STATS=y -CONFIG_AIC7XXX_RESET_DELAY=15 +# CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set @@ -175,6 +181,8 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_G_NCR5380_PORT is not set +# CONFIG_SCSI_G_NCR5380_MEM is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set @@ -202,9 +210,8 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_ULTRASTOR is not set # CONFIG_SCSI_DEBUG is not set -CONFIG_SCSI_MESH=y -CONFIG_SCSI_MESH_SYNC_RATE=5 -CONFIG_SCSI_MAC53C94=y +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set # # Network device support @@ -224,8 +231,9 @@ CONFIG_NETDEVICES=y # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MACE=y -CONFIG_BMAC=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +CONFIG_NCR885E=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set @@ -235,38 +243,11 @@ CONFIG_BMAC=y # CONFIG_YELLOWFIN is not set # CONFIG_ACENIC is not set # CONFIG_NET_ISA is not set -CONFIG_NET_EISA=y -CONFIG_PCNET32=y -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_DEC_ELCP is not set -# CONFIG_DGRS is not set -# CONFIG_EEXPRESS_PRO100 is not set -# CONFIG_LNE390 is not set -# CONFIG_NE3210 is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_ES3210 is not set -# CONFIG_EPIC100 is not set -# CONFIG_ZNET is not set -# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_NET_EISA is not set # CONFIG_NET_POCKET is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set - -# -# Appletalk devices -# -# CONFIG_LTPC is not set -# CONFIG_COPS is not set -# CONFIG_IPDDP is not set -CONFIG_PPP=y -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_RADIO is not set @@ -287,13 +268,6 @@ CONFIG_PPP=y # CONFIG_DLCI is not set # -# PCMCIA network devices -# -# CONFIG_PCMCIA_PCNET is not set -# CONFIG_PCMCIA_3C589 is not set -# CONFIG_PCMCIA_RAYCS is not set - -# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -311,45 +285,14 @@ CONFIG_PPP=y # # Console drivers # -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FB_CLGEN is not set -# CONFIG_FB_PM2 is not set -CONFIG_FB_OF=y -CONFIG_FB_CONTROL=y -CONFIG_FB_PLATINUM=y -CONFIG_FB_VALKYRIE=y -CONFIG_FB_IMSTT=y -CONFIG_FB_CT65550=y -# CONFIG_FB_S3TRIO is not set -# CONFIG_FB_VGA16 is not set -CONFIG_FB_MATROX=y -# CONFIG_FB_MATROX_MILLENIUM is not set -CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y -# CONFIG_FB_MATROX_MULTIHEAD is not set -CONFIG_FB_ATY=y -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_CFB16=y -CONFIG_FBCON_CFB24=y -CONFIG_FBCON_CFB32=y -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -CONFIG_FBCON_FONTS=y -# CONFIG_FONT_8x8 is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_SUN8x16=y -CONFIG_FONT_SUN12x22=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set # # Character devices # CONFIG_VT=y CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=m +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y @@ -362,14 +305,13 @@ CONFIG_BUSMOUSE=y # CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_LOGIBUSMOUSE is not set # CONFIG_MS_BUSMOUSE is not set -# CONFIG_ADB_MOUSE is not set CONFIG_MOUSE=y CONFIG_PSMOUSE=y # CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set # CONFIG_QIC02_TAPE is not set # CONFIG_WATCHDOG is not set -CONFIG_NVRAM=y +# CONFIG_NVRAM is not set # CONFIG_RTC is not set # @@ -389,6 +331,14 @@ CONFIG_NVRAM=y # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set +# CONFIG_FT_NORMAL_DEBUG is not set +# CONFIG_FT_FULL_DEBUG is not set +# CONFIG_FT_NO_TRACE is not set +# CONFIG_FT_NO_TRACE_AT_ALL is not set +# CONFIG_FT_STD_FDC is not set +# CONFIG_FT_MACH2 is not set +# CONFIG_FT_PROBE_FC10 is not set +# CONFIG_FT_ALT_FDC is not set # CONFIG_DRM is not set # @@ -400,14 +350,11 @@ CONFIG_NVRAM=y # Filesystems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -427,11 +374,10 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set -CONFIG_NFS_FS=y -CONFIG_NFSD=y -# CONFIG_NFSD_SUN is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set @@ -451,49 +397,11 @@ CONFIG_MSDOS_PARTITION=y # # Sound # -CONFIG_SOUND=y -CONFIG_DMASOUND=y -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_WAVEFRONT is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_SOFTOSS is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_UART6850 is not set - -# -# Additional low level sound drivers -# -# CONFIG_LOWLEVEL_SOUND is not set +# CONFIG_SOUND is not set # # Kernel hacking # -CONFIG_MAGIC_SYSRQ=y +# CONFIG_MAGIC_SYSRQ is not set # CONFIG_KGDB is not set -CONFIG_XMON=y +# CONFIG_XMON is not set diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index 983a9f2eb..88686acc4 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -286,9 +286,6 @@ chrp_pcibios_fixup(void) { if ( dev->irq ) dev->irq = openpic_to_irq( dev->irq ); - /* adjust the io_port for the NCR cards for busses other than 0 -- Cort */ - if ( (dev->bus->number > 0) && (dev->vendor == PCI_VENDOR_ID_NCR) ) - dev->resource[0].start += (dev->bus->number*0x08000000); /* these need to be absolute addrs for OF and Matrox FB -- Cort */ if ( dev->vendor == PCI_VENDOR_ID_MATROX ) { @@ -305,6 +302,10 @@ chrp_pcibios_fixup(void) pcibios_write_config_word(dev->bus->number, dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); } + if ( (dev->bus->number > 0) && + ((dev->vendor == PCI_VENDOR_ID_NCR) || + (dev->vendor == PCI_VENDOR_ID_AMD))) + dev->resource[0].start += (dev->bus->number*0x08000000); } } diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index 58d2003c4..e70ba4dca 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -28,7 +28,6 @@ #include <linux/reboot.h> #include <linux/init.h> #include <linux/blk.h> -#include <linux/ide.h> #include <linux/ioport.h> #include <linux/console.h> #include <linux/pci.h> @@ -37,6 +36,7 @@ #include <linux/adb.h> #include <linux/module.h> #include <linux/delay.h> +#include <linux/ide.h> #include <asm/mmu.h> #include <asm/processor.h> @@ -127,7 +127,7 @@ chrp_get_cpuinfo(char *buffer) len = sprintf(buffer,"machine\t\t: CHRP %s\n", model); /* longtrail (goldengate) stuff */ - if ( !strncmp( model, "IBM,LongTrail", 9 ) ) + if ( !strncmp( model, "IBM,LongTrail", 13 ) ) { /* VLSI VAS96011/12 `Golden Gate 2' */ /* Memory banks */ @@ -198,21 +198,27 @@ static void __init sio_fixup_irq(const char *name, u8 device, u8 level, u8 type) { u8 level0, type0, active; - - /* select logical device */ - sio_write(device, 0x07); - active = sio_read(0x30); - level0 = sio_read(0x70); - type0 = sio_read(0x71); - printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0, - !active ? "in" : ""); - if (level0 == level && type0 == type && active) - printk("OK\n"); - else { - printk("remapping to level %d, type %d, active\n", level, type); - sio_write(0x01, 0x30); - sio_write(level, 0x70); - sio_write(type, 0x71); + struct device_node *root; + + root = find_path_device("/"); + if (root && + !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13 ) ) + { + /* select logical device */ + sio_write(device, 0x07); + active = sio_read(0x30); + level0 = sio_read(0x70); + type0 = sio_read(0x71); + printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0, + !active ? "in" : ""); + if (level0 == level && type0 == type && active) + printk("OK\n"); + else { + printk("remapping to level %d, type %d, active\n", level, type); + sio_write(0x01, 0x30); + sio_write(level, 0x70); + sio_write(type, 0x71); + } } } diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c index 23060ba26..aee01f105 100644 --- a/arch/ppc/kernel/gemini_setup.c +++ b/arch/ppc/kernel/gemini_setup.c @@ -332,9 +332,12 @@ void __init gemini_init_IRQ(void) /* gemini has no 8259 */ open_pic.irq_offset = 0; - for( i=0; i < 16; i++ ) + for( i=0; i < OPENPIC_VEC_SPURIOUS; i++ ) irq_desc[i].ctl = &open_pic; openpic_init(1); +#ifdef __SMP__ + request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, 0, "IPI0", 0); +#endif /* __SMP__ */ } #define gemini_rtc_read(x) (readb(GEMINI_RTC+(x))) diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index 42ebfd9f4..8dda6ad6b 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -40,10 +40,10 @@ unsigned long zero_paged_on = 0; unsigned long powersave_nap = 0; unsigned long *zero_cache; /* head linked list of pre-zero'd pages */ -unsigned long zero_sz; /* # currently pre-zero'd pages */ -unsigned long zeropage_hits; /* # zero'd pages request that we've done */ -unsigned long zeropage_calls; /* # zero'd pages request that've been made */ -unsigned long zerototal; /* # pages zero'd over time */ +atomic_t zerototal; /* # pages zero'd over time */ +atomic_t zeropage_hits; /* # zero'd pages request that we've done */ +atomic_t zero_sz; /* # currently pre-zero'd pages */ +atomic_t zeropage_calls; /* # zero'd pages request that've been made */ int idled(void) { @@ -57,7 +57,7 @@ int idled(void) check_pgt_cache(); - if ( !current->need_resched && zero_paged_on ) zero_paged(); + /*if ( !current->need_resched && zero_paged_on ) zero_paged();*/ if ( !current->need_resched && htab_reclaim_on ) htab_reclaim(); if ( !current->need_resched ) power_save(); @@ -141,6 +141,7 @@ out: #endif /* CONFIG_8xx */ } +#if 0 /* * Returns a pre-zero'd page from the list otherwise returns * NULL. @@ -149,7 +150,7 @@ unsigned long get_zero_page_fast(void) { unsigned long page = 0; - atomic_inc((atomic_t *)&zero_cache_calls); + atomic_inc(&zero_cache_calls); if ( zero_quicklist ) { /* atomically remove this page from the list */ @@ -194,9 +195,9 @@ void zero_paged(void) unsigned long bytecount = 0; pte_t *pte; - if ( zero_cache_sz >= zero_cache_water[0] ) + if ( atomic_read(&zero_cache_sz) >= zero_cache_water[0] ) return; - while ( (zero_cache_sz < zero_cache_water[1]) && (!current->need_resched) ) + while ( (atomic_read(&zero_cache_sz) < zero_cache_water[1]) && (!current->need_resched) ) { /* * Mark a page as reserved so we can mess with it @@ -272,6 +273,7 @@ void zero_paged(void) atomic_inc((atomic_t *)&zero_cache_total); } } +#endif void power_save(void) { diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 9ab3589f6..d851569d5 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -241,6 +241,8 @@ int get_irq_list(char *buf) #endif /* __SMP__ */ if ( irq_desc[i].ctl ) len += sprintf(buf+len, " %s ", irq_desc[i].ctl->typename ); + else + len += sprintf(buf+len, " None "); len += sprintf(buf+len, " %s",action->name); for (action=action->next; action; action = action->next) { len += sprintf(buf+len, ", %s", action->name); @@ -297,7 +299,8 @@ asmlinkage void do_IRQ(struct pt_regs *regs, int isfake) if ( irq < 0 ) { /* -2 means ignore, already handled */ - if (irq != -2) { + if (irq != -2) + { printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", irq, regs->nip); ppc_spurious_interrupts++; diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 2b5493747..9f3f58a38 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -85,6 +85,7 @@ static void no_action(int ir1, void *dev, struct pt_regs *regs) #ifdef __SMP__ void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) { +printk("openpic_ipi_action\n"); smp_message_recv(); } #endif /* __SMP__ */ diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 518446bf9..8863a9940 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -311,18 +311,16 @@ int get_cpuinfo(char *buffer) /* * Ooh's and aah's info about zero'd pages in idle task */ - { - len += sprintf(buffer+len,"zero pages\t: total %lu (%luKb) " - "current: %lu (%luKb) hits: %lu/%lu (%lu%%)\n", - zero_cache_total, - (zero_cache_total*PAGE_SIZE)>>10, - zero_cache_sz, - (zero_cache_sz*PAGE_SIZE)>>10, - zero_cache_hits,zero_cache_calls, - /* : 1 below is so we don't div by zero */ - (zero_cache_hits*100) / - ((zero_cache_calls)?zero_cache_calls:1)); - } + len += sprintf(buffer+len,"zero pages\t: total: %u (%luKb) " + "current: %u (%luKb) hits: %u/%u (%u%%)\n", + atomic_read(&zero_cache_total), + (atomic_read(&zero_cache_total)*PAGE_SIZE)>>10, + atomic_read(&zero_cache_sz), + (atomic_read(&zero_cache_sz)*PAGE_SIZE)>>10, + atomic_read(&zero_cache_hits),atomic_read(&zero_cache_calls), + /* : 1 below is so we don't div by zero */ + (atomic_read(&zero_cache_hits)*100) / + ((atomic_read(&zero_cache_calls))?atomic_read(&zero_cache_calls):1)); if (ppc_md.get_cpuinfo != NULL) { diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index 638e06b26..a21361340 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -159,6 +159,12 @@ void smp_message_recv(void) void smp_send_reschedule(int cpu) { + /* + * This isn't the case anymore since the other CPU could be + * sleeping and won't reschedule until the next interrupt (such + * as the timer). + * -- Cort + */ /* This is only used if `cpu' is running an idle task, so it will reschedule itself anyway... */ /*smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);*/ @@ -173,7 +179,7 @@ spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED; void smp_message_pass(int target, int msg, unsigned long data, int wait) { int i; - if ( !(_machine & (_MACH_Pmac|_MACH_chrp)) ) + if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_gemini)) ) return; spin_lock(&mesg_pass_lock); @@ -216,24 +222,29 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait) { /* * There has to be some way of doing this better - - * perhaps a sent-to-all or send-to-all-but-self + * perhaps a send-to-all or send-to-all-but-self * in the openpic. This gets us going for now, though. * -- Cort */ switch ( target ) { case MSG_ALL: - for ( i = 0 ; i < smp_num_cpus ; i++ ) - openpic_cause_IPI(i, 0, 0xffffffff ); + openpic_cause_IPI(smp_processor_id(), 0, 0x0 ); + openpic_cause_IPI(smp_processor_id(), 0, 0xffffffff ); break; case MSG_ALL_BUT_SELF: for ( i = 0 ; i < smp_num_cpus ; i++ ) if ( i != smp_processor_id () ) - openpic_cause_IPI(i, 0, - 0xffffffff & ~(1 << smp_processor_id())); + { + openpic_cause_IPI(smp_processor_id(), 0, + 0x0 ); + openpic_cause_IPI(smp_processor_id(), 0, + 0xffffffff & ~(1 << smp_processor_id())); + } break; default: - openpic_cause_IPI(target, 0, 1U << target); + openpic_cause_IPI(smp_processor_id(), 0, 0x0 ); + openpic_cause_IPI(target, 0, 1U << target ); break; } } @@ -251,8 +262,7 @@ void __init smp_boot_cpus(void) struct task_struct *p; unsigned long a; - printk("Entering SMP Mode...\n"); - /* let other processors know to not do certain initialization */ + printk("Entering SMP Mode...\n"); smp_num_cpus = 1; smp_store_cpu_info(0); @@ -290,15 +300,13 @@ void __init smp_boot_cpus(void) cpu_nr = 2; break; case _MACH_chrp: - /* openpic doesn't report # of cpus, just # possible -- Cort */ -#if 0 - cpu_nr = ((openpic_read(&OpenPIC->Global.Feature_Reporting0) - & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >> - OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT)+1; -#endif + for ( i = 0; i < 4 ; i++ ) + openpic_enable_IPI(i); cpu_nr = smp_chrp_cpu_nr; break; case _MACH_gemini: + for ( i = 0; i < 4 ; i++ ) + openpic_enable_IPI(i); cpu_nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK)>>2; cpu_nr = (cpu_nr == 0) ? 4 : cpu_nr; break; @@ -350,19 +358,6 @@ void __init smp_boot_cpus(void) case _MACH_chrp: *(unsigned long *)KERNELBASE = i; asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); -#if 0 - device = find_type_devices("cpu"); - /* assume cpu device list is in order, find the ith cpu */ - for ( a = i; device && a; device = device->next, a-- ) - ; - if ( !device ) - break; - printk( "Starting %s (%lu): ", device->full_name, - *(ulong *)get_property(device, "reg", NULL) ); - call_rtas( "start-cpu", 3, 1, NULL, - *(ulong *)get_property(device, "reg", NULL), - __pa(__secondary_start_chrp), i); -#endif break; case _MACH_gemini: openpic_init_processor( 1<<i ); @@ -428,6 +423,7 @@ void __init smp_callin(void) smp_store_cpu_info(current->processor); set_dec(decrementer_count); + init_idle(); #if 0 current->mm->mmap->vm_page_prot = PAGE_SHARED; current->mm->mmap->vm_start = PAGE_OFFSET; diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index d38fa7a22..e21c30e14 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -1,5 +1,5 @@ /* - * $Id: time.c,v 1.55 1999/08/31 06:54:09 davem Exp $ + * $Id: time.c,v 1.57 1999/10/21 03:08:16 cort Exp $ * Common time routines among all ppc machines. * * Written by Cort Dougan (cort@cs.nmt.edu) to merge @@ -95,37 +95,48 @@ void timer_interrupt(struct pt_regs * regs) } #endif /* __SMP__ */ - while ((dval = get_dec()) < 0) { + dval = get_dec(); + /* + * Wait for the decrementer to change, then jump + * in and add decrementer_count to its value + * (quickly, before it changes again!) + */ + while ((d = get_dec()) == dval) + ; + /* + * Don't play catchup between the call to time_init() + * and sti() in init/main.c. + * + * This also means if we're delayed for > HZ + * we lose those ticks. If we're delayed for > HZ + * then we have something wrong anyway, though. + * + * -- Cort + */ + if ( d < (-1*decrementer_count) ) + d = 0; + set_dec(d + decrementer_count); + if ( !smp_processor_id() ) + { + do_timer(regs); /* - * Wait for the decrementer to change, then jump - * in and add decrementer_count to its value - * (quickly, before it changes again!) + * update the rtc when needed */ - while ((d = get_dec()) == dval) - ; - set_dec(d + decrementer_count); - if ( !smp_processor_id() ) + if ( (time_status & STA_UNSYNC) && + ((xtime.tv_sec > last_rtc_update + 60) || + (xtime.tv_sec < last_rtc_update)) ) { - do_timer(regs); - /* - * update the rtc when needed - */ - if ( (time_status & STA_UNSYNC) && - ((xtime.tv_sec > last_rtc_update + 60) || - (xtime.tv_sec < last_rtc_update)) ) - { - if (ppc_md.set_rtc_time(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec; - } + if (ppc_md.set_rtc_time(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + /* do it again in 60 s */ + last_rtc_update = xtime.tv_sec; } } #ifdef __SMP__ smp_local_timer_interrupt(regs); #endif - + if ( ppc_md.heartbeat && !ppc_md.heartbeat_count--) ppc_md.heartbeat(); diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index 7ccbe656f..34a32fe8c 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -204,9 +204,8 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) if (pmd_none(*pmd)) { if (!mem_init_done) pte = (pte_t *) MMU_get_page(); - else if ((pte = (pte_t *) get_zero_page_fast()) == NULL) - if ((pte = (pte_t *) __get_free_page(GFP_KERNEL))) - clear_page(pte); + else if ((pte = (pte_t *) __get_free_page(GFP_KERNEL))) + clear_page(pte); if (pte) { pmd_val(*pmd) = (unsigned long)pte; return pte + offset; @@ -1156,8 +1155,7 @@ void __init do_init_bootmem(void) __pa(end_of_DRAM) >> PAGE_SHIFT); /* remove the bootmem bitmap from the available memory */ - remove_mem_piece(&phys_avail, start, start + boot_mapsize, 1); - + remove_mem_piece(&phys_avail, start, boot_mapsize, 1); /* add everything in phys_avail into the bootmem map */ for (i = 0; i < phys_avail.n_regions; ++i) free_bootmem(phys_avail.regions[i].address, @@ -1509,10 +1507,10 @@ static void __init hash_init(void) ramsize >> 20, Hash_size >> 10, Hash); if ( Hash_size ) { + if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); __clear_user(Hash, Hash_size); - - if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); + /* * Patch up the instructions in head.S:hash_page */ diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index bd9c7bb39..ac5a075c0 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S @@ -149,7 +149,7 @@ initial_page_write: /* Unwind the stack and jmp to the debug entry */ debug: add #4,r15 ! skip syscall number - ldc.l @r15+,ssr + mov.l @r15+,r11 ! SSR mov.l @r15+,r10 ! original stack mov.l @r15+,r0 mov.l @r15+,r1 @@ -164,6 +164,7 @@ debug: or r9,r14 ldc r14,sr ! here, change the register bank mov r10,k0 + mov r11,k1 mov.l @r15+,r8 mov.l @r15+,r9 mov.l @r15+,r10 @@ -180,7 +181,7 @@ debug: ! mov.l 9f,k0 jmp @k0 - nop + ldc k1,ssr .balign 4 8: .long 0x300000f0 9: .long 0xa0000100 @@ -371,7 +372,7 @@ ret_with_reschedule: ! restore_all: add #4,r15 ! skip syscall number - ldc.l @r15+,ssr + mov.l @r15+,r11 ! SSR mov.l @r15+,r10 ! original stack mov.l @r15+,r0 mov.l @r15+,r1 @@ -386,6 +387,7 @@ restore_all: or r9,r14 ldc r14,sr ! here, change the register bank mov r10,k0 + mov r11,k1 mov.l @r15+,r8 mov.l @r15+,r9 mov.l @r15+,r10 @@ -399,6 +401,7 @@ restore_all: lds.l @r15+,pr ldc.l @r15+,spc mov k0,r15 + ldc k1,ssr rte nop @@ -515,7 +518,7 @@ none: .data ENTRY(exception_handling_table) - .long none /* XXX: Avoid spurious interrupt */ + .long error .long error .long tlb_miss_load .long tlb_miss_store diff --git a/arch/sh/kernel/irq_onchip.c b/arch/sh/kernel/irq_onchip.c index b4ba54f31..0ed3400ef 100644 --- a/arch/sh/kernel/irq_onchip.c +++ b/arch/sh/kernel/irq_onchip.c @@ -89,29 +89,33 @@ static struct hw_interrupt_type onChip_irq_type = { void disable_onChip_irq(unsigned int irq) { + unsigned long val, flags; /* Set priority in IPR to 0 */ int offset = ipr_data[irq-TIMER_IRQ].offset; unsigned long intc_ipr_address = INTC_IPR + (offset/16*INTC_SIZE); unsigned short mask = 0xffff ^ (0xf << (offset%16)); - unsigned long val; + save_and_cli(flags); val = ctrl_inw(intc_ipr_address); val &= mask; ctrl_outw(val, intc_ipr_address); + restore_flags(flags); } static void enable_onChip_irq(unsigned int irq) { + unsigned long val, flags; /* Set priority in IPR back to original value */ int offset = ipr_data[irq-TIMER_IRQ].offset; int priority = ipr_data[irq-TIMER_IRQ].priority; unsigned long intc_ipr_address = INTC_IPR + (offset/16*INTC_SIZE); unsigned short value = (priority << (offset%16)); - unsigned long val; + save_and_cli(flags); val = ctrl_inw(intc_ipr_address); val |= value; ctrl_outw(val, intc_ipr_address); + restore_flags(flags); } void make_onChip_irq(unsigned int irq) diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 59c97a66b..deb532300 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -28,14 +28,17 @@ #ifdef CONFIG_BLK_DEV_RAM #include <linux/blk.h> #endif -#include <asm/processor.h> +#include <linux/bootmem.h> #include <linux/console.h> +#include <asm/processor.h> +#include <asm/page.h> #include <asm/pgtable.h> #include <asm/uaccess.h> #include <asm/system.h> #include <asm/io.h> #include <asm/smp.h> + /* * Machine setup.. */ @@ -62,7 +65,6 @@ extern int _text, _etext, _edata, _end; #define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c)) #define INITRD_START (*(unsigned long *) (PARAM+0x010)) #define INITRD_SIZE (*(unsigned long *) (PARAM+0x014)) -#define MEMORY_END (*(unsigned long *) (PARAM+0x018)) /* ... */ #define COMMAND_LINE ((char *) (PARAM+0x100)) #define COMMAND_LINE_SIZE 256 @@ -105,11 +107,67 @@ static struct resource rom_resources[MAXROMS] = { { "Video ROM", 0xc0000, 0xc7fff } }; -void __init setup_arch(char **cmdline_p, - unsigned long * memory_start_p, - unsigned long * memory_end_p) +static unsigned long memory_start, memory_end; + +unsigned long __init memparse(char *ptr, char **retptr) { - unsigned long memory_start, memory_end; + unsigned long ret; + + ret = simple_strtoul(ptr, retptr, 0); + + if (**retptr == 'K' || **retptr == 'k') { + ret <<= 10; + (*retptr)++; + } + else if (**retptr == 'M' || **retptr == 'm') { + ret <<= 20; + (*retptr)++; + } + return ret; +} /* memparse */ + +static inline void parse_mem_cmdline (char ** cmdline_p) +{ + char c = ' ', *to = command_line, *from = COMMAND_LINE; + int len = 0; + + /* Save unparsed command line copy for /proc/cmdline */ + memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + + memory_start = (unsigned long)__va(0)+__MEMORY_START; + /* Default is 4Mbyte. */ + memory_end = (unsigned long)__va(0x00400000)+__MEMORY_START; + + for (;;) { + /* + * "mem=XXX[kKmM]" defines a size of memory. + */ + if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + { + unsigned long mem_size; + + mem_size = memparse(from+4, &from); + memory_end = memory_start + mem_size; + } + } + c = *(from++); + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; + *cmdline_p = command_line; +} + +void __init setup_arch(char **cmdline_p) +{ + unsigned long bootmap_size; + unsigned long start_pfn, max_pfn, max_low_pfn; ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); @@ -118,12 +176,9 @@ void __init setup_arch(char **cmdline_p, rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); #endif + if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; - - memory_start = (unsigned long) &_end; - memory_end = MEMORY_END; - init_mm.start_code = (unsigned long)&_text; init_mm.end_code = (unsigned long) &_etext; init_mm.end_data = (unsigned long) &_edata; @@ -134,21 +189,73 @@ void __init setup_arch(char **cmdline_p, data_resource.start = virt_to_bus(&_etext); data_resource.end = virt_to_bus(&_edata)-1; - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); - saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + parse_mem_cmdline(cmdline_p); - memcpy(command_line, COMMAND_LINE, COMMAND_LINE_SIZE); - command_line[COMMAND_LINE_SIZE-1] = '\0'; +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) - /* Not support "mem=XXX[kKmM]" command line option. */ - *cmdline_p = command_line; + /* + * partially used pages are not usable - thus + * we are rounding upwards: + */ + start_pfn = PFN_UP(__pa(&_end)-__MEMORY_START); - memory_end &= PAGE_MASK; - ram_resources[1].end = memory_end-1; + /* + * Find the highest page frame number we have available + */ + max_pfn = PFN_DOWN(__pa(memory_end)-__MEMORY_START); - *memory_start_p = memory_start; - *memory_end_p = memory_end; + /* + * Determine low and high memory ranges: + */ + max_low_pfn = max_pfn; + + /* + * Initialize the boot-time allocator (with low memory only): + */ + bootmap_size = init_bootmem(start_pfn, max_low_pfn); + + /* + * FIXME: what about high memory? + */ + ram_resources[1].end = PFN_PHYS(max_low_pfn) + __MEMORY_START; + + /* + * Register fully available low RAM pages with the bootmem allocator. + */ + { + unsigned long curr_pfn, last_pfn, size; + + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(0); + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(memory_end-__MEMORY_START); + + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + + size = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + } + /* + * Reserve the kernel text and + * Reserve the bootmem bitmap itself as well. We do this in two + * steps (first step was init_bootmem()) because this catches + * the (very unlikely) case of us accidentally initializing the + * bootmem allocator with an invalid RAM area. + */ + reserve_bootmem(PAGE_SIZE, PFN_PHYS(start_pfn) + bootmap_size); + + /* + * reserve physical page 0 - it's a special BIOS page on many boxes, + * enabling clean reboots, SMP operation, laptop functions. + */ + reserve_bootmem(0, PAGE_SIZE); #ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE) { @@ -156,10 +263,12 @@ void __init setup_arch(char **cmdline_p, initrd_end = initrd_start+INITRD_SIZE; if (initrd_end > memory_end) { printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end,memory_end); + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + initrd_end,memory_end); initrd_start = 0; - } + } else + reserve_bootmem(__pa(initrd_start)-__MEMORY_START, + INITRD_SIZE); } #endif diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index 934c84744..5f7d68755 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -6,7 +6,7 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = lib.a -L_OBJS = delay.o memcpy.o memset.o memmove.o old-checksum.o \ +L_OBJS = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \ checksum.o include $(TOPDIR)/Rules.make diff --git a/arch/sh/lib/memchr.S b/arch/sh/lib/memchr.S new file mode 100644 index 000000000..d5f9ba2e3 --- /dev/null +++ b/arch/sh/lib/memchr.S @@ -0,0 +1,26 @@ +/* $Id: memchr.S,v 1.1 1999/10/17 11:32:38 gniibe Exp $ + * + * "memchr" implementation of SuperH + * + * Copyright (C) 1999 Niibe Yutaka + * + */ + +/* + * void *memchr(const void *s, int c, size_t n); + */ + +#include <linux/linkage.h> +ENTRY(memchr) + tst r6,r6 + bt/s 2f + exts.b r5,r5 +1: mov.b @r4,r1 + cmp/eq r1,r5 + bt/s 3f + dt r6 + bf/s 1b + add #1,r4 +2: mov #0,r4 +3: rts + mov r4,r0 diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 4c602a385..2dc194a77 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -24,6 +24,7 @@ #ifdef CONFIG_BLK_DEV_INITRD #include <linux/blk.h> #endif +#include <linux/bootmem.h> #include <asm/processor.h> #include <asm/system.h> @@ -37,21 +38,53 @@ */ unsigned long mmu_context_cache; -static unsigned long totalram = 0; +static unsigned long totalram_pages = 0; +static unsigned long totalhigh_pages = 0; extern void show_net_buffers(void); extern unsigned long init_smp_mappings(unsigned long); -void __bad_pte_kernel(pmd_t *pmd) +/* + * BAD_PAGE is the page that is used for page faults when linux + * is out-of-memory. Older versions of linux just did a + * do_exit(), but using this instead means there is less risk + * for a process dying in kernel mode, possibly leaving an inode + * unused etc.. + * + * BAD_PAGETABLE is the accompanying page-table: it is initialized + * to point to BAD_PAGE entries. + * + * ZERO_PAGE is a special page that is used for zero-initialized + * data and COW. + */ + +unsigned long empty_bad_page[1024]; +pte_t empty_bad_pte_table[PTRS_PER_PTE]; +extern unsigned long empty_zero_page[1024]; + +static pte_t * get_bad_pte_table(void) +{ + pte_t v; + int i; + + v = pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED)); + + for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++) + empty_bad_pte_table[i] = v; + + return empty_bad_pte_table; +} + +void __handle_bad_pmd(pmd_t *pmd) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); + pmd_ERROR(*pmd); + pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table()); } -void __bad_pte(pmd_t *pmd) +void __handle_bad_pmd_kernel(pmd_t *pmd) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE); + pmd_ERROR(*pmd); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table()); } pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) @@ -61,16 +94,16 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) pte = (pte_t *) __get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - clear_page((unsigned long)pte); + clear_page(pte); pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); return pte + offset; } - pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table()); return NULL; } free_page((unsigned long)pte); if (pmd_bad(*pmd)) { - __bad_pte_kernel(pmd); + __handle_bad_pmd_kernel(pmd); return NULL; } return (pte_t *) pmd_page(*pmd) + offset; @@ -83,19 +116,19 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) pte = (unsigned long) __get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - clear_page(pte); + clear_page((void *)pte); pmd_val(*pmd) = _PAGE_TABLE + __pa(pte); - return (pte_t *)(pte + offset); + return (pte_t *)pte + offset; } - pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE); + pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table()); return NULL; } free_page(pte); if (pmd_bad(*pmd)) { - __bad_pte(pmd); + __handle_bad_pmd(pmd); return NULL; } - return (pte_t *) (pmd_page(*pmd) + offset); + return (pte_t *) pmd_page(*pmd) + offset; } int do_check_pgt_cache(int low, int high) @@ -114,37 +147,6 @@ int do_check_pgt_cache(int low, int high) return freed; } -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving an inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -pte_t * __bad_pagetable(void) -{ - extern unsigned long empty_bad_page_table[PAGE_SIZE]; - unsigned long page = (unsigned long)empty_bad_page_table; - - clear_page(page); - return (pte_t *)empty_bad_page_table; -} - -pte_t __bad_page(void) -{ - extern char empty_bad_page[PAGE_SIZE]; - unsigned long page = (unsigned long)empty_bad_page; - - clear_page(page); - return pte_mkdirty(mk_pte(page, PAGE_SHARED)); -} - void show_mem(void) { int i,free = 0,total = 0,reserved = 0; @@ -170,13 +172,12 @@ void show_mem(void) printk("%d pages shared\n",shared); printk("%d pages swap cached\n",cached); printk("%ld pages in page table cache\n",pgtable_cache_size); + show_buffers(); #ifdef CONFIG_NET show_net_buffers(); #endif } -extern unsigned long free_area_init(unsigned long, unsigned long); - /* References to section boundaries */ extern char _text, _etext, _edata, __bss_start, _end; @@ -190,13 +191,10 @@ pgd_t swapper_pg_dir[1024]; * This routines also unmaps the page at virtual kernel address 0, so * that we can trap those pesky NULL-reference errors in the kernel. */ -unsigned long __init -paging_init(unsigned long start_mem, unsigned long end_mem) +void __init paging_init(void) { pgd_t * pg_dir; - start_mem = PAGE_ALIGN(start_mem); - /* We don't need kernel mapping as hardware support that. */ pg_dir = swapper_pg_dir; @@ -209,61 +207,25 @@ paging_init(unsigned long start_mem, unsigned long end_mem) mmu_context_cache = MMU_CONTEXT_FIRST_VERSION; set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK); - return free_area_init(start_mem, end_mem); + free_area_init(max_low_pfn); } -unsigned long empty_bad_page[1024]; -unsigned long empty_bad_page_table[1024]; -extern unsigned long empty_zero_page[1024]; - -void __init mem_init(unsigned long start_mem, unsigned long end_mem) +void __init mem_init(void) { int codepages = 0; int reservedpages = 0; int datapages = 0; int initpages = 0; - unsigned long tmp; - end_mem &= PAGE_MASK; - high_memory = (void *) end_mem; - max_mapnr = num_physpages = MAP_NR(end_mem); + max_mapnr = num_physpages = max_low_pfn; + high_memory = (void *) ((unsigned long)__va(max_low_pfn * PAGE_SIZE)+__MEMORY_START); /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); - /* Mark (clear "reserved" bit) usable pages in the mem_map[] */ - /* Note that all are marked reserved already. */ - tmp = start_mem = PAGE_ALIGN(start_mem); - while (tmp < end_mem) { - clear_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags); - clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags); - tmp += PAGE_SIZE; - } + /* this will put all low memory onto the freelists */ + totalram_pages += free_all_bootmem(); - for (tmp = PAGE_OFFSET; tmp < end_mem; tmp += PAGE_SIZE) { - if (PageReserved(mem_map+MAP_NR(tmp))) { - if (tmp >= (unsigned long) &_text && tmp < (unsigned long) &_edata) { - if (tmp < (unsigned long) &_etext) - codepages++; - else - datapages++; - } else if (tmp >= (unsigned long) &__init_begin - && tmp < (unsigned long) &__init_end) - initpages++; - else if (tmp >= (unsigned long) &__bss_start - && tmp < (unsigned long) start_mem) - datapages++; - else - reservedpages++; - continue; - } - set_page_count(mem_map+MAP_NR(tmp), 1); - totalram += PAGE_SIZE; -#ifdef CONFIG_BLK_DEV_INITRD - if (!initrd_start || (tmp < initrd_start || tmp >= initrd_end)) -#endif - free_page(tmp); - } printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", (unsigned long) nr_free_pages << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), @@ -279,19 +241,22 @@ void free_initmem(void) addr = (unsigned long)(&__init_begin); for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { - mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); + ClearPageReserved(mem_map + MAP_NR(addr)); set_page_count(mem_map+MAP_NR(addr), 1); free_page(addr); - totalram += PAGE_SIZE; + totalram_pages++; } printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) { - val->totalram = totalram; + val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages << PAGE_SHIFT; - val->bufferram = atomic_read(&buffermem); + val->freeram = nr_free_pages; + val->bufferram = atomic_read(&buffermem_pages); + val->totalhigh = totalhigh_pages; + val->freehigh = nr_free_highpages; + val->mem_unit = PAGE_SIZE; return; } diff --git a/drivers/block/Config.in b/drivers/block/Config.in index 7f70e32ee..897aaa634 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -200,6 +200,9 @@ if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD fi tristate 'XT hard disk support' CONFIG_BLK_DEV_XD +if [ "$CONFIG_PCI" = "y" ]; then + tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 +fi # PARIDE doesn't need PARPORT, but if PARPORT is configured as a module, # PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 06eed2279..9f26a4b5e 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -19,8 +19,8 @@ */ -#define DAC960_DriverVersion "2.2.4" -#define DAC960_DriverDate "23 August 1999" +#define DAC960_DriverVersion "2.3.4" +#define DAC960_DriverDate "23 September 1999" #include <linux/version.h> @@ -256,7 +256,7 @@ static void DAC960_QueueCommand(DAC960_Command_T *Command) static boolean DAC960_ExecuteCommand(DAC960_Command_T *Command) { DAC960_Controller_T *Controller = Command->Controller; - Semaphore_T Semaphore = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(Semaphore); unsigned long ProcessorFlags; Command->Semaphore = &Semaphore; DAC960_AcquireControllerLock(Controller, &ProcessorFlags); @@ -475,8 +475,8 @@ static void DAC960_DetectControllers(DAC960_ControllerType_T ControllerType) unsigned char Device = DeviceFunction >> 3; unsigned char Function = DeviceFunction & 0x7; unsigned int IRQ_Channel = PCI_Device->irq; - unsigned long BaseAddress0 = PCI_Device->base_address[0]; - unsigned long BaseAddress1 = PCI_Device->base_address[1]; + unsigned long BaseAddress0 = PCI_Device->resource[0].start; + unsigned long BaseAddress1 = PCI_Device->resource[1].start; unsigned short SubsystemVendorID, SubsystemDeviceID; int CommandIdentifier; pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_VENDOR_ID, @@ -825,7 +825,7 @@ static boolean DAC960_ReadDeviceConfiguration(DAC960_Controller_T *Controller) &Controller->InquiryStandardData[Channel][TargetID]; InquiryStandardData->PeripheralDeviceType = 0x1F; Semaphore = &Semaphores[Channel]; - *Semaphore = MUTEX_LOCKED; + init_MUTEX_LOCKED(Semaphore); DCDB = &DCDBs[Channel]; DAC960_ClearCommand(Command); Command->CommandType = DAC960_ImmediateCommand; diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 579fbc13a..92b1c7d4d 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -34,6 +34,7 @@ #include <linux/blkpg.h> #include <linux/timer.h> #include <linux/proc_fs.h> +#include <linux/init.h> #include <linux/hdreg.h> #include <linux/spinlock.h> #include <asm/uaccess.h> @@ -703,6 +704,26 @@ static ulong remap_pci_mem(ulong base, ulong size) return (ulong) (page_remapped ? (page_remapped + page_offs) : 0UL); } +#ifndef MODULE +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,13) +/* + * Config string is a comma seperated set of i/o addresses of EISA cards. + */ +static int cpqarray_setup(char *str) +{ + int i, ints[9]; + + (void)get_options(str, ARRAY_SIZE(ints), ints); + + for(i=0; i<ints[0] && i<8; i++) + eisa[i] = ints[i+1]; + return 1; +} + +__setup("smart2=", cpqarray_setup); + +#else + /* * Copy the contents of the ints[] array passed to us by init. */ @@ -712,6 +733,8 @@ void cpqarray_setup(char *str, int *ints) for(i=0; i<ints[0] && i<8; i++) eisa[i] = ints[i+1]; } +#endif +#endif /* * Find an EISA controller's signature. Set up an hba if we find it. diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 9366a8856..59116c19d 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -286,15 +286,39 @@ void set_device_ro(kdev_t dev,int flag) else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31)); } -static inline void drive_stat_acct(int cmd, unsigned long nr_sectors, - short disk_index) +static inline void drive_stat_acct(struct request *req, + unsigned long nr_sectors, int new_io) { - kstat.dk_drive[disk_index]++; - if (cmd == READ) { - kstat.dk_drive_rio[disk_index]++; + int major = MAJOR(req->rq_dev); + int minor = MINOR(req->rq_dev); + unsigned int disk_index; + + switch (major) { + case DAC960_MAJOR+0: + disk_index = (minor & 0x00f8) >> 3; + break; + case SCSI_DISK0_MAJOR: + disk_index = (minor & 0x00f0) >> 4; + break; + case IDE0_MAJOR: /* same as HD_MAJOR */ + case XT_DISK_MAJOR: + disk_index = (minor & 0x0040) >> 6; + break; + case IDE1_MAJOR: + disk_index = ((minor & 0x0040) >> 6) + 2; + break; + default: + return; + } + if (disk_index >= DK_NDRIVE) + return; + + kstat.dk_drive[disk_index] += new_io; + if (req->cmd == READ) { + kstat.dk_drive_rio[disk_index] += new_io; kstat.dk_drive_rblk[disk_index] += nr_sectors; - } else if (cmd == WRITE) { - kstat.dk_drive_wio[disk_index]++; + } else if (req->cmd == WRITE) { + kstat.dk_drive_wio[disk_index] += new_io; kstat.dk_drive_wblk[disk_index] += nr_sectors; } else printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n"); @@ -313,35 +337,11 @@ static inline void drive_stat_acct(int cmd, unsigned long nr_sectors, void add_request(struct blk_dev_struct * dev, struct request * req) { int major = MAJOR(req->rq_dev); - int minor = MINOR(req->rq_dev); struct request * tmp, **current_request; - short disk_index; unsigned long flags; int queue_new_request = 0; - switch (major) { - case DAC960_MAJOR+0: - disk_index = (minor & 0x00f8) >> 3; - if (disk_index < 4) - drive_stat_acct(req->cmd, req->nr_sectors, disk_index); - break; - case SCSI_DISK0_MAJOR: - disk_index = (minor & 0x00f0) >> 4; - if (disk_index < 4) - drive_stat_acct(req->cmd, req->nr_sectors, disk_index); - break; - case IDE0_MAJOR: /* same as HD_MAJOR */ - case XT_DISK_MAJOR: - disk_index = (minor & 0x0040) >> 6; - drive_stat_acct(req->cmd, req->nr_sectors, disk_index); - break; - case IDE1_MAJOR: - disk_index = ((minor & 0x0040) >> 6) + 2; - drive_stat_acct(req->cmd, req->nr_sectors, disk_index); - default: - break; - } - + drive_stat_acct(req, req->nr_sectors, 1); req->next = NULL; /* @@ -575,6 +575,7 @@ void make_request(int major,int rw, struct buffer_head * bh) req->bhtail->b_reqnext = bh; req->bhtail = bh; req->nr_sectors += count; + drive_stat_acct(req, count, 0); /* Can we now merge this req with the next? */ attempt_merge(req, max_sectors); /* or to the beginning? */ @@ -585,6 +586,7 @@ void make_request(int major,int rw, struct buffer_head * bh) req->current_nr_sectors = count; req->sector = sector; req->nr_sectors += count; + drive_stat_acct(req, count, 0); } else continue; diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 7c2b23dab..9fec26361 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c @@ -276,12 +276,9 @@ static ssize_t initrd_read(struct file *file, char *buf, static int initrd_release(struct inode *inode,struct file *file) { - unsigned long i; - - if (--initrd_users) return 0; - for (i = initrd_start; i < initrd_end; i += PAGE_SIZE) - free_page(i); initrd_start = 0; + /* No need to actually release the pages, because that is + done later by free_all_bootmem. */ return 0; } diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c index ac21c68f0..17e87e7f8 100644 --- a/drivers/char/bttv.c +++ b/drivers/char/bttv.c @@ -121,8 +121,9 @@ static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) if (!pmd_none(*pmd)) { ptep = pte_offset(pmd, adr); pte = *ptep; + /* Note; page_address will panic for us if the page is high */ if(pte_present(pte)) - ret = (pte_page(pte)|(adr&(PAGE_SIZE-1))); + ret = page_address(pte_page(pte))|(adr&(PAGE_SIZE-1)); } } MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret)); diff --git a/drivers/char/drm/proc.c b/drivers/char/drm/proc.c index 7db90aea8..666b6e5ac 100644 --- a/drivers/char/drm/proc.c +++ b/drivers/char/drm/proc.c @@ -393,7 +393,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len, pgprot & _PAGE_PCD ? 'u' : 'c', pgprot & _PAGE_ACCESSED ? 'a' : '-', pgprot & _PAGE_DIRTY ? 'd' : '-', - pgprot & _PAGE_4M ? 'm' : 'k', + pgprot & _PAGE_PSE ? 'm' : 'k', pgprot & _PAGE_GLOBAL ? 'g' : 'l' ); #endif DRM_PROC_PRINT("\n"); diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 38bbf438b..45193f9ce 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -158,6 +158,7 @@ #ifdef LOCAL_HEADERS #include "serial_local.h" #else +#include <linux/serialP.h> #include <linux/serial.h> #include <linux/serial_reg.h> #include <asm/serial.h> diff --git a/drivers/i2o/i2o_block.c b/drivers/i2o/i2o_block.c index 5042f4e97..c06b61d2d 100644 --- a/drivers/i2o/i2o_block.c +++ b/drivers/i2o/i2o_block.c @@ -703,7 +703,7 @@ static int i2ob_release(struct inode *inode, struct file *file) msg[2] = i2ob_context|0x80000000; msg[3] = (u32)query_done; msg[4] = 60<<16; - i2o_post_wait(dev->controller, dev->tid, msg, 20, query_done,2); + i2o_post_wait(dev->controller, msg, 20, 2); /* * Unlock the media */ @@ -712,7 +712,7 @@ static int i2ob_release(struct inode *inode, struct file *file) msg[2] = i2ob_context|0x80000000; msg[3] = (u32)query_done; msg[4] = -1; - i2o_post_wait(dev->controller, dev->tid, msg, 20, query_done,2); + i2o_post_wait(dev->controller, msg, 20, 2); /* * Now unclaim the device. @@ -766,7 +766,7 @@ static int i2ob_open(struct inode *inode, struct file *file) msg[3] = (u32)query_done; msg[4] = -1; msg[5] = 0; - i2o_post_wait(dev->controller, dev->tid, msg, 24, query_done,2); + i2o_post_wait(dev->controller, msg, 24, 2); /* * Lock the media */ @@ -775,7 +775,7 @@ static int i2ob_open(struct inode *inode, struct file *file) msg[2] = i2ob_context|0x80000000; msg[3] = (u32)query_done; msg[4] = -1; - i2o_post_wait(dev->controller, dev->tid, msg, 20, query_done,2); + i2o_post_wait(dev->controller, msg, 20, 2); } MOD_INC_USE_COUNT; return 0; @@ -788,8 +788,8 @@ static int i2ob_open(struct inode *inode, struct file *file) static int i2ob_query_device(struct i2ob_device *dev, int table, int field, void *buf, int buflen) { - return i2o_query_scalar(dev->controller, dev->tid, i2ob_context, - table, field, buf, buflen, &dev->done_flag); + return i2o_query_scalar(dev->controller, dev->tid, + table, field, buf, buflen); } @@ -891,7 +891,10 @@ static void i2ob_probe(void) for(d=c->devices;d!=NULL;d=d->next) { - if(d->class!=I2O_CLASS_RANDOM_BLOCK_STORAGE) + if(d->lct_data->class_id!=I2O_CLASS_RANDOM_BLOCK_STORAGE) + continue; + + if(d->lct_data->user_tid != 0xFFF) continue; if(unit<MAX_I2OB<<4) @@ -903,7 +906,7 @@ static void i2ob_probe(void) struct i2ob_device *dev=&i2ob_dev[unit]; dev->i2odev = d; dev->controller = c; - dev->tid = d->id; + dev->tid = d->lct_data->tid; /* * Insure the device can be claimed @@ -930,9 +933,10 @@ static void i2ob_probe(void) else { if(!warned++) - printk("i2o_block: too many controllers, registering only %d.\n", unit>>4); + printk("i2o_block: too many device, registering only %d.\n", unit>>4); } } + i2o_unlock_controller(c); } i2ob_devices = unit; } @@ -981,7 +985,7 @@ static int i2ob_reboot_event(struct notifier_block *n, unsigned long code, void msg[2] = i2ob_context|0x80000000; msg[3] = (u32)query_done; msg[4] = 60<<16; - i2o_post_wait(dev->controller, dev->tid, msg, 20, query_done,2); + i2o_post_wait(dev->controller, msg, 20, 2); /* * Unlock the media */ @@ -990,7 +994,7 @@ static int i2ob_reboot_event(struct notifier_block *n, unsigned long code, void msg[2] = i2ob_context|0x80000000; msg[3] = (u32)query_done; msg[4] = -1; - i2o_post_wait(dev->controller, dev->tid, msg, 20, query_done,2); + i2o_post_wait(dev->controller, msg, 20, 2); } } return NOTIFY_DONE; @@ -1058,7 +1062,7 @@ int i2o_block_init(void) { int i; - printk(KERN_INFO "I2O block device OSM v0.07. (C) 1999 Red Hat Software.\n"); + printk(KERN_INFO "I2O Block Storage OSM v0.07. (C) 1999 Red Hat Software.\n"); /* * Register the block device interfaces diff --git a/drivers/i2o/i2o_config.c b/drivers/i2o/i2o_config.c index 518093ea0..c8682f077 100644 --- a/drivers/i2o/i2o_config.c +++ b/drivers/i2o/i2o_config.c @@ -317,14 +317,14 @@ static int ioctl_parms(unsigned long arg, unsigned int type) return -ENOMEM; } - len = i2o_issue_params(i2o_cmd, c, kcmd.tid, cfg_handler.context, - ops, kcmd.oplen, res, 65536, &i2o_cfg_token); + len = i2o_issue_params(i2o_cmd, c, kcmd.tid, + ops, kcmd.oplen, res, 65536); i2o_unlock_controller(c); kfree(ops); - if (len < 0) { + if (len) { kfree(res); - return len; /* -DetailedStatus */ + return len; /* -DetailedStatus || -ETIMEDOUT */ } put_user(len, kcmd.reslen); @@ -413,8 +413,8 @@ int ioctl_html(unsigned long arg) msg[8] = virt_to_phys(query); } - token = i2o_post_wait(c, cmd->tid, msg, 9*4, &i2o_cfg_token, 10); - if(token != I2O_POST_WAIT_OK) + token = i2o_post_wait(c, msg, 9*4, 10); + if(token) { i2o_unlock_controller(c); kfree(res); @@ -531,8 +531,8 @@ int ioctl_swdl(unsigned long arg) // Yes...that's one minute, but the spec states that // transfers take a long time, and I've seen just how // long they can take. - token = i2o_post_wait(c, ADAPTER_TID, msg, sizeof(msg), &i2o_cfg_token,60); - if (token != I2O_POST_WAIT_OK ) // Something very wrong + token = i2o_post_wait(c, msg, sizeof(msg), 60); + if (token) // Something very wrong { i2o_unlock_controller(c); printk("Timeout downloading software"); @@ -547,8 +547,8 @@ int ioctl_swdl(unsigned long arg) msg[4] |= (u32)maxfrag; msg[7] = (0xD0000000 | diff); __copy_from_user(buffer, kxfer.buf, 8192); - token = i2o_post_wait(c, ADAPTER_TID, msg, sizeof(msg), &i2o_cfg_token,60); - if( token != I2O_POST_WAIT_OK ) // Something very wrong + token = i2o_post_wait(c, msg, sizeof(msg), 60); + if(token) // Something very wrong { i2o_unlock_controller(c); printk("Timeout downloading software"); @@ -588,10 +588,10 @@ int ioctl_validate(unsigned long arg) msg[2] = (u32)i2o_cfg_context; msg[3] = 0; - token = i2o_post_wait(c, ADAPTER_TID, msg, sizeof(msg),&i2o_cfg_token, 10); + token = i2o_post_wait(c, msg, sizeof(msg), 10); i2o_unlock_controller(c); - if (token != I2O_POST_WAIT_OK) + if (token) { printk("Can't validate configuration, ErrorStatus = %d\n", token); diff --git a/drivers/i2o/i2o_core.c b/drivers/i2o/i2o_core.c index fe8a86483..c2ade9ded 100644 --- a/drivers/i2o/i2o_core.c +++ b/drivers/i2o/i2o_core.c @@ -1,22 +1,24 @@ -/* - * Core I2O structure managment - * - * (C) Copyright 1999 Red Hat Software +/* + * Core I2O structure managment + * + * (C) Copyright 1999 Red Hat Software * - * Written by Alan Cox, Building Number Three Ltd - * - * 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. - * - * A lot of the I2O message side code from this is taken from the - * Red Creek RCPCI45 adapter driver by Red Creek Communications + * Written by Alan Cox, Building Number Three Ltd + * + * 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. + * + * A lot of the I2O message side code from this is taken from the + * Red Creek RCPCI45 adapter driver by Red Creek Communications * - * Fixes by Philipp Rumpf - * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI> - * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI> - * Deepak Saxena <deepak@plexity.net> + * Fixes by: + * Philipp Rumpf + * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI> + * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI> + * Deepak Saxena <deepak@plexity.net> + * */ #include <linux/config.h> @@ -31,11 +33,16 @@ #include <linux/malloc.h> #include <linux/spinlock.h> +#include <linux/bitops.h> +#include <linux/wait.h> +#include <linux/timer.h> + #include <asm/io.h> #include "i2o_lan.h" #define DRIVERDEBUG +// #define DEBUG_IRQ /* * Size of the I2O module table @@ -48,12 +55,36 @@ static int core_context = 0; static int reply_flag = 0; extern int i2o_online_controller(struct i2o_controller *c); +static int i2o_init_outbound_q(struct i2o_controller *c); static void i2o_core_reply(struct i2o_handler *, struct i2o_controller *, struct i2o_message *); static int i2o_add_management_user(struct i2o_device *, struct i2o_handler *); static int i2o_remove_management_user(struct i2o_device *, struct i2o_handler *); +static int i2o_quiesce_system(void); +static int i2o_enable_system(void); static void i2o_dump_message(u32 *); +static int i2o_lct_get(struct i2o_controller *); +static int i2o_hrt_get(struct i2o_controller *); + +static void i2o_sys_init(void); +static void i2o_sys_shutdown(void); + +static int i2o_build_sys_table(void); +static int i2o_systab_send(struct i2o_controller *c); + +/* + * I2O System Table. Contains information about + * all the IOPs in the system. Used to inform IOPs + * about each other's existence. + * + * sys_tbl_ver is the CurrentChangeIndicator that is + * used by IOPs to track changes. + */ +static struct i2o_sys_tbl *sys_tbl = NULL; +static int sys_tbl_ind = 0; +static int sys_tbl_len = 0; + #ifdef MODULE /* * Function table to send to bus specific layers @@ -76,6 +107,21 @@ extern void i2o_pci_core_detach(void); #endif /* MODULE */ +/* + * Structures and definitions for synchronous message posting. + * See i2o_post_wait() for description. + */ +struct i2o_post_wait_data +{ + int status; + u32 id; + wait_queue_head_t *wq; + struct i2o_post_wait_data *next; +}; +static struct i2o_post_wait_data *post_wait_queue = NULL; +static u32 post_wait_id = 0; // Unique ID for each post_wait +static spinlock_t post_wait_lock = SPIN_LOCK_UNLOCKED; +static void i2o_post_wait_complete(u32, int); /* Message handler */ static struct i2o_handler i2o_core_handler = @@ -85,6 +131,7 @@ static struct i2o_handler i2o_core_handler = 0 }; + /* * I2O configuration spinlock. This isnt a big deal for contention * so we have one only @@ -92,11 +139,17 @@ static struct i2o_handler i2o_core_handler = static spinlock_t i2o_configuration_lock = SPIN_LOCK_UNLOCKED; +/* + * I2O Core reply handler + * + * Only messages this should see are i2o_post_wait() replies + */ void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *m) { u32 *msg=(u32 *)m; - u32 *flag = (u32 *)msg[3]; + u32 status; + u32 context = msg[3]; #if 0 i2o_report_status(KERN_INFO, "i2o_core", msg); @@ -117,13 +170,18 @@ void i2o_core_reply(struct i2o_handler *h, struct i2o_controller *c, return; } - if (msg[4] >> 24) + if(msg[2]&0x80000000) // Post wait message { - i2o_report_status(KERN_WARNING, "i2o_core", msg); - *flag = -(msg[4] & 0xFFFF); + if (msg[4] >> 24) + { + i2o_report_status(KERN_WARNING, "i2o_core: post_wait reply", msg); + status = -(msg[4] & 0xFFFF); + } + else + status = I2O_POST_WAIT_OK; + + i2o_post_wait_complete(context, status); } - else - *flag = I2O_POST_WAIT_OK; } /* @@ -245,6 +303,12 @@ int i2o_install_controller(struct i2o_controller *c) c->next=i2o_controller_chain; i2o_controller_chain=c; c->unit = i; + c->page_frame = NULL; + c->hrt = NULL; + c->lct = NULL; + c->status_block = NULL; + printk(KERN_INFO "lct @ %p hrt @ %p status @ %p", + c->lct, c->hrt, c->status_block); sprintf(c->name, "i2o/iop%d", i); i2o_num_controllers++; spin_unlock(&i2o_configuration_lock); @@ -261,10 +325,14 @@ int i2o_delete_controller(struct i2o_controller *c) struct i2o_controller **p; int users; +#ifdef DRIVERDEBUG + printk(KERN_INFO "Deleting controller iop%d\n", c->unit); +#endif + spin_lock(&i2o_configuration_lock); if((users=atomic_read(&c->users))) { - printk("I2O: %d users for controller iop%d\n", users, c->unit); + printk(KERN_INFO "I2O: %d users for controller iop%d\n", users, c->unit); spin_unlock(&i2o_configuration_lock); return -EBUSY; } @@ -280,21 +348,6 @@ int i2o_delete_controller(struct i2o_controller *c) p=&i2o_controller_chain; - /* Send first SysQuiesce to other IOPs */ - while(*p) - { - if(*p!=c) - { - printk("Quiescing controller %p != %p\n", c, *p); - if(i2o_quiesce_controller(*p)<0) - printk(KERN_INFO "Unable to quiesce iop%d\n", - (*p)->unit); - } - p=&((*p)->next); - } - - p=&i2o_controller_chain; - while(*p) { if(*p==c) @@ -308,15 +361,26 @@ int i2o_delete_controller(struct i2o_controller *c) *p=c->next; spin_unlock(&i2o_configuration_lock); + + printk(KERN_INFO "hrt %p lct %p page_frame %p status_block %p\n", + c->hrt, c->lct, c->page_frame, c->status_block); if(c->page_frame) kfree(c->page_frame); if(c->hrt) kfree(c->hrt); if(c->lct) kfree(c->lct); - i2o_controllers[c->unit]=NULL; + if(c->status_block) + kfree(c->status_block); + kfree(c); + + i2o_controllers[c->unit]=NULL; + i2o_num_controllers--; +#ifdef DRIVERDEBUG + printk(KERN_INFO "iop deleted\n"); +#endif return 0; } p=&((*p)->next); @@ -360,7 +424,7 @@ int i2o_claim_device(struct i2o_device *d, struct i2o_handler *h, u32 type) return -EBUSY; } - if(i2o_issue_claim(d->controller,d->id, h->context, 1, &reply_flag, type) < 0) + if(i2o_issue_claim(d->controller,d->lct_data->tid, h->context, 1, &reply_flag, type)) { return -EBUSY; } @@ -395,8 +459,8 @@ int i2o_release_device(struct i2o_device *d, struct i2o_handler *h, u32 type) err = -ENOENT; else { - if(i2o_issue_claim(d->controller, d->id, h->context, 0, - &reply_flag, type) < 0) + if(i2o_issue_claim(d->controller, d->lct_data->tid, h->context, 0, + &reply_flag, type)) { err = -ENXIO; } @@ -418,8 +482,8 @@ int i2o_release_device(struct i2o_device *d, struct i2o_handler *h, u32 type) { atomic_dec(&d->controller->users); - if(i2o_issue_claim(d->controller,d->id, h->context, 0, - &reply_flag, type) < 0) + if(i2o_issue_claim(d->controller,d->lct_data->tid, h->context, 0, + &reply_flag, type)) err = -ENXIO; } @@ -468,7 +532,11 @@ void i2o_run_queue(struct i2o_controller *c) { struct i2o_message *m; u32 mv; - + +#ifdef DEBUG_IRQ + printk(KERN_INFO "iop%d interrupt\n", c->unit); +#endif + while((mv=I2O_REPLY_READ32(c))!=0xFFFFFFFF) { struct i2o_handler *i; @@ -478,7 +546,11 @@ void i2o_run_queue(struct i2o_controller *c) */ if(((m->function_addr>>24)&0xFF)==0x15) printk("UTFR!\n"); -// printk("dispatching.\n"); + +#ifdef DEBUG_IRQ + i2o_dump_message((u32*)m); +#endif + i=i2o_handlers[m->initiator_context&(MAX_I2O_MODULES-1)]; if(i) i->reply(i,c,m); @@ -572,8 +644,10 @@ u32 i2o_wait_message(struct i2o_controller *c, char *why) { if((jiffies-time)>=5*HZ) { +#ifdef DRIVERDEBUG printk(KERN_ERR "%s: Timeout waiting for message frame to send %s.\n", c->name, why); +#endif return 0xFFFFFFFF; } schedule(); @@ -596,8 +670,10 @@ u32 i2o_wait_reply(struct i2o_controller *c, char *why, int timeout) { if(jiffies-time >= timeout*HZ ) { +#ifdef DRIVERDEBUG printk(KERN_ERR "%s: timeout waiting for %s reply.\n", c->name, why); +#endif return 0xFFFFFFFF; } schedule(); @@ -686,8 +762,10 @@ static int i2o_query_scalar_polled(struct i2o_controller *c, int tid, void *buf, /* Do we have an error block ? */ if(p[1]&0xFF000000) { +#ifdef DRIVERDEBUG printk(KERN_ERR "%s: error in field read.\n", c->name); +#endif kfree(rbuf); return -EBADR; } @@ -711,25 +789,27 @@ static int i2o_query_scalar_polled(struct i2o_controller *c, int tid, void *buf, void i2o_report_controller_unit(struct i2o_controller *c, int unit) { char buf[64]; + return; - if(i2o_query_scalar_polled(c, unit, buf, 16, 0xF100, 3)>=0) + if(i2o_query_scalar(c, unit, 0xF100, 3, buf, 16)) { buf[16]=0; printk(KERN_INFO " Vendor: %s\n", buf); } - if(i2o_query_scalar_polled(c, unit, buf, 16, 0xF100, 4)>=0) + if(i2o_query_scalar(c, unit, 0xF100, 4, buf, 16)) { + buf[16]=0; printk(KERN_INFO " Device: %s\n", buf); } #if 0 - if(i2o_query_scalar_polled(c, unit, buf, 16, 0xF100, 5)>=0) + if(i2o_query_scalar(c, unit, 0xF100, 5, buf, 16)) { buf[16]=0; printk(KERN_INFO "Description: %s\n", buf); } #endif - if(i2o_query_scalar_polled(c, unit, buf, 8, 0xF100, 6)>=0) + if(i2o_query_scalar(c, unit, 0xF100, 6, buf, 8)) { buf[8]=0; printk(KERN_INFO " Rev: %s\n", buf); @@ -749,6 +829,7 @@ void i2o_report_controller_unit(struct i2o_controller *c, int unit) static int i2o_parse_hrt(struct i2o_controller *c) { +#ifdef DRIVERDEBUG u32 *rows=c->hrt; u8 *p=(u8 *)c->hrt; u8 *d; @@ -766,8 +847,8 @@ static int i2o_parse_hrt(struct i2o_controller *c) count=p[0]|(p[1]<<8); length = p[2]; - printk(KERN_INFO "HRT has %d entries of %d bytes each.\n", - count, length<<2); + printk(KERN_INFO "iop%d: HRT has %d entries of %d bytes each.\n", + c->unit, count, length<<2); rows+=2; @@ -829,6 +910,7 @@ static int i2o_parse_hrt(struct i2o_controller *c) printk("\n"); rows+=length; } +#endif return 0; } @@ -845,12 +927,12 @@ static int i2o_parse_lct(struct i2o_controller *c) u32 *p; struct i2o_device *d; char str[22]; - u32 *lct=(u32 *)c->lct; + pi2o_lct lct = c->lct; - max=lct[0]&0xFFFF; + max = lct->table_size; - max-=3; - max/=9; + max -= 3; + max /= 9; if(max==0) { @@ -866,28 +948,25 @@ static int i2o_parse_lct(struct i2o_controller *c) max=128; } - if(lct[1]&(1<<0)) - printk(KERN_WARNING "Configuration dialog desired.\n"); + if(lct->iop_flags&(1<<0)) + printk(KERN_WARNING "I2O: Configuration dialog desired by iop%d.\n", c->unit); - p=lct+3; - for(i=0;i<max;i++) { d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL); if(d==NULL) { - printk("i2o_core: Out of memory for LCT data.\n"); + printk("i2o_core: Out of memory for I2O device data.\n"); return -ENOMEM; } d->controller = c; d->next = NULL; - - d->id = tid = (p[0]>>16)&0xFFF; - d->class = p[3]&0xFFF; - d->subclass = p[4]&0xFFF; - d->parent = (p[5]>>12)&0xFFF; + + d->lct_data = &lct->lct_entry[i]; + d->flags = 0; + tid = d->lct_data->tid; printk(KERN_INFO "TID %d.\n", tid); @@ -897,19 +976,19 @@ static int i2o_parse_lct(struct i2o_controller *c) printk(KERN_INFO " Class: "); - sprintf(str, "%-21s", i2o_get_class_name(d->class)); + sprintf(str, "%-21s", i2o_get_class_name(d->lct_data->class_id)); printk("%s", str); printk(" Subclass: 0x%03X Flags: ", - d->subclass); + d->lct_data->sub_class); - if(p[2]&(1<<0)) + if(d->lct_data->device_flags&(1<<0)) printk("C"); // ConfigDialog requested - if(p[2]&(1<<1)) + if(d->lct_data->device_flags&(1<<1)) printk("M"); // Multi-user capable - if(!(p[2]&(1<<4))) + if(!(d->lct_data->device_flags&(1<<4))) printk("P"); // Peer service enabled! - if(!(p[2]&(1<<5))) + if(!(d->lct_data->device_flags&(1<<5))) printk("m"); // Mgmt service enabled! printk("\n"); p+=9; @@ -917,30 +996,120 @@ static int i2o_parse_lct(struct i2o_controller *c) return 0; } + /* Quiesce IOP */ int i2o_quiesce_controller(struct i2o_controller *c) { u32 msg[4]; + if(c->status_block->iop_state != ADAPTER_STATE_OPERATIONAL) + return -EINVAL; + msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; msg[1]=I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID; - msg[2]=core_context; + msg[2]=(u32)core_context; msg[3]=(u32)&reply_flag; /* Long timeout needed for quiesce if lots of devices */ - return i2o_post_wait(c, ADAPTER_TID, msg, sizeof(msg), &reply_flag, 120); +#ifdef DRIVERDEBUG + printk(KERN_INFO "Posting quiesce message to iop%d\n", c->unit); +#endif + if(i2o_post_wait(c, msg, sizeof(msg), 120)) + return -1; + else + return 0; +} + +/* Enable IOP */ +int i2o_enable_controller(struct i2o_controller *c) +{ + u32 msg[4]; + + msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; + msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID; + msg[2]=core_context; + msg[3]=(u32)&reply_flag; + + /* How long of a timeout do we need? */ + return i2o_post_wait(c, msg, sizeof(msg), 240); +} + +/* + * Quiesce _all_ IOPs in OP state. + * Used during init/shutdown time. + */ +int i2o_quiesce_system(void) +{ + struct i2o_controller *iop; + int ret = 0; + + for(iop=i2o_controller_chain; iop != NULL; iop=iop->next) + { + /* + * Quiesce only needed on operational IOPs + */ + i2o_status_get(iop); + + if(iop->status_block->iop_state == ADAPTER_STATE_OPERATIONAL) + { +#ifdef DRIVERDEBUG + printk(KERN_INFO "Attempting to quiesce iop%d\n", iop->unit); +#endif + if(i2o_quiesce_controller(iop)) + { + printk(KERN_INFO "Unable to quiesce iop%d\n", iop->unit); + ret = -ENXIO; + } +#ifdef DRIVERDEBUG + else + printk(KERN_INFO "%s quiesced\n", iop->name); +#endif + + i2o_status_get(iop); // Update IOP state information + } + } + + return ret; } +/* + * (re)Enable _all_ IOPs in READY state. + */ +int i2o_enable_system(void) +{ + struct i2o_controller *iop; + int ret = 0; + + for(iop=i2o_controller_chain; iop != NULL; iop=iop->next) + { + /* + * Enable only valid for IOPs in READY state + */ + i2o_status_get(iop); + + if(iop->status_block->iop_state == ADAPTER_STATE_READY) + { + if(i2o_enable_controller(iop)<0) + printk(KERN_INFO "Unable to (re)enable iop%d\n", + iop->unit); + + i2o_status_get(iop); // Update IOP state information + } + } + + return ret; +} + +/* Reset an IOP, but keep message queues alive */ int i2o_clear_controller(struct i2o_controller *c) { u32 msg[4]; + int ret; - /* First stop external operations for this IOP */ - if(i2o_quiesce_controller(c)<0) - printk(KERN_INFO "Unable to quiesce iop%d\n", c->unit); - else - printk(KERN_INFO "Iop%d quiesced\n", c->unit); +#ifdef DRIVERDEBUG + printk(KERN_INFO "Clearing iop%d\n", c->unit); +#endif /* Then clear the IOP */ msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; @@ -948,7 +1117,14 @@ int i2o_clear_controller(struct i2o_controller *c) msg[2]=core_context; msg[3]=(u32)&reply_flag; - return i2o_post_wait(c, ADAPTER_TID, msg, sizeof(msg), &reply_flag, 10); + if((ret=i2o_post_wait(c, msg, sizeof(msg), 30))) + printk(KERN_INFO "ExecIopClear failed: %#10x\n", ret); +#ifdef DRIVERDEBUG + else + printk(KERN_INFO "ExecIopClear success!\n"); +#endif + + return ret; } @@ -959,27 +1135,15 @@ static int i2o_reset_controller(struct i2o_controller *c) u8 *work8; u32 *msg; long time; - struct i2o_controller *iop; - /* First stop external operations */ - for(iop=i2o_controller_chain; iop != NULL; iop=iop->next) - { - /* Quiesce is rejected on hold state */ - if(iop->status != ADAPTER_STATE_HOLD) - { - if(i2o_quiesce_controller(iop)<0) - printk(KERN_INFO "Unable to quiesce iop%d\n", - iop->unit); - else - printk(KERN_DEBUG "%s quiesced\n", iop->name); - } - } +#ifdef DRIVERDEBUG + printk(KERN_INFO "Reseting iop%d\n", c->unit); +#endif - /* Then reset the IOP */ + /* Get a message */ m=i2o_wait_message(c, "AdapterReset"); - if(m==0xFFFFFFFF) + if(m==0xFFFFFFFF) return -ETIMEDOUT; - msg=(u32 *)(c->mem_offset+m); work8=(void *)kmalloc(4, GFP_KERNEL); @@ -999,12 +1163,16 @@ static int i2o_reset_controller(struct i2o_controller *c) msg[6]=virt_to_phys(work8); msg[7]=0; /* 64bit host FIXME */ + /* Then reset the IOP */ i2o_post_message(c,m); /* Wait for a reply */ time=jiffies; - while(work8[0]==0x01) +#ifdef DRIVERDEBUG + printk(KERN_INFO "Reset posted, waiting...\n"); +#endif + while(work8[0]==0) { if((jiffies-time)>=5*HZ) { @@ -1016,8 +1184,41 @@ static int i2o_reset_controller(struct i2o_controller *c) barrier(); } - if (work8[0]==0x02) - printk(KERN_WARNING "IOP Reset rejected\n"); + if (work8[0]==0x02) + { + printk(KERN_WARNING "IOP Reset rejected\n"); + } + else + { + /* + * Once the reset is sent, the IOP goes into the INIT state + * which is inditerminate. We need to wait until the IOP + * has rebooted before we can let the system talk to + * it. We read the inbound Free_List until a message is + * available. If we can't read one in the given ammount of + * time, we assume the IOP could not reboot properly. + */ +#ifdef DRIVERDEBUG + printk(KERN_INFO "Reset succeeded...waiting for reboot\n"); +#endif + time = jiffies; + m = I2O_POST_READ32(c); + while(m == 0XFFFFFFFF) + { + if((jiffies-time) >= 30*HZ) + { + printk(KERN_ERR "i2o/iop%d: Timeout waiting for IOP reset.\n", + c->unit); + return -ETIMEDOUT; + } + schedule(); + barrier(); + m = I2O_POST_READ32(c); + } +#ifdef DRIVERDEBUG + printk(KERN_INFO "Reboot completed\n"); +#endif + } return 0; } @@ -1030,13 +1231,24 @@ int i2o_status_get(struct i2o_controller *c) u32 *msg; u8 *status_block; - status_block=(void *)kmalloc(88, GFP_KERNEL); - if(status_block==NULL) +#ifdef DRIVERDEBUG + printk(KERN_INFO "Getting status block for iop%d\n", c->unit); +#endif + if(c->status_block) + kfree(c->status_block); + + c->status_block = + (pi2o_status_block)kmalloc(sizeof(i2o_status_block),GFP_KERNEL); + if(c->status_block == NULL) { - printk(KERN_ERR "StatusGet failed - no free memory.\n"); +#ifdef DRIVERDEBUG + printk(KERN_ERR "No memory in status get!\n"); +#endif return -ENOMEM; } + status_block = (u8*)c->status_block; + m=i2o_wait_message(c, "StatusGet"); if(m==0xFFFFFFFF) return -ETIMEDOUT; @@ -1049,7 +1261,7 @@ int i2o_status_get(struct i2o_controller *c) msg[3]=0; msg[4]=0; msg[5]=0; - msg[6]=virt_to_phys(status_block); + msg[6]=virt_to_phys(c->status_block); msg[7]=0; /* 64bit host FIXME */ msg[8]=88; @@ -1062,7 +1274,9 @@ int i2o_status_get(struct i2o_controller *c) { if((jiffies-time)>=5*HZ) { +#ifdef DRIVERDEBUG printk(KERN_ERR "IOP get status timeout.\n"); +#endif return -ETIMEDOUT; } schedule(); @@ -1070,8 +1284,6 @@ int i2o_status_get(struct i2o_controller *c) } /* Ok the reply has arrived. Fill in the important stuff */ - c->status = status_block[10]; - c->i2oversion = (status_block[9]>>4)&0xFF; c->inbound_size = (status_block[12]|(status_block[13]<<8))*4; return 0; @@ -1080,8 +1292,10 @@ int i2o_status_get(struct i2o_controller *c) int i2o_hrt_get(struct i2o_controller *c) { - u32 m; - u32 *msg; + u32 msg[6]; + + if(c->hrt) + kfree(c->hrt); c->hrt=kmalloc(2048, GFP_KERNEL); if(c->hrt==NULL) @@ -1090,12 +1304,6 @@ int i2o_hrt_get(struct i2o_controller *c) return -ENOMEM; } - m=i2o_wait_message(c, "HRTGet"); - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - - msg=(u32 *)(c->mem_offset+m); - msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4; msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID; msg[2]= core_context; @@ -1103,26 +1311,200 @@ int i2o_hrt_get(struct i2o_controller *c) msg[4]= (0xD0000000 | 2048); /* Simple transaction , 2K */ msg[5]= virt_to_phys(c->hrt); /* Dump it here */ - i2o_post_message(c,m); + return i2o_post_wait(c, msg, sizeof(msg), 20); +} - barrier(); +static int i2o_systab_send(struct i2o_controller* iop) +{ + u32 msg[10]; + u32 privmem[2]; + u32 privio[2]; + int ret; - /* Now wait for a reply */ - m=i2o_wait_reply(c, "HRTGet", 5); + privmem[0]=iop->priv_mem; /* Private memory space base address */ + privmem[1]=iop->priv_mem_size; + privio[0]=iop->priv_io; /* Private I/O address */ + privio[1]=iop->priv_io_size; - if(m==0xFFFFFFFF) - return -ETIMEDOUT; + msg[0] = NINE_WORD_MSG_SIZE|SGL_OFFSET_6; + msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID; + msg[2] = 0; /* Context not needed */ + msg[3] = 0; + msg[4] = (0<<16)|((iop->unit+2)<<12); /* Host 0 IOP ID (unit + 2) */ + msg[5] = 0; /* Segment 0 */ + + /* + * Scatter Gather List + */ + msg[6] = 0x54000000|sys_tbl_len; + msg[7] = virt_to_phys(sys_tbl); + msg[8] = 0xD4000000|48; /* One table for now */ + msg[9] = virt_to_phys(privmem); +/* msg[10] = virt_to_phys(privio); */ - msg=(u32 *)bus_to_virt(m); + ret=i2o_post_wait(iop, msg, sizeof(msg), 120); + if(ret) + return ret; - if(msg[4]>>24) - i2o_report_status(KERN_WARNING, "i2o_core", msg); + return 0; +} - I2O_REPLY_WRITE32(c,m); +/* + * Initialize I2O subsystem. + */ +static void __init i2o_sys_init() +{ + struct i2o_controller *iop; + int ret; + u32 m; - return 0; + printk(KERN_INFO "Activating I2O controllers\n"); + printk(KERN_INFO "This may take a few minutes if there are many devices\n"); + + /* Get the status for each IOP */ + for(iop = i2o_controller_chain; iop; iop = iop->next) + { +#ifdef DRIVERDEBUG + printk(KERN_INFO "Getting initial status for iop%d\n", iop->unit); +#endif + i2o_status_get(iop); + + if(iop->status_block->iop_state == ADAPTER_STATE_FAULTED) + { + printk(KERN_CRIT "i2o: iop%d has hardware fault\n", + iop->unit); + i2o_delete_controller(iop); + } + + if(iop->status_block->iop_state == ADAPTER_STATE_HOLD || + iop->status_block->iop_state == ADAPTER_STATE_READY || + iop->status_block->iop_state == ADAPTER_STATE_OPERATIONAL || + iop->status_block->iop_state == ADAPTER_STATE_FAILED) + { + int msg[256]; + +#ifdef DRIVERDEBUG + printk(KERN_INFO "iop%d already running...trying to reboot", + iop->unit); +#endif + i2o_init_outbound_q(iop); + I2O_REPLY_WRITE32(iop,virt_to_phys(msg)); + i2o_quiesce_controller(iop); + i2o_reset_controller(iop); + i2o_status_get(iop); + } + } + + /* + * Now init the outbound queue for each one. + */ + for(iop = i2o_controller_chain; iop; iop = iop->next) + { + int i; + + if((ret=i2o_init_outbound_q(iop))) + { + printk(KERN_ERR + "IOP%d initialization failed: Could not initialize outbound q\n", + iop->unit); + i2o_delete_controller(iop); + } + iop->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL); + + if(iop->page_frame==NULL) + { + printk(KERN_ERR "IOP init failed: no memory for message page.\n"); + i2o_delete_controller(iop); + continue; + } + + m=virt_to_phys(iop->page_frame); + + for(i=0; i< NMBR_MSG_FRAMES; i++) + { + I2O_REPLY_WRITE32(iop,m); + mb(); + m+=MSG_FRAME_SIZE; + mb(); + } + } + + /* + * OK..parse the HRT + */ + for(iop = i2o_controller_chain; iop; iop = iop->next) + { + if(i2o_hrt_get(iop)) + { + i2o_delete_controller(iop); + break; + } + if(i2o_parse_hrt(iop)) + i2o_delete_controller(iop); + } + + /* + * Build and send the system table + */ + i2o_build_sys_table(); + for(iop = i2o_controller_chain; iop; iop = iop->next) +#ifdef DRIVERDEBUG + { + printk(KERN_INFO "Sending system table to iop%d\n", iop->unit); +#endif + i2o_systab_send(iop); +#ifdef DRIVERDEBUG + } +#endif + + /* + * Enable + */ + for(iop = i2o_controller_chain; iop; iop = iop->next) + { +#ifdef DRIVERDEBUG + printk(KERN_INFO "Enableing iop%d\n", iop->unit); +#endif + if(i2o_enable_controller(iop)) + { + printk(KERN_ERR "Could not enable iop%d\n", iop->unit); + i2o_delete_controller(iop); + } + } + + /* + * OK..one last thing and we're ready to go! + */ + for(iop = i2o_controller_chain; iop; iop = iop->next) + { +#ifdef DRIVERDEBUG + printk(KERN_INFO "Getting LCT for iop%d\n", iop->unit); +#endif + if(i2o_lct_get(iop)) + { + printk(KERN_ERR "Could not get LCT from iop%d\n", iop->unit); + i2o_delete_controller(iop); + } + else + i2o_parse_lct(iop); + } } +/* + * Shutdown I2O system + * + * 1. Quiesce all controllers + * 2. Delete all controllers + * + */ +static void i2o_sys_shutdown(void) +{ + struct i2o_controller *iop = NULL; + + i2o_quiesce_system(); + for(iop = i2o_controller_chain; iop; iop = iop->next) + i2o_delete_controller(iop); +} /* * Bring an I2O controller into HOLD state. See the 1.5 @@ -1141,13 +1523,11 @@ int i2o_hrt_get(struct i2o_controller *c) * * Send GetHRT, Parse it */ - int i2o_activate_controller(struct i2o_controller *c) { - long time; + return 0; +#ifdef I2O_HOTPLUG_SUPPORT u32 m; - u8 *workspace; - u32 *msg; int i; int ret; @@ -1157,7 +1537,8 @@ int i2o_activate_controller(struct i2o_controller *c) if((ret=i2o_status_get(c))) return ret; - if(c->status == ADAPTER_STATE_FAULTED) /* not likely to be seen */ + /* not likely to be seen */ + if(c->status_block->iop_state == ADAPTER_STATE_FAULTED) { printk(KERN_CRIT "i2o: iop%d has hardware fault\n", c->unit); @@ -1165,14 +1546,22 @@ int i2o_activate_controller(struct i2o_controller *c) } /* - * If the board is running, reset it - we have no idea - * what kind of a mess the previous owner left it in. + * If the board is running, reset it - we have no idea + * what kind of a mess the previous owner left it in. + * We need to feed the IOP a single outbound message + * so that it can reply back to the ExecSysQuiesce. */ - if(c->status == ADAPTER_STATE_HOLD || - c->status == ADAPTER_STATE_READY || - c->status == ADAPTER_STATE_OPERATIONAL || - c->status == ADAPTER_STATE_FAILED) + if(c->status_block->iop_state == ADAPTER_STATE_HOLD || + c->status_block->iop_state == ADAPTER_STATE_READY || + c->status_block->iop_state == ADAPTER_STATE_OPERATIONAL || + c->status_block->iop_state == ADAPTER_STATE_FAILED) { + int msg[256]; + printk(KERN_INFO "i2o/iop%d already running, reseting\n", c->unit); + + if(i2o_init_outbound_q(c)); + I2O_REPLY_WRITE32(c,virt_to_phys(msg)); + if((ret=i2o_reset_controller(c))) return ret; @@ -1180,15 +1569,62 @@ int i2o_activate_controller(struct i2o_controller *c) return ret; } - workspace = (void *)kmalloc(88, GFP_KERNEL); - if(workspace==NULL) + if((ret=i2o_init_outbound_q(c))) + { + printk(KERN_ERR + "IOP%d initialization failed: Could not initialize outbound queue\n", + c->unit); + return ret; + } + + /* TODO: v2.0: Set Executive class group 000Bh - OS Operating Info */ + + c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL); + if(c->page_frame==NULL) { - printk(KERN_ERR "IOP initialisation failed - no free memory.\n"); + printk(KERN_ERR "IOP init failed: no memory for message page.\n"); return -ENOMEM; } + + m=virt_to_phys(c->page_frame); + + for(i=0; i< NMBR_MSG_FRAMES; i++) + { + I2O_REPLY_WRITE32(c,m); + mb(); + m+=MSG_FRAME_SIZE; + mb(); + } + + /* + * The outbound queue is initialised and loaded, + * + * Now we need the Hardware Resource Table. We must ask for + * this next we can't issue random messages yet. + */ + ret=i2o_hrt_get(c); if(ret) return ret; + + ret=i2o_parse_hrt(c); + if(ret) + return ret; + + return i2o_online_controller(c); +#endif +} + +/* + * Clear and (re)initialize IOP's outbound queue + */ +int i2o_init_outbound_q(struct i2o_controller *c) +{ + u8 workspace[88]; + u32 m; + u32 *msg; + u32 time; memset(workspace, 0, 88); + printk(KERN_INFO "i2o/iop%d: Initializing Outbound Queue\n", c->unit); m=i2o_wait_message(c, "OutboundInit"); if(m==0xFFFFFFFF) { @@ -1211,7 +1647,6 @@ int i2o_activate_controller(struct i2o_controller *c) /* * Post it */ - i2o_post_message(c,m); barrier(); @@ -1222,7 +1657,8 @@ int i2o_activate_controller(struct i2o_controller *c) { if((jiffies-time)>=5*HZ) { - printk(KERN_ERR "IOP outbound initialise failed.\n"); + printk(KERN_ERR "i2o/iop%d: IOP outbound initialise failed.\n", + c->unit); kfree(workspace); return -ETIMEDOUT; } @@ -1230,64 +1666,28 @@ int i2o_activate_controller(struct i2o_controller *c) barrier(); } - kfree(workspace); - - /* TODO: v2.0: Set Executive class group 000Bh - OS Operating Info */ - - c->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL); - if(c->page_frame==NULL) - { - printk(KERN_ERR "IOP init failed: no memory for message page.\n"); - return -ENOMEM; - } - - m=virt_to_phys(c->page_frame); - - for(i=0; i< NMBR_MSG_FRAMES; i++) - { - I2O_REPLY_WRITE32(c,m); - mb(); - m+=MSG_FRAME_SIZE; - } - - /* - * The outbound queue is initialised and loaded, - * - * Now we need the Hardware Resource Table. We must ask for - * this next we can't issue random messages yet. - */ - ret=i2o_hrt_get(c); - if(ret) - return ret; - - ret=i2o_parse_hrt(c); - if(ret) - return ret; - - return i2o_online_controller(c); -// i2o_report_controller_unit(c, ADAPTER_TID); + return 0; } - +/* + * Get the IOP's Logical Configuration Table + */ int i2o_lct_get(struct i2o_controller *c) { - u32 m; - u32 *msg; + u32 msg[8]; - m=i2o_wait_message(c, "LCTNotify"); - - if(m==0xFFFFFFFF) - return -ETIMEDOUT; +#ifdef DRIVERDEBUG + printk(KERN_INFO "Getting lct for iop%d\n", c->unit); +#endif - msg=(u32 *)(c->mem_offset+m); + if(c->lct) + kfree(c->lct); c->lct = kmalloc(8192, GFP_KERNEL); if(c->lct==NULL) { - msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1]= HOST_TID<<12|ADAPTER_TID; /* NOP */ - i2o_post_message(c,m); - printk(KERN_ERR "No free memory for i2o controller buffer.\n"); + printk(KERN_ERR "i2o/iop%d: No free memory for i2o controller buffer.\n", + c->unit); return -ENOMEM; } @@ -1302,25 +1702,8 @@ int i2o_lct_get(struct i2o_controller *c) msg[6] = 0xD0000000|8192; msg[7] = virt_to_bus(c->lct); - i2o_post_message(c,m); - - barrier(); - - /* Now wait for a reply */ - m=i2o_wait_reply(c, "LCTNotify", 5); - - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - - msg=(u32 *)bus_to_virt(m); - - /* TODO: Check TableSize for big LCTs and send new ExecLctNotify - * with bigger workspace */ - - if(msg[4]>>24) - i2o_report_status(KERN_ERR, "i2o_core", msg); - - return 0; + + return(i2o_post_wait(c, msg, sizeof(msg), 120)); } @@ -1330,13 +1713,14 @@ int i2o_lct_get(struct i2o_controller *c) int i2o_online_controller(struct i2o_controller *c) { - u32 m; - u32 *msg; - u32 systab[32]; + return 0; +#ifdef I2O_HOTPLUG_SUPPORT + u32 msg[10]; u32 privmem[2]; u32 privio[2]; + u32 systab[32]; int ret; - + systab[0]=1; systab[1]=0; systab[2]=0; @@ -1350,103 +1734,45 @@ int i2o_online_controller(struct i2o_controller *c) systab[10]=virt_to_phys(c->post_port); systab[11]=0; + i2o_build_sys_table(); + privmem[0]=c->priv_mem; /* Private memory space base address */ privmem[1]=c->priv_mem_size; privio[0]=c->priv_io; /* Private I/O address */ privio[1]=c->priv_io_size; - - m=i2o_wait_message(c, "SysTabSet"); - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - - /* Now we build the systab */ - msg=(u32 *)(c->mem_offset+m); - + msg[0] = NINE_WORD_MSG_SIZE|SGL_OFFSET_6; msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID; msg[2] = 0; /* Context not needed */ msg[3] = 0; - msg[4] = (1<<16)|(2<<12); /* Host 1 I2O 2 */ - msg[5] = 1; /* Segment 1 */ + msg[4] = (0<<16)|(2<<12); /* Host 1 I2O 2 */ + msg[5] = 0; /* Segment 1 */ /* * Scatter Gather List */ - - msg[6] = 0x54000000|48; /* One table for now */ - msg[7] = virt_to_phys(systab); + msg[6] = 0x54000000|sys_tbl_len; /* One table for now */ + msg[7] = virt_to_phys(sys_tbl); msg[8] = 0xD4000000|48; /* One table for now */ msg[9] = virt_to_phys(privmem); -/* msg[10] = virt_to_phys(privio); */ - - i2o_post_message(c,m); +/* msg[10] = virt_to_phys(privio); */ - barrier(); - - /* - * Now wait for a reply - */ - - - m=i2o_wait_reply(c, "SysTabSet", 5); - - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - - msg=(u32 *)bus_to_virt(m); - - if(msg[4]>>24) - { - i2o_report_status(KERN_ERR, "i2o_core", msg); - } - I2O_REPLY_WRITE32(c,m); + return(i2o_post_wait(c, msg, sizeof(msg), 120)); /* * Finally we go online */ - - m=i2o_wait_message(c, "SysEnable"); - - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - - msg=(u32 *)(c->mem_offset+m); - - msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1] = I2O_CMD_SYS_ENABLE<<24 | HOST_TID<<12 | ADAPTER_TID; - msg[2] = 0; /* Context not needed */ - msg[3] = 0; - - i2o_post_message(c,m); - - barrier(); - - /* - * Now wait for a reply - */ - - - m=i2o_wait_reply(c, "SysEnable", 240); - - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - - msg=(u32 *)bus_to_virt(m); - - if(msg[4]>>24) - { - i2o_report_status(KERN_ERR, "i2o_core", msg); - } - I2O_REPLY_WRITE32(c,m); + ret = i2o_enable_controller(c); + if(ret) + return ret; /* * Grab the LCT, see what is attached */ - ret=i2o_lct_get(c); if(ret) { - /* Maybe we should do also sthg else */ + /* Maybe we should do also do something else */ return ret; } @@ -1454,11 +1780,73 @@ int i2o_online_controller(struct i2o_controller *c) if(ret) return ret; - I2O_REPLY_WRITE32(c,m); - return 0; +#endif } +static int i2o_build_sys_table(void) +{ + struct i2o_controller *iop = NULL; + int count = 0; +#ifdef DRIVERDEBUG + u32 *table; +#endif + + sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs + (i2o_num_controllers) * + sizeof(struct i2o_sys_tbl_entry); + +#ifdef DRIVERDEBUG + printk(KERN_INFO "Building system table len = %d\n", sys_tbl_len); +#endif + if(sys_tbl) + kfree(sys_tbl); + + sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL); + if(!sys_tbl) + return -ENOMEM; + memset((void*)sys_tbl, 0, sys_tbl_len); + + sys_tbl->num_entries = i2o_num_controllers; + sys_tbl->version = I2OVERSION; /* TODO: Version 2.0 */ + sys_tbl->change_ind = sys_tbl_ind++; + + for(iop = i2o_controller_chain; iop; iop = iop->next) + { + // Get updated IOP state so we have the latest information + i2o_status_get(iop); + + sys_tbl->iops[count].org_id = iop->status_block->org_id; + sys_tbl->iops[count].iop_id = iop->unit + 2; + sys_tbl->iops[count].seg_num = 0; + sys_tbl->iops[count].i2o_version = + iop->status_block->i2o_version; + sys_tbl->iops[count].iop_state = + iop->status_block->iop_state; + sys_tbl->iops[count].msg_type = + iop->status_block->msg_type; + sys_tbl->iops[count].frame_size = + iop->status_block->inbound_frame_size; + sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ?? + sys_tbl->iops[count].iop_capabilities = + iop->status_block->iop_capabilities; + sys_tbl->iops[count].inbound_low = + (u32)virt_to_phys(iop->post_port); + sys_tbl->iops[count].inbound_high = 0; // TODO: 64-bit support + + count++; + } + +#ifdef DRIVERDEBUG + table = (u32*)sys_tbl; + for(count = 0; count < (sys_tbl_len >>2); count++) + printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", count, table[count]); +#endif + + return 0; +} + + /* * Run time support routines */ @@ -1469,11 +1857,11 @@ int i2o_online_controller(struct i2o_controller *c) * this is simply not worth optimising */ -int i2o_post_this(struct i2o_controller *c, int tid, u32 *data, int len) +int i2o_post_this(struct i2o_controller *c, u32 *data, int len) { u32 m; u32 *msg; - unsigned long t=jiffies; + unsigned long t=jiffies; do { @@ -1485,8 +1873,9 @@ int i2o_post_this(struct i2o_controller *c, int tid, u32 *data, int len) if(m==0xFFFFFFFF) { - printk(KERN_ERR "i2o: controller not responding.\n"); - return -1; + printk(KERN_ERR "i2o/iop%d: Timeout waiting for message frame!\n", + c->unit); + return -ETIMEDOUT; } msg = bus_to_virt(c->mem_offset + m); memcpy(msg, data, len); @@ -1495,32 +1884,114 @@ int i2o_post_this(struct i2o_controller *c, int tid, u32 *data, int len) } /* - * Post a message and wait for a response flag to be set. This API will - * change to use wait_queue's one day + * Post a message and wait for a response flag to be set. */ - -int i2o_post_wait(struct i2o_controller *c, int tid, u32 *data, int len, int *flag, int timeout) +int i2o_post_wait(struct i2o_controller *c, u32 *msg, int len, int timeout) { - unsigned long t=jiffies; + DECLARE_WAIT_QUEUE_HEAD(wq_i2o_post); + int status = 0; + int flags = 0; + int ret = 0; + struct i2o_post_wait_data *p1, *p2; + struct i2o_post_wait_data *wait_data = + kmalloc(sizeof(struct i2o_post_wait_data), GFP_KERNEL); + + if(!wait_data) + return -ETIMEDOUT; + + p1 = p2 = NULL; - *flag = 0; - - if(i2o_post_this(c, tid, data, len)) - return I2O_POST_WAIT_TIMEOUT; - - while(!*flag && (jiffies-t)<timeout*HZ) + /* + * The spin locking is needed to keep anyone from playing + * with the queue pointers and id while we do the same + */ + spin_lock_irqsave(&post_wait_lock, flags); + wait_data->next = post_wait_queue; + post_wait_queue = wait_data; + wait_data->id = ++post_wait_id; + spin_unlock_irqrestore(&post_wait_lock, flags); + + wait_data->wq = &wq_i2o_post; + wait_data->status = -ETIMEDOUT; + + msg[3] = (u32)wait_data->id; + msg[2] = 0x80000000|(u32)core_context; + + if((ret=i2o_post_this(c, msg, len))) + return ret; + /* + * Go to sleep and wait for timeout or wake_up call + */ + interruptible_sleep_on_timeout(&wq_i2o_post, HZ * timeout); + + /* + * Grab transaction status + */ + status = wait_data->status; + + /* + * Remove the entry from the queue. + * Since i2o_post_wait() may have been called again by + * a different thread while we were waiting for this + * instance to complete, we're not guaranteed that + * this entry is at the head of the queue anymore, so + * we need to search for it, find it, and delete it. + */ + spin_lock_irqsave(&post_wait_lock, flags); + for(p1 = post_wait_queue; p1; ) { - schedule(); - mb(); + if(p1 == wait_data) + { + if(p2) + p2->next = p1->next; + else + post_wait_queue = p1->next; + + break; + } + p1 = p1->next; } + spin_unlock_irqrestore(&post_wait_lock, flags); + + kfree(wait_data); - if (*flag < 0) - return *flag; /* DetailedStatus */ + return status; +} - if (*flag == 0) - return I2O_POST_WAIT_TIMEOUT; - - return I2O_POST_WAIT_OK; +/* + * i2o_post_wait is completed and we want to wake up the + * sleeping proccess. Called by core's reply handler. + */ +static void i2o_post_wait_complete(u32 context, int status) +{ + struct i2o_post_wait_data *p1 = NULL; + + /* + * We need to search through the post_wait + * queue to see if the given message is still + * outstanding. If not, it means that the IOP + * took longer to respond to the message than we + * had allowed and timer has already expired. + * Not much we can do about that except log + * it for debug purposes, increase timeout, and recompile + * + * Lock needed to keep anyone from moving queue pointers + * around while we're looking through them. + */ + spin_lock(&post_wait_lock); + for(p1 = post_wait_queue; p1; p1 = p1->next) + { + if(p1->id == context) + { + p1->status = status; + wake_up_interruptible(p1->wq); + spin_unlock(&post_wait_lock); + return; + } + } + spin_unlock(&post_wait_lock); + + printk(KERN_DEBUG "i2o_post_wait reply after timeout!"); } /* @@ -1543,7 +2014,7 @@ int i2o_issue_claim(struct i2o_controller *c, int tid, int context, int onoff, i msg[3] = (u32)flag; msg[4] = type; - return i2o_post_wait(c, tid, msg, 20, flag,2); + return i2o_post_wait(c, msg, 20, 2); } /* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET @@ -1554,60 +2025,56 @@ int i2o_issue_claim(struct i2o_controller *c, int tid, int context, int onoff, i * Note that the minimum sized resblk is 8 bytes and contains * ResultCount, ErrorInfoSize, BlockStatus and BlockSize. */ -int i2o_issue_params(int cmd, - struct i2o_controller *iop, int tid, int context, - void *opblk, int oplen, void *resblk, int reslen, - int *flag) +int i2o_issue_params(int cmd, struct i2o_controller *iop, int tid, + void *opblk, int oplen, void *resblk, int reslen) { - u32 msg[9]; +u32 msg[9]; u8 *res = (u8 *)resblk; int res_count; int blk_size; int bytes; int wait_status; - msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5; - msg[1] = cmd << 24 | HOST_TID << 12 | tid; - msg[2] = context | 0x80000000; - msg[3] = (u32)flag; - msg[4] = 0; - msg[5] = 0x54000000 | oplen; /* OperationBlock */ - msg[6] = virt_to_bus(opblk); - msg[7] = 0xD0000000 | reslen; /* ResultBlock */ - msg[8] = virt_to_bus(resblk); - - wait_status = i2o_post_wait(iop, tid, msg, sizeof(msg), flag, 10); - if (wait_status < 0) - return wait_status; /* -DetailedStatus */ - - if (res[1]&0x00FF0000) /* BlockStatus != SUCCESS */ - { - printk(KERN_WARNING "%s - Error:\n ErrorInfoSize = 0x%02x, " - "BlockStatus = 0x%02x, BlockSize = 0x%04x\n", - (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET" - : "PARAMS_GET", - res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF); - return -((res[1] >> 16) & 0xFF); /* -BlockStatus */ - } + msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5; + msg[1] = cmd << 24 | HOST_TID << 12 | tid; + msg[4] = 0; + msg[5] = 0x54000000 | oplen; /* OperationBlock */ + msg[6] = virt_to_bus(opblk); + msg[7] = 0xD0000000 | reslen; /* ResultBlock */ + msg[8] = virt_to_bus(resblk); + + wait_status = i2o_post_wait(iop, msg, sizeof(msg), 10); + if (wait_status) + return wait_status; /* -DetailedStatus */ - res_count = res[0] & 0xFFFF; /* # of resultblocks */ - bytes = 4; - res += 4; - while (res_count--) + if (res[1]&0x00FF0000) /* BlockStatus != SUCCESS */ + { + printk(KERN_WARNING "%s - Error:\n ErrorInfoSize = 0x%02x, " + "BlockStatus = 0x%02x, BlockSize = 0x%04x\n", + (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET" + : "PARAMS_GET", + res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF); + return -((res[1] >> 16) & 0xFF); /* -BlockStatus */ + } + + res_count = res[0] & 0xFFFF; /* # of resultblocks */ + bytes = 4; + res += 4; + while (res_count--) { blk_size = (res[0] & 0xFFFF) << 2; bytes += blk_size; res += blk_size; } - - return bytes; /* total sizeof Result List in bytes */ + + return bytes; /* total sizeof Result List in bytes */ } /* * Query one scalar group value or a whole scalar group. */ -int i2o_query_scalar(struct i2o_controller *iop, int tid, int context, - int group, int field, void *buf, int buflen, int *flag) +int i2o_query_scalar(struct i2o_controller *iop, int tid, + int group, int field, void *buf, int buflen) { u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; u8 resblk[8+buflen]; /* 8 bytes for header */ @@ -1616,8 +2083,8 @@ int i2o_query_scalar(struct i2o_controller *iop, int tid, int context, if (field == -1) /* whole group */ opblk[4] = -1; - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, iop, tid, context, - opblk, sizeof(opblk), resblk, sizeof(resblk), flag); + size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, iop, tid, + opblk, sizeof(opblk), resblk, sizeof(resblk)); if (size < 0) return size; @@ -1629,38 +2096,38 @@ int i2o_query_scalar(struct i2o_controller *iop, int tid, int context, /* * Set a scalar group value or a whole group. */ -int i2o_set_scalar(struct i2o_controller *iop, int tid, int context, - int group, int field, void *buf, int buflen, int *flag) +int i2o_set_scalar(struct i2o_controller *iop, int tid, + int group, int field, void *buf, int buflen) { u16 *opblk; u8 resblk[8+buflen]; /* 8 bytes for header */ int size; - opblk = kmalloc(buflen+64, GFP_KERNEL); - if (opblk == NULL) - { - printk(KERN_ERR "i2o: no memory for operation buffer.\n"); - return -ENOMEM; - } + opblk = kmalloc(buflen+64, GFP_KERNEL); + if (opblk == NULL) + { + printk(KERN_ERR "i2o: no memory for operation buffer.\n"); + return -ENOMEM; + } - opblk[0] = 1; /* operation count */ - opblk[1] = 0; /* pad */ - opblk[2] = I2O_PARAMS_FIELD_SET; - opblk[3] = group; + opblk[0] = 1; /* operation count */ + opblk[1] = 0; /* pad */ + opblk[2] = I2O_PARAMS_FIELD_SET; + opblk[3] = group; - if(field == -1) { /* whole group */ - opblk[4] = -1; - memcpy(opblk+5, buf, buflen); - } - else /* single field */ - { - opblk[4] = 1; - opblk[5] = field; - memcpy(opblk+6, buf, buflen); - } + if(field == -1) { /* whole group */ + opblk[4] = -1; + memcpy(opblk+5, buf, buflen); + } + else /* single field */ + { + opblk[4] = 1; + opblk[5] = field; + memcpy(opblk+6, buf, buflen); + } - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, - opblk, 12+buflen, resblk, sizeof(resblk), flag); + size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, + opblk, 12+buflen, resblk, sizeof(resblk)); kfree(opblk); return size; @@ -1687,10 +2154,9 @@ int i2o_set_scalar(struct i2o_controller *iop, int tid, int context, * * You could also use directly function i2o_issue_params(). */ -int i2o_query_table(int oper, - struct i2o_controller *iop, int tid, int context, int group, +int i2o_query_table(int oper, struct i2o_controller *iop, int tid, int group, int fieldcount, void *ibuf, int ibuflen, - void *resblk, int reslen, int *flag) + void *resblk, int reslen) { u16 *opblk; int size; @@ -1709,8 +2175,8 @@ int i2o_query_table(int oper, opblk[4] = fieldcount; memcpy(opblk+5, ibuf, ibuflen); /* other params */ - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET,iop, tid, context, - opblk, 10+ibuflen, resblk, reslen, flag); + size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET,iop, tid, + opblk, 10+ibuflen, resblk, reslen); kfree(opblk); return size; @@ -1720,14 +2186,13 @@ int i2o_query_table(int oper, * Clear table group, i.e. delete all rows. */ -int i2o_clear_table(struct i2o_controller *iop, int tid, int context, - int group, int *flag) +int i2o_clear_table(struct i2o_controller *iop, int tid, int group) { u16 opblk[] = { 1, 0, I2O_PARAMS_TABLE_CLEAR, group }; u8 resblk[32]; /* min 8 bytes for result header */ - return i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, - opblk, sizeof(opblk), resblk, sizeof(resblk), flag); + return i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, + opblk, sizeof(opblk), resblk, sizeof(resblk)); } /* @@ -1739,9 +2204,8 @@ int i2o_clear_table(struct i2o_controller *iop, int tid, int context, * buf contains fieldindexes, rowcount, keyvalues */ -int i2o_row_add_table(struct i2o_controller *iop, int tid, int context, - int group, int fieldcount, void *buf, int buflen, - int *flag) +int i2o_row_add_table(struct i2o_controller *iop, int tid, + int group, int fieldcount, void *buf, int buflen) { u16 *opblk; u8 resblk[32]; /* min 8 bytes for header */ @@ -1761,8 +2225,8 @@ int i2o_row_add_table(struct i2o_controller *iop, int tid, int context, opblk[4] = fieldcount; memcpy(opblk+5, buf, buflen); - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, - opblk, 10+buflen, resblk, sizeof(resblk), flag); + size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, + opblk, 10+buflen, resblk, sizeof(resblk)); kfree(opblk); return size; @@ -1772,9 +2236,8 @@ int i2o_row_add_table(struct i2o_controller *iop, int tid, int context, * Delete rows from a table group. */ -int i2o_row_delete_table(struct i2o_controller *iop, int tid, int context, - int group, int keycount, void *keys, int keyslen, - int *flag) +int i2o_row_delete_table(struct i2o_controller *iop, int tid, + int group, int keycount, void *keys, int keyslen) { u16 *opblk; u8 resblk[32]; /* min 8 bytes for header */ @@ -1794,8 +2257,8 @@ int i2o_row_delete_table(struct i2o_controller *iop, int tid, int context, opblk[4] = keycount; memcpy(opblk+5, keys, keyslen); - size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, context, - opblk, 10+keyslen, resblk, sizeof(resblk), flag); + size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_SET, iop, tid, + opblk, 10+keyslen, resblk, sizeof(resblk)); kfree(opblk); return size; @@ -2134,9 +2597,10 @@ static void i2o_dump_message(u32 *msg) #ifdef DRIVERDEBUG int i; - printk(KERN_INFO "Dumping I2O message @ %p\n", msg); + printk(KERN_INFO "Dumping I2O message size %d @ %p\n", + msg[0]>>16&0xffff, msg); for(i = 0; i < ((msg[0]>>16)&0xffff); i++) - printk(KERN_INFO "\tmsg[%d] = %#10x\n", i, msg[i]); + printk(KERN_INFO " msg[%d] = %0#10x\n", i, msg[i]); #endif } @@ -2181,27 +2645,35 @@ MODULE_DESCRIPTION("I2O Core"); int init_module(void) { + printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n"); if (i2o_install_handler(&i2o_core_handler) < 0) { - printk(KERN_ERR "i2o_core: Unable to install core handler.\n"); + printk(KERN_ERR + "i2o_core: Unable to install core handler.\nI2O stack not loaded!"); return 0; } core_context = i2o_core_handler.context; /* - * Attach core to I2O PCI subsystem + * Attach core to I2O PCI transport (and others as they are developed) */ #ifdef CONFIG_I2O_PCI_MODULE if(i2o_pci_core_attach(&i2o_core_functions) < 0) printk(KERN_INFO "No PCI I2O controllers found\n"); #endif + if(i2o_num_controllers) + i2o_sys_init(); + return 0; } void cleanup_module(void) { + if(i2o_num_controllers) + i2o_sys_shutdown(); + #ifdef CONFIG_I2O_PCI_MODULE i2o_pci_core_detach(); #endif @@ -2220,16 +2692,23 @@ extern int i2o_scsi_init(void); int __init i2o_init(void) { - if (i2o_install_handler(&i2o_core_handler) < 0) - { - printk(KERN_ERR "i2o_core: Unable to install core handler.\n"); - return 0; - } + printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n"); + if (i2o_install_handler(&i2o_core_handler) < 0) + { + printk(KERN_ERR + "i2o_core: Unable to install core handler.\nI2O stack not loaded!"); + return 0; + } + + core_context = i2o_core_handler.context; - core_context = i2o_core_handler.context; #ifdef CONFIG_I2O_PCI i2o_pci_init(); #endif + + if(i2o_num_controllers) + i2o_init(); + i2o_config_init(); #ifdef CONFIG_I2O_BLOCK i2o_block_init(); diff --git a/drivers/i2o/i2o_lan.c b/drivers/i2o/i2o_lan.c index 087ee84bd..60798606a 100644 --- a/drivers/i2o/i2o_lan.c +++ b/drivers/i2o/i2o_lan.c @@ -302,7 +302,7 @@ static int i2o_lan_receive_post(struct net_device *dev, u32 count) : count - total; msg[0] = I2O_MESSAGE_SIZE(4 + 3 * bucket_count) | SGL_OFFSET_4; - msg[1] = LAN_RECEIVE_POST<<24 | HOST_TID<<12 | i2o_dev->id; + msg[1] = LAN_RECEIVE_POST<<24 | HOST_TID<<12 | i2o_dev->lct_data->tid; msg[2] = priv->unit << 16 | lan_context; // InitiatorContext msg[3] = bucket_count; // BucketCount @@ -343,12 +343,12 @@ static int i2o_lan_reset(struct net_device *dev) u32 msg[5]; msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0; - msg[1] = LAN_RESET<<24 | HOST_TID<<12 | i2o_dev->id; + msg[1] = LAN_RESET<<24 | HOST_TID<<12 | i2o_dev->lct_data->tid; msg[2] = priv->unit << 16 | lan_context; // InitiatorContext msg[3] = 0; // TransactionContext msg[4] = 1 << 16; // return posted buckets - if (i2o_post_this(iop, i2o_dev->id, msg, sizeof(msg)) < 0) + if (i2o_post_this(iop, msg, sizeof(msg)) < 0) return -ETIMEDOUT; return 0; @@ -368,12 +368,12 @@ static int i2o_lan_suspend(struct net_device *dev) dprintk( "%s: LAN SUSPEND MESSAGE\n", dev->name ); msg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0; - msg[1] = LAN_SUSPEND<<24 | HOST_TID<<12 | i2o_dev->id; + msg[1] = LAN_SUSPEND<<24 | HOST_TID<<12 | i2o_dev->lct_data->tid; msg[2] = priv->unit << 16 | lan_context; // InitiatorContext msg[3] = 0; // TransactionContext msg[4] = 1 << 16; // return posted buckets - if (i2o_post_this(iop, i2o_dev->id, msg, sizeof(msg)) < 0) + if (i2o_post_this(iop, msg, sizeof(msg))< 0) return -ETIMEDOUT; return 0; @@ -400,8 +400,7 @@ static void i2o_set_batch_mode(struct net_device *dev) // enable batch mode, toggle automatically val = 0x00000000; // val = 0x00000001; // turn off batch mode - if (i2o_set_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0003, 0, - &val, 4, &priv->reply_flag) <0) + if (i2o_set_scalar(iop, i2o_dev->lct_data->tid, 0x0003, 0, &val, 4) < 0) printk(KERN_WARNING "Unable to enter I2O LAN batch mode.\n"); else dprintk(KERN_INFO "%s: I2O LAN batch mode enabled.\n",dev->name); @@ -414,8 +413,7 @@ static void i2o_set_batch_mode(struct net_device *dev) /* set LAN_OPERATION attributes */ val = dev->mtu + dev->hard_header_len; // PacketOrphanLimit - if (i2o_set_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0004, 2, - &val, 4, &priv->reply_flag) < 0) + if (i2o_set_scalar(iop, i2o_dev->lct_data->tid, 0x0004, 2, &val, 4)) printk(KERN_WARNING "i2o_lan: Unable to set PacketOrphanLimit.\n"); else dprintk(KERN_INFO "%s: PacketOrphanLimit set to %d\n", @@ -438,7 +436,7 @@ static int i2o_lan_open(struct net_device *dev) printk(KERN_WARNING "%s: Unable to claim the I2O LAN device.\n", dev->name); return -EAGAIN; } - dprintk(KERN_INFO "%s: I2O LAN device claimed (tid=%d).\n", dev->name, i2o_dev->id); + dprintk(KERN_INFO "%s: I2O LAN device claimed (tid=%d).\n", dev->name, i2o_dev->lct_data->tid); i2o_lan_reset(dev); @@ -467,7 +465,7 @@ static int i2o_lan_close(struct net_device *dev) if(i2o_release_device(i2o_dev, &i2o_lan_handler, I2O_CLAIM_PRIMARY)) printk(KERN_WARNING "%s: Unable to unclaim I2O LAN device " - "(tid=%d)\n", dev->name, i2o_dev->id); + "(tid=%d)\n", dev->name, i2o_dev->lct_data->tid); MOD_DEC_USE_COUNT; @@ -521,7 +519,7 @@ static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev) msg = bus_to_virt(iop->mem_offset + m); msg[0] = SEVEN_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4; - msg[1] = LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->id; + msg[1] = LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data->tid; msg[2] = priv->unit << 16 | lan_context; // IntiatorContext msg[3] = 1 << 4; // TransmitControlWord @@ -554,8 +552,8 @@ static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev) u64 val64[16]; u64 supported_group[4] = { 0, 0, 0, 0 }; - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0100, -1, - val64, sizeof(val64), &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0100, -1, + val64, sizeof(val64)) < 0) printk("%s: Unable to query LAN_HISTORICAL_STATS.\n",dev->name); else { dprintk("%s: LAN_HISTORICAL_STATS queried.\n",dev->name); @@ -568,13 +566,13 @@ static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev) priv->stats.rx_dropped = val64[6]; } - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0180, -1, - &supported_group, sizeof(supported_group), &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0180, -1, + &supported_group, sizeof(supported_group)) < 0) printk("%s: Unable to query LAN_SUPPORTED_OPTIONAL_HISTORICAL_STATS.\n",dev->name); if (supported_group[2]) { - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0183, -1, - val64, sizeof(val64), &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0183, -1, + val64, sizeof(val64) ) < 0) printk("%s: Unable to query LAN_OPTIONAL_RX_HISTORICAL_STATS.\n",dev->name); else { dprintk("%s: LAN_OPTIONAL_RX_HISTORICAL_STATS queried.\n",dev->name); @@ -584,12 +582,12 @@ static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev) } } - if (i2o_dev->subclass == I2O_LAN_ETHERNET) + if (i2o_dev->lct_data->sub_class == I2O_LAN_ETHERNET) { u64 supported_stats = 0; - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0200, -1, - val64, sizeof(val64), &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0200, -1, + val64, sizeof(val64)) < 0) printk("%s: Unable to query LAN_802_3_HISTORICAL_STATS.\n",dev->name); else { dprintk("%s: LAN_802_3_HISTORICAL_STATS queried.\n",dev->name); @@ -598,13 +596,13 @@ static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev) priv->stats.tx_carrier_errors = val64[6]; } - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0280, -1, - &supported_stats, 8, &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0280, -1, + &supported_stats, 8) < 0) printk("%s: Unable to query LAN_SUPPORTED_802_3_HISTORICAL_STATS\n", dev->name); if (supported_stats != 0) { - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0281, -1, - val64, sizeof(val64), &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0281, -1, + val64, sizeof(val64)) < 0) printk("%s: Unable to query LAN_OPTIONAL_802_3_HISTORICAL_STATS.\n",dev->name); else { dprintk("%s: LAN_OPTIONAL_802_3_HISTORICAL_STATS queried.\n",dev->name); @@ -618,10 +616,10 @@ static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev) } #ifdef CONFIG_TR - if (i2o_dev->subclass == I2O_LAN_TR) + if (i2o_dev->lct_data->sub_class == I2O_LAN_TR) { - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0300, -1, - val64, sizeof(val64), &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0300, -1, + val64, sizeof(val64)) < 0) printk("%s: Unable to query LAN_802_5_HISTORICAL_STATS.\n",dev->name); else { struct tr_statistics *stats = @@ -644,10 +642,10 @@ static struct net_device_stats *i2o_lan_get_stats(struct net_device *dev) #endif #ifdef CONFIG_FDDI - if (i2o_dev->subclass == I2O_LAN_FDDI) + if (i2o_dev->lct_data->sub_class == I2O_LAN_FDDI) { - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0400, -1, - val64, sizeof(val64), &priv->reply_flag) < 0) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0400, -1, + val64, sizeof(val64)) < 0) printk("%s: Unable to query LAN_FDDI_HISTORICAL_STATS.\n",dev->name); else { // dprintk("%s: LAN_FDDI_HISTORICAL_STATS queried.\n",dev->name); @@ -691,8 +689,8 @@ return; * *because its trying to sleep in an irq - this must be async - Alan */ - if (i2o_query_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0001, -1, - &work32, sizeof(work32), &priv->reply_flag) < 0 ) + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0001, -1, + &work32, sizeof(work32)) < 0) { printk(KERN_WARNING "i2o_lan: Unable to query " " LAN_MAC_ADDRESS table.\n"); @@ -734,12 +732,11 @@ return; mclist = mclist->next; } - if (i2o_clear_table(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0002, - &priv->reply_flag) < 0 ) + if (i2o_clear_table(iop, i2o_dev->lct_data->tid, 0x0002) < 0) dprintk("%s: Unable to clear LAN_MULTICAST_MAC_ADDRESS table.\n",dev->name); - if (i2o_row_add_table(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0002, -1, - work32, dev->mc_count*8, &priv->reply_flag) < 0) + if (i2o_row_add_table(iop, i2o_dev->lct_data->tid, 0x0002, -1, + work32, dev->mc_count*8) < 0) dprintk("%s: Unable to set LAN_MULTICAST_MAC_ADDRESS table.\n",dev->name); } @@ -748,8 +745,8 @@ return; dprintk(KERN_INFO "i2o_lan: Enabling unicast mode...\n"); } - if (i2o_set_scalar(iop, i2o_dev->id, priv->unit << 16 | lan_context, 0x0001, 3, - &filter_mask, 4, &priv->reply_flag) <0) + if (i2o_set_scalar(iop, i2o_dev->lct_data->tid, 0x0001, 3, + &filter_mask, 4) < 0) printk(KERN_WARNING "i2o_lan: Unable to set MAC FilterMask.\n"); return; @@ -764,10 +761,10 @@ struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev) unsigned short (*type_trans)(struct sk_buff *, struct net_device *); void (*unregister_dev)(struct net_device *dev); - switch (i2o_dev->subclass) + switch (i2o_dev->lct_data->sub_class) { case I2O_LAN_ETHERNET: - dev = init_etherdev(NULL, sizeof(struct i2o_lan_local)); + dev = init_etherdev(NULL, sizeof(struct i2o_lan_local)); if (dev == NULL) return NULL; type_trans = eth_type_trans; @@ -827,7 +824,7 @@ struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev) case I2O_LAN_UNKNOWN: default: printk(KERN_ERR "i2o_lan: LAN type 0x%08X not supported\n", - i2o_dev->subclass); + i2o_dev->lct_data->sub_class); return NULL; } @@ -840,9 +837,8 @@ struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev) i2o_landevs[unit] = dev; priv->unit = unit; - if (i2o_query_scalar(i2o_dev->controller, i2o_dev->id, - priv->unit << 16 | lan_context, - 0x0001, 0, &hw_addr, 8, &priv->reply_flag) < 0) + if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data->tid, + 0x0001, 0, &hw_addr, 8) < 0) { printk(KERN_ERR "%s: Unable to query hardware address.\n", dev->name); unit--; @@ -858,9 +854,8 @@ struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev) dev->addr_len = 6; memcpy(dev->dev_addr, hw_addr, 6); - if (i2o_query_scalar(i2o_dev->controller, i2o_dev->id, - priv->unit << 16 | lan_context, - 0x0007, 2, &max_tx, 4, &priv->reply_flag) < 0) + if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data->tid, + 0x0007, 2, &max_tx, 4) < 0) { printk(KERN_ERR "%s: Unable to query max TX queue.\n", dev->name); unit--; @@ -912,7 +907,10 @@ int __init i2o_lan_init(void) for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next) { - if (i2o_dev->class != I2O_CLASS_LAN) + if (i2o_dev->lct_data->class_id != I2O_CLASS_LAN) + continue; + + if(i2o_dev->lct_data->user_tid != 0xFFF) continue; if (unit == MAX_LAN_CARDS) @@ -931,7 +929,7 @@ int __init i2o_lan_init(void) printk(KERN_INFO "%s: I2O LAN device registered, tid = %d," " subclass = 0x%08X, unit = %d.\n", - dev->name, i2o_dev->id, i2o_dev->subclass, + dev->name, i2o_dev->lct_data->tid, i2o_dev->lct_data->sub_class, ((struct i2o_lan_local *)dev->priv)->unit); } @@ -955,7 +953,7 @@ void cleanup_module(void) struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; - switch (i2o_dev->subclass) + switch (i2o_dev->lct_data->sub_class) { case I2O_LAN_ETHERNET: unregister_netdev(dev); @@ -975,7 +973,7 @@ void cleanup_module(void) #endif default: printk(KERN_WARNING "i2o_lan: Spurious I2O LAN subclass 0x%08X.\n", - i2o_dev->subclass); + i2o_dev->lct_data->sub_class); } dprintk(KERN_INFO "%s: I2O LAN device unregistered.\n", diff --git a/drivers/i2o/i2o_pci.c b/drivers/i2o/i2o_pci.c index f7afa9a46..122c488a9 100644 --- a/drivers/i2o/i2o_pci.c +++ b/drivers/i2o/i2o_pci.c @@ -25,6 +25,10 @@ #include <linux/malloc.h> #include <asm/io.h> +#ifdef CONFIG_MTRR +#include <asm/mtrr.h> +#endif // CONFIG_MTRR + #ifdef MODULE /* * Core function table @@ -46,6 +50,11 @@ static void i2o_pci_dispose(struct i2o_controller *c) if(c->bus.pci.irq > 0) free_irq(c->bus.pci.irq, c); iounmap(((u8 *)c->post_port)-0x40); + +#ifdef CONFIG_MTRR + if(c->bus.pci.mtrr_reg > 0) + mtrr_del(c->bus.pci.mtrr_reg, 0, 0); +#endif } /* @@ -66,6 +75,19 @@ static int i2o_pci_unbind(struct i2o_controller *c, struct i2o_device *dev) } /* + * Bus specific enable/disable functions + */ +static void i2o_pci_enable(struct i2o_controller *c) +{ + I2O_IRQ_WRITE32(c, 0); +} + +static void i2o_pci_disable(struct i2o_controller *c) +{ + I2O_IRQ_WRITE32(c, 0xFFFFFFFF); +} + +/* * Bus specific interrupt handler */ @@ -81,8 +103,9 @@ static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) /* * Install a PCI (or in theory AGP) i2o controller + * + * TODO: Add support for polled controllers */ - int __init i2o_pci_install(struct pci_dev *dev) { struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller), @@ -128,7 +151,7 @@ int __init i2o_pci_install(struct pci_dev *dev) kfree(c); return -EINVAL; } - + c->bus.pci.irq = -1; c->irq_mask = (volatile u32 *)(mem+0x34); @@ -141,9 +164,19 @@ int __init i2o_pci_install(struct pci_dev *dev) c->bind = i2o_pci_bind; c->unbind = i2o_pci_unbind; + c->bus_enable = i2o_pci_enable; + c->bus_disable = i2o_pci_disable; c->type = I2O_TYPE_PCI; + /* + * Enable Write Combining MTRR for IOP's memory region + */ +#ifdef CONFIG_MTRR + c->bus.pci.mtrr_reg = + mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1); +#endif + I2O_IRQ_WRITE32(c,0xFFFFFFFF); #ifdef MODULE @@ -180,6 +213,9 @@ int __init i2o_pci_install(struct pci_dev *dev) return -EBUSY; } } + + printk(KERN_INFO "Installed iop%d at IRQ%d\n", c->unit, dev->irq); + I2O_IRQ_WRITE32(c,0x0); return 0; } @@ -211,102 +247,54 @@ int __init i2o_pci_scan(void) return count?count:-ENODEV; } -static void i2o_pci_unload(void) +#ifdef I2O_HOTPLUG_SUPPORT +/* + * Activate a newly found PCI I2O controller + * Not used now, but will be needed in future for + * hot plug PCI support + */ +static void i2o_pci_activate(i2o_controller * c) { int i=0; struct i2o_controller *c; - for(i = 0; i < MAX_I2O_CONTROLLERS; i++) + if(c->type == I2O_TYPE_PCI) { + I2O_IRQ_WRITE32(c,0); #ifdef MODULE - c=core->find(i); + if(core->activate(c)) #else - c=i2o_find_controller(i); + if(i2o_activate_controller(c)) #endif /* MODULE */ - - if(c==NULL) - continue; - -#ifdef MODULE - core->unlock(c); -#else - i2o_unlock_controller(c); -#endif /* MODULE */ - - if(c->type == I2O_TYPE_PCI) + { + printk("I2O: Failed to initialize iop%d\n", c->unit); #ifdef MODULE + core->unlock(c); core->delete(c); #else + i2o_unlock_controller(c); i2o_delete_controller(c); -#endif /* MODULE */ - } -} - -static void i2o_pci_activate(void) -{ - int i=0; - struct i2o_controller *c; - - for(i = 0; i < MAX_I2O_CONTROLLERS; i++) - { -#ifdef MODULE - c=core->find(i); -#else - c=i2o_find_controller(i); -#endif /* MODULE */ - - if(c==NULL) - continue; - - if(c->type == I2O_TYPE_PCI) - { -#ifdef MODULE - if(core->activate(c)) -#else - if(i2o_activate_controller(c)) -#endif /* MODULE */ - { - printk("I2O: Failed to initialize iop%d\n", c->unit); -#ifdef MODULE - core->unlock(c); - core->delete(c); -#else - i2o_unlock_controller(c); - i2o_delete_controller(c); #endif - continue; - } - I2O_IRQ_WRITE32(c,0); + continue; } -#ifdef MODULE - core->unlock(c); -#else - i2o_unlock_controller(c); -#endif } } - +#endif // I2O_HOTPLUG_SUPPORT #ifdef MODULE int i2o_pci_core_attach(struct i2o_core_func_table *table) { - int i; - MOD_INC_USE_COUNT; core = table; - - if((i = i2o_pci_scan())<0) - return -ENODEV; - i2o_pci_activate(); - return i; + return i2o_pci_scan(); } void i2o_pci_core_detach(void) { - i2o_pci_unload(); + core = NULL; MOD_DEC_USE_COUNT; } @@ -314,16 +302,8 @@ void i2o_pci_core_detach(void) int init_module(void) { printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n"); - -/* - * Let the core call the scan function for module dependency - * reasons. See include/linux/i2o.h for the reason why this - * is done. - * - * if(i2o_pci_scan()<0) - * return -ENODEV; - * i2o_pci_activate(); - */ + + core = NULL; return 0; @@ -343,9 +323,6 @@ MODULE_DESCRIPTION("I2O PCI Interface"); void __init i2o_pci_init(void) { printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n"); - if(i2o_pci_scan()>=0) - { - i2o_pci_activate(); - } + i2o_pci_scan(); } #endif diff --git a/drivers/i2o/i2o_proc.c b/drivers/i2o/i2o_proc.c index cbb29bc5b..4059a5189 100644 --- a/drivers/i2o/i2o_proc.c +++ b/drivers/i2o/i2o_proc.c @@ -1,7 +1,7 @@ /* * procfs handler for Linux I2O subsystem * - * Copyright (c) 1999 Deepak Saxena + * (c) Copyright 1999 Deepak Saxena * * Originally written by Deepak Saxena(deepak@plexity.net) * @@ -790,16 +790,15 @@ int i2o_proc_read_hw(char *buf, char **start, off_t offset, int len, len = 0; - token = i2o_query_scalar(c, ADAPTER_TID, proc_context, + token = i2o_query_scalar(c, ADAPTER_TID, 0, // ParamGroup 0x0000h -1, // all fields &work32, - sizeof(work32), - &i2o_proc_token); + sizeof(work32)); if(token < 0) { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + len += sprintf(buf, "Error waiting for reply from IOP\n"); spin_unlock(&i2o_proc_lock); return len; } @@ -875,10 +874,10 @@ int i2o_proc_read_ddm_table(char *buf, char **start, off_t offset, int len, len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - c, ADAPTER_TID, proc_context, + c, ADAPTER_TID, 0x0003, -1, NULL, 0, - &result, sizeof(result), &i2o_proc_token); + &result, sizeof(result)); if (token<0) switch (token) @@ -941,16 +940,13 @@ int i2o_proc_read_ds(char *buf, char **start, off_t offset, int len, { struct i2o_controller *c = (struct i2o_controller*)data; u32 work32[8]; - int token; spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(c, ADAPTER_TID, proc_context, 0x0004, -1, - &work32, sizeof(work32), &i2o_proc_token); - - if (token<0) + if(i2o_query_scalar(c, ADAPTER_TID, 0x0004, -1, &work32, + sizeof(work32)) < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); spin_unlock(&i2o_proc_lock); @@ -1009,10 +1005,10 @@ int i2o_proc_read_dst(char *buf, char **start, off_t offset, int len, len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - c, ADAPTER_TID, proc_context, + c, ADAPTER_TID, 0x0005, -1, NULL, 0, - &result, sizeof(result), &i2o_proc_token); + &result, sizeof(result)); if (token<0) switch (token) @@ -1094,10 +1090,10 @@ int i2o_proc_read_groups(char *buf, char **start, off_t offset, int len, len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - c, ADAPTER_TID, proc_context, + c, ADAPTER_TID, 0xF000, -1, NULL, 0, - &work16, sizeof(work16), &i2o_proc_token); + &work16, sizeof(work16)); if (token<0) switch (token) @@ -1181,10 +1177,10 @@ int i2o_proc_read_priv_msgs(char *buf, char **start, off_t offset, int len, len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - c, ADAPTER_TID, proc_context, + c, ADAPTER_TID, 0xF000, -1, NULL, 0, - &work16, sizeof(work16), &i2o_proc_token); + &work16, sizeof(work16)); if (token<0) switch (token) @@ -1243,12 +1239,11 @@ int i2o_proc_read_dev(char *buf, char **start, off_t offset, int len, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, + token = i2o_query_scalar(d->controller, d->lct_data->tid, 0xF100, // ParamGroup F100h (Device Identity) -1, // all fields &work32, - sizeof(work32), - &i2o_proc_token); + sizeof(work32)); if(token < 0) { @@ -1308,12 +1303,11 @@ int i2o_proc_read_ddm(char *buf, char **start, off_t offset, int len, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, + token = i2o_query_scalar(d->controller, d->lct_data->tid, 0xF101, // ParamGroup F101h (DDM Identity) -1, // all fields &work32, - sizeof(work32), - &i2o_proc_token); + sizeof(work32)); if(token < 0) { @@ -1352,12 +1346,11 @@ int i2o_proc_read_uinfo(char *buf, char **start, off_t offset, int len, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, + token = i2o_query_scalar(d->controller, d->lct_data->tid, 0xF102, // ParamGroup F102h (User Information) -1, // all fields &work32, - sizeof(work32), - &i2o_proc_token); + sizeof(work32)); if(token < 0) { @@ -1390,12 +1383,11 @@ int i2o_proc_read_sgl_limits(char *buf, char **start, off_t offset, int len, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, + token = i2o_query_scalar(d->controller, d->lct_data->tid, 0xF103, // ParamGroup F103h (SGL Operating Limits) -1, // all fields &work32, - sizeof(work32), - &i2o_proc_token); + sizeof(work32)); if(token < 0) { @@ -1760,8 +1752,8 @@ int i2o_proc_read_lan_dev_info(char *buf, char **start, off_t offset, int len, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0000, -1, &work32, 56*4, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0000, -1, &work32, 56*4); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -1883,8 +1875,8 @@ int i2o_proc_read_lan_mac_addr(char *buf, char **start, off_t offset, int len, spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0001, -1, &work32, 48*4, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0001, -1, &work32, 48*4); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -1973,9 +1965,8 @@ int i2o_proc_read_lan_mcast_addr(char *buf, char **start, off_t offset, len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - d->controller, d->id, proc_context, 0x0002, -1, - NULL, 0, &field32, sizeof(field32), - &i2o_proc_token); + d->controller, d->lct_data->tid, 0x0002, -1, + NULL, 0, &field32, sizeof(field32)); if (token<0) switch (token) { @@ -2026,8 +2017,8 @@ int i2o_proc_read_lan_batch_control(char *buf, char **start, off_t offset, spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0003, -1, &work32, 9*4, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0003, -1, &work32, 9*4); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2086,8 +2077,8 @@ int i2o_proc_read_lan_operation(char *buf, char **start, off_t offset, int len, spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0004, -1, &work32, 20, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0004, -1, &work32, 20); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2151,8 +2142,8 @@ int i2o_proc_read_lan_media_operation(char *buf, char **start, off_t offset, spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0005, -1, &work32, 36, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0005, -1, &work32, 36); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2225,9 +2216,8 @@ int i2o_proc_read_lan_alt_addr(char *buf, char **start, off_t offset, int len, len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - d->controller, d->id, proc_context, 0x0006, -1, - NULL, 0, &field32, sizeof(field32), - &i2o_proc_token); + d->controller, d->lct_data->tid, 0x0006, -1, + NULL, 0, &field32, sizeof(field32)); if (token<0) switch (token) { @@ -2279,8 +2269,8 @@ int i2o_proc_read_lan_tx_info(char *buf, char **start, off_t offset, int len, spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0007, -1, &work32, 8*4, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0007, -1, &work32, 8*4); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2341,8 +2331,8 @@ int i2o_proc_read_lan_rx_info(char *buf, char **start, off_t offset, int len, spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0008, -1, &work32, 8*4, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0008, -1, &work32, 8*4); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2376,8 +2366,8 @@ int i2o_proc_read_lan_hist_stats(char *buf, char **start, off_t offset, int len, spin_lock(&i2o_proc_lock); len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0100, -1, &work64, 9*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0100, -1, &work64, 9*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2421,8 +2411,8 @@ int i2o_proc_read_lan_supp_opt_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0180, -1, &work64, 4*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0180, -1, &work64, 4*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2461,8 +2451,8 @@ int i2o_proc_read_lan_opt_tx_hist_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0182, -1, &work64, 9*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0182, -1, &work64, 9*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2506,8 +2496,8 @@ int i2o_proc_read_lan_opt_rx_hist_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0183, -1, &work64, 11*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0183, -1, &work64, 11*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2555,8 +2545,8 @@ int i2o_proc_read_lan_eth_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0200, -1, &work64, 8*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0200, -1, &work64, 8*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2597,8 +2587,8 @@ int i2o_proc_read_lan_supp_eth_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0280, -1, &work64, 8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0280, -1, &work64, 8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2625,8 +2615,8 @@ int i2o_proc_read_lan_opt_eth_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0281, -1, &work64, 3*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0281, -1, &work64, 3*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2677,8 +2667,8 @@ int i2o_proc_read_lan_tr_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0300, -1, &work64, 13*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0300, -1, &work64, 13*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2771,8 +2761,8 @@ int i2o_proc_read_lan_fddi_stats(char *buf, char **start, off_t offset, len = 0; - token = i2o_query_scalar(d->controller, d->id, proc_context, - 0x0400, -1, &work64, 11*8, &i2o_proc_token); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0400, -1, &work64, 11*8); if(token < 0) { len += sprintf(buf, "Timeout waiting for reply from IOP\n"); @@ -2853,7 +2843,7 @@ static int i2o_proc_add_controller(struct i2o_controller *pctrl, for(dev = pctrl->devices; dev; dev = dev->next) { - sprintf(buff, "%0#5x", dev->id); + sprintf(buff, "%0#5x", dev->lct_data->tid); dir1 = create_proc_entry(buff, S_IFDIR, dir); dev->proc_entry = dir1; @@ -2863,7 +2853,7 @@ static int i2o_proc_add_controller(struct i2o_controller *pctrl, i2o_proc_create_entries(dev, generic_dev_entries, dir1); - switch(dev->class) + switch(dev->lct_data->class_id) { case I2O_CLASS_SCSI_PERIPHERAL: case I2O_CLASS_RANDOM_BLOCK_STORAGE: @@ -2871,7 +2861,7 @@ static int i2o_proc_add_controller(struct i2o_controller *pctrl, break; case I2O_CLASS_LAN: i2o_proc_create_entries(dev, lan_entries, dir1); - switch(dev->subclass) + switch(dev->lct_data->sub_class) { case I2O_LAN_ETHERNET: i2o_proc_create_entries(dev, lan_eth_entries, @@ -2909,14 +2899,14 @@ static void i2o_proc_remove_controller(struct i2o_controller *pctrl, for(dev=pctrl->devices; dev; dev=dev->next) { de=dev->proc_entry; - sprintf(dev_id, "%0#5x", dev->id); + sprintf(dev_id, "%0#5x", dev->lct_data->tid); /* Would it be safe to remove _files_ even if they are in use? */ if((de) && (!de->count)) { i2o_proc_remove_entries(generic_dev_entries, de); - switch(dev->class) + switch(dev->lct_data->class_id) { case I2O_CLASS_SCSI_PERIPHERAL: case I2O_CLASS_RANDOM_BLOCK_STORAGE: @@ -2924,7 +2914,7 @@ static void i2o_proc_remove_controller(struct i2o_controller *pctrl, break; case I2O_CLASS_LAN: i2o_proc_remove_entries(lan_entries, de); - switch(dev->subclass) + switch(dev->lct_data->sub_class) { case I2O_LAN_ETHERNET: i2o_proc_remove_entries(lan_eth_entries, de); diff --git a/drivers/i2o/i2o_scsi.c b/drivers/i2o/i2o_scsi.c index 7b309411b..46f7fbfb0 100644 --- a/drivers/i2o/i2o_scsi.c +++ b/drivers/i2o/i2o_scsi.c @@ -301,14 +301,12 @@ static int i2o_find_lun(struct i2o_controller *c, struct i2o_device *d, int *tar { u8 reply[8]; - if(i2o_query_scalar(c, d->id, scsi_context|0x40000000, - 0, 3, reply, 4, &lun_done)<0) + if(i2o_query_scalar(c, d->lct_data->tid, 0, 3, reply, 4)) return -1; *target=reply[0]; - if(i2o_query_scalar(c, d->id, scsi_context|0x40000000, - 0, 4, reply, 8, &lun_done)<0) + if(i2o_query_scalar(c, d->lct_data->tid, 0, 4, reply, 8)) return -1; *lun=reply[1]; @@ -325,7 +323,7 @@ void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_H int target; h->controller=c; - h->bus_task=d->id; + h->bus_task=d->lct_data->tid; for(target=0;target<16;target++) for(lun=0;lun<8;lun++) @@ -334,34 +332,33 @@ void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_H for(unit=c->devices;unit!=NULL;unit=unit->next) { dprintk(("Class %03X, parent %d, want %d.\n", - unit->class, unit->parent, d->id)); + unit->lct_data->class_id, unit->lct_data->parent, d->lct_data->tid)); /* Only look at scsi and fc devices */ - if ( (unit->class != I2O_CLASS_SCSI_PERIPHERAL) - && (unit->class != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL) + if ( (unit->lct_data->class_id != I2O_CLASS_SCSI_PERIPHERAL) + && (unit->lct_data->class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL) ) continue; /* On our bus ? */ dprintk(("Found a disk.\n")); - if ( (unit->parent == d->id) - || (unit->parent == d->parent) + if ((unit->lct_data->parent_tid == d->lct_data->tid) + || (unit->lct_data->parent_tid == d->lct_data->parent_tid) ) { u16 limit; dprintk(("Its ours.\n")); if(i2o_find_lun(c, unit, &target, &lun)==-1) { - printk(KERN_ERR "i2o_scsi: Unable to get lun for tid %d.\n", d->id); + printk(KERN_ERR "i2o_scsi: Unable to get lun for tid %d.\n", d->lct_data->tid); continue; } dprintk(("Found disk %d %d.\n", target, lun)); - h->task[target][lun]=unit->id; + h->task[target][lun]=unit->lct_data->tid; h->tagclock[target][lun]=jiffies; /* Get the max fragments/request */ - i2o_query_scalar(c, d->id, scsi_context|0x40000000, - 0xF103, 3, &limit, 2, &lun_done); + i2o_query_scalar(c, d->lct_data->tid, 0xF103, 3, &limit, 2); /* sanity */ if ( limit == 0 ) @@ -435,8 +432,8 @@ int i2o_scsi_detect(Scsi_Host_Template * tpnt) /* * bus_adapter, SCSI (obsolete), or FibreChannel busses only */ - if( (d->class!=I2O_CLASS_BUS_ADAPTER_PORT) // bus_adapter - && (d->class!=I2O_CLASS_FIBRE_CHANNEL_PORT) // FC_PORT + if( (d->lct_data->class_id!=I2O_CLASS_BUS_ADAPTER_PORT) // bus_adapter + && (d->lct_data->class_id!=I2O_CLASS_FIBRE_CHANNEL_PORT) // FC_PORT ) continue; diff --git a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c index 720932cc9..39a27107f 100644 --- a/drivers/macintosh/macserial.c +++ b/drivers/macintosh/macserial.c @@ -2584,7 +2584,9 @@ void unregister_serial(int line) * ------------------------------------------------------------ */ #ifdef CONFIG_SERIAL_CONSOLE - +#ifdef CONFIG_SERIAL +#error Cannot build serial console with macserial and serial drivers +#endif /* * Print a string to the serial port trying not to disturb @@ -2843,7 +2845,7 @@ static struct console sercons = { /* * Register console. */ -long __init serial_console_init(long kmem_start, long kmem_end) +void __init serial_console_init(void) { register_console(&sercons); return kmem_start; diff --git a/drivers/misc/acpi.c b/drivers/misc/acpi.c index 03c39fb61..093a7bbb8 100644 --- a/drivers/misc/acpi.c +++ b/drivers/misc/acpi.c @@ -29,8 +29,13 @@ #include <linux/sched.h> #include <linux/wait.h> #include <linux/spinlock.h> +#include <linux/ioport.h> +#include <linux/slab.h> +#include <linux/pci.h> #include <asm/uaccess.h> #include <asm/io.h> +#include <linux/sysctl.h> +#include <linux/delay.h> #include <linux/acpi.h> /* @@ -49,7 +54,26 @@ #define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue * x = NULL #endif +static int acpi_do_ulong(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len); +static int acpi_do_event_reg(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len); +static int acpi_do_event(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len); + +static struct ctl_table_header *acpi_sysctl = NULL; + static struct acpi_facp *acpi_facp = NULL; +static int acpi_fake_facp = 0; static unsigned long acpi_facp_addr = 0; static unsigned long acpi_dsdt_addr = 0; @@ -57,15 +81,64 @@ static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED; static volatile u32 acpi_pm1_status = 0; static volatile u32 acpi_gpe_status = 0; static volatile u32 acpi_gpe_level = 0; -static DECLARE_WAIT_QUEUE_HEAD(acpi_wait_event); +static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); /* Make it impossible to enter L2/L3 until after we've initialized */ static unsigned long acpi_p_lvl2_lat = ~0UL; static unsigned long acpi_p_lvl3_lat = ~0UL; /* Initialize to guaranteed harmless port read */ -static u16 acpi_p_lvl2 = 0x80; -static u16 acpi_p_lvl3 = 0x80; +static unsigned long acpi_p_lvl2 = 0x80; +static unsigned long acpi_p_lvl3 = 0x80; + +static struct ctl_table acpi_table[] = +{ + {ACPI_FACP, "facp", + &acpi_facp_addr, sizeof(acpi_facp_addr), + 0400, NULL, &acpi_do_ulong}, + + {ACPI_DSDT, "dsdt", + &acpi_dsdt_addr, sizeof(acpi_dsdt_addr), + 0400, NULL, &acpi_do_ulong}, + + {ACPI_PM1_ENABLE, "pm1_enable", + NULL, 0, + 0600, NULL, &acpi_do_event_reg}, + + {ACPI_GPE_ENABLE, "gpe_enable", + NULL, 0, + 0600, NULL, &acpi_do_event_reg}, + + {ACPI_GPE_LEVEL, "gpe_level", + NULL, 0, + 0600, NULL, &acpi_do_event_reg}, + + {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event}, + + {ACPI_P_LVL2, "p_lvl2", + &acpi_p_lvl2, sizeof(acpi_p_lvl2), + 0600, NULL, &acpi_do_ulong}, + + {ACPI_P_LVL3, "p_lvl3", + &acpi_p_lvl3, sizeof(acpi_p_lvl3), + 0600, NULL, &acpi_do_ulong}, + + {ACPI_P_LVL2_LAT, "p_lvl2_lat", + &acpi_p_lvl2_lat, sizeof(acpi_p_lvl2_lat), + 0600, NULL, &acpi_do_ulong}, + + {ACPI_P_LVL3_LAT, "p_lvl3_lat", + &acpi_p_lvl3_lat, sizeof(acpi_p_lvl3_lat), + 0600, NULL, &acpi_do_ulong}, + + {0} +}; + +static struct ctl_table acpi_dir_table[] = +{ + {CTL_ACPI, "acpi", NULL, 0, 0500, acpi_table}, + {0} +}; /* @@ -73,7 +146,9 @@ static u16 acpi_p_lvl3 = 0x80; */ static u32 acpi_read_pm1_control(struct acpi_facp *facp) { - u32 value = inw(facp->pm1a_cnt); + u32 value = 0; + if (facp->pm1a_cnt) + value = inw(facp->pm1a_cnt); if (facp->pm1b_cnt) value |= inw(facp->pm1b_cnt); return value; @@ -84,7 +159,9 @@ static u32 acpi_read_pm1_control(struct acpi_facp *facp) */ static u32 acpi_read_pm1_status(struct acpi_facp *facp) { - u32 value = inw(facp->pm1a_evt); + u32 value = 0; + if (facp->pm1a_evt) + value = inw(facp->pm1a_evt); if (facp->pm1b_evt) value |= inw(facp->pm1b_evt); return value; @@ -95,7 +172,8 @@ static u32 acpi_read_pm1_status(struct acpi_facp *facp) */ static void acpi_write_pm1_status(struct acpi_facp *facp, u32 value) { - outw(value, facp->pm1a_evt); + if (facp->pm1a_evt) + outw(value, facp->pm1a_evt); if (facp->pm1b_evt) outw(value, facp->pm1b_evt); } @@ -106,7 +184,9 @@ static void acpi_write_pm1_status(struct acpi_facp *facp, u32 value) static u32 acpi_read_pm1_enable(struct acpi_facp *facp) { int offset = facp->pm1_evt_len >> 1; - u32 value = inw(facp->pm1a_evt + offset); + u32 value = 0; + if (facp->pm1a_evt) + value = inw(facp->pm1a_evt + offset); if (facp->pm1b_evt) value |= inw(facp->pm1b_evt + offset); return value; @@ -118,7 +198,8 @@ static u32 acpi_read_pm1_enable(struct acpi_facp *facp) static void acpi_write_pm1_enable(struct acpi_facp *facp, u32 value) { int offset = facp->pm1_evt_len >> 1; - outw(value, facp->pm1a_evt + offset); + if (facp->pm1a_evt) + outw(value, facp->pm1a_evt + offset); if (facp->pm1b_evt) outw(value, facp->pm1b_evt + offset); } @@ -136,9 +217,11 @@ static u32 acpi_read_gpe_status(struct acpi_facp *facp) for (i = size - 1; i >= 0; i--) value = (value << 8) | inb(facp->gpe1 + i); } - size = facp->gpe0_len >> 1; - for (i = size - 1; i >= 0; i--) - value = (value << 8) | inb(facp->gpe0 + i); + if (facp->gpe0) { + size = facp->gpe0_len >> 1; + for (i = size - 1; i >= 0; i--) + value = (value << 8) | inb(facp->gpe0 + i); + } return value; } @@ -149,10 +232,12 @@ static void acpi_write_gpe_status(struct acpi_facp *facp, u32 value) { int i, size; - size = facp->gpe0_len >> 1; - for (i = 0; i < size; i++) { - outb(value & 0xff, facp->gpe0 + i); - value >>= 8; + if (facp->gpe0) { + size = facp->gpe0_len >> 1; + for (i = 0; i < size; i++) { + outb(value & 0xff, facp->gpe0 + i); + value >>= 8; + } } if (facp->gpe1) { size = facp->gpe1_len >> 1; @@ -178,9 +263,11 @@ static u32 acpi_read_gpe_enable(struct acpi_facp *facp) value = (value << 8) | inb(facp->gpe1 + offset + i); } } - size = facp->gpe0_len >> 1; - for (i = size - 1; i >= 0; i--) - value = (value << 8) | inb(facp->gpe0 + offset + i); + if (facp->gpe0) { + size = facp->gpe0_len >> 1; + for (i = size - 1; i >= 0; i--) + value = (value << 8) | inb(facp->gpe0 + offset + i); + } return value; } @@ -192,9 +279,11 @@ static void acpi_write_gpe_enable(struct acpi_facp *facp, u32 value) int i, offset; offset = facp->gpe0_len >> 1; - for (i = 0; i < offset; i++) { - outb(value & 0xff, facp->gpe0 + offset + i); - value >>= 8; + if (facp->gpe0) { + for (i = 0; i < offset; i++) { + outb(value & 0xff, facp->gpe0 + offset + i); + value >>= 8; + } } if (facp->gpe1) { offset = facp->gpe1_len >> 1; @@ -238,9 +327,9 @@ static void acpi_unmap_table(struct acpi_table *table) } /* - * Locate and map ACPI tables (FACP, DSDT, ...) + * Locate and map ACPI tables */ -static int __init acpi_map_tables(void) +static int __init acpi_find_tables(void) { struct acpi_rsdp *rsdp; struct acpi_table *rsdt; @@ -251,8 +340,8 @@ static int __init acpi_map_tables(void) // search BIOS memory for RSDP for (i = ACPI_BIOS_ROM_BASE; i < ACPI_BIOS_ROM_END; i += 16) { rsdp = (struct acpi_rsdp *) phys_to_virt(i); - if (rsdp->signature[0] == ACPI_RSDP1_SIG && - rsdp->signature[1] == ACPI_RSDP2_SIG) { + if (rsdp->signature[0] == ACPI_RSDP1_SIG + && rsdp->signature[1] == ACPI_RSDP2_SIG) { char oem[7]; int j; @@ -270,14 +359,13 @@ static int __init acpi_map_tables(void) break; } } - if (i >= ACPI_BIOS_ROM_END) { - printk(KERN_ERR "ACPI: no RSDP found\n"); + if (i >= ACPI_BIOS_ROM_END) return -ENODEV; - } + // fetch RSDT from RSDP rsdt = acpi_map_table(rsdp->rsdt); if (!rsdt || rsdt->signature != ACPI_RSDT_SIG) { - printk(KERN_ERR "ACPI: no RSDT found\n"); + printk(KERN_ERR "ACPI: missing RSDT\n"); acpi_unmap_table(rsdt); return -ENODEV; } @@ -288,11 +376,11 @@ static int __init acpi_map_tables(void) while (rsdt_entry_count) { struct acpi_table *dt = acpi_map_table(*rsdt_entry); if (dt && dt->signature == ACPI_FACP_SIG) { - acpi_facp = (struct acpi_facp *) dt; + acpi_facp = (struct acpi_facp*) dt; acpi_facp_addr = *rsdt_entry; acpi_dsdt_addr = acpi_facp->dsdt; - break; - } else { + } + else { acpi_unmap_table(dt); } rsdt_entry++; @@ -302,22 +390,89 @@ static int __init acpi_map_tables(void) acpi_unmap_table(rsdt); if (!acpi_facp) { - printk(KERN_ERR "ACPI: no FACP found\n"); + printk(KERN_ERR "ACPI: missing FACP\n"); return -ENODEV; } return 0; } /* - * Unmap ACPI tables (FACP, DSDT, ...) + * Unmap or destroy ACPI tables */ -static void acpi_unmap_tables(void) +static void acpi_destroy_tables(void) { - acpi_idle = NULL; + if (!acpi_fake_facp) + acpi_unmap_table((struct acpi_table*) acpi_facp); + else + kfree(acpi_facp); +} + +/* + * Locate PIIX4 device and create a fake FACP + */ +static int __init acpi_find_piix4(void) +{ + struct pci_dev *dev; + u32 base; + u16 cmd; + u8 pmregmisc; + + dev = pci_find_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_3, + NULL); + if (!dev) + return -ENODEV; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + if (!(cmd & PCI_COMMAND_IO)) + return -ENODEV; + + pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc); + if (!(pmregmisc & ACPI_PIIX4_PMIOSE)) + return -ENODEV; + + pci_read_config_dword(dev, 0x40, &base); + if (!(base & PCI_BASE_ADDRESS_SPACE_IO)) + return -ENODEV; + + base &= PCI_BASE_ADDRESS_IO_MASK; + if (!base) + return -ENODEV; + + printk(KERN_INFO "ACPI: found PIIX4 at 0x%04x\n", base); + + acpi_facp = kmalloc(sizeof(struct acpi_facp), GFP_KERNEL); + if (!acpi_facp) + return -ENOMEM; + + acpi_fake_facp = 1; + memset(acpi_facp, 0, sizeof(struct acpi_facp)); + acpi_facp->int_model = ACPI_PIIX4_INT_MODEL; + acpi_facp->sci_int = ACPI_PIIX4_SCI_INT; + acpi_facp->smi_cmd = ACPI_PIIX4_SMI_CMD; + acpi_facp->acpi_enable = ACPI_PIIX4_ACPI_ENABLE; + acpi_facp->acpi_disable = ACPI_PIIX4_ACPI_DISABLE; + acpi_facp->s4bios_req = ACPI_PIIX4_S4BIOS_REQ; + acpi_facp->pm1a_evt = base + ACPI_PIIX4_PM1_EVT; + acpi_facp->pm1a_cnt = base + ACPI_PIIX4_PM1_CNT; + acpi_facp->pm2_cnt = ACPI_PIIX4_PM2_CNT; + acpi_facp->pm_tmr = base + ACPI_PIIX4_PM_TMR; + acpi_facp->gpe0 = base + ACPI_PIIX4_GPE0; + acpi_facp->pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN; + acpi_facp->pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN; + acpi_facp->pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN; + acpi_facp->pm_tm_len = ACPI_PIIX4_PM_TM_LEN; + acpi_facp->gpe0_len = ACPI_PIIX4_GPE0_LEN; + acpi_facp->p_lvl2_lat = ~0; + acpi_facp->p_lvl3_lat = ~0; + + acpi_facp_addr = virt_to_phys(acpi_facp); acpi_dsdt_addr = 0; - acpi_facp_addr = 0; - acpi_unmap_table((struct acpi_table *) acpi_facp); - acpi_facp = NULL; + + acpi_p_lvl2 = base + ACPI_PIIX4_P_LVL2; + acpi_p_lvl3 = base + ACPI_PIIX4_P_LVL3; + + return 0; } /* @@ -355,25 +510,7 @@ static void acpi_irq(int irq, void *dev_id, struct pt_regs *regs) acpi_pm1_status |= pm1_status; acpi_gpe_status |= gpe_status; spin_unlock_irqrestore(&acpi_event_lock, flags); - wake_up_interruptible(&acpi_wait_event); -} - -/* - * Handle open of /dev/acpi - */ -static int acpi_open(struct inode *inode, struct file *file) -{ - MOD_INC_USE_COUNT; - return 0; -} - -/* - * Handle close of /dev/acpi - */ -static int acpi_release(struct inode *inode, struct file *file) -{ - MOD_DEC_USE_COUNT; - return 0; + wake_up_interruptible(&acpi_event_wait); } /* @@ -389,7 +526,8 @@ static inline int acpi_is_enabled(struct acpi_facp *facp) */ static int acpi_enable(struct acpi_facp *facp) { - outb(facp->acpi_enable, facp->smi_cmd); + if (facp->smi_cmd) + outb(facp->acpi_enable, facp->smi_cmd); return (acpi_is_enabled(facp) ? 0:-1); } @@ -404,132 +542,29 @@ static int acpi_disable(struct acpi_facp *facp) acpi_write_gpe_status(facp, acpi_read_gpe_status(facp)); acpi_write_pm1_enable(facp, 0); acpi_write_pm1_status(facp, acpi_read_pm1_status(facp)); - - outb(facp->acpi_disable, facp->smi_cmd); + + if (facp->smi_cmd) + outb(facp->acpi_disable, facp->smi_cmd); return (acpi_is_enabled(facp) ? -1:0); } /* - * Handle command to /dev/acpi + * Idle loop */ -static int acpi_ioctl(struct inode *inode, - struct file *file, - unsigned cmd, - unsigned long arg) -{ - int status = -EINVAL; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - switch (cmd) { - case ACPI_FIND_TABLES: - status = verify_area(VERIFY_WRITE, - (void *) arg, - sizeof(struct acpi_find_tables)); - if (!status) { - struct acpi_find_tables *rqst - = (struct acpi_find_tables *) arg; - put_user(acpi_facp_addr, &rqst->facp); - put_user(acpi_dsdt_addr, &rqst->dsdt); - status = 0; - } - break; - case ACPI_ENABLE_EVENT: - status = verify_area(VERIFY_READ, - (void *) arg, - sizeof(struct acpi_enable_event)); - if (!status) { - struct acpi_enable_event *rqst - = (struct acpi_enable_event *) arg; - u32 pm1_enable, gpe_enable, gpe_level; - u32 pm1_enabling, gpe_enabling; - - get_user(pm1_enable, &rqst->pm1_enable); - get_user(gpe_enable, &rqst->gpe_enable); - get_user(gpe_level, &rqst->gpe_level); - gpe_level &= gpe_enable; - - // clear previously disabled events before enabling - pm1_enabling = (pm1_enable - & ~acpi_read_pm1_enable(acpi_facp)); - acpi_write_pm1_status(acpi_facp, pm1_enabling); - gpe_enabling = (gpe_enable & - ~acpi_read_gpe_enable(acpi_facp)); - while (acpi_read_gpe_status(acpi_facp) & gpe_enabling) - acpi_write_gpe_status(acpi_facp, gpe_enabling); - - status = 0; - - if (pm1_enable || gpe_enable) { - // enable ACPI unless it is already - if (!acpi_is_enabled(acpi_facp) - && acpi_enable(acpi_facp)) { - status = -EBUSY; - } - } - else { - // disable ACPI unless it is already - if (acpi_is_enabled(acpi_facp) - && acpi_disable(acpi_facp)) { - status = -EBUSY; - } - } - - if (!status) - { - acpi_write_pm1_enable(acpi_facp, pm1_enable); - acpi_write_gpe_enable(acpi_facp, gpe_enable); - acpi_gpe_level = gpe_level; - } - } - break; - case ACPI_WAIT_EVENT: - status = verify_area(VERIFY_WRITE, - (void *) arg, - sizeof(struct acpi_wait_event)); - if (!status) { - struct acpi_wait_event *rqst - = (struct acpi_wait_event *) arg; - u32 pm1_status = 0; - u32 gpe_status = 0; - - for (;;) { - unsigned long flags; - - // we need an atomic exchange here - spin_lock_irqsave(&acpi_event_lock, flags); - pm1_status = acpi_pm1_status; - acpi_pm1_status = 0; - gpe_status = acpi_gpe_status; - acpi_gpe_status = 0; - spin_unlock_irqrestore(&acpi_event_lock, - flags); - - if (pm1_status || gpe_status) - break; - - // wait for an event to arrive - interruptible_sleep_on(&acpi_wait_event); - if (signal_pending(current)) - return -ERESTARTSYS; - } - - put_user(pm1_status, &rqst->pm1_status); - put_user(gpe_status, &rqst->gpe_status); - status = 0; - } - break; - } - return status; -} - static void acpi_idle_handler(void) { - unsigned long time; static int sleep_level = 1; + u32 timer, pm2_cnt; + unsigned long time; - time = inl(acpi_facp->pm_tmr); + // get current time (fallback to CPU cycles if no PM timer) + timer = acpi_facp->pm_tmr; + if (timer) + time = inl(timer); + else + time = get_cycles(); + + // sleep switch (sleep_level) { case 1: __asm__ __volatile__("sti ; hlt": : :"memory"); @@ -538,18 +573,25 @@ static void acpi_idle_handler(void) inb(acpi_p_lvl2); break; case 3: - /* Disable PCI arbitration while sleeping, - to avoid DMA corruption? */ - if (acpi_facp->pm2_cnt) { - unsigned int port = acpi_facp->pm2_cnt; - outb(inb(port) | ACPI_ARB_DIS, port); + pm2_cnt = acpi_facp->pm2_cnt; + if (pm2_cnt) { + /* Disable PCI arbitration while sleeping, + to avoid DMA corruption? */ + outb(inb(pm2_cnt) | ACPI_ARB_DIS, pm2_cnt); + inb(acpi_p_lvl3); + outb(inb(pm2_cnt) & ~ACPI_ARB_DIS, pm2_cnt); + } + else { inb(acpi_p_lvl3); - outb(inb(port) & ~ACPI_ARB_DIS, port); - break; } - inb(acpi_p_lvl3); + break; } - time = (inl(acpi_facp->pm_tmr) - time) & ACPI_TMR_MASK; + + // calculate time spent sleeping (fallback to CPU cycles) + if (timer) + time = (inl(timer) - time) & ACPI_TMR_MASK; + else + time = ACPI_CPU_TO_TMR_TICKS(get_cycles() - time); if (time > acpi_p_lvl3_lat) sleep_level = 3; @@ -559,50 +601,24 @@ static void acpi_idle_handler(void) sleep_level = 1; } -static struct file_operations acpi_fops = -{ - NULL, /* llseek */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* poll */ - acpi_ioctl, /* ioctl */ - NULL, /* mmap */ - acpi_open, /* open */ - NULL, /* flush */ - acpi_release, /* release */ - NULL, /* fsync */ - NULL, /* fasync */ - NULL, /* check_media_change */ - NULL, /* revalidate */ - NULL, /* lock */ -}; - -static struct miscdevice acpi_device = -{ - ACPI_MINOR_DEV, - "acpi", - &acpi_fops, - NULL, - NULL -}; - /* * Claim ACPI I/O ports */ static int acpi_claim_ioports(struct acpi_facp *facp) { // we don't get a guarantee of contiguity for any of the ACPI registers - request_region(facp->pm1a_evt, facp->pm1_evt_len, "acpi"); + if (facp->pm1a_evt) + request_region(facp->pm1a_evt, facp->pm1_evt_len, "acpi"); if (facp->pm1b_evt) request_region(facp->pm1b_evt, facp->pm1_evt_len, "acpi"); - request_region(facp->pm1a_cnt, facp->pm1_cnt_len, "acpi"); + if (facp->pm1a_cnt) + request_region(facp->pm1a_cnt, facp->pm1_cnt_len, "acpi"); if (facp->pm1b_cnt) request_region(facp->pm1b_cnt, facp->pm1_cnt_len, "acpi"); - if (facp->pm2_cnt) - request_region(facp->pm2_cnt, facp->pm2_cnt_len, "acpi"); - request_region(facp->pm_tmr, facp->pm_tm_len, "acpi"); - request_region(facp->gpe0, facp->gpe0_len, "acpi"); + if (facp->pm_tmr) + request_region(facp->pm_tmr, facp->pm_tm_len, "acpi"); + if (facp->gpe0) + request_region(facp->gpe0, facp->gpe0_len, "acpi"); if (facp->gpe1) request_region(facp->gpe1, facp->gpe1_len, "acpi"); @@ -615,16 +631,18 @@ static int acpi_claim_ioports(struct acpi_facp *facp) static int acpi_release_ioports(struct acpi_facp *facp) { // we don't get a guarantee of contiguity for any of the ACPI registers - release_region(facp->pm1a_evt, facp->pm1_evt_len); + if (facp->pm1a_evt) + release_region(facp->pm1a_evt, facp->pm1_evt_len); if (facp->pm1b_evt) release_region(facp->pm1b_evt, facp->pm1_evt_len); - release_region(facp->pm1a_cnt, facp->pm1_cnt_len); + if (facp->pm1a_cnt) + release_region(facp->pm1a_cnt, facp->pm1_cnt_len); if (facp->pm1b_cnt) release_region(facp->pm1b_cnt, facp->pm1_cnt_len); - if (facp->pm2_cnt) - release_region(facp->pm2_cnt, facp->pm2_cnt_len); - release_region(facp->pm_tmr, facp->pm_tm_len); - release_region(facp->gpe0, facp->gpe0_len); + if (facp->pm_tmr) + release_region(facp->pm_tmr, facp->pm_tm_len); + if (facp->gpe0) + release_region(facp->gpe0, facp->gpe0_len); if (facp->gpe1) release_region(facp->gpe1, facp->gpe1_len); @@ -632,28 +650,224 @@ static int acpi_release_ioports(struct acpi_facp *facp) } /* + * Examine/modify value + */ +static int acpi_do_ulong(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len) +{ + char str[2 * sizeof(unsigned long) + 4], *strend; + unsigned long val; + int size; + + if (!write) { + if (file->f_pos) { + *len = 0; + return 0; + } + + val = *(unsigned long*) ctl->data; + size = sprintf(str, "0x%08lx\n", val); + if (*len >= size) { + copy_to_user(buffer, str, size); + *len = size; + } + else + *len = 0; + } + else { + size = sizeof(str) - 1; + if (size > *len) + size = *len; + copy_from_user(str, buffer, size); + str[size] = '\0'; + val = simple_strtoul(str, &strend, 0); + if (strend == str) + return -EINVAL; + *(unsigned long*) ctl->data = val; + } + + file->f_pos += *len; + return 0; +} + +/* + * Examine/modify event register + */ +static int acpi_do_event_reg(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len) +{ + char str[2 * sizeof(u32) + 4], *strend; + u32 val, enabling; + int size; + + if (!write) { + if (file->f_pos) { + *len = 0; + return 0; + } + + val = 0; + switch (ctl->ctl_name) { + case ACPI_PM1_ENABLE: + val = acpi_read_pm1_enable(acpi_facp); + break; + case ACPI_GPE_ENABLE: + val = acpi_read_gpe_enable(acpi_facp); + break; + case ACPI_GPE_LEVEL: + val = acpi_gpe_level; + break; + } + + size = sprintf(str, "0x%08x\n", val); + if (*len >= size) { + copy_to_user(buffer, str, size); + *len = size; + } + else + *len = 0; + } + else + { + // fetch user value + size = sizeof(str) - 1; + if (size > *len) + size = *len; + copy_from_user(str, buffer, size); + str[size] = '\0'; + val = (u32) simple_strtoul(str, &strend, 0); + if (strend == str) + return -EINVAL; + + // store value in register + switch (ctl->ctl_name) { + case ACPI_PM1_ENABLE: + // clear previously disabled events + enabling = (val + & ~acpi_read_pm1_enable(acpi_facp)); + acpi_write_pm1_status(acpi_facp, enabling); + + if (val) { + // enable ACPI unless it is already + if (!acpi_is_enabled(acpi_facp)) + acpi_enable(acpi_facp); + } + else if (!acpi_read_gpe_enable(acpi_facp)) { + // disable ACPI unless it is already + if (acpi_is_enabled(acpi_facp)) + acpi_disable(acpi_facp); + } + + acpi_write_pm1_enable(acpi_facp, val); + break; + case ACPI_GPE_ENABLE: + // clear previously disabled events + enabling = (val + & ~acpi_read_gpe_enable(acpi_facp)); + while (acpi_read_gpe_status(acpi_facp) & enabling) + acpi_write_gpe_status(acpi_facp, enabling); + + if (val) { + // enable ACPI unless it is already + if (!acpi_is_enabled(acpi_facp)) + acpi_enable(acpi_facp); + } + else if (!acpi_read_pm1_enable(acpi_facp)) { + // disable ACPI unless it is already + if (acpi_is_enabled(acpi_facp)) + acpi_disable(acpi_facp); + } + + acpi_write_gpe_enable(acpi_facp, val); + break; + case ACPI_GPE_LEVEL: + acpi_gpe_level = val; + break; + } + } + + file->f_pos += *len; + return 0; +} + +/* + * Wait for next event + */ +static int acpi_do_event(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len) +{ + u32 pm1_status = 0, gpe_status = 0; + char str[4 * sizeof(u32) + 6]; + int size; + + if (write) + return -EPERM; + if (*len < sizeof(str)) { + *len = 0; + return 0; + } + + for (;;) { + unsigned long flags; + + // we need an atomic exchange here + spin_lock_irqsave(&acpi_event_lock, flags); + pm1_status = acpi_pm1_status; + acpi_pm1_status = 0; + gpe_status = acpi_gpe_status; + acpi_gpe_status = 0; + spin_unlock_irqrestore(&acpi_event_lock, flags); + + if (pm1_status || gpe_status) + break; + + // wait for an event to arrive + interruptible_sleep_on(&acpi_event_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + } + + size = sprintf(str, "0x%08x 0x%08x\n", pm1_status, gpe_status); + copy_to_user(buffer, str, size); + *len = size; + file->f_pos += size; + + return 0; +} + +/* * Initialize and enable ACPI */ static int __init acpi_init(void) { - if (acpi_map_tables()) + if (acpi_find_tables() && acpi_find_piix4()) { + // no ACPI tables and not PIIX4 return -ENODEV; + } - if (request_irq(acpi_facp->sci_int, - acpi_irq, - SA_INTERRUPT | SA_SHIRQ, - "acpi", - NULL)) { + if (acpi_facp->sci_int + && request_irq(acpi_facp->sci_int, + acpi_irq, + SA_INTERRUPT | SA_SHIRQ, + "acpi", + NULL)) { printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", acpi_facp->sci_int); - acpi_unmap_tables(); + acpi_destroy_tables(); return -ENODEV; } acpi_claim_ioports(acpi_facp); - - if (misc_register(&acpi_device)) - printk(KERN_ERR "ACPI: misc. register failed\n"); + acpi_sysctl = register_sysctl_table(acpi_dir_table, 1); /* * Set up the ACPI idle function. Note that we can't really @@ -664,7 +878,9 @@ static int __init acpi_init(void) if (smp_num_cpus > 1) return 0; #endif + acpi_idle = acpi_idle_handler; + return 0; } @@ -673,11 +889,16 @@ static int __init acpi_init(void) */ static void __exit acpi_exit(void) { - misc_deregister(&acpi_device); + acpi_idle = NULL; + + unregister_sysctl_table(acpi_sysctl); acpi_disable(acpi_facp); acpi_release_ioports(acpi_facp); - free_irq(acpi_facp->sci_int, NULL); - acpi_unmap_tables(); + + if (acpi_facp->sci_int) + free_irq(acpi_facp->sci_int, NULL); + + acpi_destroy_tables(); } #ifdef MODULE diff --git a/drivers/net/Config.in b/drivers/net/Config.in index d54f8fd30..0757aa349 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -46,6 +46,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then if [ "$CONFIG_PPC" = "y" ]; then tristate ' MACE (Power Mac ethernet) support' CONFIG_MACE tristate ' BMAC (G3 ethernet) support' CONFIG_BMAC + tristate ' Symbios 53c885 (Synergy ethernet) support' CONFIG_NCR885E fi if [ "$CONFIG_ZORRO" = "y" ]; then tristate ' Ariadne support' CONFIG_ARIADNE @@ -217,6 +218,7 @@ fi tristate 'PPP (point-to-point protocol) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP + dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m fi diff --git a/drivers/net/Makefile b/drivers/net/Makefile index fe9208d4d..12fbc99f3 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -299,6 +299,13 @@ CONFIG_SLHC_BUILTIN = y MX_OBJS += ppp_async.o endif endif + ifeq ($(CONFIG_PPP_SYNC_TTY),y) + LX_OBJS += ppp_synctty.o + else + ifeq ($(CONFIG_PPP_SYNC_TTY),m) + MX_OBJS += ppp_synctty.o + endif + endif ifeq ($(CONFIG_PPP_DEFLATE),y) CONFIG_PPPDEF_BUILTIN = y else @@ -316,6 +323,9 @@ else ifeq ($(CONFIG_PPP_ASYNC),m) MX_OBJS += ppp_async.o endif + ifeq ($(CONFIG_PPP_SYNC_TTY),m) + MX_OBJS += ppp_synctty.o + endif ifeq ($(CONFIG_PPP_DEFLATE),m) CONFIG_PPPDEF_MODULE = y endif @@ -1031,6 +1041,14 @@ else endif endif +ifeq ($(CONFIG_NCR885E),y) +L_OBJS += ncr885e.o +else + ifeq ($(CONFIG_NCR885E),m) + M_OBJS += ncr885e.o + endif +endif + ifeq ($(CONFIG_ADAPTEC_STARFIRE),y) L_OBJS += starfire.o else diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index 353b44dc8..906d3fab7 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -1,184 +1,184 @@ -/* $Id: arcnet.c,v 1.34 1997/11/09 11:04:55 mj Exp $ - - Written 1994-1996 by Avery Pennarun, - derived from skeleton.c by Donald Becker. - - ********************** - - The original copyright was as follows: - - skeleton.c Written 1993 by Donald Becker. - Copyright 1993 United States Government as represented by the - Director, National Security Agency. This software may only be used - and distributed according to the terms of the GNU Public License as - modified by SRC, incorporated herein by reference. - - ********************** - - v3.02 (98/06/07) - - Use register_netdevice() instead of register_netdev() to create - new devices for RFC1051 and Ethernet encapsulation in arcnet_open. - Likewise for unregistering them later. This avoids the deadlock - encountered because the original routines call rtnl_lock() when - it's already locked. [dw] - - v3.01 (98/04/17) - - Interrupt handler now also checks dev->[se]dev are non-NULL - to avoid crashes in interrupts during card init. [dw] - - v3.00 (97/11/09) - - Minor cleanup of debugging messages. [mj] - - v2.93 ALPHA (97/11/06) - - irq2dev mapping removed. - - Interrupt handler now checks whether dev->priv is non-null in order - to avoid crashes in interrupts which come during card init. [mj] - - v2.92 ALPHA (97/09/02) - - Code cleanup [Martin Mares <mj@atrey.karlin.mff.cuni.cz>] - - Better probing for the COM90xx chipset, although only as - a temporary solution until we implement adding of all found - devices at once. [mj] - - v2.91 ALPHA (97/08/19) - - Add counting of octets in/out. - - v2.90 ALPHA (97/08/08) - - Add support for kernel command line parsing so that chipset - drivers are usable when compiled in. - - v2.80 ALPHA (97/08/01) - - Split source into multiple files; generic arcnet support and - individual chipset drivers. <Dave@imladris.demon.co.uk> - - v2.61 ALPHA (97/07/30) by David Woodhouse (Dave@imladris.demon.co.uk) - for Nortel (Northern Telecom). - - Added support for IO-mapped modes and for SMC COM20020 chipset. - - Fixed (avoided) race condition in send_packet routines which was - discovered when the buffer copy routines got slow (?). - - Fixed support for device naming at load time. - - Added backplane, clock and timeout options for COM20020. - - Added support for promiscuous mode. - - v2.60 ALPHA (96/11/23) - - Added patch from Vojtech Pavlik <vojtech@atrey.karlin.mff.cuni.cz> - and Martin Mares <mj@k332.feld.cvut.cz> to make the driver work - with the new Linux 2.1.x memory management. I modified their - patch quite a bit though; bugs are my fault. More changes should - be made to get eliminate any remaining phys_to_virt calls. - - Quietly ignore protocol id's 0, 1, 8, and 243. Thanks to Jake - Messinger <jake@ams.com> for reporting these codes and their - meanings. - - Smarter shmem probe for cards with 4k mirrors. (does it work?) - - Initial support for RIM I type cards which use no I/O ports at - all. To use this option, you need to compile with RIM_I_MODE - enabled. Thanks to Kolja Waschk <kawk@yo.com> for explaining - RIM I programming to me. Now, does my RIM I code actually - work? - - v2.56 (96/10/18) - - Turned arc0e/arc0s startup messages back on by default, as most - people will probably not notice the additional devices - otherwise. This causes undue confusion. - - Fixed a tiny but noticeable bug in the packet debugging routines - (thanks Tomasz) - - The following has been SUMMARIZED. The complete ChangeLog is - available in the full Linux-ARCnet package at - http://www.worldvisions.ca/~apenwarr/arcnet - - v2.50 (96/02/24) - - Massively improved autoprobe routines; they now work even as a - module. Thanks to Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz> - for his ideas and help in this area. - - Changed printk's around quite a lot. - - v2.22 (95/12/08) - - Major cleanups, speedups, and better code-sharing. - - Eliminated/changed many useless/meaningless/scary debug messages - (and, in most cases, the bugs that caused them). - - Better IPX support. - - lp->stats updated properly. - - RECON checking now by default only prints a message if there are - excessive errors (ie. your cable is probably broken). - - New RFC1051-compliant "arc0s" virtual device by Tomasz - Motylewski. - - Excess debug messages can be compiled out to reduce code size. - - v2.00 (95/09/06) - - ARCnet RECON messages are now detected and logged as "carrier" - errors. - - The TXACK flag is now checked, and errors are logged. - - Debug levels are now completely different. See the README. - - Massive code cleanups, with several no-longer-necessary and some - completely useless options removed. - - Multiprotocol support. You can now use the "arc0e" device to - send "Ethernet-Encapsulation" packets, which are compatible with - Windows for Workgroups and LAN Manager, and possibly other - software. See the README for more information. - - v1.02 (95/06/21) - - A fix to make "exception" packets sent from Linux receivable - on other systems. (The protocol_id byte was sometimes being set - incorrectly, and Linux wasn't checking it on receive so it - didn't show up) - - v1.01 (95/03/24) - - Fixed some IPX-related bugs. (Thanks to Tomasz Motylewski - <motyl@tichy.ch.uj.edu.pl> for the patches to make arcnet work - with dosemu!) - - v1.00 (95/02/15) - - Initial non-alpha release. - - - TO DO: (semi-prioritized) - - - Use cleaner "architecture-independent" shared memory access. - This is half-done in ARCnet 2.60, but still uses some - undocumented i386 stuff. (We shouldn't call phys_to_virt, - for example.) - - Allow use of RFC1051 or Ether devices without RFC1201. - - Keep separate stats for each device. - - Support "arpless" mode like NetBSD does, and as recommended - by the (obsoleted) RFC1051. - - Smarter recovery from RECON-during-transmit conditions. (ie. - retransmit immediately) - - Add support for the new 1.3.x IP header cache, and other features. - - Replace setting of debug level with the "metric" flag hack by - something that still exists. SIOCDEVPRIVATE is a good candidate, - but it would require an extra user-level utility. - - - What about cards with shared memory that can be "turned off?" - (or that have none at all, like the SMC PC500longboard) - Does this work now, with IO_MAPPED_BUFFERS? - - - Autoconfigure PDI5xxPlus cards. (I now have a PDI508Plus to play - with temporarily.) Update: yes, the Pure Data config program - for DOS works fine, but the PDI508Plus I have doesn't! :) - - ATA protocol support?? - - VINES TCP/IP encapsulation?? (info needed) - - Sources: - - Crynwr arcnet.com/arcether.com packet drivers. - - arcnet.c v0.00 dated 1/1/94 and apparently by - Donald Becker - it didn't work :) - - skeleton.c v0.05 dated 11/16/93 by Donald Becker - (from Linux Kernel 1.1.45) - - RFC's 1201 and 1051 - re: TCP/IP over ARCnet - - The official ARCnet COM9026 data sheets (!) thanks to Ken - Cornetet <kcornete@nyx10.cs.du.edu> - - The official ARCnet COM20020 data sheets. - - Information on some more obscure ARCnet controller chips, thanks - to the nice people at SMC. - - net/inet/eth.c (from kernel 1.1.50) for header-building info. - - Alternate Linux ARCnet source by V.Shergin <vsher@sao.stavropol.su> - - Textual information and more alternate source from Joachim Koenig - <jojo@repas.de> -*/ +/* $Id: arcnet.c,v 1.34 1997/11/09 11:04:55 mj Exp $ + + Written 1994-1996 by Avery Pennarun, + derived from skeleton.c by Donald Becker. + + ********************** + + The original copyright was as follows: + + skeleton.c Written 1993 by Donald Becker. + Copyright 1993 United States Government as represented by the + Director, National Security Agency. This software may only be used + and distributed according to the terms of the GNU Public License as + modified by SRC, incorporated herein by reference. + + ********************** + + v3.02 (98/06/07) + - Use register_netdevice() instead of register_netdev() to create + new devices for RFC1051 and Ethernet encapsulation in arcnet_open. + Likewise for unregistering them later. This avoids the deadlock + encountered because the original routines call rtnl_lock() when + it's already locked. [dw] + + v3.01 (98/04/17) + - Interrupt handler now also checks dev->[se]dev are non-NULL + to avoid crashes in interrupts during card init. [dw] + + v3.00 (97/11/09) + - Minor cleanup of debugging messages. [mj] + + v2.93 ALPHA (97/11/06) + - irq2dev mapping removed. + - Interrupt handler now checks whether dev->priv is non-null in order + to avoid crashes in interrupts which come during card init. [mj] + + v2.92 ALPHA (97/09/02) + - Code cleanup [Martin Mares <mj@atrey.karlin.mff.cuni.cz>] + - Better probing for the COM90xx chipset, although only as + a temporary solution until we implement adding of all found + devices at once. [mj] + + v2.91 ALPHA (97/08/19) + - Add counting of octets in/out. + + v2.90 ALPHA (97/08/08) + - Add support for kernel command line parsing so that chipset + drivers are usable when compiled in. + + v2.80 ALPHA (97/08/01) + - Split source into multiple files; generic arcnet support and + individual chipset drivers. <Dave@imladris.demon.co.uk> + + v2.61 ALPHA (97/07/30) by David Woodhouse (Dave@imladris.demon.co.uk) + for Nortel (Northern Telecom). + - Added support for IO-mapped modes and for SMC COM20020 chipset. + - Fixed (avoided) race condition in send_packet routines which was + discovered when the buffer copy routines got slow (?). + - Fixed support for device naming at load time. + - Added backplane, clock and timeout options for COM20020. + - Added support for promiscuous mode. + + v2.60 ALPHA (96/11/23) + - Added patch from Vojtech Pavlik <vojtech@atrey.karlin.mff.cuni.cz> + and Martin Mares <mj@k332.feld.cvut.cz> to make the driver work + with the new Linux 2.1.x memory management. I modified their + patch quite a bit though; bugs are my fault. More changes should + be made to get eliminate any remaining phys_to_virt calls. + - Quietly ignore protocol id's 0, 1, 8, and 243. Thanks to Jake + Messinger <jake@ams.com> for reporting these codes and their + meanings. + - Smarter shmem probe for cards with 4k mirrors. (does it work?) + - Initial support for RIM I type cards which use no I/O ports at + all. To use this option, you need to compile with RIM_I_MODE + enabled. Thanks to Kolja Waschk <kawk@yo.com> for explaining + RIM I programming to me. Now, does my RIM I code actually + work? + + v2.56 (96/10/18) + - Turned arc0e/arc0s startup messages back on by default, as most + people will probably not notice the additional devices + otherwise. This causes undue confusion. + - Fixed a tiny but noticeable bug in the packet debugging routines + (thanks Tomasz) + + The following has been SUMMARIZED. The complete ChangeLog is + available in the full Linux-ARCnet package at + http://www.worldvisions.ca/~apenwarr/arcnet + + v2.50 (96/02/24) + - Massively improved autoprobe routines; they now work even as a + module. Thanks to Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz> + for his ideas and help in this area. + - Changed printk's around quite a lot. + + v2.22 (95/12/08) + - Major cleanups, speedups, and better code-sharing. + - Eliminated/changed many useless/meaningless/scary debug messages + (and, in most cases, the bugs that caused them). + - Better IPX support. + - lp->stats updated properly. + - RECON checking now by default only prints a message if there are + excessive errors (ie. your cable is probably broken). + - New RFC1051-compliant "arc0s" virtual device by Tomasz + Motylewski. + - Excess debug messages can be compiled out to reduce code size. + + v2.00 (95/09/06) + - ARCnet RECON messages are now detected and logged as "carrier" + errors. + - The TXACK flag is now checked, and errors are logged. + - Debug levels are now completely different. See the README. + - Massive code cleanups, with several no-longer-necessary and some + completely useless options removed. + - Multiprotocol support. You can now use the "arc0e" device to + send "Ethernet-Encapsulation" packets, which are compatible with + Windows for Workgroups and LAN Manager, and possibly other + software. See the README for more information. + + v1.02 (95/06/21) + - A fix to make "exception" packets sent from Linux receivable + on other systems. (The protocol_id byte was sometimes being set + incorrectly, and Linux wasn't checking it on receive so it + didn't show up) + + v1.01 (95/03/24) + - Fixed some IPX-related bugs. (Thanks to Tomasz Motylewski + <motyl@tichy.ch.uj.edu.pl> for the patches to make arcnet work + with dosemu!) + + v1.00 (95/02/15) + - Initial non-alpha release. + + + TO DO: (semi-prioritized) + + - Use cleaner "architecture-independent" shared memory access. + This is half-done in ARCnet 2.60, but still uses some + undocumented i386 stuff. (We shouldn't call phys_to_virt, + for example.) + - Allow use of RFC1051 or Ether devices without RFC1201. + - Keep separate stats for each device. + - Support "arpless" mode like NetBSD does, and as recommended + by the (obsoleted) RFC1051. + - Smarter recovery from RECON-during-transmit conditions. (ie. + retransmit immediately) + - Add support for the new 1.3.x IP header cache, and other features. + - Replace setting of debug level with the "metric" flag hack by + something that still exists. SIOCDEVPRIVATE is a good candidate, + but it would require an extra user-level utility. + + - What about cards with shared memory that can be "turned off?" + (or that have none at all, like the SMC PC500longboard) + Does this work now, with IO_MAPPED_BUFFERS? + + - Autoconfigure PDI5xxPlus cards. (I now have a PDI508Plus to play + with temporarily.) Update: yes, the Pure Data config program + for DOS works fine, but the PDI508Plus I have doesn't! :) + - ATA protocol support?? + - VINES TCP/IP encapsulation?? (info needed) + + Sources: + - Crynwr arcnet.com/arcether.com packet drivers. + - arcnet.c v0.00 dated 1/1/94 and apparently by + Donald Becker - it didn't work :) + - skeleton.c v0.05 dated 11/16/93 by Donald Becker + (from Linux Kernel 1.1.45) + - RFC's 1201 and 1051 - re: TCP/IP over ARCnet + - The official ARCnet COM9026 data sheets (!) thanks to Ken + Cornetet <kcornete@nyx10.cs.du.edu> + - The official ARCnet COM20020 data sheets. + - Information on some more obscure ARCnet controller chips, thanks + to the nice people at SMC. + - net/inet/eth.c (from kernel 1.1.50) for header-building info. + - Alternate Linux ARCnet source by V.Shergin <vsher@sao.stavropol.su> + - Textual information and more alternate source from Joachim Koenig + <jojo@repas.de> + */ static const char *version = - "arcnet.c: v3.02 98/06/07 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n"; +"arcnet.c: v3.02 98/06/07 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n"; #include <linux/module.h> #include <linux/config.h> @@ -230,15 +230,15 @@ static const char *version = #define ARCSTATUS ((*lp->astatus)(dev)) #define ACOMMAND(x) ((*lp->acommand)(dev, x)) -int arcnet_debug=ARCNET_DEBUG; +int arcnet_debug = ARCNET_DEBUG; /* Exported function prototypes */ #ifdef MODULE -int init_module(void); +int init_module(void); void cleanup_module(void); #else -void arcnet_init(void); +int arcnet_init(void); static int init_module(void); #ifdef CONFIG_ARCNET_COM90xx extern char com90xx_explicit; @@ -247,13 +247,13 @@ extern int arc90xx_probe(struct net_device *dev); #endif void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp); -void arcnet_use_count (int open); +void arcnet_use_count(int open); void arcnet_setup(struct net_device *dev); void arcnet_makename(char *device); void arcnetA_continue_tx(struct net_device *dev); -int arcnet_go_tx(struct net_device *dev,int enable_irq); -void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs); -void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr); +int arcnet_go_tx(struct net_device *dev, int enable_irq); +void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs); +void arcnet_rx(struct arcnet_local *lp, u_char * arcsoft, short length, int saddr, int daddr); EXPORT_SYMBOL(arcnet_debug); EXPORT_SYMBOL(arcnet_tx_done); @@ -266,32 +266,32 @@ EXPORT_SYMBOL(arcnet_interrupt); EXPORT_SYMBOL(arcnet_rx); #if ARCNET_DEBUG_MAX & D_SKB -void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb, - char *desc); +void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, + char *desc); EXPORT_SYMBOL(arcnet_dump_skb); #else -# define arcnet_dump_skb(dev,skb,desc) ; +#define arcnet_dump_skb(dev,skb,desc) ; #endif #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext, - char *desc); +void arcnet_dump_packet(struct net_device *dev, u_char * buffer, int ext, + char *desc); EXPORT_SYMBOL(arcnet_dump_packet); #else -# define arcnet_dump_packet(dev,buffer,ext,desc) ; +#define arcnet_dump_packet(dev,buffer,ext,desc) ; #endif /* Internal function prototypes */ static int arcnet_open(struct net_device *dev); static int arcnet_close(struct net_device *dev); -static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len); +static int arcnetA_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len); static int arcnetA_rebuild_header(struct sk_buff *skb); -static int arcnet_send_packet_bad(struct sk_buff *skb,struct net_device *dev); +static int arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev); static int arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev); -static void arcnetA_rx(struct net_device *dev,u_char *buf, - int length,u_char saddr, u_char daddr); +static void arcnetA_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr); static struct net_device_stats *arcnet_get_stats(struct net_device *dev); static unsigned short arcnetA_type_trans(struct sk_buff *skb, struct net_device *dev); @@ -302,8 +302,8 @@ static unsigned short arcnetA_type_trans(struct sk_buff *skb, static int arcnetE_init(struct net_device *dev); static int arcnetE_open_close(struct net_device *dev); static int arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev); -static void arcnetE_rx(struct net_device *dev,u_char *arcsoft, - int length,u_char saddr, u_char daddr); +static void arcnetE_rx(struct net_device *dev, u_char * arcsoft, + int length, u_char saddr, u_char daddr); #endif @@ -312,12 +312,12 @@ static void arcnetE_rx(struct net_device *dev,u_char *arcsoft, static int arcnetS_init(struct net_device *dev); static int arcnetS_open_close(struct net_device *dev); static int arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev); -static void arcnetS_rx(struct net_device *dev,u_char *buf, - int length,u_char saddr, u_char daddr); -static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len); +static void arcnetS_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr); +static int arcnetS_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len); static int arcnetS_rebuild_header(struct sk_buff *skb); -static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev); +static unsigned short arcnetS_type_trans(struct sk_buff *skb, struct net_device *dev); #endif @@ -330,22 +330,21 @@ static unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device * /* Dump the contents of an sk_buff */ #if ARCNET_DEBUG_MAX & D_SKB -void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb,char *desc) +void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc) { int i; long flags; save_flags(flags); cli(); - printk(KERN_DEBUG "%6s: skb dump (%s) follows:",dev->name,desc); - for(i=0; i<skb->len; i++) - { - if (i%16==0) - printk("\n" KERN_DEBUG "[%04X] ",i); - printk("%02X ",((u_char *)skb->data)[i]); + printk(KERN_DEBUG "%6s: skb dump (%s) follows:", dev->name, desc); + for (i = 0; i < skb->len; i++) { + if (i % 16 == 0) + printk("\n" KERN_DEBUG "[%04X] ", i); + printk("%02X ", ((u_char *) skb->data)[i]); } - printk("\n"); - restore_flags(flags); + printk("\n"); + restore_flags(flags); } #endif @@ -353,19 +352,18 @@ void arcnet_dump_skb(struct net_device *dev,struct sk_buff *skb,char *desc) /* Dump the contents of an ARCnet buffer */ #if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) -void arcnet_dump_packet(struct net_device *dev,u_char *buffer,int ext,char *desc) +void arcnet_dump_packet(struct net_device *dev, u_char * buffer, int ext, char *desc) { int i; long flags; save_flags(flags); cli(); - printk(KERN_DEBUG "%6s: packet dump (%s) follows:",dev->name,desc); - for (i=0; i<256+(ext!=0)*256; i++) - { - if (i%16==0) - printk("\n" KERN_DEBUG "[%04X] ",i); - printk("%02X ",buffer[i]); + printk(KERN_DEBUG "%6s: packet dump (%s) follows:", dev->name, desc); + for (i = 0; i < 256 + (ext != 0) * 256; i++) { + if (i % 16 == 0) + printk("\n" KERN_DEBUG "[%04X] ", i); + printk("%02X ", buffer[i]); } printk("\n"); restore_flags(flags); @@ -386,24 +384,24 @@ void arcnet_setup(struct net_device *dev) { dev_init_buffers(dev); - dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */ - dev->addr_len = 1; - dev->type = ARPHRD_ARCNET; - dev->tx_queue_len = 30; + dev->broadcast[0] = 0x00; /* for us, broadcasts are address 0 */ + dev->addr_len = 1; + dev->type = ARPHRD_ARCNET; + dev->tx_queue_len = 30; /* New-style flags. */ - dev->flags = IFF_BROADCAST; + dev->flags = IFF_BROADCAST; /* Put in this stuff here, so we don't have to export the symbols * to the chipset drivers. */ - dev->open=arcnet_open; - dev->stop=arcnet_close; - dev->hard_start_xmit=arcnetA_send_packet; - dev->get_stats=arcnet_get_stats; - dev->hard_header=arcnetA_header; - dev->rebuild_header=arcnetA_rebuild_header; + dev->open = arcnet_open; + dev->stop = arcnet_close; + dev->hard_start_xmit = arcnetA_send_packet; + dev->get_stats = arcnet_get_stats; + dev->hard_header = arcnetA_header; + dev->rebuild_header = arcnetA_rebuild_header; } @@ -420,167 +418,164 @@ void arcnet_setup(struct net_device *dev) * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ -static int -arcnet_open(struct net_device *dev) +static int arcnet_open(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - - /* if (dev->metric>=1000) - * { - * arcnet_debug=dev->metric-1000; - * printk(KERN_INFO "%6s: debug level set to %d\n",dev->name,arcnet_debug); - * dev->metric=1; - *} - */ - BUGMSG(D_INIT,"arcnet_open: resetting card.\n"); - - /* try to put the card in a defined state - if it fails the first - * time, actually reset it. - */ - if ((*lp->arcnet_reset)(dev,0) && (*lp->arcnet_reset)(dev,1)) - return -ENODEV; - - dev->tbusy=0; - dev->interrupt=0; - lp->intx=0; - lp->in_txhandler=0; - - /* The RFC1201 driver is the default - just store */ - lp->adev=dev; - - /* we're started */ - dev->start=1; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + + /* if (dev->metric>=1000) + * { + * arcnet_debug=dev->metric-1000; + * printk(KERN_INFO "%6s: debug level set to %d\n",dev->name,arcnet_debug); + * dev->metric=1; + *} + */ + BUGMSG(D_INIT, "arcnet_open: resetting card.\n"); + + /* try to put the card in a defined state - if it fails the first + * time, actually reset it. + */ + if ((*lp->arcnet_reset) (dev, 0) && (*lp->arcnet_reset) (dev, 1)) + return -ENODEV; + + dev->tbusy = 0; + dev->interrupt = 0; + lp->intx = 0; + lp->in_txhandler = 0; + + /* The RFC1201 driver is the default - just store */ + lp->adev = dev; + + /* we're started */ + dev->start = 1; #ifdef CONFIG_ARCNET_ETH - /* Initialize the ethernet-encap protocol driver */ - lp->edev=(struct net_device *)kmalloc(sizeof(struct net_device),GFP_KERNEL); - if (lp->edev == NULL) - return -ENOMEM; - memcpy(lp->edev,dev,sizeof(struct net_device)); - lp->edev->type=ARPHRD_ETHER; - lp->edev->name=(char *)kmalloc(10,GFP_KERNEL); - if (lp->edev->name == NULL) { - kfree(lp->edev); - lp->edev = NULL; - return -ENOMEM; - } - sprintf(lp->edev->name,"%se",dev->name); - lp->edev->init=arcnetE_init; - register_netdevice(lp->edev); + /* Initialize the ethernet-encap protocol driver */ + lp->edev = (struct net_device *) kmalloc(sizeof(struct net_device), GFP_KERNEL); + if (lp->edev == NULL) + return -ENOMEM; + memcpy(lp->edev, dev, sizeof(struct net_device)); + lp->edev->type = ARPHRD_ETHER; + lp->edev->name = (char *) kmalloc(10, GFP_KERNEL); + if (lp->edev->name == NULL) { + kfree(lp->edev); + lp->edev = NULL; + return -ENOMEM; + } + sprintf(lp->edev->name, "%se", dev->name); + lp->edev->init = arcnetE_init; + register_netdevice(lp->edev); #endif #ifdef CONFIG_ARCNET_1051 - /* Initialize the RFC1051-encap protocol driver */ - lp->sdev=(struct net_device *)kmalloc(sizeof(struct net_device)+10,GFP_KERNEL); - if(lp->sdev == NULL) - { + /* Initialize the RFC1051-encap protocol driver */ + lp->sdev = (struct net_device *) kmalloc(sizeof(struct net_device) + 10, GFP_KERNEL); + if (lp->sdev == NULL) { #ifdef CONFIG_ARCNET_ETH - if(lp->edev) - kfree(lp->edev); - lp->edev=NULL; - return -ENOMEM; -#endif - } - memcpy(lp->sdev,dev,sizeof(struct net_device)); - lp->sdev->name=(char *)(lp+1); - sprintf(lp->sdev->name,"%ss",dev->name); - lp->sdev->init=arcnetS_init; - register_netdevice(lp->sdev); + if (lp->edev) + kfree(lp->edev); + lp->edev = NULL; + return -ENOMEM; +#endif + } + memcpy(lp->sdev, dev, sizeof(struct net_device)); + lp->sdev->name = (char *) (lp + 1); + sprintf(lp->sdev->name, "%ss", dev->name); + lp->sdev->init = arcnetS_init; + register_netdevice(lp->sdev); #endif - /* Enable TX if we need to */ - if (lp->en_dis_able_TX) - (*lp->en_dis_able_TX)(dev, 1); + /* Enable TX if we need to */ + if (lp->en_dis_able_TX) + (*lp->en_dis_able_TX) (dev, 1); - /* make sure we're ready to receive IRQ's. - * arcnet_reset sets this for us, but if we receive one before - * START is set to 1, it could be ignored. So, we turn IRQ's - * off, then on again to clean out the IRQ controller. - */ + /* make sure we're ready to receive IRQ's. + * arcnet_reset sets this for us, but if we receive one before + * START is set to 1, it could be ignored. So, we turn IRQ's + * off, then on again to clean out the IRQ controller. + */ - AINTMASK(0); - udelay(1); /* give it time to set the mask before - * we reset it again. (may not even be - * necessary) - */ - SETMASK; + AINTMASK(0); + udelay(1); /* give it time to set the mask before + * we reset it again. (may not even be + * necessary) + */ + SETMASK; - /* Let it increase its use count */ - (*lp->openclose_device)(1); + /* Let it increase its use count */ + (*lp->openclose_device) (1); - return 0; + return 0; } /* The inverse routine to arcnet_open - shuts down the card. */ -static int -arcnet_close(struct net_device *dev) +static int arcnet_close(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - if (test_and_set_bit(0, (int *)&dev->tbusy)) - BUGMSG(D_NORMAL, "arcnet_close: tbusy already set!\n"); + if (test_and_set_bit(0, (int *) &dev->tbusy)) + BUGMSG(D_NORMAL, "arcnet_close: tbusy already set!\n"); - dev->start=0; + dev->start = 0; #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=1; - lp->sdev->start=0; + lp->sdev->tbusy = 1; + lp->sdev->start = 0; #endif #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=1; - lp->edev->start=0; + lp->edev->tbusy = 1; + lp->edev->start = 0; #endif - /* Shut down the card */ + /* Shut down the card */ - /* Disable TX if we need to */ - if (lp->en_dis_able_TX) - (*lp->en_dis_able_TX)(dev, 0); + /* Disable TX if we need to */ + if (lp->en_dis_able_TX) + (*lp->en_dis_able_TX) (dev, 0); - (*lp->arcnet_reset)(dev, 3); /* reset IRQ won't run if START=0 */ + (*lp->arcnet_reset) (dev, 3); /* reset IRQ won't run if START=0 */ #if 0 - lp->intmask=0; - SETMASK; /* no IRQ's (except RESET, of course) */ - ACOMMAND(NOTXcmd); /* stop transmit */ - ACOMMAND(NORXcmd); /* disable receive */ + lp->intmask = 0; + SETMASK; /* no IRQ's (except RESET, of course) */ + ACOMMAND(NOTXcmd); /* stop transmit */ + ACOMMAND(NORXcmd); /* disable receive */ #endif - /* reset more flags */ - dev->interrupt=0; + /* reset more flags */ + dev->interrupt = 0; #ifdef CONFIG_ARCNET_ETH - lp->edev->interrupt=0; + lp->edev->interrupt = 0; #endif #ifdef CONFIG_ARCNET_1051 - lp->sdev->interrupt=0; + lp->sdev->interrupt = 0; #endif - /* do NOT free lp->adev!! It's static! */ - lp->adev=NULL; + /* do NOT free lp->adev!! It's static! */ + lp->adev = NULL; #ifdef CONFIG_ARCNET_ETH - /* free the ethernet-encap protocol device */ - lp->edev->priv=NULL; - unregister_netdevice(lp->edev); - kfree(lp->edev->name); - kfree(lp->edev); - lp->edev=NULL; + /* free the ethernet-encap protocol device */ + lp->edev->priv = NULL; + unregister_netdevice(lp->edev); + kfree(lp->edev->name); + kfree(lp->edev); + lp->edev = NULL; #endif #ifdef CONFIG_ARCNET_1051 - /* free the RFC1051-encap protocol device */ - lp->sdev->priv=NULL; - unregister_netdevice(lp->sdev); - kfree(lp->sdev); - lp->sdev=NULL; + /* free the RFC1051-encap protocol device */ + lp->sdev->priv = NULL; + unregister_netdevice(lp->sdev); + kfree(lp->sdev); + lp->sdev = NULL; #endif - /* Update the statistics here. (not necessary in ARCnet) */ + /* Update the statistics here. (not necessary in ARCnet) */ - /* Decrease the use count */ - (*lp->openclose_device)(0); + /* Decrease the use count */ + (*lp->openclose_device) (0); - return 0; + return 0; } @@ -592,241 +587,213 @@ arcnet_close(struct net_device *dev) /* Generic error checking routine for arcnet??_send_packet */ -static int -arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev) +static int arcnet_send_packet_bad(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - - BUGMSG(D_DURING,"transmit requested (status=%Xh, inTX=%d)\n", - ARCSTATUS,lp->intx); - - if (lp->in_txhandler) - { - BUGMSG(D_NORMAL,"send_packet called while in txhandler!\n"); - lp->stats.tx_dropped++; - return 1; - } - - if (lp->intx>1) - { - BUGMSG(D_NORMAL,"send_packet called while intx!\n"); - lp->stats.tx_dropped++; - return 1; - } - - if (test_bit(0, (int *)&dev->tbusy)) - { - /* If we get here, some higher level has decided we are broken. - There should really be a "kick me" function call instead. */ - int tickssofar = jiffies - dev->trans_start; - - int status=ARCSTATUS; - - if (tickssofar < TX_TIMEOUT) - { - BUGMSG(D_DURING,"premature kickme! (status=%Xh ticks=%d o.skb=%ph numsegs=%d segnum=%d\n", - status,tickssofar,lp->outgoing.skb, - lp->outgoing.numsegs, - lp->outgoing.segnum); - return 1; - } + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - lp->intmask &= ~TXFREEflag; - SETMASK; + BUGMSG(D_DURING, "transmit requested (status=%Xh, inTX=%d)\n", + ARCSTATUS, lp->intx); - if (status&TXFREEflag) /* transmit _DID_ finish */ - { - BUGMSG(D_NORMAL,"tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n", - status,tickssofar,lp->intmask,lp->lasttrans_dest); - lp->stats.tx_errors++; + if (lp->in_txhandler) { + BUGMSG(D_NORMAL, "send_packet called while in txhandler!\n"); + lp->stats.tx_dropped++; + return 1; } - else - { - BUGMSG(D_EXTRA,"tx timed out (status=%Xh, tickssofar=%d, intmask=%Xh, dest=%02Xh)\n", - status,tickssofar,lp->intmask,lp->lasttrans_dest); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - - ACOMMAND(NOTXcmd); + if (lp->intx > 1) { + BUGMSG(D_NORMAL, "send_packet called while intx!\n"); + lp->stats.tx_dropped++; + return 1; } + if (test_bit(0, (int *) &dev->tbusy)) { + /* If we get here, some higher level has decided we are broken. + There should really be a "kick me" function call instead. */ + int tickssofar = jiffies - dev->trans_start; + + int status = ARCSTATUS; + + if (tickssofar < TX_TIMEOUT) { + BUGMSG(D_DURING, "premature kickme! (status=%Xh ticks=%d o.skb=%ph numsegs=%d segnum=%d\n", + status, tickssofar, lp->outgoing.skb, + lp->outgoing.numsegs, + lp->outgoing.segnum); + return 1; + } + lp->intmask &= ~TXFREEflag; + SETMASK; + + if (status & TXFREEflag) { /* transmit _DID_ finish */ + BUGMSG(D_NORMAL, "tx timeout - missed IRQ? (status=%Xh, ticks=%d, mask=%Xh, dest=%02Xh)\n", + status, tickssofar, lp->intmask, lp->lasttrans_dest); + lp->stats.tx_errors++; + } else { + BUGMSG(D_EXTRA, "tx timed out (status=%Xh, tickssofar=%d, intmask=%Xh, dest=%02Xh)\n", + status, tickssofar, lp->intmask, lp->lasttrans_dest); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + + ACOMMAND(NOTXcmd); + } - if (lp->outgoing.skb) - { - dev_kfree_skb(lp->outgoing.skb); - lp->stats.tx_dropped++; - } - lp->outgoing.skb=NULL; + if (lp->outgoing.skb) { + dev_kfree_skb(lp->outgoing.skb); + lp->stats.tx_dropped++; + } + lp->outgoing.skb = NULL; #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=0; + lp->edev->tbusy = 0; #endif #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=0; + lp->sdev->tbusy = 0; #endif - if (!test_and_clear_bit(0,(int *)&dev->tbusy)) - BUGMSG(D_EXTRA, "after timing out, tbusy was clear!\n"); - - lp->txready=0; - lp->sending=0; - - return 1; - } - - if (lp->txready) /* transmit already in progress! */ - { - BUGMSG(D_NORMAL,"trying to start new packet while busy! (status=%Xh)\n", - ARCSTATUS); - lp->intmask &= ~TXFREEflag; - SETMASK; - ACOMMAND(NOTXcmd); /* abort current send */ - (*lp->inthandler)(dev); /* fake an interrupt */ - lp->stats.tx_errors++; - lp->stats.tx_fifo_errors++; - lp->txready=0; /* we definitely need this line! */ - - return 1; - } - - /* Block a timer-based transmit from overlapping. This could better be - done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ - if (test_and_set_bit(0, (int *)&lp->adev->tbusy)) - { - BUGMSG(D_NORMAL,"transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n", - ARCSTATUS,lp->intx,jiffies-dev->trans_start); - lp->stats.tx_errors++; - lp->stats.tx_fifo_errors++; - return -EBUSY; - } + if (!test_and_clear_bit(0, (int *) &dev->tbusy)) + BUGMSG(D_EXTRA, "after timing out, tbusy was clear!\n"); + + lp->txready = 0; + lp->sending = 0; + + return 1; + } + if (lp->txready) { /* transmit already in progress! */ + BUGMSG(D_NORMAL, "trying to start new packet while busy! (status=%Xh)\n", + ARCSTATUS); + lp->intmask &= ~TXFREEflag; + SETMASK; + ACOMMAND(NOTXcmd); /* abort current send */ + (*lp->inthandler) (dev); /* fake an interrupt */ + lp->stats.tx_errors++; + lp->stats.tx_fifo_errors++; + lp->txready = 0; /* we definitely need this line! */ + + return 1; + } + /* Block a timer-based transmit from overlapping. This could better be + done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ + if (test_and_set_bit(0, (int *) &lp->adev->tbusy)) { + BUGMSG(D_NORMAL, "transmitter called with busy bit set! (status=%Xh, inTX=%d, tickssofar=%ld)\n", + ARCSTATUS, lp->intx, jiffies - dev->trans_start); + lp->stats.tx_errors++; + lp->stats.tx_fifo_errors++; + return -EBUSY; + } #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=1; + lp->sdev->tbusy = 1; #endif #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=1; + lp->edev->tbusy = 1; #endif - return 0; + return 0; } /* Called by the kernel in order to transmit a packet. */ -static int -arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) +static int arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int bad,oldmask=0; - struct Outgoing *out=&(lp->outgoing); - - lp->intx++; - - oldmask |= lp->intmask; - lp->intmask=0; - SETMASK; - - bad=arcnet_send_packet_bad(skb,dev); - if (bad) - { - lp->intx--; - lp->intmask=oldmask; - SETMASK; - return bad; - } - - /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - - lp->intmask = oldmask & ~TXFREEflag; - SETMASK; - - out->length = 1 < skb->len ? skb->len : 1; - out->hdr=(struct ClientData*)skb->data; - out->skb=skb; - - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"tx"); - - out->hdr->sequence=(lp->sequence++); - - /* fits in one packet? */ - if (out->length-EXTRA_CLIENTDATA<=XMTU) - { - BUGMSG(D_DURING,"not splitting %d-byte packet. (split_flag=%d)\n", - out->length,out->hdr->split_flag); - if (out->hdr->split_flag) - BUGMSG(D_NORMAL,"short packet has split_flag set?! (split_flag=%d)\n", - out->hdr->split_flag); - out->numsegs=1; - out->segnum=1; - (*lp->prepare_tx)(dev, - ((char *)out->hdr)+EXTRA_CLIENTDATA, - sizeof(struct ClientData)-EXTRA_CLIENTDATA, - ((char *)skb->data)+sizeof(struct ClientData), - out->length-sizeof(struct ClientData), - out->hdr->daddr,1,0); - - /* done right away */ - lp->stats.tx_bytes += out->skb->len; - dev_kfree_skb(out->skb); - out->skb=NULL; - - if (arcnet_go_tx(dev,1)) - { - /* inform upper layers */ - arcnet_tx_done(dev, lp); - } - } - else /* too big for one - split it */ - { - int maxsegsize=XMTU-4; - - out->data=(u_char *)skb->data - + sizeof(struct ClientData); - out->dataleft=out->length-sizeof(struct ClientData); - out->numsegs=(out->dataleft+maxsegsize-1)/maxsegsize; - out->segnum=0; - - BUGMSG(D_TX,"packet (%d bytes) split into %d fragments:\n", - out->length,out->numsegs); - - /* if a packet waiting, launch it */ - arcnet_go_tx(dev,1); - - if (!lp->txready) - { - /* prepare a packet, launch it and prepare - * another. - */ - arcnetA_continue_tx(dev); - if (arcnet_go_tx(dev,1)) - { - arcnetA_continue_tx(dev); - arcnet_go_tx(dev,1); - } + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int bad, oldmask = 0; + struct Outgoing *out = &(lp->outgoing); + + lp->intx++; + + oldmask |= lp->intmask; + lp->intmask = 0; + SETMASK; + + bad = arcnet_send_packet_bad(skb, dev); + if (bad) { + lp->intx--; + lp->intmask = oldmask; + SETMASK; + return bad; } + /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ + + lp->intmask = oldmask & ~TXFREEflag; + SETMASK; - /* if segnum==numsegs, the transmission is finished; - * free the skb right away. - */ - - if (out->segnum==out->numsegs) - { - /* transmit completed */ - out->segnum++; - if (out->skb) - { - lp->stats.tx_bytes += skb->len; - dev_kfree_skb(out->skb); - } - out->skb=NULL; + out->length = 1 < skb->len ? skb->len : 1; + out->hdr = (struct ClientData *) skb->data; + out->skb = skb; + + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx"); + + out->hdr->sequence = (lp->sequence++); + + /* fits in one packet? */ + if (out->length - EXTRA_CLIENTDATA <= XMTU) { + BUGMSG(D_DURING, "not splitting %d-byte packet. (split_flag=%d)\n", + out->length, out->hdr->split_flag); + if (out->hdr->split_flag) + BUGMSG(D_NORMAL, "short packet has split_flag set?! (split_flag=%d)\n", + out->hdr->split_flag); + out->numsegs = 1; + out->segnum = 1; + (*lp->prepare_tx) (dev, + ((char *) out->hdr) + EXTRA_CLIENTDATA, + sizeof(struct ClientData) - EXTRA_CLIENTDATA, + ((char *) skb->data) + sizeof(struct ClientData), + out->length - sizeof(struct ClientData), + out->hdr->daddr, 1, 0); + + /* done right away */ + lp->stats.tx_bytes += out->skb->len; + dev_kfree_skb(out->skb); + out->skb = NULL; + + if (arcnet_go_tx(dev, 1)) { + /* inform upper layers */ + arcnet_tx_done(dev, lp); + } + } else { /* too big for one - split it */ + int maxsegsize = XMTU - 4; + + out->data = (u_char *) skb->data + + sizeof(struct ClientData); + out->dataleft = out->length - sizeof(struct ClientData); + out->numsegs = (out->dataleft + maxsegsize - 1) / maxsegsize; + out->segnum = 0; + + BUGMSG(D_TX, "packet (%d bytes) split into %d fragments:\n", + out->length, out->numsegs); + + /* if a packet waiting, launch it */ + arcnet_go_tx(dev, 1); + + if (!lp->txready) { + /* prepare a packet, launch it and prepare + * another. + */ + arcnetA_continue_tx(dev); + if (arcnet_go_tx(dev, 1)) { + arcnetA_continue_tx(dev); + arcnet_go_tx(dev, 1); + } + } + /* if segnum==numsegs, the transmission is finished; + * free the skb right away. + */ + + if (out->segnum == out->numsegs) { + /* transmit completed */ + out->segnum++; + if (out->skb) { + lp->stats.tx_bytes += skb->len; + dev_kfree_skb(out->skb); + } + out->skb = NULL; + } } - } - dev->trans_start=jiffies; - lp->intx--; + dev->trans_start = jiffies; + lp->intx--; - /* make sure we didn't ignore a TX IRQ while we were in here */ - lp->intmask |= TXFREEflag; - SETMASK; + /* make sure we didn't ignore a TX IRQ while we were in here */ + lp->intmask |= TXFREEflag; + SETMASK; - return 0; + return 0; } @@ -836,44 +803,41 @@ arcnetA_send_packet(struct sk_buff *skb, struct net_device *dev) */ void arcnetA_continue_tx(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int maxsegsize=XMTU-4; - struct Outgoing *out=&(lp->outgoing); - - BUGMSG(D_DURING,"continue_tx called (status=%Xh, intx=%d, intxh=%d, intmask=%Xh\n", - ARCSTATUS,lp->intx,lp->in_txhandler,lp->intmask); - - if (lp->txready) - { - BUGMSG(D_NORMAL,"continue_tx: called with packet in buffer!\n"); - return; - } - - if (out->segnum>=out->numsegs) - { - BUGMSG(D_NORMAL,"continue_tx: building segment %d of %d!\n", - out->segnum+1,out->numsegs); - } - - if (!out->segnum) /* first packet */ - out->hdr->split_flag=((out->numsegs-2)<<1)+1; - else - out->hdr->split_flag=out->segnum<<1; - - out->seglen=maxsegsize; - if (out->seglen>out->dataleft) out->seglen=out->dataleft; - - BUGMSG(D_TX,"building packet #%d (%d bytes) of %d (%d total), splitflag=%d\n", - out->segnum+1,out->seglen,out->numsegs, - out->length,out->hdr->split_flag); - - (*lp->prepare_tx)(dev,((char *)out->hdr)+EXTRA_CLIENTDATA, - sizeof(struct ClientData)-EXTRA_CLIENTDATA, - out->data,out->seglen,out->hdr->daddr,1,0); - - out->dataleft-=out->seglen; - out->data+=out->seglen; - out->segnum++; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int maxsegsize = XMTU - 4; + struct Outgoing *out = &(lp->outgoing); + + BUGMSG(D_DURING, "continue_tx called (status=%Xh, intx=%d, intxh=%d, intmask=%Xh\n", + ARCSTATUS, lp->intx, lp->in_txhandler, lp->intmask); + + if (lp->txready) { + BUGMSG(D_NORMAL, "continue_tx: called with packet in buffer!\n"); + return; + } + if (out->segnum >= out->numsegs) { + BUGMSG(D_NORMAL, "continue_tx: building segment %d of %d!\n", + out->segnum + 1, out->numsegs); + } + if (!out->segnum) /* first packet */ + out->hdr->split_flag = ((out->numsegs - 2) << 1) + 1; + else + out->hdr->split_flag = out->segnum << 1; + + out->seglen = maxsegsize; + if (out->seglen > out->dataleft) + out->seglen = out->dataleft; + + BUGMSG(D_TX, "building packet #%d (%d bytes) of %d (%d total), splitflag=%d\n", + out->segnum + 1, out->seglen, out->numsegs, + out->length, out->hdr->split_flag); + + (*lp->prepare_tx) (dev, ((char *) out->hdr) + EXTRA_CLIENTDATA, + sizeof(struct ClientData) - EXTRA_CLIENTDATA, + out->data, out->seglen, out->hdr->daddr, 1, 0); + + out->dataleft -= out->seglen; + out->data += out->seglen; + out->segnum++; } @@ -887,36 +851,34 @@ void arcnetA_continue_tx(struct net_device *dev) * to the card; TXFREEflag is always OR'ed into the memory variable either * way. */ -int arcnet_go_tx(struct net_device *dev,int enable_irq) +int arcnet_go_tx(struct net_device *dev, int enable_irq) { - struct arcnet_local *lp=(struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - BUGMSG(D_DURING,"go_tx: status=%Xh, intmask=%Xh, txready=%d, sending=%d\n", - ARCSTATUS,lp->intmask,lp->txready,lp->sending); + BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, txready=%d, sending=%d\n", + ARCSTATUS, lp->intmask, lp->txready, lp->sending); - if (lp->sending || !lp->txready) - { - if (enable_irq && lp->sending) - { + if (lp->sending || !lp->txready) { + if (enable_irq && lp->sending) { lp->intmask |= TXFREEflag; SETMASK; } return 0; } - /* start sending */ - ACOMMAND(TXcmd|(lp->txready<<3)); + ACOMMAND(TXcmd | (lp->txready << 3)); lp->stats.tx_packets++; - lp->txready=0; + lp->txready = 0; lp->sending++; - lp->lasttrans_dest=lp->lastload_dest; - lp->lastload_dest=0; + lp->lasttrans_dest = lp->lastload_dest; + lp->lastload_dest = 0; lp->intmask |= TXFREEflag; - if (enable_irq) SETMASK; + if (enable_irq) + SETMASK; return 1; } @@ -933,85 +895,75 @@ int arcnet_go_tx(struct net_device *dev,int enable_irq) * interrupts. Establish which device needs attention, and call the correct * chipset interrupt handler. */ -void -arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs) +void arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct arcnet_local *lp; - if (dev==NULL) - { - BUGMSG(D_DURING, "arcnet: irq %d for unknown device.\n", irq); - return; - } - - BUGMSG(D_DURING,"in arcnet_interrupt\n"); - - lp=(struct arcnet_local *)dev->priv; - if (!lp) - { - BUGMSG(D_DURING, "arcnet: irq ignored.\n"); - return; - } + if (dev == NULL) { + BUGMSG(D_DURING, "arcnet: irq %d for unknown device.\n", irq); + return; + } + BUGMSG(D_DURING, "in arcnet_interrupt\n"); + lp = (struct arcnet_local *) dev->priv; + if (!lp) { + BUGMSG(D_DURING, "arcnet: irq ignored.\n"); + return; + } /* RESET flag was enabled - if !dev->start, we must clear it right * away (but nothing else) since inthandler() is never called. */ - if (!dev->start) - { - if (ARCSTATUS & RESETflag) - ACOMMAND(CFLAGScmd|RESETclear); - return; - } - - - if (test_and_set_bit(0, (int *)&dev->interrupt)) - { - BUGMSG(D_NORMAL,"DRIVER PROBLEM! Nested arcnet interrupts!\n"); - return; /* don't even try. */ - } + if (!dev->start) { + if (ARCSTATUS & RESETflag) + ACOMMAND(CFLAGScmd | RESETclear); + return; + } + if (test_and_set_bit(0, (int *) &dev->interrupt)) { + BUGMSG(D_NORMAL, "DRIVER PROBLEM! Nested arcnet interrupts!\n"); + return; /* don't even try. */ + } #ifdef CONFIG_ARCNET_1051 if (lp->sdev) - lp->sdev->interrupt=1; + lp->sdev->interrupt = 1; #endif #ifdef CONFIG_ARCNET_ETH if (lp->edev) - lp->edev->interrupt=1; + lp->edev->interrupt = 1; #endif /* Call the "real" interrupt handler. */ - (*lp->inthandler)(dev); + (*lp->inthandler) (dev); #ifdef CONFIG_ARCNET_ETH if (lp->edev) - lp->edev->interrupt=0; + lp->edev->interrupt = 0; #endif #ifdef CONFIG_ARCNET_1051 if (lp->sdev) - lp->sdev->interrupt=0; + lp->sdev->interrupt = 0; #endif - if (!test_and_clear_bit(0, (int *)&dev->interrupt)) - BUGMSG(D_NORMAL, "Someone cleared our dev->interrupt flag!\n"); + if (!test_and_clear_bit(0, (int *) &dev->interrupt)) + BUGMSG(D_NORMAL, "Someone cleared our dev->interrupt flag!\n"); } void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp) { - if (dev->tbusy) - { + if (dev->tbusy) { #ifdef CONFIG_ARCNET_ETH - lp->edev->tbusy=0; + lp->edev->tbusy = 0; #endif #ifdef CONFIG_ARCNET_1051 - lp->sdev->tbusy=0; + lp->sdev->tbusy = 0; #endif - if (!test_and_clear_bit(0, (int *)&dev->tbusy)) - BUGMSG(D_NORMAL, "In arcnet_tx_done: Someone cleared our dev->tbusy" - " flag!\n"); + if (!test_and_clear_bit(0, (int *) &dev->tbusy)) + BUGMSG(D_NORMAL, "In arcnet_tx_done: Someone cleared our dev->tbusy" + " flag!\n"); - mark_bh(NET_BH); - } + mark_bh(NET_BH); + } } @@ -1026,53 +978,52 @@ void arcnet_tx_done(struct net_device *dev, struct arcnet_local *lp) * protocol ID found. */ -void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr, int daddr) +void arcnet_rx(struct arcnet_local *lp, u_char * arcsoft, short length, int saddr, int daddr) { - struct net_device *dev=lp->adev; - - BUGMSG(D_DURING,"received packet from %02Xh to %02Xh (%d bytes)\n", - saddr,daddr,length); - - /* call the right receiver for the protocol */ - switch (arcsoft[0]) - { - case ARC_P_IP: - case ARC_P_ARP: - case ARC_P_RARP: - case ARC_P_IPX: - case ARC_P_NOVELL_EC: - arcnetA_rx(lp->adev,arcsoft,length,saddr,daddr); - break; + struct net_device *dev = lp->adev; + + BUGMSG(D_DURING, "received packet from %02Xh to %02Xh (%d bytes)\n", + saddr, daddr, length); + + /* call the right receiver for the protocol */ + switch (arcsoft[0]) { + case ARC_P_IP: + case ARC_P_ARP: + case ARC_P_RARP: + case ARC_P_IPX: + case ARC_P_NOVELL_EC: + arcnetA_rx(lp->adev, arcsoft, length, saddr, daddr); + break; #ifdef CONFIG_ARCNET_ETH - case ARC_P_ETHER: - arcnetE_rx(lp->edev,arcsoft,length,saddr,daddr); - break; + case ARC_P_ETHER: + arcnetE_rx(lp->edev, arcsoft, length, saddr, daddr); + break; #endif #ifdef CONFIG_ARCNET_1051 - case ARC_P_IP_RFC1051: - case ARC_P_ARP_RFC1051: - arcnetS_rx(lp->sdev,arcsoft,length,saddr,daddr); - break; + case ARC_P_IP_RFC1051: + case ARC_P_ARP_RFC1051: + arcnetS_rx(lp->sdev, arcsoft, length, saddr, daddr); + break; #endif - case ARC_P_DATAPOINT_BOOT: - case ARC_P_DATAPOINT_MOUNT: - break; - case ARC_P_POWERLAN_BEACON: - case ARC_P_POWERLAN_BEACON2: - break; - case ARC_P_LANSOFT: /* don't understand. fall through. */ - default: - BUGMSG(D_EXTRA,"received unknown protocol %d (%Xh) from station %d.\n", - arcsoft[0],arcsoft[0],saddr); - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - break; - } - - /* If any worth-while packets have been received, a mark_bh(NET_BH) - * has been done by netif_rx and Linux will handle them after we - * return. - */ + case ARC_P_DATAPOINT_BOOT: + case ARC_P_DATAPOINT_MOUNT: + break; + case ARC_P_POWERLAN_BEACON: + case ARC_P_POWERLAN_BEACON2: + break; + case ARC_P_LANSOFT: /* don't understand. fall through. */ + default: + BUGMSG(D_EXTRA, "received unknown protocol %d (%Xh) from station %d.\n", + arcsoft[0], arcsoft[0], saddr); + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + break; + } + + /* If any worth-while packets have been received, a mark_bh(NET_BH) + * has been done by netif_rx and Linux will handle them after we + * return. + */ } @@ -1081,275 +1032,238 @@ void arcnet_rx(struct arcnet_local *lp, u_char *arcsoft, short length, int saddr /* Packet receiver for "standard" RFC1201-style packets */ -static void -arcnetA_rx(struct net_device *dev,u_char *buf, - int length, u_char saddr, u_char daddr) +static void arcnetA_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - struct sk_buff *skb; - struct ClientData *arcsoft,*soft; - - BUGMSG(D_DURING,"it's an RFC1201 packet (length=%d)\n", - length); - - /* compensate for EXTRA_CLIENTDATA (which isn't actually in the - * packet) - */ - arcsoft=(struct ClientData *)(buf-EXTRA_CLIENTDATA); - length+=EXTRA_CLIENTDATA; - - if (arcsoft->split_flag==0xFF) /* Exception Packet */ - { - BUGMSG(D_DURING,"compensating for exception packet\n"); - - /* skip over 4-byte junkola */ - arcsoft=(struct ClientData *) - ((u_char *)arcsoft + 4); - length-=4; - } - - if (!arcsoft->split_flag) /* not split */ - { - struct Incoming *in=&lp->incoming[saddr]; - - BUGMSG(D_RX,"incoming is not split (splitflag=%d)\n", - arcsoft->split_flag); - - if (in->skb) /* already assembling one! */ - { - BUGMSG(D_EXTRA,"aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n", - in->sequence,arcsoft->split_flag, - arcsoft->sequence); - lp->aborted_seq=arcsoft->sequence; - kfree_skb(in->skb); - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - in->skb=NULL; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + struct sk_buff *skb; + struct ClientData *arcsoft, *soft; + + BUGMSG(D_DURING, "it's an RFC1201 packet (length=%d)\n", + length); + + /* compensate for EXTRA_CLIENTDATA (which isn't actually in the + * packet) + */ + arcsoft = (struct ClientData *) (buf - EXTRA_CLIENTDATA); + length += EXTRA_CLIENTDATA; + + if (arcsoft->split_flag == 0xFF) { /* Exception Packet */ + BUGMSG(D_DURING, "compensating for exception packet\n"); + + /* skip over 4-byte junkola */ + arcsoft = (struct ClientData *) + ((u_char *) arcsoft + 4); + length -= 4; } + if (!arcsoft->split_flag) { /* not split */ + struct Incoming *in = &lp->incoming[saddr]; + + BUGMSG(D_RX, "incoming is not split (splitflag=%d)\n", + arcsoft->split_flag); + + if (in->skb) { /* already assembling one! */ + BUGMSG(D_EXTRA, "aborting assembly (seq=%d) for unsplit packet (splitflag=%d, seq=%d)\n", + in->sequence, arcsoft->split_flag, + arcsoft->sequence); + lp->aborted_seq = arcsoft->sequence; + kfree_skb(in->skb); + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + in->skb = NULL; + } + in->sequence = arcsoft->sequence; - in->sequence=arcsoft->sequence; - - skb = alloc_skb(length, GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } - soft=(struct ClientData *)skb->data; - - skb_put(skb,length); - skb->dev = dev; - - memcpy((u_char *)soft+EXTRA_CLIENTDATA, - (u_char *)arcsoft+EXTRA_CLIENTDATA, - length-EXTRA_CLIENTDATA); - soft->daddr=daddr; - soft->saddr=saddr; - - /* ARP packets have problems when sent from DOS. - * source address is always 0 on some systems! So we take - * the hardware source addr (which is impossible to fumble) - * and insert it ourselves. - */ - if (soft->protocol_id == ARC_P_ARP) - { - struct arphdr *arp=(struct arphdr *) - ((char *)soft+sizeof(struct ClientData)); - - /* make sure addresses are the right length */ - if (arp->ar_hln==1 && arp->ar_pln==4) - { - char *cptr=(char *)(arp)+sizeof(struct arphdr); - - if (!*cptr) /* is saddr = 00? */ - { - BUGMSG(D_EXTRA,"ARP source address was 00h, set to %02Xh.\n", - saddr); - lp->stats.rx_crc_errors++; - *cptr=saddr; + skb = alloc_skb(length, GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; } - else - { - BUGMSG(D_DURING,"ARP source address (%Xh) is fine.\n", - *cptr); + soft = (struct ClientData *) skb->data; + + skb_put(skb, length); + skb->dev = dev; + + memcpy((u_char *) soft + EXTRA_CLIENTDATA, + (u_char *) arcsoft + EXTRA_CLIENTDATA, + length - EXTRA_CLIENTDATA); + soft->daddr = daddr; + soft->saddr = saddr; + + /* ARP packets have problems when sent from DOS. + * source address is always 0 on some systems! So we take + * the hardware source addr (which is impossible to fumble) + * and insert it ourselves. + */ + if (soft->protocol_id == ARC_P_ARP) { + struct arphdr *arp = (struct arphdr *) + ((char *) soft + sizeof(struct ClientData)); + + /* make sure addresses are the right length */ + if (arp->ar_hln == 1 && arp->ar_pln == 4) { + char *cptr = (char *) (arp) + sizeof(struct arphdr); + + if (!*cptr) { /* is saddr = 00? */ + BUGMSG(D_EXTRA, "ARP source address was 00h, set to %02Xh.\n", + saddr); + lp->stats.rx_crc_errors++; + *cptr = saddr; + } else { + BUGMSG(D_DURING, "ARP source address (%Xh) is fine.\n", + *cptr); + } + } else { + BUGMSG(D_NORMAL, "funny-shaped ARP packet. (%Xh, %Xh)\n", + arp->ar_hln, arp->ar_pln); + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + } } - } - else - { - BUGMSG(D_NORMAL,"funny-shaped ARP packet. (%Xh, %Xh)\n", - arp->ar_hln,arp->ar_pln); - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - } - } + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); + + lp->stats.rx_bytes += skb->len; + skb->protocol = arcnetA_type_trans(skb, dev); + netif_rx(skb); + } else { /* split packet */ + /* NOTE: MSDOS ARP packet correction should only need to + * apply to unsplit packets, since ARP packets are so short. + * + * My interpretation of the RFC1201 (ARCnet) document is that + * if a packet is received out of order, the entire assembly + * process should be aborted. + * + * The RFC also mentions "it is possible for successfully + * received packets to be retransmitted." As of 0.40 all + * previously received packets are allowed, not just the + * most recent one. + * + * We allow multiple assembly processes, one for each + * ARCnet card possible on the network. Seems rather like + * a waste of memory. Necessary? + */ - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx"); - - lp->stats.rx_bytes += skb->len; - skb->protocol=arcnetA_type_trans(skb,dev); - netif_rx(skb); - } - else /* split packet */ - { - /* NOTE: MSDOS ARP packet correction should only need to - * apply to unsplit packets, since ARP packets are so short. - * - * My interpretation of the RFC1201 (ARCnet) document is that - * if a packet is received out of order, the entire assembly - * process should be aborted. - * - * The RFC also mentions "it is possible for successfully - * received packets to be retransmitted." As of 0.40 all - * previously received packets are allowed, not just the - * most recent one. - * - * We allow multiple assembly processes, one for each - * ARCnet card possible on the network. Seems rather like - * a waste of memory. Necessary? - */ - - struct Incoming *in=&lp->incoming[saddr]; - - BUGMSG(D_RX,"packet is split (splitflag=%d, seq=%d)\n", - arcsoft->split_flag,in->sequence); - - if (in->skb && in->sequence!=arcsoft->sequence) - { - BUGMSG(D_EXTRA,"wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n", - saddr,in->sequence,arcsoft->sequence, - arcsoft->split_flag); - kfree_skb(in->skb); - in->skb=NULL; - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - in->lastpacket=in->numpackets=0; - } + struct Incoming *in = &lp->incoming[saddr]; - if (arcsoft->split_flag & 1) /* first packet in split */ - { - BUGMSG(D_RX,"brand new splitpacket (splitflag=%d)\n", - arcsoft->split_flag); - if (in->skb) /* already assembling one! */ - { - BUGMSG(D_EXTRA,"aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n", - in->sequence,arcsoft->split_flag, - arcsoft->sequence); - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - kfree_skb(in->skb); - } - - in->sequence=arcsoft->sequence; - in->numpackets=((unsigned)arcsoft->split_flag>>1)+2; - in->lastpacket=1; - - if (in->numpackets>16) - { - BUGMSG(D_EXTRA,"incoming packet more than 16 segments; dropping. (splitflag=%d)\n", - arcsoft->split_flag); - lp->stats.rx_errors++; - lp->stats.rx_length_errors++; - return; - } - - in->skb=skb=alloc_skb(508*in->numpackets - + sizeof(struct ClientData), - GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"(split) memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } - - soft=(struct ClientData *)skb->data; - - skb_put(skb,sizeof(struct ClientData)); - skb->dev=dev; - - memcpy((u_char *)soft+EXTRA_CLIENTDATA, - (u_char *)arcsoft+EXTRA_CLIENTDATA, - sizeof(struct ClientData)-EXTRA_CLIENTDATA); - soft->split_flag=0; /* final packet won't be split */ - } - else /* not first packet */ - { - int packetnum=((unsigned)arcsoft->split_flag>>1) + 1; - - /* if we're not assembling, there's no point - * trying to continue. - */ - if (!in->skb) - { - if (lp->aborted_seq != arcsoft->sequence) - { - BUGMSG(D_EXTRA,"can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n", - arcsoft->split_flag,arcsoft->sequence, lp->aborted_seq); - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; + BUGMSG(D_RX, "packet is split (splitflag=%d, seq=%d)\n", + arcsoft->split_flag, in->sequence); + + if (in->skb && in->sequence != arcsoft->sequence) { + BUGMSG(D_EXTRA, "wrong seq number (saddr=%d, expected=%d, seq=%d, splitflag=%d)\n", + saddr, in->sequence, arcsoft->sequence, + arcsoft->split_flag); + kfree_skb(in->skb); + in->skb = NULL; + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + in->lastpacket = in->numpackets = 0; } - return; - } - - in->lastpacket++; - if (packetnum!=in->lastpacket) /* not the right flag! */ - { - /* harmless duplicate? ignore. */ - if (packetnum<=in->lastpacket-1) - { - BUGMSG(D_EXTRA,"duplicate splitpacket ignored! (splitflag=%d)\n", - arcsoft->split_flag); - lp->stats.rx_errors++; - lp->stats.rx_frame_errors++; - return; + if (arcsoft->split_flag & 1) { /* first packet in split */ + BUGMSG(D_RX, "brand new splitpacket (splitflag=%d)\n", + arcsoft->split_flag); + if (in->skb) { /* already assembling one! */ + BUGMSG(D_EXTRA, "aborting previous (seq=%d) assembly (splitflag=%d, seq=%d)\n", + in->sequence, arcsoft->split_flag, + arcsoft->sequence); + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + kfree_skb(in->skb); + } + in->sequence = arcsoft->sequence; + in->numpackets = ((unsigned) arcsoft->split_flag >> 1) + 2; + in->lastpacket = 1; + + if (in->numpackets > 16) { + BUGMSG(D_EXTRA, "incoming packet more than 16 segments; dropping. (splitflag=%d)\n", + arcsoft->split_flag); + lp->stats.rx_errors++; + lp->stats.rx_length_errors++; + return; + } + in->skb = skb = alloc_skb(508 * in->numpackets + + sizeof(struct ClientData), + GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "(split) memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; + } + soft = (struct ClientData *) skb->data; + + skb_put(skb, sizeof(struct ClientData)); + skb->dev = dev; + + memcpy((u_char *) soft + EXTRA_CLIENTDATA, + (u_char *) arcsoft + EXTRA_CLIENTDATA, + sizeof(struct ClientData) - EXTRA_CLIENTDATA); + soft->split_flag = 0; /* final packet won't be split */ + } else { /* not first packet */ + int packetnum = ((unsigned) arcsoft->split_flag >> 1) + 1; + + /* if we're not assembling, there's no point + * trying to continue. + */ + if (!in->skb) { + if (lp->aborted_seq != arcsoft->sequence) { + BUGMSG(D_EXTRA, "can't continue split without starting first! (splitflag=%d, seq=%d, aborted=%d)\n", + arcsoft->split_flag, arcsoft->sequence, lp->aborted_seq); + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + } + return; + } + in->lastpacket++; + if (packetnum != in->lastpacket) { /* not the right flag! */ + /* harmless duplicate? ignore. */ + if (packetnum <= in->lastpacket - 1) { + BUGMSG(D_EXTRA, "duplicate splitpacket ignored! (splitflag=%d)\n", + arcsoft->split_flag); + lp->stats.rx_errors++; + lp->stats.rx_frame_errors++; + return; + } + /* "bad" duplicate, kill reassembly */ + BUGMSG(D_EXTRA, "out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n", + in->sequence, arcsoft->split_flag, + arcsoft->sequence); + lp->aborted_seq = arcsoft->sequence; + kfree_skb(in->skb); + in->skb = NULL; + lp->stats.rx_errors++; + lp->stats.rx_missed_errors++; + in->lastpacket = in->numpackets = 0; + return; + } + soft = (struct ClientData *) in->skb->data; } - /* "bad" duplicate, kill reassembly */ - BUGMSG(D_EXTRA,"out-of-order splitpacket, reassembly (seq=%d) aborted (splitflag=%d, seq=%d)\n", - in->sequence,arcsoft->split_flag, - arcsoft->sequence); - lp->aborted_seq=arcsoft->sequence; - kfree_skb(in->skb); - in->skb=NULL; - lp->stats.rx_errors++; - lp->stats.rx_missed_errors++; - in->lastpacket=in->numpackets=0; - return; - } - - soft=(struct ClientData *)in->skb->data; - } + skb = in->skb; + + memcpy(skb->data + skb->len, + (u_char *) arcsoft + sizeof(struct ClientData), + length - sizeof(struct ClientData)); + skb_put(skb, length - sizeof(struct ClientData)); - skb=in->skb; - - memcpy(skb->data+skb->len, - (u_char *)arcsoft+sizeof(struct ClientData), - length-sizeof(struct ClientData)); - skb_put(skb,length-sizeof(struct ClientData)); - - soft->daddr=daddr; - soft->saddr=saddr; - - /* are we done? */ - if (in->lastpacket == in->numpackets) - { - if (!skb || !in->skb) - { - BUGMSG(D_NORMAL,"?!? done reassembling packet, no skb? (skb=%ph, in->skb=%ph)\n", - skb,in->skb); - } - else - { - in->skb=NULL; - in->lastpacket=in->numpackets=0; - - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx"); - - lp->stats.rx_bytes += skb->len; - skb->protocol=arcnetA_type_trans(skb,dev); - netif_rx(skb); - } + soft->daddr = daddr; + soft->saddr = saddr; + + /* are we done? */ + if (in->lastpacket == in->numpackets) { + if (!skb || !in->skb) { + BUGMSG(D_NORMAL, "?!? done reassembling packet, no skb? (skb=%ph, in->skb=%ph)\n", + skb, in->skb); + } else { + in->skb = NULL; + in->lastpacket = in->numpackets = 0; + + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); + + lp->stats.rx_bytes += skb->len; + skb->protocol = arcnetA_type_trans(skb, dev); + netif_rx(skb); + } + } } - } } @@ -1359,89 +1273,86 @@ arcnetA_rx(struct net_device *dev,u_char *buf, * * ****************************************************************************/ -/* Get the current statistics. This may be called with the card open or +/* Get the current statistics. This may be called with the card open or * closed. */ static struct net_device_stats *arcnet_get_stats(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - return &lp->stats; + return &lp->stats; } /* Create the ARCnet ClientData header for an arbitrary protocol layer - * - * saddr=NULL means use device source address (always will anyway) - * daddr=NULL means leave destination address (eg unresolved arp) + + * saddr=NULL means use device source address (always will anyway) + * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len) +static int arcnetA_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) { - struct ClientData *head = (struct ClientData *) - skb_push(skb,dev->hard_header_len); - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); - - BUGMSG(D_DURING,"create header from %d to %d; protocol %d (%Xh); size %u.\n", - saddr ? *(u_char*)saddr : -1, - daddr ? *(u_char*)daddr : -1, - type,type,len); - - /* set the protocol ID according to RFC1201 */ - switch(type) - { - case ETH_P_IP: - head->protocol_id=ARC_P_IP; - break; - case ETH_P_ARP: - head->protocol_id=ARC_P_ARP; - break; - case ETH_P_RARP: - head->protocol_id=ARC_P_RARP; - break; - case ETH_P_IPX: - case ETH_P_802_3: - case ETH_P_802_2: - head->protocol_id=ARC_P_IPX; - break; - case ETH_P_ATALK: - head->protocol_id=ARC_P_ATALK; - break; - default: - BUGMSG(D_NORMAL,"I don't understand protocol %d (%Xh)\n", - type,type); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - return 0; - } - - /* - * Set the source hardware address. - * - * This is pretty pointless for most purposes, but it can help - * in debugging. saddr is stored in the ClientData header and - * removed before sending the packet (since ARCnet does not allow - * us to change the source address in the actual packet sent) - */ - if(saddr) - head->saddr=((u_char*)saddr)[0]; - else - head->saddr=((u_char*)(dev->dev_addr))[0]; - - head->split_flag=0; /* split packets are done elsewhere */ - head->sequence=0; /* so are sequence numbers */ - - /* supposedly if daddr is NULL, we should ignore it... */ - if(daddr) - { - head->daddr=((u_char*)daddr)[0]; - return dev->hard_header_len; - } - else - head->daddr=0; /* better fill one in anyway */ - - return -dev->hard_header_len; + struct ClientData *head = (struct ClientData *) + skb_push(skb, dev->hard_header_len); + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + BUGMSG(D_DURING, "create header from %d to %d; protocol %d (%Xh); size %u.\n", + saddr ? *(u_char *) saddr : -1, + daddr ? *(u_char *) daddr : -1, + type, type, len); + + /* set the protocol ID according to RFC1201 */ + switch (type) { + case ETH_P_IP: + head->protocol_id = ARC_P_IP; + break; + case ETH_P_ARP: + head->protocol_id = ARC_P_ARP; + break; + case ETH_P_RARP: + head->protocol_id = ARC_P_RARP; + break; + case ETH_P_IPX: + case ETH_P_802_3: + case ETH_P_802_2: + head->protocol_id = ARC_P_IPX; + break; + case ETH_P_ATALK: + head->protocol_id = ARC_P_ATALK; + break; + default: + BUGMSG(D_NORMAL, "I don't understand protocol %d (%Xh)\n", + type, type); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + return 0; + } + + /* + * Set the source hardware address. + * + * This is pretty pointless for most purposes, but it can help + * in debugging. saddr is stored in the ClientData header and + * removed before sending the packet (since ARCnet does not allow + * us to change the source address in the actual packet sent) + */ + if (saddr) + head->saddr = ((u_char *) saddr)[0]; + else + head->saddr = ((u_char *) (dev->dev_addr))[0]; + + head->split_flag = 0; /* split packets are done elsewhere */ + head->sequence = 0; /* so are sequence numbers */ + + /* supposedly if daddr is NULL, we should ignore it... */ + if (daddr) { + head->daddr = ((u_char *) daddr)[0]; + return dev->hard_header_len; + } else + head->daddr = 0; /* better fill one in anyway */ + + return -dev->hard_header_len; } @@ -1451,86 +1362,84 @@ static int arcnetA_header(struct sk_buff *skb,struct net_device *dev, */ static int arcnetA_rebuild_header(struct sk_buff *skb) { - struct ClientData *head = (struct ClientData *)skb->data; - struct net_device *dev=skb->dev; - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); + struct ClientData *head = (struct ClientData *) skb->data; + struct net_device *dev = skb->dev; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); #ifdef CONFIG_INET - int status; + int status; #endif - /* - * Only ARP and IP are currently supported - * - * FIXME: Anyone want to spec IPv6 over ARCnet ? - */ - - if(head->protocol_id != ARC_P_IP) - { - BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n", - head->protocol_id,head->protocol_id); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - head->daddr=0; - /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len);*/ - return 0; - } - - /* - * Try to get ARP to resolve the header. - */ + /* + * Only ARP and IP are currently supported + * + * FIXME: Anyone want to spec IPv6 over ARCnet ? + */ + + if (head->protocol_id != ARC_P_IP) { + BUGMSG(D_NORMAL, "I don't understand protocol type %d (%Xh) addresses!\n", + head->protocol_id, head->protocol_id); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + head->daddr = 0; + /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len); */ + return 0; + } + /* + * Try to get ARP to resolve the header. + */ #ifdef CONFIG_INET - BUGMSG(D_DURING,"rebuild header from %d to %d; protocol %Xh\n", - head->saddr,head->daddr,head->protocol_id); - status=arp_find(&(head->daddr),skb)? 1 : 0; - BUGMSG(D_DURING," rebuilt: from %d to %d; protocol %Xh\n", - head->saddr,head->daddr,head->protocol_id); - return status; + BUGMSG(D_DURING, "rebuild header from %d to %d; protocol %Xh\n", + head->saddr, head->daddr, head->protocol_id); + status = arp_find(&(head->daddr), skb) ? 1 : 0; + BUGMSG(D_DURING, " rebuilt: from %d to %d; protocol %Xh\n", + head->saddr, head->daddr, head->protocol_id); + return status; #else - return 0; + return 0; #endif } /* Determine a packet's protocol ID. - * + * With ARCnet we have to convert everything to Ethernet-style stuff. */ -static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct net_device *dev) +static unsigned short arcnetA_type_trans(struct sk_buff *skb, struct net_device *dev) { - struct ClientData *head; - struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); - - /* Pull off the arcnet header. */ - skb->mac.raw=skb->data; - skb_pull(skb,dev->hard_header_len); - head=(struct ClientData *)skb->mac.raw; - - if (head->daddr==0) - skb->pkt_type=PACKET_BROADCAST; - else if (dev->flags&IFF_PROMISC) - { - /* if we're not sending to ourselves :) */ - if (head->daddr != dev->dev_addr[0]) - skb->pkt_type=PACKET_OTHERHOST; - } - - /* now return the protocol number */ - switch (head->protocol_id) - { - case ARC_P_IP: return htons(ETH_P_IP); - case ARC_P_ARP: return htons(ETH_P_ARP); - case ARC_P_RARP: return htons(ETH_P_RARP); - - case ARC_P_IPX: - case ARC_P_NOVELL_EC: - return htons(ETH_P_802_3); - default: - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - return 0; - } - - return htons(ETH_P_IP); + struct ClientData *head; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* Pull off the arcnet header. */ + skb->mac.raw = skb->data; + skb_pull(skb, dev->hard_header_len); + head = (struct ClientData *) skb->mac.raw; + + if (head->daddr == 0) + skb->pkt_type = PACKET_BROADCAST; + else if (dev->flags & IFF_PROMISC) { + /* if we're not sending to ourselves :) */ + if (head->daddr != dev->dev_addr[0]) + skb->pkt_type = PACKET_OTHERHOST; + } + /* now return the protocol number */ + switch (head->protocol_id) { + case ARC_P_IP: + return htons(ETH_P_IP); + case ARC_P_ARP: + return htons(ETH_P_ARP); + case ARC_P_RARP: + return htons(ETH_P_RARP); + + case ARC_P_IPX: + case ARC_P_NOVELL_EC: + return htons(ETH_P_802_3); + default: + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + return 0; + } + + return htons(ETH_P_IP); } @@ -1545,17 +1454,17 @@ static unsigned short arcnetA_type_trans(struct sk_buff *skb,struct net_device * */ static int arcnetE_init(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; - ether_setup(dev); /* we're emulating ether here, not ARCnet */ - dev->dev_addr[0]=0; - dev->dev_addr[5]=lp->stationid; - dev->mtu=512-sizeof(struct archdr)-dev->hard_header_len-1; - dev->open=arcnetE_open_close; - dev->stop=arcnetE_open_close; - dev->hard_start_xmit=arcnetE_send_packet; + ether_setup(dev); /* we're emulating ether here, not ARCnet */ + dev->dev_addr[0] = 0; + dev->dev_addr[5] = lp->stationid; + dev->mtu = 512 - sizeof(struct archdr) - dev->hard_header_len - 1; + dev->open = arcnetE_open_close; + dev->stop = arcnetE_open_close; + dev->hard_start_xmit = arcnetE_send_packet; - return 0; + return 0; } @@ -1564,86 +1473,77 @@ static int arcnetE_init(struct net_device *dev) */ static int arcnetE_open_close(struct net_device *dev) { - return 0; + return 0; } /* Called by the kernel in order to transmit an ethernet-type packet. */ -static int -arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) +static int arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int bad,oldmask=0; - u_char daddr; - short offset,length=skb->len+1; - u_char proto=ARC_P_ETHER; - - lp->intx++; - - oldmask |= lp->intmask; - lp->intmask=0; - SETMASK; - - bad=arcnet_send_packet_bad(skb,dev); - if (bad) - { - lp->intx--; - lp->intmask=oldmask; - SETMASK; - return bad; - } - - /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - - lp->intmask=oldmask; - SETMASK; - - if (length>XMTU) - { - BUGMSG(D_NORMAL,"MTU must be <= 493 for ethernet encap (length=%d).\n", - length); - BUGMSG(D_NORMAL,"transmit aborted.\n"); - - dev_kfree_skb(skb); - lp->intx--; - return 0; - } - - BUGMSG(D_DURING,"starting tx sequence...\n"); - - /* broadcasts have address FF:FF:FF:FF:FF:FF in etherspeak */ - if (((struct ethhdr*)(skb->data))->h_dest[0] == 0xFF) - daddr=0; - else - daddr=((struct ethhdr*)(skb->data))->h_dest[5]; - - /* load packet into shared memory */ - offset=512-length; - if (length>MTU) /* long/exception packet */ - { - if (length<MinTU) offset-=3; - } - else /* short packet */ - { - offset-=256; - } - - BUGMSG(D_DURING," length=%Xh, offset=%Xh\n", - length,offset); - - (*lp->prepare_tx)(dev, &proto, 1, skb->data, length-1, daddr, 0, - offset); + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int bad, oldmask = 0; + u_char daddr; + short offset, length = skb->len + 1; + u_char proto = ARC_P_ETHER; + + lp->intx++; + + oldmask |= lp->intmask; + lp->intmask = 0; + SETMASK; + + bad = arcnet_send_packet_bad(skb, dev); + if (bad) { + lp->intx--; + lp->intmask = oldmask; + SETMASK; + return bad; + } + /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - dev_kfree_skb(skb); + lp->intmask = oldmask; + SETMASK; + + if (length > XMTU) { + BUGMSG(D_NORMAL, "MTU must be <= 493 for ethernet encap (length=%d).\n", + length); + BUGMSG(D_NORMAL, "transmit aborted.\n"); + + dev_kfree_skb(skb); + lp->intx--; + return 0; + } + BUGMSG(D_DURING, "starting tx sequence...\n"); + + /* broadcasts have address FF:FF:FF:FF:FF:FF in etherspeak */ + if (((struct ethhdr *) (skb->data))->h_dest[0] == 0xFF) + daddr = 0; + else + daddr = ((struct ethhdr *) (skb->data))->h_dest[5]; + + /* load packet into shared memory */ + offset = 512 - length; + if (length > MTU) { /* long/exception packet */ + if (length < MinTU) + offset -= 3; + } else { /* short packet */ + offset -= 256; + } - if (arcnet_go_tx(dev,1)) - { - /* inform upper layers */ - arcnet_tx_done(lp->adev, lp); - } + BUGMSG(D_DURING, " length=%Xh, offset=%Xh\n", + length, offset); - dev->trans_start=jiffies; + (*lp->prepare_tx) (dev, &proto, 1, skb->data, length - 1, daddr, 0, + offset); + + dev_kfree_skb(skb); + + if (arcnet_go_tx(dev, 1)) { + /* inform upper layers */ + arcnet_tx_done(lp->adev, lp); + } + dev->trans_start = jiffies; lp->intx--; /* make sure we didn't ignore a TX IRQ while we were in here */ @@ -1656,37 +1556,35 @@ arcnetE_send_packet(struct sk_buff *skb, struct net_device *dev) /* Packet receiver for ethernet-encap packets. */ -static void -arcnetE_rx(struct net_device *dev,u_char *arcsoft, - int length,u_char saddr, u_char daddr) +static void arcnetE_rx(struct net_device *dev, u_char * arcsoft, + int length, u_char saddr, u_char daddr) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; struct sk_buff *skb; - BUGMSG(D_DURING,"it's an ethernet-encap packet (length=%d)\n", - length); - - skb = alloc_skb(length, GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } + BUGMSG(D_DURING, "it's an ethernet-encap packet (length=%d)\n", + length); - skb_put(skb,length); + skb = alloc_skb(length, GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; + } + skb_put(skb, length); - skb->dev = dev; + skb->dev = dev; - memcpy(skb->data,(u_char *)arcsoft+1,length-1); + memcpy(skb->data, (u_char *) arcsoft + 1, length - 1); - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx"); + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); lp->stats.rx_bytes += skb->len; - skb->protocol=eth_type_trans(skb,dev); - netif_rx(skb); + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); } -#endif /* CONFIG_ARCNET_ETH */ +#endif /* CONFIG_ARCNET_ETH */ #ifdef CONFIG_ARCNET_1051 /**************************************************************************** @@ -1699,22 +1597,22 @@ arcnetE_rx(struct net_device *dev,u_char *arcsoft, */ static int arcnetS_init(struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - - arcnet_setup(dev); - - /* And now fill particular fields with arcnet values */ - dev->dev_addr[0]=lp->stationid; - dev->hard_header_len=sizeof(struct S_ClientData); - dev->mtu=512-sizeof(struct archdr)-dev->hard_header_len - + S_EXTRA_CLIENTDATA; - dev->open=arcnetS_open_close; - dev->stop=arcnetS_open_close; - dev->hard_start_xmit=arcnetS_send_packet; - dev->hard_header=arcnetS_header; - dev->rebuild_header=arcnetS_rebuild_header; - - return 0; + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + + arcnet_setup(dev); + + /* And now fill particular fields with arcnet values */ + dev->dev_addr[0] = lp->stationid; + dev->hard_header_len = sizeof(struct S_ClientData); + dev->mtu = 512 - sizeof(struct archdr) - dev->hard_header_len + + S_EXTRA_CLIENTDATA; + dev->open = arcnetS_open_close; + dev->stop = arcnetS_open_close; + dev->hard_start_xmit = arcnetS_send_packet; + dev->hard_header = arcnetS_header; + dev->rebuild_header = arcnetS_rebuild_header; + + return 0; } @@ -1723,171 +1621,160 @@ static int arcnetS_init(struct net_device *dev) */ static int arcnetS_open_close(struct net_device *dev) { - return 0; + return 0; } /* Called by the kernel in order to transmit an RFC1051-type packet. */ -static int -arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev) +static int arcnetS_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - int bad,length; - struct S_ClientData *hdr=(struct S_ClientData *)skb->data; - - lp->intx++; - - bad=arcnet_send_packet_bad(skb,dev); - if (bad) - { - lp->intx--; - return bad; - } - - /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ - - length = 1 < skb->len ? skb->len : 1; - - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"tx"); - - /* fits in one packet? */ - if (length-S_EXTRA_CLIENTDATA<=XMTU) - { - (*lp->prepare_tx)(dev, - skb->data+S_EXTRA_CLIENTDATA, - sizeof(struct S_ClientData)-S_EXTRA_CLIENTDATA, - skb->data+sizeof(struct S_ClientData), - length-sizeof(struct S_ClientData), - hdr->daddr,0,0); - - /* done right away */ - dev_kfree_skb(skb); - - if (arcnet_go_tx(dev,1)) - { - /* inform upper layers */ - arcnet_tx_done(lp->adev, lp); + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + int bad, length; + struct S_ClientData *hdr = (struct S_ClientData *) skb->data; + + lp->intx++; + + bad = arcnet_send_packet_bad(skb, dev); + if (bad) { + lp->intx--; + return bad; } - } - else /* too big for one - not accepted */ - { - BUGMSG(D_NORMAL,"packet too long (length=%d)\n", - length); - dev_kfree_skb(skb); - lp->stats.tx_dropped++; - arcnet_tx_done(lp->adev, lp); - } - - dev->trans_start=jiffies; - lp->intx--; - - /* make sure we didn't ignore a TX IRQ while we were in here */ - lp->intmask |= TXFREEflag; - SETMASK; - - return 0; + /* arcnet_send_packet_pad has already set tbusy - don't bother here. */ + + length = 1 < skb->len ? skb->len : 1; + + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "tx"); + + /* fits in one packet? */ + if (length - S_EXTRA_CLIENTDATA <= XMTU) { + (*lp->prepare_tx) (dev, + skb->data + S_EXTRA_CLIENTDATA, + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA, + skb->data + sizeof(struct S_ClientData), + length - sizeof(struct S_ClientData), + hdr->daddr, 0, 0); + + /* done right away */ + dev_kfree_skb(skb); + + if (arcnet_go_tx(dev, 1)) { + /* inform upper layers */ + arcnet_tx_done(lp->adev, lp); + } + } else { /* too big for one - not accepted */ + BUGMSG(D_NORMAL, "packet too long (length=%d)\n", + length); + dev_kfree_skb(skb); + lp->stats.tx_dropped++; + arcnet_tx_done(lp->adev, lp); + } + + dev->trans_start = jiffies; + lp->intx--; + + /* make sure we didn't ignore a TX IRQ while we were in here */ + lp->intmask |= TXFREEflag; + SETMASK; + + return 0; } /* Packet receiver for RFC1051 packets; */ -static void -arcnetS_rx(struct net_device *dev,u_char *buf, - int length,u_char saddr, u_char daddr) +static void arcnetS_rx(struct net_device *dev, u_char * buf, + int length, u_char saddr, u_char daddr) { - struct arcnet_local *lp = (struct arcnet_local *)dev->priv; - struct sk_buff *skb; - struct S_ClientData *arcsoft,*soft; - - arcsoft=(struct S_ClientData *)(buf-S_EXTRA_CLIENTDATA); - length+=S_EXTRA_CLIENTDATA; - - BUGMSG(D_DURING,"it's an RFC1051 packet (length=%d)\n", - length); - - { /* was "if not split" in A protocol, S is never split */ - - skb = alloc_skb(length, GFP_ATOMIC); - if (skb == NULL) { - BUGMSG(D_NORMAL,"Memory squeeze, dropping packet.\n"); - lp->stats.rx_dropped++; - return; - } - soft=(struct S_ClientData *)skb->data; - skb_put(skb,length); - - memcpy((u_char *)soft + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA, - (u_char *)arcsoft + sizeof(struct S_ClientData) -S_EXTRA_CLIENTDATA, - length - sizeof(struct S_ClientData) + S_EXTRA_CLIENTDATA); - soft->protocol_id=arcsoft->protocol_id; - soft->daddr=daddr; - soft->saddr=saddr; - skb->dev = dev; /* is already lp->sdev */ - - BUGLVL(D_SKB) arcnet_dump_skb(dev,skb,"rx"); - - lp->stats.rx_bytes += skb->len; - skb->protocol=arcnetS_type_trans(skb,dev); - netif_rx(skb); - } + struct arcnet_local *lp = (struct arcnet_local *) dev->priv; + struct sk_buff *skb; + struct S_ClientData *arcsoft, *soft; + + arcsoft = (struct S_ClientData *) (buf - S_EXTRA_CLIENTDATA); + length += S_EXTRA_CLIENTDATA; + + BUGMSG(D_DURING, "it's an RFC1051 packet (length=%d)\n", + length); + + { /* was "if not split" in A protocol, S is never split */ + + skb = alloc_skb(length, GFP_ATOMIC); + if (skb == NULL) { + BUGMSG(D_NORMAL, "Memory squeeze, dropping packet.\n"); + lp->stats.rx_dropped++; + return; + } + soft = (struct S_ClientData *) skb->data; + skb_put(skb, length); + + memcpy((u_char *) soft + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA, + (u_char *) arcsoft + sizeof(struct S_ClientData) - S_EXTRA_CLIENTDATA, + length - sizeof(struct S_ClientData) + S_EXTRA_CLIENTDATA); + soft->protocol_id = arcsoft->protocol_id; + soft->daddr = daddr; + soft->saddr = saddr; + skb->dev = dev; /* is already lp->sdev */ + + BUGLVL(D_SKB) arcnet_dump_skb(dev, skb, "rx"); + + lp->stats.rx_bytes += skb->len; + skb->protocol = arcnetS_type_trans(skb, dev); + netif_rx(skb); + } } /* Create the ARCnet ClientData header for an arbitrary protocol layer - * - * saddr=NULL means use device source address (always will anyway) - * daddr=NULL means leave destination address (eg unresolved arp) + + * saddr=NULL means use device source address (always will anyway) + * daddr=NULL means leave destination address (eg unresolved arp) */ -static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, - unsigned short type,void *daddr,void *saddr,unsigned len) +static int arcnetS_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) { - struct S_ClientData *head = (struct S_ClientData *) - skb_push(skb,dev->hard_header_len); - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); - - /* set the protocol ID according to RFC1051 */ - switch(type) - { - case ETH_P_IP: - head->protocol_id=ARC_P_IP_RFC1051; - BUGMSG(D_DURING,"S_header: IP_RFC1051 packet.\n"); - break; - case ETH_P_ARP: - head->protocol_id=ARC_P_ARP_RFC1051; - BUGMSG(D_DURING,"S_header: ARP_RFC1051 packet.\n"); - break; - default: - BUGMSG(D_NORMAL,"I don't understand protocol %d (%Xh)\n", - type,type); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - return 0; - } - - /* - * Set the source hardware address. - * - * This is pretty pointless for most purposes, but it can help - * in debugging. saddr is stored in the ClientData header and - * removed before sending the packet (since ARCnet does not allow - * us to change the source address in the actual packet sent) - */ - if(saddr) - head->saddr=((u_char*)saddr)[0]; - else - head->saddr=((u_char*)(dev->dev_addr))[0]; - - /* supposedly if daddr is NULL, we should ignore it... */ - if(daddr) - { - head->daddr=((u_char*)daddr)[0]; + struct S_ClientData *head = (struct S_ClientData *) + skb_push(skb, dev->hard_header_len); + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* set the protocol ID according to RFC1051 */ + switch (type) { + case ETH_P_IP: + head->protocol_id = ARC_P_IP_RFC1051; + BUGMSG(D_DURING, "S_header: IP_RFC1051 packet.\n"); + break; + case ETH_P_ARP: + head->protocol_id = ARC_P_ARP_RFC1051; + BUGMSG(D_DURING, "S_header: ARP_RFC1051 packet.\n"); + break; + default: + BUGMSG(D_NORMAL, "I don't understand protocol %d (%Xh)\n", + type, type); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + return 0; + } + + /* + * Set the source hardware address. + * + * This is pretty pointless for most purposes, but it can help + * in debugging. saddr is stored in the ClientData header and + * removed before sending the packet (since ARCnet does not allow + * us to change the source address in the actual packet sent) + */ + if (saddr) + head->saddr = ((u_char *) saddr)[0]; + else + head->saddr = ((u_char *) (dev->dev_addr))[0]; + + /* supposedly if daddr is NULL, we should ignore it... */ + if (daddr) { + head->daddr = ((u_char *) daddr)[0]; return dev->hard_header_len; - } - else - head->daddr=0; /* better fill one in anyway */ + } else + head->daddr = 0; /* better fill one in anyway */ - return -dev->hard_header_len; + return -dev->hard_header_len; } @@ -1897,75 +1784,73 @@ static int arcnetS_header(struct sk_buff *skb,struct net_device *dev, */ static int arcnetS_rebuild_header(struct sk_buff *skb) { - struct net_device *dev=skb->dev; - struct S_ClientData *head = (struct S_ClientData *)skb->data; - struct arcnet_local *lp=(struct arcnet_local *)(dev->priv); - - /* - * Only ARP and IP are currently supported - */ - - if(head->protocol_id != ARC_P_IP_RFC1051) - { - BUGMSG(D_NORMAL,"I don't understand protocol type %d (%Xh) addresses!\n", - head->protocol_id,head->protocol_id); - lp->stats.tx_errors++; - lp->stats.tx_aborted_errors++; - head->daddr=0; - /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len);*/ - return 0; - } - - /* - * Try to get ARP to resolve the header. - */ + struct net_device *dev = skb->dev; + struct S_ClientData *head = (struct S_ClientData *) skb->data; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* + * Only ARP and IP are currently supported + */ + + if (head->protocol_id != ARC_P_IP_RFC1051) { + BUGMSG(D_NORMAL, "I don't understand protocol type %d (%Xh) addresses!\n", + head->protocol_id, head->protocol_id); + lp->stats.tx_errors++; + lp->stats.tx_aborted_errors++; + head->daddr = 0; + /*memcpy(eth->h_source, dev->dev_addr, dev->addr_len); */ + return 0; + } + /* + * Try to get ARP to resolve the header. + */ #ifdef CONFIG_INET - return arp_find(&(head->daddr),skb)? 1 : 0; + return arp_find(&(head->daddr), skb) ? 1 : 0; #else - return 0; + return 0; #endif } /* Determine a packet's protocol ID. - * + * With ARCnet we have to convert everything to Ethernet-style stuff. */ -unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev) +unsigned short arcnetS_type_trans(struct sk_buff *skb, struct net_device *dev) { - struct S_ClientData *head; - struct arcnet_local *lp=(struct arcnet_local *) (dev->priv); - - /* Pull off the arcnet header. */ - skb->mac.raw=skb->data; - skb_pull(skb,dev->hard_header_len); - head=(struct S_ClientData *)skb->mac.raw; - - if (head->daddr==0) - skb->pkt_type=PACKET_BROADCAST; - else if (dev->flags&IFF_PROMISC) - { - /* if we're not sending to ourselves :) */ - if (head->daddr != dev->dev_addr[0]) - skb->pkt_type=PACKET_OTHERHOST; - } - - /* now return the protocol number */ - switch (head->protocol_id) - { - case ARC_P_IP_RFC1051: return htons(ETH_P_IP); - case ARC_P_ARP_RFC1051: return htons(ETH_P_ARP); - case ARC_P_ATALK: return htons(ETH_P_ATALK); /* untested appletalk */ - default: - lp->stats.rx_errors++; - lp->stats.rx_crc_errors++; - return 0; - } - - return htons(ETH_P_IP); + struct S_ClientData *head; + struct arcnet_local *lp = (struct arcnet_local *) (dev->priv); + + /* Pull off the arcnet header. */ + skb->mac.raw = skb->data; + skb_pull(skb, dev->hard_header_len); + head = (struct S_ClientData *) skb->mac.raw; + + if (head->daddr == 0) + skb->pkt_type = PACKET_BROADCAST; + else if (dev->flags & IFF_PROMISC) { + /* if we're not sending to ourselves :) */ + if (head->daddr != dev->dev_addr[0]) + skb->pkt_type = PACKET_OTHERHOST; + } + /* now return the protocol number */ + switch (head->protocol_id) { + case ARC_P_IP_RFC1051: + return htons(ETH_P_IP); + case ARC_P_ARP_RFC1051: + return htons(ETH_P_ARP); + case ARC_P_ATALK: + return htons(ETH_P_ATALK); /* untested appletalk */ + default: + lp->stats.rx_errors++; + lp->stats.rx_crc_errors++; + return 0; + } + + return htons(ETH_P_IP); } -#endif /* CONFIG_ARCNET_1051 */ +#endif /* CONFIG_ARCNET_1051 */ /**************************************************************************** @@ -1978,15 +1863,15 @@ unsigned short arcnetS_type_trans(struct sk_buff *skb,struct net_device *dev) void cleanup_module(void) { - printk("Generic arcnet support removed.\n"); + printk("Generic arcnet support removed.\n"); } void arcnet_use_count(int open) { - if (open) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; + if (open) + MOD_INC_USE_COUNT; + else + MOD_DEC_USE_COUNT; } #else @@ -1996,54 +1881,52 @@ void arcnet_use_count(int open) } struct net_device arcnet_devs[MAX_ARCNET_DEVS]; -int arcnet_num_devs=0; +int arcnet_num_devs = 0; char arcnet_dev_names[MAX_ARCNET_DEVS][10]; -void __init arcnet_init(void) +int __init arcnet_init(void) { - int c; + int c; - init_module(); + init_module(); - /* Don't register_netdev here. The chain hasn't been initialised. */ + /* Don't register_netdev here. The chain hasn't been initialised. */ #ifdef CONFIG_ARCNET_COM90xx - if ((!com90xx_explicit) && arcnet_num_devs < MAX_ARCNET_DEVS) - { - arcnet_devs[arcnet_num_devs].init=arc90xx_probe; - arcnet_devs[arcnet_num_devs].name= - (char *)&arcnet_dev_names[arcnet_num_devs]; - arcnet_num_devs++; - } + if ((!com90xx_explicit) && arcnet_num_devs < MAX_ARCNET_DEVS) { + arcnet_devs[arcnet_num_devs].init = arc90xx_probe; + arcnet_devs[arcnet_num_devs].name = + (char *) &arcnet_dev_names[arcnet_num_devs]; + arcnet_num_devs++; + } #endif - if (!arcnet_num_devs) - { - printk("Don't forget to load the chipset driver.\n"); - return; - } - - /* Link into the device chain */ + if (!arcnet_num_devs) { + printk("Don't forget to load the chipset driver.\n"); + return 0; + } + /* Link into the device chain */ - /* Q: Should we put ourselves at the beginning or the end of the chain? */ - /* Probably the end, because we're not so fast, but... */ + /* Q: Should we put ourselves at the beginning or the end of the chain? */ + /* Probably the end, because we're not so fast, but... */ - for (c=0; c< (arcnet_num_devs-1); c++) - arcnet_devs[c].next=&arcnet_devs[c+1]; + for (c = 0; c < (arcnet_num_devs - 1); c++) + arcnet_devs[c].next = &arcnet_devs[c + 1]; - write_lock_bh(&dev_base_lock); - arcnet_devs[c].next=dev_base; - dev_base=&arcnet_devs[0]; - write_unlock_bh(&dev_base_lock); + write_lock_bh(&dev_base_lock); + arcnet_devs[c].next = dev_base; + dev_base = &arcnet_devs[0]; + write_unlock_bh(&dev_base_lock); - /* Give names to those without them */ + /* Give names to those without them */ - for (c=0; c< arcnet_num_devs; c++) - if (!arcnet_dev_names[c][0]) - arcnet_makename((char *)&arcnet_dev_names[c]); + for (c = 0; c < arcnet_num_devs; c++) + if (!arcnet_dev_names[c][0]) + arcnet_makename((char *) &arcnet_dev_names[c]); + return 0; } -#endif /* MODULE */ +#endif /* MODULE */ #ifdef MODULE @@ -2053,48 +1936,46 @@ static int __init init_module(void) #endif { #ifdef ALPHA_WARNING - BUGLVL(D_EXTRA) - { - printk("arcnet: ***\n"); - printk("arcnet: * Read arcnet.txt for important release notes!\n"); - printk("arcnet: *\n"); - printk("arcnet: * This is an ALPHA version! (Last stable release: v2.56) E-mail me if\n"); - printk("arcnet: * you have any questions, comments, or bug reports.\n"); - printk("arcnet: ***\n"); - } + BUGLVL(D_EXTRA) { + printk("arcnet: ***\n"); + printk("arcnet: * Read arcnet.txt for important release notes!\n"); + printk("arcnet: *\n"); + printk("arcnet: * This is an ALPHA version! (Last stable release: v2.56) E-mail me if\n"); + printk("arcnet: * you have any questions, comments, or bug reports.\n"); + printk("arcnet: ***\n"); + } #endif - printk("%sAvailable protocols: ARCnet RFC1201" + printk("%sAvailable protocols: ARCnet RFC1201" #ifdef CONFIG_ARCNET_ETH - ", Ethernet-Encap" + ", Ethernet-Encap" #endif #ifdef CONFIG_ARCNET_1051 - ", ARCnet RFC1051" + ", ARCnet RFC1051" #endif #ifdef MODULE - ".\nDon't forget to load the chipset driver" + ".\nDon't forget to load the chipset driver" #endif - ".\n",version); - return 0; + ".\n", version); + return 0; } void arcnet_makename(char *device) { - struct net_device *dev; - int arcnum; - - arcnum = 0; - for (;;) - { - sprintf(device, "arc%d", arcnum); - read_lock_bh(&dev_base_lock); - for (dev = dev_base; dev; dev=dev->next) - if (dev->name != device && !strcmp(dev->name, device)) - break; - read_unlock_bh(&dev_base_lock); - if (!dev) - return; - arcnum++; - } + struct net_device *dev; + int arcnum; + + arcnum = 0; + for (;;) { + sprintf(device, "arc%d", arcnum); + read_lock_bh(&dev_base_lock); + for (dev = dev_base; dev; dev = dev->next) + if (dev->name != device && !strcmp(dev->name, device)) + break; + read_unlock_bh(&dev_base_lock); + if (!dev) + return; + arcnum++; + } } diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c index f83fce38c..10d6cf208 100644 --- a/drivers/net/irda/actisys.c +++ b/drivers/net/irda/actisys.c @@ -7,7 +7,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Sat Jun 26 16:57:57 1999 + * Modified at: Mon Oct 18 23:37:06 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -32,33 +32,31 @@ #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/irda_device.h> -#include <net/irda/dongle.h> -static void actisys_reset(struct irda_device *dev); -static void actisys_open(struct irda_device *idev, int type); -static void actisys_close(struct irda_device *dev); -static void actisys_change_speed( struct irda_device *dev, __u32 speed); -static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos); +static int actisys_change_speed(struct irda_task *task); +static int actisys_reset(struct irda_task *task); +static void actisys_open(dongle_t *self, struct qos_info *qos); +static void actisys_close(dongle_t *self); /* These are the baudrates supported */ -static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400}; +static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400 }; -static struct dongle dongle = { - ACTISYS_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_ACTISYS_DONGLE, actisys_open, actisys_close, actisys_reset, actisys_change_speed, - actisys_init_qos, }; -static struct dongle dongle_plus = { - ACTISYS_PLUS_DONGLE, +static struct dongle_reg dongle_plus = { + Q_NULL, + IRDA_ACTISYS_PLUS_DONGLE, actisys_open, actisys_close, actisys_reset, actisys_change_speed, - actisys_init_qos, }; int __init actisys_init(void) @@ -82,20 +80,23 @@ void actisys_cleanup(void) irda_device_unregister_dongle(&dongle_plus); } -static void actisys_open(struct irda_device *idev, int type) +static void actisys_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> actisys"); + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; + /* Remove support for 38400 if this is not a 220L+ dongle */ + if (self->issue->type == IRDA_ACTISYS_DONGLE) + qos->baud_rate.bits &= ~IR_38400; + + qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ MOD_INC_USE_COUNT; } -static void actisys_close(struct irda_device *idev) +static void actisys_close(dongle_t *self) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } @@ -107,52 +108,84 @@ static void actisys_close(struct irda_device *idev) * To cycle through the available baud rates, pulse RTS low for a few * ms. */ -static void actisys_change_speed(struct irda_device *idev, __u32 speed) +static int actisys_change_speed(struct irda_task *task) { - __u32 current_baudrate; + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; + __u32 current_speed; int index = 0; + int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - current_baudrate = idev->qos.baud_rate.value; + current_speed = self->speed; /* Find the correct baudrate index for the currently used baudrate */ - while (current_baudrate != baud_rates[index]) + while (current_speed != baud_rates[index]) index++; - DEBUG( 4, __FUNCTION__ "(), index=%d\n", index); + IRDA_DEBUG(4, __FUNCTION__ "(), index=%d\n", index); - /* Cycle through avaiable baudrates until we reach the correct one */ - while (current_baudrate != speed) { - DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", + switch (task->state) { + case IRDA_TASK_INIT: + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + ret = MSECS_TO_JIFFIES(100); + break; + } + + IRDA_DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", baud_rates[index]); /* Set DTR, clear RTS */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); + self->set_dtr_rts(self->dev, TRUE, FALSE); - /* Wait at a few ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + irda_task_next_state(task, IRDA_TASK_WAIT1); + /* Wait at a few ms */ + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT1: /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); - /* Wait at a few ms again */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + irda_task_next_state(task, IRDA_TASK_WAIT2); + /* Wait at a few ms again */ + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT2: /* Go to next baudrate */ - if (idev->io.dongle_id == ACTISYS_DONGLE) + if (self->issue->type == IRDA_ACTISYS_DONGLE) index = (index+1) % 4; /* IR-220L */ else index = (index+1) % 5; /* IR-220L+ */ - current_baudrate = baud_rates[index]; + current_speed = baud_rates[index]; + + /* Check if we need to go some more rounds */ + if (current_speed != speed) + irda_task_next_state(task, IRDA_TASK_INIT); + else { + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + } + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + ret = -1; + break; } - DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", baud_rates[index]); + + self->speed = speed; + + IRDA_DEBUG(4, __FUNCTION__ "(), current baudrate = %d\n", + baud_rates[index]); + + return ret; } /* @@ -162,45 +195,42 @@ static void actisys_change_speed(struct irda_device *idev, __u32 speed) * called with a process context! * * 1. Clear DTR for a few ms. - * */ -static void actisys_reset(struct irda_device *idev) +static int actisys_reset(struct irda_task *task) { - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - /* Clear DTR */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); + dongle_t *self = (dongle_t *) task->instance; + int ret = 0; - /* Sleep 10-20 ms*/ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); - - /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); - - idev->qos.baud_rate.value = 9600; -} + ASSERT(task != NULL, return -1;); -/* - * Function actisys_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void actisys_init_qos(struct irda_device *idev, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + switch (task->state) { + case IRDA_TASK_INIT: + /* Clear DTR */ + self->set_dtr_rts(self->dev, FALSE, TRUE); + + irda_task_next_state(task, IRDA_TASK_WAIT); - /* Remove support for 38400 if this is not a 220L+ dongle */ - if (idev->io.dongle_id == ACTISYS_DONGLE) - qos->baud_rate.bits &= ~IR_38400; + /* Sleep 10-20 ms*/ + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT: + /* Go back to normal mode */ + self->set_dtr_rts(self->dev, TRUE, TRUE); - qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ + irda_task_next_state(task, IRDA_TASK_DONE); + + self->speed = 9600; + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + ret = -1; + break; + } + return ret; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver"); @@ -225,5 +255,4 @@ void cleanup_module(void) { actisys_cleanup(); } - -#endif +#endif /* MODULE */ diff --git a/drivers/net/irda/airport.c b/drivers/net/irda/airport.c index edfc2e6e6..a1eee252b 100644 --- a/drivers/net/irda/airport.c +++ b/drivers/net/irda/airport.c @@ -56,7 +56,7 @@ int __init airport_init(void) { int ret; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ret = irda_device_register_dongle(&dongle); if (ret < 0) return ret; @@ -65,17 +65,17 @@ int __init airport_init(void) void airport_cleanup(void) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); irda_device_unregister_dongle(&dongle); } static void airport_open(struct irda_device *idev, int type) { - DEBUG(2, __FUNCTION__ "(,%d)\n", type); + IRDA_DEBUG(2, __FUNCTION__ "(,%d)\n", type); if (strlen(idev->description) < sizeof(idev->description) - 13) strcat(idev->description, " <-> airport"); else - DEBUG(0, __FUNCTION__ " description too long: %s\n", + IRDA_DEBUG(0, __FUNCTION__ " description too long: %s\n", idev->description); idev->io.dongle_id = type; @@ -86,7 +86,7 @@ static void airport_open(struct irda_device *idev, int type) static void airport_close(struct irda_device *idev) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); /* Power off dongle */ irda_device_set_dtr_rts(idev, FALSE, FALSE); @@ -95,13 +95,13 @@ static void airport_close(struct irda_device *idev) static void airport_set_command_mode(struct irda_device *idev) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); irda_device_set_dtr_rts(idev, FALSE, TRUE); } static void airport_set_normal_mode(struct irda_device *idev) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); irda_device_set_dtr_rts(idev, TRUE, TRUE); } @@ -109,7 +109,7 @@ static void airport_set_normal_mode(struct irda_device *idev) void airport_write_char(struct irda_device *idev, unsigned char c) { int actual; - DEBUG(2, __FUNCTION__ "(,0x%x)\n", c & 0xff); + IRDA_DEBUG(2, __FUNCTION__ "(,0x%x)\n", c & 0xff); actual = idev->raw_write(idev, &c, 1); ASSERT(actual == 1, return;); } @@ -120,22 +120,22 @@ static int airport_waitfor_char(struct irda_device *idev, unsigned char c) { int i, found = FALSE; int before; - DEBUG(2, __FUNCTION__ "(,0x%x)\n", c); + IRDA_DEBUG(2, __FUNCTION__ "(,0x%x)\n", c); /* Sleep approx. 10 ms */ before = jiffies; current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(20)); - DEBUG(4, __FUNCTION__ " waited %ldms\n", + IRDA_DEBUG(4, __FUNCTION__ " waited %ldms\n", JIFFIES_TO_MSECS(jiffies - before)); for ( i = 0 ; !found && i < idev->rx_buff.len ; i++ ) { - /* DEBUG(6, __FUNCTION__ " 0x02x\n", idev->rx_buff.data[i]); */ + /* IRDA_DEBUG(6, __FUNCTION__ " 0x02x\n", idev->rx_buff.data[i]); */ found = c == idev->rx_buff.data[i]; } idev->rx_buff.len = 0; - DEBUG(2, __FUNCTION__ " returns %s\n", (found ? "true" : "false")); + IRDA_DEBUG(2, __FUNCTION__ " returns %s\n", (found ? "true" : "false")); return found; } @@ -144,7 +144,7 @@ static int airport_check_command_mode(struct irda_device *idev) int i; int found = FALSE; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(20)); airport_set_command_mode(idev); @@ -160,9 +160,9 @@ static int airport_check_command_mode(struct irda_device *idev) } if (found) { - DEBUG(2, __FUNCTION__ " OK. (%d)\n", i); + IRDA_DEBUG(2, __FUNCTION__ " OK. (%d)\n", i); } else { - DEBUG(0, __FUNCTION__ " FAILED!\n"); + IRDA_DEBUG(0, __FUNCTION__ " FAILED!\n"); } return found; } @@ -173,7 +173,7 @@ static int airport_write_register(struct irda_device *idev, unsigned char reg) int ok = FALSE; int i; - DEBUG(4, __FUNCTION__ "(,0x%x)\n", reg); + IRDA_DEBUG(4, __FUNCTION__ "(,0x%x)\n", reg); airport_check_command_mode(idev); for ( i = 0 ; i < 6 ; i++ ) { @@ -191,9 +191,9 @@ static int airport_write_register(struct irda_device *idev, unsigned char reg) airport_set_normal_mode(idev); if (ok) { - DEBUG(4, __FUNCTION__ "(,0x%x) returns OK\n", reg); + IRDA_DEBUG(4, __FUNCTION__ "(,0x%x) returns OK\n", reg); } else { - DEBUG(0, __FUNCTION__ "(,0x%x) returns False!\n", reg); + IRDA_DEBUG(0, __FUNCTION__ "(,0x%x) returns False!\n", reg); } return ok; } @@ -209,7 +209,7 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) __u32 current_baudrate; int baudcode; - DEBUG(4, __FUNCTION__ "(,%d)\n", speed); + IRDA_DEBUG(4, __FUNCTION__ "(,%d)\n", speed); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -224,16 +224,16 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) case 57600: baudcode = 0x60; break; case 115200: baudcode = 0x70; break; default: - DEBUG(0, __FUNCTION__ " bad baud rate: %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ " bad baud rate: %d\n", speed); return; } current_baudrate = idev->qos.baud_rate.value; - DEBUG(4, __FUNCTION__ " current baudrate: %d\n", current_baudrate); + IRDA_DEBUG(4, __FUNCTION__ " current baudrate: %d\n", current_baudrate); /* The dongle falls back to 9600 baud */ if (current_baudrate != 9600) { - DEBUG(4, __FUNCTION__ " resetting speed to 9600 baud\n"); + IRDA_DEBUG(4, __FUNCTION__ " resetting speed to 9600 baud\n"); ASSERT(idev->change_speed , return;); idev->change_speed(idev, 9600); idev->qos.baud_rate.value = 9600; @@ -247,11 +247,11 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) if (airport_write_register(idev, baudcode|0x01)) { /* ok */ } else { - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ " Cannot set new speed in second register\n"); } } else { - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ " Cannot set new speed in first register\n"); } @@ -260,7 +260,7 @@ static void airport_change_speed(struct irda_device *idev, __u32 speed) /* How do I signal an error in these functions? */ - DEBUG(4, __FUNCTION__ " returning\n"); + IRDA_DEBUG(4, __FUNCTION__ " returning\n"); } @@ -275,7 +275,7 @@ static void airport_reset(struct irda_device *idev) { int ok; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); ASSERT(idev->set_raw_mode /* The airport needs this */, return;); @@ -286,10 +286,10 @@ static void airport_reset(struct irda_device *idev) airport_set_normal_mode(idev); /* Sleep 2000 ms */ - DEBUG(2, __FUNCTION__ " waiting for powerup\n"); + IRDA_DEBUG(2, __FUNCTION__ " waiting for powerup\n"); current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(2000)); - DEBUG(2, __FUNCTION__ " finished waiting for powerup\n"); + IRDA_DEBUG(2, __FUNCTION__ " finished waiting for powerup\n"); /* set dongle speed to 9600 */ ok = TRUE; @@ -322,12 +322,12 @@ static void airport_reset(struct irda_device *idev) current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(20)); - DEBUG(4, __FUNCTION__ " waited 20ms\n"); + IRDA_DEBUG(4, __FUNCTION__ " waited 20ms\n"); idev->qos.baud_rate.value = 9600; if (!ok) MESSAGE(__FUNCTION__ "() failed.\n"); - DEBUG(2, __FUNCTION__ " returning.\n"); + IRDA_DEBUG(2, __FUNCTION__ " returning.\n"); } /* diff --git a/drivers/net/irda/esi.c b/drivers/net/irda/esi.c index f531c1af4..bc6f28da7 100644 --- a/drivers/net/irda/esi.c +++ b/drivers/net/irda/esi.c @@ -1,27 +1,33 @@ /********************************************************************* * * Filename: esi.c - * Version: 1.4 + * Version: 1.5 * Description: Driver for the Extended Systems JetEye PC dongle * Status: Experimental. - * Author: Thomas Davis, <ratbert@radiks.net> + * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Feb 21 18:54:38 1998 - * Modified at: Sat Jun 26 16:50:17 1999 + * Modified at: Mon Oct 18 12:35:43 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> - * Sources: esi.c - * - * Copyright (c) 1998-1999, Dag Brattli, <dagb@cs.uit.no> - * Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>, + * + * Copyright (c) 1999 Dag Brattli, <dagb@cs.uit.no>, + * 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 + * + * 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. - * + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * ********************************************************************/ #include <linux/module.h> @@ -34,22 +40,19 @@ #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/irda_device.h> -#include <net/irda/irtty.h> -#include <net/irda/dongle.h> -static void esi_open(struct irda_device *idev, int type); -static void esi_close(struct irda_device *driver); -static void esi_change_speed(struct irda_device *idev, __u32 speed); -static void esi_reset(struct irda_device *idev); -static void esi_qos_init(struct irda_device *idev, struct qos_info *qos); +static void esi_open(dongle_t *self, struct qos_info *qos); +static void esi_close(dongle_t *self); +static int esi_change_speed(struct irda_task *task); +static int esi_reset(struct irda_task *task); -static struct dongle dongle = { - ESI_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_ESI_DONGLE, esi_open, esi_close, esi_reset, esi_change_speed, - esi_qos_init, }; int __init esi_init(void) @@ -62,37 +65,40 @@ void esi_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void esi_open(struct irda_device *idev, int type) +static void esi_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> esi"); - - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; + qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200; + qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */ MOD_INC_USE_COUNT; } -static void esi_close(struct irda_device *idev) +static void esi_close(dongle_t *dongle) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + dongle->set_dtr_rts(dongle->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } /* - * Function esi_change_speed (idev, speed) + * Function esi_change_speed (task) * * Set the speed for the Extended Systems JetEye PC ESI-9680 type dongle * */ -static void esi_change_speed(struct irda_device *idev, __u32 speed) +static int esi_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; int dtr, rts; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + return MSECS_TO_JIFFIES(100); + } + switch (speed) { case 19200: dtr = TRUE; @@ -109,28 +115,34 @@ static void esi_change_speed(struct irda_device *idev, __u32 speed) } /* Change speed of dongle */ - irda_device_set_dtr_rts(idev, dtr, rts); -} + self->set_dtr_rts(self->dev, dtr, rts); + self->speed = speed; -static void esi_reset( struct irda_device *idev) -{ - /* Empty */ + irda_task_next_state(task, IRDA_TASK_DONE); + + /* Unlock */ + self->busy = 0; + + return 0; } /* - * Function esi_qos_init (qos) + * Function esi_reset (task) * - * Init QoS capabilities for the dongle + * Reset dongle; * */ -static void esi_qos_init(struct irda_device *idev, struct qos_info *qos) +static int esi_reset(struct irda_task *task) { - qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200; - qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */ + dongle_t *self = (dongle_t *) task->instance; + + self->set_dtr_rts(self->dev, FALSE, FALSE); + irda_task_next_state(task, IRDA_TASK_DONE); + + return 0; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver"); @@ -155,6 +167,5 @@ void cleanup_module(void) { esi_cleanup(); } - -#endif +#endif /* MODULE */ diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c index 2d1d1f269..4fa2ec59f 100644 --- a/drivers/net/irda/girbil.c +++ b/drivers/net/irda/girbil.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Feb 6 21:02:33 1999 - * Modified at: Sun Jul 18 12:09:26 1999 + * Modified at: Mon Oct 18 22:15:20 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -32,13 +32,11 @@ #include <net/irda/irmod.h> #include <net/irda/irda_device.h> #include <net/irda/irtty.h> -#include <net/irda/dongle.h> -static void girbil_reset(struct irda_device *dev); -static void girbil_open(struct irda_device *dev, int type); -static void girbil_close(struct irda_device *dev); -static void girbil_change_speed(struct irda_device *dev, __u32 speed); -static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos); +static int girbil_reset(struct irda_task *task); +static void girbil_open(dongle_t *self, struct qos_info *qos); +static void girbil_close(dongle_t *self); +static int girbil_change_speed(struct irda_task *task); /* Control register 1 */ #define GIRBIL_TXEN 0x01 /* Enable transmitter */ @@ -67,13 +65,13 @@ static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos); /* Control register 2 (0x5) */ #define GIRBIL_LOAD 0x51 /* Load the new baud rate value */ -static struct dongle dongle = { - GIRBIL_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_GIRBIL_DONGLE, girbil_open, girbil_close, girbil_reset, girbil_change_speed, - girbil_init_qos, }; int __init girbil_init(void) @@ -86,20 +84,18 @@ void girbil_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void girbil_open(struct irda_device *idev, int type) +static void girbil_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> girbil"); + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + qos->min_turn_time.bits &= 0x03; - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; - MOD_INC_USE_COUNT; } -static void girbil_close(struct irda_device *idev) +static void girbil_close(dongle_t *self) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } @@ -111,47 +107,80 @@ static void girbil_close(struct irda_device *idev) * function must be called with a process context! * */ -static void girbil_change_speed(struct irda_device *idev, __u32 speed) +static int girbil_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; __u8 control[2]; - - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - switch (speed) { - case 9600: - default: - control[0] = GIRBIL_9600; + int ret = 0; + + switch (task->state) { + case IRDA_TASK_INIT: + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + return MSECS_TO_JIFFIES(100); + } + + /* Need to reset the dongle and go to 9600 bps before + programming */ + if (irda_task_execute(self, girbil_reset, NULL, task, + (void *) speed)) + { + /* Dongle need more time to reset */ + irda_task_next_state(task, IRDA_TASK_CHILD_WAIT); + + /* Give reset 1 sec to finish */ + ret = MSECS_TO_JIFFIES(1000); + } break; - case 19200: - control[0] = GIRBIL_19200; + case IRDA_TASK_CHILD_WAIT: + WARNING(__FUNCTION__ "(), resetting dongle timed out!\n"); + ret = -1; break; - case 34800: - control[0] = GIRBIL_38400; + case IRDA_TASK_CHILD_DONE: + /* Set DTR and Clear RTS to enter command mode */ + self->set_dtr_rts(self->dev, FALSE, TRUE); + + switch (speed) { + case 9600: + default: + control[0] = GIRBIL_9600; + break; + case 19200: + control[0] = GIRBIL_19200; + break; + case 34800: + control[0] = GIRBIL_38400; + break; + case 57600: + control[0] = GIRBIL_57600; + break; + case 115200: + control[0] = GIRBIL_115200; + break; + } + control[1] = GIRBIL_LOAD; + + /* Write control bytes */ + self->write(self->dev, control, 2); + irda_task_next_state(task, IRDA_TASK_WAIT); + ret = MSECS_TO_JIFFIES(100); break; - case 57600: - control[0] = GIRBIL_57600; + case IRDA_TASK_WAIT: + /* Go back to normal mode */ + self->set_dtr_rts(self->dev, TRUE, TRUE); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; break; - case 115200: - control[0] = GIRBIL_115200; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + ret = -1; break; } - control[1] = GIRBIL_LOAD; - - /* Need to reset the dongle and go to 9600 bps before programming */ - girbil_reset(idev); - - /* Set DTR and Clear RTS to enter command mode */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); - - /* Write control bytes */ - irda_device_raw_write(idev, control, 2); - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(100)); - - /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + return ret; } /* @@ -164,54 +193,47 @@ static void girbil_change_speed(struct irda_device *idev, __u32 speed) * 0. set RTS, and wait at least 5 ms * 1. clear RTS */ -void girbil_reset(struct irda_device *idev) +static int girbil_reset(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; __u8 control = GIRBIL_TXEN | GIRBIL_RXEN; - - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - /* Make sure the IrDA chip also goes to defalt speed */ - if (idev->change_speed) - idev->change_speed(idev, 9600); - - /* Reset dongle */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); - - /* Sleep at least 5 ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(10)); - - /* Set DTR and clear RTS to enter command mode */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(10)); - - /* Write control byte */ - irda_device_raw_write(idev, &control, 1); - - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); - - /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); -} - -/* - * Function girbil_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void girbil_init_qos(struct irda_device *idev, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits &= 0x03; + int ret = 0; + + switch (task->state) { + case IRDA_TASK_INIT: + /* Reset dongle */ + self->set_dtr_rts(self->dev, TRUE, FALSE); + irda_task_next_state(task, IRDA_TASK_WAIT1); + /* Sleep at least 5 ms */ + ret = MSECS_TO_JIFFIES(10); + break; + case IRDA_TASK_WAIT1: + /* Set DTR and clear RTS to enter command mode */ + self->set_dtr_rts(self->dev, FALSE, TRUE); + irda_task_next_state(task, IRDA_TASK_WAIT2); + ret = MSECS_TO_JIFFIES(10); + break; + case IRDA_TASK_WAIT2: + /* Write control byte */ + self->write(self->dev, &control, 1); + irda_task_next_state(task, IRDA_TASK_WAIT3); + ret = MSECS_TO_JIFFIES(20); + break; + case IRDA_TASK_WAIT3: + /* Go back to normal mode */ + self->set_dtr_rts(self->dev, TRUE, TRUE); + irda_task_next_state(task, IRDA_TASK_DONE); + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + ret = -1; + break; + } + return ret; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver"); @@ -236,5 +258,4 @@ void cleanup_module(void) { girbil_cleanup(); } - #endif /* MODULE */ diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index b60241a40..d4f4f6d71 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Tue Aug 31 13:54:27 1999 + * Modified at: Wed Oct 20 00:07:42 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: serial.c by Linus Torvalds * @@ -48,6 +48,7 @@ #include <linux/errno.h> #include <linux/init.h> #include <linux/spinlock.h> +#include <linux/rtnetlink.h> #include <asm/system.h> #include <asm/bitops.h> @@ -69,22 +70,22 @@ static unsigned int irq[] = { 0, 0, 0, 0 }; static unsigned int qos_mtt_bits = 0x03; -static struct irda_device *dev_self[] = { NULL, NULL, NULL, NULL}; +static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL}; static char *driver_name = "irport"; static int irport_open(int i, unsigned int iobase, unsigned int irq); -static int irport_close(struct irda_device *idev); +static int irport_close(struct irport_cb *self); -static void irport_write_wakeup(struct irda_device *idev); +static void irport_write_wakeup(struct irport_cb *self); static int irport_write(int iobase, int fifo_size, __u8 *buf, int len); -static void irport_receive(struct irda_device *idev); +static void irport_receive(struct irport_cb *self); static int irport_net_init(struct net_device *dev); static int irport_net_open(struct net_device *dev); static int irport_net_close(struct net_device *dev); -static int irport_is_receiving(struct irda_device *idev); -static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts); -static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len); +static int irport_is_receiving(struct irport_cb *self); +static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts); +static int irport_raw_write(struct net_device *dev, __u8 *buf, int len); int __init irport_init(void) { @@ -114,7 +115,7 @@ static void irport_cleanup(void) { int i; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) @@ -125,108 +126,154 @@ static void irport_cleanup(void) static int irport_open(int i, unsigned int iobase, unsigned int irq) { - struct irda_device *idev; + struct net_device *dev; + struct irport_cb *self; int ret; + int err; - DEBUG( 0, __FUNCTION__ "()\n"); - -/* if (irport_probe(iobase, irq) == -1) */ -/* return -1; */ + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* * Allocate new instance of the driver */ - idev = kmalloc(sizeof(struct irda_device), GFP_KERNEL); - if (idev == NULL) { - printk( KERN_ERR "IrDA: Can't allocate memory for " - "IrDA control block!\n"); + self = kmalloc(sizeof(struct irport_cb), GFP_KERNEL); + if (!self) { + ERROR(__FUNCTION__ "(), can't allocate memory for " + "control block!\n"); return -ENOMEM; } - memset(idev, 0, sizeof(struct irda_device)); + memset(self, 0, sizeof(struct irport_cb)); + spin_lock_init(&self->lock); + /* Need to store self somewhere */ - dev_self[i] = idev; + dev_self[i] = self; /* Initialize IO */ - idev->io.iobase2 = iobase; - idev->io.irq2 = irq; - idev->io.io_ext = IO_EXTENT; - idev->io.fifo_size = 16; - - idev->netdev.base_addr = iobase; - idev->netdev.irq = irq; + self->io.iobase2 = iobase; + self->io.irq2 = irq; + self->io.io_ext = IO_EXTENT; + self->io.fifo_size = 16; /* Lock the port that we need */ - ret = check_region(idev->io.iobase2, idev->io.io_ext); + ret = check_region(self->io.iobase2, self->io.io_ext); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", - idev->io.iobase2); - /* irport_cleanup(self->idev); */ + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + self->io.iobase2); + /* irport_cleanup(self->self); */ return -ENODEV; } - request_region(idev->io.iobase2, idev->io.io_ext, idev->name); + request_region(self->io.iobase2, self->io.io_ext, driver_name); /* Initialize QoS for this device */ - irda_init_max_qos_capabilies(&idev->qos); + irda_init_max_qos_capabilies(&self->qos); - idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200; - idev->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&idev->qos); + self->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&self->qos); - idev->flags = IFF_SIR|IFF_PIO; + self->flags = IFF_SIR|IFF_PIO; - /* Specify which buffer allocation policy we need */ - idev->rx_buff.flags = GFP_KERNEL; - idev->tx_buff.flags = GFP_KERNEL; - - idev->rx_buff.truesize = 4000; - idev->tx_buff.truesize = 4000; + /* Specify how much memory we want */ + self->rx_buff.truesize = 4000; + self->tx_buff.truesize = 4000; - /* Initialize callbacks */ - idev->change_speed = irport_change_speed; - idev->wait_until_sent = irport_wait_until_sent; - idev->is_receiving = irport_is_receiving; - idev->set_dtr_rts = irport_set_dtr_rts; - idev->raw_write = irport_raw_write; + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL); + 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, + GFP_KERNEL); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; + self->mode = IRDA_IRLAP; + + if (!(dev = dev_alloc("irda%d", &err))) { + ERROR(__FUNCTION__ "(), dev_alloc() failed!\n"); + return -ENOMEM; + } + /* dev_alloc doesn't clear the struct, so lets do a little hack */ + memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*)); + + dev->priv = (void *) self; + self->netdev = dev; /* Override the network functions we need to use */ - idev->netdev.init = irport_net_init; - idev->netdev.hard_start_xmit = irport_hard_xmit; - idev->netdev.open = irport_net_open; - idev->netdev.stop = irport_net_close; + dev->init = irport_net_init; + dev->hard_start_xmit = irport_hard_xmit; + dev->open = irport_net_open; + dev->stop = irport_net_close; + + /* Make ifconfig display some details */ + dev->base_addr = iobase; + dev->irq = irq; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } + MESSAGE("IrDA: Registered device %s\n", dev->name); - /* Open the IrDA device */ - irda_device_open(idev, driver_name, NULL); - return 0; } -static int irport_close(struct irda_device *idev) +static int irport_close(struct irport_cb *self) { - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - /* Release the IO-port that this driver is using */ - DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", - idev->io.iobase2); - release_region(idev->io.iobase2, idev->io.io_ext); + /* We are not using any dongle anymore! */ + if (self->dongle) + irda_device_dongle_cleanup(self->dongle); + self->dongle = NULL; + + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdevice(self->netdev); + rtnl_unlock(); + } - irda_device_close(idev); + /* Release the IO-port that this driver is using */ + IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", + self->io.iobase2); + release_region(self->io.iobase2, self->io.io_ext); - kfree(idev); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); + + kfree(self); return 0; } -void irport_start(struct irda_device *idev, int iobase) +void irport_start(struct irport_cb *self, int iobase) { unsigned long flags; - spin_lock_irqsave(&idev->lock, flags); + spin_lock_irqsave(&self->lock, flags); - irport_stop(idev, iobase); + irport_stop(self, iobase); /* Initialize UART */ outb(UART_LCR_WLEN8, iobase+UART_LCR); /* Reset DLAB */ @@ -235,14 +282,14 @@ void irport_start(struct irda_device *idev, int iobase) /* Turn on interrups */ outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); } -void irport_stop(struct irda_device *idev, int iobase) +void irport_stop(struct irport_cb *self, int iobase) { unsigned long flags; - spin_lock_irqsave(&idev->lock, flags); + spin_lock_irqsave(&self->lock, flags); /* Reset UART */ outb(0, iobase+UART_MCR); @@ -250,7 +297,7 @@ void irport_stop(struct irda_device *idev, int iobase) /* Turn off interrupts */ outb(0, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); } /* @@ -261,18 +308,18 @@ void irport_stop(struct irda_device *idev, int iobase) */ int irport_probe(int iobase) { - DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase); + IRDA_DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase); return 0; } /* - * Function irport_change_speed (idev, speed) + * Function irport_change_speed (self, speed) * * Set speed of IrDA port to specified baudrate * */ -void irport_change_speed(struct irda_device *idev, __u32 speed) +void irport_change_speed(struct irport_cb *self, __u32 speed) { unsigned long flags; int iobase; @@ -280,17 +327,16 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) int lcr; /* Line control reg */ int divisor; - DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed); + IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Update accounting for new speed */ - idev->io.baudrate = speed; + self->io.speed = speed; - spin_lock_irqsave(&idev->lock, flags); + spin_lock_irqsave(&self->lock, flags); /* Turn off interrupts */ outb(0, iobase+UART_IER); @@ -304,7 +350,7 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) * almost 1,7 ms at 19200 bps. At speeds above that we can just forget * about this timeout since it will always be fast enough. */ - if (idev->io.baudrate < 38400) + if (self->io.speed < 38400) fcr |= UART_FCR_TRIGGER_1; else fcr |= UART_FCR_TRIGGER_14; @@ -321,7 +367,7 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) /* Turn on interrups */ outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); } /* @@ -331,39 +377,38 @@ void irport_change_speed(struct irda_device *idev, __u32 speed) * more packets to send, we send them here. * */ -static void irport_write_wakeup(struct irda_device *idev) +static void irport_write_wakeup(struct irport_cb *self) { int actual = 0; int iobase; int fcr; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Finished with frame? */ - if (idev->tx_buff.len > 0) { + if (self->tx_buff.len > 0) { /* Write data left in transmit buffer */ - actual = irport_write(idev->io.iobase2, idev->io.fifo_size, - idev->tx_buff.data, idev->tx_buff.len); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + actual = irport_write(self->io.iobase2, self->io.fifo_size, + self->tx_buff.data, self->tx_buff.len); + self->tx_buff.data += actual; + self->tx_buff.len -= actual; } else { - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* * Now serial buffer is almost free & we can start * transmission of another packet */ - idev->netdev.tbusy = 0; /* Unlock */ - idev->stats.tx_packets++; + self->netdev->tbusy = 0; /* Unlock */ + self->stats.tx_packets++; /* Schedule network layer, so we can get some more frames */ mark_bh(NET_BH); fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR; - if (idev->io.baudrate < 38400) + if (self->io.speed < 38400) fcr |= UART_FCR_TRIGGER_1; else fcr |= UART_FCR_TRIGGER_14; @@ -391,7 +436,7 @@ static int irport_write(int iobase, int fifo_size, __u8 *buf, int len) /* Tx FIFO should be empty! */ if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n"); return -1; } @@ -415,19 +460,19 @@ static int irport_write(int iobase, int fifo_size, __u8 *buf, int len) */ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) { - struct irda_device *idev; + struct irport_cb *self; unsigned long flags; int actual = 0; int iobase; + __u32 speed; ASSERT(dev != NULL, return 0;); - idev = (struct irda_device *) dev->priv; + self = (struct irport_cb *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) { @@ -436,28 +481,32 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) return -EBUSY; WARNING("%s: transmit timed out\n", dev->name); - irport_start(idev, iobase); - irport_change_speed(idev, idev->io.baudrate); + irport_start(self, iobase); + irport_change_speed(self, self->io.speed ); dev->trans_start = jiffies; } - spin_lock_irqsave(&idev->lock, flags); + /* Check if we need to change the speed */ + if ((speed = irda_get_speed(skb)) != self->io.speed) + irport_change_speed(self, speed); + + spin_lock_irqsave(&self->lock, flags); /* Init tx buffer */ - idev->tx_buff.data = idev->tx_buff.head; + self->tx_buff.data = self->tx_buff.head; /* Copy skb to tx_buff while wrapping, stuffing and making CRC */ - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; /* Turn on transmit finished interrupt. Will fire immediately! */ outb(UART_IER_THRI, iobase+UART_IER); - spin_unlock_irqrestore(&idev->lock, flags); + spin_unlock_irqrestore(&self->lock, flags); dev_kfree_skb(skb); @@ -465,30 +514,31 @@ int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev) } /* - * Function irport_receive (idev) + * Function irport_receive (self) * * Receive one frame from the infrared port * */ -static void irport_receive(struct irda_device *idev) +static void irport_receive(struct irport_cb *self) { int boguscount = 0; int iobase; - ASSERT(idev != NULL, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* * Receive all characters in Rx FIFO, unwrap and unstuff them. * async_unwrap_char will deliver all found frames */ do { - async_unwrap_char(idev, inb(iobase+UART_RX)); + async_unwrap_char(self->netdev, &self->rx_buff, + inb(iobase+UART_RX)); /* Make sure we don't stay here to long */ if (boguscount++ > 32) { - DEBUG(2,__FUNCTION__ "(), breaking!\n"); + IRDA_DEBUG(2,__FUNCTION__ "(), breaking!\n"); break; } } while (inb(iobase+UART_LSR) & UART_LSR_DR); @@ -501,45 +551,47 @@ static void irport_receive(struct irda_device *idev) */ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct irda_device *idev = (struct irda_device *) dev_id; + struct net_device *dev = (struct net_device *) dev_id; + struct irport_cb *self; + int boguscount = 0; int iobase; int iir, lsr; - int boguscount = 0; - if (!idev) { + if (!dev) { WARNING(__FUNCTION__ "() irq %d for unknown device.\n", irq); return; } + self = (struct irport_cb *) dev->priv; - spin_lock(&idev->lock); + spin_lock(&self->lock); - idev->netdev.interrupt = 1; + dev->interrupt = 1; - iobase = idev->io.iobase2; + iobase = self->io.iobase2; iir = inb(iobase+UART_IIR) & UART_IIR_ID; while (iir) { /* Clear interrupt */ lsr = inb(iobase+UART_LSR); - DEBUG(4, __FUNCTION__ "(), iir=%02x, lsr=%02x, iobase=%#x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), iir=%02x, lsr=%02x, iobase=%#x\n", iir, lsr, iobase); switch (iir) { case UART_IIR_RLSI: - DEBUG(2, __FUNCTION__ "(), RLSI\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), RLSI\n"); break; case UART_IIR_RDI: /* Receive interrupt */ - irport_receive(idev); + irport_receive(self); break; case UART_IIR_THRI: if (lsr & UART_LSR_THRE) /* Transmitter ready for data */ - irport_write_wakeup(idev); + irport_write_wakeup(self); break; default: - DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir); + IRDA_DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir); break; } @@ -549,9 +601,9 @@ void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) iir = inb(iobase + UART_IIR) & UART_IIR_ID; } - idev->netdev.interrupt = 0; + dev->interrupt = 0; - spin_unlock(&idev->lock); + spin_unlock(&self->lock); } static int irport_net_init(struct net_device *dev) @@ -572,24 +624,32 @@ static int irport_net_init(struct net_device *dev) */ static int irport_net_open(struct net_device *dev) { - struct irda_device *idev; + struct irport_cb *self; int iobase; ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct irport_cb *) dev->priv; - iobase = idev->io.iobase2; + iobase = self->io.iobase2; - if (request_irq(idev->io.irq2, irport_interrupt, 0, idev->name, - (void *) idev)) + if (request_irq(self->io.irq2, irport_interrupt, 0, dev->name, + (void *) dev)) return -EAGAIN; - irport_start(idev, iobase); - irda_device_net_open(dev); + irport_start(self, iobase); + + /* Ready to play! */ + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + /* + * Open new IrLAP layer instance, now that everything should be + * initialized properly + */ + self->irlap = irlap_open(dev, &self->qos); - /* Change speed to make sure dongles follow us again */ - if (idev->change_speed) - idev->change_speed(idev, 9600); + /* FIXME: change speed of dongle */ MOD_INC_USE_COUNT; @@ -597,30 +657,37 @@ static int irport_net_open(struct net_device *dev) } /* - * Function irport_net_close (idev) + * Function irport_net_close (self) * * * */ static int irport_net_close(struct net_device *dev) { - struct irda_device *idev; + struct irport_cb *self; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct irport_cb *) dev->priv; - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;) + ASSERT(self != NULL, return -1;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; - irda_device_net_close(dev); - irport_stop(idev, iobase); + /* Stop device */ + dev->tbusy = 1; + dev->start = 0; - free_irq(idev->io.irq2, idev); + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; + + irport_stop(self, iobase); + + free_irq(self->io.irq2, dev); MOD_DEC_USE_COUNT; @@ -628,34 +695,36 @@ static int irport_net_close(struct net_device *dev) } /* - * Function irport_wait_until_sent (idev) + * Function irport_wait_until_sent (self) * * Delay exectution until finished transmitting * */ -void irport_wait_until_sent(struct irda_device *idev) +#if 0 +void irport_wait_until_sent(struct irport_cb *self) { int iobase; - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Wait until Tx FIFO is empty */ while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - DEBUG(2, __FUNCTION__ "(), waiting!\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), waiting!\n"); current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(60)); } } +#endif /* - * Function irport_is_receiving (idev) + * Function irport_is_receiving (self) * * Returns true is we are currently receiving data * */ -static int irport_is_receiving(struct irda_device *idev) +static int irport_is_receiving(struct irport_cb *self) { - return (idev->rx_buff.state != OUTSIDE_FRAME); + return (self->rx_buff.state != OUTSIDE_FRAME); } /* @@ -664,14 +733,14 @@ static int irport_is_receiving(struct irda_device *idev) * This function can be used by dongles etc. to set or reset the status * of the dtr and rts lines */ -static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts) +static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts) { + struct irport_cb *self = dev->priv; int iobase; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; if (dtr) dtr = UART_MCR_DTR; @@ -681,19 +750,19 @@ static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts) outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR); } -static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len) +static int irport_raw_write(struct net_device *dev, __u8 *buf, int len) { - int iobase; + struct irport_cb *self = (struct irport_cb *) dev->priv; int actual = 0; + int iobase; - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - iobase = idev->io.iobase2; + iobase = self->io.iobase2; /* Tx FIFO should be empty! */ if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) { - DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n"); return -1; } @@ -708,33 +777,20 @@ static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len) } #ifdef MODULE - MODULE_PARM(io, "1-4i"); MODULE_PARM(irq, "1-4i"); MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode"); -/* - * Function cleanup_module (void) - * - * - * - */ void cleanup_module(void) { irport_cleanup(); } -/* - * Function init_module (void) - * - * - */ int init_module(void) { return irport_init(); } - #endif /* MODULE */ diff --git a/drivers/net/irda/irtty.c b/drivers/net/irda/irtty.c index 6a439a1a8..b6a9dad59 100644 --- a/drivers/net/irda/irtty.c +++ b/drivers/net/irda/irtty.c @@ -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 Sep 28 08:39:29 1999 + * Modified at: Wed Oct 20 00:05:43 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> @@ -29,6 +29,8 @@ #include <linux/tty.h> #include <linux/init.h> #include <linux/skbuff.h> +#include <linux/if_arp.h> +#include <linux/rtnetlink.h> #include <asm/segment.h> #include <asm/uaccess.h> @@ -36,7 +38,6 @@ #include <net/irda/irda.h> #include <net/irda/irtty.h> #include <net/irda/wrapper.h> -#include <net/irda/irlap.h> #include <net/irda/timer.h> #include <net/irda/irda_device.h> @@ -46,27 +47,31 @@ static struct tty_ldisc irda_ldisc; static int qos_mtt_bits = 0x03; /* 5 ms or more */ +/* Network device fuction prototypes */ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev); -static void irtty_wait_until_sent(struct irda_device *driver); -static int irtty_is_receiving(struct irda_device *idev); -static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts); -static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len); -static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, - int timeout); -static void irtty_set_raw_mode(struct irda_device *dev, int mode); static int irtty_net_init(struct net_device *dev); static int irtty_net_open(struct net_device *dev); static int irtty_net_close(struct net_device *dev); +static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct net_device_stats *irtty_net_get_stats(struct net_device *dev); +/* Line discipline function prototypes */ static int irtty_open(struct tty_struct *tty); static void irtty_close(struct tty_struct *tty); static int irtty_ioctl(struct tty_struct *, void *, int, void *); static int irtty_receive_room(struct tty_struct *tty); -static void irtty_change_speed(struct irda_device *dev, __u32 speed); static void irtty_write_wakeup(struct tty_struct *tty); - static void irtty_receive_buf(struct tty_struct *, const unsigned char *, char *, int); + +/* IrDA specific function protoctypes */ +static int irtty_is_receiving(struct irtty_cb *self); +static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts); +static int irtty_raw_write(struct net_device *dev, __u8 *buf, int len); +static int irtty_raw_read(struct net_device *dev, __u8 *buf, int len); +static int irtty_set_mode(struct net_device *dev, int mode); +static int irtty_change_speed(struct irda_task *task); + char *driver_name = "irtty"; int __init irtty_init(void) @@ -140,13 +145,16 @@ static void irtty_cleanup(void) */ static int irtty_open(struct tty_struct *tty) { + struct net_device *dev; struct irtty_cb *self; char name[16]; + int err; ASSERT(tty != NULL, return -EEXIST;); /* First make sure we're not already connected. */ self = (struct irtty_cb *) tty->disc_data; + if (self != NULL && self->magic == IRTTY_MAGIC) return -EEXIST; @@ -168,9 +176,8 @@ static int irtty_open(struct tty_struct *tty) sprintf(name, "%s%d", tty->driver.name, MINOR(tty->device) - tty->driver.minor_start + tty->driver.name_base); - - /* hashbin_insert( irtty, (QUEUE*) self, 0, self->name); */ - hashbin_insert(irtty, (QUEUE*) self, (int) self, NULL); + + hashbin_insert(irtty, (queue_t *) self, (int) self, NULL); if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty); @@ -179,11 +186,7 @@ static int irtty_open(struct tty_struct *tty) tty->ldisc.flush_buffer(tty); self->magic = IRTTY_MAGIC; - - /* - * Initialize driver - */ - self->idev.rx_buff.state = OUTSIDE_FRAME; + self->rx_buff.state = OUTSIDE_FRAME; /* * Initialize QoS capabilities, we fill in all the stuff that @@ -191,40 +194,71 @@ static int irtty_open(struct tty_struct *tty) * that are not device dependent (such as link disconnect time) so * this parameter can be set by IrLAP (or the user) instead. DB */ - irda_init_max_qos_capabilies(&self->idev.qos); + irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ - self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200; - self->idev.qos.min_turn_time.bits = qos_mtt_bits; - self->idev.flags = IFF_SIR | IFF_PIO; - irda_qos_bits_to_value(&self->idev.qos); - - /* Specify which buffer allocation policy we need */ - self->idev.rx_buff.flags = GFP_KERNEL; - self->idev.tx_buff.flags = GFP_KERNEL; + self->qos.min_turn_time.bits = qos_mtt_bits; + self->flags = IFF_SIR | IFF_PIO; + irda_qos_bits_to_value(&self->qos); /* Specify how much memory we want */ - self->idev.rx_buff.truesize = 4000; - self->idev.tx_buff.truesize = 4000; - - /* Initialize callbacks */ - self->idev.change_speed = irtty_change_speed; - self->idev.is_receiving = irtty_is_receiving; - self->idev.wait_until_sent = irtty_wait_until_sent; - self->idev.set_dtr_rts = irtty_set_dtr_rts; - self->idev.set_raw_mode = irtty_set_raw_mode; - self->idev.raw_write = irtty_raw_write; - self->idev.raw_read = irtty_raw_read; + self->rx_buff.truesize = 4000; + self->tx_buff.truesize = 4000; + + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL); + 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, + GFP_KERNEL); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + + self->magic = IRTTY_MAGIC; + + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; + + if (!(dev = dev_alloc("irda%d", &err))) { + ERROR(__FUNCTION__ "(), dev_alloc() failed!\n"); + return -ENOMEM; + } + /* dev_alloc doesn't clear the struct */ + memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*)); + + dev->priv = (void *) self; + self->netdev = dev; /* Override the network functions we need to use */ - self->idev.netdev.init = irtty_net_init; - self->idev.netdev.hard_start_xmit = irtty_hard_xmit; - self->idev.netdev.open = irtty_net_open; - self->idev.netdev.stop = irtty_net_close; + dev->init = irtty_net_init; + dev->hard_start_xmit = irtty_hard_xmit; + dev->open = irtty_net_open; + dev->stop = irtty_net_close; + dev->get_stats = irtty_net_get_stats; + dev->do_ioctl = irtty_net_ioctl; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } - /* Open the IrDA device */ - irda_device_open(&self->idev, name, self); + MESSAGE("IrDA: Registered device %s\n", dev->name); MOD_INC_USE_COUNT; @@ -245,39 +279,50 @@ static void irtty_close(struct tty_struct *tty) /* First make sure we're connected. */ ASSERT(self != NULL, return;); ASSERT(self->magic == IRTTY_MAGIC, return;); - - /* Remove driver */ - irda_device_close(&self->idev); - + /* Stop tty */ tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); tty->disc_data = 0; - + + /* We are not using any dongle anymore! */ + if (self->dongle) + irda_device_dongle_cleanup(self->dongle); + self->dongle = NULL; + + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdevice(self->netdev); + rtnl_unlock(); + } + self->tty = NULL; self->magic = 0; self = hashbin_remove(irtty, (int) self, NULL); - - if (self != NULL) - kfree(self); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); + + kfree(self); + MOD_DEC_USE_COUNT; } /* - * Function irtty_stop_receiver (irda_device, stop) + * Function irtty_stop_receiver (self, stop) * * * */ -static void irtty_stop_receiver(struct irda_device *idev, int stop) +static void irtty_stop_receiver(struct irtty_cb *self, int stop) { struct termios old_termios; - struct irtty_cb *self; int cflag; - self = (struct irtty_cb *) idev->priv; - old_termios = *(self->tty->termios); cflag = self->tty->termios->c_cflag; @@ -291,24 +336,16 @@ static void irtty_stop_receiver(struct irda_device *idev, int stop) } /* - * Function irtty_change_speed (self, speed) + * Function irtty_do_change_speed (self, speed) * - * Change the speed of the serial port. The driver layer must check that - * all transmission has finished using the irtty_wait_until_sent() - * function. + * Change the speed of the serial port. */ -static void irtty_change_speed(struct irda_device *idev, __u32 speed) +static void __irtty_change_speed(struct irtty_cb *self, __u32 speed) { struct termios old_termios; - struct irtty_cb *self; int cflag; - DEBUG(4, __FUNCTION__ "(), <%ld>\n", jiffies); - - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - self = (struct irtty_cb *) idev->priv; + IRDA_DEBUG(0, __FUNCTION__ "(), <%ld>\n", jiffies); ASSERT(self != NULL, return;); ASSERT(self->magic == IRTTY_MAGIC, return;); @@ -318,7 +355,7 @@ static void irtty_change_speed(struct irda_device *idev, __u32 speed) cflag &= ~CBAUD; - DEBUG(4, __FUNCTION__ "(), Setting speed to %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ "(), Setting speed to %d\n", speed); switch (speed) { case 1200: @@ -350,6 +387,81 @@ static void irtty_change_speed(struct irda_device *idev, __u32 speed) self->tty->termios->c_cflag = cflag; self->tty->driver.set_termios(self->tty, &old_termios); + + self->io.speed = speed; +} + +/* + * Function irtty_change_speed (instance, state, param) + * + * State machine for changing speed of the device. We do it this way since + * we cannot use schedule_timeout() when we are in interrupt context + */ +static int irtty_change_speed(struct irda_task *task) +{ + struct irtty_cb *self; + __u32 speed = (__u32) task->param; + int ret = 0; + + IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies); + + self = (struct irtty_cb *) task->instance; + + ASSERT(self != NULL, return -1;); + + switch (task->state) { + case IRDA_TASK_INIT: + case IRDA_TASK_WAIT: + /* Are we ready to change speed yet? */ + if (self->tty->driver.chars_in_buffer(self->tty)) { + task->state = IRDA_TASK_WAIT; + + /* Try again later */ + ret = MSECS_TO_JIFFIES(20); + break; + } + + if (self->dongle) + irda_task_next_state(task, IRDA_TASK_CHILD_INIT); + else + irda_task_next_state(task, IRDA_TASK_CHILD_DONE); + break; + case IRDA_TASK_CHILD_INIT: + /* Go to default speed */ + __irtty_change_speed(self, 9600); + + /* Change speed of dongle */ + if (irda_task_execute(self->dongle, + self->dongle->issue->change_speed, + NULL, task, (void *) speed)) + { + /* Dongle need more time to change its speed */ + irda_task_next_state(task, IRDA_TASK_CHILD_WAIT); + + /* Give dongle 1 sec to finish */ + ret = MSECS_TO_JIFFIES(1000); + } else + /* Child finished immediately */ + irda_task_next_state(task, IRDA_TASK_CHILD_DONE); + break; + case IRDA_TASK_CHILD_WAIT: + WARNING(__FUNCTION__ + "(), changing speed of dongle timed out!\n"); + ret = -1; + break; + case IRDA_TASK_CHILD_DONE: + /* Finally we are ready to change the speed */ + __irtty_change_speed(self, speed); + + irda_task_next_state(task, IRDA_TASK_DONE); + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + ret = -1; + break; + } + return ret; } /* @@ -360,9 +472,11 @@ static void irtty_change_speed(struct irda_device *idev, __u32 speed) */ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) { + dongle_t *dongle; + struct irtty_info info; struct irtty_cb *self; - int err = 0; int size = _IOC_SIZE(cmd); + int err = 0; self = (struct irtty_cb *) tty->disc_data; @@ -370,13 +484,13 @@ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;); if (_IOC_DIR(cmd) & _IOC_READ) - err = verify_area( VERIFY_WRITE, (void *) arg, size); + err = verify_area(VERIFY_WRITE, (void *) arg, size); else if (_IOC_DIR(cmd) & _IOC_WRITE) - err = verify_area( VERIFY_READ, (void *) arg, size); + err = verify_area(VERIFY_READ, (void *) arg, size); if (err) return err; - switch(cmd) { + switch (cmd) { case TCGETS: case TCGETA: return n_tty_ioctl(tty, (struct file *) file, cmd, @@ -384,7 +498,34 @@ static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg) break; case IRTTY_IOCTDONGLE: /* Initialize dongle */ - irda_device_init_dongle(&self->idev, (int) arg); + dongle = irda_device_dongle_init(self->netdev, (int) arg); + if (!dongle) + break; + + /* Initialize callbacks */ + dongle->set_mode = irtty_set_mode; + dongle->read = irtty_raw_read; + dongle->write = irtty_raw_write; + dongle->set_dtr_rts = irtty_set_dtr_rts; + + /* Bind dongle */ + self->dongle = dongle; + + /* Now initialize the dongle! */ + dongle->issue->open(dongle, &self->qos); + + /* Reset dongle */ + irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, + NULL); + break; + case IRTTY_IOCGET: + ASSERT(self->netdev != NULL, return -1;); + + memset(&info, 0, sizeof(struct irtty_info)); + strncpy(info.name, self->netdev->name, 5); + + if (copy_to_user(arg, &info, sizeof(struct irtty_info))) + return -EFAULT; break; default: return -ENOIOCTLCMD; @@ -405,34 +546,61 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, { struct irtty_cb *self = (struct irtty_cb *) tty->disc_data; - DEBUG(5, __FUNCTION__ "(,,,count=%d)\n", count); /* Read the characters out of the buffer */ while (count--) { /* * Characters received with a parity error, etc? */ if (fp && *fp++) { - DEBUG( 0, "Framing or parity error!\n"); - irda_device_set_media_busy(&self->idev.netdev, TRUE); - + IRDA_DEBUG(0, "Framing or parity error!\n"); + irda_device_set_media_busy(self->netdev, TRUE); + cp++; continue; } + + switch (self->mode) { + case IRDA_IRLAP: + /* Unwrap and destuff one byte */ + async_unwrap_char(self->netdev, &self->rx_buff, *cp++); + break; + case IRDA_RAW: + /* What should we do when the buffer is full? */ + if (self->rx_buff.len == self->rx_buff.truesize) + self->rx_buff.len = 0; + + self->rx_buff.data[self->rx_buff.len++] = *cp++; + break; + default: + break; + } + } +} - DEBUG(6, __FUNCTION__ " char=0x%02x\n", *cp); - if (self->idev.raw_mode) { - struct irda_device *idev = &self->idev; +/* + * Function irtty_change_speed_complete (task) + * + * Called when the change speed operation completes + * + */ +static int irtty_change_speed_complete(struct irda_task *task) +{ + struct irtty_cb *self; - /* What should we do when the buffer is full? */ - if (idev->rx_buff.len == idev->rx_buff.truesize) - idev->rx_buff.len = 0; + IRDA_DEBUG(0, __FUNCTION__ "()\n"); - idev->rx_buff.data[idev->rx_buff.len++] = *cp++; - } else { - /* Unwrap and destuff one byte */ - async_unwrap_char(&self->idev, *cp++); - } - } + self = (struct irtty_cb *) task->instance; + + ASSERT(self != NULL, return -1;); + ASSERT(self->netdev != NULL, return -1;); + + /* Finished changing speed, so we are not busy any longer */ + self->netdev->tbusy = 0; + + /* Signal network layer so it can try to send the frame */ + mark_bh(NET_BH); + + return 0; } /* @@ -444,29 +612,34 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) { struct irtty_cb *self; - struct irda_device *idev; int actual = 0; + __u32 speed; - idev = (struct irda_device *) dev->priv; - - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); - - self = (struct irtty_cb *) idev->priv; - + self = (struct irtty_cb *) dev->priv; ASSERT(self != NULL, return 0;); - ASSERT(self->magic == IRTTY_MAGIC, return 0;); /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) return -EBUSY; + + /* Check if we need to change the speed */ + if ((speed = irda_get_speed(skb)) != self->io.speed) { + if (irda_task_execute(self, irtty_change_speed, + irtty_change_speed_complete, NULL, + (void *) speed)) + /* + * Task not finished yet, so make the netdevice + * layer requeue the frame + */ + return -EBUSY; + } /* Init tx buffer*/ - idev->tx_buff.data = idev->tx_buff.head; + self->tx_buff.data = self->tx_buff.head; /* Copy skb to tx_buff while wrapping, stuffing and making CRC */ - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); self->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); @@ -474,22 +647,22 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) if (self->tty->driver.write) actual = self->tty->driver.write(self->tty, 0, - idev->tx_buff.data, - idev->tx_buff.len); + self->tx_buff.data, + self->tx_buff.len); /* Hide the part we just transmitted */ - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; - idev->stats.tx_packets++; - idev->stats.tx_bytes += idev->tx_buff.len; + self->stats.tx_packets++; + self->stats.tx_bytes += self->tx_buff.len; #if 0 /* * Did we transmit the whole frame? Commented out for now since * I must check if this optimalization really works. DB. */ - if ((idev->tx_buff.len) == 0) { - DEBUG( 4, "irtty_xmit_buf: finished with frame!\n"); + if ((self->tx_buff.len) == 0) { + IRDA_DEBUG( 4, "irtty_xmit_buf: finished with frame!\n"); self->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); irda_unlock( &self->tbusy); } @@ -507,7 +680,7 @@ static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev) */ static int irtty_receive_room(struct tty_struct *tty) { - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); return 65536; /* We can handle an infinite amount of data. :-) */ } @@ -521,7 +694,6 @@ static int irtty_receive_room(struct tty_struct *tty) static void irtty_write_wakeup(struct tty_struct *tty) { struct irtty_cb *self = (struct irtty_cb *) tty->disc_data; - struct irda_device *idev; int actual = 0; /* @@ -530,26 +702,24 @@ static void irtty_write_wakeup(struct tty_struct *tty) ASSERT(self != NULL, return;); ASSERT(self->magic == IRTTY_MAGIC, return;); - idev = &self->idev; - /* Finished with frame? */ - if (idev->tx_buff.len > 0) { + if (self->tx_buff.len > 0) { /* Write data left in transmit buffer */ - actual = tty->driver.write(tty, 0, idev->tx_buff.data, - idev->tx_buff.len); + actual = tty->driver.write(tty, 0, self->tx_buff.data, + self->tx_buff.len); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; } else { /* * Now serial buffer is almost free & we can start * transmission of another packet */ - DEBUG(5, __FUNCTION__ "(), finished with frame!\n"); + IRDA_DEBUG(5, __FUNCTION__ "(), finished with frame!\n"); tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - idev->netdev.tbusy = 0; /* Unlock */ + self->netdev->tbusy = 0; /* Unlock */ /* Tell network layer that we want more frames */ mark_bh(NET_BH); @@ -557,34 +727,14 @@ static void irtty_write_wakeup(struct tty_struct *tty) } /* - * Function irtty_is_receiving (idev) + * Function irtty_is_receiving (self) * * Return TRUE is we are currently receiving a frame * */ -static int irtty_is_receiving(struct irda_device *idev) +static int irtty_is_receiving(struct irtty_cb *self) { - return (idev->rx_buff.state != OUTSIDE_FRAME); -} - -/* - * Function irtty_change_speed_ready (idev) - * - * Are we completely finished with transmitting frames so its possible - * to change the speed of the serial port. Warning this function must - * be called with a process context! - */ -static void irtty_wait_until_sent(struct irda_device *idev) -{ - struct irtty_cb *self = (struct irtty_cb *) idev->priv; - - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRTTY_MAGIC, return;); - - DEBUG(4, "Chars in buffer %d\n", - self->tty->driver.chars_in_buffer(self->tty)); - - tty_wait_until_sent(self->tty, 0); + return (self->rx_buff.state != OUTSIDE_FRAME); } /* @@ -593,15 +743,14 @@ static void irtty_wait_until_sent(struct irda_device *idev) * This function can be used by dongles etc. to set or reset the status * of the dtr and rts lines */ -static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts) +static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts) { - struct tty_struct *tty; struct irtty_cb *self; + struct tty_struct *tty; mm_segment_t fs; int arg = 0; - self = (struct irtty_cb *) idev->priv; - + self = (struct irtty_cb *) dev->priv; tty = self->tty; #ifdef TIOCM_OUT2 /* Not defined for ARM */ @@ -627,52 +776,62 @@ static void irtty_set_dtr_rts(struct irda_device *idev, int dtr, int rts) ERROR(__FUNCTION__ "(), error doing ioctl!\n"); } set_fs(fs); + + return 0; } /* - * Function irtty_set_raw_mode (idev, status) + * Function irtty_set_mode (self, status) * * For the airport dongle, we need support for reading raw characters * from the IrDA device. This function switches between those modes. * FALSE is the default mode, and will then treat incoming data as IrDA * packets. */ -void irtty_set_raw_mode(struct irda_device *idev, int status) +int irtty_set_mode(struct net_device *dev, int mode) { struct irtty_cb *self; - DEBUG(2, __FUNCTION__ "(), status=%s\n", status ? "TRUE" : "FALSE"); + self = (struct irtty_cb *) dev->priv; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - self = (struct irtty_cb *) idev->priv; + ASSERT(self != NULL, return -1;); + IRDA_DEBUG(2, __FUNCTION__ "(), mode=%s\n", infrared_mode[mode]); + /* save status for driver */ - self->idev.raw_mode = status; + self->mode = mode; /* reset the buffer state */ - idev->rx_buff.data = idev->rx_buff.head; - idev->rx_buff.len = 0; - idev->rx_buff.state = OUTSIDE_FRAME; + self->rx_buff.data = self->rx_buff.head; + self->rx_buff.len = 0; + self->rx_buff.state = OUTSIDE_FRAME; + + return 0; } /* - * Function irtty_raw_read (idev, buf, len) + * Function irtty_raw_read (self, buf, len) * * Receive incomming data. This function sleeps, so it must only be * called with a process context. Timeout is currently defined to be * a multiple of 10 ms. */ -static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, - int timeout) +static int irtty_raw_read(struct net_device *dev, __u8 *buf, int len) { + struct irtty_cb *self; int count; - buf = idev->rx_buff.data; + self = (struct irtty_cb *) dev->priv; + + ASSERT(self != NULL, return 0;); + ASSERT(self->magic == IRTTY_MAGIC, return 0;); + + return 0; +#if 0 + buf = self->rx_buff.data; /* Wait for the requested amount of data to arrive */ - while (len < idev->rx_buff.len) { + while (len < self->rx_buff.len) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(10)); @@ -680,30 +839,27 @@ static int irtty_raw_read(struct irda_device *idev, __u8 *buf, int len, break; } - count = idev->rx_buff.len < len ? idev->rx_buff.len : len; + count = self->rx_buff.len < len ? self->rx_buff.len : len; /* * Reset the state, this mean that a raw read is sort of a * datagram read, and _not_ a stream style read. Be aware of the * difference. Implementing it the other way will just be painful ;-) */ - idev->rx_buff.data = idev->rx_buff.head; - idev->rx_buff.len = 0; - idev->rx_buff.state = OUTSIDE_FRAME; - + self->rx_buff.data = self->rx_buff.head; + self->rx_buff.len = 0; + self->rx_buff.state = OUTSIDE_FRAME; +#endif /* Return the amount we were able to get */ return count; } -static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len) +static int irtty_raw_write(struct net_device *dev, __u8 *buf, int len) { struct irtty_cb *self; int actual = 0; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); - - self = (struct irtty_cb *) idev->priv; + self = (struct irtty_cb *) dev->priv; ASSERT(self != NULL, return 0;); ASSERT(self->magic == IRTTY_MAGIC, return 0;); @@ -714,8 +870,6 @@ static int irtty_raw_write(struct irda_device *idev, __u8 *buf, int len) return actual; } - - static int irtty_net_init(struct net_device *dev) { /* Set up to be a normal IrDA network device driver */ @@ -728,12 +882,26 @@ static int irtty_net_init(struct net_device *dev) static int irtty_net_open(struct net_device *dev) { - struct irda_device *idev = dev->priv; + struct irtty_cb *self = (struct irtty_cb *) dev->priv; - irda_device_net_open(dev); + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRTTY_MAGIC, return -1;); + + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + + /* Ready to play! */ + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; /* Make sure we can receive more data */ - irtty_stop_receiver(idev, FALSE); + irtty_stop_receiver(self, FALSE); + + /* + * Open new IrLAP layer instance, now that everything should be + * initialized properly + */ + self->irlap = irlap_open(dev, &self->qos); MOD_INC_USE_COUNT; @@ -742,18 +910,105 @@ static int irtty_net_open(struct net_device *dev) static int irtty_net_close(struct net_device *dev) { - struct irda_device *idev = dev->priv; + struct irtty_cb *self = (struct irtty_cb *) dev->priv; + + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRTTY_MAGIC, return -1;); /* Make sure we don't receive more data */ - irtty_stop_receiver(idev, TRUE); + irtty_stop_receiver(self, TRUE); - irda_device_net_close(dev); + /* Stop device */ + dev->tbusy = 1; + dev->start = 0; + + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; MOD_DEC_USE_COUNT; return 0; } +/* + * Function irtty_net_ioctl (dev, rq, cmd) + * + * Process IOCTL commands for this device + * + */ +static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct if_irda_req *irq = (struct if_irda_req *) rq; + struct irtty_cb *self; + dongle_t *dongle; + unsigned long flags; + int ret = 0; + + ASSERT(dev != NULL, return -1;); + + self = dev->priv; + + ASSERT(self != NULL, return -1;); + ASSERT(self->magic == IRTTY_MAGIC, return -1;); + + IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd); + + /* Disable interrupts & save flags */ + save_flags(flags); + cli(); + + switch (cmd) { + case SIOCSBANDWIDTH: /* Set bandwidth */ + irda_task_execute(self, irtty_change_speed, NULL, NULL, + (void *) irq->ifr_baudrate); + break; + case SIOCSDONGLE: /* Set dongle */ + /* Initialize dongle */ + dongle = irda_device_dongle_init(dev, irq->ifr_dongle); + if (!dongle) + break; + + dongle->set_mode = irtty_set_mode; + dongle->read = irtty_raw_read; + dongle->write = irtty_raw_write; + dongle->set_dtr_rts = irtty_set_dtr_rts; + + self->dongle = dongle; + + /* Now initialize the dongle! */ + dongle->issue->open(dongle, &self->qos); + + /* Reset dongle */ + irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, + NULL); + break; + case SIOCSMEDIABUSY: /* Set media busy */ + irda_device_set_media_busy(self->netdev, TRUE); + break; + case SIOCGRECEIVING: /* Check if we are receiving right now */ + irq->ifr_receiving = irtty_is_receiving(self); + break; + case SIOCSDTRRTS: + irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts); + break; + default: + ret = -EOPNOTSUPP; + } + + restore_flags(flags); + + return ret; +} + +static struct net_device_stats *irtty_net_get_stats(struct net_device *dev) +{ + struct irtty_cb *self = (struct irtty_cb *) dev->priv; + + return &self->stats; +} + #ifdef MODULE MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); diff --git a/drivers/net/irda/litelink.c b/drivers/net/irda/litelink.c index 203838cea..f5da3faf6 100644 --- a/drivers/net/irda/litelink.c +++ b/drivers/net/irda/litelink.c @@ -6,7 +6,7 @@ * Status: Stable * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Fri May 7 12:50:33 1999 - * Modified at: Sat Jun 26 17:01:05 1999 + * Modified at: Mon Oct 18 12:45:51 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -37,27 +37,25 @@ #include <net/irda/irda.h> #include <net/irda/irmod.h> #include <net/irda/irda_device.h> -#include <net/irda/dongle.h> #define MIN_DELAY 25 /* 15 us, but wait a little more to be sure */ #define MAX_DELAY 10000 /* 1 ms */ -static void litelink_open(struct irda_device *idev, int type); -static void litelink_close(struct irda_device *dev); -static void litelink_change_speed(struct irda_device *dev, __u32); -static void litelink_reset(struct irda_device *dev); -static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos); +static void litelink_open(dongle_t *self, struct qos_info *qos); +static void litelink_close(dongle_t *self); +static int litelink_change_speed(struct irda_task *task); +static int litelink_reset(struct irda_task *task); /* These are the baudrates supported */ static __u32 baud_rates[] = { 115200, 57600, 38400, 19200, 9600 }; -static struct dongle dongle = { - LITELINK_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_LITELINK_DONGLE, litelink_open, litelink_close, litelink_reset, litelink_change_speed, - litelink_init_qos, }; int __init litelink_init(void) @@ -70,114 +68,102 @@ void litelink_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void litelink_open(struct irda_device *idev, int type) +static void litelink_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> litelink"); - - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ MOD_INC_USE_COUNT; } -static void litelink_close(struct irda_device *idev) +static void litelink_close(dongle_t *self) { /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } /* - * Function litelink_change_speed (idev, speed) + * Function litelink_change_speed (task) * * Change speed of the Litelink dongle. To cycle through the available * baud rates, pulse RTS low for a few ms. */ -static void litelink_change_speed(struct irda_device *idev, __u32 speed) +static int litelink_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; int i; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - /* Clear RTS to reset dongle */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); + self->set_dtr_rts(self->dev, TRUE, FALSE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Cycle through avaiable baudrates until we reach the correct one */ for (i=0; i<5 && baud_rates[i] != speed; i++) { - /* Set DTR, clear RTS */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); + self->set_dtr_rts(self->dev, FALSE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); } + + irda_task_next_state(task, IRDA_TASK_DONE); + + return 0; } /* - * Function litelink_reset (dev) + * Function litelink_reset (task) * * Reset the Litelink type dongle. Warning, this function must only be * called with a process context! * */ -static void litelink_reset(struct irda_device *idev) +static int litelink_reset(struct irda_task *task) { - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - + dongle_t *self = (dongle_t *) task->instance; + /* Power on dongle */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Clear RTS to reset dongle */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); + self->set_dtr_rts(self->dev, TRUE, FALSE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* Go back to normal mode */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + self->set_dtr_rts(self->dev, TRUE, TRUE); /* Sleep a minimum of 15 us */ udelay(MIN_DELAY); /* This dongles speed defaults to 115200 bps */ - idev->qos.baud_rate.value = 115200; -} + self->speed = 115200; -/* - * Function litelink_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void litelink_init_qos(struct irda_device *idev, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits &= 0x40; /* Needs 0.01 ms */ + return 0; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Parallax Litelink dongle driver"); @@ -202,5 +188,4 @@ void cleanup_module(void) { litelink_cleanup(); } - -#endif +#endif /* MODULE */ diff --git a/drivers/net/irda/pc87108.c b/drivers/net/irda/pc87108.c index 3b575d01e..fae329ac9 100644 --- a/drivers/net/irda/pc87108.c +++ b/drivers/net/irda/pc87108.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Nov 7 21:43:15 1998 - * Modified at: Wed Aug 11 09:26:26 1999 + * Modified at: Wed Oct 20 00:08:41 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> @@ -29,11 +29,11 @@ * * __u8 bank; * - * bank = inb( iobase+BSR); + * bank = inb(iobase+BSR); * * do_your_stuff_here(); * - * outb( bank, iobase+BSR); + * outb(bank, iobase+BSR); * * If you find bugs in this file, its very likely that the same bug * will also be in w83977af_ir.c since the implementations is quite @@ -51,6 +51,7 @@ #include <linux/delay.h> #include <linux/malloc.h> #include <linux/init.h> +#include <linux/rtnetlink.h> #include <asm/io.h> #include <asm/dma.h> @@ -101,19 +102,19 @@ static char *dongle_types[] = { static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr, unsigned int irq, unsigned int dma); #ifdef MODULE -static int pc87108_close(struct irda_device *idev); +static int pc87108_close(struct pc87108 *self); #endif /* MODULE */ static int pc87108_probe(int iobase, int board_addr, int irq, int dma); -static void pc87108_pio_receive(struct irda_device *idev); -static int pc87108_dma_receive(struct irda_device *idev); -static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase); +static void pc87108_pio_receive(struct pc87108 *self); +static int pc87108_dma_receive(struct pc87108 *self); +static int pc87108_dma_receive_complete(struct pc87108 *self, int iobase); static int pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size); -static void pc87108_dma_write(struct irda_device *idev, int iobase); -static void pc87108_change_speed(struct irda_device *idev, __u32 baud); +static void pc87108_dma_write(struct pc87108 *self, int iobase); +static void pc87108_change_speed(struct pc87108 *self, __u32 baud); static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void pc87108_wait_until_sent(struct irda_device *idev); -static int pc87108_is_receiving(struct irda_device *idev); +static void pc87108_wait_until_sent(struct pc87108 *self); +static int pc87108_is_receiving(struct pc87108 *self); static int pc87108_read_dongle_id (int iobase); static void pc87108_init_dongle_interface (int iobase, int dongle_id); @@ -152,11 +153,11 @@ static void pc87108_cleanup(void) { int i; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) - pc87108_close(&(dev_self[i]->idev)); + pc87108_close(dev_self[i]); } } #endif /* MODULE */ @@ -170,12 +171,13 @@ static void pc87108_cleanup(void) static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr, unsigned int irq, unsigned int dma) { + struct net_device *dev; struct pc87108 *self; - struct irda_device *idev; - int ret; int dongle_id; + int ret; + int err; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); if ((dongle_id = pc87108_probe(iobase, board_addr, irq, dma)) == -1) return -1; @@ -194,90 +196,127 @@ static int pc87108_open(int i, unsigned int iobase, unsigned int board_addr, /* Need to store self somewhere */ dev_self[i] = self; - idev = &self->idev; - /* Initialize IO */ - idev->io.iobase = iobase; - idev->io.irq = irq; - idev->io.io_ext = CHIP_IO_EXTENT; - idev->io.dma = dma; - idev->io.fifo_size = 32; + self->io.iobase = iobase; + self->io.irq = irq; + self->io.io_ext = CHIP_IO_EXTENT; + self->io.dma = dma; + self->io.fifo_size = 32; /* Lock the port that we need */ - ret = check_region(idev->io.iobase, idev->io.io_ext); + ret = check_region(self->io.iobase, self->io.io_ext); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", - idev->io.iobase); - /* pc87108_cleanup( self->idev); */ + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + self->io.iobase); + /* pc87108_cleanup(self->self); */ return -ENODEV; } - request_region(idev->io.iobase, idev->io.io_ext, idev->name); + request_region(self->io.iobase, self->io.io_ext, driver_name); /* Initialize QoS for this device */ - irda_init_max_qos_capabilies(&idev->qos); + irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ - idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); - idev->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&idev->qos); + self->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&self->qos); - idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE; - - /* Specify which buffer allocation policy we need */ - idev->rx_buff.flags = GFP_KERNEL | GFP_DMA; - idev->tx_buff.flags = GFP_KERNEL | GFP_DMA; + self->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO|IFF_DONGLE; /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ - idev->rx_buff.truesize = 14384; - idev->tx_buff.truesize = 4000; + self->rx_buff.truesize = 14384; + self->tx_buff.truesize = 4000; + + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL|GFP_DMA); + 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, + GFP_KERNEL|GFP_DMA); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; - /* Initialize callbacks */ - idev->change_speed = pc87108_change_speed; - idev->wait_until_sent = pc87108_wait_until_sent; - idev->is_receiving = pc87108_is_receiving; - + if (!(dev = dev_alloc("irda%d", &err))) { + ERROR(__FUNCTION__ "(), dev_alloc() failed!\n"); + return -ENOMEM; + } + /* dev_alloc doesn't clear the struct, so lets do a little hack */ + memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*)); + + dev->priv = (void *) self; + self->netdev = dev; + /* Override the network functions we need to use */ - idev->netdev.init = pc87108_net_init; - idev->netdev.hard_start_xmit = pc87108_hard_xmit; - idev->netdev.open = pc87108_net_open; - idev->netdev.stop = pc87108_net_close; + dev->init = pc87108_net_init; + dev->hard_start_xmit = pc87108_hard_xmit; + dev->open = pc87108_net_open; + dev->stop = pc87108_net_close; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } - idev->io.dongle_id = dongle_id; + MESSAGE("IrDA: Registered device %s\n", dev->name); + + self->io.dongle_id = dongle_id; pc87108_init_dongle_interface(iobase, dongle_id); - /* Open the IrDA device */ - irda_device_open(idev, driver_name, self); - return 0; } #ifdef MODULE /* - * Function pc87108_close (idev) + * Function pc87108_close (self) * * Close driver instance * */ -static int pc87108_close(struct irda_device *idev) +static int pc87108_close(struct pc87108 *self) { - struct pc87108 *self; int iobase; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); + + ASSERT(self != NULL, return -1;); - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + iobase = self->io.iobase; - iobase = idev->io.iobase; - self = (struct pc87108 *) idev->priv; + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdev(self->netdev); + rtnl_unlock(); + } /* Release the PORT that this driver is using */ - DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase); - release_region(idev->io.iobase, idev->io.io_ext); + IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", self->io.iobase); + release_region(self->io.iobase, self->io.io_ext); - irda_device_close(idev); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); kfree(self); @@ -297,7 +336,7 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) __u8 temp=0; int dongle_id; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Base Address and Interrupt Control Register BAIC */ outb(0, board_addr); @@ -326,7 +365,7 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) case 0: outb(0x08+temp, board_addr+1); break; case 1: outb(0x10+temp, board_addr+1); break; case 3: outb(0x18+temp, board_addr+1); break; - default: DEBUG( 0, __FUNCTION__ "(), invalid dma"); + default: IRDA_DEBUG(0, __FUNCTION__ "(), invalid dma"); } /* Mode Control Register MCTL */ @@ -344,13 +383,13 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) } /* Switch to advanced mode */ - switch_bank( iobase, BANK2); + switch_bank(iobase, BANK2); outb(ECR1_EXT_SL, iobase+ECR1); switch_bank(iobase, BANK0); dongle_id = pc87108_read_dongle_id(iobase); - DEBUG(0, __FUNCTION__ "(), Found dongle: %s\n", - dongle_types[ dongle_id]); + IRDA_DEBUG(0, __FUNCTION__ "(), Found dongle: %s\n", + dongle_types[dongle_id]); /* Set FIFO threshold to TX17, RX16, reset and enable FIFO's */ switch_bank(iobase, BANK0); @@ -380,7 +419,7 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) outb(2048 & 0xff, iobase+4); outb((2048 >> 8) & 0x1f, iobase+5); - DEBUG(0, "PC87108 driver loaded. Version: 0x%02x\n", version); + IRDA_DEBUG(0, "PC87108 driver loaded. Version: 0x%02x\n", version); /* Enable receive interrupts */ switch_bank(iobase, BANK0); @@ -397,14 +436,14 @@ static int pc87108_probe(int iobase, int board_addr, int irq, int dma) * that the user may have plugged/unplugged the IrDA Dongle. * */ -static int pc87108_read_dongle_id ( int iobase) +static int pc87108_read_dongle_id (int iobase) { int dongle_id; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Select Bank 7 */ switch_bank(iobase, BANK7); @@ -416,7 +455,7 @@ static int pc87108_read_dongle_id ( int iobase) udelay(50); /* IRCFG1: read the ID bits */ - dongle_id = inb( iobase+4) & 0x0f; + dongle_id = inb(iobase+4) & 0x0f; #ifdef BROKEN_DONGLE_ID if (dongle_id == 0x0a) @@ -426,7 +465,7 @@ static int pc87108_read_dongle_id ( int iobase) /* Go back to bank 0 before returning */ switch_bank(iobase, BANK0); - DEBUG(0, __FUNCTION__ "(), Dongle = %#x\n", dongle_id); + IRDA_DEBUG(0, __FUNCTION__ "(), Dongle = %#x\n", dongle_id); outb(bank, iobase+BSR); @@ -446,49 +485,49 @@ static void pc87108_init_dongle_interface (int iobase, int dongle_id) int bank; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Select Bank 7 */ - switch_bank( iobase, BANK7); + switch_bank(iobase, BANK7); /* IRCFG4: set according to dongle_id */ switch (dongle_id) { case 0x00: /* same as */ case 0x01: /* Differential serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x02: /* same as */ case 0x03: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x04: /* Sharp RY5HD01 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); break; case 0x05: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet", dongle_types[dongle_id]); break; case 0x06: /* Single-ended serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x07: /* Consumer-IR only */ - DEBUG( 0, __FUNCTION__ "(), %s is not for IrDA mode\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n", dongle_types[dongle_id]); break; case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); break; case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */ - outb_p( 0x28, iobase+7); /* Set irsl[0-2] as output */ + outb_p(0x28, iobase+7); /* Set irsl[0-2] as output */ break; case 0x0A: /* same as */ case 0x0B: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x0C: /* same as */ @@ -497,28 +536,28 @@ static void pc87108_init_dongle_interface (int iobase, int dongle_id) * Set irsl0 as input, irsl[1-2] as output, and separate * inputs are used for SIR and MIR/FIR */ - outb( 0x48, iobase+7); + outb(0x48, iobase+7); break; case 0x0E: /* Supports SIR Mode only */ - outb( 0x28, iobase+7); /* Set irsl[0-2] as output */ + outb(0x28, iobase+7); /* Set irsl[0-2] as output */ break; case 0x0F: /* No dongle connected */ - DEBUG( 0, __FUNCTION__ "(), %s\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s\n", dongle_types[dongle_id]); - DEBUG( 0, "***\n"); + IRDA_DEBUG(0, "***\n"); - switch_bank( iobase, BANK0); - outb( 0x62, iobase+MCR); + switch_bank(iobase, BANK0); + outb(0x62, iobase+MCR); break; default: - DEBUG( 0, __FUNCTION__ "(), invalid dongle_id %#x", dongle_id); + IRDA_DEBUG(0, __FUNCTION__ "(), invalid dongle_id %#x", dongle_id); } /* IRCFG1: IRSL1 and 2 are set to IrDA mode */ - outb( 0x00, iobase+4); + outb(0x00, iobase+4); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* set_up_dongle_interface */ @@ -528,66 +567,66 @@ static void pc87108_init_dongle_interface (int iobase, int dongle_id) * Change speed of the attach dongle * */ -static void pc87108_change_dongle_speed( int iobase, int speed, int dongle_id) +static void pc87108_change_dongle_speed(int iobase, int speed, int dongle_id) { unsigned long flags; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Select Bank 7 */ - switch_bank( iobase, BANK7); + switch_bank(iobase, BANK7); /* IRCFG1: set according to dongle_id */ switch (dongle_id) { case 0x00: /* same as */ case 0x01: /* Differential serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x02: /* same as */ case 0x03: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x04: /* Sharp RY5HD01 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); case 0x05: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x06: /* Single-ended serial interface */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x07: /* Consumer-IR only */ - DEBUG( 0, __FUNCTION__ "(), %s is not for IrDA mode\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n", dongle_types[dongle_id]); break; case 0x08: /* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */ - DEBUG( 0, __FUNCTION__ "(), %s not supported yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not supported yet\n", dongle_types[dongle_id]); case 0x09: /* IBM31T1100 or Temic TFDS6000/TFDS6500 */ - switch_bank( iobase, BANK7); - outb_p( 0x01, iobase+4); + switch_bank(iobase, BANK7); + outb_p(0x01, iobase+4); - if ( speed == 4000000) { + if (speed == 4000000) { save_flags(flags); cli(); - outb( 0x81, iobase+4); - outb( 0x80, iobase+4); + outb(0x81, iobase+4); + outb(0x80, iobase+4); restore_flags(flags); } else - outb_p( 0x00, iobase+4); + outb_p(0x00, iobase+4); break; case 0x0A: /* same as */ case 0x0B: /* Reserved */ - DEBUG( 0, __FUNCTION__ "(), %s not defined by irda yet\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s not defined by irda yet\n", dongle_types[dongle_id]); break; case 0x0C: /* same as */ @@ -596,78 +635,77 @@ static void pc87108_change_dongle_speed( int iobase, int speed, int dongle_id) case 0x0E: /* Supports SIR Mode only */ break; case 0x0F: /* No dongle connected */ - DEBUG( 0, __FUNCTION__ "(), %s is not for IrDA mode\n", + IRDA_DEBUG(0, __FUNCTION__ "(), %s is not for IrDA mode\n", dongle_types[dongle_id]); - switch_bank( iobase, BANK0); - outb( 0x62, iobase+MCR); + switch_bank(iobase, BANK0); + outb(0x62, iobase+MCR); break; default: - DEBUG( 0, __FUNCTION__ "(), invalid data_rate\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), invalid data_rate\n"); } /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* - * Function pc87108_change_speed (idev, baud) + * Function pc87108_change_speed (self, baud) * * Change the speed of the device * */ -static void pc87108_change_speed(struct irda_device *idev, __u32 speed) +static void pc87108_change_speed(struct pc87108 *self, __u32 speed) { __u8 mcr = MCR_SIR; __u8 bank; int iobase; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( idev != NULL, return;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Update accounting for new speed */ - idev->io.baudrate = speed; + self->io.speed = speed; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Disable interrupts */ - switch_bank( iobase, BANK0); - outb( 0, iobase+IER); + switch_bank(iobase, BANK0); + outb(0, iobase+IER); /* Select Bank 2 */ - switch_bank( iobase, BANK2); - - outb( 0x00, iobase+BGDH); - switch ( speed) { - case 9600: outb( 0x0c, iobase+BGDL); break; - case 19200: outb( 0x06, iobase+BGDL); break; - case 37600: outb( 0x03, iobase+BGDL); break; - case 57600: outb( 0x02, iobase+BGDL); break; - case 115200: outb( 0x01, iobase+BGDL); break; + switch_bank(iobase, BANK2); + + outb(0x00, iobase+BGDH); + switch (speed) { + case 9600: outb(0x0c, iobase+BGDL); break; + case 19200: outb(0x06, iobase+BGDL); break; + case 37600: outb(0x03, iobase+BGDL); break; + case 57600: outb(0x02, iobase+BGDL); break; + case 115200: outb(0x01, iobase+BGDL); break; case 576000: - switch_bank( iobase, BANK5); + switch_bank(iobase, BANK5); /* IRCR2: MDRS is set */ - outb( inb( iobase+4) | 0x04, iobase+4); + outb(inb(iobase+4) | 0x04, iobase+4); mcr = MCR_MIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); break; case 1152000: mcr = MCR_MIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); break; case 4000000: mcr = MCR_FIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); break; default: mcr = MCR_FIR; - DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); break; } @@ -676,34 +714,34 @@ static void pc87108_change_speed(struct irda_device *idev, __u32 speed) outb(mcr | MCR_TX_DFR, iobase+MCR); /* Give some hits to the transceiver */ - pc87108_change_dongle_speed( iobase, speed, idev->io.dongle_id); + pc87108_change_dongle_speed(iobase, speed, self->io.dongle_id); /* Set FIFO threshold to TX17, RX16 */ - switch_bank( iobase, BANK0); - outb( FCR_RXTH| /* Set Rx FIFO threshold */ + switch_bank(iobase, BANK0); + outb(FCR_RXTH| /* Set Rx FIFO threshold */ FCR_TXTH| /* Set Tx FIFO threshold */ FCR_TXSR| /* Reset Tx FIFO */ FCR_RXSR| /* Reset Rx FIFO */ FCR_FIFO_EN, /* Enable FIFOs */ iobase+FCR); - /* outb( 0xa7, iobase+FCR); */ + /* outb(0xa7, iobase+FCR); */ /* Set FIFO size to 32 */ - switch_bank( iobase, BANK2); - outb( EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2); + switch_bank(iobase, BANK2); + outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2); - idev->netdev.tbusy = 0; + self->netdev->tbusy = 0; /* Enable some interrupts so we can receive frames */ - switch_bank( iobase, BANK0); - if ( speed > 115200) { - outb( IER_SFIF_IE, iobase+IER); - pc87108_dma_receive( idev); + switch_bank(iobase, BANK0); + if (speed > 115200) { + outb(IER_SFIF_IE, iobase+IER); + pc87108_dma_receive(self); } else - outb( IER_RXHDL_IE, iobase+IER); + outb(IER_RXHDL_IE, iobase+IER); /* Restore BSR */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* @@ -712,107 +750,106 @@ static void pc87108_change_speed(struct irda_device *idev, __u32 speed) * Transmit the frame! * */ -static int pc87108_hard_xmit( struct sk_buff *skb, struct net_device *dev) +static int pc87108_hard_xmit(struct sk_buff *skb, struct net_device *dev) { - struct irda_device *idev; + struct pc87108 *self; int iobase; __u8 bank; int mtt; - idev = (struct irda_device *) dev->priv; + self = (struct pc87108 *) dev->priv; - ASSERT( idev != NULL, return 0;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; - DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Lock transmit buffer */ - if ( irda_lock( (void *) &dev->tbusy) == FALSE) + if (irda_lock((void *) &dev->tbusy) == FALSE) return -EBUSY; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Decide if we should use PIO or DMA transfer */ - if ( idev->io.baudrate > 115200) { - idev->tx_buff.data = idev->tx_buff.head; - memcpy(idev->tx_buff.data, skb->data, skb->len); - idev->tx_buff.len = skb->len; + if (self->io.speed > 115200) { + self->tx_buff.data = self->tx_buff.head; + memcpy(self->tx_buff.data, skb->data, skb->len); + self->tx_buff.len = skb->len; - mtt = irda_get_mtt( skb); - if ( mtt > 50) { + mtt = irda_get_mtt(skb); + if (mtt > 50) { /* Adjust for timer resolution */ mtt = mtt / 125 + 1; /* Setup timer */ - switch_bank( iobase, BANK4); - outb( mtt & 0xff, iobase+TMRL); - outb(( mtt >> 8) & 0x0f, iobase+TMRH); + switch_bank(iobase, BANK4); + outb(mtt & 0xff, iobase+TMRL); + outb((mtt >> 8) & 0x0f, iobase+TMRH); /* Start timer */ - outb( IRCR1_TMR_EN, iobase+IRCR1); - idev->io.direction = IO_XMIT; + outb(IRCR1_TMR_EN, iobase+IRCR1); + self->io.direction = IO_XMIT; /* Enable timer interrupt */ - switch_bank( iobase, BANK0); - outb( IER_TMR_IE, iobase+IER); + switch_bank(iobase, BANK0); + outb(IER_TMR_IE, iobase+IER); } else { /* Use udelay for delays less than 50 us. */ if (mtt) - udelay( mtt); + udelay(mtt); /* Enable DMA interrupt */ - switch_bank( iobase, BANK0); - outb( IER_DMA_IE, iobase+IER); - pc87108_dma_write( idev, iobase); + switch_bank(iobase, BANK0); + outb(IER_DMA_IE, iobase+IER); + pc87108_dma_write(self, iobase); } } else { - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); - idev->tx_buff.data = idev->tx_buff.head; + self->tx_buff.data = self->tx_buff.head; /* Add interrupt on tx low level (will fire immediately) */ - switch_bank( iobase, BANK0); - outb( IER_TXLDL_IE, iobase+IER); + switch_bank(iobase, BANK0); + outb(IER_TXLDL_IE, iobase+IER); } - dev_kfree_skb( skb); + dev_kfree_skb(skb); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); return 0; } /* - * Function pc87108_dma_xmit (idev, iobase) + * Function pc87108_dma_xmit (self, iobase) * * Transmit data using DMA * */ -static void pc87108_dma_write( struct irda_device *idev, int iobase) +static void pc87108_dma_write(struct pc87108 *self, int iobase) { int bsr; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ - bsr = inb( iobase+BSR); + bsr = inb(iobase+BSR); /* Disable DMA */ switch_bank(iobase, BANK0); - outb( inb( iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); + outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); - setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, + setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, DMA_MODE_WRITE); - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Choose transmit DMA channel */ switch_bank(iobase, BANK2); - outb( inb( iobase+ECR1) | ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, + outb(inb(iobase+ECR1) | ECR1_DMASWP|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1); /* Enable DMA */ @@ -824,7 +861,7 @@ static void pc87108_dma_write( struct irda_device *idev, int iobase) } /* - * Function pc87108_pio_xmit (idev, iobase) + * Function pc87108_pio_xmit (self, iobase) * * Transmit data using PIO. Returns the number of bytes that actually * got transfered @@ -835,17 +872,17 @@ static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size) int actual = 0; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); - switch_bank( iobase, BANK0); - if (!(inb_p( iobase+LSR) & LSR_TXEMP)) { - DEBUG( 4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); + switch_bank(iobase, BANK0); + if (!(inb_p(iobase+LSR) & LSR_TXEMP)) { + IRDA_DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); fifo_size -= 17; - DEBUG( 4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); + IRDA_DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); } /* Fill FIFO with current frame */ @@ -854,7 +891,7 @@ static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size) outb(buf[actual++], iobase+TXD); } - DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", + IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", fifo_size, actual, len); /* Restore bank */ @@ -864,74 +901,69 @@ static int pc87108_pio_write(int iobase, __u8 *buf, int len, int fifo_size) } /* - * Function pc87108_dma_xmit_complete (idev) + * Function pc87108_dma_xmit_complete (self) * * The transfer of a frame in finished. This function will only be called * by the interrupt handler * */ -static void pc87108_dma_xmit_complete( struct irda_device *idev) +static void pc87108_dma_xmit_complete(struct pc87108 *self) { int iobase; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( idev != NULL, return;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Disable DMA */ - switch_bank( iobase, BANK0); - outb( inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); + switch_bank(iobase, BANK0); + outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); /* Check for underrrun! */ - if ( inb( iobase+ASCR) & ASCR_TXUR) { - idev->stats.tx_errors++; - idev->stats.tx_fifo_errors++; + if (inb(iobase+ASCR) & ASCR_TXUR) { + self->stats.tx_errors++; + self->stats.tx_fifo_errors++; /* Clear bit, by writing 1 into it */ - outb( ASCR_TXUR, iobase+ASCR); + outb(ASCR_TXUR, iobase+ASCR); } else { - idev->stats.tx_packets++; - idev->stats.tx_bytes += idev->tx_buff.len; + self->stats.tx_packets++; + self->stats.tx_bytes += self->tx_buff.len; } /* Unlock tx_buff and request another frame */ - idev->netdev.tbusy = 0; /* Unlock */ - idev->media_busy = FALSE; + self->netdev->tbusy = 0; /* Unlock */ /* Tell the network layer, that we can accept more frames */ - mark_bh( NET_BH); + mark_bh(NET_BH); /* Restore bank */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } /* - * Function pc87108_dma_receive (idev) + * Function pc87108_dma_receive (self) * * Get ready for receiving a frame. The device will initiate a DMA * if it starts to receive a frame. * */ -static int pc87108_dma_receive(struct irda_device *idev) +static int pc87108_dma_receive(struct pc87108 *self) { - struct pc87108 *self; int iobase; __u8 bsr; - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); - self = idev->priv; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ bsr = inb(iobase+BSR); @@ -940,12 +972,12 @@ static int pc87108_dma_receive(struct irda_device *idev) switch_bank(iobase, BANK0); outb(inb(iobase+MCR) & ~MCR_DMA_EN, iobase+MCR); - setup_dma(idev->io.dma, idev->rx_buff.data, - idev->rx_buff.truesize, DMA_MODE_READ); + setup_dma(self->io.dma, self->rx_buff.data, + self->rx_buff.truesize, DMA_MODE_READ); /* driver->media_busy = FALSE; */ - idev->io.direction = IO_RECV; - idev->rx_buff.data = idev->rx_buff.head; + self->io.direction = IO_RECV; + self->rx_buff.data = self->rx_buff.head; /* Reset Rx FIFO. This will also flush the ST_FIFO */ outb(FCR_RXTH|FCR_TXTH|FCR_RXSR|FCR_FIFO_EN, iobase+FCR); @@ -953,7 +985,7 @@ static int pc87108_dma_receive(struct irda_device *idev) /* Choose DMA Rx, DMA Fairness, and Advanced mode */ switch_bank(iobase, BANK2); - outb((inb( iobase+ECR1) & ~ECR1_DMASWP)|ECR1_DMANF|ECR1_EXT_SL, + outb((inb(iobase+ECR1) & ~ECR1_DMASWP)|ECR1_DMANF|ECR1_EXT_SL, iobase+ECR1); /* enable DMA */ @@ -963,40 +995,38 @@ static int pc87108_dma_receive(struct irda_device *idev) /* Restore bank register */ outb(bsr, iobase+BSR); - DEBUG(4, __FUNCTION__ "(), done!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), done!\n"); return 0; } /* - * Function pc87108_dma_receive_complete (idev) + * Function pc87108_dma_receive_complete (self) * * Finished with receiving frames * * */ -static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) +static int pc87108_dma_receive_complete(struct pc87108 *self, int iobase) { struct sk_buff *skb; - struct pc87108 *self; struct st_fifo *st_fifo; - int len; __u8 bank; __u8 status; + int len; - self = idev->priv; st_fifo = &self->st_fifo; /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Read status FIFO */ switch_bank(iobase, BANK5); - while (( status = inb( iobase+FRM_ST)) & FRM_ST_VLD) { - st_fifo->entries[ st_fifo->tail].status = status; + while ((status = inb(iobase+FRM_ST)) & FRM_ST_VLD) { + st_fifo->entries[st_fifo->tail].status = status; - st_fifo->entries[ st_fifo->tail].len = inb(iobase+RFLFL); - st_fifo->entries[ st_fifo->tail].len |= inb(iobase+RFLFH) << 8; + st_fifo->entries[st_fifo->tail].len = inb(iobase+RFLFL); + st_fifo->entries[st_fifo->tail].len |= inb(iobase+RFLFH) << 8; st_fifo->tail++; st_fifo->len++; @@ -1016,28 +1046,28 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) if (status & FRM_ST_ERR_MSK) { if (status & FRM_ST_LOST_FR) { /* Add number of lost frames to stats */ - idev->stats.rx_errors += len; + self->stats.rx_errors += len; } else { /* Skip frame */ - idev->stats.rx_errors++; + self->stats.rx_errors++; - idev->rx_buff.data += len; + self->rx_buff.data += len; if (status & FRM_ST_MAX_LEN) - idev->stats.rx_length_errors++; + self->stats.rx_length_errors++; if (status & FRM_ST_PHY_ERR) - idev->stats.rx_frame_errors++; + self->stats.rx_frame_errors++; if (status & FRM_ST_BAD_CRC) - idev->stats.rx_crc_errors++; + self->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FRM_ST_OVR1) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; if (status & FRM_ST_OVR2) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; } else { /* Check if we have transfered all data to memory */ @@ -1057,10 +1087,10 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) /* Should be OK then */ skb = dev_alloc_skb(len+1); if (skb == NULL) { - printk( KERN_INFO __FUNCTION__ + printk(KERN_INFO __FUNCTION__ "(), memory squeeze, dropping frame.\n"); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); return FALSE; } @@ -1069,22 +1099,22 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) skb_reserve(skb, 1); /* Copy frame without CRC */ - if (idev->io.baudrate < 4000000) { + if (self->io.speed < 4000000) { skb_put(skb, len-2); - memcpy(skb->data, idev->rx_buff.data, len-2); + memcpy(skb->data, self->rx_buff.data, len-2); } else { skb_put(skb, len-4); - memcpy(skb->data, idev->rx_buff.data, len-4); + memcpy(skb->data, self->rx_buff.data, len-4); } /* Move to next frame */ - idev->rx_buff.data += len; - idev->stats.rx_packets++; + self->rx_buff.data += len; + self->stats.rx_packets++; - skb->dev = &idev->netdev; + skb->dev = self->netdev; skb->mac.raw = skb->data; skb->protocol = htons(ETH_P_IRDA); - netif_rx( skb); + netif_rx(skb); } } /* Restore bank register */ @@ -1094,60 +1124,59 @@ static int pc87108_dma_receive_complete(struct irda_device *idev, int iobase) } /* - * Function pc87108_pio_receive (idev) + * Function pc87108_pio_receive (self) * * Receive all data in receiver FIFO * */ -static void pc87108_pio_receive( struct irda_device *idev) +static void pc87108_pio_receive(struct pc87108 *self) { __u8 byte = 0x00; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RXD); - async_unwrap_char(idev, byte); + async_unwrap_char(self->netdev, &self->rx_buff, byte); } while (inb(iobase+LSR) & LSR_RXDA); /* Data available */ } /* - * Function pc87108_sir_interrupt (idev, eir) + * Function pc87108_sir_interrupt (self, eir) * * Handle SIR interrupt * */ -static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir) +static __u8 pc87108_sir_interrupt(struct pc87108 *self, int eir) { int actual; __u8 new_ier = 0; /* Transmit FIFO low on data */ - if ( eir & EIR_TXLDL_EV) { + if (eir & EIR_TXLDL_EV) { /* Write data left in transmit buffer */ - actual = pc87108_pio_write(idev->io.iobase, - idev->tx_buff.data, - idev->tx_buff.len, - idev->io.fifo_size); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + actual = pc87108_pio_write(self->io.iobase, + self->tx_buff.data, + self->tx_buff.len, + self->io.fifo_size); + self->tx_buff.data += actual; + self->tx_buff.len -= actual; - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Check if finished */ - if (idev->tx_buff.len > 0) + if (self->tx_buff.len > 0) new_ier |= IER_TXLDL_IE; else { - idev->netdev.tbusy = 0; /* Unlock */ - idev->stats.tx_packets++; + self->netdev->tbusy = 0; /* Unlock */ + self->stats.tx_packets++; mark_bh(NET_BH); @@ -1156,16 +1185,16 @@ static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir) } /* Check if transmission has completed */ - if ( eir & EIR_TXEMP_EV) { + if (eir & EIR_TXEMP_EV) { /* Turn around and get ready to receive some data */ - idev->io.direction = IO_RECV; + self->io.direction = IO_RECV; new_ier |= IER_RXHDL_IE; } /* Rx FIFO threshold or timeout */ - if ( eir & EIR_RXHDL_EV) { - pc87108_pio_receive( idev); + if (eir & EIR_RXHDL_EV) { + pc87108_pio_receive(self); /* Keep receiving */ new_ier |= IER_RXHDL_IE; @@ -1174,22 +1203,22 @@ static __u8 pc87108_sir_interrupt(struct irda_device *idev, int eir) } /* - * Function pc87108_fir_interrupt (idev, eir) + * Function pc87108_fir_interrupt (self, eir) * * Handle MIR/FIR interrupt * */ -static __u8 pc87108_fir_interrupt( struct irda_device *idev, int iobase, - int eir) +static __u8 pc87108_fir_interrupt(struct pc87108 *self, int iobase, + int eir) { __u8 new_ier = 0; __u8 bank; - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* Status event, or end of frame detected in FIFO */ if (eir & (EIR_SFIF_EV|EIR_LS_EV)) { - if (pc87108_dma_receive_complete( idev, iobase)) { + if (pc87108_dma_receive_complete(self, iobase)) { /* Wait for next status FIFO interrupt */ new_ier |= IER_SFIF_IE; @@ -1197,52 +1226,52 @@ static __u8 pc87108_fir_interrupt( struct irda_device *idev, int iobase, /* DMA not finished yet */ /* Set timer value, resolution 125 us */ - switch_bank( iobase, BANK4); - outb( 0x0f, iobase+TMRL); /* 125 us */ - outb( 0x00, iobase+TMRH); + switch_bank(iobase, BANK4); + outb(0x0f, iobase+TMRL); /* 125 us */ + outb(0x00, iobase+TMRH); /* Start timer */ - outb( IRCR1_TMR_EN, iobase+IRCR1); + outb(IRCR1_TMR_EN, iobase+IRCR1); new_ier |= IER_TMR_IE; } } /* Timer finished */ - if ( eir & EIR_TMR_EV) { + if (eir & EIR_TMR_EV) { /* Disable timer */ - switch_bank( iobase, BANK4); - outb( 0, iobase+IRCR1); + switch_bank(iobase, BANK4); + outb(0, iobase+IRCR1); /* Clear timer event */ switch_bank(iobase, BANK0); - outb( ASCR_CTE, iobase+ASCR); + outb(ASCR_CTE, iobase+ASCR); /* Check if this is a TX timer interrupt */ - if ( idev->io.direction == IO_XMIT) { - pc87108_dma_write( idev, iobase); + if (self->io.direction == IO_XMIT) { + pc87108_dma_write(self, iobase); /* Interrupt on DMA */ new_ier |= IER_DMA_IE; } else { /* Check if DMA has now finished */ - pc87108_dma_receive_complete( idev, iobase); + pc87108_dma_receive_complete(self, iobase); new_ier |= IER_SFIF_IE; } } /* Finished with transmission */ - if ( eir & EIR_DMA_EV) { - pc87108_dma_xmit_complete( idev); + if (eir & EIR_DMA_EV) { + pc87108_dma_xmit_complete(self); /* Check if there are more frames to be transmitted */ - if ( irda_device_txqueue_empty( idev)) { + if (irda_device_txqueue_empty(self->netdev)) { /* Prepare for receive */ - pc87108_dma_receive( idev); + pc87108_dma_receive(self); new_ier = IER_LS_IE|IER_SFIF_IE; } } - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); return new_ier; } @@ -1255,51 +1284,52 @@ static __u8 pc87108_fir_interrupt( struct irda_device *idev, int iobase, */ static void pc87108_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + struct net_device *dev = (struct net_device *) dev_id; + struct pc87108 *self; __u8 bsr, eir, ier; int iobase; - struct irda_device *idev = (struct irda_device *) dev_id; - - if (idev == NULL) { - printk( KERN_WARNING "%s: irq %d for unknown device.\n", + if (!dev) { + printk(KERN_WARNING "%s: irq %d for unknown device.\n", driver_name, irq); return; } + self = (struct pc87108 *) dev->priv; - idev->netdev.interrupt = 1; + dev->interrupt = 1; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ - bsr = inb( iobase+BSR); + bsr = inb(iobase+BSR); - switch_bank( iobase, BANK0); - ier = inb( iobase+IER); - eir = inb( iobase+EIR) & ier; /* Mask out the interesting ones */ + switch_bank(iobase, BANK0); + ier = inb(iobase+IER); + eir = inb(iobase+EIR) & ier; /* Mask out the interesting ones */ - outb( 0, iobase+IER); /* Disable interrupts */ + outb(0, iobase+IER); /* Disable interrupts */ - if ( eir) { + if (eir) { /* Dispatch interrupt handler for the current speed */ - if ( idev->io.baudrate > 115200) - ier = pc87108_fir_interrupt( idev, iobase, eir); + if (self->io.speed > 115200) + ier = pc87108_fir_interrupt(self, iobase, eir); else - ier = pc87108_sir_interrupt( idev, eir); + ier = pc87108_sir_interrupt(self, eir); } - outb( ier, iobase+IER); /* Restore interrupts */ - outb( bsr, iobase+BSR); /* Restore bank register */ + outb(ier, iobase+IER); /* Restore interrupts */ + outb(bsr, iobase+BSR); /* Restore bank register */ - idev->netdev.interrupt = 0; + dev->interrupt = 0; } /* - * Function pc87108_wait_until_sent (idev) + * Function pc87108_wait_until_sent (self) * * This function should put the current thread to sleep until all data * have been sent, so it is safe to f.eks. change the speed. */ -static void pc87108_wait_until_sent( struct irda_device *idev) +static void pc87108_wait_until_sent(struct pc87108 *self) { /* Just delay 60 ms */ current->state = TASK_INTERRUPTIBLE; @@ -1307,33 +1337,32 @@ static void pc87108_wait_until_sent( struct irda_device *idev) } /* - * Function pc87108_is_receiving (idev) + * Function pc87108_is_receiving (self) * * Return TRUE is we are currently receiving a frame * */ -static int pc87108_is_receiving( struct irda_device *idev) +static int pc87108_is_receiving(struct pc87108 *self) { int status = FALSE; int iobase; __u8 bank; - ASSERT( idev != NULL, return FALSE;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;); + ASSERT(self != NULL, return FALSE;); - if ( idev->io.baudrate > 115200) { - iobase = idev->io.iobase; + if (self->io.speed > 115200) { + iobase = self->io.iobase; /* Check if rx FIFO is not empty */ - bank = inb( iobase+BSR); - switch_bank( iobase, BANK2); - if (( inb( iobase+RXFLV) & 0x3f) != 0) { + bank = inb(iobase+BSR); + switch_bank(iobase, BANK2); + if ((inb(iobase+RXFLV) & 0x3f) != 0) { /* We are receiving something */ status = TRUE; } - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } else - status = ( idev->rx_buff.state != OUTSIDE_FRAME); + status = (self->rx_buff.state != OUTSIDE_FRAME); return status; } @@ -1344,12 +1373,12 @@ static int pc87108_is_receiving( struct irda_device *idev) * Initialize network device * */ -static int pc87108_net_init( struct net_device *dev) +static int pc87108_net_init(struct net_device *dev) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Setup to be a normal IrDA network device driver */ - irda_device_setup( dev); + irda_device_setup(dev); /* Insert overrides below this line! */ @@ -1363,46 +1392,54 @@ static int pc87108_net_init( struct net_device *dev) * Start the device * */ -static int pc87108_net_open( struct net_device *dev) +static int pc87108_net_open(struct net_device *dev) { - struct irda_device *idev; + struct pc87108 *self; int iobase; __u8 bank; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + ASSERT(dev != NULL, return -1;); + self = (struct pc87108 *) dev->priv; - ASSERT( idev != NULL, return 0;); - ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; - if (request_irq( idev->io.irq, pc87108_interrupt, 0, idev->name, - (void *) idev)) { + if (request_irq(self->io.irq, pc87108_interrupt, 0, dev->name, + (void *) dev)) { return -EAGAIN; } /* * Always allocate the DMA channel after the IRQ, * and clean up on failure. */ - if (request_dma(idev->io.dma, idev->name)) { - free_irq( idev->io.irq, idev); + if (request_dma(self->io.dma, dev->name)) { + free_irq(self->io.irq, self); return -EAGAIN; } /* Save current bank */ - bank = inb( iobase+BSR); + bank = inb(iobase+BSR); /* turn on interrupts */ - switch_bank( iobase, BANK0); - outb( IER_LS_IE | IER_RXHDL_IE, iobase+IER); + switch_bank(iobase, BANK0); + outb(IER_LS_IE | IER_RXHDL_IE, iobase+IER); /* Restore bank register */ - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); - irda_device_net_open(dev); + /* Ready to play! */ + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + /* + * Open new IrLAP layer instance, now that everything should be + * initialized properly + */ + self->irlap = irlap_open(dev, &self->qos); MOD_INC_USE_COUNT; @@ -1417,23 +1454,29 @@ static int pc87108_net_open( struct net_device *dev) */ static int pc87108_net_close(struct net_device *dev) { - struct irda_device *idev; + struct pc87108 *self; int iobase; __u8 bank; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - irda_device_net_close(dev); - ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct pc87108 *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); + + /* Stop device */ + dev->tbusy = 1; + dev->start = 0; + + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; - iobase = idev->io.iobase; + iobase = self->io.iobase; - disable_dma(idev->io.dma); + disable_dma(self->io.dma); /* Save current bank */ bank = inb(iobase+BSR); @@ -1442,8 +1485,8 @@ static int pc87108_net_close(struct net_device *dev) switch_bank(iobase, BANK0); outb(0, iobase+IER); - free_irq(idev->io.irq, idev); - free_dma(idev->io.dma); + free_irq(self->io.irq, self); + free_dma(self->io.dma); /* Restore bank register */ outb(bank, iobase+BSR); diff --git a/drivers/net/irda/smc-ircc.c b/drivers/net/irda/smc-ircc.c index 00ab408d6..06b2af81b 100644 --- a/drivers/net/irda/smc-ircc.c +++ b/drivers/net/irda/smc-ircc.c @@ -106,7 +106,7 @@ int __init ircc_init(void) { int i; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); for ( i=0; (io[i] < 2000) && (i < 4); i++) { int ioaddr = io[i]; if (check_region(ioaddr, CHIP_IO_EXTENT)) @@ -114,7 +114,7 @@ int __init ircc_init(void) if (ircc_open( i, io[i], io2[i]) == 0) return 0; } - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return -ENODEV; } @@ -130,13 +130,13 @@ static void ircc_cleanup(void) { int i; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); for ( i=0; i < 4; i++) { if ( dev_self[i]) ircc_close( &(dev_self[i]->idev)); } - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } #endif /* MODULE */ @@ -153,10 +153,10 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2) int ret; int config; - DEBUG( ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG( ircc_debug, __FUNCTION__ " -->\n"); if ((config = ircc_probe( iobase, iobase2)) == -1) { - DEBUG(ircc_debug, + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": addr 0x%04x - no device found!\n", iobase); return -1; } @@ -199,14 +199,14 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2) /* Lock the port that we need */ ret = check_region( idev->io.iobase, idev->io.io_ext); if ( ret < 0) { - DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", + IRDA_DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", idev->io.iobase); /* ircc_cleanup( self->idev); */ return -ENODEV; } ret = check_region( idev->io.iobase2, idev->io.io_ext2); if ( ret < 0) { - DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", + IRDA_DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n", idev->io.iobase2); /* ircc_cleanup( self->idev); */ return -ENODEV; @@ -256,7 +256,7 @@ static int ircc_open( int i, unsigned int iobase, unsigned int iobase2) /* Open the IrDA device */ irda_device_open( idev, driver_name, self); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -271,7 +271,7 @@ static int ircc_close( struct irda_device *idev) { int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return -1;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;); @@ -291,20 +291,20 @@ static int ircc_close( struct irda_device *idev) serial_out(iobase, UART_SCE_CFGB, UART_CFGB_IR); /* Release the PORT that this driver is using */ - DEBUG( ircc_debug, + IRDA_DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", idev->io.iobase); release_region( idev->io.iobase, idev->io.io_ext); if ( idev->io.iobase2) { - DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", + IRDA_DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", idev->io.iobase2); release_region( idev->io.iobase2, idev->io.io_ext2); } irda_device_close( idev); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } #endif /* MODULE */ @@ -320,7 +320,7 @@ static int ircc_probe(int iobase, int iobase2) int version = 1; int low, high, chip, config, dma, irq; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); register_bank(iobase, 3); high = serial_in(iobase, UART_ID_HIGH); @@ -332,7 +332,7 @@ static int ircc_probe(int iobase, int iobase2) dma = config & 0x0f; if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) { - DEBUG(0, "SMC IrDA Controller found; IrCC version %d.%d, " + IRDA_DEBUG(0, "SMC IrDA Controller found; IrCC version %d.%d, " "port 0x%04x, dma %d, interrupt %d\n", chip & 0x0f, version, iobase, dma, irq); } else { @@ -341,7 +341,7 @@ static int ircc_probe(int iobase, int iobase2) serial_out(iobase, UART_MASTER, 0); - DEBUG(ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n"); return config; } @@ -357,7 +357,7 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) struct ircc_cb *self; int iobase, ir_mode, select, fast; - DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -374,7 +374,7 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) case 37600: case 57600: case 115200: - DEBUG(ircc_debug+1, + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ ": using irport to change speed to %d\n", speed); register_bank(iobase, 0); @@ -390,22 +390,22 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) ir_mode = UART_CFGA_IRDA_HDLC; select = 0; fast = 0; - DEBUG( ircc_debug, __FUNCTION__ ": handling baud of 576000\n"); + IRDA_DEBUG( ircc_debug, __FUNCTION__ ": handling baud of 576000\n"); break; case 1152000: ir_mode = UART_CFGA_IRDA_HDLC; select = UART_1152; fast = 0; - DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 1152000\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 1152000\n"); break; case 4000000: ir_mode = UART_CFGA_IRDA_4PPM; select = 0; fast = UART_LCR_A_FAST; - DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 4000000\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 4000000\n"); break; default: - DEBUG( 0, __FUNCTION__ ": unknown baud rate of %d\n", speed); + IRDA_DEBUG( 0, __FUNCTION__ ": unknown baud rate of %d\n", speed); return; } @@ -443,7 +443,7 @@ static void ircc_change_speed( struct irda_device *idev, __u32 speed) serial_out(iobase, UART_LCR_A, fast); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -458,7 +458,7 @@ static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) int iobase; int mtt; - DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); idev = (struct irda_device *) dev->priv; ASSERT( idev != NULL, return 0;); @@ -466,15 +466,15 @@ static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) iobase = idev->io.iobase; - DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Use irport for SIR speeds */ if (idev->io.baudrate <= 115200) { - DEBUG(ircc_debug+1, __FUNCTION__ ": calling irport_hard_xmit\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ ": calling irport_hard_xmit\n"); return irport_hard_xmit(skb, dev); } - DEBUG(ircc_debug, __FUNCTION__ ": using dma; len=%d\n", skb->len); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": using dma; len=%d\n", skb->len); /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) @@ -502,7 +502,7 @@ static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev) dev_kfree_skb( skb); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -516,7 +516,7 @@ static void ircc_dma_write( struct irda_device *idev, int iobase) { struct ircc_cb *self; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -557,7 +557,7 @@ static void ircc_dma_write( struct irda_device *idev, int iobase) serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -572,7 +572,7 @@ static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun) struct ircc_cb *self; int iobase, d; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -585,7 +585,7 @@ static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun) d = get_dma_residue(idev->io.dma); - DEBUG(ircc_debug, __FUNCTION__ ": dma residue = %d, len=%d, sent=%d\n", + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma residue = %d, len=%d, sent=%d\n", d, idev->tx_buff.len, idev->tx_buff.len - d); self = idev->priv; @@ -608,7 +608,7 @@ static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun) /* Tell the network layer, that we can accept more frames */ mark_bh( NET_BH); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -623,7 +623,7 @@ static int ircc_dma_receive( struct irda_device *idev) struct ircc_cb *self; int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return -1;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;); @@ -660,7 +660,7 @@ static int ircc_dma_receive( struct irda_device *idev) serial_in(iobase, UART_SCE_CFGB) | UART_CFGB_DMA_ENABLE | UART_CFGB_DMA_BURST); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -677,18 +677,18 @@ static int ircc_dma_receive_complete( struct irda_device *idev, int iobase) struct ircc_cb *self; int len, msgcnt; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); self = idev->priv; msgcnt = serial_in(idev->io.iobase, UART_LCR_B) & 0x08; - DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", get_dma_residue(idev->io.dma)); len = idev->rx_buff.truesize - get_dma_residue(idev->io.dma) - 4; - DEBUG(ircc_debug, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len); skb = dev_alloc_skb( len+1); @@ -715,7 +715,7 @@ static int ircc_dma_receive_complete( struct irda_device *idev, int iobase) serial_in(idev->io.iobase, UART_SCE_CFGB) & ~UART_CFGB_DMA_ENABLE); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return TRUE; } @@ -731,7 +731,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct irda_device *idev = (struct irda_device *) dev_id; - DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n"); if (idev == NULL) { printk( KERN_WARNING "%s: irq %d for unknown device.\n", @@ -740,7 +740,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (idev->io.baudrate <= 115200) { - DEBUG(ircc_debug+1, __FUNCTION__ + IRDA_DEBUG(ircc_debug+1, __FUNCTION__ ": routing interrupt to irport_interrupt\n"); return irport_interrupt( irq, dev_id, regs); } @@ -757,10 +757,10 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) serial_out(iobase, UART_IER, 0); - DEBUG(ircc_debug, __FUNCTION__ ": iir = 0x%02x\n", iir); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": iir = 0x%02x\n", iir); if (iir & UART_IIR_EOM) { - DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_EOM\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_EOM\n"); if (idev->io.direction == IO_RECV) { ircc_dma_receive_complete(idev, iobase); } else { @@ -770,7 +770,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (iir & UART_IIR_ACTIVE_FRAME) { - DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_ACTIVE_FRAME\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_ACTIVE_FRAME\n"); idev->rx_buff.state = INSIDE_FRAME; #if 0 ircc_dma_receive(idev); @@ -778,7 +778,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) } if (iir & UART_IIR_RAW_MODE) { - DEBUG(ircc_debug, __FUNCTION__ ": IIR RAW mode interrupt.\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": IIR RAW mode interrupt.\n"); } idev->netdev.interrupt = 0; @@ -787,7 +787,7 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) serial_out(iobase, UART_IER, UART_IER_ACTIVE_FRAME|UART_IER_EOM); serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -798,13 +798,13 @@ static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ static void ircc_wait_until_sent( struct irda_device *idev) { - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); /* Just delay 60 ms */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(MSECS_TO_JIFFIES(60)); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); } /* @@ -818,17 +818,17 @@ static int ircc_is_receiving( struct irda_device *idev) int status = FALSE; /* int iobase; */ - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( idev != NULL, return FALSE;); ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;); - DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", + IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n", get_dma_residue(idev->io.dma)); status = ( idev->rx_buff.state != OUTSIDE_FRAME); - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return status; } @@ -841,14 +841,14 @@ static int ircc_is_receiving( struct irda_device *idev) */ static int ircc_net_init( struct net_device *dev) { - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); /* Setup to be a normal IrDA network device driver */ irda_device_setup( dev); /* Insert overrides below this line! */ - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -864,7 +864,7 @@ static int ircc_net_open( struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -894,7 +894,7 @@ static int ircc_net_open( struct net_device *dev) MOD_INC_USE_COUNT; - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } @@ -909,7 +909,7 @@ static int ircc_net_close(struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG(ircc_debug, __FUNCTION__ " -->\n"); + IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n"); ASSERT( dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -930,7 +930,7 @@ static int ircc_net_close(struct net_device *dev) MOD_DEC_USE_COUNT; - DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); + IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n"); return 0; } diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c index 6f3c49f6f..35504cfd3 100644 --- a/drivers/net/irda/tekram.c +++ b/drivers/net/irda/tekram.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Oct 21 20:02:35 1998 - * Modified at: Thu Jul 15 01:17:53 1999 + * Modified at: Mon Oct 18 23:25:44 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -29,15 +29,14 @@ #include <linux/init.h> #include <net/irda/irda.h> +#include <net/irda/irmod.h> #include <net/irda/irda_device.h> #include <net/irda/irtty.h> -#include <net/irda/dongle.h> -static void tekram_reset(struct irda_device *dev); -static void tekram_open(struct irda_device *dev, int type); -static void tekram_close(struct irda_device *dev); -static void tekram_change_speed(struct irda_device *dev, __u32 speed); -static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos); +static void tekram_open(dongle_t *self, struct qos_info *qos); +static void tekram_close(dongle_t *self); +static int tekram_change_speed(struct irda_task *task); +static int tekram_reset(struct irda_task *task); #define TEKRAM_115200 0x00 #define TEKRAM_57600 0x01 @@ -47,13 +46,13 @@ static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos); #define TEKRAM_PW 0x10 /* Pulse select bit */ -static struct dongle dongle = { - TEKRAM_DONGLE, +static struct dongle_reg dongle = { + Q_NULL, + IRDA_TEKRAM_DONGLE, tekram_open, tekram_close, tekram_reset, tekram_change_speed, - tekram_init_qos, }; int __init tekram_init(void) @@ -66,26 +65,29 @@ void tekram_cleanup(void) irda_device_unregister_dongle(&dongle); } -static void tekram_open(struct irda_device *idev, int type) +static void tekram_open(dongle_t *self, struct qos_info *qos) { - strcat(idev->description, " <-> tekram"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + + qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; + qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */ + irda_qos_bits_to_value(qos); - idev->io.dongle_id = type; - idev->flags |= IFF_DONGLE; - MOD_INC_USE_COUNT; } -static void tekram_close(struct irda_device *idev) -{ +static void tekram_close(dongle_t *self) +{ + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); + self->set_dtr_rts(self->dev, FALSE, FALSE); MOD_DEC_USE_COUNT; } /* - * Function tekram_change_speed (tty, speed) + * Function tekram_change_speed (dev, state, speed) * * Set the speed for the Tekram IRMate 210 type dongle. Warning, this * function must be called with a process context! @@ -100,14 +102,16 @@ static void tekram_close(struct irda_device *idev) * 6. wait at least 50 us, new setting (baud rate, etc) takes effect here * after */ -static void tekram_change_speed(struct irda_device *idev, __u32 speed) +static int tekram_change_speed(struct irda_task *task) { + dongle_t *self = (dongle_t *) task->instance; + __u32 speed = (__u32) task->param; __u8 byte; + int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(task != NULL, return -1;); switch (speed) { default: @@ -128,24 +132,65 @@ static void tekram_change_speed(struct irda_device *idev, __u32 speed) break; } - /* Need to reset the dongle and go to 9600 bps before programming */ - tekram_reset(idev); - - /* Set DTR, Clear RTS */ - irda_device_set_dtr_rts(idev, TRUE, FALSE); - - /* Wait at least 7us */ - udelay(10); + switch (task->state) { + case IRDA_TASK_INIT: + /* Lock dongle */ + if (irda_lock((void *) &self->busy) == FALSE) { + IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n"); + return MSECS_TO_JIFFIES(100); + } + irda_task_next_state(task, IRDA_TASK_CHILD_INIT); + break; + case IRDA_TASK_CHILD_INIT: + /* + * Need to reset the dongle and go to 9600 bps before + * programming + */ + if (irda_task_execute(self, tekram_reset, NULL, task, + (void *) speed)) + { + /* Dongle need more time to reset */ + irda_task_next_state(task, IRDA_TASK_CHILD_WAIT); - /* Write control byte */ - irda_device_raw_write(idev, &byte, 1); + /* Give reset 1 sec to finish */ + ret = MSECS_TO_JIFFIES(1000); + } else + irda_task_next_state(task, IRDA_TASK_CHILD_DONE); + break; + case IRDA_TASK_CHILD_WAIT: + WARNING(__FUNCTION__ "(), resetting dongle timed out!\n"); + ret = -1; + break; + case IRDA_TASK_CHILD_DONE: + /* Set DTR, Clear RTS */ + self->set_dtr_rts(self->dev, TRUE, FALSE); - /* Wait at least 100 ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(100)); - - /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); + /* Wait at least 7us */ + udelay(10); + + /* Write control byte */ + self->write(self->dev, &byte, 1); + + irda_task_next_state(task, IRDA_TASK_WAIT); + + /* Wait at least 100 ms */ + ret = MSECS_TO_JIFFIES(100); + break; + case IRDA_TASK_WAIT: + /* Set DTR, Set RTS */ + self->set_dtr_rts(self->dev, TRUE, TRUE); + + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + self->busy = 0; + ret = -1; + break; + } + return ret; } /* @@ -161,50 +206,52 @@ static void tekram_change_speed(struct irda_device *idev, __u32 speed) * 3. clear DTR to SPACE state, wait at least 50 us for further * operation */ -void tekram_reset(struct irda_device *idev) +int tekram_reset(struct irda_task *task) { - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + dongle_t *self = (dongle_t *) task->instance; + int ret = 0; + + IRDA_DEBUG(2, __FUNCTION__ "()\n"); + + ASSERT(task != NULL, return -1;); /* Power off dongle */ - irda_device_set_dtr_rts(idev, FALSE, FALSE); - - /* Sleep 50 ms */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(50)); + self->set_dtr_rts(self->dev, FALSE, FALSE); - /* Clear DTR, Set RTS */ - irda_device_set_dtr_rts(idev, FALSE, TRUE); + switch (task->state) { + case IRDA_TASK_INIT: + irda_task_next_state(task, IRDA_TASK_WAIT1); - /* Should sleep 1 ms, but 10-20 should not do any harm */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(20)); + /* Sleep 50 ms */ + ret = MSECS_TO_JIFFIES(50); + break; + case IRDA_TASK_WAIT1: + /* Clear DTR, Set RTS */ + self->set_dtr_rts(self->dev, FALSE, TRUE); - /* Set DTR, Set RTS */ - irda_device_set_dtr_rts(idev, TRUE, TRUE); - - udelay(50); + irda_task_next_state(task, IRDA_TASK_WAIT2); + + /* Should sleep 1 ms, but 10 should not do any harm */ + ret = MSECS_TO_JIFFIES(10); + break; + case IRDA_TASK_WAIT2: + /* Set DTR, Set RTS */ + self->set_dtr_rts(self->dev, TRUE, TRUE); - /* Make sure the IrDA chip also goes to defalt speed */ - if (idev->change_speed) - idev->change_speed(idev, 9600); -} + udelay(50); -/* - * Function tekram_init_qos (qos) - * - * Initialize QoS capabilities - * - */ -static void tekram_init_qos(struct irda_device *idev, struct qos_info *qos) -{ - qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200; - qos->min_turn_time.bits &= 0x01; /* Needs at least 10 ms */ - irda_qos_bits_to_value(qos); + irda_task_next_state(task, IRDA_TASK_DONE); + break; + default: + ERROR(__FUNCTION__ "(), unknown state %d\n", task->state); + irda_task_next_state(task, IRDA_TASK_DONE); + + ret = -1; + } + return ret; } #ifdef MODULE - MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>"); MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver"); @@ -229,5 +276,4 @@ void cleanup_module(void) { tekram_cleanup(); } - #endif /* MODULE */ diff --git a/drivers/net/irda/toshoboe.c b/drivers/net/irda/toshoboe.c index d0dbaa4f7..55e0e5b84 100644 --- a/drivers/net/irda/toshoboe.c +++ b/drivers/net/irda/toshoboe.c @@ -95,6 +95,7 @@ static char *rcsid = "$Id: toshoboe.c,v 1.9 1999/06/29 14:21:06 root Exp $"; #include <linux/malloc.h> #include <linux/init.h> #include <linux/pci.h> +#include <linux/rtnetlink.h> #include <asm/system.h> #include <asm/io.h> @@ -122,7 +123,7 @@ static int max_baud = 4000000; static void toshoboe_stopchip (struct toshoboe_cb *self) { - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); outb_p (0x0e, OBOE_REG_11); @@ -143,7 +144,7 @@ static void toshoboe_setbaud (struct toshoboe_cb *self, int baud) { unsigned long flags; - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); printk (KERN_WARNING "ToshOboe: seting baud to %d\n", baud); @@ -212,7 +213,7 @@ toshoboe_startchip (struct toshoboe_cb *self) { __u32 physaddr; - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); outb_p (0, OBOE_LOCK); @@ -241,7 +242,7 @@ toshoboe_startchip (struct toshoboe_cb *self) static void toshoboe_enablebm (struct toshoboe_cb *self) { - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); pci_set_master (self->pdev); } @@ -250,7 +251,7 @@ static void toshoboe_disablebm (struct toshoboe_cb *self) { __u8 command; - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); pci_read_config_byte (self->pdev, PCI_COMMAND, &command); command &= ~PCI_COMMAND_MASTER; @@ -265,7 +266,7 @@ toshoboe_initbuffs (struct toshoboe_cb *self) int i; unsigned long flags; - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); save_flags (flags); cli (); @@ -287,29 +288,27 @@ toshoboe_initbuffs (struct toshoboe_cb *self) restore_flags (flags); } - - - /*Transmit something */ static int toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) { - struct irda_device *idev; struct toshoboe_cb *self; + __u32 speed; int mtt, len; - idev = (struct irda_device *) dev->priv; - ASSERT (idev != NULL, return 0; - ); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0; - ); + self = (struct toshoboe_cb *) dev->priv; - self = idev->priv; ASSERT (self != NULL, return 0; ); - if (self->stopped) + /* Check if we need to change the speed */ + if ((speed = irda_get_speed(skb)) != self->io.speed) + toshoboe_setbaud (self, speed); + + if (self->stopped) { + dev_kfree_skb(skb); return 0; + } #ifdef ONETASK if (self->txpending) @@ -376,24 +375,18 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev) static void toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) { - struct irda_device *idev = (struct irda_device *) dev_id; - struct toshoboe_cb *self; + struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id; __u8 irqstat; struct sk_buff *skb; - if (idev == NULL) + if (self == NULL) { printk (KERN_WARNING "%s: irq %d for unknown device.\n", driver_name, irq); return; } - self = idev->priv; - - if (!self) - return; - - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); irqstat = inb_p (OBOE_ISR); @@ -409,10 +402,10 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) { self->txpending--; - idev->stats.tx_packets++; + self->stats.tx_packets++; - idev->media_busy = FALSE; - idev->netdev.tbusy = 0; + /* idev->media_busy = FALSE; */ + self->netdev->tbusy = 0; mark_bh (NET_BH); } @@ -441,8 +434,8 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) skb_put (skb, len); memcpy (skb->data, self->recv_bufs[self->rxs], len); - idev->stats.rx_packets++; - skb->dev = &idev->netdev; + self->stats.rx_packets++; + skb->dev = self->netdev; skb->mac.raw = skb->data; skb->protocol = htons (ETH_P_IRDA); } @@ -479,79 +472,18 @@ toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs) { /*FIXME: I think this is a TX or RX error of some sort */ - idev->stats.tx_errors++; - idev->stats.rx_errors++; + self->stats.tx_errors++; + self->stats.rx_errors++; } } - - -/* Change the baud rate */ -static void -toshoboe_change_speed (struct irda_device *idev, __u32 speed) -{ - struct toshoboe_cb *self; - DEBUG (4, __FUNCTION__ "()\n"); - - ASSERT (idev != NULL, return; - ); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return; - ); - - self = idev->priv; - ASSERT (self != NULL, return; - ); - - - idev->io.baudrate = speed; - - if (self->stopped) - return; - - toshoboe_setbaud (self, speed); - -} - - -/* Check all xmit_tasks finished */ -static void -toshoboe_wait_until_sent (struct irda_device *idev) -{ - struct toshoboe_cb *self; - int i; - - DEBUG (4, __FUNCTION__ "()\n"); - - ASSERT (idev != NULL, return; - ); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return; - ); - - self = idev->priv; - ASSERT (self != NULL, return; - ); - - if (self->stopped) - return; - - for (i = 0; i < TX_SLOTS; ++i) - { - while (self->taskfile->xmit[i].control) - { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (MSECS_TO_JIFFIES(60)); - } - } - -} - static int -toshoboe_is_receiving (struct irda_device *idev) +toshoboe_is_receiving (struct toshoboe_cb *self) { - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); /*FIXME Can't tell! */ return (FALSE); @@ -561,7 +493,7 @@ toshoboe_is_receiving (struct irda_device *idev) static int toshoboe_net_init (struct net_device *dev) { - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); /* Setup to be a normal IrDA network device driver */ irda_device_setup (dev); @@ -607,30 +539,22 @@ toshoboe_initptrs (struct toshoboe_cb *self) static int toshoboe_net_open (struct net_device *dev) { - struct irda_device *idev; struct toshoboe_cb *self; - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); ASSERT (dev != NULL, return -1; ); - idev = (struct irda_device *) dev->priv; - - ASSERT (idev != NULL, return 0; - ); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0; - ); + self = (struct toshoboe_cb *) dev->priv; - self = idev->priv; ASSERT (self != NULL, return 0; ); if (self->stopped) return 0; - - if (request_irq (idev->io.irq, toshoboe_interrupt, - SA_SHIRQ | SA_INTERRUPT, idev->name, (void *) idev)) + if (request_irq (self->io.irq, toshoboe_interrupt, + SA_SHIRQ | SA_INTERRUPT, dev->name, (void *) self)) { return -EAGAIN; @@ -641,8 +565,17 @@ toshoboe_net_open (struct net_device *dev) toshoboe_startchip (self); toshoboe_initptrs (self); - irda_device_net_open(dev); - + /* Ready to play! */ + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + /* + * Open new IrLAP layer instance, now that everything should be + * initialized properly + */ + self->irlap = irlap_open(dev, &self->qos); + self->open = 1; MOD_INC_USE_COUNT; @@ -654,30 +587,26 @@ toshoboe_net_open (struct net_device *dev) static int toshoboe_net_close (struct net_device *dev) { - struct irda_device *idev; struct toshoboe_cb *self; - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); ASSERT (dev != NULL, return -1; ); - idev = (struct irda_device *) dev->priv; + self = (struct toshoboe_cb *) dev->priv; - ASSERT (idev != NULL, return 0; - ); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return 0; - ); - - irda_device_net_close(dev); - - self = idev->priv; - - ASSERT (self != NULL, return 0; - ); + /* Stop device */ + dev->tbusy = 1; + dev->start = 0; + + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; self->open = 0; - free_irq (idev->io.irq, (void *) idev); + free_irq (self->io.irq, (void *) self); if (!self->stopped) { @@ -698,19 +627,11 @@ toshoboe_net_close (struct net_device *dev) MODULE_PARM (max_baud, "i"); static int -toshoboe_close (struct irda_device *idev) +toshoboe_close (struct toshoboe_cb *self) { - struct toshoboe_cb *self; int i; - DEBUG (4, __FUNCTION__ "()\n"); - - ASSERT (idev != NULL, return -1; - ); - ASSERT (idev->magic == IRDA_DEVICE_MAGIC, return -1; - ); - - self = idev->priv; + IRDA_DEBUG (4, __FUNCTION__ "()\n"); ASSERT (self != NULL, return -1; ); @@ -721,7 +642,7 @@ toshoboe_close (struct irda_device *idev) toshoboe_disablebm (self); } - release_region (idev->io.iobase, idev->io.io_ext); + release_region (self->io.iobase, self->io.io_ext); for (i = 0; i < TX_SLOTS; ++i) @@ -736,14 +657,17 @@ toshoboe_close (struct irda_device *idev) self->recv_bufs[i] = NULL; } + if (self->netdev) { + /* Remove netdevice */ + rtnl_lock(); + unregister_netdevice(self->netdev); + rtnl_unlock(); + } kfree (self->taskfilebuf); self->taskfilebuf = NULL; self->taskfile = NULL; - - irda_device_close (idev); - return (0); } @@ -756,12 +680,12 @@ static int toshoboe_open (struct pci_dev *pci_dev) { struct toshoboe_cb *self; - struct irda_device *idev; + struct net_device *dev; int i = 0; int ok = 0; + int err; - - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); while (dev_self[i]) i++; @@ -790,21 +714,17 @@ toshoboe_open (struct pci_dev *pci_dev) self->pdev = pci_dev; self->base = pci_dev->resource[0].start; - idev = &self->idev; - - /*Setup idev */ - - idev->io.iobase = self->base; - idev->io.irq = pci_dev->irq; - idev->io.io_ext = CHIP_IO_EXTENT; - idev->io.baudrate = 9600; + self->io.iobase = self->base; + self->io.irq = pci_dev->irq; + self->io.io_ext = CHIP_IO_EXTENT; + self->io.speed = 9600; /* Lock the port that we need */ - i = check_region (idev->io.iobase, idev->io.io_ext); + i = check_region (self->io.iobase, self->io.io_ext); if (i < 0) { - DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", - idev->io.iobase); + IRDA_DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + self->io.iobase); dev_self[i] = NULL; kfree (self); @@ -813,57 +733,39 @@ toshoboe_open (struct pci_dev *pci_dev) } - irda_init_max_qos_capabilies (&idev->qos); - idev->qos.baud_rate.bits = 0; + irda_init_max_qos_capabilies (&self->qos); + self->qos.baud_rate.bits = 0; if (max_baud >= 2400) - idev->qos.baud_rate.bits |= IR_2400; + self->qos.baud_rate.bits |= IR_2400; /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */ if (max_baud >= 9600) - idev->qos.baud_rate.bits |= IR_9600; + self->qos.baud_rate.bits |= IR_9600; if (max_baud >= 19200) - idev->qos.baud_rate.bits |= IR_19200; + self->qos.baud_rate.bits |= IR_19200; if (max_baud >= 115200) - idev->qos.baud_rate.bits |= IR_115200; + self->qos.baud_rate.bits |= IR_115200; #ifdef ENABLE_FAST if (max_baud >= 576000) - idev->qos.baud_rate.bits |= IR_576000; + self->qos.baud_rate.bits |= IR_576000; if (max_baud >= 1152000) - idev->qos.baud_rate.bits |= IR_1152000; + self->qos.baud_rate.bits |= IR_1152000; if (max_baud >= 4000000) - idev->qos.baud_rate.bits |= (IR_4000000 << 8); + self->qos.baud_rate.bits |= (IR_4000000 << 8); #endif - idev->qos.min_turn_time.bits = 0xff; /*FIXME: what does this do? */ + self->qos.min_turn_time.bits = 0xff; /*FIXME: what does this do? */ - irda_qos_bits_to_value (&idev->qos); + irda_qos_bits_to_value (&self->qos); - idev->flags = IFF_SIR | IFF_DMA | IFF_PIO; + self->flags = IFF_SIR | IFF_DMA | IFF_PIO; #ifdef ENABLE_FAST if (max_baud >= 576000) - idev->flags |= IFF_FIR; + self->flags |= IFF_FIR; #endif - /* These aren't much use as we need to have a whole panoply of - * buffers running */ - - idev->rx_buff.flags = 0; - idev->tx_buff.flags = 0; - idev->rx_buff.truesize = 0; - idev->rx_buff.truesize = 0; - - idev->change_speed = toshoboe_change_speed; - idev->wait_until_sent = toshoboe_wait_until_sent; - idev->is_receiving = toshoboe_is_receiving; - - idev->netdev.init = toshoboe_net_init; - idev->netdev.hard_start_xmit = toshoboe_hard_xmit; - idev->netdev.open = toshoboe_net_open; - idev->netdev.stop = toshoboe_net_close; - - /* Now setup the endless buffers we need */ self->txs = 0; @@ -922,9 +824,32 @@ toshoboe_open (struct pci_dev *pci_dev) } - request_region (idev->io.iobase, idev->io.io_ext, driver_name); + request_region (self->io.iobase, self->io.io_ext, driver_name); - irda_device_open (idev, driver_name, self); + if (!(dev = dev_alloc("irda%d", &err))) { + ERROR(__FUNCTION__ "(), dev_alloc() failed!\n"); + return -ENOMEM; + } + /* dev_alloc doesn't clear the struct, so lets do a little hack */ + memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*)); + + dev->priv = (void *) self; + self->netdev = dev; + + MESSAGE("IrDA: Registered device %s\n", dev->name); + + dev->init = toshoboe_net_init; + dev->hard_start_xmit = toshoboe_hard_xmit; + dev->open = toshoboe_net_open; + dev->stop = toshoboe_net_close; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } printk (KERN_WARNING "ToshOboe: Using "); #ifdef ONETASK @@ -969,8 +894,7 @@ toshoboe_gotosleep (struct toshoboe_cb *self) static void toshoboe_wakeup (struct toshoboe_cb *self) { - struct irda_device *idev = &self->idev; - struct net_device *dev = &idev->netdev; + struct net_device *dev = self->netdev; unsigned long flags; if (!self->stopped) @@ -989,12 +913,10 @@ toshoboe_wakeup (struct toshoboe_cb *self) toshoboe_enablebm (self); toshoboe_startchip (self); - toshoboe_setbaud (self, idev->io.baudrate); + toshoboe_setbaud (self, self->io.speed); toshoboe_initptrs (self); - - dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; @@ -1093,12 +1015,12 @@ toshoboe_cleanup (void) { int i; - DEBUG (4, __FUNCTION__ "()\n"); + IRDA_DEBUG (4, __FUNCTION__ "()\n"); for (i = 0; i < 4; i++) { if (dev_self[i]) - toshoboe_close (&(dev_self[i]->idev)); + toshoboe_close (dev_self[i]); } #ifdef CONFIG_APM diff --git a/drivers/net/irda/uircc.c b/drivers/net/irda/uircc.c index 869ccd5d6..2726700bb 100644 --- a/drivers/net/irda/uircc.c +++ b/drivers/net/irda/uircc.c @@ -113,7 +113,7 @@ static void uircc_cleanup(void) { int i; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) @@ -135,7 +135,7 @@ static int uircc_open(int i, unsigned int iobase, unsigned int iobase2, struct irda_device *idev; int ret; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); if ((uircc_probe(iobase, iobase2, irq, dma)) == -1) return -1; @@ -168,14 +168,14 @@ static int uircc_open(int i, unsigned int iobase, unsigned int iobase2, /* Lock the port that we need */ ret = check_region(idev->io.iobase, idev->io.io_ext); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", idev->io.iobase); /* uircc_cleanup( self->idev); */ return -ENODEV; } ret = check_region(idev->io.iobase2, idev->io.io_ext2); if (ret < 0) { - DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", idev->io.iobase2); /* uircc_cleanup( self->idev); */ return -ENODEV; @@ -235,7 +235,7 @@ static int uircc_close(struct irda_device *idev) int iobase; int status; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return -1;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); @@ -252,11 +252,11 @@ static int uircc_close(struct irda_device *idev) irport_stop(idev, idev->io.iobase2); /* Release the PORT that this driver is using */ - DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase); + IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase); release_region(idev->io.iobase, idev->io.io_ext); if (idev->io.iobase2) { - DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase2); release_region(idev->io.iobase2, idev->io.io_ext2); } @@ -278,13 +278,13 @@ static int uircc_probe(int iobase, int iobase2, int irq, int dma) { int version; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* read the chip version, should be 0x03 */ version = inb(iobase+UIRCC_SR8); if (version != 0x03) { - DEBUG(0, __FUNCTION__ "(), Wrong chip version"); + IRDA_DEBUG(0, __FUNCTION__ "(), Wrong chip version"); return -1; } printk(KERN_INFO "Sharp UIRCC IrDA driver loaded. Version: 0x%02x\n", @@ -298,7 +298,7 @@ static int uircc_probe(int iobase, int iobase2, int irq, int dma) outb(0, iobase+UIRCC_CR11); outb(0, iobase+UIRCC_CR9); - DEBUG(0, __FUNCTION__ "(), sr15=%#x\n", inb(iobase+UIRCC_SR15)); + IRDA_DEBUG(0, __FUNCTION__ "(), sr15=%#x\n", inb(iobase+UIRCC_SR15)); /* Enable DMA single mode */ outb(UIRCC_CR1_RX_DMA|UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET, @@ -325,7 +325,7 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) int modem = UIRCC_CR10_SIR; int status; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Just test the high speed stuff */ /*speed = 4000000;*/ @@ -358,11 +358,11 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) break; case 576000: - DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); break; case 1152000: - DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); break; case 4000000: irport_stop(idev, idev->io.iobase2); @@ -371,7 +371,7 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0001); modem = UIRCC_CR10_FIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); /* Set self pole address */ //outb(0xfe, iobase+UIRCC_CR8); @@ -379,7 +379,7 @@ static void uircc_change_speed(struct irda_device *idev, __u32 speed) /* outb(0x10, iobase+UIRCC_CR11); */ break; default: - DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); + IRDA_DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); break; } @@ -419,7 +419,7 @@ static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) iobase = idev->io.iobase; - DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Reset carrier latch */ /*outb(0x02, iobase+UIRCC_CR0);*/ @@ -429,7 +429,7 @@ static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev) return irport_hard_xmit(skb, dev); } - DEBUG(0, __FUNCTION__ "(), sr0=%#x, sr1=%#x, sr2=%#x, sr3=%#x, sr10=%#x, sr11=%#x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), sr0=%#x, sr1=%#x, sr2=%#x, sr3=%#x, sr10=%#x, sr11=%#x\n", inb(iobase+UIRCC_SR0), inb(iobase+UIRCC_SR3), inb(iobase+UIRCC_SR2), inb(iobase+UIRCC_SR3), inb(iobase+UIRCC_SR10), inb(iobase+UIRCC_SR11)); @@ -473,7 +473,7 @@ static void uircc_dma_write(struct irda_device *idev, int iobase) { struct uircc_cb *self; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -519,7 +519,7 @@ static void uircc_dma_xmit_complete( struct irda_device *idev, int underrun) int iobase; int len; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(idev != NULL, return;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); @@ -535,7 +535,7 @@ static void uircc_dma_xmit_complete( struct irda_device *idev, int underrun) len = inb(iobase+UIRCC_SR4); /* Low byte */ len |= inb(iobase+UIRCC_SR5) << 8; /* High byte */ - DEBUG(4, __FUNCTION__ "(), sent %d bytes\n", len); + IRDA_DEBUG(4, __FUNCTION__ "(), sent %d bytes\n", len); /* Disable transmit */ self->cr3 &= ~UIRCC_CR3_XMIT_EN; @@ -576,7 +576,7 @@ static int uircc_dma_receive(struct irda_device *idev) ASSERT(idev != NULL, return -1;); ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); self = idev->priv; iobase= idev->io.iobase; @@ -614,7 +614,7 @@ static int uircc_dma_receive(struct irda_device *idev) self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN); outb(self->cr3, iobase+UIRCC_CR3); #endif - DEBUG(4, __FUNCTION__ "(), cr3=%#x\n", self->cr3); + IRDA_DEBUG(4, __FUNCTION__ "(), cr3=%#x\n", self->cr3); /* Address check? */ @@ -636,11 +636,11 @@ static int uircc_dma_receive_complete(struct irda_device *idev, int iobase) self = idev->priv; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Check for CRC or framing error */ if (inb(iobase+UIRCC_SR0) & UIRCC_SR0_RX_CRCFRM) { - DEBUG(0, __FUNCTION__ "(), CRC or FRAME error\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), CRC or FRAME error\n"); return -1; } @@ -651,7 +651,7 @@ static int uircc_dma_receive_complete(struct irda_device *idev, int iobase) len = inb(iobase+UIRCC_SR4); /* Low byte */ len |= inb(iobase+UIRCC_SR5) << 8; /* High byte */ - DEBUG(0, __FUNCTION__ "(), len=%d\n", len); + IRDA_DEBUG(0, __FUNCTION__ "(), len=%d\n", len); /* Receiving disable */ self->cr3 &= ~UIRCC_CR3_RECV_EN; @@ -716,12 +716,12 @@ static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* Read interrupt status */ sr3 = inb( iobase+UIRCC_SR3); if (!sr3) { - DEBUG(4,"**\n"); + IRDA_DEBUG(4,"**\n"); return; } idev->netdev.interrupt = 1; - DEBUG(4, __FUNCTION__ "(), sr3=%#x, sr2=%#x, sr10=%#x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), sr3=%#x, sr2=%#x, sr10=%#x\n", inb( iobase+UIRCC_SR3), inb( iobase+UIRCC_SR2), inb( iobase+UIRCC_SR10)); @@ -750,7 +750,7 @@ static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs) iobase+UIRCC_CR11); break; default: - DEBUG(0, __FUNCTION__ "(), unknown interrupt status=%#x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), unknown interrupt status=%#x\n", sr3); break; } @@ -800,7 +800,7 @@ static int uircc_is_receiving( struct irda_device *idev) */ static int uircc_net_init( struct net_device *dev) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); /* Setup to be a normal IrDA network device driver */ irda_device_setup(dev); @@ -822,7 +822,7 @@ static int uircc_net_open(struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; @@ -866,7 +866,7 @@ static int uircc_net_close(struct net_device *dev) struct irda_device *idev; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); idev = (struct irda_device *) dev->priv; diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c index 32e965275..422f691ab 100644 --- a/drivers/net/irda/w83977af_ir.c +++ b/drivers/net/irda/w83977af_ir.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Paul VanderSpek * Created at: Wed Nov 4 11:46:16 1998 - * Modified at: Wed Aug 11 09:27:54 1999 + * Modified at: Wed Oct 20 00:08:30 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> @@ -49,6 +49,7 @@ #include <linux/delay.h> #include <linux/malloc.h> #include <linux/init.h> +#include <linux/rtnetlink.h> #include <asm/io.h> #include <asm/dma.h> @@ -83,17 +84,16 @@ static struct w83977af_ir *dev_self[] = { NULL, NULL, NULL, NULL}; /* Some prototypes */ static int w83977af_open(int i, unsigned int iobase, unsigned int irq, unsigned int dma); -static int w83977af_close(struct irda_device *idev); +static int w83977af_close(struct w83977af_ir *self); static int w83977af_probe(int iobase, int irq, int dma); -static int w83977af_dma_receive(struct irda_device *idev); -static int w83977af_dma_receive_complete(struct irda_device *idev); +static int w83977af_dma_receive(struct w83977af_ir *self); +static int w83977af_dma_receive_complete(struct w83977af_ir *self); static int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev); static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size); -static void w83977af_dma_write(struct irda_device *idev, int iobase); -static void w83977af_change_speed(struct irda_device *idev, __u32 speed); +static void w83977af_dma_write(struct w83977af_ir *self, int iobase); +static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed); static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static void w83977af_wait_until_sent(struct irda_device *idev); -static int w83977af_is_receiving(struct irda_device *idev); +static int w83977af_is_receiving(struct w83977af_ir *self); static int w83977af_net_init(struct net_device *dev); static int w83977af_net_open(struct net_device *dev); @@ -109,13 +109,13 @@ int __init w83977af_init(void) { int i; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); for (i=0; (io[i] < 2000) && (i < 4); i++) { int ioaddr = io[i]; if (check_region(ioaddr, CHIP_IO_EXTENT) < 0) continue; - if (w83977af_open( i, io[i], irq[i], dma[i]) == 0) + if (w83977af_open(i, io[i], irq[i], dma[i]) == 0) return 0; } return -ENODEV; @@ -132,11 +132,11 @@ void w83977af_cleanup(void) { int i; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); for (i=0; i < 4; i++) { if (dev_self[i]) - w83977af_close(&(dev_self[i]->idev)); + w83977af_close(dev_self[i]); } } #endif /* MODULE */ @@ -147,14 +147,15 @@ void w83977af_cleanup(void) * Open driver instance * */ -int w83977af_open( int i, unsigned int iobase, unsigned int irq, - unsigned int dma) +int w83977af_open(int i, unsigned int iobase, unsigned int irq, + unsigned int dma) { - struct irda_device *idev; + struct net_device *dev; struct w83977af_ir *self; int ret; + int err; - DEBUG( 0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); if (w83977af_probe(iobase, irq, dma) == -1) return -1; @@ -173,83 +174,107 @@ int w83977af_open( int i, unsigned int iobase, unsigned int irq, /* Need to store self somewhere */ dev_self[i] = self; - idev = &self->idev; - /* Initialize IO */ - idev->io.iobase = iobase; - idev->io.irq = irq; - idev->io.io_ext = CHIP_IO_EXTENT; - idev->io.dma = dma; - idev->io.fifo_size = 32; + self->io.iobase = iobase; + self->io.irq = irq; + self->io.io_ext = CHIP_IO_EXTENT; + self->io.dma = dma; + self->io.fifo_size = 32; /* Lock the port that we need */ - ret = check_region(idev->io.iobase, idev->io.io_ext); + ret = check_region(self->io.iobase, self->io.io_ext); if (ret < 0) { - DEBUG( 0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", - idev->io.iobase); - /* w83977af_cleanup( self->idev); */ + IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n", + self->io.iobase); + /* w83977af_cleanup( self); */ return -ENODEV; } - request_region(idev->io.iobase, idev->io.io_ext, idev->name); + request_region(self->io.iobase, self->io.io_ext, driver_name); /* Initialize QoS for this device */ - irda_init_max_qos_capabilies(&idev->qos); + irda_init_max_qos_capabilies(&self->qos); /* The only value we must override it the baudrate */ /* FIXME: The HP HDLS-1100 does not support 1152000! */ - idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8); /* The HP HDLS-1100 needs 1 ms according to the specs */ - idev->qos.min_turn_time.bits = qos_mtt_bits; - irda_qos_bits_to_value(&idev->qos); + self->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&self->qos); - idev->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO; - - /* Specify which buffer allocation policy we need */ - idev->rx_buff.flags = GFP_KERNEL | GFP_DMA; - idev->tx_buff.flags = GFP_KERNEL | GFP_DMA; + self->flags = IFF_FIR|IFF_MIR|IFF_SIR|IFF_DMA|IFF_PIO; /* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */ - idev->rx_buff.truesize = 14384; - idev->tx_buff.truesize = 4000; + self->rx_buff.truesize = 14384; + self->tx_buff.truesize = 4000; - /* Initialize callbacks */ - idev->change_speed = w83977af_change_speed; - idev->wait_until_sent = w83977af_wait_until_sent; - idev->is_receiving = w83977af_is_receiving; + /* Allocate memory if needed */ + if (self->rx_buff.truesize > 0) { + self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize, + GFP_KERNEL|GFP_DMA); + 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, + GFP_KERNEL|GFP_DMA); + if (self->tx_buff.head == NULL) { + kfree(self->rx_buff.head); + return -ENOMEM; + } + memset(self->tx_buff.head, 0, self->tx_buff.truesize); + } + + self->rx_buff.in_frame = FALSE; + self->rx_buff.state = OUTSIDE_FRAME; + self->tx_buff.data = self->tx_buff.head; + self->rx_buff.data = self->rx_buff.head; + + if (!(dev = dev_alloc("irda%d", &err))) { + ERROR(__FUNCTION__ "(), dev_alloc() failed!\n"); + return -ENOMEM; + } + /* dev_alloc doesn't clear the struct, so lets do a little hack */ + memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*)); + + dev->priv = (void *) self; + self->netdev = dev; /* Override the network functions we need to use */ - idev->netdev.init = w83977af_net_init; - idev->netdev.hard_start_xmit = w83977af_hard_xmit; - idev->netdev.open = w83977af_net_open; - idev->netdev.stop = w83977af_net_close; + dev->init = w83977af_net_init; + dev->hard_start_xmit = w83977af_hard_xmit; + dev->open = w83977af_net_open; + dev->stop = w83977af_net_close; + + rtnl_lock(); + err = register_netdev(dev); + rtnl_unlock(); + if (err) { + ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); + return -1; + } - /* Open the IrDA device */ - irda_device_open(idev, driver_name, self); + MESSAGE("IrDA: Registered device %s\n", dev->name); return 0; } /* - * Function w83977af_close (idev) + * Function w83977af_close (self) * * Close driver instance * */ -static int w83977af_close( struct irda_device *idev) +static int w83977af_close(struct w83977af_ir *self) { - struct w83977af_ir *self; int iobase; - DEBUG(0, __FUNCTION__ "()\n"); - - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); - iobase = idev->io.iobase; - self = (struct w83977af_ir *) idev->priv; + iobase = self->io.iobase; #ifdef CONFIG_USE_W977_PNP /* enter PnP configuration mode */ @@ -262,12 +287,24 @@ static int w83977af_close( struct irda_device *idev) w977_efm_exit(); #endif /* CONFIG_USE_W977_PNP */ + + /* Remove netdevice */ + if (self->netdev) { + rtnl_lock(); + unregister_netdev(self->netdev); + rtnl_unlock(); + } + /* Release the PORT that this driver is using */ - DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", - idev->io.iobase); - release_region(idev->io.iobase, idev->io.io_ext); + IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", + self->io.iobase); + release_region(self->io.iobase, self->io.io_ext); - irda_device_close(idev); + if (self->tx_buff.head) + kfree(self->tx_buff.head); + + if (self->rx_buff.head) + kfree(self->rx_buff.head); kfree(self); @@ -284,7 +321,7 @@ int w83977af_probe( int iobase, int irq, int dma) { int version; - DEBUG( 0, __FUNCTION__ "()\n"); + IRDA_DEBUG( 0, __FUNCTION__ "()\n"); #ifdef CONFIG_USE_W977_PNP /* Enter PnP configuration mode */ w977_efm_enter(); @@ -333,7 +370,7 @@ int w83977af_probe( int iobase, int irq, int dma) /* Should be 0x1? */ if (0x10 != (version & 0xf0)) { - DEBUG( 0, __FUNCTION__ "(), Wrong chip version"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Wrong chip version"); return -1; } @@ -365,30 +402,21 @@ int w83977af_probe( int iobase, int irq, int dma) switch_bank(iobase, SET7); outb(0x40, iobase+7); - DEBUG(0, "W83977AF (IR) driver loaded. Version: 0x%02x\n", version); + IRDA_DEBUG(0, "W83977AF (IR) driver loaded. Version: 0x%02x\n", version); return 0; } -/* - * Function w83977af_change_speed (idev, baud) - * - * Change the speed of the device - * - */ -void w83977af_change_speed(struct irda_device *idev, __u32 speed) +void w83977af_change_speed(struct w83977af_ir *self, __u32 speed) { int ir_mode = HCR_SIR; int iobase; __u8 set; - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); - - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Update accounting for new speed */ - idev->io.baudrate = speed; + self->io.speed = speed; /* Save current bank */ set = inb(iobase+SSR); @@ -409,19 +437,19 @@ void w83977af_change_speed(struct irda_device *idev, __u32 speed) case 115200: outb(0x01, iobase+ABLL); break; case 576000: ir_mode = HCR_MIR_576; - DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n"); break; case 1152000: ir_mode = HCR_MIR_1152; - DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n"); break; case 4000000: ir_mode = HCR_FIR; - DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n"); break; default: ir_mode = HCR_FIR; - DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); + IRDA_DEBUG(0, __FUNCTION__ "(), unknown baud rate of %d\n", speed); break; } @@ -440,13 +468,13 @@ void w83977af_change_speed(struct irda_device *idev, __u32 speed) outb(UFR_EN_FIFO, iobase+UFR); /* First we must enable FIFO */ outb(0xa7, iobase+UFR); - idev->netdev.tbusy = 0; + self->netdev->tbusy = 0; /* Enable some interrupts so we can receive frames */ switch_bank(iobase, SET0); if (speed > PIO_MAX_SPEED) { outb(ICR_EFSFI, iobase+ICR); - w83977af_dma_receive(idev); + w83977af_dma_receive(self); } else outb(ICR_ERBRI, iobase+ICR); @@ -462,32 +490,34 @@ void w83977af_change_speed(struct irda_device *idev, __u32 speed) */ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) { - struct irda_device *idev; + struct w83977af_ir *self; + __u32 speed; int iobase; __u8 set; int mtt; - idev = (struct irda_device *) dev->priv; + self = (struct w83977af_ir *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + iobase = self->io.iobase; - iobase = idev->io.iobase; - - DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); + IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len); /* Lock transmit buffer */ if (irda_lock((void *) &dev->tbusy) == FALSE) return -EBUSY; + /* Check if we need to change the speed */ + if ((speed = irda_get_speed(skb)) != self->io.speed) + w83977af_change_speed(self, speed); + /* Save current set */ set = inb(iobase+SSR); /* Decide if we should use PIO or DMA transfer */ - if (idev->io.baudrate > PIO_MAX_SPEED) { - idev->tx_buff.data = idev->tx_buff.head; - memcpy(idev->tx_buff.data, skb->data, skb->len); - idev->tx_buff.len = skb->len; + if (self->io.speed > PIO_MAX_SPEED) { + self->tx_buff.data = self->tx_buff.head; + memcpy(self->tx_buff.data, skb->data, skb->len); + self->tx_buff.len = skb->len; mtt = irda_get_mtt(skb); #ifdef CONFIG_USE_INTERNAL_TIMER @@ -502,28 +532,28 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) /* Start timer */ outb(IR_MSL_EN_TMR, iobase+IR_MSL); - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Enable timer interrupt */ switch_bank(iobase, SET0); outb(ICR_ETMRI, iobase+ICR); } else { #endif - DEBUG(4,__FUNCTION__ "(%ld), mtt=%d\n", jiffies, mtt); + IRDA_DEBUG(4,__FUNCTION__ "(%ld), mtt=%d\n", jiffies, mtt); if (mtt) udelay(mtt); /* Enable DMA interrupt */ switch_bank(iobase, SET0); outb(ICR_EDMAI, iobase+ICR); - w83977af_dma_write(idev, iobase); + w83977af_dma_write(self, iobase); #ifdef CONFIG_USE_INTERNAL_TIMER } #endif } else { - idev->tx_buff.data = idev->tx_buff.head; - idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, - idev->tx_buff.truesize); + self->tx_buff.data = self->tx_buff.head; + self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, + self->tx_buff.truesize); /* Add interrupt on tx low level (will fire immediately) */ switch_bank(iobase, SET0); @@ -538,19 +568,19 @@ int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev) } /* - * Function w83977af_dma_write (idev, iobase) + * Function w83977af_dma_write (self, iobase) * * Send frame using DMA * */ -static void w83977af_dma_write(struct irda_device *idev, int iobase) +static void w83977af_dma_write(struct w83977af_ir *self, int iobase) { __u8 set; #ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS unsigned long flags; __u8 hcr; #endif - DEBUG(4, __FUNCTION__ "(), len=%d\n", idev->tx_buff.len); + IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", self->tx_buff.len); /* Save current set */ set = inb(iobase+SSR); @@ -566,23 +596,23 @@ static void w83977af_dma_write(struct irda_device *idev, int iobase) save_flags(flags); cli(); - disable_dma(idev->io.dma); - clear_dma_ff(idev->io.dma); - set_dma_mode(idev->io.dma, DMA_MODE_READ); - set_dma_addr(idev->io.dma, virt_to_bus(idev->tx_buff.data)); - set_dma_count(idev->io.dma, idev->tx_buff.len); + disable_dma(self->io.dma); + clear_dma_ff(self->io.dma); + set_dma_mode(self->io.dma, DMA_MODE_READ); + set_dma_addr(self->io.dma, virt_to_bus(self->tx_buff.data)); + set_dma_count(self->io.dma, self->tx_buff.len); #else - setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, + setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, DMA_MODE_WRITE); #endif - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Enable DMA */ switch_bank(iobase, SET0); #ifdef CONFIG_NETWINDER_TX_DMA_PROBLEMS hcr = inb(iobase+HCR); outb(hcr | HCR_EN_DMA, iobase+HCR); - enable_dma(idev->io.dma); + enable_dma(self->io.dma); restore_flags(flags); #else outb(inb(iobase+HCR) | HCR_EN_DMA | HCR_TX_WT, iobase+HCR); @@ -603,17 +633,17 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) int actual = 0; __u8 set; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Save current bank */ set = inb(iobase+SSR); switch_bank(iobase, SET0); if (!(inb_p(iobase+USR) & USR_TSRE)) { - DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), warning, FIFO not empty yet!\n"); fifo_size -= 17; - DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); + IRDA_DEBUG(4, __FUNCTION__ "%d bytes left in tx fifo\n", fifo_size); } /* Fill FIFO with current frame */ @@ -622,7 +652,7 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) outb(buf[actual++], iobase+TBR); } - DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", + IRDA_DEBUG(4, __FUNCTION__ "(), fifo_size %d ; %d sent of %d\n", fifo_size, actual, len); /* Restore bank */ @@ -632,23 +662,22 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size) } /* - * Function w83977af_dma_xmit_complete (idev) + * Function w83977af_dma_xmit_complete (self) * * The transfer of a frame in finished. So do the necessary things * * */ -void w83977af_dma_xmit_complete(struct irda_device *idev) +void w83977af_dma_xmit_complete(struct w83977af_ir *self) { int iobase; __u8 set; - DEBUG(4, __FUNCTION__ "(%ld)\n", jiffies); + IRDA_DEBUG(4, __FUNCTION__ "(%ld)\n", jiffies); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current set */ set = inb(iobase+SSR); @@ -659,19 +688,18 @@ void w83977af_dma_xmit_complete(struct irda_device *idev) /* Check for underrrun! */ if (inb(iobase+AUDR) & AUDR_UNDR) { - DEBUG(0, __FUNCTION__ "(), Transmit underrun!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Transmit underrun!\n"); - idev->stats.tx_errors++; - idev->stats.tx_fifo_errors++; + self->stats.tx_errors++; + self->stats.tx_fifo_errors++; /* Clear bit, by writing 1 to it */ outb(AUDR_UNDR, iobase+AUDR); } else - idev->stats.tx_packets++; + self->stats.tx_packets++; /* Unlock tx_buff and request another frame */ - idev->netdev.tbusy = 0; /* Unlock */ - idev->media_busy = FALSE; + self->netdev->tbusy = 0; /* Unlock */ /* Tell the network layer, that we want more frames */ mark_bh(NET_BH); @@ -681,15 +709,14 @@ void w83977af_dma_xmit_complete(struct irda_device *idev) } /* - * Function w83977af_dma_receive (idev) + * Function w83977af_dma_receive (self) * * Get ready for receiving a frame. The device will initiate a DMA * if it starts to receive a frame. * */ -int w83977af_dma_receive(struct irda_device *idev) +int w83977af_dma_receive(struct w83977af_ir *self) { - struct w83977af_ir *self; int iobase; __u8 set; #ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS @@ -697,13 +724,11 @@ int w83977af_dma_receive(struct irda_device *idev) __u8 hcr; #endif - ASSERT(idev != NULL, return -1;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;); + ASSERT(self != NULL, return -1;); - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); - self = idev->priv; - iobase= idev->io.iobase; + iobase= self->io.iobase; /* Save current set */ set = inb(iobase+SSR); @@ -717,20 +742,20 @@ int w83977af_dma_receive(struct irda_device *idev) outb((inb(iobase+ADCR1) & ~ADCR1_D_CHSW)/*|ADCR1_DMA_F*/|ADCR1_ADV_SL, iobase+ADCR1); - idev->io.direction = IO_RECV; - idev->rx_buff.data = idev->rx_buff.head; + self->io.direction = IO_RECV; + self->rx_buff.data = self->rx_buff.head; #ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS save_flags(flags); cli(); - disable_dma(idev->io.dma); - clear_dma_ff(idev->io.dma); - set_dma_mode(idev->io.dma, DMA_MODE_READ); - set_dma_addr(idev->io.dma, virt_to_bus(idev->rx_buff.data)); - set_dma_count(idev->io.dma, idev->rx_buff.truesize); + disable_dma(self->io.dma); + clear_dma_ff(self->io.dma); + set_dma_mode(self->io.dma, DMA_MODE_READ); + set_dma_addr(self->io.dma, virt_to_bus(self->rx_buff.data)); + set_dma_count(self->io.dma, self->rx_buff.truesize); #else - setup_dma(idev->io.dma, idev->rx_buff.data, idev->rx_buff.truesize, + setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, DMA_MODE_READ); #endif /* @@ -747,7 +772,7 @@ int w83977af_dma_receive(struct irda_device *idev) #ifdef CONFIG_NETWINDER_RX_DMA_PROBLEMS hcr = inb(iobase+HCR); outb(hcr | HCR_EN_DMA, iobase+HCR); - enable_dma(idev->io.dma); + enable_dma(self->io.dma); restore_flags(flags); #else outb(inb(iobase+HCR) | HCR_EN_DMA, iobase+HCR); @@ -759,32 +784,30 @@ int w83977af_dma_receive(struct irda_device *idev) } /* - * Function w83977af_receive_complete (idev) + * Function w83977af_receive_complete (self) * * Finished with receiving a frame * */ -int w83977af_dma_receive_complete(struct irda_device *idev) +int w83977af_dma_receive_complete(struct w83977af_ir *self) { struct sk_buff *skb; - struct w83977af_ir *self; struct st_fifo *st_fifo; int len; int iobase; __u8 set; __u8 status; - DEBUG(4, __FUNCTION__ "\n"); + IRDA_DEBUG(4, __FUNCTION__ "\n"); - self = idev->priv; st_fifo = &self->st_fifo; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current set */ set = inb(iobase+SSR); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Read status FIFO */ switch_bank(iobase, SET5); @@ -809,28 +832,28 @@ int w83977af_dma_receive_complete(struct irda_device *idev) if (status & FS_FO_ERR_MSK) { if (status & FS_FO_LST_FR) { /* Add number of lost frames to stats */ - idev->stats.rx_errors += len; + self->stats.rx_errors += len; } else { /* Skip frame */ - idev->stats.rx_errors++; + self->stats.rx_errors++; - idev->rx_buff.data += len; + self->rx_buff.data += len; if (status & FS_FO_MX_LEX) - idev->stats.rx_length_errors++; + self->stats.rx_length_errors++; if (status & FS_FO_PHY_ERR) - idev->stats.rx_frame_errors++; + self->stats.rx_frame_errors++; if (status & FS_FO_CRC_ERR) - idev->stats.rx_crc_errors++; + self->stats.rx_crc_errors++; } /* The errors below can be reported in both cases */ if (status & FS_FO_RX_OV) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; if (status & FS_FO_FSF_OV) - idev->stats.rx_fifo_errors++; + self->stats.rx_fifo_errors++; } else { /* Check if we have transfered all data to memory */ @@ -866,19 +889,19 @@ int w83977af_dma_receive_complete(struct irda_device *idev) skb_reserve(skb, 1); /* Copy frame without CRC */ - if (idev->io.baudrate < 4000000) { + if (self->io.speed < 4000000) { skb_put(skb, len-2); - memcpy(skb->data, idev->rx_buff.data, len-2); + memcpy(skb->data, self->rx_buff.data, len-2); } else { skb_put(skb, len-4); - memcpy(skb->data, idev->rx_buff.data, len-4); + memcpy(skb->data, self->rx_buff.data, len-4); } /* Move to next frame */ - idev->rx_buff.data += len; - idev->stats.rx_packets++; + self->rx_buff.data += len; + self->stats.rx_packets++; - skb->dev = &idev->netdev; + skb->dev = self->netdev; skb->mac.raw = skb->data; skb->protocol = htons(ETH_P_IRDA); netif_rx(skb); @@ -891,61 +914,60 @@ int w83977af_dma_receive_complete(struct irda_device *idev) } /* - * Function pc87108_pio_receive (idev) + * Function pc87108_pio_receive (self) * * Receive all data in receiver FIFO * */ -static void w83977af_pio_receive(struct irda_device *idev) +static void w83977af_pio_receive(struct w83977af_ir *self) { __u8 byte = 0x00; int iobase; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(idev != NULL, return;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(self != NULL, return;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Receive all characters in Rx FIFO */ do { byte = inb(iobase+RBR); - async_unwrap_char(idev, byte); + async_unwrap_char(self->netdev, &self->rx_buff, byte); } while (inb(iobase+USR) & USR_RDR); /* Data available */ } /* - * Function w83977af_sir_interrupt (idev, eir) + * Function w83977af_sir_interrupt (self, eir) * * Handle SIR interrupt * */ -static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) +static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr) { int actual; __u8 new_icr = 0; __u8 set; int iobase; - DEBUG(4, __FUNCTION__ "(), isr=%#x\n", isr); + IRDA_DEBUG(4, __FUNCTION__ "(), isr=%#x\n", isr); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Transmit FIFO low on data */ if (isr & ISR_TXTH_I) { /* Write data left in transmit buffer */ - actual = w83977af_pio_write(idev->io.iobase, - idev->tx_buff.data, - idev->tx_buff.len, - idev->io.fifo_size); + actual = w83977af_pio_write(self->io.iobase, + self->tx_buff.data, + self->tx_buff.len, + self->io.fifo_size); - idev->tx_buff.data += actual; - idev->tx_buff.len -= actual; + self->tx_buff.data += actual; + self->tx_buff.len -= actual; - idev->io.direction = IO_XMIT; + self->io.direction = IO_XMIT; /* Check if finished */ - if (idev->tx_buff.len > 0) { + if (self->tx_buff.len > 0) { new_icr |= ICR_ETXTHI; } else { set = inb(iobase+SSR); @@ -953,8 +975,8 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) outb(AUDR_SFEND, iobase+AUDR); outb(set, iobase+SSR); - idev->netdev.tbusy = 0; /* Unlock */ - idev->stats.tx_packets++; + self->netdev->tbusy = 0; /* Unlock */ + self->stats.tx_packets++; /* Schedule network layer */ mark_bh(NET_BH); @@ -966,13 +988,13 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) if (isr & ISR_TXEMP_I) { /* Turn around and get ready to receive some data */ - idev->io.direction = IO_RECV; + self->io.direction = IO_RECV; new_icr |= ICR_ERBRI; } /* Rx FIFO threshold or timeout */ if (isr & ISR_RXTH_I) { - w83977af_pio_receive(idev); + w83977af_pio_receive(self); /* Keep receiving */ new_icr |= ICR_ERBRI; @@ -981,23 +1003,23 @@ static __u8 w83977af_sir_interrupt(struct irda_device *idev, int isr) } /* - * Function pc87108_fir_interrupt (idev, eir) + * Function pc87108_fir_interrupt (self, eir) * * Handle MIR/FIR interrupt * */ -static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr) +static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr) { __u8 new_icr = 0; __u8 set; int iobase; - iobase = idev->io.iobase; + iobase = self->io.iobase; set = inb(iobase+SSR); /* End of frame detected in FIFO */ if (isr & (ISR_FEND_I|ISR_FSF_I)) { - if (w83977af_dma_receive_complete(idev)) { + if (w83977af_dma_receive_complete(self)) { /* Wait for next status FIFO interrupt */ new_icr |= ICR_EFSFI; @@ -1026,29 +1048,29 @@ static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr) /* outb(ASCR_CTE, iobase+ASCR); */ /* Check if this is a TX timer interrupt */ - if (idev->io.direction == IO_XMIT) { - w83977af_dma_write(idev, iobase); + if (self->io.direction == IO_XMIT) { + w83977af_dma_write(self, iobase); new_icr |= ICR_EDMAI; } else { /* Check if DMA has now finished */ - w83977af_dma_receive_complete(idev); + w83977af_dma_receive_complete(self); new_icr |= ICR_EFSFI; } } /* Finished with DMA */ if (isr & ISR_DMA_I) { - w83977af_dma_xmit_complete(idev); + w83977af_dma_xmit_complete(self); /* Check if there are more frames to be transmitted */ - /* if (irda_device_txqueue_empty(idev)) { */ + /* if (irda_device_txqueue_empty(self)) { */ /* Prepare for receive * * ** Netwinder Tx DMA likes that we do this anyway ** */ - w83977af_dma_receive(idev); + w83977af_dma_receive(self); new_icr = ICR_EFSFI; /* } */ } @@ -1067,20 +1089,21 @@ static __u8 w83977af_fir_interrupt(struct irda_device *idev, int isr) */ static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs) { + struct net_device *dev = (struct net_device *) dev_id; + struct w83977af_ir *self; __u8 set, icr, isr; int iobase; - struct irda_device *idev = (struct irda_device *) dev_id; - - if (idev == NULL) { + if (!dev) { printk(KERN_WARNING "%s: irq %d for unknown device.\n", driver_name, irq); return; } + self = (struct w83977af_ir *) dev->priv; - idev->netdev.interrupt = 1; + dev->interrupt = 1; - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Save current bank */ set = inb(iobase+SSR); @@ -1093,47 +1116,34 @@ static void w83977af_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (isr) { /* Dispatch interrupt handler for the current speed */ - if (idev->io.baudrate > PIO_MAX_SPEED ) - icr = w83977af_fir_interrupt(idev, isr); + if (self->io.speed > PIO_MAX_SPEED ) + icr = w83977af_fir_interrupt(self, isr); else - icr = w83977af_sir_interrupt(idev, isr); + icr = w83977af_sir_interrupt(self, isr); } outb(icr, iobase+ICR); /* Restore (new) interrupts */ outb(set, iobase+SSR); /* Restore bank register */ - idev->netdev.interrupt = 0; + self->netdev->interrupt = 0; } /* - * Function w83977af_wait_until_sent (idev) - * - * This function should put the current thread to sleep until all data - * have been sent, so it is safe to f.eks. change the speed. - */ -static void w83977af_wait_until_sent(struct irda_device *idev) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(60*HZ/1000); -} - -/* - * Function w83977af_is_receiving (idev) + * Function w83977af_is_receiving (self) * * Return TRUE is we are currently receiving a frame * */ -static int w83977af_is_receiving(struct irda_device *idev) +static int w83977af_is_receiving(struct w83977af_ir *self) { int status = FALSE; int iobase; __u8 set; - ASSERT(idev != NULL, return FALSE;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return FALSE;); + ASSERT(self != NULL, return FALSE;); - if (idev->io.baudrate > 115200) { - iobase = idev->io.iobase; + if (self->io.speed > 115200) { + iobase = self->io.iobase; /* Check if rx FIFO is not empty */ set = inb(iobase+SSR); @@ -1144,7 +1154,7 @@ static int w83977af_is_receiving(struct irda_device *idev) } outb(set, iobase+SSR); } else - status = (idev->rx_buff.state != OUTSIDE_FRAME); + status = (self->rx_buff.state != OUTSIDE_FRAME); return status; } @@ -1157,7 +1167,7 @@ static int w83977af_is_receiving(struct irda_device *idev) */ static int w83977af_net_init(struct net_device *dev) { - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); /* Set up to be a normal IrDA network device driver */ irda_device_setup(dev); @@ -1176,30 +1186,29 @@ static int w83977af_net_init(struct net_device *dev) */ static int w83977af_net_open(struct net_device *dev) { - struct irda_device *idev; + struct w83977af_ir *self; int iobase; __u8 set; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct w83977af_ir *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; - if (request_irq(idev->io.irq, w83977af_interrupt, 0, idev->name, - (void *) idev)) { + if (request_irq(self->io.irq, w83977af_interrupt, 0, dev->name, + (void *) dev)) { return -EAGAIN; } /* * Always allocate the DMA channel after the IRQ, * and clean up on failure. */ - if (request_dma(idev->io.dma, idev->name)) { - free_irq(idev->io.irq, idev); + if (request_dma(self->io.dma, dev->name)) { + free_irq(self->io.irq, self); return -EAGAIN; } @@ -1208,9 +1217,9 @@ static int w83977af_net_open(struct net_device *dev) /* Enable some interrupts so we can receive frames again */ switch_bank(iobase, SET0); - if (idev->io.baudrate > 115200) { + if (self->io.speed > 115200) { outb(ICR_EFSFI, iobase+ICR); - w83977af_dma_receive(idev); + w83977af_dma_receive(self); } else outb(ICR_ERBRI, iobase+ICR); @@ -1218,7 +1227,15 @@ static int w83977af_net_open(struct net_device *dev) outb(set, iobase+SSR); /* Ready to play! */ - irda_device_net_open(dev); + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + /* + * Open new IrLAP layer instance, now that everything should be + * initialized properly + */ + self->irlap = irlap_open(dev, &self->qos); MOD_INC_USE_COUNT; @@ -1233,25 +1250,30 @@ static int w83977af_net_open(struct net_device *dev) */ static int w83977af_net_close(struct net_device *dev) { - struct irda_device *idev; + struct w83977af_ir *self; int iobase; __u8 set; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); ASSERT(dev != NULL, return -1;); - idev = (struct irda_device *) dev->priv; + self = (struct w83977af_ir *) dev->priv; - ASSERT(idev != NULL, return 0;); - ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;); + ASSERT(self != NULL, return 0;); - iobase = idev->io.iobase; + iobase = self->io.iobase; /* Stop device */ - irda_device_net_close(dev); + dev->tbusy = 1; + dev->start = 0; + + /* Stop and remove instance of IrLAP */ + if (self->irlap) + irlap_close(self->irlap); + self->irlap = NULL; - disable_dma(idev->io.dma); + disable_dma(self->io.dma); /* Save current set */ set = inb(iobase+SSR); @@ -1260,8 +1282,8 @@ static int w83977af_net_close(struct net_device *dev) switch_bank(iobase, SET0); outb(0, iobase+ICR); - free_irq(idev->io.irq, idev); - free_dma(idev->io.dma); + free_irq(self->io.irq, self); + free_dma(self->io.dma); /* Restore bank register */ outb(set, iobase+SSR); diff --git a/drivers/net/pcmcia/ray_cs.c b/drivers/net/pcmcia/ray_cs.c index 81bba9e60..5594f51d1 100644 --- a/drivers/net/pcmcia/ray_cs.c +++ b/drivers/net/pcmcia/ray_cs.c @@ -38,6 +38,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> +#include <linux/if_arp.h> #include <linux/ioport.h> #include <linux/skbuff.h> @@ -49,6 +50,19 @@ #include <pcmcia/ds.h> #include <pcmcia/mem_op.h> +#ifdef HAS_WIRELESS_EXTENSIONS +#include <linux/wireless.h> +#if WIRELESS_EXT < 8 +#warning "Wireless extension v8 or newer required" +#endif /* WIRELESS_EXT < 8 */ +/* Warning : these stuff will slow down the driver... */ +#define WIRELESS_SPY /* Enable spying addresses */ +/* Definitions we need for spy */ +typedef struct iw_statistics iw_stats; +typedef struct iw_quality iw_qual; +typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ +#endif /* HAS_WIRELESS_EXTENSIONS */ + #include "rayctl.h" #include "ray_cs.h" @@ -72,67 +86,68 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) #endif /** Prototypes based on PCMCIA skeleton driver *******************************/ -void ray_config(dev_link_t *link); -void ray_release(u_long arg); -int ray_event(event_t event, int priority, event_callback_args_t *args); -dev_link_t *ray_attach(void); -void ray_detach(dev_link_t *); +static void ray_config(dev_link_t *link); +static void ray_release(u_long arg); +static int ray_event(event_t event, int priority, event_callback_args_t *args); +static dev_link_t *ray_attach(void); +static void ray_detach(dev_link_t *); /***** Prototypes indicated by device structure ******************************/ -int ray_dev_close(struct net_device *dev); -int ray_dev_config(struct net_device *dev, struct ifmap *map); -struct enet_statistics *ray_get_stats(struct net_device *dev); -int ray_dev_init(struct net_device *dev); -int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -int ray_open(struct net_device *dev); -int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int ray_dev_close(struct net_device *dev); +static int ray_dev_config(struct net_device *dev, struct ifmap *map); +static struct enet_statistics *ray_get_stats(struct net_device *dev); +static int ray_dev_init(struct net_device *dev); +static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int ray_open(struct net_device *dev); +static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void ray_update_multi_list(struct net_device *dev, int all); -int encapsulate_frame(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, - unsigned char *data, int len); -int translate_frame(ray_dev_t *local, struct tx_msg *ptx, +static int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data, int len); -void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, +static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, unsigned char *data); -void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); +static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); +#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ +static iw_stats * ray_get_wireless_stats(struct device * dev); +#endif /* WIRELESS_EXT > 7 */ /***** Prototypes for raylink functions **************************************/ -int asc_to_int(char a); -void authenticate(ray_dev_t *local); -int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type); -void authenticate_timeout(u_long); -int get_free_ccs(ray_dev_t *local); -int get_free_tx_ccs(ray_dev_t *local); -void init_startup_params(ray_dev_t *local); -int parse_addr(char *in_str, UCHAR *out); -int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type); -int ray_init(struct net_device *dev); -int interrupt_ecf(ray_dev_t *local, int ccs); -void ray_reset(struct net_device *dev); -void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len); -void verify_dl_startup(u_long); +static int asc_to_int(char a); +static void authenticate(ray_dev_t *local); +static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type); +static void authenticate_timeout(u_long); +static int get_free_ccs(ray_dev_t *local); +static int get_free_tx_ccs(ray_dev_t *local); +static void init_startup_params(ray_dev_t *local); +static int parse_addr(char *in_str, UCHAR *out); +static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type); +static int ray_init(struct net_device *dev); +static int interrupt_ecf(ray_dev_t *local, int ccs); +static void ray_reset(struct net_device *dev); +static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len); +static void verify_dl_startup(u_long); /* Prototypes for interrpt time functions **********************************/ -void ray_interrupt(int reg, void *dev_id, struct pt_regs *regs); -void clear_interrupt(ray_dev_t *local); -void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, +static void ray_interrupt (int reg, void *dev_id, struct pt_regs *regs); +static void clear_interrupt(ray_dev_t *local); +static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, unsigned int pkt_addr, int rx_len); -int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len); -void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs); -void release_frag_chain(ray_dev_t *local, struct rcs *prcs); -void rx_authenticate(ray_dev_t *local, struct rcs *prcs, +static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len); +static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs); +static void release_frag_chain(ray_dev_t *local, struct rcs *prcs); +static void rx_authenticate(ray_dev_t *local, struct rcs *prcs, unsigned int pkt_addr, int rx_len); -void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, +static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, int rx_len); -void associate(ray_dev_t *local); +static void associate(ray_dev_t *local); /* Card command functions */ -int dl_startup_params(struct net_device *dev); -void join_net(u_long local); -void start_net(u_long local); +static int dl_startup_params(struct net_device *dev); +static void join_net(u_long local); +static void start_net(u_long local); /* void start_net(ray_dev_t *local); */ -int ray_cs_proc_read(char *buf, char **start, off_t off, int len, int spare); +static int ray_cs_proc_read(char *buf, char **start, off_t off, int len, int spare); /* Create symbol table for registering with kernel in init_module */ EXPORT_SYMBOL(ray_dev_ioctl); EXPORT_SYMBOL(ray_rx); @@ -283,6 +298,14 @@ static UCHAR b4_default_startup_parms[] = { /*===========================================================================*/ static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0}; +static char hop_pattern_length[] = { 1, + USA_HOP_MOD, EUROPE_HOP_MOD, + JAPAN_HOP_MOD, KOREA_HOP_MOD, + SPAIN_HOP_MOD, FRANCE_HOP_MOD, + ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD, + JAPAN_TEST_HOP_MOD +}; + static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>"; #ifdef CONFIG_PROC_FS @@ -298,7 +321,7 @@ struct proc_dir_entry ray_cs_proc_entry = { }; #endif /*===========================================================================*/ -void cs_error(client_handle_t handle, int func, int ret) +static void cs_error(client_handle_t handle, int func, int ret) { error_info_t err = { func, ret }; CardServices(ReportError, handle, &err); @@ -311,7 +334,7 @@ void cs_error(client_handle_t handle, int func, int ret) configure the card at this point -- we wait until we receive a card insertion event. =============================================================================*/ -dev_link_t *ray_attach(void) +static dev_link_t *ray_attach(void) { client_reg_t client_reg; dev_link_t *link; @@ -367,6 +390,9 @@ dev_link_t *ray_attach(void) dev->set_config = &ray_dev_config; dev->get_stats = &ray_get_stats; dev->do_ioctl = &ray_dev_ioctl; +#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ + dev->get_wireless_stats = ray_get_wireless_stats; +#endif dev->set_multicast_list = &set_multicast_list; @@ -411,7 +437,7 @@ dev_link_t *ray_attach(void) structures are freed. Otherwise, the structures will be freed when the device is released. =============================================================================*/ -void ray_detach(dev_link_t *link) +static void ray_detach(dev_link_t *link) { dev_link_t **linkp; struct net_device *dev; @@ -470,7 +496,7 @@ void ray_detach(dev_link_t *link) #define CS_CHECK(fn, args...) \ while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed #define MAX_TUPLE_SIZE 128 -void ray_config(dev_link_t *link) +static void ray_config(dev_link_t *link) { client_handle_t handle = link->handle; tuple_t tuple; @@ -585,7 +611,7 @@ cs_failed: ray_release((u_long)link); } /* ray_config */ /*===========================================================================*/ -int ray_init(struct net_device *dev) +static int ray_init(struct net_device *dev) { int i; UCHAR *p; @@ -648,7 +674,7 @@ int ray_init(struct net_device *dev) } /* ray_init */ /*===========================================================================*/ /* Download startup parameters to the card and command it to read them */ -int dl_startup_params(struct net_device *dev) +static int dl_startup_params(struct net_device *dev) { int ccsindex; ray_dev_t *local = (ray_dev_t *)dev->priv; @@ -694,16 +720,9 @@ int dl_startup_params(struct net_device *dev) return 0; } /* dl_startup_params */ /*===========================================================================*/ -void init_startup_params(ray_dev_t *local) +static void init_startup_params(ray_dev_t *local) { int i; - static char hop_pattern_length[] = { 1, - USA_HOP_MOD, EUROPE_HOP_MOD, - JAPAN_HOP_MOD, KOREA_HOP_MOD, - SPAIN_HOP_MOD, FRANCE_HOP_MOD, - ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD, - JAPAN_TEST_HOP_MOD - }; if (country > JAPAN_TEST) country = USA; else @@ -762,7 +781,7 @@ void init_startup_params(ray_dev_t *local) strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE); } /* init_startup_params */ /*===========================================================================*/ -void verify_dl_startup(u_long data) +static void verify_dl_startup(u_long data) { ray_dev_t *local = (ray_dev_t *)data; struct ccs *pccs = ((struct ccs *)(local->sram + CCS_BASE)) + local->dl_param_ccs; @@ -779,7 +798,7 @@ void verify_dl_startup(u_long data) printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n", local->dl_param_ccs); for (i=0; i<sizeof(struct b5_startup_params); i++) { - printk(" %2x", readb(local->sram + HOST_TO_ECF_BASE + i)); + printk(" %2x", (unsigned int) readb(local->sram + HOST_TO_ECF_BASE + i)); } printk("\n"); } @@ -802,7 +821,7 @@ void verify_dl_startup(u_long data) } /* end verify_dl_startup */ /*===========================================================================*/ /* Command card to start a network */ -void start_net(u_long data) +static void start_net(u_long data) { ray_dev_t *local = (ray_dev_t *)data; struct ccs *pccs; @@ -828,7 +847,7 @@ void start_net(u_long data) } /* end start_net */ /*===========================================================================*/ /* Command card to join a network */ -void join_net(u_long data) +static void join_net(u_long data) { ray_dev_t *local = (ray_dev_t *)data; @@ -860,7 +879,7 @@ void join_net(u_long data) device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. =============================================================================*/ -void ray_release(u_long arg) +static void ray_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; struct net_device *dev = link->priv; @@ -912,7 +931,7 @@ void ray_release(u_long arg) actually access the device should check this flag to make sure the card is still present. =============================================================================*/ -int ray_event(event_t event, int priority, +static int ray_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; @@ -991,7 +1010,7 @@ int ray_dev_init(struct net_device *dev) return 0; } /*===========================================================================*/ -int ray_dev_config(struct net_device *dev, struct ifmap *map) +static int ray_dev_config(struct net_device *dev, struct ifmap *map) { ray_dev_t *local = dev->priv; dev_link_t *link = local->finder; @@ -1005,7 +1024,7 @@ int ray_dev_config(struct net_device *dev, struct ifmap *map) return 0; } /*===========================================================================*/ -int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) { ray_dev_t *local = dev->priv; dev_link_t *link = local->finder; @@ -1047,7 +1066,7 @@ int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } /* ray_dev_start_xmit */ /*===========================================================================*/ -int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, +static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR msg_type) { ray_dev_t *local = (ray_dev_t *)dev->priv; @@ -1089,7 +1108,7 @@ int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, } else { /* Encapsulate frame */ /* TBD TIB length will move address of ptx->var */ - memcpy( (UCHAR *)&ptx->var, data, len); + memcpy_toio(&ptx->var, data, len); offset = 0; } @@ -1121,7 +1140,7 @@ int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, return XMIT_OK; } /* end ray_hw_xmit */ /*===========================================================================*/ -int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data, +static int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data, int len) { unsigned short int proto = ((struct ethhdr *)data)->h_proto; @@ -1137,7 +1156,7 @@ int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data, /* Copy body of ethernet packet without ethernet header */ memcpy_toio((UCHAR *)&ptx->var + sizeof(struct snaphdr_t), \ data + ETH_HLEN, len - ETH_HLEN); - return sizeof(struct snaphdr_t) - ETH_HLEN; + return (int) sizeof(struct snaphdr_t) - ETH_HLEN; } else { /* already 802 type, and proto is length */ DEBUG(3,"ray_cs translate_frame 802\n"); @@ -1152,15 +1171,16 @@ int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data, /* TBD do other frame types */ } /* end translate_frame */ /*===========================================================================*/ -void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, +static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, unsigned char *data) { writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1); /*** IEEE 802.11 Address field assignments ************* - addr_1 addr_2 addr_3 - AP destination AP(BSSID) source - Infra Terminal AP terminal destination - Adhoc destination terminal BSSID + TODS FROMDS addr_1 addr_2 addr_3 addr_4 +Adhoc 0 0 dest src (terminal) BSSID N/A +AP to Terminal 0 1 dest AP(BSSID) source N/A +Terminal to AP 1 0 AP(BSSID) src (terminal) dest N/A +AP to AP 1 1 dest AP src AP dest source *******************************************************/ if (local->net_type == ADHOC) { writeb(0, &ptx->mac.frame_ctl_2); @@ -1186,11 +1206,14 @@ void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type, } } /* end encapsulate_frame */ /*===========================================================================*/ -int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { ray_dev_t *local = (ray_dev_t *)dev->priv; dev_link_t *link = local->finder; int err = 0; +#if WIRELESS_EXT > 7 + struct iwreq *wrq = (struct iwreq *) ifr; +#endif /* WIRELESS_EXT > 7 */ if (!(link->state & DEV_PRESENT)) { DEBUG(2,"ray_dev_ioctl - device not present\n"); @@ -1200,6 +1223,257 @@ int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /* Validate the command */ switch (cmd) { +#if WIRELESS_EXT > 7 + /* --------------- WIRELESS EXTENSIONS --------------- */ + /* Get name */ + case SIOCGIWNAME: + strcpy(wrq->u.name, "IEEE 802.11-FH"); + break; + + /* Get frequency/channel */ + case SIOCGIWFREQ: + wrq->u.freq.m = local->sparm.b5.a_hop_pattern; + wrq->u.freq.e = 0; + break; + + /* Get current network name (ESSID) */ + case SIOCGIWESSID: + if (wrq->u.data.pointer) + { + char essid[IW_ESSID_MAX_SIZE + 1]; + /* Get the essid that was set */ + memcpy(essid, local->sparm.b5.a_current_ess_id, + IW_ESSID_MAX_SIZE); + essid[IW_ESSID_MAX_SIZE] = '\0'; + + /* Push it out ! */ + wrq->u.data.length = strlen(essid) + 1; + wrq->u.data.flags = 1; /* active */ + copy_to_user(wrq->u.data.pointer, essid, sizeof(essid)); + } + break; + + /* Get current Access Point (BSSID in our case) */ + case SIOCGIWAP: + memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN); + wrq->u.ap_addr.sa_family = ARPHRD_ETHER; + break; + + /* Get the current bit-rate */ + case SIOCGIWRATE: + if(local->net_default_tx_rate == 3) + wrq->u.bitrate.value = 2000000; /* Hum... */ + else + wrq->u.bitrate.value = local->net_default_tx_rate * 500000; + wrq->u.bitrate.fixed = 0; /* We are in auto mode */ + break; + + /* Set the desired bit-rate */ + case SIOCSIWRATE: + /* Check if rate is in range */ + if((wrq->u.bitrate.value != 1000000) && + (wrq->u.bitrate.value != 2000000)) + { + err = -EINVAL; + break; + } + /* Hack for 1.5 Mb/s instead of 2 Mb/s */ + if((local->fw_ver == 0x55) && /* Please check */ + (wrq->u.bitrate.value == 2000000)) + local->net_default_tx_rate = 3; + else + local->net_default_tx_rate = wrq->u.bitrate.value/500000; + break; + + /* Get the current RTS threshold */ + case SIOCGIWRTS: + wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8) + + local->sparm.b5.a_rts_threshold[1]; +#if WIRELESS_EXT > 8 + wrq->u.rts.disabled = (wrq->u.rts.value == 32767); +#endif /* WIRELESS_EXT > 8 */ + wrq->u.rts.fixed = 1; + break; + + /* Get the current fragmentation threshold */ + case SIOCGIWFRAG: + wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8) + + local->sparm.b5.a_frag_threshold[1]; +#if WIRELESS_EXT > 8 + wrq->u.frag.disabled = (wrq->u.frag.value == 32767); +#endif /* WIRELESS_EXT > 8 */ + wrq->u.frag.fixed = 1; + break; +#endif /* WIRELESS_EXT > 7 */ +#if WIRELESS_EXT > 8 + + /* Get the current mode of operation */ + case SIOCGIWMODE: + if(local->sparm.b5.a_network_type) + wrq->u.mode = IW_MODE_INFRA; + else + wrq->u.mode = IW_MODE_ADHOC; + break; +#endif /* WIRELESS_EXT > 8 */ +#if WIRELESS_EXT > 7 + /* ------------------ IWSPY SUPPORT ------------------ */ + /* Define the range (variations) of above parameters */ + case SIOCGIWRANGE: + /* Basic checking... */ + if(wrq->u.data.pointer != (caddr_t) 0) + { + struct iw_range range; + memset((char *) &range, 0, sizeof(struct iw_range)); + + /* Set the length (useless : its constant...) */ + wrq->u.data.length = sizeof(struct iw_range); + + /* Set information in the range struct */ + range.throughput = 1.1 * 1000 * 1000; /* Put the right number here */ + range.num_channels = hop_pattern_length[(int)country]; + range.num_frequency = 0; + range.max_qual.qual = 0; + range.max_qual.level = 255; /* What's the correct value ? */ + range.max_qual.noise = 255; /* Idem */ + range.num_bitrates = 2; + range.bitrate[0] = 1000000; /* 1 Mb/s */ + range.bitrate[1] = 2000000; /* 2 Mb/s */ + + /* Copy structure to the user buffer */ + if(copy_to_user(wrq->u.data.pointer, &range, + sizeof(struct iw_range))) + err = -EFAULT; + } + break; + +#ifdef WIRELESS_SPY + /* Set addresses to spy */ + case SIOCSIWSPY: + /* Check the number of addresses */ + if(wrq->u.data.length > IW_MAX_SPY) + { + err = -E2BIG; + break; + } + local->spy_number = wrq->u.data.length; + + /* If there is some addresses to copy */ + if(local->spy_number > 0) + { + struct sockaddr address[IW_MAX_SPY]; + int i; + + /* Copy addresses to the driver */ + if(copy_from_user(address, wrq->u.data.pointer, + sizeof(struct sockaddr) * local->spy_number)) + { + err = -EFAULT; + break; + } + + /* Copy addresses to the lp structure */ + for(i = 0; i < local->spy_number; i++) + memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN); + + /* Reset structure... */ + memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY); + +#ifdef DEBUG_IOCTL_INFO + printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n"); + for(i = 0; i < local->spy_number; i++) + printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n", + local->spy_address[i][0], + local->spy_address[i][1], + local->spy_address[i][2], + local->spy_address[i][3], + local->spy_address[i][4], + local->spy_address[i][5]); +#endif /* DEBUG_IOCTL_INFO */ + } + break; + + /* Get the spy list and spy stats */ + case SIOCGIWSPY: + /* Set the number of addresses */ + wrq->u.data.length = local->spy_number; + + /* If the user want to have the addresses back... */ + if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0)) + { + struct sockaddr address[IW_MAX_SPY]; + int i; + + /* Copy addresses from the lp structure */ + for(i = 0; i < local->spy_number; i++) + { + memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN); + address[i].sa_family = ARPHRD_ETHER; + } + + /* Copy addresses to the user buffer */ + if(copy_to_user(wrq->u.data.pointer, address, + sizeof(struct sockaddr) * local->spy_number)) + { + err = -EFAULT; + break; + } + + /* Copy stats to the user buffer (just after) */ + if(copy_to_user(wrq->u.data.pointer + + (sizeof(struct sockaddr) * local->spy_number), + local->spy_stat, sizeof(iw_qual) * local->spy_number)) + { + err = -EFAULT; + break; + } + + /* Reset updated flags */ + for(i = 0; i < local->spy_number; i++) + local->spy_stat[i].updated = 0x0; + } /* if(pointer != NULL) */ + + break; +#endif /* WIRELESS_SPY */ + + /* ------------------ PRIVATE IOCTL ------------------ */ +#define SIOCSIPFRAMING SIOCDEVPRIVATE /* Set framing mode */ +#define SIOCGIPFRAMING SIOCDEVPRIVATE + 1 /* Get framing mode */ +#define SIOCGIPCOUNTRY SIOCDEVPRIVATE + 3 /* Get country code */ + case SIOCSIPFRAMING: + if(!suser()) /* For private IOCTLs, we need to check permissions */ + { + err = -EPERM; + break; + } + translate = *(wrq->u.name); /* Set framing mode */ + break; + case SIOCGIPFRAMING: + *(wrq->u.name) = translate; + break; + case SIOCGIPCOUNTRY: + *(wrq->u.name) = country; + break; + case SIOCGIWPRIV: + /* Export our "private" intercace */ + if(wrq->u.data.pointer != (caddr_t) 0) + { + struct iw_priv_args priv[] = + { /* cmd, set_args, get_args, name */ + { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, + { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, + { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, + }; + /* Set the number of ioctl available */ + wrq->u.data.length = 3; + /* Copy structure to the user buffer */ + if(copy_to_user(wrq->u.data.pointer, (u_char *) priv, + sizeof(priv))) + err = -EFAULT; + } + break; +#endif /* WIRELESS_EXT > 7 */ + + default: DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd); err = -EOPNOTSUPP; @@ -1207,7 +1481,38 @@ int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return err; } /* end ray_dev_ioctl */ /*===========================================================================*/ -int ray_open(struct net_device *dev) +#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ +static iw_stats * ray_get_wireless_stats(struct device * dev) +{ + ray_dev_t * local = (ray_dev_t *) dev->priv; + dev_link_t *link = local->finder; + struct status *p = (struct status *)(local->sram + STATUS_BASE); + + if(local == (ray_dev_t *) NULL) + return (iw_stats *) NULL; + + local->wstats.status = local->card_status; +#ifdef WIRELESS_SPY + if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0)) + { + /* Get it from the first node in spy list */ + local->wstats.qual.qual = local->spy_stat[0].qual; + local->wstats.qual.level = local->spy_stat[0].level; + local->wstats.qual.noise = local->spy_stat[0].noise; + local->wstats.qual.updated = local->spy_stat[0].updated; + } +#endif /* WIRELESS_SPY */ + + if((link->state & DEV_PRESENT)) { + local->wstats.qual.noise = readb(&p->rxnoise); + local->wstats.qual.updated |= 4; + } + + return &local->wstats; +} /* end ray_get_wireless_stats */ +#endif /* WIRELESS_EXT > 7 */ +/*===========================================================================*/ +static int ray_open(struct net_device *dev) { dev_link_t *link; ray_dev_t *local = (ray_dev_t *)dev->priv; @@ -1232,7 +1537,7 @@ int ray_open(struct net_device *dev) return 0; } /* end ray_open */ /*===========================================================================*/ -int ray_dev_close(struct net_device *dev) +static int ray_dev_close(struct net_device *dev) { dev_link_t *link; @@ -1255,14 +1560,14 @@ int ray_dev_close(struct net_device *dev) return 0; } /* end ray_dev_close */ /*===========================================================================*/ -void ray_reset(struct net_device *dev) { +static void ray_reset(struct net_device *dev) { DEBUG(1,"ray_reset entered\n"); return; } /*===========================================================================*/ /* Cause a firmware interrupt if it is ready for one */ /* Return nonzero if not ready */ -int interrupt_ecf(ray_dev_t *local, int ccs) +static int interrupt_ecf(ray_dev_t *local, int ccs) { int i = 50; dev_link_t *link = local->finder; @@ -1288,7 +1593,7 @@ int interrupt_ecf(ray_dev_t *local, int ccs) /*===========================================================================*/ /* Get next free transmit CCS */ /* Return - index of current tx ccs */ -int get_free_tx_ccs(ray_dev_t *local) +static int get_free_tx_ccs(ray_dev_t *local) { int i; struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE); @@ -1319,7 +1624,7 @@ int get_free_tx_ccs(ray_dev_t *local) /*===========================================================================*/ /* Get next free CCS */ /* Return - index of current ccs */ -int get_free_ccs(ray_dev_t *local) +static int get_free_ccs(ray_dev_t *local) { int i; struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE); @@ -1347,7 +1652,7 @@ int get_free_ccs(ray_dev_t *local) return ECCSFULL; } /* get_free_ccs */ /*===========================================================================*/ -void authenticate_timeout(u_long data) +static void authenticate_timeout(u_long data) { ray_dev_t *local = (ray_dev_t *)data; del_timer(&local->timer); @@ -1356,7 +1661,7 @@ void authenticate_timeout(u_long data) join_net((u_long)local); } /*===========================================================================*/ -int asc_to_int(char a) +static int asc_to_int(char a) { if (a < '0') return -1; if (a <= '9') return (a - '0'); @@ -1367,7 +1672,7 @@ int asc_to_int(char a) return -1; } /*===========================================================================*/ -int parse_addr(char *in_str, UCHAR *out) +static int parse_addr(char *in_str, UCHAR *out) { int len; int i,j,k; @@ -1395,7 +1700,7 @@ int parse_addr(char *in_str, UCHAR *out) return status; } /*===========================================================================*/ -struct enet_statistics *ray_get_stats(struct net_device *dev) +static struct enet_statistics *ray_get_stats(struct net_device *dev) { ray_dev_t *local = (ray_dev_t *)dev->priv; dev_link_t *link = local->finder; @@ -1425,7 +1730,7 @@ struct enet_statistics *ray_get_stats(struct net_device *dev) return &local->stats; } /*===========================================================================*/ -void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len) +static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len) { ray_dev_t *local = (ray_dev_t *)dev->priv; dev_link_t *link = local->finder; @@ -1542,7 +1847,7 @@ static void set_multicast_list(struct net_device *dev) /*============================================================================= * All routines below here are run at interrupt time. =============================================================================*/ -void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) +static void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct net_device *dev = (struct net_device *)dev_id; dev_link_t *link; @@ -1727,7 +2032,7 @@ void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) break; default: DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\ - rcsindex, readb(&prcs->interrupt_id)); + rcsindex, (unsigned int) readb(&prcs->interrupt_id)); break; } writeb(CCS_BUFFER_FREE, &prcs->buffer_status); @@ -1736,7 +2041,7 @@ void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs) dev->interrupt = 0; } /* ray_interrupt */ /*===========================================================================*/ -void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) +static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) { int rx_len; unsigned int pkt_addr; @@ -1750,6 +2055,7 @@ void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8) + readb(&prcs->var.rx_packet.rx_data_length[1]); + local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev); pmsg = local->rmem + pkt_addr; switch(readb(pmsg)) { @@ -1778,17 +2084,18 @@ void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs) rx_len < sizeof(struct beacon_rx) ? rx_len : sizeof(struct beacon_rx)); + local->beacon_rxed = 1; /* Get the statistics so the card counters never overflow */ ray_get_stats(dev); break; default: - DEBUG(0,"ray_cs unknown pkt type %2x\n", readb(pmsg)); + DEBUG(0,"ray_cs unknown pkt type %2x\n", (unsigned int) readb(pmsg)); break; } } /* end ray_rx */ /*===========================================================================*/ -void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, +static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, int rx_len) { struct sk_buff *skb = NULL; @@ -1797,6 +2104,10 @@ void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, UCHAR *rx_ptr; int total_len; int tmp; +#ifdef WIRELESS_SPY + int siglev = prcs->var.rx_packet.rx_sig_lev; + u_char linksrcaddr[ETH_ALEN]; /* Other end of the wireless link */ +#endif if (!sniffer) { if (translate) { @@ -1819,7 +2130,7 @@ void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, } DEBUG(4,"ray_cs rx_data packet\n"); /* If fragmented packet, verify sizes of fragments add up */ - if (prcs->var.rx_packet.next_frag_rcs_index != 0xFF) { + if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) { DEBUG(1,"ray_cs rx'ed fragment\n"); tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8) + readb(&prcs->var.rx_packet.totalpacketlength[1]); @@ -1865,7 +2176,10 @@ void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, rx_ptr = skb_put( skb, total_len); /* Copy the whole packet to sk_buff */ rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len); - + /* Get source address */ +#ifdef WIRELESS_SPY + memcpy(linksrcaddr, ((struct mac_header *)skb->data)->addr_2, ETH_ALEN); +#endif /* Now, deal with encapsulation/translation/sniffer */ if (!sniffer) { if (!translate) { @@ -1909,9 +2223,39 @@ void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr, local->stats.rx_packets++; local->stats.rx_bytes += skb->len; + + /* Gather signal strength per address */ +#ifdef WIRELESS_SPY + /* For the Access Point or the node having started the ad-hoc net + * note : ad-hoc work only in some specific configurations, but we + * kludge in ray_get_wireless_stats... */ + if(!memcmp(linksrcaddr, local->bss_id, ETH_ALEN)) + { + /* Update statistics */ + /*local->wstats.qual.qual = none ? */ + local->wstats.qual.level = siglev; + /*local->wstats.qual.noise = none ? */ + local->wstats.qual.updated = 0x2; + } + /* Now, for the addresses in the spy list */ + { + int i; + /* Look all addresses */ + for(i = 0; i < local->spy_number; i++) + /* If match */ + if(!memcmp(linksrcaddr, local->spy_address[i], ETH_ALEN)) + { + /* Update statistics */ + /*local->spy_stat[i].qual = none ? */ + local->spy_stat[i].level = siglev; + /*local->spy_stat[i].noise = none ? */ + local->spy_stat[i].updated = 0x2; + } + } +#endif /* WIRELESS_SPY */ } /* end rx_data */ /*===========================================================================*/ -void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) +static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) { snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH); struct mac_header *pmac = (struct mac_header *)skb->data; @@ -1923,11 +2267,23 @@ void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) UCHAR srcaddr[ADDRLEN]; UCHAR destaddr[ADDRLEN]; - if (local->sparm.b5.a_acting_as_ap_status != TYPE_STA) - memcpy(destaddr, pmac->addr_3, ADDRLEN); - else - memcpy(destaddr, pmac->addr_1, ADDRLEN); - memcpy(srcaddr, pmac->addr_2, ADDRLEN); + if (pmac->frame_ctl_2 & FC2_FROM_DS) { + if (pmac->frame_ctl_2 & FC2_TO_DS) { /* AP to AP */ + memcpy(destaddr, pmac->addr_3, ADDRLEN); + memcpy(srcaddr, ((unsigned char *)pmac->addr_3) + ADDRLEN, ADDRLEN); + } else { /* AP to terminal */ + memcpy(destaddr, pmac->addr_1, ADDRLEN); + memcpy(srcaddr, pmac->addr_3, ADDRLEN); + } + } else { /* Terminal to AP */ + if (pmac->frame_ctl_2 & FC2_TO_DS) { + memcpy(destaddr, pmac->addr_3, ADDRLEN); + memcpy(srcaddr, pmac->addr_2, ADDRLEN); + } else { /* Adhoc */ + memcpy(destaddr, pmac->addr_1, ADDRLEN); + memcpy(srcaddr, pmac->addr_2, ADDRLEN); + } + } #ifdef PCMCIA_DEBUG if (pc_debug > 3) { @@ -2005,7 +2361,7 @@ void untranslate(ray_dev_t *local, struct sk_buff *skb, int len) * pkt_addr = source address in receive buffer * len = length of packet to copy */ -int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length) +static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length) { int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1); if (wrap_bytes <= 0) @@ -2020,7 +2376,7 @@ int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length) return length; } /*===========================================================================*/ -void release_frag_chain(ray_dev_t *local, struct rcs* prcs) +static void release_frag_chain(ray_dev_t *local, struct rcs* prcs) { struct rcs *prcslink = prcs; int tmp = 17; @@ -2038,7 +2394,7 @@ void release_frag_chain(ray_dev_t *local, struct rcs* prcs) writeb(CCS_BUFFER_FREE, &prcslink->buffer_status); } /*===========================================================================*/ -void authenticate(ray_dev_t *local) +static void authenticate(ray_dev_t *local) { dev_link_t *link = local->finder; DEBUG(0,"ray_cs Starting authentication.\n"); @@ -2060,7 +2416,7 @@ void authenticate(ray_dev_t *local) local->authentication_state = AWAITING_RESPONSE; } /* end authenticate */ /*===========================================================================*/ -void rx_authenticate(ray_dev_t *local, struct rcs *prcs, +static void rx_authenticate(ray_dev_t *local, struct rcs *prcs, unsigned int pkt_addr, int rx_len) { UCHAR buff[256]; @@ -2103,7 +2459,7 @@ void rx_authenticate(ray_dev_t *local, struct rcs *prcs, } /* end rx_authenticate */ /*===========================================================================*/ -void associate(ray_dev_t *local) +static void associate(ray_dev_t *local) { struct ccs *pccs; dev_link_t *link = local->finder; @@ -2141,7 +2497,7 @@ void associate(ray_dev_t *local) } /* end associate */ /*===========================================================================*/ -void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, +static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, unsigned int pkt_addr, int rx_len) { /* UCHAR buff[256]; @@ -2154,7 +2510,7 @@ void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs, */ } /*===========================================================================*/ -void clear_interrupt(ray_dev_t *local) +static void clear_interrupt(ray_dev_t *local) { writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET); } @@ -2183,7 +2539,7 @@ static char *nettype[] = {"Adhoc", "Infra "}; static char *framing[] = {"Encapsulation", "Translation"} ; /*===========================================================================*/ -int ray_cs_proc_read(char *buf, char **start, off_t offset, +static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len, int unused) { /* Print current values which are not available via other means @@ -2229,10 +2585,13 @@ int ray_cs_proc_read(char *buf, char **start, off_t offset, len += sprintf(buf + len, "Framing mode = %s\n",framing[translate]); - /* Pull some fields out of last beacon received */ - len += sprintf(buf + len, "Beacon Interval = %d Kus\n", - local->last_bcn.beacon_intvl[0] - + 256 * local->last_bcn.beacon_intvl[1]); + len += sprintf(buf + len, "Last pkt signal lvl = %d\n", local->last_rsl); + + if (local->beacon_rxed) { + /* Pull some fields out of last beacon received */ + len += sprintf(buf + len, "Beacon Interval = %d Kus\n", + local->last_bcn.beacon_intvl[0] + + 256 * local->last_bcn.beacon_intvl[1]); p = local->last_bcn.elements; if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2; @@ -2253,25 +2612,28 @@ int ray_cs_proc_read(char *buf, char **start, off_t offset, return len; } - if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) { - pfh = (struct freq_hop_element *)p; - len += sprintf(buf + len, "Hop dwell = %d Kus\n", - pfh->dwell_time[0] + 256 * pfh->dwell_time[1]); - len += sprintf(buf + len, "Hop set = %d \n", pfh->hop_set); - len += sprintf(buf + len, "Hop pattern = %d \n", pfh->hop_pattern); - len += sprintf(buf + len, "Hop index = %d \n", pfh->hop_index); - p += p[1] + 2; - } - else { - len += sprintf(buf + len, "Parse beacon failed at FH param element\n"); - return len; + if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) { + pfh = (struct freq_hop_element *)p; + len += sprintf(buf + len, "Hop dwell = %d Kus\n", + pfh->dwell_time[0] + 256 * pfh->dwell_time[1]); + len += sprintf(buf + len, "Hop set = %d \n", pfh->hop_set); + len += sprintf(buf + len, "Hop pattern = %d \n", pfh->hop_pattern); + len += sprintf(buf + len, "Hop index = %d \n", pfh->hop_index); + p += p[1] + 2; + } + else { + len += sprintf(buf + len, "Parse beacon failed at FH param element\n"); + return len; + } + } else { + len += sprintf(buf + len, "No beacons received\n"); } return len; } #endif /*===========================================================================*/ -int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) +static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type) { int addr; struct ccs *pccs; diff --git a/drivers/net/pcmcia/ray_cs.h b/drivers/net/pcmcia/ray_cs.h index ae28bc71a..6f6f8e6ca 100644 --- a/drivers/net/pcmcia/ray_cs.h +++ b/drivers/net/pcmcia/ray_cs.h @@ -60,7 +60,18 @@ typedef struct ray_dev_t { UCHAR ASIC_version; UCHAR assoc_id[2]; UCHAR tib_length; + UCHAR last_rsl; + int beacon_rxed; struct beacon_rx last_bcn; +#ifdef WIRELESS_EXT + iw_stats wstats; /* Wireless specific stats */ +#endif +#ifdef WIRELESS_SPY + int spy_number; /* Number of addresses to spy */ + mac_addr spy_address[IW_MAX_SPY + 1]; /* The addresses to spy */ + iw_qual spy_stat[IW_MAX_SPY + 1]; /* Statistics gathered */ +#endif /* WIRELESS_SPY */ + } ray_dev_t; /*****************************************************************************/ diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 19b0c5819..bfe494177 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -561,6 +561,7 @@ ppp_init(struct net_device *dev) #ifndef MODULE extern struct compressor ppp_deflate, ppp_deflate_draft; extern int ppp_async_init(void); + extern int ppp_sync_init(void); #endif printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n"); @@ -571,6 +572,9 @@ ppp_init(struct net_device *dev) #ifdef CONFIG_PPP_ASYNC ppp_async_init(); #endif +#ifdef CONFIG_PPP_SYNC_TTY + ppp_sync_init(); +#endif #ifdef CONFIG_PPP_DEFLATE if (ppp_register_compressor(&ppp_deflate) == 0) printk(KERN_INFO "PPP Deflate compression module registered\n"); diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c new file mode 100644 index 000000000..5a1755b4e --- /dev/null +++ b/drivers/net/ppp_synctty.c @@ -0,0 +1,768 @@ +/* + * PPP synchronous tty channel driver for Linux. + * + * This is a ppp channel driver that can be used with tty device drivers + * that are frame oriented, such as synchronous HDLC devices. + * + * Complete PPP frames without encoding/decoding are exchanged between + * the channel driver and the device driver. + * + * The async map IOCTL codes are implemented to keep the user mode + * applications happy if they call them. Synchronous PPP does not use + * the async maps. + * + * Copyright 1999 Paul Mackerras. + * + * Also touched by the grubby hands of Paul Fulghum paulkf@microgate.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This driver provides the encapsulation and framing for sending + * and receiving PPP frames over sync serial lines. It relies on + * the generic PPP layer to give it frames to send and to process + * received frames. It implements the PPP line discipline. + * + * Part of the code in this driver was inspired by the old sync-only + * PPP driver, written by Michael Callahan and Al Longyear, and + * subsequently hacked by Paul Mackerras. + * + * ==FILEVERSION 991014== + */ + +/* $Id: ppp_synctty.c,v 1.3 1999/09/02 05:30:10 paulus Exp $ */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/skbuff.h> +#include <linux/tty.h> +#include <linux/netdevice.h> +#include <linux/poll.h> +#include <linux/ppp_defs.h> +#include <linux/if_ppp.h> +#include <linux/ppp_channel.h> +#include <asm/uaccess.h> + +#define PPP_VERSION "2.4.0" + +/* Structure for storing local state. */ +struct syncppp { + struct tty_struct *tty; + unsigned int flags; + unsigned int rbits; + int mru; + unsigned long busy; + u32 xaccm[8]; + u32 raccm; + unsigned int bytes_sent; + unsigned int bytes_rcvd; + + struct sk_buff *tpkt; + struct sk_buff_head xq; + unsigned long last_xmit; + + struct sk_buff *rpkt; + struct sk_buff_head rq; + wait_queue_head_t rwait; + + struct ppp_channel chan; /* interface to generic ppp layer */ + int connected; +}; + +/* Bit numbers in busy */ +#define XMIT_BUSY 0 +#define RECV_BUSY 1 +#define XMIT_WAKEUP 2 +#define XMIT_FULL 3 + +/* Bits in rbits */ +#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) + +#define PPPSYNC_MAX_RQLEN 32 /* arbitrary */ + +/* + * Prototypes. + */ +static struct sk_buff* ppp_sync_txdequeue(struct syncppp *ap); +static int ppp_sync_send(struct ppp_channel *chan, struct sk_buff *skb); +static int ppp_sync_push(struct syncppp *ap); +static void ppp_sync_flush_output(struct syncppp *ap); +static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, + char *flags, int count); + +struct ppp_channel_ops sync_ops = { + ppp_sync_send +}; + +/* + * Routines for locking and unlocking the transmit and receive paths. + */ +static inline void +lock_path(struct syncppp *ap, int bit) +{ + do { + while (test_bit(bit, &ap->busy)) + mb(); + } while (test_and_set_bit(bit, &ap->busy)); + mb(); +} + +static inline int +trylock_path(struct syncppp *ap, int bit) +{ + if (test_and_set_bit(bit, &ap->busy)) + return 0; + mb(); + return 1; +} + +static inline void +unlock_path(struct syncppp *ap, int bit) +{ + mb(); + clear_bit(bit, &ap->busy); +} + +#define lock_xmit_path(ap) lock_path(ap, XMIT_BUSY) +#define trylock_xmit_path(ap) trylock_path(ap, XMIT_BUSY) +#define unlock_xmit_path(ap) unlock_path(ap, XMIT_BUSY) +#define lock_recv_path(ap) lock_path(ap, RECV_BUSY) +#define trylock_recv_path(ap) trylock_path(ap, RECV_BUSY) +#define unlock_recv_path(ap) unlock_path(ap, RECV_BUSY) + +static inline void +flush_skb_queue(struct sk_buff_head *q) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(q)) != 0) + kfree_skb(skb); +} + +/* + * Routines implementing the synchronous PPP line discipline. + */ + +/* + * Called when a tty is put into line discipline. + */ +static int +ppp_sync_open(struct tty_struct *tty) +{ + struct syncppp *ap; + + ap = kmalloc(sizeof(*ap), GFP_KERNEL); + if (ap == 0) + return -ENOMEM; + + MOD_INC_USE_COUNT; + + /* initialize the syncppp structure */ + memset(ap, 0, sizeof(*ap)); + ap->tty = tty; + ap->mru = PPP_MRU; + ap->xaccm[0] = ~0U; + ap->xaccm[3] = 0x60000000U; + ap->raccm = ~0U; + skb_queue_head_init(&ap->xq); + skb_queue_head_init(&ap->rq); + init_waitqueue_head(&ap->rwait); + + tty->disc_data = ap; + + return 0; +} + +/* + * Called when the tty is put into another line discipline + * (or it hangs up). + */ +static void +ppp_sync_close(struct tty_struct *tty) +{ + struct syncppp *ap = tty->disc_data; + + if (ap == 0) + return; + tty->disc_data = 0; + lock_xmit_path(ap); + lock_recv_path(ap); + if (ap->rpkt != 0) + kfree_skb(ap->rpkt); + flush_skb_queue(&ap->rq); + if (ap->tpkt != 0) + kfree_skb(ap->tpkt); + flush_skb_queue(&ap->xq); + if (ap->connected) + ppp_unregister_channel(&ap->chan); + kfree(ap); + MOD_DEC_USE_COUNT; +} + +/* + * Read a PPP frame. pppd can use this to negotiate over the + * channel before it joins it to a bundle. + */ +static ssize_t +ppp_sync_read(struct tty_struct *tty, struct file *file, + unsigned char *buf, size_t count) +{ + struct syncppp *ap = tty->disc_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + struct sk_buff *skb = 0; + + ret = -ENXIO; + if (ap == 0) + goto out; /* should never happen */ + + add_wait_queue(&ap->rwait, &wait); + current->state = TASK_INTERRUPTIBLE; + for (;;) { + ret = -EAGAIN; + skb = skb_dequeue(&ap->rq); + if (skb) + break; + if (file->f_flags & O_NONBLOCK) + break; + ret = -ERESTARTSYS; + if (signal_pending(current)) + break; + schedule(); + } + current->state = TASK_RUNNING; + remove_wait_queue(&ap->rwait, &wait); + + if (skb == 0) + goto out; + + ret = -EOVERFLOW; + if (skb->len > count) + goto outf; + ret = -EFAULT; + if (copy_to_user(buf, skb->data, skb->len)) + goto outf; + ret = skb->len; + + outf: + kfree_skb(skb); + out: + return ret; +} + +/* + * Write a ppp frame. pppd can use this to send frames over + * this particular channel. + */ +static ssize_t +ppp_sync_write(struct tty_struct *tty, struct file *file, + const unsigned char *buf, size_t count) +{ + struct syncppp *ap = tty->disc_data; + struct sk_buff *skb; + ssize_t ret; + + ret = -ENXIO; + if (ap == 0) + goto out; /* should never happen */ + + ret = -ENOMEM; + skb = alloc_skb(count + 2, GFP_KERNEL); + if (skb == 0) + goto out; + skb_reserve(skb, 2); + ret = -EFAULT; + if (copy_from_user(skb_put(skb, count), buf, count)) { + kfree_skb(skb); + goto out; + } + + skb_queue_tail(&ap->xq, skb); + ppp_sync_push(ap); + + ret = count; + + out: + return ret; +} + +static int +ppp_sync_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct syncppp *ap = tty->disc_data; + int err, val; + u32 accm[8]; + struct sk_buff *skb; + + err = -ENXIO; + if (ap == 0) + goto out; /* should never happen */ + err = -EPERM; + if (!capable(CAP_NET_ADMIN)) + goto out; + + err = -EFAULT; + switch (cmd) { + case PPPIOCGFLAGS: + val = ap->flags | ap->rbits; + if (put_user(val, (int *) arg)) + break; + err = 0; + break; + case PPPIOCSFLAGS: + if (get_user(val, (int *) arg)) + break; + ap->flags = val & ~SC_RCV_BITS; + ap->rbits = val & SC_RCV_BITS; + err = 0; + break; + + case PPPIOCGASYNCMAP: + if (put_user(ap->xaccm[0], (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCSASYNCMAP: + if (get_user(ap->xaccm[0], (u32 *) arg)) + break; + err = 0; + break; + + case PPPIOCGRASYNCMAP: + if (put_user(ap->raccm, (u32 *) arg)) + break; + err = 0; + break; + case PPPIOCSRASYNCMAP: + if (get_user(ap->raccm, (u32 *) arg)) + break; + err = 0; + break; + + case PPPIOCGXASYNCMAP: + if (copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm))) + break; + err = 0; + break; + case PPPIOCSXASYNCMAP: + if (copy_from_user(accm, (void *) arg, sizeof(accm))) + break; + accm[2] &= ~0x40000000U; /* can't escape 0x5e */ + accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */ + memcpy(ap->xaccm, accm, sizeof(ap->xaccm)); + err = 0; + break; + + case PPPIOCGMRU: + if (put_user(ap->mru, (int *) arg)) + break; + err = 0; + break; + case PPPIOCSMRU: + if (get_user(val, (int *) arg)) + break; + if (val < PPP_MRU) + val = PPP_MRU; + ap->mru = val; + err = 0; + break; + + case PPPIOCATTACH: + if (get_user(val, (int *) arg)) + break; + err = -EALREADY; + if (ap->connected) + break; + ap->chan.private = ap; + ap->chan.ops = &sync_ops; + err = ppp_register_channel(&ap->chan, val); + if (err != 0) + break; + ap->connected = 1; + break; + case PPPIOCDETACH: + err = -ENXIO; + if (!ap->connected) + break; + ppp_unregister_channel(&ap->chan); + ap->connected = 0; + err = 0; + break; + + case TCGETS: + case TCGETA: + err = n_tty_ioctl(tty, file, cmd, arg); + break; + + case TCFLSH: + /* flush our buffers and the serial port's buffer */ + if (arg == TCIFLUSH || arg == TCIOFLUSH) + flush_skb_queue(&ap->rq); + if (arg == TCIOFLUSH || arg == TCOFLUSH) + ppp_sync_flush_output(ap); + err = n_tty_ioctl(tty, file, cmd, arg); + break; + + case FIONREAD: + val = 0; + if ((skb = skb_peek(&ap->rq)) != 0) + val = skb->len; + if (put_user(val, (int *) arg)) + break; + err = 0; + break; + + default: + err = -ENOIOCTLCMD; + } + out: + return err; +} + +static unsigned int +ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) +{ + struct syncppp *ap = tty->disc_data; + unsigned int mask; + + if (ap == 0) + return 0; /* should never happen */ + poll_wait(file, &ap->rwait, wait); + mask = POLLOUT | POLLWRNORM; + if (skb_peek(&ap->rq)) + mask |= POLLIN | POLLRDNORM; + if (test_bit(TTY_OTHER_CLOSED, &tty->flags) || tty_hung_up_p(file)) + mask |= POLLHUP; + return mask; +} + +static int +ppp_sync_room(struct tty_struct *tty) +{ + return 65535; +} + +static void +ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, + char *flags, int count) +{ + struct syncppp *ap = tty->disc_data; + + if (ap == 0) + return; + trylock_recv_path(ap); + ppp_sync_input(ap, buf, flags, count); + unlock_recv_path(ap); + if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) + && tty->driver.unthrottle) + tty->driver.unthrottle(tty); +} + +static void +ppp_sync_wakeup(struct tty_struct *tty) +{ + struct syncppp *ap = tty->disc_data; + + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + if (ap == 0) + return; + if (ppp_sync_push(ap) && ap->connected) + ppp_output_wakeup(&ap->chan); +} + + +static struct tty_ldisc ppp_sync_ldisc = { + magic: TTY_LDISC_MAGIC, + name: "pppsync", + open: ppp_sync_open, + close: ppp_sync_close, + read: ppp_sync_read, + write: ppp_sync_write, + ioctl: ppp_sync_ioctl, + poll: ppp_sync_poll, + receive_room: ppp_sync_room, + receive_buf: ppp_sync_receive, + write_wakeup: ppp_sync_wakeup, +}; + +int +ppp_sync_init(void) +{ + int err; + + err = tty_register_ldisc(N_SYNC_PPP, &ppp_sync_ldisc); + if (err != 0) + printk(KERN_ERR "PPP_sync: error %d registering line disc.\n", + err); + return err; +} + +/* + * Procedures for encapsulation and framing. + */ + +struct sk_buff* +ppp_sync_txdequeue(struct syncppp *ap) +{ + int proto; + unsigned char *data; + int islcp; + struct sk_buff *skb; + + while ((skb = skb_dequeue(&ap->xq)) != NULL) { + + data = skb->data; + proto = (data[0] << 8) + data[1]; + + /* LCP packets with codes between 1 (configure-request) + * and 7 (code-reject) must be sent as though no options + * have been negotiated. + */ + islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7; + + /* prepend address/control fields if necessary */ + if ((ap->flags & SC_COMP_AC) == 0 || islcp) { + if (skb_headroom(skb) < 2) { + struct sk_buff *npkt = dev_alloc_skb(skb->len + 2); + if (npkt == NULL) { + kfree_skb(skb); + continue; + } + skb_reserve(npkt,2); + memcpy(skb_put(npkt,skb->len), skb->data, skb->len); + kfree_skb(skb); + skb = npkt; + } + skb_pull(skb,2); + skb->data[0] = PPP_ALLSTATIONS; + skb->data[1] = PPP_UI; + } + + ap->last_xmit = jiffies; + break; + } + + return skb; +} + +/* + * Transmit-side routines. + */ + +/* + * Send a packet to the peer over an sync tty line. + * Returns 1 iff the packet was accepted. + * If the packet was not accepted, we will call ppp_output_wakeup + * at some later time. + */ +static int +ppp_sync_send(struct ppp_channel *chan, struct sk_buff *skb) +{ + struct syncppp *ap = chan->private; + + ppp_sync_push(ap); + + if (test_and_set_bit(XMIT_FULL, &ap->busy)) + return 0; /* already full */ + ap->tpkt = skb; + + ppp_sync_push(ap); + return 1; +} + +/* + * Push as much data as possible out to the tty. + */ +static int +ppp_sync_push(struct syncppp *ap) +{ + int sent, done = 0; + struct tty_struct *tty = ap->tty; + int tty_stuffed = 0; + + if (!trylock_xmit_path(ap)) { + set_bit(XMIT_WAKEUP, &ap->busy); + return 0; + } + for (;;) { + if (test_and_clear_bit(XMIT_WAKEUP, &ap->busy)) + tty_stuffed = 0; + if (ap->tpkt == 0) { + if ((ap->tpkt = ppp_sync_txdequeue(ap)) == 0) { + clear_bit(XMIT_FULL, &ap->busy); + done = 1; + } + } + if (!tty_stuffed && ap->tpkt != NULL) { + set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + sent = tty->driver.write(tty, 0, ap->tpkt->data, ap->tpkt->len); + if (sent < 0) + goto flush; /* error, e.g. loss of CD */ + if (sent < ap->tpkt->len) { + tty_stuffed = 1; + } else { + kfree_skb(ap->tpkt); + ap->tpkt = 0; + } + continue; + } + /* haven't made any progress */ + unlock_xmit_path(ap); + if (!(test_bit(XMIT_WAKEUP, &ap->busy) + || (!tty_stuffed && ap->tpkt != 0))) + break; + if (!trylock_xmit_path(ap)) + break; + } + return done; + +flush: + if (ap->tpkt != 0) { + kfree_skb(ap->tpkt); + ap->tpkt = 0; + clear_bit(XMIT_FULL, &ap->busy); + done = 1; + } + unlock_xmit_path(ap); + return done; +} + +/* + * Flush output from our internal buffers. + * Called for the TCFLSH ioctl. + */ +static void +ppp_sync_flush_output(struct syncppp *ap) +{ + int done = 0; + + flush_skb_queue(&ap->xq); + lock_xmit_path(ap); + if (ap->tpkt != NULL) { + kfree_skb(ap->tpkt); + ap->tpkt = 0; + clear_bit(XMIT_FULL, &ap->busy); + done = 1; + } + unlock_xmit_path(ap); + if (done && ap->connected) + ppp_output_wakeup(&ap->chan); +} + +/* + * Receive-side routines. + */ + +static inline void +process_input_packet(struct syncppp *ap) +{ + struct sk_buff *skb; + unsigned char *p; + int code = 0; + + skb = ap->rpkt; + ap->rpkt = 0; + + /* strip address/control field if present */ + p = skb->data; + if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { + /* chop off address/control */ + if (skb->len < 3) + goto err; + p = skb_pull(skb, 2); + } + + /* decompress protocol field if compressed */ + if (p[0] & 1) { + /* protocol is compressed */ + skb_push(skb, 1)[0] = 0; + } else if (skb->len < 2) + goto err; + + /* pass to generic layer or queue it */ + if (ap->connected) { + ppp_input(&ap->chan, skb); + } else { + skb_queue_tail(&ap->rq, skb); + /* drop old frames if queue too long */ + while (ap->rq.qlen > PPPSYNC_MAX_RQLEN + && (skb = skb_dequeue(&ap->rq)) != 0) + kfree(skb); + wake_up_interruptible(&ap->rwait); + } + return; + + err: + kfree_skb(skb); + if (ap->connected) + ppp_input_error(&ap->chan, code); +} + +static inline void +input_error(struct syncppp *ap, int code) +{ + if (ap->connected) + ppp_input_error(&ap->chan, code); +} + +/* called when the tty driver has data for us. + * + * Data is frame oriented: each call to ppp_sync_input is considered + * a whole frame. If the 1st flag byte is non-zero then the whole + * frame is considered to be in error and is tossed. + */ +static void +ppp_sync_input(struct syncppp *ap, const unsigned char *buf, + char *flags, int count) +{ + struct sk_buff *skb; + unsigned char *sp; + + if (count == 0) + return; + + /* if flag set, then error, ignore frame */ + if (flags != 0 && *flags) { + input_error(ap, *flags); + return; + } + + /* stuff the chars in the skb */ + if ((skb = ap->rpkt) == 0) { + if ((skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2)) == 0) { + printk(KERN_ERR "PPPsync: no memory (input pkt)\n"); + input_error(ap, 0); + return; + } + /* Try to get the payload 4-byte aligned */ + if (buf[0] != PPP_ALLSTATIONS) + skb_reserve(skb, 2 + (buf[0] & 1)); + ap->rpkt = skb; + } + if (count > skb_tailroom(skb)) { + /* packet overflowed MRU */ + input_error(ap, 1); + } else { + sp = skb_put(skb, count); + memcpy(sp, buf, count); + process_input_packet(ap); + } +} + +#ifdef MODULE +int +init_module(void) +{ + return ppp_sync_init(); +} + +void +cleanup_module(void) +{ + if (tty_register_ldisc(N_SYNC_PPP, NULL) != 0) + printk(KERN_ERR "failed to unregister Sync PPP line discipline\n"); +} +#endif /* MODULE */ diff --git a/drivers/net/strip.c b/drivers/net/strip.c index 9acb7f031..b9131cb73 100644 --- a/drivers/net/strip.c +++ b/drivers/net/strip.c @@ -118,6 +118,7 @@ static const char StripVersion[] = "1.3-STUART.CHESHIRE"; #include <linux/if_arp.h> #include <linux/if_strip.h> #include <linux/proc_fs.h> +#include <linux/serialP.h> #include <linux/serial.h> #include <net/arp.h> diff --git a/drivers/pci/pcisyms.c b/drivers/pci/pcisyms.c index 030e36f3d..44d272776 100644 --- a/drivers/pci/pcisyms.c +++ b/drivers/pci/pcisyms.c @@ -19,6 +19,7 @@ EXPORT_SYMBOL(pci_write_config_word); EXPORT_SYMBOL(pci_write_config_dword); EXPORT_SYMBOL(pci_devices); EXPORT_SYMBOL(pci_root); +EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_find_class); EXPORT_SYMBOL(pci_find_device); EXPORT_SYMBOL(pci_find_slot); diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index fa6eba768..736ac0c05 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -100,16 +100,6 @@ static irq_info_t irq_table[NR_IRQS] = { { 0, 0, 0 }, /* etc */ }; /*====================================================================== - Linux resource management extensions - -======================================================================*/ - -static spinlock_t rsrc_lock = SPIN_LOCK_UNLOCKED; - -#define check_io_region(b,n) (0) - -/*====================================================================== - These manage the internal databases of available resources. ======================================================================*/ @@ -190,7 +180,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num) b = kmalloc(256, GFP_KERNEL); memset(b, 0, 256); for (i = base, most = 0; i < base+num; i += 8) { - if (check_region(i, 8) || check_io_region(i, 8)) + if (check_region(i, 8)) continue; hole = inb(i); for (j = 1; j < 8; j++) @@ -203,7 +193,7 @@ static void do_io_probe(ioaddr_t base, ioaddr_t num) bad = any = 0; for (i = base; i < base+num; i += 8) { - if (check_region(i, 8) || check_io_region(i, 8)) + if (check_region(i, 8)) continue; for (j = 0; j < 8; j++) if (inb(i+j) != most) break; @@ -365,8 +355,7 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, char *name) if (*base != 0) { for (m = io_db.next; m != &io_db; m = m->next) { if ((*base >= m->base) && (*base+num <= m->base+m->num)) { - if (check_region(*base, num) || - check_io_region(*base, num)) { + if (check_region(*base, num)) { return -1; } else { request_region(*base, num, name); @@ -382,8 +371,7 @@ int find_io_region(ioaddr_t *base, ioaddr_t num, char *name) for (*base = (m->base + align - 1) & (~(align-1)); *base+align <= m->base + m->num; *base += align) - if ((check_region(*base, num) == 0) && - (check_io_region(*base, num) == 0)) { + if (check_region(*base, num) == 0) { request_region(*base, num, name); return 0; } diff --git a/drivers/scsi/script_asm.pl b/drivers/scsi/script_asm.pl index d99fcc950..a25a7271a 100644 --- a/drivers/scsi/script_asm.pl +++ b/drivers/scsi/script_asm.pl @@ -896,7 +896,7 @@ foreach $label (@label) { open (OUTPUT, ">$output") || die "$0 : can't open $output for writing\n"; open (OUTPUTU, ">$outputu") || die "$0 : can't open $outputu for writing\n"; -print OUTPUT "u32 ".$prefix."SCRIPT[] = {\n"; +print OUTPUT "static u32 ".$prefix."SCRIPT[] = {\n"; $instructions = 0; for ($i = 0; $i < $#code; ) { if ($list_in_array) { @@ -935,7 +935,7 @@ foreach $i (@absolute) { } printf OUTPUTU "#undef A_$i\n"; - printf OUTPUT "u32 A_".$i."_used\[\] = {\n"; + printf OUTPUT "static u32 A_".$i."_used\[\] __attribute((unused)) = {\n"; printf STDERR "$i is used $symbol_references{$i}\n" if ($debug); foreach $j (split (/\s+/,$symbol_references{$i})) { $j =~ /(ABS|REL),(.*),(.*)/; @@ -957,15 +957,15 @@ foreach $i (sort @entry) { # NCR assembler outputs label patches in the form of indices into # the code. # -printf OUTPUT "u32 ".$prefix."LABELPATCHES[] = {\n"; +printf OUTPUT "static u32 ".$prefix."LABELPATCHES[] __attribute((unused)) = {\n"; for $patch (sort {$a <=> $b} @label_patches) { printf OUTPUT "\t0x%08x,\n", $patch; } printf OUTPUT "};\n\n"; $num_external_patches = 0; -printf OUTPUT "struct {\n\tu32\toffset;\n\tvoid\t\t*address;\n". - "} ".$prefix."EXTERNAL_PATCHES[] = {\n"; +printf OUTPUT "static struct {\n\tu32\toffset;\n\tvoid\t\t*address;\n". + "} ".$prefix."EXTERNAL_PATCHES[] __attribute((unused)) = {\n"; while ($ident = pop(@external_patches)) { $off = pop(@external_patches); printf OUTPUT "\t{0x%08x, &%s},\n", $off, $ident; @@ -973,11 +973,11 @@ while ($ident = pop(@external_patches)) { } printf OUTPUT "};\n\n"; -printf OUTPUT "u32 ".$prefix."INSTRUCTIONS\t= %d;\n", +printf OUTPUT "static u32 ".$prefix."INSTRUCTIONS __attribute((unused))\t= %d;\n", $instructions; -printf OUTPUT "u32 ".$prefix."PATCHES\t= %d;\n", +printf OUTPUT "static u32 ".$prefix."PATCHES __attribute((unused))\t= %d;\n", $#label_patches+1; -printf OUTPUT "u32 ".$prefix."EXTERNAL_PATCHES_LEN\t= %d;\n", +printf OUTPUT "static u32 ".$prefix."EXTERNAL_PATCHES_LEN __attribute((unused))\t= %d;\n", $num_external_patches; close OUTPUT; close OUTPUTU; diff --git a/drivers/sound/ac97.c b/drivers/sound/ac97.c index bc313134f..b54e62f76 100644 --- a/drivers/sound/ac97.c +++ b/drivers/sound/ac97.c @@ -5,6 +5,10 @@ /* And for stereo. */ #define ST 1 +/* Whether or not the bits in the channel are inverted. */ +#define INV 1 +#define NINV 0 + static struct ac97_chn_desc { int ac97_regnum; int oss_channel; @@ -13,21 +17,22 @@ static struct ac97_chn_desc { int oss_mask; int recordNum; u16 regmask; + int is_inverted; } mixerRegs[] = { - { AC97_MASTER_VOL_STEREO, SOUND_MIXER_VOLUME, 0x3f, ST, SOUND_MASK_VOLUME, 5, 0x0000 }, - { AC97_MASTER_VOL_MONO, SOUND_MIXER_PHONEOUT, 0x3f, MO, SOUND_MASK_PHONEOUT, 6, 0x0000 }, - { AC97_MASTER_TONE, SOUND_MIXER_TREBLE, 0x0f, MO, SOUND_MASK_TREBLE, -1, 0x00ff }, - { AC97_MASTER_TONE, SOUND_MIXER_BASS, 0x0f, MO, SOUND_MASK_BASS, -1, 0xff00 }, - { AC97_PCBEEP_VOL, SOUND_MIXER_SPEAKER, 0x0f, MO, SOUND_MASK_SPEAKER, -1, 0x001e }, - { AC97_PHONE_VOL, SOUND_MIXER_PHONEIN, 0x1f, MO, SOUND_MASK_PHONEIN, 7, 0x0000 }, - { AC97_MIC_VOL, SOUND_MIXER_MIC, 0x1f, MO, SOUND_MASK_MIC, 0, 0x0000 }, - { AC97_LINEIN_VOL, SOUND_MIXER_LINE, 0x1f, ST, SOUND_MASK_LINE, 4, 0x0000 }, - { AC97_CD_VOL, SOUND_MIXER_CD, 0x1f, ST, SOUND_MASK_CD, 1, 0x0000 }, - { AC97_VIDEO_VOL, SOUND_MIXER_VIDEO, 0x1f, ST, SOUND_MASK_VIDEO, 2, 0x0000 }, - { AC97_AUX_VOL, SOUND_MIXER_LINE1, 0x1f, ST, SOUND_MASK_LINE1, 3, 0x0000 }, - { AC97_PCMOUT_VOL, SOUND_MIXER_PCM, 0x1f, ST, SOUND_MASK_PCM, -1, 0x0000 }, - { AC97_RECORD_GAIN, SOUND_MIXER_IGAIN, 0x0f, ST, SOUND_MASK_IGAIN, -1, 0x0000 }, - { -1, -1, 0xff, 0, 0, -1, 0x0000 }, + { AC97_MASTER_VOL_STEREO, SOUND_MIXER_VOLUME, 0x3f, ST, SOUND_MASK_VOLUME, 5, 0x0000, INV }, + { AC97_MASTER_VOL_MONO, SOUND_MIXER_PHONEOUT, 0x3f, MO, SOUND_MASK_PHONEOUT, 6, 0x0000, INV }, + { AC97_MASTER_TONE, SOUND_MIXER_TREBLE, 0x0f, MO, SOUND_MASK_TREBLE, -1, 0x00ff, INV }, + { AC97_MASTER_TONE, SOUND_MIXER_BASS, 0x0f, MO, SOUND_MASK_BASS, -1, 0xff00, INV }, + { AC97_PCBEEP_VOL, SOUND_MIXER_SPEAKER, 0x0f, MO, SOUND_MASK_SPEAKER, -1, 0x001e, INV }, + { AC97_PHONE_VOL, SOUND_MIXER_PHONEIN, 0x1f, MO, SOUND_MASK_PHONEIN, 7, 0x0000, INV }, + { AC97_MIC_VOL, SOUND_MIXER_MIC, 0x1f, MO, SOUND_MASK_MIC, 0, 0x0000, INV }, + { AC97_LINEIN_VOL, SOUND_MIXER_LINE, 0x1f, ST, SOUND_MASK_LINE, 4, 0x0000, INV }, + { AC97_CD_VOL, SOUND_MIXER_CD, 0x1f, ST, SOUND_MASK_CD, 1, 0x0000, INV }, + { AC97_VIDEO_VOL, SOUND_MIXER_VIDEO, 0x1f, ST, SOUND_MASK_VIDEO, 2, 0x0000, INV }, + { AC97_AUX_VOL, SOUND_MIXER_LINE1, 0x1f, ST, SOUND_MASK_LINE1, 3, 0x0000, INV }, + { AC97_PCMOUT_VOL, SOUND_MIXER_PCM, 0x1f, ST, SOUND_MASK_PCM, -1, 0x0000, INV }, + { AC97_RECORD_GAIN, SOUND_MIXER_IGAIN, 0x0f, ST, SOUND_MASK_IGAIN, -1, 0x0000, NINV }, + { -1, -1, 0xff, 0, 0, -1, 0x0000, 0 }, }; static struct ac97_chn_desc * @@ -104,6 +109,25 @@ ac97_init (struct ac97_hwint *dev) return 0; } +/* Reset the mixer to the currently saved settings. */ +int +ac97_reset (struct ac97_hwint *dev) +{ + int x; + + if (dev->reset_device (dev)) + return -1; + + /* Now set the registers back to their last-written values. */ + for (x = 0; mixerRegs[x].ac97_regnum != -1; x++) { + int regnum = mixerRegs[x].ac97_regnum; + int value = dev->last_written_mixer_values [regnum / 2]; + if (value >= 0) + ac97_put_register (dev, regnum, value); + } + return 0; +} + /* Return the contents of register REG; use the cache if the value in it is valid. Returns a negative error code on failure. */ int @@ -156,38 +180,45 @@ ac97_put_register (struct ac97_hwint *dev, u8 reg, u16 value) scaled value on success. */ static int -ac97_scale_to_oss_val (int value, int maxval, int is_stereo) +ac97_scale_to_oss_val (int value, int maxval, int is_stereo, int inv) { /* Muted? */ if (value & AC97_MUTE) return 0; if (is_stereo) - return (ac97_scale_to_oss_val (value & 255, maxval, 0) << 8) - | (ac97_scale_to_oss_val ((value >> 8) & 255, maxval, 0) << 0); + return (ac97_scale_to_oss_val (value & 255, maxval, 0, inv) << 8) + | (ac97_scale_to_oss_val ((value >> 8) & 255, maxval, 0, inv) << 0); else { int i; /* Inverted. */ - value = maxval - value; + if (inv) + value = maxval - value; i = (value * 100 + (maxval / 2)) / maxval; if (i > 100) i = 100; + if (i < 0) + i = 0; return i; } } static int -ac97_scale_from_oss_val (int value, int maxval, int is_stereo) +ac97_scale_from_oss_val (int value, int maxval, int is_stereo, int inv) { if (is_stereo) - return (ac97_scale_from_oss_val (value & 255, maxval, 0) << 8) - | (ac97_scale_from_oss_val ((value >> 8) & 255, maxval, 0) << 0); + return (ac97_scale_from_oss_val (value & 255, maxval, 0, inv) << 8) + | (ac97_scale_from_oss_val ((value >> 8) & 255, maxval, 0, inv) << 0); else { - int i = maxval - ((value & 255) * maxval + 50) / 100; + int i = ((value & 255) * maxval + 50) / 100; + if (inv) + i = maxval - i; if (i < 0) i = 0; + if (i > maxval) + i = maxval; return i; } } @@ -204,7 +235,8 @@ ac97_set_mixer (struct ac97_hwint *dev, int oss_channel, u16 oss_value) if (! ac97_is_valid_channel (dev, channel)) return -ENODEV; scaled_value = ac97_scale_from_oss_val (oss_value, channel->maxval, - channel->is_stereo); + channel->is_stereo, + channel->is_inverted); if (scaled_value < 0) return scaled_value; @@ -253,7 +285,8 @@ ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel) regval >>= 1; } return ac97_scale_to_oss_val (regval, channel->maxval, - channel->is_stereo); + channel->is_stereo, + channel->is_inverted); } int @@ -383,8 +416,9 @@ ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, caddr_t arg) else ret = -EFAULT; } - if (ret >= 0) { - if (dev->last_written_OSS_values[channel] == AC97_REGVAL_UNKNOWN) + if (ret >= 0 && (dir & _IOC_READ)) { + if (dev->last_written_OSS_values[channel] + == AC97_REGVAL_UNKNOWN) dev->last_written_OSS_values[channel] = ac97_get_mixer_scaled (dev, channel); ret = dev->last_written_OSS_values[channel]; diff --git a/drivers/sound/ac97.h b/drivers/sound/ac97.h index 490d69f88..294000f6d 100644 --- a/drivers/sound/ac97.h +++ b/drivers/sound/ac97.h @@ -10,7 +10,7 @@ #include "sound_config.h" #include "sound_calls.h" -#define AC97_RESET 0x0000 // */ +#define AC97_RESET 0x0000 // #define AC97_MASTER_VOL_STEREO 0x0002 // Line Out #define AC97_HEADPHONE_VOL 0x0004 // #define AC97_MASTER_VOL_MONO 0x0006 // TAD Output @@ -207,6 +207,10 @@ extern int ac97_get_mixer_scaled (struct ac97_hwint *dev, int oss_channel); /* Default ioctl. */ extern int ac97_mixer_ioctl (struct ac97_hwint *dev, unsigned int cmd, caddr_t arg); + +/* Do a complete reset on the AC97 mixer, restoring all mixer registers to + the current values. Normally used after an APM resume event. */ +extern int ac97_reset (struct ac97_hwint *dev); #endif /* diff --git a/drivers/sound/nm256.h b/drivers/sound/nm256.h index 4cc720ab9..c640b88ce 100644 --- a/drivers/sound/nm256.h +++ b/drivers/sound/nm256.h @@ -3,10 +3,12 @@ #include "ac97.h" +/* The revisions that we currently handle. */ enum nm256rev { REV_NM256AV, REV_NM256ZX }; +/* Per-card structure. */ struct nm256_info { /* Magic number used to verify that this struct is valid. */ @@ -34,10 +36,12 @@ struct nm256_info /* The mixer device. */ int mixer_oss_dev; - /* Can only be opened once for each operation. These aren't set - until an actual I/O operation is performed; this allows one - device to be open for read/write without inhibiting I/O to - the other device. */ + /* + * Can only be opened once for each operation. These aren't set + * until an actual I/O operation is performed; this allows one + * device to be open for read/write without inhibiting I/O to + * the other device. + */ int is_open_play; int is_open_record; @@ -46,25 +50,40 @@ struct nm256_info /* Ditto for recording a sample. */ int recording; - /* The two memory ports. */ - char *ports[2]; - - /* Starting offset of the port1 area mapped into memory. */ - u32 port1_start; - /* Ending offset. */ - u32 port1_end; - /* The offset of the end of the actual buffer area. */ - u32 bufend; + /* The two memory ports. */ + struct nm256_ports { + /* Physical address of the port. */ + u32 physaddr; + /* Our mapped-in pointer. */ + char *ptr; + /* PTR's offset within the physical port. */ + u32 start_offset; + /* And the offset of the end of the buffer. */ + u32 end_offset; + } port[2]; /* The following are offsets within memory port 1. */ u32 coeffBuf; u32 allCoeffBuf; + /* Record and playback buffers. */ u32 abuf1, abuf2; /* Offset of the AC97 mixer in memory port 2. */ u32 mixer; + /* Offset of the mixer status register in memory port 2. */ + u32 mixer_status_offset; + + /* Non-zero if we have written initial values to the mixer. */ + u8 mixer_values_init; + + /* + * Status mask bit; (*mixer_status_loc & mixer_status_mask) == 0 means + * it's ready. + */ + u16 mixer_status_mask; + /* The sizes of the playback and record ring buffers. */ u32 playbackBufferSize; u32 recordBufferSize; @@ -77,7 +96,7 @@ struct nm256_info /* The start of the block currently playing. */ u32 curPlayPos; - /* The amount of data we requested to record. */ + /* The amount of data we were requested to record. */ u32 requestedRecAmt; /* The offset of the currently-recording block. */ u32 curRecPos; @@ -107,10 +126,17 @@ struct nm256_info /* Debug flag--bigger numbers mean more output. */ extern int nm256_debug; -/* Size of the second memory port. */ +/* The BIOS signature. */ +#define NM_SIGNATURE 0x4e4d0000 +/* Signature mask. */ +#define NM_SIG_MASK 0xffff0000 + +/* Size of the second memory area. */ #define NM_PORT2_SIZE 4096 -/* The location of the mixer. */ -#define NM_MIXER_BASE 0x600 + +/* The base offset of the mixer in the second memory area. */ +#define NM_MIXER_OFFSET 0x600 + /* The maximum size of a coefficient entry. */ #define NM_MAX_COEFFICIENT 0x5000 @@ -123,21 +149,33 @@ extern int nm256_debug; #define NM_MISC_INT_2 0x1 #define NM_ACK_INT(CARD, X) nm256_writePort16((CARD), 2, NM_INT_REG, (X) << 1) -/* For the second revision. It uses the same interrupt register, but it - holds 32 bits instead of 16. */ +/* The AV's "mixer ready" status bit and location. */ +#define NM_MIXER_STATUS_OFFSET 0xa04 +#define NM_MIXER_READY_MASK 0x0800 +#define NM_MIXER_PRESENCE 0xa06 +#define NM_PRESENCE_MASK 0x0050 +#define NM_PRESENCE_VALUE 0x0040 + +/* + * For the ZX. It uses the same interrupt register, but it holds 32 + * bits instead of 16. + */ #define NM2_PLAYBACK_INT 0x10000 #define NM2_RECORD_INT 0x80000 #define NM2_MISC_INT_1 0x8 #define NM2_MISC_INT_2 0x2 #define NM2_ACK_INT(CARD, X) nm256_writePort32((CARD), 2, NM_INT_REG, (X)) +/* The ZX's "mixer ready" status bit and location. */ +#define NM2_MIXER_STATUS_OFFSET 0xa06 +#define NM2_MIXER_READY_MASK 0x0800 + /* The playback registers start from here. */ #define NM_PLAYBACK_REG_OFFSET 0x0 /* The record registers start from here. */ #define NM_RECORD_REG_OFFSET 0x200 -/* The rate register is located 2 bytes from the start of the register - area. */ +/* The rate register is located 2 bytes from the start of the register area. */ #define NM_RATE_REG_OFFSET 2 /* Mono/stereo flag, number of bits on playback, and rate mask. */ @@ -156,7 +194,7 @@ extern int nm256_debug; #define NM_AUDIO_MUTE_LEFT 0x8000 #define NM_AUDIO_MUTE_RIGHT 0x0080 -/* Recording enable register */ +/* Recording enable register. */ #define NM_RECORD_ENABLE_REG (NM_RECORD_REG_OFFSET + 0) #define NM_RECORD_ENABLE_FLAG 1 #define NM_RECORD_FREERUN 2 @@ -179,26 +217,25 @@ extern int nm256_debug; if (port < 1 || port > 2 || card == NULL) \ return -1; \ \ - if (port == 1) { \ - if (offset < card->port1_start || offset >= card->port1_end) { \ - printk (KERN_ERR "Bad port request port 1:0x%x\n", offset); \ - return -1; \ - } \ - offset -= card->port1_start; \ - } else if (offset < 0 || offset > 4096) { \ - printk (KERN_ERR "Bad port request port 2: 0x%x\n", offset); \ - return -1; \ - } + if (offset < card->port[port - 1].start_offset \ + || offset >= card->port[port - 1].end_offset) { \ + printk (KERN_ERR "Bad access: port %d, offset 0x%x\n", port, offset); \ + return -1; \ + } \ + offset -= card->port[port - 1].start_offset; #define DEFwritePortX(X, func) \ static inline int nm256_writePort##X (struct nm256_info *card,\ - int port, int offset, int value)\ + int port, int offset, int value)\ {\ u##X *addr;\ \ + if (nm256_debug > 1)\ + printk (KERN_DEBUG "Writing 0x%x to %d:0x%x\n", value, port, offset);\ +\ NM_FIX_PORT;\ \ - addr = (u##X *)(card->ports[port - 1] + offset);\ + addr = (u##X *)(card->port[port - 1].ptr + offset);\ func (value, addr);\ return 0;\ } @@ -207,29 +244,28 @@ DEFwritePortX (8, writeb) DEFwritePortX (16, writew) DEFwritePortX (32, writel) -#define DEFreadPortX(X) \ +#define DEFreadPortX(X, func) \ static inline u##X nm256_readPort##X (struct nm256_info *card,\ int port, int offset)\ {\ - u##X *addr, res;\ + u##X *addr;\ \ NM_FIX_PORT\ \ - addr = (u##X *)(card->ports[port - 1] + offset);\ - memcpy_fromio (&res, addr, sizeof (res));\ - return res;\ + addr = (u##X *)(card->port[port - 1].ptr + offset);\ + return func(addr);\ } -DEFreadPortX (8) -DEFreadPortX (16) -DEFreadPortX (32) +DEFreadPortX (8, readb) +DEFreadPortX (16, readw) +DEFreadPortX (32, readl) static inline int nm256_writeBuffer8 (struct nm256_info *card, u8 *src, int port, int offset, int amt) { NM_FIX_PORT; - memcpy_toio (card->ports[port - 1] + offset, src, amt); + memcpy_toio (card->port[port - 1].ptr + offset, src, amt); return 0; } @@ -238,7 +274,7 @@ nm256_readBuffer8 (struct nm256_info *card, u8 *dst, int port, int offset, int amt) { NM_FIX_PORT; - memcpy_fromio (dst, card->ports[port - 1] + offset, amt); + memcpy_fromio (dst, card->port[port - 1].ptr + offset, amt); return 0; } diff --git a/drivers/sound/nm256_audio.c b/drivers/sound/nm256_audio.c index 0c3ee7b37..a066c65b9 100644 --- a/drivers/sound/nm256_audio.c +++ b/drivers/sound/nm256_audio.c @@ -1,27 +1,37 @@ -/* Audio driver for the NeoMagic 256AV and 256ZX chipsets in native - mode, with AC97 mixer support. - - Overall design and parts of this code stolen from vidc_*.c and - skeleton.c. - - Yeah, there are a lot of magic constants in here. You tell ME what - they are. I just get this stuff psychically, remember? - - This driver was written by someone who wishes to remain anonymous. - It is in the public domain, so share and enjoy. Try to make a profit - off of it; go on, I dare you. */ +/* + * Audio driver for the NeoMagic 256AV and 256ZX chipsets in native + * mode, with AC97 mixer support. + * + * Overall design and parts of this code stolen from vidc_*.c and + * skeleton.c. + * + * Yeah, there are a lot of magic constants in here. You tell ME what + * they are. I just get this stuff psychically, remember? + * + * This driver was written by someone who wishes to remain anonymous. + * It is in the public domain, so share and enjoy. Try to make a profit + * off of it; go on, I dare you. + */ #include <linux/config.h> #include <linux/pci.h> #include <linux/module.h> +#ifdef CONFIG_APM +#include <linux/apm_bios.h> +#endif #include "sound_config.h" #include "soundmodule.h" #include "nm256.h" #include "nm256_coeff.h" int nm256_debug = 0; +static int force_load = 0; -/* The size of the playback reserve. */ +/* + * The size of the playback reserve. When the playback buffer has less + * than NM256_PLAY_WMARK_SIZE bytes to output, we request a new + * buffer. + */ #define NM256_PLAY_WMARK_SIZE 512 static struct audio_driver nm256_audio_driver; @@ -29,16 +39,74 @@ static struct audio_driver nm256_audio_driver; static int nm256_grabInterrupt (struct nm256_info *card); static int nm256_releaseInterrupt (struct nm256_info *card); static void nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy); -static void nm256_interrupt_zx (int irq, void *dev_id, - struct pt_regs *dummy); +static void nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy); /* These belong in linux/pci.h. */ #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 #define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 +/* eeeew. */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) +#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start) +#else +#define RSRCADDRESS(dev,num) ((dev)->base_address[(num)] \ + & PCI_BASE_ADDRESS_MEM_MASK) + +#endif + /* List of cards. */ static struct nm256_info *nmcard_list; +/* Release the mapped-in memory for CARD. */ +static void +nm256_release_ports (struct nm256_info *card) +{ + int x; + + for (x = 0; x < 2; x++) { + if (card->port[x].ptr != NULL) { + u32 size = + card->port[x].end_offset - card->port[x].start_offset; + release_region ((unsigned long) card->port[x].ptr, size); + card->port[x].ptr = NULL; + } + } +} + +/* + * Map in the memory ports for CARD, if they aren't already mapped in + * and have been configured. If successful, a zero value is returned; + * otherwise any previously mapped-in areas are released and a non-zero + * value is returned. + * + * This is invoked twice, once for each port. Ideally it would only be + * called once, but we now need to map in the second port in order to + * check how much memory the card has on the 256ZX. + */ +static int +nm256_remap_ports (struct nm256_info *card) +{ + int x; + + for (x = 0; x < 2; x++) { + if (card->port[x].ptr == NULL && card->port[x].end_offset > 0) { + u32 physaddr + = card->port[x].physaddr + card->port[x].start_offset; + u32 size + = card->port[x].end_offset - card->port[x].start_offset; + + card->port[x].ptr = ioremap_nocache (physaddr, size); + + if (card->port[x].ptr == NULL) { + printk (KERN_ERR "NM256: Unable to remap port %d\n", x + 1); + nm256_release_ports (card); + return -1; + } + } + } + return 0; +} + /* Locate the card in our list. */ static struct nm256_info * nm256_find_card (int dev) @@ -52,8 +120,10 @@ nm256_find_card (int dev) return NULL; } -/* Ditto, but find the card struct corresponding to the mixer device DEV - instead. */ +/* + * Ditto, but find the card struct corresponding to the mixer device DEV + * instead. + */ static struct nm256_info * nm256_find_card_for_mixer (int dev) { @@ -81,11 +151,13 @@ static int samplerates[9] = { 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999 }; -/* Set the card samplerate, word size and stereo mode to correspond to - the settings in the CARD struct for the specified device in DEV. - We keep two separate sets of information, one for each device; the - hardware is not actually configured until a read or write is - attempted. */ +/* + * Set the card samplerate, word size and stereo mode to correspond to + * the settings in the CARD struct for the specified device in DEV. + * We keep two separate sets of information, one for each device; the + * hardware is not actually configured until a read or write is + * attempted. + */ int nm256_setInfo (int dev, struct nm256_info *card) @@ -113,24 +185,33 @@ nm256_setInfo (int dev, struct nm256_info *card) break; if (x < 8) { - u8 speedbits = ((x << 4) & NM_RATE_MASK) - | (card->sinfo[w].bits == 16 ? NM_RATE_BITS_16: 0) - | (card->sinfo[w].stereo ? NM_RATE_STEREO : 0); + u8 ratebits = ((x << 4) & NM_RATE_MASK); + if (card->sinfo[w].bits == 16) + ratebits |= NM_RATE_BITS_16; + if (card->sinfo[w].stereo) + ratebits |= NM_RATE_STEREO; card->sinfo[w].samplerate = samplerates[x]; + if (card->dev_for_play == dev && card->playing) { + if (nm256_debug) + printk (KERN_DEBUG "Setting play ratebits to 0x%x\n", + ratebits); nm256_loadCoefficient (card, 0, x); nm256_writePort8 (card, 2, - NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET, - speedbits); + NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET, + ratebits); } if (card->dev_for_record == dev && card->recording) { + if (nm256_debug) + printk (KERN_DEBUG "Setting record ratebits to 0x%x\n", + ratebits); nm256_loadCoefficient (card, 1, x); - nm256_writePort8 (card, 2, - NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET, - speedbits); + nm256_writePort8 (card, 2, + NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET, + ratebits); } return 0; } @@ -149,7 +230,7 @@ startPlay (struct nm256_info *card) /* Enable playback engine and interrupts. */ nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG, - NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN); + NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN); /* Enable both channels. */ nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG, 0x0); @@ -157,9 +238,11 @@ startPlay (struct nm256_info *card) } } -/* Request one chunk of AMT bytes from the recording device. When the - operation is complete, the data will be copied into BUFFER and the - function DMAbuf_inputintr will be invoked. */ +/* + * Request one chunk of AMT bytes from the recording device. When the + * operation is complete, the data will be copied into BUFFER and the + * function DMAbuf_inputintr will be invoked. + */ static void nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) @@ -167,11 +250,14 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) u32 endpos; int enableEngine = 0; u32 ringsize = card->recordBufferSize; + unsigned long flags; if (amt > (ringsize / 2)) { - /* Of course this won't actually work right, because the - caller is going to assume we will give what we got asked - for. */ + /* + * Of course this won't actually work right, because the + * caller is going to assume we will give what we got asked + * for. + */ printk (KERN_ERR "NM256: Read request too large: %d\n", amt); amt = ringsize / 2; } @@ -181,8 +267,12 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) return; } - /* If we're not currently recording, set up the start and end registers - for the recording engine. */ + save_flags (flags); + cli (); + /* + * If we're not currently recording, set up the start and end registers + * for the recording engine. + */ if (! card->recording) { card->recording = 1; if (nm256_grabInterrupt (card) == 0) { @@ -198,10 +288,16 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) } else { /* Not sure what else to do here. */ + restore_flags (flags); return; } } + /* + * If we happen to go past the end of the buffer a bit (due to a + * delayed interrupt) it's OK. So might as well set the watermark + * right at the end of the data we want. + */ endpos = card->abuf2 + ((card->curRecPos + amt) % ringsize); card->recBuf = buffer; @@ -211,6 +307,8 @@ nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt) if (enableEngine) nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN); + + restore_flags (flags); } /* Stop the play engine. */ @@ -219,7 +317,7 @@ stopPlay (struct nm256_info *card) { /* Shut off sound from both channels. */ nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG, - NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT); + NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT); /* Disable play engine. */ nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG, 0); if (card->playing) { @@ -246,18 +344,22 @@ stopRecord (struct nm256_info *card) } } -/* Ring buffers, man. That's where the hip-hop, wild-n-wooly action's at. - 1972? - - Write AMT bytes of BUFFER to the playback ring buffer, and start the - playback engine running. It will only accept up to 1/2 of the total - size of the ring buffer. */ +/* + * Ring buffers, man. That's where the hip-hop, wild-n-wooly action's at. + * 1972? (Well, I suppose it was cheep-n-easy to implement.) + * + * Write AMT bytes of BUFFER to the playback ring buffer, and start the + * playback engine running. It will only accept up to 1/2 of the total + * size of the ring buffer. No check is made that we're about to overwrite + * the currently-playing sample. + */ static void nm256_write_block (struct nm256_info *card, char *buffer, u32 amt) { u32 ringsize = card->playbackBufferSize; u32 endstop; + unsigned long flags; if (amt > (ringsize / 2)) { printk (KERN_ERR "NM256: Write request too large: %d\n", amt); @@ -273,6 +375,9 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt) card->requested_amt = amt; + save_flags (flags); + cli (); + if ((card->curPlayPos + amt) >= ringsize) { u32 rem = ringsize - card->curPlayPos; @@ -288,33 +393,40 @@ nm256_write_block (struct nm256_info *card, char *buffer, u32 amt) card->abuf1 + card->curPlayPos, amt); - /* Setup the start-n-stop-n-limit registers, and start that engine - goin'. - - Normally we just let it wrap around to avoid the click-click - action scene. */ + /* + * Setup the start-n-stop-n-limit registers, and start that engine + * goin'. + * + * Normally we just let it wrap around to avoid the click-click + * action scene. + */ if (! card->playing) { - /* The PBUFFER_END register in this case points to one "word" + /* The PBUFFER_END register in this case points to one sample before the end of the buffer. */ int w = (card->dev_for_play == card->dev[0] ? 0 : 1); - int wordsize = (card->sinfo[w].bits == 16 ? 2 : 1) - * (card->sinfo[w].stereo ? 2 : 1); + int sampsize = (card->sinfo[w].bits == 16 ? 2 : 1); + + if (card->sinfo[w].stereo) + sampsize *= 2; /* Need to set the not-normally-changing-registers up. */ nm256_writePort32 (card, 2, NM_PBUFFER_START, card->abuf1 + card->curPlayPos); nm256_writePort32 (card, 2, NM_PBUFFER_END, - card->abuf1 + ringsize - wordsize); + card->abuf1 + ringsize - sampsize); nm256_writePort32 (card, 2, NM_PBUFFER_CURRP, card->abuf1 + card->curPlayPos); } endstop = (card->curPlayPos + amt - NM256_PLAY_WMARK_SIZE) % ringsize; nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop); + if (! card->playing) startPlay (card); + + restore_flags (flags); } -/* We just got a card playback interrupt; process it. */ +/* We just got a card playback interrupt; process it. */ static void nm256_get_new_block (struct nm256_info *card) { @@ -332,13 +444,14 @@ nm256_get_new_block (struct nm256_info *card) amt -= card->curPlayPos; if (card->requested_amt > (amt + NM256_PLAY_WMARK_SIZE)) { - u32 endstop = + u32 endstop = card->curPlayPos + card->requested_amt - NM256_PLAY_WMARK_SIZE; nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop); - } else { + } + else { card->curPlayPos += card->requested_amt; /* Get a new block to write. This will eventually invoke - nm256_write_block (). */ + nm256_write_block () or stopPlay (). */ DMAbuf_outputintr (card->dev_for_play, 1); } } @@ -346,9 +459,11 @@ nm256_get_new_block (struct nm256_info *card) /* Ultra cheez-whiz. But I'm too lazy to grep headers. */ #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) -/* Read the last-recorded block from the ring buffer, copy it into the - saved buffer pointer, and invoke DMAuf_inputintr() with the recording - device. */ +/* + * Read the last-recorded block from the ring buffer, copy it into the + * saved buffer pointer, and invoke DMAuf_inputintr() with the recording + * device. + */ static void nm256_read_block (struct nm256_info *card) @@ -363,8 +478,10 @@ nm256_read_block (struct nm256_info *card) currptr = 0; } - /* This test is probably redundant; we shouldn't be here unless - it's true. */ + /* + * This test is probably redundant; we shouldn't be here unless + * it's true. + */ if (card->recording) { /* If we wrapped around, copy everything from the start of our recording buffer to the end of the buffer. */ @@ -394,52 +511,28 @@ nm256_read_block (struct nm256_info *card) } #undef MIN -/* Initialize the hardware and various other card data we'll need - later. */ +/* + * Initialize the hardware. + */ static void nm256_initHw (struct nm256_info *card) { - int x; - - card->playbackBufferSize = 16384; - card->recordBufferSize = 16384; - - card->coeffBuf = card->bufend - NM_MAX_COEFFICIENT; - card->abuf2 = card->coeffBuf - card->recordBufferSize; - card->abuf1 = card->abuf2 - card->playbackBufferSize; - card->allCoeffBuf = card->abuf2 - (NM_TOTAL_COEFF_COUNT * 4); - - /* Fixed setting. */ - card->mixer = NM_MIXER_BASE; - - card->playing = 0; - card->is_open_play = 0; - card->curPlayPos = 0; - - card->recording = 0; - card->is_open_record = 0; - card->curRecPos = 0; - - card->coeffsCurrent = 0; - - card->opencnt[0] = 0; card->opencnt[1] = 0; - /* Reset everything. */ - nm256_writePort8 (card, 2, 0, 0x11); - - /* Disable recording. */ - nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, 0); + nm256_writePort8 (card, 2, 0x0, 0x11); nm256_writePort16 (card, 2, 0x214, 0); - /* Reasonable default settings, but largely unnecessary. */ - for (x = 0; x < 2; x++) { - card->sinfo[x].bits = 8; - card->sinfo[x].stereo = 0; - card->sinfo[x].samplerate = 8000; - } + stopRecord (card); + stopPlay (card); } -/* Handle a potential interrupt for the device referred to by DEV_ID. */ +/* + * Handle a potential interrupt for the device referred to by DEV_ID. + * + * I don't like the cut-n-paste job here either between the two routines, + * but there are sufficient differences between the two interrupt handlers + * that parameterizing it isn't all that great either. (Could use a macro, + * I suppose...yucky bleah.) + */ static void nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy) @@ -458,14 +551,32 @@ nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy) /* Not ours. */ if (status == 0) { if (badintrcount++ > 1000) { - printk (KERN_ERR "NM256: Releasing interrupt, over 1000 invalid interrupts\n"); - nm256_releaseInterrupt (card); + /* + * I'm not sure if the best thing is to stop the card from + * playing or just release the interrupt (after all, we're in + * a bad situation, so doing fancy stuff may not be such a good + * idea). + * + * I worry about the card engine continuing to play noise + * over and over, however--that could become a very + * obnoxious problem. And we know that when this usually + * happens things are fairly safe, it just means the user's + * inserted a PCMCIA card and someone's spamming us with IRQ 9s. + */ + + if (card->playing) + stopPlay (card); + if (card->recording) + stopRecord (card); + badintrcount = 0; } return; } badintrcount = 0; + /* Rather boring; check for individual interrupts and process them. */ + if (status & NM_PLAYBACK_INT) { status &= ~NM_PLAYBACK_INT; NM_ACK_INT (card, NM_PLAYBACK_INT); @@ -503,6 +614,7 @@ nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy) nm256_writePort8 (card, 2, 0x400, cbyte & ~2); } + /* Unknown interrupt. */ if (status) { printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n", status); @@ -511,8 +623,11 @@ nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy) } } -/* Handle a potential interrupt for the device referred to by DEV_ID. - This handler is for the 256ZX. */ +/* + * Handle a potential interrupt for the device referred to by DEV_ID. + * This handler is for the 256ZX, and is very similar to the non-ZX + * routine. + */ static void nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy) @@ -532,13 +647,33 @@ nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy) if (status == 0) { if (badintrcount++ > 1000) { printk (KERN_ERR "NM256: Releasing interrupt, over 1000 invalid interrupts\n"); - nm256_releaseInterrupt (card); + /* + * I'm not sure if the best thing is to stop the card from + * playing or just release the interrupt (after all, we're in + * a bad situation, so doing fancy stuff may not be such a good + * idea). + * + * I worry about the card engine continuing to play noise + * over and over, however--that could become a very + * obnoxious problem. And we know that when this usually + * happens things are fairly safe, it just means the user's + * inserted a PCMCIA card and someone's spamming us with + * IRQ 9s. + */ + + if (card->playing) + stopPlay (card); + if (card->recording) + stopRecord (card); + badintrcount = 0; } return; } badintrcount = 0; + /* Rather boring; check for individual interrupts and process them. */ + if (status & NM2_PLAYBACK_INT) { status &= ~NM2_PLAYBACK_INT; NM2_ACK_INT (card, NM2_PLAYBACK_INT); @@ -575,6 +710,7 @@ nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy) nm256_writePort8 (card, 2, 0x400, cbyte & ~2); } + /* Unknown interrupt. */ if (status) { printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n", status); @@ -583,7 +719,9 @@ nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy) } } -/* Request our interrupt. */ +/* + * Request our interrupt. + */ static int nm256_grabInterrupt (struct nm256_info *card) { @@ -597,7 +735,9 @@ nm256_grabInterrupt (struct nm256_info *card) return 0; } -/* Release our interrupt. */ +/* + * Release our interrupt. + */ static int nm256_releaseInterrupt (struct nm256_info *card) { @@ -612,6 +752,11 @@ nm256_releaseInterrupt (struct nm256_info *card) return 0; } +/* + * Waits for the mixer to become ready to be written; returns a zero value + * if it timed out. + */ + static int nm256_isReady (struct ac97_hwint *dev) { @@ -626,26 +771,25 @@ nm256_isReady (struct ac97_hwint *dev) return 0; } - if (card->rev == REV_NM256AV) { - testaddr = 0xa06; - testb = 0x0100; - } else if (card->rev == REV_NM256ZX) { - testaddr = 0xa08; - testb = 0x0800; - } else { - return -1; - } + testaddr = card->mixer_status_offset; + testb = card->mixer_status_mask; - while (t2-- > 0) { - if ((nm256_readPort16 (card, 2, testaddr) & testb) == 0) { + /* + * Loop around waiting for the mixer to become ready. + */ + while (! done && t2-- > 0) { + if ((nm256_readPort16 (card, 2, testaddr) & testb) == 0) done = 1; - break; - } - udelay (100); + else + udelay (100); } return done; } +/* + * Return the contents of the AC97 mixer register REG. Returns a positive + * value if successful, or a negative error code. + */ static int nm256_readAC97Reg (struct ac97_hwint *dev, u8 reg) { @@ -661,6 +805,7 @@ nm256_readAC97Reg (struct ac97_hwint *dev, u8 reg) nm256_isReady (dev); res = nm256_readPort16 (card, 2, card->mixer + reg); + /* Magic delay. Bleah yucky. */ udelay (1000); return res; } @@ -668,6 +813,10 @@ nm256_readAC97Reg (struct ac97_hwint *dev, u8 reg) return -EINVAL; } +/* + * Writes VALUE to AC97 mixer register REG. Returns 0 if successful, or + * a negative error code. + */ static int nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value) { @@ -706,6 +855,13 @@ nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value) return ! done; } +/* + * Initial register values to be written to the AC97 mixer. + * While most of these are identical to the reset values, we do this + * so that we have most of the register contents cached--this avoids + * reading from the mixer directly (which seems to be problematic, + * probably due to ignorance). + */ struct initialValues { unsigned short port; @@ -714,23 +870,24 @@ struct initialValues static struct initialValues nm256_ac97_initial_values[] = { - { 0x0002, 0x8000 }, - { 0x0004, 0x0000 }, - { 0x0006, 0x0000 }, - { 0x000A, 0x0000 }, - { 0x000C, 0x0008 }, - { 0x000E, 0x8008 }, - { 0x0010, 0x8808 }, - { 0x0012, 0x8808 }, - { 0x0014, 0x8808 }, - { 0x0016, 0x8808 }, - { 0x0018, 0x0808 }, - { 0x001A, 0x0000 }, - { 0x001C, 0x0B0B }, - { 0x0020, 0x0000 }, + { AC97_MASTER_VOL_STEREO, 0x8000 }, + { AC97_HEADPHONE_VOL, 0x8000 }, + { AC97_MASTER_VOL_MONO, 0x0000 }, + { AC97_PCBEEP_VOL, 0x0000 }, + { AC97_PHONE_VOL, 0x0008 }, + { AC97_MIC_VOL, 0x8000 }, + { AC97_LINEIN_VOL, 0x8808 }, + { AC97_CD_VOL, 0x8808 }, + { AC97_VIDEO_VOL, 0x8808 }, + { AC97_AUX_VOL, 0x8808 }, + { AC97_PCMOUT_VOL, 0x0808 }, + { AC97_RECORD_SELECT, 0x0000 }, + { AC97_RECORD_GAIN, 0x0B0B }, + { AC97_GENERAL_PURPOSE, 0x0000 }, { 0xffff, 0xffff } }; +/* Initialize the AC97 into a known state. */ static int nm256_resetAC97 (struct ac97_hwint *dev) { @@ -742,22 +899,28 @@ nm256_resetAC97 (struct ac97_hwint *dev) return -EINVAL; } - /* Reset the card. 'Tis magic! */ + /* Reset the mixer. 'Tis magic! */ nm256_writePort8 (card, 2, 0x6c0, 1); nm256_writePort8 (card, 2, 0x6cc, 0x87); nm256_writePort8 (card, 2, 0x6cc, 0x80); nm256_writePort8 (card, 2, 0x6cc, 0x0); - for (x = 0; nm256_ac97_initial_values[x].port != 0xffff; x++) { - ac97_put_register (dev, - nm256_ac97_initial_values[x].port, - nm256_ac97_initial_values[x].value); + if (! card->mixer_values_init) { + for (x = 0; nm256_ac97_initial_values[x].port != 0xffff; x++) { + ac97_put_register (dev, + nm256_ac97_initial_values[x].port, + nm256_ac97_initial_values[x].value); + card->mixer_values_init = 1; + } } return 0; } -/* We don't do anything special here. */ +/* + * We don't do anything particularly special here; it just passes the + * mixer ioctl to the AC97 driver. + */ static int nm256_default_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg) { @@ -774,7 +937,12 @@ static struct mixer_operations nm256_mixer_operations = { nm256_default_mixer_ioctl }; -/* I "love" C sometimes. Got braces? */ +/* + * Default settings for the OSS mixer. These are set last, after the + * mixer is initialized. + * + * I "love" C sometimes. Got braces? + */ static struct ac97_mixer_value_list mixer_defaults[] = { { SOUND_MIXER_VOLUME, { { 85, 85 } } }, { SOUND_MIXER_SPEAKER, { { 100 } } }, @@ -783,6 +951,8 @@ static struct ac97_mixer_value_list mixer_defaults[] = { { -1, { { 0, 0 } } } }; + +/* Installs the AC97 mixer into CARD. */ static int nm256_install_mixer (struct nm256_info *card) { @@ -812,36 +982,67 @@ nm256_install_mixer (struct nm256_info *card) return 0; } -/* See if the signature left by the NM256 BIOS is intact; if so, we use - the associated address as the end of our buffer. */ +/* Perform a full reset on the hardware; this is invoked when an APM + resume event occurs. */ static void -nm256_peek_for_sig (struct nm256_info *card, u32 port1addr) +nm256_full_reset (struct nm256_info *card) { - char *temp = ioremap_nocache (port1addr + card->port1_end - 0x0400, 16); + nm256_initHw (card); + ac97_reset (&(card->mdev)); +} + +/* + * See if the signature left by the NM256 BIOS is intact; if so, we use + * the associated address as the end of our audio buffer in the video + * RAM. + */ + +static void +nm256_peek_for_sig (struct nm256_info *card) +{ + u32 port1offset + = card->port[0].physaddr + card->port[0].end_offset - 0x0400; + /* The signature is located 1K below the end of video RAM. */ + char *temp = ioremap_nocache (port1offset, 16); + /* Default buffer end is 5120 bytes below the top of RAM. */ + u32 default_value = card->port[0].end_offset - 0x1400; u32 sig; + /* Install the default value first, so we don't have to repeatedly + do it if there is a problem. */ + card->port[0].end_offset = default_value; + if (temp == NULL) { printk (KERN_ERR "NM256: Unable to scan for card signature in video RAM\n"); return; } - memcpy_fromio (&sig, temp, sizeof (u32)); - if ((sig & 0xffff0000) == 0x4e4d0000) { - memcpy_fromio (&(card->bufend), temp + 4, sizeof (u32)); + sig = readl (temp); + if ((sig & NM_SIG_MASK) == NM_SIGNATURE) { + u32 pointer = readl (temp + 4); + + /* + * If it's obviously invalid, don't use it (the port already has a + * suitable default value set). + */ + if (pointer != 0xffffffff) + card->port[0].end_offset = pointer; + printk (KERN_INFO "NM256: Found card signature in video RAM: 0x%x\n", - card->bufend); + pointer); } release_region ((unsigned long) temp, 16); } -/* Install a driver for the soundcard referenced by PCIDEV. */ +/* + * Install a driver for the PCI device referenced by PCIDEV. + * VERSTR is a human-readable version string. + */ static int nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) { struct nm256_info *card; - u32 port1addr = pcidev->resource[0].start; - u32 port2addr = pcidev->resource[1].start; int x; card = kmalloc (sizeof (struct nm256_info), GFP_KERNEL); @@ -855,52 +1056,85 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) card->recording = 0; card->rev = rev; - /* The NM256 has two memory ports. The first port is nothing - more than a chunk of video RAM, which is used as the I/O ring - buffer. The second port has the actual juicy stuff (like the - mixer and the playback engine control registers). */ + /* Init the memory port info. */ + for (x = 0; x < 2; x++) { + card->port[x].physaddr = RSRCADDRESS (pcidev, x); + card->port[x].ptr = NULL; + card->port[x].start_offset = 0; + card->port[x].end_offset = 0; + } - card->ports[1] = ioremap_nocache (port2addr, NM_PORT2_SIZE); + /* Port 2 is easy. */ + card->port[1].start_offset = 0; + card->port[1].end_offset = NM_PORT2_SIZE; - if (card->ports[1] == NULL) { - printk (KERN_ERR "NM256: Unable to remap port 2\n"); + /* Yuck. But we have to map in port 2 so we can check how much RAM the + card has. */ + if (nm256_remap_ports (card)) { kfree_s (card, sizeof (struct nm256_info)); return 0; } + /* + * The NM256 has two memory ports. The first port is nothing + * more than a chunk of video RAM, which is used as the I/O ring + * buffer. The second port has the actual juicy stuff (like the + * mixer and the playback engine control registers). + */ + if (card->rev == REV_NM256AV) { - card->port1_end = 2560 * 1024; + /* Ok, try to see if this is a non-AC97 version of the hardware. */ + int pval = nm256_readPort16 (card, 2, NM_MIXER_PRESENCE); + if ((pval & NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) { + if (! force_load) { + printk (KERN_ERR "NM256: This doesn't look to me like the AC97-compatible version.\n"); + printk (KERN_ERR " You can force the driver to load by passing in the module\n"); + printk (KERN_ERR " parameter:\n"); + printk (KERN_ERR " force_ac97 = 1\n"); + printk (KERN_ERR "\n"); + printk (KERN_ERR " More likely, you should be using the appropriate SB-16 or\n"); + printk (KERN_ERR " CS4232 driver instead. (If your BIOS has settings for\n"); + printk (KERN_ERR " IRQ and/or DMA for the sound card, this is *not* the correct\n"); + printk (KERN_ERR " driver to use.)\n"); + nm256_release_ports (card); + kfree_s (card, sizeof (struct nm256_info)); + return 0; + } + else { + printk (KERN_INFO "NM256: Forcing driver load as per user request.\n"); + } + } + else { + /* printk (KERN_INFO "NM256: Congratulations. You're not running Eunice.\n")*/; + } + card->port[0].end_offset = 2560 * 1024; card->introutine = nm256_interrupt; + card->mixer_status_offset = NM_MIXER_STATUS_OFFSET; + card->mixer_status_mask = NM_MIXER_READY_MASK; } else { + /* Not sure if there is any relevant detect for the ZX or not. */ if (nm256_readPort8 (card, 2, 0xa0b) != 0) - card->port1_end = 6144 * 1024; + card->port[0].end_offset = 6144 * 1024; else - card->port1_end = 4096 * 1024; + card->port[0].end_offset = 4096 * 1024; card->introutine = nm256_interrupt_zx; + card->mixer_status_offset = NM2_MIXER_STATUS_OFFSET; + card->mixer_status_mask = NM2_MIXER_READY_MASK; } - /* Default value. */ - card->bufend = card->port1_end - 0x1400; - - if (buffertop >= 98304 && buffertop < card->port1_end) - card->bufend = buffertop; + if (buffertop >= 98304 && buffertop < card->port[0].end_offset) + card->port[0].end_offset = buffertop; else - nm256_peek_for_sig (card, port1addr); + nm256_peek_for_sig (card); - card->port1_start = card->bufend - 98304; + card->port[0].start_offset = card->port[0].end_offset - 98304; printk (KERN_INFO "NM256: Mapping port 1 from 0x%x - 0x%x\n", - card->port1_start, card->port1_end); - - card->ports[0] = - ioremap_nocache (port1addr + card->port1_start, - card->port1_end - card->port1_start); + card->port[0].start_offset, card->port[0].end_offset); - if (card->ports[0] == NULL) { - printk (KERN_ERR "NM256: Unable to remap port 1\n"); - release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + if (nm256_remap_ports (card)) { kfree_s (card, sizeof (struct nm256_info)); return 0; } @@ -911,9 +1145,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) card->has_irq = 0; if (nm256_grabInterrupt (card) != 0) { - release_region ((unsigned long) card->ports[0], - card->port1_end - card->port1_start); - release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + nm256_release_ports (card); kfree_s (card, sizeof (struct nm256_info)); return 0; } @@ -924,10 +1156,36 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) * Init the board. */ + card->playbackBufferSize = 16384; + card->recordBufferSize = 16384; + + card->coeffBuf = card->port[0].end_offset - NM_MAX_COEFFICIENT; + card->abuf2 = card->coeffBuf - card->recordBufferSize; + card->abuf1 = card->abuf2 - card->playbackBufferSize; + card->allCoeffBuf = card->abuf2 - (NM_TOTAL_COEFF_COUNT * 4); + + /* Fixed setting. */ + card->mixer = NM_MIXER_OFFSET; + card->mixer_values_init = 0; + + card->is_open_play = 0; + card->is_open_record = 0; + + card->coeffsCurrent = 0; + + card->opencnt[0] = 0; card->opencnt[1] = 0; + + /* Reasonable default settings, but largely unnecessary. */ + for (x = 0; x < 2; x++) { + card->sinfo[x].bits = 8; + card->sinfo[x].stereo = 0; + card->sinfo[x].samplerate = 8000; + } + nm256_initHw (card); for (x = 0; x < 2; x++) { - if ((card->dev[x] = + if ((card->dev[x] = sound_install_audiodrv(AUDIO_DRIVER_VERSION, "NM256", &nm256_audio_driver, sizeof(struct audio_driver), @@ -940,9 +1198,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) } else { printk(KERN_ERR "NM256: Too many PCM devices available\n"); - release_region ((unsigned long) card->ports[0], - card->port1_end - card->port1_start); - release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + nm256_release_ports (card); kfree_s (card, sizeof (struct nm256_info)); return 0; } @@ -964,6 +1220,48 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr) return 1; } + +#ifdef CONFIG_APM +/* + * APM event handler, so the card is properly reinitialized after a power + * event. + */ +static int +handle_apm_event (apm_event_t event) +{ + static int down = 0; + + switch (event) + { + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + down++; + break; + case APM_NORMAL_RESUME: + case APM_CRITICAL_RESUME: + if (down) + { + struct nm256_info *crd; + + down = 0; + for (crd = nmcard_list; crd != NULL; crd = crd->next_card) + { + int playing = crd->playing; + nm256_full_reset (crd); + /* + * A little ugly, but that's ok; pretend the + * block we were playing is done. + */ + if (playing) + DMAbuf_outputintr (crd->dev_for_play, 1); + } + } + break; + } + return 0; +} +#endif + /* * This loop walks the PCI configuration database and finds where * the sound cards are. @@ -993,6 +1291,10 @@ init_nm256(void) if (count == 0) return -ENODEV; +#ifdef CONFIG_APM + apm_register_callback (&handle_apm_event); +#endif + printk (KERN_INFO "Done installing NM256 audio driver.\n"); return 0; } @@ -1028,10 +1330,13 @@ nm256_audio_open(int dev, int mode) if (! ((mode & OPEN_READ) || (mode & OPEN_WRITE))) return -EIO; - /* If it's open for both read and write, and the card's currently - being read or written to, then do the opposite of what has - already been done. Otherwise, don't specify any mode until the - user actually tries to do I/O. */ + /* + * If it's open for both read and write, and the card's currently + * being read or written to, then do the opposite of what has + * already been done. Otherwise, don't specify any mode until the + * user actually tries to do I/O. (Some programs open the device + * for both read and write, but only actually do reading or writing.) + */ if ((mode & OPEN_WRITE) && (mode & OPEN_READ)) { if (card->is_open_play) @@ -1105,6 +1410,7 @@ nm256_audio_close(int dev) } } +/* Standard ioctl handler. */ static int nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg) { @@ -1122,6 +1428,11 @@ nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg) else w = 1; + /* + * The code here is messy. There are probably better ways to do + * it. (It should be possible to handle it the same way the AC97 mixer + * is done.) + */ switch (cmd) { case SOUND_PCM_WRITE_RATE: @@ -1193,8 +1504,12 @@ nm256_audio_ioctl(int dev, unsigned int cmd, caddr_t arg) return put_user(ret, (int *) arg); } -/* Given the dev DEV and an associated physical buffer PHYSBUF, return - a pointer to the actual buffer in kernel space. */ +/* + * Given the sound device DEV and an associated physical buffer PHYSBUF, + * return a pointer to the actual buffer in kernel space. + * + * This routine should exist as part of the soundcore routines. + */ static char * nm256_getDMAbuffer (int dev, unsigned long physbuf) @@ -1238,9 +1553,10 @@ nm256_audio_output_block(int dev, unsigned long physbuf, } } +/* Ditto, but do recording instead. */ static void nm256_audio_start_input(int dev, unsigned long physbuf, int count, - int intrflag) + int intrflag) { struct nm256_info *card = nm256_find_card (dev); @@ -1252,6 +1568,12 @@ nm256_audio_start_input(int dev, unsigned long physbuf, int count, } } +/* + * Prepare for inputting samples to DEV. + * Each requested buffer will be BSIZE byes long, with a total of + * BCOUNT buffers. + */ + static int nm256_audio_prepare_for_input(int dev, int bsize, int bcount) { @@ -1278,6 +1600,7 @@ nm256_audio_prepare_for_input(int dev, int bsize, int bcount) * 2. We get a write buffer without dma_mode setup (dmabuf.c:1152) * 3. We restart a transfer (dmabuf.c:1324) */ + static int nm256_audio_prepare_for_output(int dev, int bsize, int bcount) { @@ -1342,12 +1665,13 @@ static int loaded = 0; MODULE_PARM (usecache, "i"); MODULE_PARM (buffertop, "i"); MODULE_PARM (nm256_debug, "i"); +MODULE_PARM (force_load, "i"); int init_module (void) { nmcard_list = NULL; - printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.0\n"); + printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1\n"); if (init_nm256 () == 0) { SOUND_LOCK; @@ -1372,9 +1696,7 @@ cleanup_module (void) stopRecord (card); if (card->has_irq) free_irq (card->irq, card); - release_region ((unsigned long) card->ports[0], - card->port1_end - card->port1_start); - release_region ((unsigned long) card->ports[1], NM_PORT2_SIZE); + nm256_release_ports (card); sound_unload_mixerdev (card->mixer_oss_dev); sound_unload_audiodev (card->dev[0]); sound_unload_audiodev (card->dev[1]); @@ -1383,6 +1705,9 @@ cleanup_module (void) } nmcard_list = NULL; } +#ifdef CONFIG_APM + apm_unregister_callback (&handle_apm_event); +#endif } #endif diff --git a/drivers/sound/nm256_coeff.h b/drivers/sound/nm256_coeff.h index c8fc7ecbe..0ceecc200 100644 --- a/drivers/sound/nm256_coeff.h +++ b/drivers/sound/nm256_coeff.h @@ -4622,7 +4622,8 @@ nm256_getStartOffset (u8 which) } static void -nm256_loadOneCoefficient (struct nm256_info *card, u32 port, u16 which) +nm256_loadOneCoefficient (struct nm256_info *card, int devnum, u32 port, + u16 which) { u32 coeffBuf = (which < 8) ? card->coeffBuf : card->allCoeffBuf; u16 offset = nm256_getStartOffset (which); @@ -4631,11 +4632,14 @@ nm256_loadOneCoefficient (struct nm256_info *card, u32 port, u16 which) card->coeffsCurrent = 0; if (nm256_debug) - printk (KERN_INFO "NM256: Loading coefficient buffer 0x%x-0x%x with coefficient %d\n", - coeffBuf, coeffBuf + size - 1, which); + printk (KERN_INFO "NM256: Loading coefficient buffer 0x%x-0x%x with coefficient %d, size %d, port 0x%x\n", + coeffBuf, coeffBuf + size - 1, which, size, port); nm256_writeBuffer8 (card, coefficients + offset, 1, coeffBuf, size); nm256_writePort32 (card, 2, port + 0, coeffBuf); - nm256_writePort32 (card, 2, port + 4, coeffBuf + size - 1); + /* ??? Record seems to behave differently than playback. */ + if (devnum == 0) + size--; + nm256_writePort32 (card, 2, port + 4, coeffBuf + size); } static void @@ -4663,7 +4667,7 @@ nm256_loadCoefficient (struct nm256_info *card, int which, int number) number += 8; if (! nm256_cachedCoefficients (card)) - nm256_loadOneCoefficient (card, addrs[which], number); + nm256_loadOneCoefficient (card, which, addrs[which], number); else { u32 base = card->allCoeffBuf; u32 offset = nm256_getStartOffset (number); diff --git a/drivers/usb/acm.c b/drivers/usb/acm.c index 3ecea982e..a47920d00 100644 --- a/drivers/usb/acm.c +++ b/drivers/usb/acm.c @@ -486,8 +486,8 @@ static void acm_disconnect(struct usb_device *dev) if (!acm->present) return; - printk("disconnecting\n"); - + acm->active=0; + acm->present=0; if (acm->writing){ usb_terminate_bulk(acm->dev, acm->writetransfer); acm->writing=0; @@ -498,8 +498,6 @@ static void acm_disconnect(struct usb_device *dev) } usb_release_irq(acm->dev,acm->ctrltransfer, acm->ctrlpipe); //BUG: What to do if a device is open?? Notify process or not allow cleanup? - acm->active=0; - acm->present=0; kfree(acm->writebuffer); kfree(acm->readbuffer); diff --git a/drivers/usb/cpia.c b/drivers/usb/cpia.c index 976ab02da..e6515c710 100644 --- a/drivers/usb/cpia.c +++ b/drivers/usb/cpia.c @@ -52,7 +52,7 @@ static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) ptep = pte_offset(pmd, adr); pte = *ptep; if (pte_present(pte)) - ret = (pte_page(pte) | (adr & (PAGE_SIZE-1))); + ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1)); } } MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret)); diff --git a/drivers/usb/ezusb.c b/drivers/usb/ezusb.c index 8aabddd17..c64335699 100644 --- a/drivers/usb/ezusb.c +++ b/drivers/usb/ezusb.c @@ -1073,11 +1073,8 @@ void ezusb_cleanup(void) #ifdef MODULE -int minor = 192; - int init_module(void) { - ezusb_misc.minor = minor; return ezusb_init(); } diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c index 59a539867..98c1c540c 100644 --- a/drivers/usb/hub.c +++ b/drivers/usb/hub.c @@ -15,6 +15,7 @@ #include <linux/spinlock.h> #include <asm/uaccess.h> +#include <asm/byteorder.h> #include "usb.h" #include "hub.h" @@ -51,16 +52,16 @@ static int usb_set_port_feature(struct usb_device *dev, int port, int feature) static int usb_get_hub_status(struct usb_device *dev, void *data) { - /* FIXME: Don't hardcode 4 */ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0, data, 4, HZ); + USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0, + data, sizeof(struct usb_hub_status), HZ); } static int usb_get_port_status(struct usb_device *dev, int port, void *data) { - /* FIXME: Don't hardcode 4 */ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port, data, 4, HZ); + USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port, + data, sizeof(struct usb_hub_status), HZ); } /* @@ -101,6 +102,7 @@ static int usb_hub_configure(struct usb_hub *hub) unsigned char buffer[4], *bitmap; struct usb_hub_descriptor *descriptor; struct usb_descriptor_header *header; + struct usb_hub_status *hubsts; int i; /* Set it to the first configuration */ @@ -121,7 +123,7 @@ static int usb_hub_configure(struct usb_hub *hub) descriptor = (struct usb_hub_descriptor *)bitmap; hub->nports = dev->maxchild = descriptor->bNbrPorts; - printk(KERN_INFO "hub: %d-port%s detected\n", hub->nports, + printk(KERN_INFO "hub: %d port%s detected\n", hub->nports, (hub->nports == 1) ? "" : "s"); switch (descriptor->wHubCharacteristics & HUB_CHAR_LPSM) { @@ -144,14 +146,14 @@ static int usb_hub_configure(struct usb_hub *hub) switch (descriptor->wHubCharacteristics & HUB_CHAR_OCPM) { case 0x00: - printk(KERN_INFO "hub: global over current protection\n"); + printk(KERN_INFO "hub: global over-current protection\n"); break; case 0x08: - printk(KERN_INFO "hub: individual port over current protection\n"); + printk(KERN_INFO "hub: individual port over-current protection\n"); break; case 0x10: case 0x18: - printk(KERN_INFO "hub: no over current protection\n"); + printk(KERN_INFO "hub: no over-current protection\n"); break; } @@ -171,11 +173,12 @@ static int usb_hub_configure(struct usb_hub *hub) if (usb_get_hub_status(dev, buffer)) return -1; + hubsts = (struct usb_hub_status *)buffer; printk(KERN_INFO "hub: local power source is %s\n", - (buffer[0] & 1) ? "lost (inactive)" : "good"); + (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good"); - printk(KERN_INFO "hub: %sover current condition exists\n", - (buffer[0] & 2) ? "" : "no "); + printk(KERN_INFO "hub: %sover-current condition exists\n", + (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no "); /* Enable power to the ports */ printk(KERN_INFO "hub: enabling power on all ports\n"); @@ -292,7 +295,7 @@ static void hub_disconnect(struct usb_device *dev) static void usb_hub_port_connect_change(struct usb_device *hub, int port) { struct usb_device *usb; - unsigned char buf[4]; + struct usb_port_status portsts; unsigned short portstatus, portchange; /* Disconnect anything that may have been there */ @@ -304,13 +307,13 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port) wait_ms(50); /* FIXME: This is from the *BSD stack, thanks! :) */ /* Check status */ - if (usb_get_port_status(hub, port + 1, buf)) { + if (usb_get_port_status(hub, port + 1, &portsts)) { printk(KERN_ERR "get_port_status failed\n"); return; } - portstatus = le16_to_cpup((unsigned short *)buf + 0); - portchange = le16_to_cpup((unsigned short *)buf + 1); + portstatus = le16_to_cpu(portsts.wPortStatus); + portchange = le16_to_cpu(portsts.wPortChange); /* If it's not in CONNECT and ENABLE state, we're done */ if ((!(portstatus & USB_PORT_STAT_CONNECTION)) && @@ -373,16 +376,16 @@ static void usb_hub_events(void) spin_unlock_irqrestore(&hub_event_lock, flags); for (i = 0; i < hub->nports; i++) { - unsigned char buf[4]; + struct usb_port_status portsts; unsigned short portstatus, portchange; - if (usb_get_port_status(dev, i + 1, buf)) { + if (usb_get_port_status(dev, i + 1, &portsts)) { printk(KERN_ERR "get_port_status failed\n"); continue; } - portstatus = le16_to_cpup((unsigned short *)buf + 0); - portchange = le16_to_cpup((unsigned short *)buf + 1); + portstatus = le16_to_cpu(portsts.wPortStatus); + portchange = le16_to_cpu(portsts.wPortChange); if (portchange & USB_PORT_STAT_C_CONNECTION) { printk(KERN_INFO "hub: port %d connection change\n", @@ -415,9 +418,8 @@ static void usb_hub_events(void) usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET); } - - } - } + } /* end for i */ + } /* end while (1) */ he_unlock: spin_unlock_irqrestore(&hub_event_lock, flags); diff --git a/drivers/usb/hub.h b/drivers/usb/hub.h index 49c531d30..c95a07d74 100644 --- a/drivers/usb/hub.h +++ b/drivers/usb/hub.h @@ -4,7 +4,7 @@ #include <linux/list.h> /* - * Hub feature numbers + * Hub Class feature numbers */ #define C_HUB_LOCAL_POWER 0 #define C_HUB_OVER_CURRENT 1 @@ -25,7 +25,12 @@ #define USB_PORT_FEAT_C_OVER_CURRENT 19 #define USB_PORT_FEAT_C_RESET 20 -/* wPortStatus */ +struct usb_port_status { + __u16 wPortStatus; + __u16 wPortChange; +} __attribute__ ((packed)); + +/* wPortStatus bits */ #define USB_PORT_STAT_CONNECTION 0x0001 #define USB_PORT_STAT_ENABLE 0x0002 #define USB_PORT_STAT_SUSPEND 0x0004 @@ -34,7 +39,7 @@ #define USB_PORT_STAT_POWER 0x0100 #define USB_PORT_STAT_LOW_SPEED 0x0200 -/* wPortChange */ +/* wPortChange bits */ #define USB_PORT_STAT_C_CONNECTION 0x0001 #define USB_PORT_STAT_C_ENABLE 0x0002 #define USB_PORT_STAT_C_SUSPEND 0x0004 @@ -46,6 +51,20 @@ #define HUB_CHAR_COMPOUND 0x0004 #define HUB_CHAR_OCPM 0x0018 +struct usb_hub_status { + __u16 wHubStatus; + __u16 wHubChange; +} __attribute__ ((packed)); + +/* + *Hub Status & Hub Change bit masks + */ +#define HUB_STATUS_LOCAL_POWER 0x0001 +#define HUB_STATUS_OVERCURRENT 0x0002 + +#define HUB_CHANGE_LOCAL_POWER 0x0001 +#define HUB_CHANGE_OVERCURRENT 0x0002 + /* Hub descriptor */ struct usb_hub_descriptor { __u8 bLength; @@ -103,4 +122,3 @@ struct usb_hub { }; #endif - diff --git a/drivers/usb/ohci-hcd.c b/drivers/usb/ohci-hcd.c index 3dc6d74ca..3345e12be 100644 --- a/drivers/usb/ohci-hcd.c +++ b/drivers/usb/ohci-hcd.c @@ -14,9 +14,8 @@ * [ Open Host Controller Interface driver for USB. ] * [ (C) Copyright 1999 Linus Torvalds (uhci.c) ] * [ (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com> ] - * [ _Log: ohci-hcd.c,v _ - * [ Revision 1.1 1999/04/05 08:32:30 greg ] * + * v4.3 1999/10/27 multiple HCs, bulk_request * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl. * v4.0 1999/08/18 @@ -48,6 +47,7 @@ #include <linux/errno.h> #include <linux/timer.h> #include <linux/spinlock.h> +#include <linux/list.h> #include <asm/io.h> #include <asm/irq.h> @@ -61,6 +61,7 @@ static int handle_apm_event(apm_event_t event); static int apm_resume = 0; #endif +static LIST_HEAD(ohci_hcd_list); static int ohci_link_ed(struct ohci * ohci, struct usb_ohci_ed *ed); static int sohci_kill_isoc (struct usb_isoc_desc *id); @@ -85,10 +86,11 @@ OHCI_DEBUG(printk("******* dev: devnum: %4x, slow: %4x, maxpacketsize: %4x\n",us **** Interface functions ***********************************************/ -static int sohci_blocking_handler(void * ohci_in, struct usb_ohci_ed *ed, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) +static int sohci_blocking_handler(void * ohci_in, struct usb_ohci_td *td, void * data, int data_len, int dlen, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) { + struct usb_ohci_ed *ed = td->ed; if(lw0 != NULL) { - if(USB_ST_CRC < 0 && (status == USB_ST_DATAUNDERRUN || status == USB_ST_NOERROR)) + if(0 < 0 && (status == USB_ST_DATAUNDERRUN || status == USB_ST_NOERROR)) ((struct ohci_state * )lw0)->status = data_len; else ((struct ohci_state * )lw0)->status = status; @@ -107,9 +109,9 @@ static int sohci_blocking_handler(void * ohci_in, struct usb_ohci_ed *ed, void * return 0; } -static int sohci_int_handler(void * ohci_in, struct usb_ohci_ed *ed, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) +static int sohci_int_handler(void * ohci_in, struct usb_ohci_td *td, void * data, int data_len, int dlen, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) { - + struct usb_ohci_ed *ed = td->ed; struct ohci * ohci = ohci_in; usb_device_irq handler=(void *) lw0; void *dev_id = (void *) lw1; @@ -127,9 +129,30 @@ static int sohci_int_handler(void * ohci_in, struct usb_ohci_ed *ed, void * data return 0; } -static int sohci_iso_handler(void * ohci_in, struct usb_ohci_ed *ed, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) { +static int sohci_ret_handler(void * ohci_in, struct usb_ohci_td *td, void * data, int data_len, int dlen, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) +{ + struct usb_ohci_ed *ed = td->ed; + struct ohci * ohci = ohci_in; + usb_device_irq handler=(void *) lw0; + void *dev_id = (void *) lw1; + int ret; + + OHCI_DEBUG({ int i; printk("USB HC RET <<<: %x: data(%d):", ed->hwINFO, data_len);) + OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);) + OHCI_DEBUG( printk(" ret_status: %x\n", status); }) + + ret = handler(status, data, data_len, dev_id); + if(ret == 0) return 0; /* 0 .. do not requeue */ + if(status > 0) return -1; /* error occured do not requeue ? */ + ohci_trans_req(ohci, ed, 0, NULL, data, dlen, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id, td->type & 0x7, sohci_ret_handler); /* requeue int request */ + + return 0; +} + +static int sohci_iso_handler(void * ohci_in, struct usb_ohci_td *td, void * data, int data_len, int dlen, int status, __OHCI_BAG lw0, __OHCI_BAG lw1) { // struct ohci * ohci = ohci_in; + struct usb_ohci_ed *ed = td->ed; unsigned int ix = (unsigned int) lw0; struct usb_isoc_desc * id = (struct usb_isoc_desc *) lw1; struct usb_ohci_td **tdp = id->td; @@ -311,7 +334,7 @@ static void * sohci_request_bulk(struct usb_device *usb_dev, unsigned int pipe, OHCI_DEBUG( printk("USB HC BULK_RQ>>>: %x \n", ed->hwINFO);) - ohci_trans_req(ohci, ed, 0, NULL, data, len, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id, (usb_pipeout(pipe))?BULK_OUT:BULK_IN, sohci_int_handler); + ohci_trans_req(ohci, ed, 0, NULL, data, len, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id, (usb_pipeout(pipe))?BULK_OUT:BULK_IN, sohci_ret_handler); if (ED_STATE(ed) != ED_OPER) ohci_link_ed(ohci, ed); return ed; @@ -482,7 +505,7 @@ static int sohci_kill_isoc(struct usb_isoc_desc *id) { struct usb_ohci_ed *ed = NULL; struct usb_ohci_td **td = id->td; int i; -printk("KILL_ISOC***:\n"); + for (i = 0; i < id->frame_count; i++) { if(td[i]) { td[i]->type |= DEL; @@ -490,22 +513,17 @@ printk("KILL_ISOC***:\n"); } } if(ed) usb_ohci_rm_ep(id->usb_dev, ed, NULL, NULL, NULL, TD_RM); -printk(": end KILL_ISOC***: %p\n", ed); + id->start_frame = -1; return 0; } static void sohci_free_isoc(struct usb_isoc_desc *id) { -printk("FREE_ISOC***\n"); -wait_ms(2000); + if(id->start_frame >= 0) sohci_kill_isoc(id); -printk("FREE_ISOC2***\n"); -wait_ms(2000); kfree(id->td); kfree(id); -printk("FREE_ISOC3***\n"); -wait_ms(2000); } struct usb_operations sohci_device_operations = { @@ -772,17 +790,14 @@ struct usb_ohci_ed *usb_ohci_add_ep(struct usb_device * usb_dev, struct usb_hcd_ // struct ohci * ohci = usb_dev->bus->hcpriv; struct usb_ohci_td * td; - struct usb_ohci_ed * ed, *ed1; + struct usb_ohci_ed * ed; - int ed_state, ed_state1; + int ed_state; spin_lock(&usb_ed_lock); ed = ohci_find_ep(usb_dev, hcd_ed); - - ed1 = ((void *) ed) + 0x40; ed_state1 = ED_STATE(ed1); -OHCI_DEBUG(printk("++++ USB HC add 60 ed1 %x: %x :state: %x\n", ed1->hwINFO, (unsigned int ) ed1, ed_state1); ) ed_state = ED_STATE(ed); /* store state of ed */ OHCI_DEBUG(printk("USB HC add ed %x: %x :state: %x\n", ed->hwINFO, (unsigned int ) ed, ed_state); ) if (ed_state == ED_NEW) { @@ -1139,7 +1154,8 @@ static int usb_ohci_done_list(struct ohci * ohci, struct usb_ohci_td * td_list) struct usb_ohci_td * td_list_next = NULL; int cc; - int i; + int i; + int dlen = 0; while(td_list) { td_list_next = td_list->next_dl_td; @@ -1156,8 +1172,9 @@ static int usb_ohci_done_list(struct ohci * ohci, struct usb_ohci_td * td_list) } else { if(td_list->hwBE != 0) { + dlen = (bus_to_virt(td_list->hwBE) - td_list->buffer_start + 1); if(td_list->hwCBP == 0) - td_list->ed->len += (bus_to_virt(td_list->hwBE) - td_list->buffer_start + 1); + td_list->ed->len += dlen; else td_list->ed->len += (bus_to_virt(td_list->hwCBP) - td_list->buffer_start); } @@ -1170,9 +1187,10 @@ static int usb_ohci_done_list(struct ohci * ohci, struct usb_ohci_td * td_list) if((td_list->type & SEND) && (ED_STATE(td_list->ed) != ED_STOP) && (td_list->handler)) { /* send the reply */ td_list->handler((void *) ohci, - td_list->ed, + td_list, td_list->ed->buffer_start, td_list->ed->len, + dlen, cc, td_list->lw0, td_list->lw1); @@ -1227,7 +1245,7 @@ void reset_hc(struct ohci *ohci) { udelay(1); } } -static struct ohci *__ohci; + /* * Start an OHCI controller, set the BUS operational @@ -1353,7 +1371,7 @@ static struct ohci *alloc_ohci(void* mem_base) ohci->irq = -1; ohci->regs = mem_base; ohci->hc_area = hc_area; - __ohci = ohci; + /* * for load ballancing of the interrupt branches */ @@ -1395,7 +1413,7 @@ static void release_ohci(struct ohci *ohci) /* disconnect all devices */ if(ohci->bus->root_hub) usb_disconnect(&ohci->bus->root_hub); - reset_hc(__ohci); + reset_hc(ohci); writel(OHCI_USB_RESET, &ohci->regs->control); wait_ms(10); @@ -1428,6 +1446,9 @@ static int found_ohci(int irq, void* mem_base) return -ENOMEM; } + INIT_LIST_HEAD(&ohci->ohci_hcd_list); + list_add(&ohci->ohci_hcd_list, &ohci_hcd_list); + reset_hc(ohci); writel(OHCI_USB_RESET, &ohci->regs->control); wait_ms(10); @@ -1438,6 +1459,7 @@ static int found_ohci(int irq, void* mem_base) start_hc(ohci); return 0; } + printk(KERN_ERR "USB HC (ohci-hcd): request interrupt %d failed\n", irq); release_ohci(ohci); return -EBUSY; } @@ -1445,7 +1467,8 @@ static int found_ohci(int irq, void* mem_base) static int start_ohci(struct pci_dev *dev) { unsigned int mem_base = dev->resource[0].start; - + + pci_set_master(dev); mem_base = (unsigned int) ioremap_nocache(mem_base, 4096); if (!mem_base) { @@ -1488,17 +1511,18 @@ static int handle_apm_event(apm_event_t event) int ohci_hcd_init(void) { + int ret = -ENODEV; struct pci_dev *dev = NULL; while((dev = pci_find_class(PCI_CLASS_SERIAL_USB_OHCI, dev))) { - if (start_ohci(dev) < 0) return -ENODEV; + if (start_ohci(dev) >= 0) ret = 0; } #ifdef CONFIG_APM apm_register_callback(&handle_apm_event); #endif - return 0; + return ret; } #ifdef MODULE @@ -1509,10 +1533,17 @@ int init_module(void) void cleanup_module(void) { + struct ohci *ohci; + # ifdef CONFIG_APM apm_unregister_callback(&handle_apm_event); # endif - release_ohci(__ohci); + while(!list_empty(&ohci_hcd_list)) { + ohci = list_entry(ohci_hcd_list.next, struct ohci, ohci_hcd_list); + list_del(ohci->ohci_hcd_list); + INIT_LIST_HEAD(ohci->ohci_hcd_list); + release_ohci(ohci); + } } #endif //MODULE diff --git a/drivers/usb/ohci-hcd.h b/drivers/usb/ohci-hcd.h index 3ff3ae91d..722bbeaea 100644 --- a/drivers/usb/ohci-hcd.h +++ b/drivers/usb/ohci-hcd.h @@ -48,10 +48,11 @@ #include <linux/list.h> #include <asm/io.h> struct usb_ohci_ed; +struct usb_ohci_td; /* for ED and TD structures */ typedef void * __OHCI_BAG; -typedef int (*f_handler )(void * ohci, struct usb_ohci_ed *ed, void *data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1); +typedef int (*f_handler )(void * ohci, struct usb_ohci_td *td, void *data, int data_len, int dlen, int status, __OHCI_BAG lw0, __OHCI_BAG lw1); @@ -309,7 +310,9 @@ struct ohci { int irq; struct ohci_regs *regs; /* OHCI controller's memory */ struct ohci_hc_area *hc_area; /* hcca, int ed-tree, ohci itself .. */ - + + struct list_head ohci_hcd_list; /* list of all ohci_hcd */ + int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load ballancing)*/ struct usb_ohci_ed * ed_rm_list; /* list of all endpoints to be removed */ struct usb_ohci_ed * ed_bulktail; /* last endpoint of bulk list */ diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c index 20be3faab..25b2b303c 100644 --- a/drivers/usb/uhci.c +++ b/drivers/usb/uhci.c @@ -154,7 +154,10 @@ static int uhci_td_result(struct uhci_device *dev, struct uhci_td *td, unsigned actlength = uhci_actual_length(tmp->status); if (rval) *rval += actlength; - if (explength != actlength) { + /* This check is bogus, at least for acm. It + always expects 64, but gets as many bytes + as available (typically 1) -- pavel */ + if (0 && (explength != actlength)) { /* Reset the data toggle on error. */ if (debug || uhci_debug) printk(KERN_DEBUG "Set toggle from %p rval %ld%c for status=%x to %d, exp=%d, act=%d\n", diff --git a/drivers/usb/usb-serial.c b/drivers/usb/usb-serial.c index b85f2b5c6..6eb2d6455 100644 --- a/drivers/usb/usb-serial.c +++ b/drivers/usb/usb-serial.c @@ -11,6 +11,9 @@ * vendor and device ids for that device. * * + * version 0.1.2 (10/25/99) gkh + * Fixed bug in detecting device. + * * version 0.1.1 (10/05/99) gkh * Changed the major number to not conflict with anything else. * @@ -528,7 +531,7 @@ static int usb_serial_probe(struct usb_device *dev) serial->interrupt_in_interval = endpoint->bInterval; /* serial->interrupt_in_pipe = usb_rcvbulkpipe (dev, serial->bulk_in_endpoint); */ serial->interrupt_in_buffer = kmalloc (serial->bulk_in_size, GFP_KERNEL); - if (!serial->bulk_in_buffer) { + if (!serial->interrupt_in_buffer) { printk("USB Serial: Couldn't allocate interrupt_in_buffer\n"); goto probe_error; } diff --git a/fs/Config.in b/fs/Config.in index 0158b268d..78af8d3d4 100644 --- a/fs/Config.in +++ b/fs/Config.in @@ -59,11 +59,11 @@ fi tristate 'ROM filesystem support' CONFIG_ROMFS_FS tristate 'Second extended fs support' CONFIG_EXT2_FS tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS -if [ "$CONFIG_SYSV_FS" != "n" -a "$CONFIG_EXPERIMENTAL" ]; then +if [ "$CONFIG_SYSV_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' SYSV filesystem write support (DANGEROUS)' CONFIG_SYSV_FS_WRITE fi tristate 'UFS filesystem support (read only)' CONFIG_UFS_FS -if [ "$CONFIG_UFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" ]; then +if [ "$CONFIG_UFS_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' UFS filesystem write support (DANGEROUS)' CONFIG_UFS_FS_WRITE fi @@ -79,11 +79,9 @@ if [ "$CONFIG_INET" = "y" ]; then if [ "$CONFIG_NFS_FS" = "y" -a "$CONFIG_IP_PNP" = "y" ]; then bool ' Root file system on NFS' CONFIG_ROOT_NFS fi - if [ "$CONFIG_EXPERIMENTAL" ]; then - tristate 'NFS server support (EXPERIMENTAL)' CONFIG_NFSD - if [ "$CONFIG_NFSD" != "n" ]; then - bool ' Emulate SUN NFS server' CONFIG_NFSD_SUN - fi + tristate 'NFS server support' CONFIG_NFSD + if [ "$CONFIG_NFSD" != "n" ]; then + bool ' Emulate SUN NFS server' CONFIG_NFSD_SUN fi if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then define_bool CONFIG_SUNRPC y diff --git a/fs/buffer.c b/fs/buffer.c index 39dd880f8..7b2906868 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -751,9 +751,6 @@ static void end_buffer_io_async(struct buffer_head * bh, int uptodate) if (test_and_clear_bit(PG_decr_after, &page->flags)) atomic_dec(&nr_async_pages); - if (page->owner != (void *)-1) - PAGE_BUG(page); - page->owner = current; UnlockPage(page); return; @@ -1181,8 +1178,6 @@ static int create_page_buffers(int rw, struct page *page, kdev_t dev, int b[], i if (!PageLocked(page)) BUG(); - if (page->owner != current) - PAGE_BUG(page); /* * Allocate async buffer heads pointing to this page, just for I/O. * They don't show up in the buffer hash table, but they *are* @@ -1297,15 +1292,16 @@ static void create_empty_buffers(struct page *page, struct inode *inode, unsigne static void unmap_underlying_metadata(struct buffer_head * bh) { +#if 0 bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size); - if (bh) - { + if (bh) { unmap_buffer(bh); /* Here we could run brelse or bforget. We use bforget because it will try to put the buffer in the freelist. */ __bforget(bh); } +#endif } /* @@ -1947,7 +1943,6 @@ int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size) } if (!page->buffers) BUG(); - page->owner = (void *)-1; head = page->buffers; bh = head; @@ -1989,7 +1984,6 @@ int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size) } else { if (!nr && rw == READ) { SetPageUptodate(page); - page->owner = current; UnlockPage(page); } if (nr && (rw == WRITE)) @@ -2023,7 +2017,6 @@ int block_read_full_page(struct file * file, struct page * page) blocks = PAGE_SIZE >> inode->i_sb->s_blocksize_bits; iblock = page->offset >> inode->i_sb->s_blocksize_bits; - page->owner = (void *)-1; bh = head; nr = 0; @@ -2057,7 +2050,6 @@ int block_read_full_page(struct file * file, struct page * page) * uptodate as well. */ SetPageUptodate(page); - page->owner = current; UnlockPage(page); } return 0; @@ -2201,11 +2193,13 @@ busy_buffer_page: void show_buffers(void) { +#ifdef __SMP__ struct buffer_head * bh; int found = 0, locked = 0, dirty = 0, used = 0, lastused = 0; int protected = 0; int nlist; static char *buf_types[NR_LIST] = { "CLEAN", "LOCKED", "DIRTY" }; +#endif printk("Buffer memory: %6dkB\n", atomic_read(&buffermem_pages) << (PAGE_SHIFT-10)); diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 52e97c585..4cf932d51 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -668,6 +668,16 @@ void ext2_read_inode (struct inode * inode) inode->i_ctime = le32_to_cpu(raw_inode->i_ctime); inode->i_mtime = le32_to_cpu(raw_inode->i_mtime); inode->u.ext2_i.i_dtime = le32_to_cpu(raw_inode->i_dtime); + /* We now have enough fields to check if the inode was active or not. + * This is needed because nfsd might try to access dead inodes + * the test is that same one that e2fsck uses + * NeilBrown 1999oct15 + */ + if (inode->i_nlink == 0 && (inode->i_mode == 0 || inode->u.ext2_i.i_dtime)) { + /* this inode is deleted */ + brelse (bh); + goto bad_inode; + } inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */ inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); inode->i_version = ++event; diff --git a/fs/fat/Makefile b/fs/fat/Makefile index 8e8064c28..339250c7c 100644 --- a/fs/fat/Makefile +++ b/fs/fat/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile. O_TARGET := fat.o -O_OBJS := buffer.o cache.o dir.o file.o inode.o misc.o mmap.o tables.o cvf.o +O_OBJS := buffer.o cache.o dir.o file.o inode.o misc.o tables.o cvf.o OX_OBJS := fatfs_syms.o M_OBJS := $(O_TARGET) diff --git a/fs/fat/fatfs_syms.c b/fs/fat/fatfs_syms.c index 070361aa9..590b585dd 100644 --- a/fs/fat/fatfs_syms.c +++ b/fs/fat/fatfs_syms.c @@ -33,7 +33,6 @@ EXPORT_SYMBOL(fat_fs_panic); EXPORT_SYMBOL(fat__get_entry); EXPORT_SYMBOL(fat_lock_creation); EXPORT_SYMBOL(fat_mark_buffer_dirty); -EXPORT_SYMBOL(fat_mmap); EXPORT_SYMBOL(fat_notify_change); EXPORT_SYMBOL(fat_parent_ino); EXPORT_SYMBOL(fat_put_super); @@ -54,7 +53,6 @@ EXPORT_SYMBOL(fat_get_cluster); EXPORT_SYMBOL(lock_fat); EXPORT_SYMBOL(unlock_fat); EXPORT_SYMBOL(fat_dir_ioctl); -EXPORT_SYMBOL(fat_readpage); EXPORT_SYMBOL(fat_add_entries); EXPORT_SYMBOL(fat_dir_empty); diff --git a/fs/fat/file.c b/fs/fat/file.c index 5baa51af4..505dc4e06 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -115,13 +115,13 @@ static int fat_write_partial_page(struct file *file, struct page *page, unsigned struct inode *inode = dentry->d_inode; struct page *new_page, **hash; unsigned long pgpos; - unsigned long page_cache = 0; + struct page *page_cache = NULL; long status; pgpos = MSDOS_I(inode)->i_realsize & PAGE_CACHE_MASK; while (pgpos < page->offset) { - hash = page_hash(inode, pgpos); -repeat_find: new_page = __find_lock_page(inode, pgpos, hash); + hash = page_hash(&inode->i_data, pgpos); +repeat_find: new_page = __find_lock_page(&inode->i_data, pgpos, hash); if (!new_page) { if (!page_cache) { page_cache = page_cache_alloc(); @@ -130,10 +130,10 @@ repeat_find: new_page = __find_lock_page(inode, pgpos, hash); status = -ENOMEM; goto out; } - new_page = page_cache_entry(page_cache); - if (add_to_page_cache_unique(new_page,inode,pgpos,hash)) + new_page = page_cache; + if (add_to_page_cache_unique(new_page,&inode->i_data,pgpos,hash)) goto repeat_find; - page_cache = 0; + page_cache = NULL; } status = block_write_cont_page(file, new_page, PAGE_SIZE, 0, NULL); UnlockPage(new_page); diff --git a/fs/fat/mmap.c b/fs/fat/mmap.c deleted file mode 100644 index 80ec56b54..000000000 --- a/fs/fat/mmap.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * linux/fs/fat/mmap.c - * - * Written by Jacques Gelinas (jacques@solucorp.qc.ca) - * Inspired by fs/nfs/mmap.c (Jon Tombs 15 Aug 1993) - * - * mmap handling for fat-based filesystems - */ - -#define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S)) -#include <linux/version.h> - -#include <linux/stat.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/shm.h> -#include <linux/errno.h> -#include <linux/mman.h> -#include <linux/string.h> -#include <linux/malloc.h> -#include <linux/msdos_fs.h> - -#include <asm/uaccess.h> -#include <asm/system.h> - -/* - * Fill in the supplied page for mmap - */ -static unsigned long fat_file_mmap_nopage( - struct vm_area_struct * area, - unsigned long address, - int error_code) -{ - struct inode * inode = area->vm_file->f_dentry->d_inode; - unsigned long page; - unsigned int clear; - int pos; - long gap; /* distance from eof to pos */ - - page = __get_free_page(GFP_KERNEL); - if (!page) - return page; - address &= PAGE_MASK; - pos = address - area->vm_start + area->vm_offset; - - clear = 0; - gap = inode->i_size - pos; - if (gap <= 0){ - /* mmaping beyond end of file */ - clear = PAGE_SIZE; - }else{ - int cur_read; - int need_read; - struct file filp; - if (gap < PAGE_SIZE){ - clear = PAGE_SIZE - gap; - } - filp.f_reada = 0; - filp.f_pos = pos; - filp.f_dentry=area->vm_file->f_dentry; - need_read = PAGE_SIZE - clear; - { - mm_segment_t cur_fs = get_fs(); - set_fs (KERNEL_DS); - cur_read = fat_file_read (&filp, (char*)page, - need_read, &filp.f_pos); - set_fs (cur_fs); - } - if (cur_read != need_read){ - printk ("MSDOS: Error while reading an mmap file %d <> %d\n" - ,cur_read,need_read); - } - } - if (clear > 0){ - memset ((char*)page+PAGE_SIZE-clear,0,clear); - } - return page; -} - -struct vm_operations_struct fat_file_mmap = { - NULL, /* open */ - NULL, /* close */ - NULL, /* unmap */ - NULL, /* protect */ - NULL, /* sync */ - NULL, /* advise */ - fat_file_mmap_nopage, /* nopage */ - NULL, /* wppage */ - NULL /* swapout */ -}; - -/* - * This is used for a general mmap of an msdos file - * Returns 0 if ok, or a negative error code if not. - */ -int fat_mmap(struct file * file, struct vm_area_struct * vma) -{ - struct inode *inode = file->f_dentry->d_inode; - if (MSDOS_SB(inode->i_sb)->cvf_format && - MSDOS_SB(inode->i_sb)->cvf_format->cvf_mmap) - return MSDOS_SB(inode->i_sb)->cvf_format->cvf_mmap(file,vma); - - if (vma->vm_flags & VM_SHARED) /* only PAGE_COW or read-only supported now */ - return -EINVAL; - if (vma->vm_offset & (inode->i_sb->s_blocksize - 1)) - return -EINVAL; - if (!inode->i_sb || !S_ISREG(inode->i_mode)) - return -EACCES; - if (!IS_RDONLY(inode)) { - inode->i_atime = CURRENT_TIME; - mark_inode_dirty(inode); - } - - vma->vm_ops = &fat_file_mmap; - return 0; -} - - -int fat_readpage(struct file *file, struct page * page) -{ - struct dentry * dentry = file->f_dentry; - struct inode * inode = dentry->d_inode; - if (MSDOS_SB(inode->i_sb)->cvf_format && - MSDOS_SB(inode->i_sb)->cvf_format->cvf_readpage) - return MSDOS_SB(inode->i_sb)->cvf_format->cvf_readpage(inode,page); - - printk("fat_readpage called with no handler (shouldn't happen)\n"); - return -1; -} - diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 066ce5c28..72f61c20a 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -91,7 +91,7 @@ static int hpfs_write_partial_page(struct file *file, struct page *page, unsigne struct inode *inode = dentry->d_inode; struct page *new_page, **hash; unsigned long pgpos; - unsigned long page_cache = 0; + struct page * page_cache = NULL; long status; printk("- off: %08x\n", (int)page->offset); @@ -99,8 +99,8 @@ static int hpfs_write_partial_page(struct file *file, struct page *page, unsigne while (pgpos < page->offset) { long pgp = pgpos; printk("pgpos: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks); - hash = page_hash(inode, pgpos); -repeat_find: new_page = __find_lock_page(inode, pgpos, hash); + hash = page_hash(&inode->i_data, pgpos); +repeat_find: new_page = __find_lock_page(&inode->i_data, pgpos, hash); if (!new_page) { if (!page_cache) { page_cache = page_cache_alloc(); @@ -109,10 +109,10 @@ repeat_find: new_page = __find_lock_page(inode, pgpos, hash); status = -ENOMEM; goto out; } - new_page = page_cache_entry(page_cache); - if (add_to_page_cache_unique(new_page,inode,pgpos,hash)) + new_page = page_cache; + if (add_to_page_cache_unique(new_page,&inode->i_data,pgpos,hash)) goto repeat_find; - page_cache = 0; + page_cache = NULL; } printk("A\n"); status = block_write_cont_page(file, new_page, PAGE_SIZE, 0, NULL); diff --git a/fs/inode.c b/fs/inode.c index f03295d5c..bb4e0031f 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -89,7 +89,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) memset(inode, 0, sizeof(*inode)); init_waitqueue_head(&inode->i_wait); INIT_LIST_HEAD(&inode->i_hash); - INIT_LIST_HEAD(&inode->i_pages); + INIT_LIST_HEAD(&inode->i_data.pages); INIT_LIST_HEAD(&inode->i_dentry); sema_init(&inode->i_sem, 1); spin_lock_init(&inode->i_shared_lock); @@ -247,7 +247,7 @@ void write_inode_now(struct inode *inode) */ void clear_inode(struct inode *inode) { - if (inode->i_nrpages) + if (inode->i_data.nrpages) BUG(); if (!(inode->i_state & I_FREEING)) BUG(); @@ -274,7 +274,7 @@ static void dispose_list(struct list_head * head) list_del(inode_entry); inode = list_entry(inode_entry, struct inode, i_list); - if (inode->i_nrpages) + if (inode->i_data.nrpages) truncate_inode_pages(inode, 0); clear_inode(inode); destroy_inode(inode); @@ -351,7 +351,7 @@ int invalidate_inodes(struct super_block * sb) * dispose_list. */ #define CAN_UNUSE(inode) \ - (((inode)->i_state | (inode)->i_nrpages) == 0) + (((inode)->i_state | (inode)->i_data.nrpages) == 0) #define INODE(entry) (list_entry(entry, struct inode, i_list)) void prune_icache(int goal) @@ -658,7 +658,7 @@ void iput(struct inode *inode) if (op && op->delete_inode) { void (*delete)(struct inode *) = op->delete_inode; spin_unlock(&inode_lock); - if (inode->i_nrpages) + if (inode->i_data.nrpages) truncate_inode_pages(inode, 0); delete(inode); spin_lock(&inode_lock); diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 8df091923..4160bf2e3 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -69,6 +69,7 @@ nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock) call->a_args.lock = *lock; call->a_args.lock.caller = system_utsname.nodename; + init_waitqueue_head(&lock->fl.fl_wait); /* set default data area */ call->a_args.lock.oh.data = call->a_owner; diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index ea541e796..d3af541dd 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -576,9 +576,9 @@ printk("ncp_do_readdir: finding cache for %s/%s\n", #endif /* cache using inspired by smbfs and nfs */ - hash = page_hash(dir, 0); + hash = page_hash(&dir->i_data, 0); - page = __find_lock_page(dir, 0, hash); + page = __find_lock_page(&dir->i_data, 0, hash); if (!page) { unsigned long page_cache; @@ -586,7 +586,7 @@ printk("ncp_do_readdir: finding cache for %s/%s\n", page_cache = page_cache_alloc(); if (page_cache) { page = page_cache_entry(page_cache); - if (add_to_page_cache_unique(page, dir, 0, hash)) { + if (add_to_page_cache_unique(page, &dir->i_data, 0, hash)) { page_cache_release(page); page = NULL; page_cache_free(page_cache); diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b7ec225ac..651b1152c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -255,7 +255,7 @@ static long refetch_to_readdir_cookie(struct file *file, struct inode *inode) again: cur_off = 0; for (;;) { - page = find_get_page(inode, cur_off); + page = find_get_page(&inode->i_data, cur_off); if (page) { if (!Page_Uptodate(page)) goto out_error; @@ -332,16 +332,16 @@ static struct page *try_to_get_dirent_page(struct file *file, __u32 cookie, int goto out; } - hash = page_hash(inode, offset); + hash = page_hash(&inode->i_data, offset); repeat: - page = __find_lock_page(inode, offset, hash); + page = __find_lock_page(&inode->i_data, offset, hash); if (page) { page_cache_free(page_cache); goto unlock_out; } page = page_cache; - if (add_to_page_cache_unique(page, inode, offset, hash)) { + if (add_to_page_cache_unique(page, &inode->i_data, offset, hash)) { page_cache_release(page); goto repeat; } @@ -431,8 +431,8 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) if ((offset = nfs_readdir_offset(inode, filp->f_pos)) < 0) goto no_dirent_page; - hash = page_hash(inode, offset); - page = __find_get_page(inode, offset, hash); + hash = page_hash(&inode->i_data, offset); + page = __find_get_page(&inode->i_data, offset, hash); if (!page) goto no_dirent_page; if (!Page_Uptodate(page)) diff --git a/fs/nfs/read.c b/fs/nfs/read.c index a7960c1e0..a85ef5e74 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -152,7 +152,6 @@ nfs_readpage_result(struct rpc_task *task) fail++; dprintk("NFS: %d successful reads, %d failures\n", succ, fail); } - page->owner = current; // HACK, FIXME, will go away. UnlockPage(page); free_page(address); diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 6b0d0f05b..1b1705ef2 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c @@ -66,16 +66,16 @@ static struct page *try_to_get_symlink_page(struct dentry *dentry, struct inode if (!page_cache) goto out; - hash = page_hash(inode, 0); + hash = page_hash(&inode->i_data, 0); repeat: - page = __find_lock_page(inode, 0, hash); + page = __find_lock_page(&inode->i_data, 0, hash); if (page) { page_cache_free(page_cache); goto unlock_out; } page = page_cache; - if (add_to_page_cache_unique(page, inode, 0, hash)) { + if (add_to_page_cache_unique(page, &inode->i_data, 0, hash)) { page_cache_release(page); goto repeat; } @@ -107,7 +107,7 @@ static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen) u32 *p, len; /* Caller revalidated the directory inode already. */ - page = find_get_page(inode, 0); + page = find_get_page(&inode->i_data, 0); if (!page) goto no_readlink_page; if (!Page_Uptodate(page)) @@ -142,7 +142,7 @@ nfs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow) u32 *p; /* Caller revalidated the directory inode already. */ - page = find_get_page(inode, 0); + page = find_get_page(&inode->i_data, 0); if (!page) goto no_followlink_page; if (!Page_Uptodate(page)) diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 1ad581ea8..d5b1537db 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -365,16 +365,6 @@ exp_do_unexport(svc_export *unexp) exp->ex_parent = unexp->ex_parent; } - /* - * Check whether this is the last export for this device, - * and if so flush any cached dentries. - */ - if (!exp_device_in_use(unexp->ex_dev)) { -printk("exp_do_unexport: %s last use, flushing cache\n", - kdevname(unexp->ex_dev)); - nfsd_fh_flush(unexp->ex_dev); - } - dentry = unexp->ex_dentry; inode = dentry->d_inode; if (unexp->ex_dev != inode->i_dev || unexp->ex_ino != inode->i_ino) @@ -628,6 +618,7 @@ struct flags { { NFSEXP_KERBEROS, { "kerberos", ""}}, { NFSEXP_SUNSECURE, { "sunsecure", ""}}, { NFSEXP_CROSSMNT, {"nohide", ""}}, + { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, { 0, {"", ""}} }; diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 150acc6d9..4ec7b691b 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -39,7 +39,6 @@ #include <linux/smp.h> #include <linux/smp_lock.h> -extern void nfsd_fh_init(void); extern long sys_call_table[]; static int nfsctl_svc(struct nfsctl_svc *data); @@ -79,7 +78,6 @@ nfsd_init(void) nfsd_cache_init(); /* RPC reply cache */ nfsd_export_init(); /* Exports table */ nfsd_lockd_init(); /* lockd->nfsd callbacks */ - nfsd_fh_init(); /* FH table */ proc_export_init(); initialized = 1; } diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index a1241da96..5f8e90a0e 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -4,6 +4,8 @@ * NFS server file handle treatment. * * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> + * Portions Copyright (C) 1999 G. Allen Morris III <gam3@acm.org> + * Extensive cleanup by Neil Brown <neilb@cse.unsw.edu.au> Southern-Spring 1999 */ #include <linux/sched.h> @@ -22,308 +24,48 @@ #define NFSD_PARANOIA 1 /* #define NFSD_DEBUG_VERBOSE 1 */ -extern unsigned long max_mapnr; - -#define NFSD_FILE_CACHE 0 -#define NFSD_DIR_CACHE 1 -struct fh_entry { - struct dentry * dentry; - unsigned long reftime; - ino_t ino; - kdev_t dev; -}; - -#define NFSD_MAXFH PAGE_SIZE/sizeof(struct fh_entry) -static struct fh_entry filetable[NFSD_MAXFH]; -static struct fh_entry dirstable[NFSD_MAXFH]; static int nfsd_nr_verified = 0; static int nfsd_nr_put = 0; -static unsigned long nfsd_next_expire = 0; - -static int add_to_fhcache(struct dentry *, int); -static int nfsd_d_validate(struct dentry *); -struct dentry * lookup_inode(kdev_t, ino_t, ino_t); - -static LIST_HEAD(fixup_head); -static LIST_HEAD(path_inuse); -static int nfsd_nr_fixups = 0; -static int nfsd_nr_paths = 0; -#define NFSD_MAX_PATHS 500 -#define NFSD_MAX_FIXUPAGE 60*HZ - -struct nfsd_fixup { - struct list_head lru; - ino_t dir; - ino_t ino; - kdev_t dev; - struct dentry *dentry; - unsigned long reftime; -}; - -struct nfsd_path { - struct list_head lru; - unsigned long reftime; - int users; - ino_t ino; - kdev_t dev; - char name[1]; -}; - -static struct nfsd_fixup * find_cached_lookup(kdev_t dev, ino_t dir, ino_t ino) -{ - struct list_head *tmp = fixup_head.next; - - for (; tmp != &fixup_head; tmp = tmp->next) { - struct nfsd_fixup *fp; - fp = list_entry(tmp, struct nfsd_fixup, lru); - if (fp->ino != ino) - continue; - if (fp->dir != dir) - continue; - if (fp->dev != dev) - continue; - list_del(tmp); - list_add(tmp, &fixup_head); - fp->reftime = jiffies; - return fp; - } - return NULL; -} - -/* - * Save the dentry pointer from a successful lookup. - */ -static void add_to_lookup_cache(struct dentry *dentry, struct knfs_fh *fh) -{ - struct nfsd_fixup *fp; - - fp = find_cached_lookup(u32_to_kdev_t(fh->fh_dev), - u32_to_ino_t(fh->fh_dirino), - u32_to_ino_t(fh->fh_ino)); - if (fp) { - fp->dentry = dentry; - return; - } - - /* - * Add a new entry. The small race here is unimportant: - * if another task adds the same lookup, both entries - * will be consistent. - */ - fp = kmalloc(sizeof(struct nfsd_fixup), GFP_KERNEL); - if (fp) { - fp->dir = u32_to_kdev_t(fh->fh_dirino); - fp->ino = u32_to_ino_t(fh->fh_ino); - fp->dev = u32_to_ino_t(fh->fh_dev); - fp->dentry = dentry; - fp->reftime = jiffies; - list_add(&fp->lru, &fixup_head); - nfsd_nr_fixups++; - } -} - -static void free_fixup_entry(struct nfsd_fixup *fp) -{ - list_del(&fp->lru); - kfree(fp); - nfsd_nr_fixups--; -} - -/* - * Copy a dentry's path into the specified buffer. - */ -static int copy_path(char *buffer, struct dentry *dentry, int namelen) -{ - char *p, *b = buffer; - int result = 0, totlen = 0, len; - - while (1) { - struct dentry *parent; - dentry = dentry->d_covers; - parent = dentry->d_parent; - len = dentry->d_name.len; - p = (char *) dentry->d_name.name + len; - totlen += len; - if (totlen > namelen) - goto out; - while (len--) - *b++ = *(--p); - if (dentry == parent) - break; - dentry = parent; - totlen++; - if (totlen > namelen) - goto out; - *b++ = '/'; - } - *b = 0; - - /* - * Now reverse in place ... - */ - p = buffer; - while (p < b) { - char c = *(--b); - *b = *p; - *p++ = c; - } - result = 1; -out: - return result; -} - -/* - * Add a dentry's path to the path cache. - */ -static int add_to_path_cache(struct dentry *dentry) -{ - struct inode *inode = dentry->d_inode; - struct dentry *this; - struct nfsd_path *new; - int len, result = 0; - -#ifdef NFSD_DEBUG_VERBOSE -printk("add_to_path_cache: caching %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif - /* - * Get the length of the full pathname. - */ -restart: - len = 0; - this = dentry; - while (1) { - struct dentry *parent; - this = this->d_covers; - parent = this->d_parent; - len += this->d_name.len; - if (this == parent) - break; - this = parent; - len++; - } - /* - * Allocate a structure to hold the path. - */ - new = kmalloc(sizeof(struct nfsd_path) + len, GFP_KERNEL); - if (new) { - new->users = 0; - new->reftime = jiffies; - new->ino = inode->i_ino; - new->dev = inode->i_dev; - result = copy_path(new->name, dentry, len); - if (!result) - goto retry; - list_add(&new->lru, &path_inuse); - nfsd_nr_paths++; -#ifdef NFSD_DEBUG_VERBOSE -printk("add_to_path_cache: added %s, paths=%d\n", new->name, nfsd_nr_paths); -#endif - } - return result; - - /* - * If the dentry's path length changed, just try again. - */ -retry: - kfree(new); - printk(KERN_DEBUG "add_to_path_cache: path length changed, retrying\n"); - goto restart; -} - -/* - * Search for a path entry for the specified (dev, inode). - */ -static struct nfsd_path *get_path_entry(kdev_t dev, ino_t ino) -{ - struct nfsd_path *pe; - struct list_head *tmp; - - for (tmp = path_inuse.next; tmp != &path_inuse; tmp = tmp->next) { - pe = list_entry(tmp, struct nfsd_path, lru); - if (pe->ino != ino) - continue; - if (pe->dev != dev) - continue; - list_del(tmp); - list_add(tmp, &path_inuse); - pe->users++; - pe->reftime = jiffies; -#ifdef NFSD_PARANOIA -printk("get_path_entry: found %s for %s/%ld\n", pe->name, kdevname(dev), ino); -#endif - return pe; - } - return NULL; -} - -static void put_path(struct nfsd_path *pe) -{ - pe->users--; -} - -static void free_path_entry(struct nfsd_path *pe) -{ - if (pe->users) - printk(KERN_DEBUG "free_path_entry: %s in use, users=%d\n", - pe->name, pe->users); - list_del(&pe->lru); - kfree(pe); - nfsd_nr_paths--; -} struct nfsd_getdents_callback { - struct nfsd_dirent *dirent; - ino_t dirino; /* parent inode number */ - int found; /* dirent inode matched? */ + struct qstr *name; /* name that was found. name->name already points to a buffer */ + unsigned long ino; /* the inum we are looking for */ + int found; /* inode matched? */ int sequence; /* sequence counter */ }; -struct nfsd_dirent { - ino_t ino; /* preset to desired entry */ - int len; - char name[256]; -}; - /* - * A rather strange filldir function to capture the inode number - * for the second entry (the parent inode) and the name matching - * the specified inode number. + * A rather strange filldir function to capture + * the name matching the specified inode number. */ -static int filldir_one(void * __buf, const char * name, int len, +static int filldir_one(void * __buf, const char * name, int len, off_t pos, ino_t ino) { struct nfsd_getdents_callback *buf = __buf; - struct nfsd_dirent *dirent = buf->dirent; + struct qstr *qs = buf->name; + char *nbuf = (char*)qs->name; /* cast is to get rid of "const" */ int result = 0; buf->sequence++; #ifdef NFSD_DEBUG_VERBOSE -printk("filldir_one: seq=%d, ino=%ld, name=%s\n", buf->sequence, ino, name); +dprintk("filldir_one: seq=%d, ino=%ld, name=%s\n", buf->sequence, ino, name); #endif - if (buf->sequence == 2) { - buf->dirino = ino; - goto out; - } - if (dirent->ino == ino) { - dirent->len = len; - memcpy(dirent->name, name, len); - dirent->name[len] = 0; + if (buf->ino == ino) { + qs->len = len; + memcpy(nbuf, name, len); + nbuf[len] = '\0'; buf->found = 1; result = -1; } -out: return result; } /* - * Read a directory and return the parent inode number and the name - * of the specified entry. The dirent must be initialized with the - * inode number of the desired entry. + * Read a directory and return the name of the specified entry. */ -static int get_parent_ino(struct dentry *dentry, struct nfsd_dirent *dirent) +static int get_ino_name(struct dentry *dentry, struct qstr *name, unsigned long ino) { struct inode *dir = dentry->d_inode; int error; @@ -346,8 +88,8 @@ static int get_parent_ino(struct dentry *dentry, struct nfsd_dirent *dirent) if (!file.f_op->readdir) goto out_close; - buffer.dirent = dirent; - buffer.dirino = 0; + buffer.name = name; + buffer.ino = ino; buffer.found = 0; buffer.sequence = 0; while (1) { @@ -365,7 +107,6 @@ static int get_parent_ino(struct dentry *dentry, struct nfsd_dirent *dirent) if (old_seq == buffer.sequence) break; } - dirent->ino = buffer.dirino; out_close: if (file.f_op->release) @@ -374,663 +115,245 @@ out: return error; } -/* - * Look up a dentry given inode and parent inode numbers. - * - * This relies on the ability of a Unix-like filesystem to return - * the parent inode of a directory as the ".." (second) entry. - * - * This could be further optimized if we had an efficient way of - * searching for a dentry given the inode: as we walk up the tree, - * it's likely that a dentry exists before we reach the root. +/* this should be provided by each filesystem in an nfsd_operations interface as + * iget isn't really the right interface */ -struct dentry * lookup_inode(kdev_t dev, ino_t dirino, ino_t ino) +static inline struct dentry *nfsd_iget(struct super_block *sb, unsigned long ino, __u32 generation) { - struct super_block *sb; - struct dentry *root, *dentry, *result; - struct inode *dir; - char *name; - unsigned long page; - ino_t root_ino; - int error; - struct nfsd_dirent dirent; - result = ERR_PTR(-ENOMEM); - page = __get_free_page(GFP_KERNEL); - if (!page) - goto out; - - /* - * Get the root dentry for the device. - */ - result = ERR_PTR(-ENOENT); - sb = get_super(dev); - if (!sb) - goto out_page; - result = ERR_PTR(-ENOSYS); - if (!sb->s_op->read_inode) /* No working iget(), e.g. FAT */ - goto out_page; - root = dget(sb->s_root); - root_ino = root->d_inode->i_ino; /* usually 2 */ - - name = (char *) page + PAGE_SIZE; - *(--name) = 0; - - /* - * Walk up the tree to construct the name string. - * When we reach the root inode, look up the name - * relative to the root dentry. + /* iget isn't really right if the inode is currently unallocated!! + * This should really all be done inside each filesystem + * + * ext2fs' read_inode has been strengthed to return a bad_inode if the inode + * had been deleted. + * + * Currently we don't know the generation for parent directory, so a generation + * of 0 means "accept any" */ - while (1) { - if (ino == root_ino) { - if (*name == '/') - name++; - /* - * Note: this dput()s the root dentry. - */ - result = lookup_dentry(name, root, 0); - break; - } - - result = ERR_PTR(-ENOENT); - dir = iget(sb, dirino); - if (!dir) - goto out_root; - dentry = d_alloc_root(dir); - if (!dentry) - goto out_iput; - - /* - * Get the name for this inode and the next parent inode. - */ - dirent.ino = ino; - error = get_parent_ino(dentry, &dirent); - result = ERR_PTR(error); - dput(dentry); - if (error) - goto out_root; - /* - * Prepend the name to the buffer. - */ - result = ERR_PTR(-ENAMETOOLONG); - name -= (dirent.len + 1); - if ((unsigned long) name <= page) - goto out_root; - memcpy(name + 1, dirent.name, dirent.len); - *name = '/'; - - /* - * Make sure we can't get caught in a loop ... - */ - if (dirino == dirent.ino && dirino != root_ino) { - printk(KERN_DEBUG - "lookup_inode: looping?? (ino=%ld, path=%s)\n", - dirino, name); - goto out_root; - } - ino = dirino; - dirino = dirent.ino; - } - -out_page: - free_page(page); -out: - return result; - - /* - * Error exits ... - */ -out_iput: - result = ERR_PTR(-ENOMEM); - iput(dir); -out_root: - dput(root); - goto out; -} - -/* - * Find an entry in the cache matching the given dentry pointer. - */ -static struct fh_entry *find_fhe(struct dentry *dentry, int cache, - struct fh_entry **empty) -{ - struct fh_entry *fhe; - int i, found = (empty == NULL) ? 1 : 0; - - if (!dentry) - goto out; - - fhe = (cache == NFSD_FILE_CACHE) ? &filetable[0] : &dirstable[0]; - for (i = 0; i < NFSD_MAXFH; i++, fhe++) { - if (fhe->dentry == dentry) { - fhe->reftime = jiffies; - return fhe; - } - if (!found && !fhe->dentry) { - found = 1; - *empty = fhe; - } - } -out: - return NULL; -} - -/* - * Expire a cache entry. - */ -static void expire_fhe(struct fh_entry *empty, int cache) -{ - struct dentry *dentry = empty->dentry; - -#ifdef NFSD_DEBUG_VERBOSE -printk("expire_fhe: expiring %s/%s, d_count=%d, ino=%ld\n", -dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count,empty->ino); -#endif - empty->dentry = NULL; /* no dentry */ - /* - * Add the parent to the dir cache before releasing the dentry, - * and check whether to save a copy of the dentry's path. - */ - if (!IS_ROOT(dentry)) { - struct dentry *parent = dget(dentry->d_parent); - if (add_to_fhcache(parent, NFSD_DIR_CACHE)) - nfsd_nr_verified++; - else - dput(parent); - /* - * If we're expiring a directory, copy its path. - */ - if (cache == NFSD_DIR_CACHE) { - add_to_path_cache(dentry); - } - } - dput(dentry); - nfsd_nr_put++; -} - -/* - * Look for an empty slot, or select one to expire. - */ -static void expire_slot(int cache) -{ - struct fh_entry *fhe, *empty = NULL; - unsigned long oldest = -1; - int i; - - fhe = (cache == NFSD_FILE_CACHE) ? &filetable[0] : &dirstable[0]; - for (i = 0; i < NFSD_MAXFH; i++, fhe++) { - if (!fhe->dentry) - goto out; - if (fhe->reftime < oldest) { - oldest = fhe->reftime; - empty = fhe; + struct inode *inode; + struct list_head *lp; + struct dentry *result; + inode = iget(sb, ino); + if (is_bad_inode(inode) + || (generation && inode->i_generation != generation) + ) { + /* we didn't find the right inode.. */ + dprintk("fh_verify: Inode %lu, Bad count: %d %d or version %u %u\n", + inode->i_ino, + inode->i_nlink, inode->i_count, + inode->i_generation, + generation); + + iput(inode); + return NULL; + } + /* now to find a dentry. + * If possible, get a well-connected one + */ + for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) { + result = list_entry(lp,struct dentry, d_alias); + if (! IS_ROOT(result) || inode->i_sb->s_root == result) { + dget(result); + iput(inode); + return result; } } - if (empty) - expire_fhe(empty, cache); - -out: - return; -} - -/* - * Expire any cache entries older than a certain age. - */ -static void expire_old(int cache, int age) -{ - struct list_head *tmp; - struct fh_entry *fhe; - int i; - -#ifdef NFSD_DEBUG_VERBOSE -printk("expire_old: expiring %s older than %d\n", -(cache == NFSD_FILE_CACHE) ? "file" : "dir", age); -#endif - fhe = (cache == NFSD_FILE_CACHE) ? &filetable[0] : &dirstable[0]; - for (i = 0; i < NFSD_MAXFH; i++, fhe++) { - if (!fhe->dentry) - continue; - if ((jiffies - fhe->reftime) > age) - expire_fhe(fhe, cache); - } - - /* - * Remove old entries from the patch-up cache. - */ - while ((tmp = fixup_head.prev) != &fixup_head) { - struct nfsd_fixup *fp; - fp = list_entry(tmp, struct nfsd_fixup, lru); - if ((jiffies - fp->reftime) < NFSD_MAX_FIXUPAGE) - break; - free_fixup_entry(fp); - } - - /* - * Trim the path cache ... - */ - while (nfsd_nr_paths > NFSD_MAX_PATHS) { - struct nfsd_path *pe; - pe = list_entry(path_inuse.prev, struct nfsd_path, lru); - if (pe->users) - break; - free_path_entry(pe); + result = d_alloc_root(inode); + if (result == NULL) { + iput(inode); + return ERR_PTR(-ENOMEM); } + d_rehash(result); /* so a dput won't loose it */ + return result; } -/* - * Add a dentry to the file or dir cache. - * - * Note: As NFS file handles must have an inode, we don't accept - * negative dentries. +/* this routine links an IS_ROOT dentry into the dcache tree. It gains "parent" + * as a parent and "name" as a name + * It should possibly go in dcache.c */ -static int add_to_fhcache(struct dentry *dentry, int cache) +int d_splice(struct dentry *target, struct dentry *parent, struct qstr *name) { - struct fh_entry *fhe, *empty = NULL; - struct inode *inode = dentry->d_inode; - - if (!inode) { + struct dentry *tdentry; #ifdef NFSD_PARANOIA -printk("add_to_fhcache: %s/%s rejected, no inode!\n", -dentry->d_parent->d_name.name, dentry->d_name.name); + if (!IS_ROOT(target)) + printk("nfsd: d_splice with no-root target: %s/%s\n", parent->d_name.name, name->name); #endif - return 0; - } - -repeat: - fhe = find_fhe(dentry, cache, &empty); - if (fhe) { - return 0; - } + name->hash = full_name_hash(name->name, name->len); + tdentry = d_alloc(parent, name); + if (tdentry == NULL) + return -ENOMEM; + d_move(target, tdentry); - /* - * Not found ... make a new entry. + /* tdentry will have been made a "child" of target (the parent of target) + * make it an IS_ROOT instead */ - if (empty) { - empty->dentry = dentry; - empty->reftime = jiffies; - empty->ino = inode->i_ino; - empty->dev = inode->i_dev; - return 1; - } - - expire_slot(cache); - goto repeat; + list_del(&tdentry->d_child); + tdentry->d_parent = tdentry; + d_rehash(target); + dput(tdentry); + return 0; } -/* - * Find an entry in the dir cache for the specified inode number. - */ -static struct fh_entry *find_fhe_by_ino(kdev_t dev, ino_t ino) -{ - struct fh_entry * fhe = &dirstable[0]; - int i; - - for (i = 0; i < NFSD_MAXFH; i++, fhe++) { - if (fhe->ino == ino && fhe->dev == dev) { - fhe->reftime = jiffies; - return fhe; - } - } - return NULL; -} - -/* - * Find the (directory) dentry with the specified (dev, inode) number. - * Note: this leaves the dentry in the cache. +/* this routine finds the dentry of the parent of a given directory + * it should be in the filesystem accessed by nfsd_operations + * it assumes lookup("..") works. */ -static struct dentry *find_dentry_by_ino(kdev_t dev, ino_t ino) +struct dentry *nfsd_findparent(struct dentry *child) { - struct fh_entry *fhe; - struct nfsd_path *pe; - struct dentry * dentry; - -#ifdef NFSD_DEBUG_VERBOSE -printk("find_dentry_by_ino: looking for inode %ld\n", ino); -#endif - /* - * Special case: inode number 2 is the root inode, - * so we can use the root dentry for the device. - */ - if (ino == 2) { - struct super_block *sb = get_super(dev); - if (sb) { -#ifdef NFSD_PARANOIA -printk("find_dentry_by_ino: getting root dentry for %s\n", kdevname(dev)); -#endif - if (sb->s_root) { - dentry = dget(sb->s_root); - goto out; - } else { -#ifdef NFSD_PARANOIA - printk("find_dentry_by_ino: %s has no root??\n", - kdevname(dev)); -#endif - } - } - } + struct dentry *tdentry, *pdentry; + tdentry = d_alloc(child, &(const struct qstr) {"..", 2, 0}); + if (!tdentry) + return ERR_PTR(-ENOMEM); - /* - * Search the dentry cache ... + /* I'm going to assume that if the returned dentry is different, then + * it is well connected. But nobody returns different dentrys do they? */ - fhe = find_fhe_by_ino(dev, ino); - if (fhe) { - dentry = dget(fhe->dentry); - goto out; - } - /* - * Search the path cache ... - */ - dentry = NULL; - pe = get_path_entry(dev, ino); - if (pe) { - struct dentry *res; - res = lookup_dentry(pe->name, NULL, 0); - if (!IS_ERR(res)) { - struct inode *inode = res->d_inode; - if (inode && inode->i_ino == ino && - inode->i_dev == dev) { - dentry = res; -#ifdef NFSD_PARANOIA -printk("find_dentry_by_ino: found %s/%s, ino=%ld\n", -dentry->d_parent->d_name.name, dentry->d_name.name, ino); -#endif - if (add_to_fhcache(dentry, NFSD_DIR_CACHE)) { - dget(dentry); - nfsd_nr_verified++; - } - } else { - dput(res); - } - } else { -#ifdef NFSD_PARANOIA -printk("find_dentry_by_ino: %s lookup failed\n", pe->name); -#endif + pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); + if (!pdentry) { + /* I don't want to return a ".." dentry. + * I would prefer to return an unconnected "IS_ROOT" dentry, + * though a properly connected dentry is even better + */ + /* if first or last of alias list is not tdentry, use that + * else make a root dentry + */ + struct list_head *aliases = &tdentry->d_inode->i_dentry; + if (aliases->next != aliases) { + pdentry = list_entry(aliases->next, struct dentry, d_alias); + if (pdentry == tdentry) + pdentry = list_entry(aliases->prev, struct dentry, d_alias); + if (pdentry == tdentry) + pdentry = NULL; + if (pdentry) dget(pdentry); } - put_path(pe); - } -out: - return dentry; -} - -/* - * Look for an entry in the file cache matching the dentry pointer, - * and verify that the (dev, inode) numbers are correct. If found, - * the entry is removed from the cache. - */ -static struct dentry *find_dentry_in_fhcache(struct knfs_fh *fh) -{ - struct fh_entry * fhe; - - fhe = find_fhe(fh->fh_dcookie, NFSD_FILE_CACHE, NULL); - if (fhe) { - struct dentry *parent, *dentry; - struct inode *inode; - - dentry = fhe->dentry; - inode = dentry->d_inode; - - if (!inode) { -#ifdef NFSD_PARANOIA -printk("find_dentry_in_fhcache: %s/%s has no inode!\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif - goto out; + if (pdentry == NULL) { + pdentry = d_alloc_root(igrab(tdentry->d_inode)); + if (pdentry) d_rehash(pdentry); } - if (inode->i_ino != u32_to_ino_t(fh->fh_ino)) - goto out; - if (inode->i_dev != u32_to_kdev_t(fh->fh_dev)) - goto out; - - fhe->dentry = NULL; - fhe->ino = 0; - fhe->dev = 0; - nfsd_nr_put++; - /* - * Make sure the parent is in the dir cache ... - */ - parent = dget(dentry->d_parent); - if (add_to_fhcache(parent, NFSD_DIR_CACHE)) - nfsd_nr_verified++; - else - dput(parent); - return dentry; + if (pdentry == NULL) + pdentry = ERR_PTR(-ENOMEM); } -out: - return NULL; + dput(tdentry); /* it was never rehashed, it will be discarded */ + return pdentry; } /* - * Look for an entry in the parent directory with the specified - * inode number. - */ -static struct dentry *lookup_by_inode(struct dentry *parent, ino_t ino) -{ - struct dentry *dentry; - int error; - struct nfsd_dirent dirent; - - /* - * Search the directory for the inode number. - */ - dirent.ino = ino; - error = get_parent_ino(parent, &dirent); - if (error) { -#ifdef NFSD_PARANOIA -printk("lookup_by_inode: ino %ld not found in %s\n", ino, parent->d_name.name); -#endif - goto no_entry; - } -#ifdef NFSD_PARANOIA -printk("lookup_by_inode: found %s\n", dirent.name); -#endif - - dentry = lookup_dentry(dirent.name, parent, 0); - if (!IS_ERR(dentry)) { - if (dentry->d_inode && dentry->d_inode->i_ino == ino) - goto out; -#ifdef NFSD_PARANOIA -printk("lookup_by_inode: %s/%s inode mismatch??\n", -parent->d_name.name, dentry->d_name.name); -#endif - dput(dentry); - } else { -#ifdef NFSD_PARANOIA -printk("lookup_by_inode: %s lookup failed, error=%ld\n", -dirent.name, PTR_ERR(dentry)); -#endif - } - -no_entry: - dentry = NULL; -out: - return dentry; - -} - -/* - * Search the fix-up list for a dentry from a prior lookup. - */ -static struct dentry *nfsd_cached_lookup(struct knfs_fh *fh) -{ - struct nfsd_fixup *fp; - - fp = find_cached_lookup(u32_to_kdev_t(fh->fh_dev), - u32_to_ino_t(fh->fh_dirino), - u32_to_ino_t(fh->fh_ino)); - if (fp) - return fp->dentry; - return NULL; -} - -void -expire_all(void) -{ - if (time_after_eq(jiffies, nfsd_next_expire)) { - expire_old(NFSD_FILE_CACHE, 5*HZ); - expire_old(NFSD_DIR_CACHE , 60*HZ); - nfsd_next_expire = jiffies + 5*HZ; - } -} - -/* - * Free cache after unlink/rmdir. - */ -void -expire_by_dentry(struct dentry *dentry) -{ - struct fh_entry *fhe; - - fhe = find_fhe(dentry, NFSD_FILE_CACHE, NULL); - if (fhe) { - expire_fhe(fhe, NFSD_FILE_CACHE); - } - fhe = find_fhe(dentry, NFSD_DIR_CACHE, NULL); - if (fhe) { - expire_fhe(fhe, NFSD_DIR_CACHE); - } -} - -/* - * The is the basic lookup mechanism for turning an NFS file handle - * into a dentry. There are several levels to the search: - * (1) Look for the dentry pointer the short-term fhcache, - * and verify that it has the correct inode number. - * - * (2) Try to validate the dentry pointer in the file handle, - * and verify that it has the correct inode number. If this - * fails, check for a cached lookup in the fix-up list and - * repeat step (2) using the new dentry pointer. - * - * (3) Look up the dentry by using the inode and parent inode numbers - * to build the name string. This should succeed for any Unix-like - * filesystem. - * - * (4) Search for the parent dentry in the dir cache, and then - * look for the name matching the inode number. - * - * (5) The most general case ... search the whole volume for the inode. - * - * If successful, we return a dentry with the use count incremented. - * - * Note: steps (4) and (5) above are probably unnecessary now that (3) - * is working. Remove the code once this is verified ... + * This is the basic lookup mechanism for turning an NFS file handle + * into a dentry. + * We use nfsd_iget and if that doesn't return a suitably connected dentry, + * we try to find the parent, and the parent of that and so-on until a + * connection if made. */ static struct dentry * -find_fh_dentry(struct knfs_fh *fh) -{ - struct dentry *dentry, *parent; - int looked_up = 0, retry = 0; - - /* - * Stage 1: Look for the dentry in the short-term fhcache. - */ - dentry = find_dentry_in_fhcache(fh); - if (dentry) { - nfsdstats.fh_cached++; - goto out; - } - - /* - * Stage 2: Attempt to validate the dentry in the file handle. - */ - dentry = fh->fh_dcookie; -recheck: - if (nfsd_d_validate(dentry)) { - struct inode * dir = dentry->d_parent->d_inode; - - if (dir->i_ino == u32_to_ino_t(fh->fh_dirino) && - dir->i_dev == u32_to_kdev_t(fh->fh_dev)) { - struct inode * inode = dentry->d_inode; - /* - * NFS file handles must always have an inode, - * so we won't accept a negative dentry. - */ - if (inode && inode->i_ino == u32_to_ino_t(fh->fh_ino)) { - dget(dentry); -#ifdef NFSD_DEBUG_VERBOSE -printk("find_fh_dentry: validated %s/%s, ino=%ld\n", -dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_ino); -#endif - if (!retry) - nfsdstats.fh_valid++; - else { - nfsdstats.fh_fixup++; -#ifdef NFSD_DEBUG_VERBOSE -printk("find_fh_dentry: retried validation successful\n"); -#endif - } - goto out; +find_fh_dentry(struct super_block *sb, struct knfs_fh *fh, int needpath) +{ + struct dentry *dentry, *result = NULL; + struct qstr qs; + char namebuf[256]; + int found =0; + u32 err; + + qs.name = namebuf; + /* + * Attempt to find the inode. + */ + result = nfsd_iget(sb, fh->fh_ino, fh->fh_generation); + err = PTR_ERR(result); + if (IS_ERR(result)) + goto err_out; + err = -ESTALE; + if (!result) { + dprintk("find_fh_dentry: No inode found.\n"); + goto err_out; + } + if (!IS_ROOT(result) || result->d_inode->i_sb->s_root ==result) + return result; + + /* result is now a "root" dentry, which may be adequate as it stands, or else + * will get spliced into the dcache tree */ + + if (!S_ISDIR(result->d_inode->i_mode) && ! needpath) { + return result; + } + + /* It's a directory, or we are required to confirm the file's + * location in the tree. + */ + found = 0; + if (!S_ISDIR(result->d_inode->i_mode)) { + if (fh->fh_dirino == 0) + goto err_result; /* don't know how to find parent */ + else { + /* need to iget fh->fh_dirino and make sure this inode is in that directory */ + dentry = nfsd_iget(sb, fh->fh_dirino, 0); + err = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto err_result; + err = -ESTALE; + if (!dentry->d_inode + || !S_ISDIR(dentry->d_inode->i_mode)) { + goto err_dentry; } + if (!IS_ROOT(dentry) || dentry->d_inode->i_sb->s_root ==dentry) + found = 1; + err = get_ino_name(dentry, &qs, result->d_inode->i_ino); + if (err) + goto err_dentry; + + /* OK, we have the name in parent of inode, lets fill in the dentry */ + err = d_splice(result, dentry, &qs); + if (err) + goto err_dentry; } } - - /* - * Before proceeding to a lookup, check whether we cached a - * prior lookup. If so, try to validate that dentry ... - */ - if (!retry && (dentry = nfsd_cached_lookup(fh)) != NULL) { - retry = 1; - goto recheck; - } - - /* - * Stage 3: Look up the dentry based on the inode and parent inode - * numbers. This should work for all Unix-like filesystems. - */ - looked_up = 1; - dentry = lookup_inode(u32_to_kdev_t(fh->fh_dev), - u32_to_ino_t(fh->fh_dirino), - u32_to_ino_t(fh->fh_ino)); - if (!IS_ERR(dentry)) { - struct inode * inode = dentry->d_inode; -#ifdef NFSD_DEBUG_VERBOSE -printk("find_fh_dentry: looked up %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif - if (inode && inode->i_ino == u32_to_ino_t(fh->fh_ino)) { - nfsdstats.fh_lookup++; - goto out; + else + dentry = dget(result); + + while(!found) { + /* LOOP INVARIANT */ + /* haven't found a place in the tree yet, but we do have a path + * from dentry down to result, and dentry is a directory. + * Have a hold on dentry and result */ + struct dentry *pdentry; + struct inode *parent; + + pdentry = nfsd_findparent(dentry); + err = PTR_ERR(pdentry); + if (IS_ERR(pdentry)) + goto err_dentry; + parent = pdentry->d_inode; + err = -EACCES; + if (!parent) { + dput(pdentry); + goto err_dentry; } -#ifdef NFSD_PARANOIA -printk("find_fh_dentry: %s/%s lookup mismatch!\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif - dput(dentry); - } - - /* - * Stage 4: Look for the parent dentry in the fhcache ... - */ - parent = find_dentry_by_ino(u32_to_kdev_t(fh->fh_dev), - u32_to_ino_t(fh->fh_dirino)); - if (parent) { - /* - * ... then search for the inode in the parent directory. + /* I'm not sure that this is the best test for + * "is it not a floating dentry?" */ - dentry = lookup_by_inode(dget(parent), u32_to_ino_t(fh->fh_ino)); - dput(parent); - if (dentry) - goto out; - } + if (!IS_ROOT(pdentry) || parent->i_sb->s_root == pdentry) + found = 1; - /* - * Stage 5: Search the whole volume. - */ -#ifdef NFSD_PARANOIA -printk("find_fh_dentry: %s, %u/%u not found -- need full search!\n", -kdevname(u32_to_kdev_t(fh->fh_dev)), fh->fh_dirino, fh->fh_ino); -#endif - dentry = NULL; - nfsdstats.fh_stale++; - -out: - if (looked_up && dentry) { - add_to_lookup_cache(dentry, fh); + err = get_ino_name(pdentry, &qs, dentry->d_inode->i_ino); + if (err) { + dput(pdentry); + goto err_dentry; + } + err = d_splice(dentry, pdentry, &qs); + dprintk("nfsd_fh: found name %s for ino %ld\n", dentry->d_name.name, dentry->d_inode->i_ino); + dput(dentry); + dentry = pdentry; } + dput(dentry); + return result; - expire_all(); - - return dentry; +err_dentry: + dput(dentry); +err_result: + dput(result); +err_out: + if (err == -ESTALE) + nfsdstats.fh_stale++; + return ERR_PTR(err); } /* @@ -1038,6 +361,9 @@ out: * * Note that the file handle dentry may need to be freed even after * an error return. + * + * This is only called at the start of an nfsproc call, so fhp points to + * a svc_fh which is all 0 except for the over-the-wire file handle. */ u32 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) @@ -1048,20 +374,36 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) struct inode *inode; u32 error = 0; - dprintk("nfsd: fh_verify(exp %x/%u cookie %p)\n", - fh->fh_xdev, fh->fh_xino, fh->fh_dcookie); + dprintk("nfsd: fh_verify(exp %s/%u file (%s/%u dir %u)\n", + kdevname(fh->fh_xdev), + fh->fh_xino, + kdevname(fh->fh_dev), + fh->fh_ino, + fh->fh_dirino); + + /* + * Security: Check that the fh is internally consistant (from <gam3@acm.org>) + */ + if (fh->fh_dev != fh->fh_xdev) { + printk("fh_verify: Security: export on other device (%s, %s).\n", + kdevname(fh->fh_dev), kdevname(fh->fh_xdev)); + error = nfserr_stale; + nfsdstats.fh_stale++; + goto out; + } - if (fhp->fh_dverified) - goto check_type; /* * Look up the export entry. */ error = nfserr_stale; exp = exp_get(rqstp->rq_client, - u32_to_kdev_t(fh->fh_xdev), - u32_to_ino_t(fh->fh_xino)); - if (!exp) /* export entry revoked */ + u32_to_kdev_t(fh->fh_xdev), + u32_to_ino_t(fh->fh_xino)); + if (!exp) { + /* export entry revoked */ + nfsdstats.fh_stale++; goto out; + } /* Check if the request originated from a secure port. */ error = nfserr_perm; @@ -1079,32 +421,31 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) /* * Look up the dentry using the NFS file handle. */ - error = nfserr_noent; - dentry = find_fh_dentry(fh); - if (!dentry) + + dentry = find_fh_dentry(exp->ex_dentry->d_inode->i_sb, + fh, + !(exp->ex_flags & NFSEXP_NOSUBTREECHECK)); + + if (IS_ERR(dentry)) { + error = nfserrno(-PTR_ERR(dentry)); goto out; + } - /* - * Note: it's possible the returned dentry won't be the one in the - * file handle. We can correct the file handle for our use, but - * unfortunately the client will keep sending the broken one. Let's - * hope the lookup will keep patching things up. - */ fhp->fh_dentry = dentry; fhp->fh_export = exp; fhp->fh_dverified = 1; nfsd_nr_verified++; + inode = dentry->d_inode; + /* Type check. The correct error return for type mismatches * does not seem to be generally agreed upon. SunOS seems to * use EISDIR if file isn't S_IFREG; a comment in the NFSv3 * spec says this is incorrect (implementation notes for the * write call). */ -check_type: - dentry = fhp->fh_dentry; - inode = dentry->d_inode; - exp = fhp->fh_export; + + /* When is type ever negative? */ if (type > 0 && (inode->i_mode & S_IFMT) != type) { error = (type == S_IFDIR)? nfserr_notdir : nfserr_isdir; goto out; @@ -1118,35 +459,37 @@ check_type: * Security: Check that the export is valid for dentry <gam3@acm.org> */ error = 0; - if (fh->fh_dev != fh->fh_xdev) { - printk("fh_verify: Security: export on other device" - " (%d, %d).\n", fh->fh_dev, fh->fh_xdev); - error = nfserr_stale; - } else if (exp->ex_dentry != dentry) { - struct dentry *tdentry = dentry; - do { - tdentry = tdentry->d_parent; - if (exp->ex_dentry == tdentry) - break; - /* executable only by root and we can't be root */ - if (current->fsuid && - !(tdentry->d_inode->i_uid && - (tdentry->d_inode->i_mode & S_IXUSR)) && - !(tdentry->d_inode->i_gid && - (tdentry->d_inode->i_mode & S_IXGRP)) && - !(tdentry->d_inode->i_mode & S_IXOTH) && - (exp->ex_flags & NFSEXP_ROOTSQUASH)) { + if (!(exp->ex_flags & NFSEXP_NOSUBTREECHECK)) { + if (exp->ex_dentry != dentry) { + struct dentry *tdentry = dentry; + + do { + tdentry = tdentry->d_parent; + if (exp->ex_dentry == tdentry) + break; + /* executable only by root and we can't be root */ + if (current->fsuid + && (exp->ex_flags & NFSEXP_ROOTSQUASH) + && !(tdentry->d_inode->i_uid + && (tdentry->d_inode->i_mode & S_IXUSR)) + && !(tdentry->d_inode->i_gid + && (tdentry->d_inode->i_mode & S_IXGRP)) + && !(tdentry->d_inode->i_mode & S_IXOTH) + ) { + error = nfserr_stale; + nfsdstats.fh_stale++; + dprintk("fh_verify: no root_squashed access.\n"); + } + } while ((tdentry != tdentry->d_parent)); + if (exp->ex_dentry != tdentry) { error = nfserr_stale; -dprintk("fh_verify: no root_squashed access.\n"); + nfsdstats.fh_stale++; + printk("nfsd Security: %s/%s bad export.\n", + dentry->d_parent->d_name.name, + dentry->d_name.name); + goto out; } - } while (!IS_ROOT(tdentry)); - if (exp->ex_dentry != tdentry) { - error = nfserr_stale; - printk("nfsd Security: %s/%s bad export.\n", - dentry->d_parent->d_name.name, - dentry->d_name.name); - goto out; } } @@ -1155,9 +498,10 @@ dprintk("fh_verify: no root_squashed access.\n"); error = nfsd_permission(exp, dentry, access); } #ifdef NFSD_PARANOIA -if (error) -printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n", -dentry->d_parent->d_name.name, dentry->d_name.name, access, (error >> 24)); + if (error) { + printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n", + dentry->d_parent->d_name.name, dentry->d_name.name, access, (error >> 24)); + } #endif out: return error; @@ -1192,14 +536,17 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry) } fh_init(fhp); - fhp->fh_handle.fh_dcookie = dentry; + fhp->fh_handle.fh_dirino = ino_t_to_u32(parent->d_inode->i_ino); + fhp->fh_handle.fh_dev = kdev_t_to_u32(parent->d_inode->i_dev); + fhp->fh_handle.fh_xdev = kdev_t_to_u32(exp->ex_dev); + fhp->fh_handle.fh_xino = ino_t_to_u32(exp->ex_ino); + fhp->fh_handle.fh_dcookie = (struct dentry *)0xfeebbaca; if (inode) { fhp->fh_handle.fh_ino = ino_t_to_u32(inode->i_ino); + fhp->fh_handle.fh_generation = inode->i_generation; + if (S_ISDIR(inode->i_mode) || (exp->ex_flags & NFSEXP_NOSUBTREECHECK)) + fhp->fh_handle.fh_dirino = 0; } - fhp->fh_handle.fh_dirino = ino_t_to_u32(parent->d_inode->i_ino); - fhp->fh_handle.fh_dev = kdev_t_to_u32(parent->d_inode->i_dev); - fhp->fh_handle.fh_xdev = kdev_t_to_u32(exp->ex_dev); - fhp->fh_handle.fh_xino = ino_t_to_u32(exp->ex_ino); fhp->fh_dentry = dentry; /* our internal copy */ fhp->fh_export = exp; @@ -1211,6 +558,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry) /* * Update file handle information after changing a dentry. + * This is only called by nfsd_create */ void fh_update(struct svc_fh *fhp) @@ -1226,6 +574,10 @@ fh_update(struct svc_fh *fhp) if (!inode) goto out_negative; fhp->fh_handle.fh_ino = ino_t_to_u32(inode->i_ino); + fhp->fh_handle.fh_generation = inode->i_generation; + if (S_ISDIR(inode->i_mode) || (fhp->fh_export->ex_flags & NFSEXP_NOSUBTREECHECK)) + fhp->fh_handle.fh_dirino = 0; + out: return; @@ -1239,8 +591,7 @@ out_negative: } /* - * Release a file handle. If the file handle carries a dentry count, - * we add the dentry to the short-term cache rather than release it. + * Release a file handle. */ void fh_put(struct svc_fh *fhp) @@ -1251,10 +602,8 @@ fh_put(struct svc_fh *fhp) fhp->fh_dverified = 0; if (!dentry->d_count) goto out_bad; - if (!dentry->d_inode || !add_to_fhcache(dentry, 0)) { - dput(dentry); - nfsd_nr_put++; - } + dput(dentry); + nfsd_nr_put++; } return; @@ -1263,135 +612,3 @@ out_bad: dentry->d_parent->d_name.name, dentry->d_name.name); return; } - -/* - * Verify that the FH dentry is still a valid dentry pointer. - * After making some preliminary checks, we ask VFS to verify - * that it is indeed a dentry. - */ -static int nfsd_d_validate(struct dentry *dentry) -{ - unsigned long dent_addr = (unsigned long) dentry; - unsigned long min_addr = PAGE_OFFSET; - unsigned long max_addr = min_addr + (max_mapnr << PAGE_SHIFT); - unsigned long align_mask = 0x0F; - unsigned int len; - int valid = 0; - - if (dent_addr < min_addr) - goto bad_addr; - if (dent_addr > max_addr - sizeof(struct dentry)) - goto bad_addr; - if ((dent_addr & ~align_mask) != dent_addr) - goto bad_align; - if (!kern_addr_valid(dent_addr)) - goto bad_addr; - /* - * Looks safe enough to dereference ... - */ - len = dentry->d_name.len; - if (len > NFS_MAXNAMLEN) - goto out; - /* - * Note: d_validate doesn't dereference the parent pointer ... - * just combines it with the name hash to find the hash chain. - */ - valid = d_validate(dentry, dentry->d_parent, dentry->d_name.hash, len); - -out: - return valid; - -bad_addr: - printk(KERN_DEBUG "nfsd_d_validate: invalid address %lx\n", dent_addr); - goto out; -bad_align: - printk(KERN_DEBUG "nfsd_d_validate: unaligned address %lx\n", dent_addr); - goto out; -} - -/* - * Flush any cached dentries for the specified device - * or for all devices. - * - * This is called when revoking the last export for a - * device, so that it can be unmounted cleanly. - */ -void nfsd_fh_flush(kdev_t dev) -{ - struct fh_entry *fhe; - int i, pass = 2; - - fhe = &filetable[0]; - while (pass--) { - for (i = 0; i < NFSD_MAXFH; i++, fhe++) { - struct dentry *dentry = fhe->dentry; - if (!dentry) - continue; - if (dev && dentry->d_inode->i_dev != dev) - continue; - fhe->dentry = NULL; - dput(dentry); - nfsd_nr_put++; - } - fhe = &dirstable[0]; - } -} - -/* - * Free the dentry and path caches. - */ -void nfsd_fh_free(void) -{ - struct list_head *tmp; - int i; - - /* Flush dentries for all devices */ - nfsd_fh_flush(0); - - /* - * N.B. write a destructor for these lists ... - */ - i = 0; - while ((tmp = fixup_head.next) != &fixup_head) { - struct nfsd_fixup *fp; - fp = list_entry(tmp, struct nfsd_fixup, lru); - free_fixup_entry(fp); - i++; - } - printk(KERN_DEBUG "nfsd_fh_free: %d fixups freed\n", i); - - i = 0; - while ((tmp = path_inuse.next) != &path_inuse) { - struct nfsd_path *pe; - pe = list_entry(tmp, struct nfsd_path, lru); - free_path_entry(pe); - i++; - } - printk(KERN_DEBUG "nfsd_fh_free: %d paths freed\n", i); - - printk(KERN_DEBUG "nfsd_fh_free: verified %d, put %d\n", - nfsd_nr_verified, nfsd_nr_put); -} - -void nfsd_fh_init(void) -{ - /* Sanity check */ - extern void __my_nfsfh_is_too_big(void); - if (sizeof(struct nfs_fhbase) > 32) - __my_nfsfh_is_too_big(); - - memset(filetable, 0, NFSD_MAXFH*sizeof(struct fh_entry)); - memset(dirstable, 0, NFSD_MAXFH*sizeof(struct fh_entry)); - INIT_LIST_HEAD(&path_inuse); - INIT_LIST_HEAD(&fixup_head); - - printk(KERN_DEBUG - "nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH); - /* - * Display a warning if the ino_t is larger than 32 bits. - */ - if (sizeof(ino_t) > sizeof(__u32)) - printk(KERN_INFO - "NFSD: ino_t is %d bytes, using lower 4 bytes\n", - sizeof(ino_t)); -} diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index b7fa534e0..0057e1fa3 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -101,7 +101,7 @@ static void nfsd(struct svc_rqst *rqstp) { struct svc_serv *serv = rqstp->rq_server; - int oldumask, err, first = 0; + int oldumask, err; /* Lock module and set up kernel thread */ MOD_INC_USE_COUNT; @@ -117,7 +117,6 @@ nfsd(struct svc_rqst *rqstp) current->fs->umask = 0; if (!nfsd_active++) { nfssvc_boot = xtime; /* record boot time */ - first = 1; } lockd_up(); /* start lockd */ @@ -136,13 +135,8 @@ nfsd(struct svc_rqst *rqstp) * recvfrom routine. */ while ((err = svc_recv(serv, rqstp, - first?5*HZ:MAX_SCHEDULE_TIMEOUT)) == -EAGAIN) { - if (first && 1) { - exp_readlock(); - expire_all(); - exp_unlock(); - } - } + MAX_SCHEDULE_TIMEOUT)) == -EAGAIN) + ; if (err < 0) break; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index fa1753633..bc849dd8e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -234,6 +234,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) int ftype = 0; int imode; int err; + kernel_cap_t saved_cap = 0; if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE)) accmode |= MAY_WRITE; @@ -242,7 +243,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) /* Get inode */ err = fh_verify(rqstp, fhp, ftype, accmode); - if (err) + if (err || !iap->ia_valid) goto out; dentry = fhp->fh_dentry; @@ -252,7 +253,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap) if (err) goto out_nfserr; - /* The size case is special... */ + /* The size case is special. It changes the file as well as the attributes. */ if (iap->ia_valid & ATTR_SIZE) { if (!S_ISREG(inode->i_mode)) printk("nfsd_setattr: size change??\n"); @@ -264,15 +265,14 @@ printk("nfsd_setattr: size change??\n"); err = get_write_access(inode); if (err) goto out_nfserr; - /* N.B. Should we update the inode cache here? */ - inode->i_size = iap->ia_size; - if (inode->i_op && inode->i_op->truncate) - inode->i_op->truncate(inode); - mark_inode_dirty(inode); - put_write_access(inode); - iap->ia_valid &= ~ATTR_SIZE; - iap->ia_valid |= ATTR_MTIME; - iap->ia_mtime = CURRENT_TIME; + + err = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL, + iap->ia_size<inode->i_size ? iap->ia_size : inode->i_size, + abs(inode->i_size - iap->ia_size)); + + if (err) + goto out_nfserr; + DQUOT_INIT(inode); } imode = inode->i_mode; @@ -294,23 +294,32 @@ printk("nfsd_setattr: size change??\n"); } /* Change the attributes. */ - if (iap->ia_valid) { - kernel_cap_t saved_cap = 0; - iap->ia_valid |= ATTR_CTIME; - iap->ia_ctime = CURRENT_TIME; - if (current->fsuid != 0) { - saved_cap = current->cap_effective; - cap_clear(current->cap_effective); - } + + iap->ia_valid |= ATTR_CTIME; + if (current->fsuid != 0) { + saved_cap = current->cap_effective; + cap_clear(current->cap_effective); + } + if (iap->ia_valid & ATTR_SIZE) { + fh_lock(fhp); err = notify_change(dentry, iap); - if (current->fsuid != 0) - current->cap_effective = saved_cap; - if (err) - goto out_nfserr; - if (EX_ISSYNC(fhp->fh_export)) - write_inode_now(inode); + if (!err) { + vmtruncate(inode,iap->ia_size); + if (inode->i_op && inode->i_op->truncate) + inode->i_op->truncate(inode); + } + fh_unlock(fhp); + put_write_access(inode); } + else + err = notify_change(dentry, iap); + if (current->fsuid != 0) + current->cap_effective = saved_cap; + if (err) + goto out_nfserr; + if (EX_ISSYNC(fhp->fh_export)) + write_inode_now(inode); err = 0; out: return err; @@ -401,7 +410,6 @@ nfsd_close(struct file *filp) filp->f_op->release(inode, filp); if (filp->f_mode & FMODE_WRITE) { put_write_access(inode); - DQUOT_DROP(inode); } } @@ -548,7 +556,6 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, if ((stable || (stable = EX_ISSYNC(exp))) && !EX_WGATHER(exp)) file.f_flags |= O_SYNC; - fh_lock(fhp); /* lock inode */ file.f_pos = offset; /* set write offset */ /* Write the data. */ @@ -580,8 +587,6 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, current->cap_effective = saved_cap; } - fh_unlock(fhp); /* unlock inode */ - if (err >= 0 && stable) { static unsigned long last_ino = 0; static kdev_t last_dev = NODEV; @@ -651,9 +656,13 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, err = nfserr_perm; if (!flen) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE); - if (err) - goto out; + + /* from mkdir it won't be verified, from create it will */ + if (!fhp->fh_dverified) { + err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE); + if (err) + goto out; + } dentry = fhp->fh_dentry; dirp = dentry->d_inode; @@ -731,7 +740,6 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, */ DQUOT_INIT(dirp); err = opfunc(dirp, dchild, iap->ia_mode, rdev); - DQUOT_DROP(dirp); if (err < 0) goto out_nfserr; @@ -786,6 +794,11 @@ nfsd_truncate(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned long size) err = get_write_access(inode); if (err) goto out_nfserr; + err = locks_verify_area(FLOCK_VERIFY_WRITE, inode, NULL, + size<inode->i_size ? size : inode->i_size, + abs(inode->i_size - size)); + if (err) + goto out_nfserr; /* Things look sane, lock and do it. */ fh_lock(fhp); @@ -797,15 +810,14 @@ nfsd_truncate(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned long size) cap_clear(current->cap_effective); } err = notify_change(dentry, &newattrs); - if (current->fsuid != 0) - current->cap_effective = saved_cap; if (!err) { vmtruncate(inode, size); if (inode->i_op && inode->i_op->truncate) inode->i_op->truncate(inode); } + if (current->fsuid != 0) + current->cap_effective = saved_cap; put_write_access(inode); - DQUOT_DROP(inode); fh_unlock(fhp); out_nfserr: if (err) @@ -902,7 +914,6 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (!dnew->d_inode) { DQUOT_INIT(dirp); err = dirp->i_op->symlink(dirp, dnew, path); - DQUOT_DROP(dirp); if (!err) { if (EX_ISSYNC(fhp->fh_export)) write_inode_now(dirp); @@ -981,7 +992,6 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, DQUOT_INIT(dirp); err = dirp->i_op->link(dold, dirp, dnew); - DQUOT_DROP(dirp); if (!err) { if (EX_ISSYNC(ffhp->fh_export)) { write_inode_now(dirp); @@ -1105,8 +1115,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, } } else dprintk("nfsd: Caught race in nfsd_rename"); - DQUOT_DROP(fdir); - DQUOT_DROP(tdir); nfsd_double_up(&tdir->i_sem, &fdir->i_sem); dput(ndentry); @@ -1157,7 +1165,6 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, goto out; } - expire_by_dentry(rdentry); if (type != S_IFDIR) { /* It's UNLINK */ @@ -1168,7 +1175,6 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, err = vfs_unlink(dirp, rdentry); - DQUOT_DROP(dirp); fh_unlock(fhp); dput(rdentry); @@ -1188,7 +1194,6 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, err = vfs_rmdir(dirp, rdentry); rdentry->d_count--; - DQUOT_DROP(dirp); if (!fhp->fh_post_version) fhp->fh_post_version = dirp->i_version; fhp->fh_locked = 0; diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index a30f382a6..539b60da9 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c @@ -404,9 +404,6 @@ romfs_readpage(struct file * file, struct page * page) get_page(page); buf = page_address(page); - /* hack? */ - page->owner = current; - offset = page->offset; if (offset < inode->i_size) { avail = inode->i_size-offset; diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c index 950ecb3c1..efb472d4b 100644 --- a/fs/smbfs/cache.c +++ b/fs/smbfs/cache.c @@ -43,16 +43,16 @@ printk_name(const char *name, int len) * the page if it isn't in memory. As I understand it the rest of the * smb-cache code assumes we return a locked page. */ -unsigned long -get_cached_page(struct inode * inode, unsigned long offset, int new) +static unsigned long +get_cached_page(struct address_space *mapping, unsigned long offset, int new) { struct page * page; struct page ** hash; unsigned long new_page; again: - hash = page_hash(inode, offset); - page = __find_lock_page(inode, offset, hash); + hash = page_hash(mapping, offset); + page = __find_lock_page(mapping, offset, hash); if(!page && new) { /* not in cache, alloc a new page */ new_page = page_cache_alloc(); @@ -60,7 +60,7 @@ get_cached_page(struct inode * inode, unsigned long offset, int new) return 0; clear_page(new_page); /* smb code assumes pages are zeroed */ page = page_cache_entry(new_page); - if (add_to_page_cache_unique(page, inode, offset, hash)) { + if (add_to_page_cache_unique(page, mapping, offset, hash)) { /* Hmm, a page has materialized in the cache. Fine. Go back and get that page instead ... throwing away this one first. */ @@ -75,10 +75,10 @@ get_cached_page(struct inode * inode, unsigned long offset, int new) return page_address(page); } -static inline struct inode * +static inline struct address_space * get_cache_inode(struct cache_head *cachep) { - return (mem_map + MAP_NR((unsigned long) cachep))->inode; + return (mem_map + MAP_NR((unsigned long) cachep))->mapping; } /* @@ -89,14 +89,14 @@ get_cache_inode(struct cache_head *cachep) struct cache_head * smb_get_dircache(struct dentry * dentry) { - struct inode * inode = dentry->d_inode; + struct address_space * mapping = &dentry->d_inode->i_data; struct cache_head * cachep; #ifdef SMBFS_DEBUG_VERBOSE printk("smb_get_dircache: finding cache for %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); #endif - cachep = (struct cache_head *) get_cached_page(inode, 0, 1); + cachep = (struct cache_head *) get_cached_page(mapping, 0, 1); if (!cachep) goto out; if (cachep->valid) @@ -118,7 +118,7 @@ printk("smb_get_dircache: cache %s/%s has existing block!\n", dentry->d_parent->d_name.name, dentry->d_name.name); #endif offset = PAGE_SIZE + (i << PAGE_SHIFT); - block = (struct cache_block *) get_cached_page(inode, + block = (struct cache_block *) get_cached_page(mapping, offset, 0); if (!block) goto out; @@ -187,7 +187,7 @@ void smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry, off_t fpos) { - struct inode * inode = get_cache_inode(cachep); + struct address_space * mapping = get_cache_inode(cachep); struct cache_index * index; struct cache_block * block; unsigned long page_off; @@ -195,8 +195,8 @@ smb_add_to_cache(struct cache_head * cachep, struct cache_dirent *entry, unsigned int needed = len + sizeof(struct cache_entry); #ifdef SMBFS_DEBUG_VERBOSE -printk("smb_add_to_cache: cache inode %p, status %d, adding ", - inode, cachep->status); +printk("smb_add_to_cache: cache %p, status %d, adding ", + mapping, cachep->status); printk_name(entry->name, entry->len); printk(" at %ld\n", fpos); #endif @@ -251,14 +251,14 @@ printk("smb_add_to_cache: new index already has block!\n"); get_block: cachep->pages++; page_off = PAGE_SIZE + (cachep->idx << PAGE_SHIFT); - block = (struct cache_block *) get_cached_page(inode, page_off, 1); + block = (struct cache_block *) get_cached_page(mapping, page_off, 1); if (block) { index->block = block; index->space = PAGE_SIZE; #ifdef SMBFS_DEBUG_VERBOSE -printk("smb_add_to_cache: inode=%p, pages=%d, block at %ld\n", -inode, cachep->pages, page_off); +printk("smb_add_to_cache: mapping=%p, pages=%d, block at %ld\n", +mapping, cachep->pages, page_off); #endif goto add_entry; } diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h index f451a608a..10c7c72b2 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -28,6 +28,10 @@ /* * Bit simplified and optimized by Jan Hubicka * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999. + * + * isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added, + * isa_read[wl] and isa_write[wl] fixed + * - Arnaldo Carvalho de Melo <acme@conectiva.com.br> */ #ifdef SLOW_IO_BY_JUMPING @@ -192,11 +196,14 @@ extern void iounmap(void *addr); #define __ISA_IO_base ((char *)(PAGE_OFFSET)) #define isa_readb(a) readb(__ISA_IO_base + (a)) -#define isa_readw(a) readb(__ISA_IO_base + (a)) -#define isa_readl(a) readb(__ISA_IO_base + (a)) +#define isa_readw(a) readw(__ISA_IO_base + (a)) +#define isa_readl(a) readl(__ISA_IO_base + (a)) #define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a)) -#define isa_writew(w,a) writeb(w,__ISA_IO_base + (a)) -#define isa_writel(l,a) writeb(l,__ISA_IO_base + (a)) +#define isa_writew(w,a) writew(w,__ISA_IO_base + (a)) +#define isa_writel(l,a) writel(l,__ISA_IO_base + (a)) +#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c)) /* * Again, i386 does not require mem IO specific function. diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index 11577168a..c7109c721 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -84,9 +84,7 @@ extern int console_loglevel; * see^H^H^Hhear bugs in early bootup as well! */ #define BUG() do { \ - __asm__ __volatile__ ("movb $0x3,%al; outb %al,$0x61"); \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ - console_loglevel = 0; \ __asm__ __volatile__(".byte 0x0f,0x0b"); \ } while (0) diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h index a8a05239c..02f90e21d 100644 --- a/include/asm-i386/pgtable-2level.h +++ b/include/asm-i386/pgtable-2level.h @@ -32,7 +32,7 @@ extern inline int pgd_none(pgd_t pgd) { return 0; } extern inline int pgd_bad(pgd_t pgd) { return 0; } extern inline int pgd_present(pgd_t pgd) { return 1; } -#define pgd_clear(xp) do { pgd_val(*(xp)) = 0; } while (0) +#define pgd_clear(xp) do { } while (0) #define pgd_page(pgd) \ ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 88f066864..ddd5e165e 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -407,8 +407,8 @@ extern inline unsigned long thread_saved_pc(struct thread_struct *t) } #define THREAD_SIZE (2*PAGE_SIZE) -extern struct task_struct * alloc_task_struct(void); -extern void free_task_struct(struct task_struct *); +#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) +#define free_task_struct(p) free_pages((unsigned long) (p), 1) #define init_task (init_task_union.task) #define init_stack (init_task_union.stack) diff --git a/include/asm-i386/resource.h b/include/asm-i386/resource.h index 0f4089694..0f43dba41 100644 --- a/include/asm-i386/resource.h +++ b/include/asm-i386/resource.h @@ -22,16 +22,16 @@ #define INIT_RLIMITS \ { \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { _STK_LIM, LONG_MAX }, \ - { 0, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { 0, 0 }, \ - { INR_OPEN, INR_OPEN }, \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { _STK_LIM, RLIM_INFINITY }, \ + { 0, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ + { INR_OPEN, INR_OPEN }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ } #endif /* __KERNEL__ */ diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h index 3997b2aae..7b0cddf96 100644 --- a/include/asm-i386/semaphore.h +++ b/include/asm-i386/semaphore.h @@ -98,8 +98,6 @@ asmlinkage int __down_interruptible(struct semaphore * sem); asmlinkage int __down_trylock(struct semaphore * sem); asmlinkage void __up(struct semaphore * sem); -extern spinlock_t semaphore_wake_lock; - /* * This is ugly, but we want the default case to fall through. * "down_failed" is a special asm handler that calls the C diff --git a/include/asm-i386/string-486.h b/include/asm-i386/string-486.h index 4b5c5fe25..4c2531712 100644 --- a/include/asm-i386/string-486.h +++ b/include/asm-i386/string-486.h @@ -15,7 +15,9 @@ * * Split into 2 CPU specific files by Alan Cox to keep #ifdef noise down. * - * 99/9/15 Proper reg args for newer gcc/egcs - Petkan (petkan@spct.net) + * 1999/10/5 Proper register args for newer GCCs and minor bugs + * fixed - Petko Manolov (petkan@spct.net) + * 1999/10/14 3DNow memscpy() added - Petkan */ #define __HAVE_ARCH_STRCPY @@ -103,7 +105,7 @@ __asm__ __volatile__( "incl %1\n\t" "testb %b0,%b0\n\t" "jne 2b\n" - "3:\txorl %0,%0\n\t" + "3:\txorb %0,%0\n\t" "movb %b0,(%1)\n\t" :"=q" (dummy), "=r" (tmp), "=r" (src), "=r" (count) :"1" (tmp), "2" (src), "3" (count) @@ -254,6 +256,7 @@ __asm__ __volatile__( return __res-cs; } +#if 0 #define __HAVE_ARCH_STRPBRK extern inline char * strpbrk(const char * cs,const char * ct) { @@ -261,7 +264,7 @@ int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" @@ -270,7 +273,7 @@ __asm__ __volatile__( "1:\tlodsb\n\t" "testb %%al,%%al\n\t" "je 2f\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "movl %%edx,%%ecx\n\t" "repne\n\t" "scasb\n\t" @@ -284,7 +287,9 @@ __asm__ __volatile__( :"dx", "di"); return __res; } +#endif +#if 0 #define __HAVE_ARCH_STRSTR extern inline char * strstr(const char * cs,const char * ct) { @@ -292,13 +297,13 @@ int d0, d1; register char * __res; __asm__ __volatile__( "cld\n\t" \ - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ "movl %%ecx,%%edx\n" - "1:\tmovl %4,%%edi\n\t" + "1:\tmovl %6,%%edi\n\t" "movl %%esi,%%eax\n\t" "movl %%edx,%%ecx\n\t" "repe\n\t" @@ -315,6 +320,7 @@ __asm__ __volatile__( :"dx", "di"); return __res; } +#endif #define __HAVE_ARCH_STRLEN extern inline size_t strlen(const char * s) @@ -343,7 +349,7 @@ extern inline size_t strnlen(const char * s, size_t count) int d0; register int __res; __asm__ __volatile__( - "movl %1,%0\n\t" + "movl %3,%0\n\t" "jmp 2f\n" "1:\tcmpb $0,(%0)\n\t" "je 3f\n\t" @@ -351,13 +357,14 @@ __asm__ __volatile__( "2:\tdecl %2\n\t" "cmpl $-1,%2\n\t" "jne 1b\n" - "3:\tsubl %1,%0" + "3:\tsubl %3,%0" :"=a" (__res), "=&d" (d0) :"1" (count), "c" (s)); return __res; } /* end of additional stuff */ +#if 0 #define __HAVE_ARCH_STRTOK extern inline char * strtok(char * s,const char * ct) { @@ -418,19 +425,7 @@ __asm__ __volatile__( :"ax","cx","dx","di","memory"); return __res; } - -#define __memcpy_c(d,s,count) \ -((count%4==0) ? \ - __memcpy_by4((d),(s),(count)) : \ - ((count%2==0) ? \ - __memcpy_by2((d),(s),(count)) : \ - __memcpy_g((d),(s),(count)))) - -#define __HAVE_ARCH_MEMCPY -#define memcpy(d,s,count) \ -(__builtin_constant_p(count) ? \ - __memcpy_c((d),(s),(count)) : \ - __memcpy_g((d),(s),(count))) +#endif /* * These ought to get tweaked to do some cache priming. @@ -494,6 +489,63 @@ __asm__ __volatile__ ( return (to); } +#define __memcpy_c(d,s,count) \ +((count%4==0) ? \ + __memcpy_by4((d),(s),(count)) : \ + ((count%2==0) ? \ + __memcpy_by2((d),(s),(count)) : \ + __memcpy_g((d),(s),(count)))) + +#define __memcpy(d,s,count) \ +(__builtin_constant_p(count) ? \ + __memcpy_c((d),(s),(count)) : \ + __memcpy_g((d),(s),(count))) + +#define __HAVE_ARCH_MEMCPY + +#include <linux/config.h> + +#ifdef CONFIG_X86_USE_3DNOW + +#include <linux/spinlock.h> +#include <asm/system.h> +#include <asm/ptrace.h> +#include <linux/smp.h> +#include <linux/interrupt.h> +#include <asm/mmx.h> + +/* +** This CPU favours 3DNow strongly (eg AMD K6-II, K6-III, Athlon) +*/ + +extern inline void * __constant_memcpy3d(void * to, const void * from, size_t len) +{ + if(len<512 || in_interrupt()) + return __memcpy_c(to, from, len); + return _mmx_memcpy(to, from, len); +} + +extern __inline__ void *__memcpy3d(void *to, const void *from, size_t len) +{ + if(len<512 || in_interrupt()) + return __memcpy_g(to, from, len); + return _mmx_memcpy(to, from, len); +} + +#define memcpy(d, s, count) \ +(__builtin_constant_p(count) ? \ + __constant_memcpy3d((d),(s),(count)) : \ + __memcpy3d((d),(s),(count))) + +#else /* CONFIG_X86_USE_3DNOW */ + +/* +** Generic routines +*/ + +#define memcpy(d, s, count) __memcpy(d, s, count) + +#endif /* CONFIG_X86_USE_3DNOW */ #define __HAVE_ARCH_MEMMOVE extern inline void * memmove(void * dest,const void * src, size_t n) diff --git a/include/asm-i386/termios.h b/include/asm-i386/termios.h index 6d576ea00..9e55723d3 100644 --- a/include/asm-i386/termios.h +++ b/include/asm-i386/termios.h @@ -53,6 +53,7 @@ struct termio { #define N_IRDA 11 /* Linux IR - http://www.cs.uit.no/~dagb/irda/irda.html */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 /* synchronous PPP */ #ifdef __KERNEL__ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index d4c77dd78..176ea2696 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -1,12 +1,12 @@ -/* $Id: io.h,v 1.7 1999/10/09 00:01:43 ralf Exp $ +/* $Id: io.h,v 1.8 2000/01/27 01:05:37 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1994, 1995 Waldorf GmbH - * Copyright (C) 1994 - 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1994 - 2000 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #ifndef _ASM_IO_H #define _ASM_IO_H @@ -184,11 +184,15 @@ extern inline void iounmap(void *addr) #define __ISA_IO_base ((char *)(PAGE_OFFSET)) #define isa_readb(a) readb(a) -#define isa_readw(a) readb(a) -#define isa_readl(a) readb(a) +#define isa_readw(a) readw(a) +#define isa_readl(a) readl(a) #define isa_writeb(b,a) writeb(b,a) -#define isa_writew(w,a) writeb(w,a) -#define isa_writel(l,a) writeb(l,a) +#define isa_writew(w,a) writew(w,a) +#define isa_writel(l,a) writel(l,a) + +#define isa_memset_io(a,b,c) memset_io((a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio((a),(b),(c)) /* * We don't have csum_partial_copy_fromio() yet, so we cheat here and diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index b21f9d874..e5ba85843 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.21 1999/10/12 17:33:50 harald Exp $ +/* $Id: processor.h,v 1.22 1999/12/04 03:59:12 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -189,7 +189,6 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) -#define forget_segments() do { } while (0) /* * Return saved PC of a blocked thread. diff --git a/include/asm-mips/resource.h b/include/asm-mips/resource.h index d02021e0d..c628852f1 100644 --- a/include/asm-mips/resource.h +++ b/include/asm-mips/resource.h @@ -1,4 +1,4 @@ -/* $Id: resource.h,v 1.2 1999/01/04 16:09:25 ralf Exp $ +/* $Id: resource.h,v 1.3 1999/10/09 00:01:43 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -29,16 +29,16 @@ #define INIT_RLIMITS \ { \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { _STK_LIM, LONG_MAX }, \ - { 0, LONG_MAX }, \ - { INR_OPEN, INR_OPEN }, \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { 0, 0 }, \ - { LONG_MAX, LONG_MAX }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { _STK_LIM, RLIM_INFINITY }, \ + { 0, RLIM_INFINITY }, \ + { INR_OPEN, INR_OPEN }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ } #endif /* __KERNEL__ */ diff --git a/include/asm-mips/termios.h b/include/asm-mips/termios.h index 82823ab40..e7688850b 100644 --- a/include/asm-mips/termios.h +++ b/include/asm-mips/termios.h @@ -1,5 +1,4 @@ -/* - * ioctls for Linux/MIPS. +/* $Id: termios.h,v 1.8 2000/01/27 22:49:42 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -7,8 +6,8 @@ * * Copyright (C) 1995, 1996 by Ralf Baechle */ -#ifndef __ASM_MIPS_TERMIOS_H -#define __ASM_MIPS_TERMIOS_H +#ifndef _ASM_TERMIOS_H +#define _ASM_TERMIOS_H #include <asm/termbits.h> #include <asm/ioctls.h> @@ -100,6 +99,7 @@ struct termio { #define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 /* synchronous PPP */ #ifdef __KERNEL__ @@ -141,4 +141,4 @@ struct termio { #endif /* defined(__KERNEL__) */ -#endif /* __ASM_MIPS_TERMIOS_H */ +#endif /* _ASM_TERMIOS_H */ diff --git a/include/asm-mips64/io.h b/include/asm-mips64/io.h index 09976d4b0..be76a8910 100644 --- a/include/asm-mips64/io.h +++ b/include/asm-mips64/io.h @@ -1,12 +1,12 @@ -/* $Id: io.h,v 1.4 2000/01/25 21:58:42 kanoj Exp $ +/* $Id: io.h,v 1.5 2000/01/27 01:05:37 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1994, 1995 Waldorf GmbH - * Copyright (C) 1994 - 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1994 - 2000 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #ifndef _ASM_IO_H #define _ASM_IO_H @@ -167,11 +167,15 @@ extern inline void iounmap(void *addr) #define __ISA_IO_base ((char *)(PAGE_OFFSET)) #define isa_readb(a) readb(a) -#define isa_readw(a) readb(a) -#define isa_readl(a) readb(a) +#define isa_readw(a) readw(a) +#define isa_readl(a) readl(a) #define isa_writeb(b,a) writeb(b,a) -#define isa_writew(w,a) writeb(w,a) -#define isa_writel(l,a) writeb(l,a) +#define isa_writew(w,a) writew(w,a) +#define isa_writel(l,a) writel(l,a) + +#define isa_memset_io(a,b,c) memset_io((a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio((a),(b),(c)) /* * We don't have csum_partial_copy_fromio() yet, so we cheat here and diff --git a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h index 1bb9240e8..b79dfceb2 100644 --- a/include/asm-mips64/processor.h +++ b/include/asm-mips64/processor.h @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.5 2000/01/16 01:40:43 ralf Exp $ +/* $Id: processor.h,v 1.6 2000/01/17 23:32:47 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -192,7 +192,6 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); /* Copy and release all segment info associated with a VM */ #define copy_segments(p, mm) do { } while(0) #define release_segments(mm) do { } while(0) -#define forget_segments() do { } while (0) /* * Return saved PC of a blocked thread. diff --git a/include/asm-mips64/resource.h b/include/asm-mips64/resource.h index 771cb260d..6f317289f 100644 --- a/include/asm-mips64/resource.h +++ b/include/asm-mips64/resource.h @@ -1,4 +1,4 @@ -/* $Id: resource.h,v 1.1 1999/08/18 23:37:52 ralf Exp $ +/* $Id: resource.h,v 1.2 1999/10/09 00:01:43 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -30,16 +30,16 @@ #define INIT_RLIMITS \ { \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { _STK_LIM, LONG_MAX }, \ - { 0, LONG_MAX }, \ - { NR_OPEN, NR_OPEN }, \ - { LONG_MAX, LONG_MAX }, \ - { LONG_MAX, LONG_MAX }, \ - { 0, 0 }, \ - { LONG_MAX, LONG_MAX }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { _STK_LIM, RLIM_INFINITY }, \ + { 0, RLIM_INFINITY }, \ + { NR_OPEN, NR_OPEN }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ + { 0, 0 }, \ + { RLIM_INFINITY, RLIM_INFINITY }, \ } #endif /* __KERNEL__ */ diff --git a/include/asm-mips64/termios.h b/include/asm-mips64/termios.h index bab195a83..05eb9c253 100644 --- a/include/asm-mips64/termios.h +++ b/include/asm-mips64/termios.h @@ -1,4 +1,4 @@ -/* $Id$ +/* $Id: termios.h,v 1.1 1999/08/18 23:37:53 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -99,6 +99,7 @@ struct termio { #define N_IRDA 11 /* Linux IrDa - http://www.cs.uit.no/~dagb/irda/irda.html */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ #define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 /* synchronous PPP */ #ifdef __KERNEL__ diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h index dfd6a240b..5cac2be5e 100644 --- a/include/asm-ppc/dma.h +++ b/include/asm-ppc/dma.h @@ -99,18 +99,21 @@ extern unsigned long ISA_DMA_THRESHOLD; /* used in nasty hack for sound - see prep_setup_arch() -- Cort */ extern long ppc_cs4232_dma, ppc_cs4232_dma2; -#ifdef CONFIG_CS4232 +#if defined(CONFIG_CS4232) +#if defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC) #define SND_DMA1 ppc_cs4232_dma #define SND_DMA2 ppc_cs4232_dma2 -#else -#ifdef CONFIG_MSS +#else /* !CONFIG_PREP && !CONFIG_ALL_PPC */ +#define SND_DMA1 -1 +#define SND_DMA2 -1 +#endif /* !CONFIG_PREP */ +#elif defined(CONFIG_MSS) #define SND_DMA1 CONFIG_MSS_DMA #define SND_DMA2 CONFIG_MSS_DMA2 #else #define SND_DMA1 -1 #define SND_DMA2 -1 #endif -#endif /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -203,6 +206,7 @@ static __inline__ void enable_dma(unsigned int dmanr) */ unsigned char ucDmaCmd=0x00; +#if defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC) if(_prep_type==_PREP_Radstone) { switch(ucSystemType) @@ -227,6 +231,7 @@ static __inline__ void enable_dma(unsigned int dmanr) } } } +#endif /* CONFIG_PREP || CONFIG_ALL_PPC */ if (dmanr != 4) { diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index ad2eba41f..673d74397 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -423,10 +423,10 @@ extern struct pgtable_cache_struct { #define pgtable_cache_size (quicklists.pgtable_cache_sz) extern unsigned long *zero_cache; /* head linked list of pre-zero'd pages */ -extern unsigned long zero_sz; /* # currently pre-zero'd pages */ -extern unsigned long zeropage_hits; /* # zero'd pages request that we've done */ -extern unsigned long zeropage_calls; /* # zero'd pages request that've been made */ -extern unsigned long zerototal; /* # pages zero'd over time */ +extern atomic_t zero_sz; /* # currently pre-zero'd pages */ +extern atomic_t zeropage_hits; /* # zero'd pages request that we've done */ +extern atomic_t zeropage_calls; /* # zero'd pages request that've been made */ +extern atomic_t zerototal; /* # pages zero'd over time */ #define zero_quicklist (zero_cache) #define zero_cache_sz (zero_sz) @@ -440,12 +440,9 @@ extern unsigned long get_zero_page_fast(void); extern __inline__ pgd_t *get_pgd_slow(void) { pgd_t *ret, *init; - - if ( (ret = (pgd_t *)get_zero_page_fast()) == NULL ) - { - if ( (ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL ) - memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); - } + /*if ( (ret = (pgd_t *)get_zero_page_fast()) == NULL )*/ + if ( (ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL ) + memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); if (ret) { init = pgd_offset(&init_mm, 0); memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, @@ -489,7 +486,7 @@ extern __inline__ pte_t *get_pte_fast(void) pte_quicklist = (unsigned long *)(*ret); ret[0] = ret[1]; pgtable_cache_size--; - } + } return (pte_t *)ret; } diff --git a/include/asm-sh/dma.h b/include/asm-sh/dma.h index 4561b3d05..16f54584c 100644 --- a/include/asm-sh/dma.h +++ b/include/asm-sh/dma.h @@ -6,6 +6,10 @@ #define MAX_DMA_CHANNELS 8 +/* The maximum address that we can perform a DMA transfer to on this platform */ +/* XXX: This is not applicable to SuperH, just needed for alloc_bootmem */ +#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) + extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ extern void free_dma(unsigned int dmanr); /* release it again */ diff --git a/include/asm-sh/highmem.h b/include/asm-sh/highmem.h new file mode 100644 index 000000000..bd5564aea --- /dev/null +++ b/include/asm-sh/highmem.h @@ -0,0 +1,85 @@ +/* + * highmem.h: virtual kernel memory mappings for high memory + * + * Used in CONFIG_HIGHMEM systems for memory pages which + * are not addressable by direct kernel virtual adresses. + * + * Copyright (C) 1999 Gerhard Wichert, Siemens AG + * Gerhard.Wichert@pdb.siemens.de + * + * + * Redesigned the x86 32-bit VM architecture to deal with + * up to 16 Terrabyte physical memory. With current x86 CPUs + * we now support up to 64 Gigabytes physical RAM. + * + * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> + */ + +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#include <linux/init.h> + +/* undef for production */ +#define HIGHMEM_DEBUG 1 + +/* declarations for highmem.c */ +extern unsigned long highstart_pfn, highend_pfn; + +extern pte_t *kmap_pte; +extern pgprot_t kmap_prot; + +extern void kmap_init(void) __init; + +/* kmap helper functions necessary to access the highmem pages in kernel */ +#include <asm/pgtable.h> +#include <asm/kmap_types.h> + +extern inline unsigned long kmap(struct page *page, enum km_type type) +{ + if (page < highmem_start_page) + return page_address(page); + { + enum fixed_addresses idx = type+KM_TYPE_NR*smp_processor_id(); + unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN+idx); + +#if HIGHMEM_DEBUG + if (!pte_none(*(kmap_pte-idx))) + { + __label__ here; + here: + printk(KERN_ERR "not null pte on CPU %d from %p\n", + smp_processor_id(), &&here); + } +#endif + set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + __flush_tlb_one(vaddr); + + return vaddr; + } +} + +extern inline void kunmap(unsigned long vaddr, enum km_type type) +{ +#if HIGHMEM_DEBUG + enum fixed_addresses idx = type+KM_TYPE_NR*smp_processor_id(); + if ((vaddr & PAGE_MASK) == __fix_to_virt(FIX_KMAP_BEGIN+idx)) + { + /* force other mappings to Oops if they'll try to access + this pte without first remap it */ + pte_clear(kmap_pte-idx); + __flush_tlb_one(vaddr); + } +#endif +} + +extern inline void kmap_check(void) +{ +#if HIGHMEM_DEBUG + int idx_base = KM_TYPE_NR*smp_processor_id(), i; + for (i = idx_base; i < idx_base+KM_TYPE_NR; i++) + if (!pte_none(*(kmap_pte-i))) + BUG(); +#endif +} +#endif /* _ASM_HIGHMEM_H */ diff --git a/include/asm-sh/mmu_context.h b/include/asm-sh/mmu_context.h index d08cf7863..aca17690f 100644 --- a/include/asm-sh/mmu_context.h +++ b/include/asm-sh/mmu_context.h @@ -141,7 +141,7 @@ extern __inline__ void switch_mm(struct mm_struct *prev, struct task_struct *tsk, unsigned int cpu) { if (prev != next) { - unsigned long __pgdir = __pa(next->pgd); + unsigned long __pgdir = (unsigned long)next->pgd; __asm__ __volatile__("mov.l %0,%1": \ :"r" (__pgdir), "m" (__m(MMU_TTB))); diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 9c8b732b2..228c8d2d8 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -23,12 +23,9 @@ #ifdef __KERNEL__ #ifndef __ASSEMBLY__ -#define STRICT_MM_TYPECHECKS - #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) -#ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ @@ -47,26 +44,6 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -#else -/* - * .. while these make it easier on the compiler - */ -typedef unsigned long pte_t; -typedef unsigned long pmd_t; -typedef unsigned long pgd_t; -typedef unsigned long pgprot_t; - -#define pte_val(x) (x) -#define pmd_val(x) (x) -#define pgd_val(x) (x) -#define pgprot_val(x) (x) - -#define __pte(x) (x) -#define __pmd(x) (x) -#define __pgd(x) (x) -#define __pgprot(x) (x) - -#endif #endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ @@ -75,7 +52,7 @@ typedef unsigned long pgprot_t; /* * IF YOU CHANGE THIS, PLEASE ALSO CHANGE * - * arch/sh/vmlinux.lds + * arch/sh/vmlinux.lds.S * * which has the same constant encoded.. */ @@ -89,8 +66,15 @@ typedef unsigned long pgprot_t; #define MAP_NR(addr) ((__pa(addr)-__MEMORY_START) >> PAGE_SHIFT) #ifndef __ASSEMBLY__ + +extern int console_loglevel; + +/* + * Tell the user there is some problem. + */ #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + console_loglevel = 0; \ asm volatile("nop"); \ } while (0) diff --git a/include/asm-sh/pgtable-2level.h b/include/asm-sh/pgtable-2level.h new file mode 100644 index 000000000..ebfa410b3 --- /dev/null +++ b/include/asm-sh/pgtable-2level.h @@ -0,0 +1,62 @@ +#ifndef __ASM_SH_PGTABLE_2LEVEL_H +#define __ASM_SH_PGTABLE_2LEVEL_H + +/* + * traditional two-level paging structure: + */ + +#define PGDIR_SHIFT 22 +#define PTRS_PER_PGD 1024 + +/* + * this is two-level, so we don't really have any + * PMD directory physically. + */ +#define PMD_SHIFT 22 +#define PTRS_PER_PMD 1 + +#define PTRS_PER_PTE 1024 + +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#define pmd_ERROR(e) \ + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +extern inline int pgd_none(pgd_t pgd) { return 0; } +extern inline int pgd_bad(pgd_t pgd) { return 0; } +extern inline int pgd_present(pgd_t pgd) { return 1; } +#define pgd_clear(xp) do { pgd_val(*(xp)) = 0; } while (0) + +#define pgd_page(pgd) \ +((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) + +extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +{ + return (pmd_t *) dir; +} + +extern __inline__ pmd_t *get_pmd_fast(void) +{ + return (pmd_t *)0; +} + +extern __inline__ void free_pmd_fast(pmd_t *pmd) { } +extern __inline__ void free_pmd_slow(pmd_t *pmd) { } + +extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) +{ + if (!pgd) + BUG(); + return (pmd_t *) pgd; +} + +#define SWP_ENTRY(type,offset) __pte((((type) << 1) | ((offset) << 8))) + +#endif /* __ASM_SH_PGTABLE_2LEVEL_H */ diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index cf5eab380..7ea944afa 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -65,25 +65,36 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); #endif /* !__ASSEMBLY__ */ -/* PMD_SHIFT determines the size of the area a second-level page table can map */ -#define PMD_SHIFT 22 +#define pgd_quicklist (current_cpu_data.pgd_quick) +#define pmd_quicklist ((unsigned long *)0) +#define pte_quicklist (current_cpu_data.pte_quick) +#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) + +#include <asm/pgtable-2level.h> + +/* + * Certain architectures need to do special things when PTEs + * within a page table are directly modified. Thus, the following + * hook is made available. + */ +#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) + +#define __beep() asm("") + #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) - -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT 22 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -/* - * Entries per page directory level: we use two-level, so - * we don't really have any PMD directory physically. - */ -#define PTRS_PER_PTE 1024 -#define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 1024 #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) +#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) + +#define TWOLEVEL_PGDIR_SHIFT 22 +#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT) +#define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS) + #ifndef __ASSEMBLY__ #define VMALLOC_START P3SEG #define VMALLOC_VMADDR(x) ((unsigned long)(x)) @@ -96,7 +107,7 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); /* 0x010 */ #define _PAGE_RW 0x020 /* PR0-bit : write access allowed */ #define _PAGE_USER 0x040 /* PR1-bit : user space access allowed */ -/* 0x080 */ +#define _PAGE_PROTNONE 0x080 /* software: if not present */ #define _PAGE_PRESENT 0x100 /* V-bit : page is valid */ #if defined(__sh3__) @@ -115,7 +126,7 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) -#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) @@ -156,154 +167,101 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); extern pte_t __bad_page(void); extern pte_t * __bad_pagetable(void); +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ extern unsigned long empty_zero_page[1024]; +#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page)) -#define BAD_PAGETABLE __bad_pagetable() -#define BAD_PAGE __bad_page() -#define ZERO_PAGE(vaddr) ((unsigned long) empty_zero_page) - -/* number of bits that fit into a memory pointer */ -#define BITS_PER_PTR (8*sizeof(unsigned long)) - -/* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) - -/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ -/* 64-bit machines, beware! SRB. */ -#define SIZEOF_PTR_LOG2 2 - -/* to find an entry in a page-table */ -#define PAGE_PTR(address) \ -((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) - -/* Certain architectures need to do special things when pte's - * within a page table are directly modified. Thus, the following - * hook is made available. +/* + * Handling allocation failures during page table setup. */ -extern __inline__ void set_pte(pte_t *ptep, pte_t pteval) -{ - *ptep = pteval; -} +extern void __handle_bad_pmd(pmd_t * pmd); +extern void __handle_bad_pmd_kernel(pmd_t * pmd); -extern __inline__ int pte_none(pte_t pte) -{ - return !pte_val(pte); -} - -extern __inline__ int pte_present(pte_t pte) -{ - return pte_val(pte) & _PAGE_PRESENT; -} - -extern __inline__ void pte_clear(pte_t *ptep) -{ - pte_val(*ptep) = 0; -} - -extern __inline__ int pmd_none(pmd_t pmd) -{ - return !pmd_val(pmd); -} +#define pte_none(x) (!pte_val(x)) +#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) +#define pte_clear(xp) do { pte_val(*(xp)) = 0; } while (0) +#define pte_pagenr(x) ((unsigned long)((pte_val(x) >> PAGE_SHIFT))) +#define pmd_none(x) (!pmd_val(x)) #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) - -extern __inline__ int pmd_present(pmd_t pmd) -{ - return pmd_val(pmd) & _PAGE_PRESENT; -} - -extern __inline__ void pmd_clear(pmd_t *pmdp) -{ - pmd_val(*pmdp) = 0; -} +#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) +#define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0) /* - * The "pgd_xxx()" functions here are trivial for a folded two-level - * setup: the pgd is never bad, and a pmd always exists (as it's folded - * into the pgd entry) + * Permanent address of a page. Obviously must never be + * called on a highmem page. */ -extern __inline__ int pgd_none(pgd_t pgd) { return 0; } -extern __inline__ int pgd_bad(pgd_t pgd) { return 0; } -extern __inline__ int pgd_present(pgd_t pgd) { return 1; } -extern __inline__ void pgd_clear(pgd_t * pgdp) { } +#define page_address(page) ({ if (PageHighMem(page)) BUG(); PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT); }) +#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) +#define pte_page(x) (mem_map+pte_pagenr(x)) /* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -extern __inline__ int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern __inline__ int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern __inline__ int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; } -extern __inline__ int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; } -extern __inline__ int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_RW; } - -extern __inline__ pte_t pte_rdprotect(pte_t pte){ pte_val(pte) &= ~_PAGE_USER; return pte; } -extern __inline__ pte_t pte_exprotect(pte_t pte){ pte_val(pte) &= ~_PAGE_USER; return pte; } -extern __inline__ pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } -extern __inline__ pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -extern __inline__ pte_t pte_wrprotect(pte_t pte){ pte_val(pte) &= ~_PAGE_RW; return pte; } -extern __inline__ pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } -extern __inline__ pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } -extern __inline__ pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } -extern __inline__ pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } -extern __inline__ pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; } +extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +extern inline int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; } +extern inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; } +extern inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_RW; } + +extern inline pte_t pte_rdprotect(pte_t pte){ pte_val(pte) &= ~_PAGE_USER; return pte; } +extern inline pte_t pte_exprotect(pte_t pte){ pte_val(pte) &= ~_PAGE_USER; return pte; } +extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } +extern inline pte_t pte_wrprotect(pte_t pte){ pte_val(pte) &= ~_PAGE_RW; return pte; } +extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } +extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } +extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } +extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } +extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; } /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot) +extern inline pte_t mk_pte(struct page *page, pgprot_t pgprot) { - return __pte(__pa(page) | pgprot_val(pgprot)); + pte_t __pte; + + pte_val(__pte) = (page-mem_map)*(unsigned long long)PAGE_SIZE + + pgprot_val(pgprot); + return __pte; } /* This takes a physical page address that is used by the remapping functions */ -extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) -{ - return __pte(physpage | pgprot_val(pgprot)); -} +#define mk_pte_phys(physpage, pgprot) \ +({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; }) -extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot) -{ - return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); -} +extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } -extern __inline__ unsigned long pte_page(pte_t pte) -{ - return (unsigned long)__va(pte_val(pte) & PAGE_MASK); -} +#define page_pte_prot(page,prot) mk_pte(page, prot) +#define page_pte(page) page_pte_prot(page, __pgprot(0)) -extern __inline__ unsigned long pmd_page(pmd_t pmd) -{ - return (unsigned long)__va(pmd_val(pmd) & PAGE_MASK); -} +#define pmd_page(pmd) \ +((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) -extern __inline__ void pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - pmd_val(*pmdp) = __pa(((unsigned long) ptep) & PAGE_MASK) | _PAGE_TABLE; -} +/* to find an entry in a page-table-directory. */ +#define __pgd_offset(address) \ + ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) + +#define pgd_offset(mm, address) ((mm)->pgd+__pgd_offset(address)) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) -/* to find an entry in a page-table-directory */ -extern __inline__ pgd_t *pgd_offset(struct mm_struct *mm, unsigned long addr) -{ - return mm->pgd + (addr >> PGDIR_SHIFT); -} +#define __pmd_offset(address) \ + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) -/* Find an entry in the second-level page table.. */ -extern __inline__ pmd_t * pmd_offset(pgd_t * dir, unsigned long addr) -{ - return (pmd_t *) dir; -} - -/* Find an entry in the third-level page table.. */ -extern __inline__ pte_t *pte_offset(pmd_t * dir, unsigned long addr) -{ - return (pte_t *) (pmd_page(*dir)) + - ((addr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} +/* Find an entry in the third-level page table.. */ +#define __pte_offset(address) \ + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset(dir, address) ((pte_t *) pmd_page(*(dir)) + \ + __pte_offset(address)) /* * Allocate and free page tables. The xxx_kernel() versions are @@ -311,11 +269,6 @@ extern __inline__ pte_t *pte_offset(pmd_t * dir, unsigned long addr) * if any. */ -#define pgd_quicklist (current_cpu_data.pgd_quick) -#define pmd_quicklist ((unsigned long *)0) -#define pte_quicklist (current_cpu_data.pte_quick) -#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) - extern __inline__ pgd_t *get_pgd_slow(void) { pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL); @@ -379,23 +332,6 @@ extern __inline__ void free_pte_slow(pte_t *pte) free_page((unsigned long)pte); } -/* We don't use pmd cache, so these are dummy routines */ -extern __inline__ pmd_t *get_pmd_fast(void) -{ - return (pmd_t *)0; -} - -extern __inline__ void free_pmd_fast(pmd_t *pmd) -{ -} - -extern __inline__ void free_pmd_slow(pmd_t *pmd) -{ -} - -extern void __bad_pte(pmd_t *pmd); -extern void __bad_pte_kernel(pmd_t *pmd); - #define pte_free_kernel(pte) free_pte_slow(pte) #define pte_free(pte) free_pte_slow(pte) #define pgd_free(pgd) free_pgd_slow(pgd) @@ -405,15 +341,15 @@ extern __inline__ pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) { - pte_t *page = get_pte_fast(); + pte_t *page = (pte_t *) get_pte_fast(); if (!page) return get_pte_kernel_slow(pmd, address); - pmd_set(pmd, page); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(page); return page + address; } if (pmd_bad(*pmd)) { - __bad_pte_kernel(pmd); + __handle_bad_pmd_kernel(pmd); return NULL; } return (pte_t *) pmd_page(*pmd) + address; @@ -421,13 +357,13 @@ extern __inline__ pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) extern __inline__ pte_t * pte_alloc(pmd_t * pmd, unsigned long address) { - address = (address >> (PAGE_SHIFT-2)) & 4*(PTRS_PER_PTE - 1); + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) goto getnew; if (pmd_bad(*pmd)) goto fix; - return (pte_t *) (pmd_page(*pmd) + address); + return (pte_t *)pmd_page(*pmd) + address; getnew: { unsigned long page = (unsigned long) get_pte_fast(); @@ -435,10 +371,10 @@ getnew: if (!page) return get_pte_slow(pmd, address); pmd_val(*pmd) = _PAGE_TABLE + __pa(page); - return (pte_t *) (page + address); + return (pte_t *)page + address; } fix: - __bad_pte(pmd); + __handle_bad_pmd(pmd); return NULL; } @@ -450,11 +386,6 @@ extern inline void pmd_free(pmd_t * pmd) { } -extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) -{ - return (pmd_t *) pgd; -} - #define pmd_free_kernel pmd_free #define pmd_alloc_kernel pmd_alloc @@ -481,9 +412,8 @@ extern pgd_t swapper_pg_dir[1024]; extern void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, pte_t pte); -#define SWP_TYPE(entry) (((entry) >> 1) & 0x3f) -#define SWP_OFFSET(entry) ((entry) >> 8) -#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) +#define SWP_TYPE(entry) (((pte_val(entry)) >> 1) & 0x3f) +#define SWP_OFFSET(entry) ((pte_val(entry)) >> 8) #define module_map vmalloc #define module_unmap vfree diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 4efcf3fe2..07175eff5 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -33,7 +33,6 @@ struct sh_cpuinfo { char hard_math; - /* Not yet used */ unsigned long *pgd_quick; unsigned long *pte_quick; unsigned long pgtable_cache_sz; diff --git a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h index 16f70ffd7..8db187a29 100644 --- a/include/asm-sh/spinlock.h +++ b/include/asm-sh/spinlock.h @@ -1,6 +1,53 @@ #ifndef __ASM_SH_SPINLOCK_H #define __ASM_SH_SPINLOCK_H +#ifndef __SMP__ + +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) (1) +#define spin_unlock_wait(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() + +#define spin_lock_irqsave(lock, flags) save_and_cli(flags) +#define spin_unlock_irqrestore(lock, flags) restore_flags(flags) + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED (rwlock_t) { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) + +#else + #error "No SMP on SH" +#endif /* SMP */ + #endif /* __ASM_SH_SPINLOCK_H */ diff --git a/include/asm-sh/string.h b/include/asm-sh/string.h index 6752d3f9c..56ea9d8e8 100644 --- a/include/asm-sh/string.h +++ b/include/asm-sh/string.h @@ -18,9 +18,9 @@ extern __inline__ char *strcpy(char *__dest, const char *__src) "cmp/eq #0,%2\n\t" "bf/s 1b\n\t" " add #1,%0\n\t" - :"=&r" (__dest), "=&r" (__src), "=&z" (__dummy) - :"0" (__dest), "1" (__src) - :"memory"); + : "=r" (__dest), "=r" (__src), "=&z" (__dummy) + : "0" (__dest), "1" (__src) + : "memory"); return __xdest; } @@ -37,12 +37,12 @@ extern __inline__ char *strncpy(char *__dest, const char *__src, size_t __n) __asm__ __volatile__( "1:\n" "mov.b @%1+,%2\n\t" - "mov.b %2,@%0\n\t" - "cmp/eq #0,%2\n\t" - "bt/s 2f\n\t" - " cmp/eq %5,%1\n\t" - "bf/s 1b\n\t" - " add #1,%0\n" + "mov.b %2,@%0\n\t" + "cmp/eq #0,%2\n\t" + "bt/s 2f\n\t" + " cmp/eq %5,%1\n\t" + "bf/s 1b\n\t" + " add #1,%0\n" "2:" : "=r" (__dest), "=r" (__src), "=&z" (__dummy) : "0" (__dest), "1" (__src), "r" (__src+__n) @@ -113,6 +113,9 @@ extern void *memcpy(void *__to, __const__ void *__from, size_t __n); #define __HAVE_ARCH_MEMMOVE extern void *memmove(void *__dest, __const__ void *__src, size_t __n); +#define __HAVE_ARCH_MEMCHR +extern void *memchr(const void *__s, int __c, size_t __n); + /* Don't build bcopy at all ... */ #define __HAVE_ARCH_BCOPY diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 40c54212f..d898e3517 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -98,7 +98,7 @@ extern __inline__ void __sti(void) __asm__ __volatile__("stc sr,%0\n\t" "and %1,%0\n\t" "ldc %0,sr" - : "=&z" (__dummy) + : "=&r" (__dummy) : "r" (0xefffffff) : "memory"); } @@ -109,24 +109,24 @@ extern __inline__ void __cli(void) __asm__ __volatile__("stc sr,%0\n\t" "or %1,%0\n\t" "ldc %0,sr" - : "=&z" (__dummy) + : "=&r" (__dummy) : "r" (0x10000000) : "memory"); } #define __save_flags(x) \ -__asm__ __volatile__("stc sr,%0\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop":"=r" (x): /* no inputs */ :"memory") - -#define __save_and_cli(x) \ -({ unsigned long __dummy; \ -__asm__ __volatile__( \ - "stc sr,%0\n\t" \ - "mov %0,%1\n\t" \ - "or %2,%1\n\t" \ - "ldc %1,sr" \ - : "=&r" (x), "=&z" (__dummy) \ - : "r" (0x10000000) \ - : "memory"); }) +__asm__ __volatile__("stc sr,%0":"=r" (x): /* no inputs */ :"memory") + +#define __save_and_cli(x) \ +x = (__extension__ ({ unsigned long __dummy,__sr; \ + __asm__ __volatile__( \ + "stc sr,%1\n\t" \ + "or %0,%1\n\t" \ + "stc sr,%0\n\t" \ + "ldc %1,sr" \ + : "=r" (__sr), "=&r" (__dummy) \ + : "0" (0x10000000) \ + : "memory"); __sr; })) #define __restore_flags(x) \ __asm__ __volatile__("ldc %0,sr": /* no output */: "r" (x):"memory") diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 1f5ec5f7a..5b53842be 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -24,9 +24,6 @@ #include <linux/types.h> #include <linux/ioctl.h> -/* /dev/acpi minor number */ -#define ACPI_MINOR_DEV 167 - /* RSDP location */ #define ACPI_BIOS_ROM_BASE (0x0e0000) #define ACPI_BIOS_ROM_END (0x100000) @@ -40,7 +37,7 @@ /* PM1_STS/EN flags */ #define ACPI_TMR 0x0001 -#define ACPI_BM 0x0010 +#define ACPI_BM 0x0010 #define ACPI_GBL 0x0020 #define ACPI_PWRBTN 0x0100 #define ACPI_SLPBTN 0x0200 @@ -57,27 +54,33 @@ #define ACPI_SLP_EN 0x2000 /* PM_TMR masks */ -#define ACPI_TMR_MASK 0x00ffffff +#define ACPI_TMR_MASK 0x00ffffff #define ACPI_TMR_HZ 3580000 /* 3.58 MHz */ /* strangess to avoid integer overflow */ #define ACPI_uS_TO_TMR_TICKS(val) \ (((val) * (ACPI_TMR_HZ / 10000)) / 100) +/* CPU cycles -> PM timer cycles, looks somewhat heuristic but + (ticks = 3/11 * CPU_MHz + 2) comes pretty close for my systems + */ +#define ACPI_CPU_TO_TMR_TICKS(cycles) \ + ((cycles) / (3 * (loops_per_sec + 2500) / 500000 / 11 + 2)) + /* PM2_CNT flags */ #define ACPI_ARB_DIS 0x01 /* FACP flags */ -#define ACPI_WBINVD 0x00000001 +#define ACPI_WBINVD 0x00000001 #define ACPI_WBINVD_FLUSH 0x00000002 -#define ACPI_PROC_C1 0x00000004 -#define ACPI_P_LVL2_UP 0x00000008 -#define ACPI_PWR_BUTTON 0x00000010 -#define ACPI_SLP_BUTTON 0x00000020 -#define ACPI_FIX_RTC 0x00000040 -#define ACPI_RTC_64 0x00000080 +#define ACPI_PROC_C1 0x00000004 +#define ACPI_P_LVL2_UP 0x00000008 +#define ACPI_PWR_BUTTON 0x00000010 +#define ACPI_SLP_BUTTON 0x00000020 +#define ACPI_FIX_RTC 0x00000040 +#define ACPI_RTC_64 0x00000080 #define ACPI_TMR_VAL_EXT 0x00000100 -#define ACPI_DCK_CAP 0x00000200 +#define ACPI_DCK_CAP 0x00000200 struct acpi_rsdp { __u32 signature[2]; @@ -142,25 +145,65 @@ struct acpi_facp { __u32 flags; }; -#define ACPI_FIND_TABLES _IOR('A', 1, struct acpi_find_tables) -#define ACPI_ENABLE_EVENT _IOW('A', 2, struct acpi_enable_event) -#define ACPI_WAIT_EVENT _IOR('A', 3, struct acpi_wait_event) +/* + * Sysctl declarations + */ -struct acpi_find_tables { - unsigned long facp; /* FACP physical address */ - unsigned long dsdt; /* DSDT physical address */ +enum +{ + CTL_ACPI = 10 }; -struct acpi_enable_event { - __u32 pm1_enable; /* fixed events */ - __u32 gpe_enable; /* general-purpose events (GPEs) */ - __u32 gpe_level; /* level-triggered GPEs */ +enum +{ + ACPI_FACP = 1, + ACPI_DSDT, + ACPI_PM1_ENABLE, + ACPI_GPE_ENABLE, + ACPI_GPE_LEVEL, + ACPI_EVENT, + ACPI_P_LVL2, + ACPI_P_LVL3, + ACPI_P_LVL2_LAT, + ACPI_P_LVL3_LAT, }; -struct acpi_wait_event { - __u32 pm1_status; /* fixed events */ - __u32 gpe_status; /* general-purpose events */ -}; +/* + * PIIX4-specific ACPI info (for systems with PIIX4 but no ACPI tables) + */ + +#define ACPI_PIIX4_INT_MODEL 0x00 +#define ACPI_PIIX4_SCI_INT 0x0009 + +#define ACPI_PIIX4_SMI_CMD 0x00b2 +#define ACPI_PIIX4_ACPI_ENABLE 0xf0 +#define ACPI_PIIX4_ACPI_DISABLE 0xf1 +#define ACPI_PIIX4_S4BIOS_REQ 0xf2 + +#define ACPI_PIIX4_PM1_EVT 0x0000 +#define ACPI_PIIX4_PM1_CNT 0x0004 +#define ACPI_PIIX4_S0_MASK (0x0005 << 10) +#define ACPI_PIIX4_S1_MASK (0x0004 << 10) +#define ACPI_PIIX4_S2_MASK (0x0003 << 10) +#define ACPI_PIIX4_S3_MASK (0x0002 << 10) +#define ACPI_PIIX4_S4_MASK (0x0001 << 10) +#define ACPI_PIIX4_S5_MASK (0x0000 << 10) +#define ACPI_PIIX4_PM_TMR 0x0008 +#define ACPI_PIIX4_GPE0 0x000c +#define ACPI_PIIX4_P_CNT 0x0010 +#define ACPI_PIIX4_P_LVL2 0x0014 +#define ACPI_PIIX4_P_LVL3 0x0015 + +#define ACPI_PIIX4_PM1_EVT_LEN 0x04 +#define ACPI_PIIX4_PM1_CNT_LEN 0x02 +#define ACPI_PIIX4_PM_TM_LEN 0x04 +#define ACPI_PIIX4_GPE0_LEN 0x04 + +#define ACPI_PIIX4_PM2_CNT 0x0022 +#define ACPI_PIIX4_PM2_CNT_LEN 0x01 + +#define ACPI_PIIX4_PMREGMISC 0x80 +#define ACPI_PIIX4_PMIOSE 0x01 #ifdef __KERNEL__ diff --git a/include/linux/fs.h b/include/linux/fs.h index c6c7d76d2..58fc251ac 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -328,6 +328,11 @@ struct iattr { */ struct page; +struct address_space { + struct list_head pages; + unsigned long nrpages; +}; + struct inode { struct list_head i_hash; struct list_head i_list; @@ -348,14 +353,13 @@ struct inode { unsigned long i_blksize; unsigned long i_blocks; unsigned long i_version; - unsigned long i_nrpages; struct semaphore i_sem; struct inode_operations *i_op; struct super_block *i_sb; wait_queue_head_t i_wait; struct file_lock *i_flock; struct vm_area_struct *i_mmap; - struct list_head i_pages; + struct address_space i_data; spinlock_t i_shared_lock; struct dquot *i_dquot[MAXQUOTAS]; struct pipe_inode_info *i_pipe; diff --git a/include/linux/i2o.h b/include/linux/i2o.h index d11ff1f09..9ddcb7bb8 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -10,6 +10,209 @@ /* How many controllers are we allowing */ #define MAX_I2O_CONTROLLERS 32 +#include <linux/ioctl.h> + +/* + * I2O Control IOCTLs and structures + */ +#define I2O_MAGIC_NUMBER 'i' +#define I2OGETIOPS _IOR(I2O_MAGIC_NUMBER,0,u8[MAX_I2O_CONTROLLERS]) +#define I2OHRTGET _IOWR(I2O_MAGIC_NUMBER,1,struct i2o_cmd_hrtlct) +#define I2OLCTGET _IOWR(I2O_MAGIC_NUMBER,2,struct i2o_cmd_hrtlct) +#define I2OPARMSET _IOWR(I2O_MAGIC_NUMBER,3,struct i2o_cmd_psetget) +#define I2OPARMGET _IOWR(I2O_MAGIC_NUMBER,4,struct i2o_cmd_psetget) +#define I2OSWDL _IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer) +#define I2OSWUL _IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer) +#define I2OSWDEL _IOWR(I2O_MAGIC_NUMBER,7,struct i2o_sw_xfer) +#define I2OVALIDATE _IOR(I2O_MAGIC_NUMBER,8,u32) +#define I2OHTML _IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html) + +/* On hold until we figure this out +#define I2OEVTREG _IO(I2O_MAGIC_NUMBER,10) +#define I2OEVTCLR _IO(I2O_MAGIC_NUMBER,11) +#define I2OEVTGET _IO(I2O_MAGIC_NUMBER,12) + */ + +struct i2o_cmd_hrtlct +{ + unsigned int iop; /* IOP unit number */ + void *resbuf; /* Buffer for result */ + unsigned int *reslen; /* Buffer length in bytes */ +}; + +struct i2o_cmd_psetget +{ + unsigned int iop; /* IOP unit number */ + unsigned int tid; /* Target device TID */ + void *opbuf; /* Operation List buffer */ + unsigned int oplen; /* Operation List buffer length in bytes */ + void *resbuf; /* Result List buffer */ + unsigned int *reslen; /* Result List buffer length in bytes */ +}; + +struct i2o_sw_xfer +{ + unsigned int iop; /* IOP unit number */ + unsigned char flags; /* Flags field */ + unsigned char sw_type; /* Software type */ + unsigned int sw_id; /* Software ID */ + void *buf; /* Pointer to software buffer */ + unsigned int *swlen; /* Length of software data */ + unsigned int *maxfrag; /* Maximum fragment count */ + unsigned int *curfrag; /* Current fragment count */ +}; + +struct i2o_html +{ + unsigned int iop; /* IOP unit number */ + unsigned int tid; /* Target device ID */ + unsigned int page; /* HTML page */ + void *resbuf; /* Buffer for reply HTML page */ + unsigned int *reslen; /* Length in bytes of reply buffer */ + void *qbuf; /* Pointer to HTTP query string */ + unsigned int qlen; /* Length in bytes of query string buffer */ +}; + + +/************************************************************************** + * HRT related constants and structures + **************************************************************************/ +#define I2O_BUS_LOCAL 0 +#define I2O_BUS_ISA 1 +#define I2O_BUS_EISA 2 +#define I2O_BUS_MCA 3 +#define I2O_BUS_PCI 4 +#define I2O_BUS_PCMCIA 5 +#define I2O_BUS_NUBUS 6 +#define I2O_BUS_CARDBUS 7 +#define I2O_BUS_UNKNOWN 0x80 + +#ifndef __KERNEL__ +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +#endif /* __KERNEL__ */ + +typedef struct _i2o_pci_bus { + u8 PciFunctionNumber; + u8 PciDeviceNumber; + u8 PciBusNumber; + u8 reserved; + u16 PciVendorID; + u16 PciDeviceID; +} i2o_pci_bus, *pi2o_pci_bus; + +typedef struct _i2o_local_bus { + u16 LbBaseIOPort; + u16 reserved; + u32 LbBaseMemoryAddress; +} i2o_local_bus, *pi2o_local_bus; + +typedef struct _i2o_isa_bus { + u16 IsaBaseIOPort; + u8 CSN; + u8 reserved; + u32 IsaBaseMemoryAddress; +} i2o_isa_bus, *pi2o_isa_bus; + +typedef struct _i2o_eisa_bus_info { + u16 EisaBaseIOPort; + u8 reserved; + u8 EisaSlotNumber; + u32 EisaBaseMemoryAddress; +} i2o_eisa_bus, *pi2o_eisa_bus; + +typedef struct _i2o_mca_bus { + u16 McaBaseIOPort; + u8 reserved; + u8 McaSlotNumber; + u32 McaBaseMemoryAddress; +} i2o_mca_bus, *pi2o_mca_bus; + +typedef struct _i2o_other_bus { + u16 BaseIOPort; + u16 reserved; + u32 BaseMemoryAddress; +} i2o_other_bus, *pi2o_other_bus; + +typedef struct _i2o_hrt_entry { + u32 adapter_id; + u32 parent_tid:12; + u32 state:4; + u32 bus_num:8; + u32 bus_type:8; + union { + i2o_pci_bus pci_bus; + i2o_local_bus local_bus; + i2o_isa_bus isa_bus; + i2o_eisa_bus eisa_bus; + i2o_mca_bus mca_bus; + i2o_other_bus other_bus; + } bus; +} i2o_hrt_entry, *pi2o_hrt_entry; + +typedef struct _i2o_hrt { + u16 num_entries; + u8 entry_len; + u8 hrt_version; + u32 change_ind; + i2o_hrt_entry hrt_entry[1]; +} i2o_hrt, *pi2o_hrt; + +typedef struct _i2o_lct_entry { + u32 entry_size:16; + u32 tid:12; + u32 reserved:4; + u32 change_ind; + u32 device_flags; + u32 class_id:12; + u32 version:4; + u32 vendor_id:16; + u32 sub_class; + u32 user_tid:12; + u32 parent_tid:12; + u32 bios_info:8; + u8 identity_tag[8]; + u32 event_capabilities; +} i2o_lct_entry, *pi2o_lct_entry; + +typedef struct _i2o_lct { + u32 table_size:16; + u32 boot_tid:12; + u32 lct_ver:4; + u32 iop_flags; + u32 current_change_ind; + i2o_lct_entry lct_entry[1]; +} i2o_lct, *pi2o_lct; + +typedef struct _i2o_status_block { + u16 org_id; + u16 reserved; + u16 iop_id:12; + u16 reserved1:4; + u16 host_unit_id; + u16 segment_number:12; + u16 i2o_version:4; + u8 iop_state; + u8 msg_type; + u16 inbound_frame_size; + u8 init_code; + u8 reserved2; + u32 max_inbound_frames; + u32 max_outbound_frames; + char product_id[24]; + u32 expected_lct_size; + u32 iop_capabilities; + u32 desired_mem_size; + u32 current_mem_size; + u32 current_mem_base; + u32 desired_io_size; + u32 current_io_size; + u32 current_io_base; + u32 reserved3:24; + u32 cmd_status:8; +} i2o_status_block, *pi2o_status_block; + #ifdef __KERNEL__ /* ioctl stuff only thing exported to users */ @@ -43,13 +246,11 @@ struct i2o_message struct i2o_device { - int class; /* Block, Net, SCSI etc (from spec) */ - int subclass; /* eth, fddi, tr etc (from spec) */ - int id; /* I2O ID assigned by the controller */ - int parent; /* Parent device */ - int flags; /* Control flags */ + pi2o_lct_entry lct_data;/* Device LCT information */ + u32 flags; int i2oversion; /* I2O version supported. Actually there * should be high and low version */ + struct proc_dir_entry* proc_entry; /* /proc dir */ /* Primary user */ @@ -70,6 +271,9 @@ struct i2o_device struct i2o_pci { int irq; +#ifdef CONFIG_MTRR + int mtrr_reg; +#endif }; @@ -81,8 +285,6 @@ struct i2o_controller { char name[16]; int unit; - int status; /* I2O status */ - int i2oversion; int type; #define I2O_TYPE_PCI 0x01 /* PCI I2O controller */ @@ -94,10 +296,14 @@ struct i2o_controller volatile u32 *post_port; /* Messaging ports */ volatile u32 *reply_port; volatile u32 *irq_mask; /* Interrupt port */ - u32 *lct; - u32 *hrt; + + pi2o_status_block status_block; /* IOP status block */ + pi2o_lct lct; + pi2o_hrt hrt; + u32 mem_offset; /* MFA offset */ u32 mem_phys; /* MFA physical */ + u32 priv_mem; u32 priv_mem_size; u32 priv_io; @@ -115,6 +321,9 @@ struct i2o_controller int (*bind)(struct i2o_controller *, struct i2o_device *); /* Bus specific initiator */ int (*unbind)(struct i2o_controller *, struct i2o_device *); + /* Bus specific enable/disable */ + void (*bus_enable)(struct i2o_controller *c); + void (*bus_disable)(struct i2o_controller *c); void *page_frame; /* Message buffers */ int inbound_size; /* Inbound queue size */ @@ -144,8 +353,7 @@ struct i2o_core_func_table { int (*install)(struct i2o_controller *); int (*activate)(struct i2o_controller *); - struct i2o_controller* - (*find)(int); + struct i2o_controller* (*find)(int); void (*unlock)(struct i2o_controller *); void (*run_queue)(struct i2o_controller *c); int (*delete)(struct i2o_controller *); @@ -153,9 +361,40 @@ struct i2o_core_func_table #endif /* - * Messenger inlines + * I2O System table entry */ +struct i2o_sys_tbl_entry +{ + u16 org_id; + u16 reserved1; + u32 iop_id:12; + u32 reserved2:20; + u16 seg_num:12; + u16 i2o_version:4; + u8 iop_state; + u8 msg_type; + u16 frame_size; + u16 reserved3; + u32 last_changed; + u32 iop_capabilities; + u32 inbound_low; + u32 inbound_high; +}; + +struct i2o_sys_tbl +{ + u8 num_entries; + u8 version; + u16 reserved1; + u32 change_ind; + u32 reserved2; + u32 reserved3; + struct i2o_sys_tbl_entry iops[0]; +}; +/* + * Messenger inlines + */ extern inline u32 I2O_POST_READ32(struct i2o_controller *c) { return *c->post_port; @@ -211,6 +450,7 @@ extern int i2o_delete_controller(struct i2o_controller *); extern int i2o_activate_controller(struct i2o_controller *); extern void i2o_unlock_controller(struct i2o_controller *); extern struct i2o_controller *i2o_find_controller(int); +extern int i2o_status_get(struct i2o_controller *); extern int i2o_num_controllers; extern int i2o_install_handler(struct i2o_handler *); @@ -221,24 +461,24 @@ extern int i2o_delete_device(struct i2o_device *); extern int i2o_claim_device(struct i2o_device *, struct i2o_handler *, u32); extern int i2o_release_device(struct i2o_device *, struct i2o_handler *, u32); -extern int i2o_post_this(struct i2o_controller *, int, u32 *, int); -extern int i2o_post_wait(struct i2o_controller *, int, u32 *, int, int *, int); +extern int i2o_post_this(struct i2o_controller *, u32 *, int); +extern int i2o_post_wait(struct i2o_controller *, u32 *, int, int); extern int i2o_issue_claim(struct i2o_controller *, int, int, int, int *, u32); -extern int i2o_issue_params(int, struct i2o_controller *, int, int, void *, - int, void *, int, int *); - -extern int i2o_query_scalar(struct i2o_controller *, int, int, int, int, - void *, int, int *); -extern int i2o_set_scalar(struct i2o_controller *, int, int, int, int, - void *, int, int *); - -extern int i2o_query_table(int, struct i2o_controller *, int, int, int, int, - void *, int, void *, int, int *); -extern int i2o_clear_table(struct i2o_controller *, int, int, int, int *); -extern int i2o_row_add_table(struct i2o_controller *, int, int, int, int, - void *, int, int *); -extern int i2o_row_delete_table(struct i2o_controller *, int, int, int, int, - void *, int, int *); +extern int i2o_issue_params(int, struct i2o_controller *, int, void *, + int, void *, int); + +extern int i2o_query_scalar(struct i2o_controller *, int, int, int, + void *, int); +extern int i2o_set_scalar(struct i2o_controller *, int, int, int, + void *, int); + +extern int i2o_query_table(int, struct i2o_controller *, int, int, int, + void *, int, void *, int); +extern int i2o_clear_table(struct i2o_controller *, int, int); +extern int i2o_row_add_table(struct i2o_controller *, int, int, int, + void *, int); +extern int i2o_row_delete_table(struct i2o_controller *, int, int, int, + void *, int); extern void i2o_run_queue(struct i2o_controller *); extern void i2o_report_status(const char *, const char *, u32 *); @@ -551,182 +791,9 @@ extern const char *i2o_get_class_name(int); #define MSG_POOL_SIZE 16384 -#define I2O_POST_WAIT_OK 1 +#define I2O_POST_WAIT_OK 0 #define I2O_POST_WAIT_TIMEOUT -ETIMEDOUT #endif /* __KERNEL__ */ -#include <linux/ioctl.h> - -/* - * I2O Control IOCTLs and structures - */ -#define I2O_MAGIC_NUMBER 'i' -#define I2OGETIOPS _IOR(I2O_MAGIC_NUMBER,0,u8[MAX_I2O_CONTROLLERS]) -#define I2OHRTGET _IOWR(I2O_MAGIC_NUMBER,1,struct i2o_cmd_hrtlct) -#define I2OLCTGET _IOWR(I2O_MAGIC_NUMBER,2,struct i2o_cmd_hrtlct) -#define I2OPARMSET _IOWR(I2O_MAGIC_NUMBER,3,struct i2o_cmd_psetget) -#define I2OPARMGET _IOWR(I2O_MAGIC_NUMBER,4,struct i2o_cmd_psetget) -#define I2OSWDL _IOWR(I2O_MAGIC_NUMBER,5,struct i2o_sw_xfer) -#define I2OSWUL _IOWR(I2O_MAGIC_NUMBER,6,struct i2o_sw_xfer) -#define I2OSWDEL _IOWR(I2O_MAGIC_NUMBER,7,struct i2o_sw_xfer) -#define I2OVALIDATE _IOR(I2O_MAGIC_NUMBER,8,u32) -#define I2OHTML _IOWR(I2O_MAGIC_NUMBER,9,struct i2o_html) - -/* On hold until we figure this out -#define I2OEVTREG _IO(I2O_MAGIC_NUMBER,10) -#define I2OEVTCLR _IO(I2O_MAGIC_NUMBER,11) -#define I2OEVTGET _IO(I2O_MAGIC_NUMBER,12) - */ - -struct i2o_cmd_hrtlct -{ - unsigned int iop; /* IOP unit number */ - void *resbuf; /* Buffer for result */ - unsigned int *reslen; /* Buffer length in bytes */ -}; - -struct i2o_cmd_psetget -{ - unsigned int iop; /* IOP unit number */ - unsigned int tid; /* Target device TID */ - void *opbuf; /* Operation List buffer */ - unsigned int oplen; /* Operation List buffer length in bytes */ - void *resbuf; /* Result List buffer */ - unsigned int *reslen; /* Result List buffer length in bytes */ -}; - -struct i2o_sw_xfer -{ - unsigned int iop; /* IOP unit number */ - unsigned char flags; /* Flags field */ - unsigned char sw_type; /* Software type */ - unsigned int sw_id; /* Software ID */ - void *buf; /* Pointer to software buffer */ - unsigned int *swlen; /* Length of software data */ - unsigned int *maxfrag; /* Maximum fragment count */ - unsigned int *curfrag; /* Current fragment count */ -}; - -struct i2o_html -{ - unsigned int iop; /* IOP unit number */ - unsigned int tid; /* Target device ID */ - unsigned int page; /* HTML page */ - void *resbuf; /* Buffer for reply HTML page */ - unsigned int *reslen; /* Length in bytes of reply buffer */ - void *qbuf; /* Pointer to HTTP query string */ - unsigned int qlen; /* Length in bytes of query string buffer */ -}; - - -/************************************************************************** - * HRT related constants and structures - **************************************************************************/ -#define I2O_BUS_LOCAL 0 -#define I2O_BUS_ISA 1 -#define I2O_BUS_EISA 2 -#define I2O_BUS_MCA 3 -#define I2O_BUS_PCI 4 -#define I2O_BUS_PCMCIA 5 -#define I2O_BUS_NUBUS 6 -#define I2O_BUS_CARDBUS 7 -#define I2O_BUS_UNKNOWN 0x80 - -#ifndef __KERNEL__ -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#endif /* __KERNEL__ */ - -typedef struct _i2o_pci_bus { - u8 PciFunctionNumber; - u8 PciDeviceNumber; - u8 PciBusNumber; - u8 reserved; - u16 PciVendorID; - u16 PciDeviceID; -} i2o_pci_bus, *pi2o_pci_bus; - -typedef struct _i2o_local_bus { - u16 LbBaseIOPort; - u16 reserved; - u32 LbBaseMemoryAddress; -} i2o_local_bus, *pi2o_local_bus; - -typedef struct _i2o_isa_bus { - u16 IsaBaseIOPort; - u8 CSN; - u8 reserved; - u32 IsaBaseMemoryAddress; -} i2o_isa_bus, *pi2o_isa_bus; - -typedef struct _i2o_eisa_bus_info { - u16 EisaBaseIOPort; - u8 reserved; - u8 EisaSlotNumber; - u32 EisaBaseMemoryAddress; -} i2o_eisa_bus, *pi2o_eisa_bus; - -typedef struct _i2o_mca_bus { - u16 McaBaseIOPort; - u8 reserved; - u8 McaSlotNumber; - u32 McaBaseMemoryAddress; -} i2o_mca_bus, *pi2o_mca_bus; - -typedef struct _i2o_other_bus { - u16 BaseIOPort; - u16 reserved; - u32 BaseMemoryAddress; -} i2o_other_bus, *pi2o_other_bus; - -typedef struct _i2o_hrt_entry { - u32 adapter_id; - u32 parent_tid:12; - u32 state:4; - u32 bus_num:8; - u32 bus_type:8; - union { - i2o_pci_bus pci_bus; - i2o_local_bus local_bus; - i2o_isa_bus isa_bus; - i2o_eisa_bus eisa_bus; - i2o_mca_bus mca_bus; - i2o_other_bus other_bus; - } bus; -} i2o_hrt_entry, *pi2o_hrt_entry; - -typedef struct _i2o_hrt { - u16 num_entries; - u8 entry_len; - u8 hrt_version; - u32 change_ind; - i2o_hrt_entry hrt_entry[1]; -} i2o_hrt, *pi2o_hrt; - -typedef struct _i2o_lct_entry { - u32 entry_size:16; - u32 tid:12; - u32 reserved:4; - u32 change_ind; - u32 device_flags; - u32 class_id; - u32 sub_class; - u32 user_tid:12; - u32 parent_tid:12; - u32 bios_info:8; - u8 identity_tag[8]; - u32 event_capabilities; -} i2o_lct_entry, *pi2o_lct_entry; - -typedef struct _i2o_lct { - u32 table_size:16; - u32 boot_tid:12; - u32 lct_ver:4; - u32 iop_flags; - u32 current_change_ind; - i2o_lct_entry lct_entry[1]; -} i2o_lct, *pi2o_lct; - -#endif +#endif /* _I2O_H */ diff --git a/include/linux/irda.h b/include/linux/irda.h index 5d547a99f..712b2aa9a 100644 --- a/include/linux/irda.h +++ b/include/linux/irda.h @@ -1,12 +1,12 @@ /********************************************************************* * * Filename: irda.h - * Version: 1.0 - * Description: Exported IrDA sockets interface + * Version: + * Description: * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Mar 8 14:06:12 1999 - * Modified at: Mon Sep 27 12:11:49 1999 + * Modified at: Sun Oct 10 23:00:59 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -19,7 +19,7 @@ * Neither Dag Brattli nor University of Tromsø admit liability nor * provide warranty for any of this software. This material is * provided "AS-IS" and at no charge. - * + * ********************************************************************/ #ifndef KERNEL_IRDA_H @@ -44,17 +44,28 @@ #define HINT_OBEX 0x20 /* IrLMP character code values */ -#define CS_ASCII 0x00 -#define CS_ISO_8859_1 0x01 -#define CS_ISO_8859_2 0x02 -#define CS_ISO_8859_3 0x03 -#define CS_ISO_8859_4 0x04 -#define CS_ISO_8859_5 0x05 -#define CS_ISO_8859_6 0x06 -#define CS_ISO_8859_7 0x07 -#define CS_ISO_8859_8 0x08 -#define CS_ISO_8859_9 0x09 -#define CS_UNICODE 0xff +#define CS_ASCII 0x00 +#define CS_ISO_8859_1 0x01 +#define CS_ISO_8859_2 0x02 +#define CS_ISO_8859_3 0x03 +#define CS_ISO_8859_4 0x04 +#define CS_ISO_8859_5 0x05 +#define CS_ISO_8859_6 0x06 +#define CS_ISO_8859_7 0x07 +#define CS_ISO_8859_8 0x08 +#define CS_ISO_8859_9 0x09 +#define CS_UNICODE 0xff + +/* These are the currently known dongles */ +typedef enum { + IRDA_TEKRAM_DONGLE, + IRDA_ESI_DONGLE, + IRDA_ACTISYS_DONGLE, + IRDA_ACTISYS_PLUS_DONGLE, + IRDA_GIRBIL_DONGLE, + IRDA_LITELINK_DONGLE, + IRDA_AIRPORT_DONGLE, +} IRDA_DONGLE; #define SOL_IRLMP 266 /* Same as SOL_IRDA for now */ #define SOL_IRTTP 266 /* Same as SOL_IRDA for now */ @@ -68,12 +79,12 @@ #define IRTTP_QOS_GET 6 #define IRTTP_MAX_SDU_SIZE 7 -#define IAS_MAX_STRING 256 -#define IAS_MAX_OCTET_STRING 1024 -#define IAS_MAX_CLASSNAME 64 -#define IAS_MAX_ATTRIBNAME 256 +#define IAS_MAX_STRING 256 +#define IAS_MAX_OCTET_STRING 1024 +#define IAS_MAX_CLASSNAME 64 +#define IAS_MAX_ATTRIBNAME 256 -#define LSAP_ANY 0xff +#define LSAP_ANY 0xff struct sockaddr_irda { sa_family_t sir_family; /* AF_IRDA */ @@ -113,6 +124,61 @@ struct irda_ias_set { } attribute; }; +/* Some private IOCTL's (max 16) */ +#define SIOCSDONGLE (SIOCDEVPRIVATE + 0) +#define SIOCGDONGLE (SIOCDEVPRIVATE + 1) +#define SIOCSBANDWIDTH (SIOCDEVPRIVATE + 2) +#define SIOCSMEDIABUSY (SIOCDEVPRIVATE + 3) +#define SIOCGMEDIABUSY (SIOCDEVPRIVATE + 4) +#define SIOCGRECEIVING (SIOCDEVPRIVATE + 5) +#define SIOCSRAWMODE (SIOCDEVPRIVATE + 6) +#define SIOCSDTRRTS (SIOCDEVPRIVATE + 7) +#define SIOCGQOS (SIOCDEVPRIVATE + 8) + +/* No reason to include <linux/if.h> just because of this one ;-) */ +#define IRNAMSIZ 16 + +/* IrDA quality of service information (must not exceed 16 bytes) */ +struct if_irda_qos { + unsigned long baudrate; + unsigned short data_size; + unsigned short window_size; + unsigned short min_turn_time; + unsigned short max_turn_time; + unsigned char add_bofs; + unsigned char link_disc; +}; + +/* For setting RTS and DTR lines of a dongle */ +struct if_irda_line { + unsigned char dtr; + unsigned char rts; +}; + +/* IrDA interface configuration (data part must not exceed 16 bytes) */ +struct if_irda_req { + union { + char ifrn_name[IRNAMSIZ]; /* if name, e.g. "irda0" */ + } ifr_ifrn; + + /* Data part */ + union { + struct if_irda_line ifru_line; + struct if_irda_qos ifru_qos; + unsigned short ifru_flags; + unsigned int ifru_receiving; + unsigned int ifru_raw_mode; + unsigned int ifru_dongle; + } ifr_ifru; +}; + +#define ifr_baudrate ifr_ifru.ifru_qos.baudrate +#define ifr_receiving ifr_ifru.ifru_receiving +#define ifr_dongle ifr_ifru.ifru_dongle +#define ifr_raw_mode ifr_ifru.ifru_raw_mode +#define ifr_dtr ifr_ifru.ifru_line.dtr +#define ifr_rts ifr_ifru.ifru_line.rts + #endif /* KERNEL_IRDA_H */ diff --git a/include/linux/major.h b/include/linux/major.h index 5af26c50d..dfca27dc5 100644 --- a/include/linux/major.h +++ b/include/linux/major.h @@ -117,6 +117,7 @@ #define AURORA_MAJOR 79 +#define RTF_MAJOR 150 #define RAW_MAJOR 162 #define UNIX98_PTY_MASTER_MAJOR 128 diff --git a/include/linux/mm.h b/include/linux/mm.h index 778511f6f..1f23dac1c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -106,7 +106,7 @@ struct vm_operations_struct { void (*advise)(struct vm_area_struct *area, unsigned long, size_t, unsigned int advise); struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int write_access); struct page * (*wppage)(struct vm_area_struct * area, unsigned long address, struct page * page); - int (*swapout)(struct vm_area_struct *, struct page *); + int (*swapout)(struct page *, struct file *); }; /* @@ -120,7 +120,7 @@ struct vm_operations_struct { typedef struct page { /* these must be first (free area handling) */ struct list_head list; - struct inode *inode; + struct address_space *mapping; unsigned long offset; struct page *next_hash; atomic_t count; @@ -129,17 +129,13 @@ typedef struct page { wait_queue_head_t wait; struct page **pprev_hash; struct buffer_head * buffers; - void *owner; /* temporary debugging check */ } mem_map_t; -#define get_page(p) do { atomic_inc(&(p)->count); \ - } while (0) -#define put_page(p) __free_page(p) -#define put_page_testzero(p) ({ int __ret = atomic_dec_and_test(&(p)->count);\ - __ret; }) -#define page_count(p) atomic_read(&(p)->count) -#define set_page_count(p,v) do { atomic_set(&(p)->count, v); \ - } while (0) +#define get_page(p) atomic_inc(&(p)->count) +#define put_page(p) __free_page(p) +#define put_page_testzero(p) atomic_dec_and_test(&(p)->count) +#define page_count(p) atomic_read(&(p)->count) +#define set_page_count(p,v) atomic_set(&(p)->count, v) /* Page flag bit values */ #define PG_locked 0 @@ -158,54 +154,44 @@ typedef struct page { /* Make it prettier to test the above... */ -#define Page_Uptodate(page) (test_bit(PG_uptodate, &(page)->flags)) -#define SetPageUptodate(page) do { set_bit(PG_uptodate, &(page)->flags); \ - } while (0) -#define ClearPageUptodate(page) do { clear_bit(PG_uptodate, &(page)->flags); \ - } while (0) -#define PageLocked(page) (test_bit(PG_locked, &(page)->flags)) -#define LockPage(page) \ - do { int _ret = test_and_set_bit(PG_locked, &(page)->flags); \ - if (_ret) PAGE_BUG(page); \ - if (page->owner) PAGE_BUG(page); \ - page->owner = current; } while (0) -#define TryLockPage(page) ({ int _ret = test_and_set_bit(PG_locked, &(page)->flags); \ - if (!_ret) page->owner = current; _ret; }) +#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) +#define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags) +#define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags) +#define PageLocked(page) test_bit(PG_locked, &(page)->flags) +#define LockPage(page) set_bit(PG_locked, &(page)->flags) +#define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags) #define UnlockPage(page) do { \ - if (page->owner != current) { \ -BUG(); } page->owner = 0; \ -if (!test_and_clear_bit(PG_locked, &(page)->flags)) { \ - PAGE_BUG(page); } wake_up(&page->wait); } while (0) -#define PageError(page) (test_bit(PG_error, &(page)->flags)) -#define SetPageError(page) ({ int _ret = test_and_set_bit(PG_error, &(page)->flags); _ret; }) -#define ClearPageError(page) do { if (!test_and_clear_bit(PG_error, &(page)->flags)) BUG(); } while (0) -#define PageReferenced(page) (test_bit(PG_referenced, &(page)->flags)) -#define PageDecrAfter(page) (test_bit(PG_decr_after, &(page)->flags)) -#define PageDMA(page) (test_bit(PG_DMA, &(page)->flags)) -#define PageSlab(page) (test_bit(PG_slab, &(page)->flags)) -#define PageSwapCache(page) (test_bit(PG_swap_cache, &(page)->flags)) -#define PageReserved(page) (test_bit(PG_reserved, &(page)->flags)) - -#define PageSetSlab(page) (set_bit(PG_slab, &(page)->flags)) -#define PageSetSwapCache(page) (set_bit(PG_swap_cache, &(page)->flags)) - -#define PageTestandSetSwapCache(page) \ - (test_and_set_bit(PG_swap_cache, &(page)->flags)) - -#define PageClearSlab(page) (clear_bit(PG_slab, &(page)->flags)) -#define PageClearSwapCache(page)(clear_bit(PG_swap_cache, &(page)->flags)) - -#define PageTestandClearSwapCache(page) \ - (test_and_clear_bit(PG_swap_cache, &(page)->flags)) + clear_bit(PG_locked, &(page)->flags); \ + wake_up(&page->wait); \ + } while (0) +#define PageError(page) test_bit(PG_error, &(page)->flags) +#define SetPageError(page) test_and_set_bit(PG_error, &(page)->flags) +#define ClearPageError(page) clear_bit(PG_error, &(page)->flags) +#define PageReferenced(page) test_bit(PG_referenced, &(page)->flags) +#define PageDecrAfter(page) test_bit(PG_decr_after, &(page)->flags) +#define PageDMA(page) test_bit(PG_DMA, &(page)->flags) +#define PageSlab(page) test_bit(PG_slab, &(page)->flags) +#define PageSwapCache(page) test_bit(PG_swap_cache, &(page)->flags) +#define PageReserved(page) test_bit(PG_reserved, &(page)->flags) + +#define PageSetSlab(page) set_bit(PG_slab, &(page)->flags) +#define PageSetSwapCache(page) set_bit(PG_swap_cache, &(page)->flags) + +#define PageTestandSetSwapCache(page) test_and_set_bit(PG_swap_cache, &(page)->flags) + +#define PageClearSlab(page) clear_bit(PG_slab, &(page)->flags) +#define PageClearSwapCache(page) clear_bit(PG_swap_cache, &(page)->flags) + +#define PageTestandClearSwapCache(page) test_and_clear_bit(PG_swap_cache, &(page)->flags) + #ifdef CONFIG_HIGHMEM -#define PageHighMem(page) (test_bit(PG_highmem, &(page)->flags)) +#define PageHighMem(page) test_bit(PG_highmem, &(page)->flags) #else -#define PageHighMem(page) 0 /* needed to optimize away at compile time */ +#define PageHighMem(page) 0 /* needed to optimize away at compile time */ #endif -#define SetPageReserved(page) do { set_bit(PG_reserved, &(page)->flags); \ - } while (0) -#define ClearPageReserved(page) do { test_and_clear_bit(PG_reserved, &(page)->flags); } while (0) +#define SetPageReserved(page) set_bit(PG_reserved, &(page)->flags) +#define ClearPageReserved(page) clear_bit(PG_reserved, &(page)->flags) /* @@ -359,7 +345,6 @@ extern void remove_inode_page(struct page *); extern unsigned long page_unuse(struct page *); extern int shrink_mmap(int, int); extern void truncate_inode_pages(struct inode *, unsigned long); -extern unsigned long get_cached_page(struct inode *, unsigned long, int); extern void put_cached_page(unsigned long); /* @@ -414,10 +399,8 @@ static inline int expand_stack(struct vm_area_struct * vma, unsigned long addres address &= PAGE_MASK; grow = vma->vm_start - address; - if (vma->vm_end - address - > (unsigned long) current->rlim[RLIMIT_STACK].rlim_cur || - (vma->vm_mm->total_vm << PAGE_SHIFT) + grow - > (unsigned long) current->rlim[RLIMIT_AS].rlim_cur) + if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur || + (vma->vm_mm->total_vm << PAGE_SHIFT) + grow > current->rlim[RLIMIT_AS].rlim_cur) return -ENOMEM; vma->vm_start = address; vma->vm_offset -= grow; diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index 3370208ae..1f3a61486 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h @@ -34,8 +34,9 @@ #define NFSEXP_UIDMAP 0x0040 #define NFSEXP_KERBEROS 0x0080 /* not available */ #define NFSEXP_SUNSECURE 0x0100 -#define NFSEXP_CROSSMNT 0x0200 /* not available */ -#define NFSEXP_ALLFLAGS 0x03FF +#define NFSEXP_CROSSMNT 0x0200 +#define NFSEXP_NOSUBTREECHECK 0x0400 +#define NFSEXP_ALLFLAGS 0x07FF #ifdef __KERNEL__ diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index 5c0d673f2..ca34d85e3 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h @@ -109,9 +109,6 @@ void nfsd_fh_flush(kdev_t); void nfsd_fh_init(void); void nfsd_fh_free(void); -void expire_all(void); -void expire_by_dentry(struct dentry *); - static __inline__ struct svc_fh * fh_copy(struct svc_fh *dst, struct svc_fh *src) { diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 6410d3d1e..de5514574 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -59,10 +59,13 @@ extern void page_cache_init(unsigned long); * and get a reasonable hash by knowing roughly how the * inode pointer and offsets are distributed (ie, we * roughly know which bits are "significant") + * + * For the time being it will work for struct address_space too (most of + * them sitting inside the inodes). We might want to change it later. */ -extern inline unsigned long _page_hashfn(struct inode * inode, unsigned long offset) +extern inline unsigned long _page_hashfn(struct address_space * mapping, unsigned long offset) { -#define i (((unsigned long) inode)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1))) +#define i (((unsigned long) mapping)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1))) #define o (offset >> PAGE_SHIFT) #define s(x) ((x)+((x)>>PAGE_HASH_BITS)) return s(i+o) & (PAGE_HASH_SIZE-1); @@ -71,33 +74,33 @@ extern inline unsigned long _page_hashfn(struct inode * inode, unsigned long off #undef s } -#define page_hash(inode,offset) (page_hash_table+_page_hashfn(inode,offset)) +#define page_hash(mapping,offset) (page_hash_table+_page_hashfn(mapping,offset)) -extern struct page * __find_get_page (struct inode * inode, +extern struct page * __find_get_page (struct address_space *mapping, unsigned long offset, struct page **hash); -#define find_get_page(inode, offset) \ - __find_get_page(inode, offset, page_hash(inode, offset)) -extern struct page * __find_lock_page (struct inode * inode, +#define find_get_page(mapping, offset) \ + __find_get_page(mapping, offset, page_hash(mapping, offset)) +extern struct page * __find_lock_page (struct address_space * mapping, unsigned long offset, struct page **hash); extern void lock_page(struct page *page); -#define find_lock_page(inode, offset) \ - __find_lock_page(inode, offset, page_hash(inode, offset)) +#define find_lock_page(mapping, offset) \ + __find_lock_page(mapping, offset, page_hash(mapping, offset)) extern void __add_page_to_hash_queue(struct page * page, struct page **p); -extern void add_to_page_cache(struct page * page, struct inode * inode, unsigned long offset); -extern int add_to_page_cache_unique(struct page * page, struct inode * inode, unsigned long offset, struct page **hash); +extern void add_to_page_cache(struct page * page, struct address_space *mapping, unsigned long offset); +extern int add_to_page_cache_unique(struct page * page, struct address_space *mapping, unsigned long offset, struct page **hash); extern inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long offset) { - __add_page_to_hash_queue(page, page_hash(inode,offset)); + __add_page_to_hash_queue(page, page_hash(&inode->i_data,offset)); } -extern inline void add_page_to_inode_queue(struct inode * inode, struct page * page) +extern inline void add_page_to_inode_queue(struct address_space *mapping, struct page * page) { - struct list_head *head = &inode->i_pages; + struct list_head *head = &mapping->pages; - if (!inode->i_nrpages++) { + if (!mapping->nrpages++) { if (!list_empty(head)) BUG(); } else { @@ -105,14 +108,14 @@ extern inline void add_page_to_inode_queue(struct inode * inode, struct page * p BUG(); } list_add(&page->list, head); - page->inode = inode; + page->mapping = mapping; } extern inline void remove_page_from_inode_queue(struct page * page) { - struct inode * inode = page->inode; + struct address_space * mapping = page->mapping; - inode->i_nrpages--; + mapping->nrpages--; list_del(&page->list); } diff --git a/include/linux/resource.h b/include/linux/resource.h index f3bffbd7f..5b38bb9e9 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -37,11 +37,16 @@ struct rusage { long ru_nivcsw; /* involuntary " */ }; -#define RLIM_INFINITY ((long)(~0UL>>1)) +/* + * SuS says limits have to be unsigned. + * + * Which makes a ton more sense anyway. + */ +#define RLIM_INFINITY (~0UL) struct rlimit { - long rlim_cur; - long rlim_max; + unsigned long rlim_cur; + unsigned long rlim_max; }; #define PRIO_MIN (-20) diff --git a/include/linux/serialP.h b/include/linux/serialP.h index 3726d9b5d..9f8af3dec 100644 --- a/include/linux/serialP.h +++ b/include/linux/serialP.h @@ -23,9 +23,6 @@ #include <linux/termios.h> #include <linux/tqueue.h> #include <linux/wait.h> -#ifdef CONFIG_PCI -#include <linux/pci.h> -#endif /* * Counters of the input lines (CTS, DSR, RI, CD) interrupts @@ -151,6 +148,7 @@ struct rs_multiport_struct { /* * Structures and definitions for PCI support */ +struct pci_dev; struct pci_board { unsigned short vendor; unsigned short device; diff --git a/include/linux/swap.h b/include/linux/swap.h index 7030b788d..0e186d76b 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -65,7 +65,7 @@ extern int nr_free_pages; extern int nr_lru_pages; extern struct list_head lru_cache; extern atomic_t nr_async_pages; -extern struct inode swapper_inode; +extern struct address_space swapper_space; extern atomic_t page_cache_size; extern atomic_t buffermem_pages; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index c5ba9895f..0e1e65a70 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -103,7 +103,8 @@ enum KERN_MSGPOOL=37, /* int: Maximum system message pool size */ KERN_SYSRQ=38, /* int: Sysreq enable */ KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */ - KERN_RANDOM=40 /* Random driver */ + KERN_RANDOM=40, /* Random driver */ + KERN_SHMALL=41 /* int: Maximum size of shared memory */ }; diff --git a/include/linux/tty.h b/include/linux/tty.h index 69050c8a8..5d85bca76 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -23,7 +23,6 @@ #include <linux/tqueue.h> #include <linux/tty_driver.h> #include <linux/tty_ldisc.h> -#include <linux/serialP.h> #include <asm/system.h> diff --git a/include/net/irda/discovery.h b/include/net/irda/discovery.h index 4d0fe7157..90b8abd41 100644 --- a/include/net/irda/discovery.h +++ b/include/net/irda/discovery.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Apr 6 16:53:53 1999 - * Modified at: Mon Aug 23 09:26:24 1999 + * Modified at: Tue Oct 5 10:05:10 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -45,7 +45,7 @@ * The DISCOVERY structure is used for both discovery requests and responses */ typedef struct { - QUEUE queue; /* Must be first! */ + queue_t q; /* Must be first! */ __u32 saddr; /* Which link the device was discovered */ __u32 daddr; /* Remote device address */ diff --git a/include/net/irda/dongle.h b/include/net/irda/dongle.h deleted file mode 100644 index fd7c7131f..000000000 --- a/include/net/irda/dongle.h +++ /dev/null @@ -1,52 +0,0 @@ -/********************************************************************* - * - * Filename: dongle.h - * Version: - * Description: - * Status: Experimental. - * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Wed Oct 21 22:47:12 1998 - * Modified at: Sat Jun 26 16:58:44 1999 - * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1998-1999 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. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - * - ********************************************************************/ - -#ifndef DONGLE_H -#define DONGLE_H - -#include <net/irda/qos.h> - -/* These are the currently known dongles */ -typedef enum { - TEKRAM_DONGLE, - ESI_DONGLE, - ACTISYS_DONGLE, - ACTISYS_PLUS_DONGLE, - GIRBIL_DONGLE, - LITELINK_DONGLE, - AIRPORT_DONGLE, -} IRDA_DONGLE; - -struct irda_device; - -struct dongle { - IRDA_DONGLE type; - void (*open)(struct irda_device *, int type); - void (*close)(struct irda_device *); - void (*reset)( struct irda_device *); - void (*change_speed)( struct irda_device *, __u32 speed); - void (*qos_init)( struct irda_device *, struct qos_info *); -}; - -#endif diff --git a/include/net/irda/ircomm_core.h b/include/net/irda/ircomm_core.h index 0af1767fe..3e674fe14 100644 --- a/include/net/irda/ircomm_core.h +++ b/include/net/irda/ircomm_core.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Wed Jun 9 08:58:43 1999 - * Modified at: Fri Aug 13 07:24:18 1999 + * Modified at: Tue Oct 5 09:13:50 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -53,7 +53,7 @@ typedef struct { } call_t; struct ircomm_cb { - QUEUE queue; + queue_t queue; magic_t magic; notify_t notify; diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 500baba37..96cc04056 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 23:24:22 1999 - * Modified at: Tue Aug 31 10:22:02 1999 + * Modified at: Tue Oct 5 12:01:07 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -32,6 +32,8 @@ #define IRCOMM_TTY_H #include <linux/serial.h> +#include <linux/termios.h> +#include <linux/timer.h> #include <net/irda/irias_object.h> #include <net/irda/ircomm_core.h> @@ -46,7 +48,7 @@ * IrCOMM TTY driver state */ struct ircomm_tty_cb { - QUEUE queue; + queue_t queue; magic_t magic; int state; @@ -54,7 +56,6 @@ struct ircomm_tty_cb { struct tty_struct *tty; struct ircomm_cb *ircomm; - struct sk_buff_head tx_queue; /* Frames to be transmitted */ struct sk_buff *tx_skb; struct sk_buff *ctrl_skb; @@ -64,7 +65,7 @@ struct ircomm_tty_cb { __u8 service_type; int line; - int flags; + __u32 flags; __u8 dlsap_sel; __u8 slsap_sel; diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h index 5e00eec7a..402cc0791 100644 --- a/include/net/irda/irda.h +++ b/include/net/irda/irda.h @@ -2,11 +2,11 @@ * * Filename: irda.h * Version: - * Description: + * Description: IrDA common include file for kernel internal use * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Dec 9 21:13:12 1997 - * Modified at: Mon Sep 27 11:13:18 1999 + * Modified at: Tue Oct 19 21:12:54 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -28,6 +28,10 @@ #include <linux/config.h> #include <linux/skbuff.h> #include <linux/kernel.h> +#include <linux/if.h> +#include <linux/irda.h> + +typedef __u32 magic_t; #include <net/irda/qos.h> #include <net/irda/irqueue.h> @@ -40,12 +44,16 @@ #define FALSE 0 #endif -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#ifndef IRDA_MIN /* Lets not mix this MIN with other header files */ +#define IRDA_MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif -#define ALIGN __attribute__((aligned)) -#define PACK __attribute__((packed)) +#ifndef ALIGN +# define ALIGN __attribute__((aligned)) +#endif +#ifndef PACK +# define PACK __attribute__((packed)) +#endif #ifdef CONFIG_IRDA_DEBUG @@ -55,14 +63,14 @@ extern __u32 irda_debug; /* use 0 for production, 1 for verification, >2 for debug */ #define IRDA_DEBUG_LEVEL 0 -#define DEBUG(n, args...) (irda_debug >= (n)) ? (printk(KERN_DEBUG args)) : 0 +#define IRDA_DEBUG(n, args...) (irda_debug >= (n)) ? (printk(KERN_DEBUG args)) : 0 #define ASSERT(expr, func) \ if(!(expr)) { \ printk( "Assertion failed! %s,%s,%s,line=%d\n",\ #expr,__FILE__,__FUNCTION__,__LINE__); \ ##func} #else -#define DEBUG(n, args...) +#define IRDA_DEBUG(n, args...) #define ASSERT(expr, func) #endif /* CONFIG_IRDA_DEBUG */ @@ -76,7 +84,6 @@ if(!(expr)) { \ * Magic numbers used by Linux-IrDA. Random numbers which must be unique to * give the best protection */ -typedef __u32 magic_t; #define IRTTY_MAGIC 0x2357 #define LAP_MAGIC 0x1357 @@ -92,6 +99,7 @@ typedef __u32 magic_t; #define IRLAN_MAGIC 0x754 #define IAS_OBJECT_MAGIC 0x34234 #define IAS_ATTRIB_MAGIC 0x45232 +#define IRDA_TASK_MAGIC 0x38423 #define IAS_DEVICE_ID 0x5342 #define IAS_PNP_ID 0xd342 @@ -147,51 +155,19 @@ typedef union { __u8 byte[2]; } __u16_host_order; -/* Per-packet information we need to hide inside sk_buff */ +/* + * Per-packet information we need to hide inside sk_buff + * (must not exceed 48 bytes, check with struct sk_buff) + */ struct irda_skb_cb { magic_t magic; /* Be sure that we can trust the information */ - int mtt; /* minimum turn around time */ - int xbofs; /* number of xbofs required, used by SIR mode */ - int line; /* Used by IrCOMM in IrLPT mode */ - void *instance; /* Used by IrTTP */ + __u32 speed; /* The Speed this frame should be sent with */ + __u16 mtt; /* Minimum turn around time */ + int xbofs; /* Number of xbofs required, used by SIR mode */ + __u8 line; /* Used by IrCOMM in IrLPT mode */ void (*destructor)(struct sk_buff *skb); /* Used for flow control */ }; -/* - * Information monitored by some layers - */ -struct irda_statistics -{ - int rx_packets; /* total packets received */ - int tx_packets; /* total packets transmitted */ - int rx_errors; /* bad packets received */ - int tx_errors; /* packet transmit problems */ - int rx_dropped; /* no space in linux buffers */ - int tx_dropped; /* no space available in linux */ - int rx_compressed; - int tx_compressed; - int rx_bytes; /* total bytes received */ - int tx_bytes; /* total bytes transmitted */ - - int multicast; /* multicast packets received */ - int collisions; - - /* detailed rx_errors: */ - int rx_length_errors; - int rx_over_errors; /* receiver ring buff overflow */ - int rx_crc_errors; /* recved pkt with crc error */ - int rx_frame_errors; /* recv'd frame alignment error */ - int rx_fifo_errors; /* recv'r fifo overrun */ - int rx_missed_errors; /* receiver missed packet */ - - /* detailed tx_errors */ - int tx_aborted_errors; - int tx_carrier_errors; - int tx_fifo_errors; - int tx_heartbeat_errors; - int tx_window_errors; -}; - /* Misc status information */ typedef enum { STATUS_OK, diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h index 5c5d2280e..d633d0e51 100644 --- a/include/net/irda/irda_device.h +++ b/include/net/irda/irda_device.h @@ -1,17 +1,16 @@ /********************************************************************* * * Filename: irda_device.h - * Version: - * Description: + * Version: 0.9 + * Description: Contains various declarations used by the drivers * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Apr 14 12:41:42 1998 - * Modified at: Mon Sep 20 11:21:31 1999 + * Modified at: Tue Oct 19 20:00:03 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. * Copyright (c) 1998 Thomas Davis, <ratbert@radiks.net>, - * Copyright (c) 1998 Haris Zukanovic, <haris@stud.cs.uit.no> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -36,18 +35,13 @@ #include <linux/tty.h> #include <linux/netdevice.h> #include <linux/spinlock.h> +#include <linux/irda.h> #include <net/irda/irda.h> #include <net/irda/qos.h> -#include <net/irda/dongle.h> #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 */ @@ -57,14 +51,74 @@ #define IFF_DMA 0x0020 /* Supports DMA transfer of data */ #define IFF_SHM 0x0040 /* Supports shared memory data transfers */ #define IFF_DONGLE 0x0080 /* Interface has a dongle attached */ -#define IFF_AIR 0x0100 /* Supports A(dvanced)IR standards */ +#define IFF_AIR 0x0100 /* Supports Advanced IR (AIR) standards */ #define IO_XMIT 0x01 #define IO_RECV 0x02 -struct dongle_q { - QUEUE q; - struct dongle *dongle; +typedef enum { + IRDA_IRLAP, /* IrDA mode, and deliver to IrLAP */ + IRDA_RAW, /* IrDA mode */ + SHARP_ASK, + TV_REMOTE, /* Also known as Consumer Electronics IR */ +} INFRARED_MODE; + +typedef enum { + IRDA_TASK_INIT, /* All tasks are initialized with this state */ + IRDA_TASK_DONE, /* Signals that the task is finished */ + IRDA_TASK_WAIT, + IRDA_TASK_WAIT1, + IRDA_TASK_WAIT2, + IRDA_TASK_WAIT3, + IRDA_TASK_CHILD_INIT, /* Initializing child task */ + IRDA_TASK_CHILD_WAIT, /* Waiting for child task to finish */ + IRDA_TASK_CHILD_DONE /* Child task is finished */ +} TASK_STATE; + +struct irda_task; +typedef int (*TASK_CALLBACK) (struct irda_task *task); + +struct irda_task { + queue_t q; + magic_t magic; + + TASK_STATE state; + TASK_CALLBACK function; + TASK_CALLBACK finished; + + /* struct net_device *dev; */ + struct irda_task *parent; + struct timer_list timer; + + void *instance; /* Instance being called */ + void *param; /* Parameter to be used by instance */ +}; + +/* Dongle info */ +struct dongle_reg; +typedef struct { + struct dongle_reg *issue; /* Registration info */ + struct net_device *dev; /* Device we are attached to */ + __u32 speed; /* Current speed */ + + int busy; + + /* Callbacks to the IrDA device driver */ + int (*set_mode)(struct net_device *, int mode); + int (*read)(struct net_device *dev, __u8 *buf, int len); + int (*write)(struct net_device *dev, __u8 *buf, int len); + int (*set_dtr_rts)(struct net_device *dev, int dtr, int rts); +} dongle_t; + +/* Dongle registration info */ +struct dongle_reg { + queue_t q; /* Must be first */ + IRDA_DONGLE type; + + void (*open)(dongle_t *dongle, struct qos_info *qos); + void (*close)(dongle_t *dongle); + int (*reset)(struct irda_task *task); + int (*change_speed)(struct irda_task *task); }; /* Chip specific info */ @@ -79,7 +133,7 @@ struct chipio_t { int irqflags; /* interrupt flags (ie, SA_SHIRQ|SA_INTERRUPT) */ int direction; /* Link direction, used by some FIR drivers */ - __u32 baudrate; /* Currently used baudrate */ + __u32 speed; /* Currently used speed */ int dongle_id; /* Dongle or transceiver currently used */ }; @@ -95,87 +149,38 @@ struct iobuff_t { int len; /* length of data */ int truesize; /* total size of buffer */ __u16 fcs; - - int flags; /* Allocation flags (GFP_KERNEL | GFP_DMA ) */ }; -/* - * This structure contains data that _we_ would have liked to be in the device - * structure, but we don't want to mess it up more than it is already. Better - * to keep the data in separate structures! This structure abstracts common - * stuff from IrDA port implementations. - */ -struct irda_device { - QUEUE q; /* Must be first */ - magic_t magic; /* Our magic bullet */ - - char name[16]; /* Name of device "irda0" */ - char description[32]; /* Something like "irda0 <-> ttyS0" */ - - struct irlap_cb *irlap; /* The link layer we are connected to */ - struct net_device netdev; /* Yes! we are some kind of netdevice */ - struct enet_statistics stats; - - __u32 flags; /* Interface flags (see defs above) */ - - void *priv; /* Pointer to low level implementation */ - - struct qos_info qos; /* QoS capabilities for this device */ - - struct chipio_t io; - struct iobuff_t tx_buff; - struct iobuff_t rx_buff; - - struct dongle *dongle; /* Dongle driver */ - - spinlock_t lock; /* For serializing operations */ - - /* Media busy stuff */ - int media_busy; - struct timer_list media_busy_timer; - - int raw_mode; - - /* Callbacks to driver specific implementations */ - void (*change_speed)(struct irda_device *idev, __u32 speed); - int (*is_receiving)(struct irda_device *); /* receiving? */ - void (*set_dtr_rts)(struct irda_device *idev, int dtr, int rts); - void (*set_raw_mode)(struct irda_device *dev, int mode); - int (*raw_write)(struct irda_device *idev, __u8 *buf, int len); - int (*raw_read)(struct irda_device *idev, __u8 *buf, int len, - int timeout); - void (*wait_until_sent)(struct irda_device *); - void (*set_caddr)(struct irda_device *); /* Set connection addr */ -}; - -extern hashbin_t *irda_device; - /* Function prototypes */ int irda_device_init(void); void irda_device_cleanup(void); -int irda_device_open(struct irda_device *, char *name, void *priv); -void irda_device_close(struct irda_device *); - /* Interface to be uses by IrLAP */ 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); /* 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); -int irda_device_register_dongle(struct dongle *dongle); -int irda_device_set_raw_mode(struct irda_device* self, int status); +int irda_device_txqueue_empty(struct net_device *dev); +int irda_device_set_raw_mode(struct net_device* self, int status); +int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts); int irda_device_setup(struct net_device *dev); +/* Dongle interface */ +void irda_device_unregister_dongle(struct dongle_reg *dongle); +int irda_device_register_dongle(struct dongle_reg *dongle); +dongle_t *irda_device_dongle_init(struct net_device *dev, int type); +int irda_device_dongle_cleanup(dongle_t *dongle); + void setup_dma(int channel, char *buffer, int count, int mode); -int irda_device_net_open(struct net_device *dev); -int irda_device_net_close(struct net_device *dev); +int irda_task_kick(struct irda_task *task); +int irda_task_execute(void *instance, TASK_CALLBACK function, + TASK_CALLBACK finished, struct irda_task *parent, + void *param); +void irda_task_next_state(struct irda_task *task, TASK_STATE state); + +extern const char *infrared_mode[]; /* * Function irda_get_mtt (skb) @@ -197,21 +202,22 @@ extern inline __u16 irda_get_mtt(struct sk_buff *skb) return mtt; } -extern inline void irda_device_set_dtr_rts(struct irda_device *self, int dtr, - int rts) +/* + * Function irda_get_speed (skb) + * + * Extact the speed this frame should be sent out with from the skb + * + */ +extern inline __u32 irda_get_speed(struct sk_buff *skb) { - if (self->set_dtr_rts) - self->set_dtr_rts(self, dtr, rts); -} + __u32 speed; -extern inline int irda_device_raw_write(struct irda_device *self, __u8 *buf, - int len) -{ - int ret = -1; + if (((struct irda_skb_cb *)(skb->cb))->magic != LAP_MAGIC) + speed = 9600; + else + speed = ((struct irda_skb_cb *)(skb->cb))->speed; - if (self->raw_write) - ret = self->raw_write(self, buf, len); - return ret; + return speed; } #endif diff --git a/include/net/irda/iriap.h b/include/net/irda/iriap.h index 994c49f61..9b3629fcf 100644 --- a/include/net/irda/iriap.h +++ b/include/net/irda/iriap.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Thu Aug 21 00:02:07 1997 - * Modified at: Thu Jul 1 10:10:42 1999 + * Modified at: Tue Oct 5 10:05:33 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved. @@ -57,7 +57,7 @@ typedef void (*CONFIRM_CALLBACK)(int result, __u16 obj_id, struct ias_value *value, void *priv); struct iriap_cb { - QUEUE queue; /* Must be first */ + queue_t q; /* Must be first */ magic_t magic; /* Magic cookie */ int mode; /* Client or server */ diff --git a/include/net/irda/irias_object.h b/include/net/irda/irias_object.h index b057b2a4f..1b6f871e6 100644 --- a/include/net/irda/irias_object.h +++ b/include/net/irda/irias_object.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Thu Oct 1 22:49:50 1998 - * Modified at: Thu Jul 1 11:37:15 1999 + * Modified at: Tue Oct 5 10:45:21 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -38,7 +38,7 @@ * LM-IAS Object */ struct ias_object { - QUEUE queue; /* Must be first! */ + queue_t q; /* Must be first! */ magic_t magic; char *name; @@ -66,7 +66,7 @@ struct ias_value { * Attributes used by LM-IAS objects */ struct ias_attrib { - QUEUE queue; /* Must be first! */ + queue_t q; /* Must be first! */ int magic; char *name; /* Attribute name */ diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h index 236d27602..01c364ea2 100644 --- a/include/net/irda/irlan_common.h +++ b/include/net/irda/irlan_common.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:37 1997 - * Modified at: Mon May 31 13:54:20 1999 + * Modified at: Tue Oct 5 11:35:42 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -159,7 +159,7 @@ struct irlan_provider_cb { * IrLAN control block */ struct irlan_cb { - QUEUE queue; /* Must be first */ + queue_t q; /* Must be first */ int magic; char ifname[9]; diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h index f21365188..8059956fa 100644 --- a/include/net/irda/irlap.h +++ b/include/net/irda/irlap.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Aug 4 20:40:53 1997 - * Modified at: Mon Sep 20 10:14:47 1999 + * Modified at: Thu Oct 7 23:06:36 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -67,6 +67,7 @@ #define NS_INVALID -1 #ifdef CONFIG_IRDA_COMPRESSION + /* * Just some shortcuts (may give you strange compiler errors if you change * them :-) @@ -78,7 +79,7 @@ #define irda_incomp (*self->decompressor.cp->incomp) struct irda_compressor { - QUEUE queue; + queue_t q; struct compressor *cp; void *state; /* Not used by IrDA */ @@ -87,7 +88,7 @@ struct irda_compressor { /* Main structure of IrLAP */ struct irlap_cb { - QUEUE q; /* Must be first */ + queue_t q; /* Must be first */ magic_t magic; struct net_device *netdev; @@ -104,6 +105,10 @@ struct irlap_cb { struct timer_list wd_timer; struct timer_list backoff_timer; + /* Media busy stuff */ + struct timer_list media_busy_timer; + int media_busy; + /* Timeouts which will be different with different turn time */ int slot_timeout; int poll_timeout; @@ -157,8 +162,9 @@ struct irlap_cb { hashbin_t *discovery_log; discovery_t *discovery_cmd; - struct qos_info qos_tx; /* QoS requested by peer */ - struct qos_info qos_rx; /* QoS requested by self */ + struct qos_info qos_tx; /* QoS requested by peer */ + struct qos_info qos_rx; /* QoS requested by self */ + struct qos_info *qos_dev; /* QoS supported by device */ notify_t notify; /* Callbacks to IrLMP */ @@ -166,8 +172,6 @@ struct irlap_cb { int xbofs_delay; /* Nr of XBOF's used to MTT */ int bofs_count; /* Negotiated extra BOFs */ - struct irda_statistics stats; - #ifdef CONFIG_IRDA_COMPRESSION struct irda_compressor compressor; struct irda_compressor decompressor; @@ -182,7 +186,7 @@ extern hashbin_t *irlap; int irlap_init(void); void irlap_cleanup(void); -struct irlap_cb *irlap_open(struct net_device *dev); +struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos); void irlap_close(struct irlap_cb *self); void irlap_connect_request(struct irlap_cb *self, __u32 daddr, @@ -191,10 +195,9 @@ void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb); void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb); void irlap_connect_confirm(struct irlap_cb *, struct sk_buff *skb); -inline void irlap_data_indication(struct irlap_cb *, struct sk_buff *); -inline void irlap_unit_data_indication(struct irlap_cb *, struct sk_buff *); -inline void irlap_data_request(struct irlap_cb *, struct sk_buff *, - int reliable); +void irlap_data_indication(struct irlap_cb *, struct sk_buff *); +void irlap_unit_data_indication(struct irlap_cb *, struct sk_buff *); +void irlap_data_request(struct irlap_cb *, struct sk_buff *, int reliable); void irlap_disconnect_request(struct irlap_cb *); void irlap_disconnect_indication(struct irlap_cb *, LAP_REASON reason); @@ -225,14 +228,7 @@ void irlap_apply_default_connection_parameters(struct irlap_cb *self); void irlap_apply_connection_parameters(struct irlap_cb *, struct qos_info *); void irlap_set_local_busy(struct irlap_cb *self, int status); -extern inline __u8 irlap_get_header_size(struct irlap_cb *self) -{ - return 2; -} - -extern inline int irlap_get_tx_queue_len(struct irlap_cb *self) -{ - return skb_queue_len(&self->tx_list); -} +#define IRLAP_GET_HEADER_SIZE(self) 2 /* Will be different when we get VFIR */ +#define IRLAP_GET_TX_QUEUE_LEN(self) skb_queue_len(&self->tx_list) #endif diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h index 40024d38c..e1ba9ee65 100644 --- a/include/net/irda/irlmp.h +++ b/include/net/irda/irlmp.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 17 20:54:32 1997 - * Modified at: Thu Jul 8 13:44:20 1999 + * Modified at: Tue Oct 5 15:20:56 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -78,13 +78,13 @@ typedef void (*DISCOVERY_CALLBACK1) (discovery_t *); typedef void (*DISCOVERY_CALLBACK2) (hashbin_t *); typedef struct { - QUEUE queue; /* Must be first */ + queue_t queue; /* Must be first */ __u16 hints; /* Hint bits */ } irlmp_service_t; typedef struct { - QUEUE queue; /* Must be first */ + queue_t queue; /* Must be first */ __u16 hint_mask; @@ -98,14 +98,12 @@ struct lap_cb; /* Forward decl. */ * Information about each logical LSAP connection */ struct lsap_cb { - QUEUE queue; /* Must be first */ + queue_t queue; /* Must be first */ magic_t magic; int connected; int persistent; - struct irda_statistics stats; - __u8 slsap_sel; /* Source (this) LSAP address */ __u8 dlsap_sel; /* Destination LSAP address (if connected) */ @@ -124,7 +122,7 @@ struct lsap_cb { * Information about each registred IrLAP layer */ struct lap_cb { - QUEUE queue; /* Must be first */ + queue_t queue; /* Must be first */ magic_t magic; int reason; /* LAP disconnect reason */ @@ -248,7 +246,7 @@ static inline int irlmp_get_lap_tx_queue_len(struct lsap_cb *self) ASSERT(self->lap != NULL, return 0;); ASSERT(self->lap->irlap != NULL, return 0;); - return irlap_get_tx_queue_len(self->lap->irlap); + return IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap); } #endif diff --git a/include/net/irda/irmod.h b/include/net/irda/irmod.h index f80221fb8..ca5338edc 100644 --- a/include/net/irda/irmod.h +++ b/include/net/irda/irmod.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Dec 15 13:58:52 1997 - * Modified at: Fri Apr 9 11:13:39 1999 + * Modified at: Tue Oct 5 10:26:46 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli, All Rights Reserved. + * Copyright (c) 1998-1999 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 @@ -69,7 +69,7 @@ typedef void (*TODO_CALLBACK)( void *self, __u32 param); * addtional information */ struct irda_event { - QUEUE q; /* Must be first */ + queue_t q; /* Must be first */ struct irmanager_event event; }; @@ -78,7 +78,7 @@ struct irda_event { * Funtions with needs to be called with a process context */ struct irda_todo { - QUEUE q; /* Must be first */ + queue_t q; /* Must be first */ void *self; TODO_CALLBACK callback; @@ -94,8 +94,8 @@ struct irda_cb { int in_use; - QUEUE *event_queue; /* Events queued for the irmanager */ - QUEUE *todo_queue; /* Todo list */ + queue_t *event_queue; /* Events queued for the irmanager */ + queue_t *todo_queue; /* Todo list */ }; int irmod_init_module(void); @@ -110,7 +110,7 @@ void irmod_cleanup_module(void); static inline int irda_lock(int *lock) { if (test_and_set_bit( 0, (void *) lock)) { - DEBUG(3, __FUNCTION__ + IRDA_DEBUG(3, __FUNCTION__ "(), Trying to lock, already locked variable!\n"); return FALSE; } diff --git a/include/net/irda/irport.h b/include/net/irda/irport.h index 74d6133d8..789c4fce6 100644 --- a/include/net/irda/irport.h +++ b/include/net/irda/irport.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 3 13:49:59 1997 - * Modified at: Sat Jun 26 16:57:03 1999 + * Modified at: Mon Oct 18 12:55:07 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no> @@ -29,6 +29,7 @@ #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/types.h> +#include <linux/spinlock.h> #include <net/irda/irda_device.h> @@ -49,14 +50,35 @@ #define FRAME_MAX_SIZE 2048 -void irport_start(struct irda_device *idev, int iobase); -void irport_stop(struct irda_device *idev, int iobase); +struct irport_cb { + queue_t q; /* Must be first */ + magic_t magic; + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct tty_struct *tty; + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct chipio_t io; /* IrDA controller information */ + struct iobuff_t tx_buff; /* Transmit buffer */ + struct iobuff_t rx_buff; /* Receive buffer */ + + struct qos_info qos; /* QoS capabilities for this device */ + dongle_t *dongle; /* Dongle driver */ + + __u32 flags; /* Interface flags */ + + spinlock_t lock; /* For serializing operations */ + + int mode; +}; + +void irport_start(struct irport_cb *self, int iobase); +void irport_stop(struct irport_cb *self, int iobase); int irport_probe(int iobase); -void irport_change_speed(struct irda_device *idev, __u32 speed); void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs); - int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev); -void irport_wait_until_sent(struct irda_device *idev); #endif diff --git a/include/net/irda/irqueue.h b/include/net/irda/irqueue.h index 52ce2b9d7..3b5bfd492 100644 --- a/include/net/irda/irqueue.h +++ b/include/net/irda/irqueue.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Jun 9 13:26:50 1998 - * Modified at: Thu Jul 1 10:18:21 1999 + * Modified at: Thu Oct 7 13:25:16 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (C) 1998-1999, Aage Kvalnes <aage@cs.uit.no> @@ -53,56 +53,49 @@ #define ALIGN __attribute__((aligned)) #endif -typedef void (*FREE_FUNC)( void *arg); +#define Q_NULL { NULL, NULL, "", 0 } + +typedef void (*FREE_FUNC)(void *arg); /* * Hashbin */ #define GET_HASHBIN(x) ( x & HASHBIN_MASK ) -#define QUEUE struct queue_t -struct queue_t { - QUEUE* q_next; - QUEUE* q_prev; +struct irqueue { + struct irqueue *q_next; + struct irqueue *q_prev; - char q_name[ NAME_SIZE]; + char q_name[NAME_SIZE]; __u32 q_hash; }; +typedef struct irqueue queue_t; typedef struct hashbin_t { __u32 magic; int hb_type; int hb_size; - spinlock_t hb_mutex[ HASHBIN_SIZE ] ALIGN; - QUEUE* hb_queue[ HASHBIN_SIZE ] ALIGN; + spinlock_t hb_mutex[HASHBIN_SIZE] ALIGN; + queue_t *hb_queue[HASHBIN_SIZE] ALIGN; - QUEUE* hb_current; + queue_t* hb_current; } hashbin_t; hashbin_t *hashbin_new(int type); int hashbin_delete(hashbin_t* hashbin, FREE_FUNC func); int hashbin_clear(hashbin_t* hashbin, FREE_FUNC free_func); -void hashbin_insert(hashbin_t* hashbin, QUEUE* entry, __u32 hashv, +void hashbin_insert(hashbin_t* hashbin, queue_t* entry, __u32 hashv, char* name); void* hashbin_find(hashbin_t* hashbin, __u32 hashv, char* name); void* hashbin_remove(hashbin_t* hashbin, __u32 hashv, char* name); void* hashbin_remove_first(hashbin_t *hashbin); -QUEUE *hashbin_get_first(hashbin_t *hashbin); -QUEUE *hashbin_get_next(hashbin_t *hashbin); +queue_t *hashbin_get_first(hashbin_t *hashbin); +queue_t *hashbin_get_next(hashbin_t *hashbin); -void enqueue_last(QUEUE **queue, QUEUE* element); -void enqueue_first(QUEUE **queue, QUEUE* element); -QUEUE *dequeue_first(QUEUE **queue); +void enqueue_last(queue_t **queue, queue_t* element); +void enqueue_first(queue_t **queue, queue_t* element); +queue_t *dequeue_first(queue_t **queue); -/* - * Function hashbin_get_size (hashbin) - * - * Returns the number of elements in the hashbin - * - */ -extern __inline__ int hashbin_get_size(hashbin_t* hashbin) -{ - return hashbin->hb_size; -} +#define HASHBIN_GET_SIZE(hashbin) hashbin->hb_size #endif diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index a44ab2b9f..ffe5b2ec9 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:31 1997 - * Modified at: Mon Sep 27 11:38:01 1999 + * Modified at: Tue Oct 5 15:17:14 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -63,7 +63,7 @@ * connection. */ struct tsap_cb { - QUEUE queue; /* For linking it into the hashbin */ + queue_t q; /* Must be first */ magic_t magic; /* Just in case */ __u8 stsap_sel; /* Source TSAP */ @@ -88,7 +88,7 @@ struct tsap_cb { notify_t notify; /* Callbacks to client layer */ - struct irda_statistics stats; + struct net_device_stats stats; struct timer_list todo_timer; __u32 max_seg_size; /* Max data that fit into an IrLAP frame */ diff --git a/include/net/irda/irtty.h b/include/net/irda/irtty.h index b04d093d1..5c418c355 100644 --- a/include/net/irda/irtty.h +++ b/include/net/irda/irtty.h @@ -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 1 10:13:02 1999 + * Modified at: Mon Oct 18 23:24:31 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved. @@ -28,29 +28,46 @@ #include <linux/if.h> #include <linux/skbuff.h> #include <linux/termios.h> +#include <linux/netdevice.h> #include <net/irda/irda.h> #include <net/irda/irqueue.h> #include <net/irda/irda_device.h> +/* Used by ioctl */ +struct irtty_info { + char name[6]; +}; + #define IRTTY_IOC_MAGIC 'e' #define IRTTY_IOCTDONGLE _IO(IRTTY_IOC_MAGIC, 1) -#define IRTTY_IOC_MAXNR 1 - -#ifndef N_IRDA -#define N_IRDA 11 /* This one should go in </asm/termio.h> */ -#endif +#define IRTTY_IOCGET _IOR(IRTTY_IOC_MAGIC, 2, struct irtty_info) +#define IRTTY_IOC_MAXNR 2 struct irtty_cb { - QUEUE q; /* Must be first */ + queue_t q; /* Must be first */ magic_t magic; - - struct tty_struct *tty; - struct irda_device idev; + + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct tty_struct *tty; + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct chipio_t io; /* IrDA controller information */ + struct iobuff_t tx_buff; /* Transmit buffer */ + struct iobuff_t rx_buff; /* Receive buffer */ + + struct qos_info qos; /* QoS capabilities for this device */ + dongle_t *dongle; /* Dongle driver */ + + __u32 flags; /* Interface flags */ + + INFRARED_MODE mode; }; -int irtty_register_dongle(struct dongle *dongle); -void irtty_unregister_dongle(struct dongle *dongle); +int irtty_register_dongle(struct dongle_reg *dongle); +void irtty_unregister_dongle(struct dongle_reg *dongle); #endif diff --git a/include/net/irda/pc87108.h b/include/net/irda/pc87108.h index 8be4feea1..7af5c0383 100644 --- a/include/net/irda/pc87108.h +++ b/include/net/irda/pc87108.h @@ -6,10 +6,10 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Fri Nov 13 14:37:40 1998 - * Modified at: Mon Jan 25 23:10:25 1999 + * Modified at: Mon Oct 18 15:08:53 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * - * Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no> + * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no> * Copyright (c) 1998 Lichen Wang, <lwang@actisys.com> * Copyright (c) 1998 Actisys Corp., www.actisys.com * All Rights Reserved @@ -183,12 +183,22 @@ struct pc87108 { int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */ int tx_len; /* Number of frames in tx_buff */ - struct irda_device idev; + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct chipio_t io; /* IrDA controller information */ + struct iobuff_t tx_buff; /* Transmit buffer */ + struct iobuff_t rx_buff; /* Receive buffer */ + struct qos_info qos; /* QoS capabilities for this device */ + + __u32 flags; /* Interface flags */ }; -static inline void switch_bank( int iobase, int bank) +static inline void switch_bank(int iobase, int bank) { - outb( bank, iobase+BSR); + outb(bank, iobase+BSR); } #endif diff --git a/include/net/irda/qos.h b/include/net/irda/qos.h index 9f7876cf7..d99abe647 100644 --- a/include/net/irda/qos.h +++ b/include/net/irda/qos.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Fri Sep 19 23:21:09 1997 - * Modified at: Mon Aug 16 10:00:18 1999 + * Modified at: Tue Oct 5 11:51:37 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -69,7 +69,7 @@ typedef struct { } qos_value_t; struct qos_info { - int magic; + magic_t magic; qos_value_t baud_rate; /* IR_11520O | ... */ qos_value_t max_turn_time; @@ -96,9 +96,9 @@ void irda_init_max_qos_capabilies(struct qos_info *qos); void irda_qos_compute_intersection(struct qos_info *, struct qos_info *); int msb_index(__u16 byte); -__u32 byte_value(__u8 byte, int *array); -int value_index(__u32 value, int *array); -__u32 index_value(int index, int *array); +__u32 byte_value(__u8 byte, __u32 *array); +int value_index(__u32 value, __u32 *array); +__u32 index_value(int index, __u32 *array); void irda_qos_bits_to_value(struct qos_info *qos); diff --git a/include/net/irda/timer.h b/include/net/irda/timer.h index f9e598a09..af843bee3 100644 --- a/include/net/irda/timer.h +++ b/include/net/irda/timer.h @@ -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 Jun 23 22:56:51 1999 + * Modified at: Thu Oct 7 12:25:24 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -26,6 +26,8 @@ #ifndef TIMER_H #define TIMER_H +#include <linux/netdevice.h> + #include <asm/param.h> /* for HZ */ #include <net/irda/irda.h> @@ -73,7 +75,7 @@ inline void irlap_start_final_timer(struct irlap_cb *self, int timeout); inline void irlap_start_wd_timer(struct irlap_cb *self, int timeout); inline void irlap_start_backoff_timer(struct irlap_cb *self, int timeout); -inline void irda_device_start_mbusy_timer(struct irda_device *self); +void irlap_start_mbusy_timer(struct irlap_cb *); struct lsap_cb; struct lap_cb; @@ -81,8 +83,5 @@ inline void irlmp_start_watchdog_timer(struct lsap_cb *, int timeout); inline void irlmp_start_discovery_timer(struct irlmp_cb *, int timeout); inline void irlmp_start_idle_timer(struct lap_cb *, int timeout); -struct irobex_cb; -inline void irobex_start_watchdog_timer(struct irobex_cb *, int timeout); - #endif diff --git a/include/net/irda/toshoboe.h b/include/net/irda/toshoboe.h index dc2ea1269..40e781690 100644 --- a/include/net/irda/toshoboe.h +++ b/include/net/irda/toshoboe.h @@ -154,7 +154,16 @@ struct OboeTaskFile struct toshoboe_cb { - struct irda_device idev; /*IRDA device */ + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct chipio_t io; /* IrDA controller information */ + struct qos_info qos; /* QoS capabilities for this device */ + + __u32 flags; /* Interface flags */ + struct pci_dev *pdev; /*PCI device */ int base; /*IO base */ int txpending; /*how many tx's are pending */ diff --git a/include/net/irda/uircc.h b/include/net/irda/uircc.h index adab0c74f..1a2bd6c00 100644 --- a/include/net/irda/uircc.h +++ b/include/net/irda/uircc.h @@ -108,9 +108,11 @@ #define UIRCC_SR13 0x0d /* Timer counter status (high byte) */ #define UIRCC_SR15 0x0f +#include <net/irda/irda_device.h> + /* Private data for each instance */ struct uircc_cb { - struct irda_device idev; + struct net_device idev; __u8 cr3; /* Copy of register sr3 */ }; diff --git a/include/net/irda/w83977af_ir.h b/include/net/irda/w83977af_ir.h index d86456ada..e94271e66 100644 --- a/include/net/irda/w83977af_ir.h +++ b/include/net/irda/w83977af_ir.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Paul VanderSpek * Created at: Thu Nov 19 13:55:34 1998 - * Modified at: Mon May 3 12:07:25 1999 + * Modified at: Fri Oct 15 16:06:46 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -170,12 +170,22 @@ struct w83977af_ir { int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */ int tx_len; /* Number of frames in tx_buff */ - struct irda_device idev; + struct net_device *netdev; /* Yes! we are some kind of netdevice */ + struct net_device_stats stats; + + struct irlap_cb *irlap; /* The link layer we are binded to */ + + struct chipio_t io; /* IrDA controller information */ + struct iobuff_t tx_buff; /* Transmit buffer */ + struct iobuff_t rx_buff; /* Receive buffer */ + struct qos_info qos; /* QoS capabilities for this device */ + + __u32 flags; /* Interface flags */ }; static inline void switch_bank( int iobase, int set) { - outb( set, iobase+SSR); + outb(set, iobase+SSR); } #endif diff --git a/include/net/irda/wrapper.h b/include/net/irda/wrapper.h index fa7ceb25c..2b29d4c42 100644 --- a/include/net/irda/wrapper.h +++ b/include/net/irda/wrapper.h @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Aug 4 20:40:53 1997 - * Modified at: Mon May 3 09:02:36 1999 + * Modified at: Thu Oct 7 11:40:25 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -28,6 +28,7 @@ #include <linux/types.h> #include <linux/skbuff.h> +#include <linux/netdevice.h> #include <net/irda/irda_device.h> @@ -51,6 +52,7 @@ enum { /* Proto definitions */ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize); -inline void async_unwrap_char(struct irda_device *idev, __u8 byte); +int async_bump(struct net_device *dev, __u8 *buf, int len); +int async_unwrap_char(struct net_device *dev, struct iobuff_t *buf, __u8 byte); #endif @@ -33,7 +33,7 @@ static void killseg (int id); static void shm_open (struct vm_area_struct *shmd); static void shm_close (struct vm_area_struct *shmd); static struct page * shm_nopage(struct vm_area_struct *, unsigned long, int); -static int shm_swapout(struct vm_area_struct *, struct page *); +static int shm_swapout(struct page *, struct file *); #ifdef CONFIG_PROC_FS static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data); #endif @@ -646,7 +646,7 @@ asmlinkage long sys_shmdt (char *shmaddr) * data structures already, and shm_swap_out() will just * work off them.. */ -static int shm_swapout(struct vm_area_struct * vma, struct page * page) +static int shm_swapout(struct page * page, struct file *file) { return 0; } @@ -681,7 +681,6 @@ again: pte_t entry = pte; spin_unlock(&shm_lock); - BUG(); page = lookup_swap_cache(entry); if (!page) { lock_kernel(); diff --git a/ipc/util.c b/ipc/util.c index c6423af6a..a1a6826cd 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -119,7 +119,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf) return -ENOSYS; } -void shm_unuse(unsigned long entry, unsigned long page) +void shm_unuse(pte_t entry, struct page *page) { } diff --git a/kernel/fork.c b/kernel/fork.c index 9f3d9f507..2cce575fc 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -352,7 +352,7 @@ void mmput(struct mm_struct *mm) void mm_release(void) { struct task_struct *tsk = current; - forget_segments(); + /* notify parent sleeping on vfork() */ if (tsk->flags & PF_VFORK) { tsk->flags &= ~PF_VFORK; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index d4480e717..52952cf97 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -49,6 +49,7 @@ #include <linux/kmod.h> #endif +extern int console_loglevel; extern void set_device_ro(kdev_t dev,int flag); extern struct file_operations * get_blkfops(unsigned int); extern int blkdev_release(struct inode * inode); @@ -92,6 +93,7 @@ EXPORT_SYMBOL(exit_sighand); /* internal kernel memory management */ EXPORT_SYMBOL(__get_free_pages); +EXPORT_SYMBOL(__get_pages); EXPORT_SYMBOL(free_pages); EXPORT_SYMBOL(__free_page); EXPORT_SYMBOL(kmem_find_general_cachep); @@ -245,6 +247,7 @@ EXPORT_SYMBOL(tq_disk); EXPORT_SYMBOL(init_buffer); EXPORT_SYMBOL(refile_buffer); EXPORT_SYMBOL(max_sectors); +EXPORT_SYMBOL(max_segments); EXPORT_SYMBOL(max_readahead); EXPORT_SYMBOL(file_moveto); @@ -257,6 +260,7 @@ EXPORT_SYMBOL(tty_flip_buffer_push); EXPORT_SYMBOL(tty_get_baud_rate); EXPORT_SYMBOL(do_SAK); EXPORT_SYMBOL(console_print); +EXPORT_SYMBOL(console_loglevel); /* filesystem registration */ EXPORT_SYMBOL(register_filesystem); diff --git a/mm/filemap.c b/mm/filemap.c index 7451f46d9..887d7b6f8 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -89,7 +89,7 @@ void remove_inode_page(struct page *page) spin_lock(&pagecache_lock); remove_page_from_inode_queue(page); remove_page_from_hash_queue(page); - page->inode = NULL; + page->mapping = NULL; spin_unlock(&pagecache_lock); } @@ -98,8 +98,7 @@ void invalidate_inode_pages(struct inode * inode) struct list_head *head, *curr; struct page * page; - head = &inode->i_pages; -repeat: + head = &inode->i_data.pages; spin_lock(&pagecache_lock); curr = head->next; @@ -115,7 +114,7 @@ repeat: remove_page_from_inode_queue(page); remove_page_from_hash_queue(page); - page->inode = NULL; + page->mapping = NULL; page_cache_release(page); } spin_unlock(&pagecache_lock); @@ -133,7 +132,7 @@ void truncate_inode_pages(struct inode * inode, unsigned long start) int partial = 0; repeat: - head = &inode->i_pages; + head = &inode->i_data.pages; spin_lock(&pagecache_lock); curr = head->next; while (curr != head) { @@ -273,7 +272,7 @@ int shrink_mmap(int priority, int gfp_mask) if (!try_to_free_buffers(page)) goto unlock_continue; /* page was locked, inode can't go away under us */ - if (!page->inode) { + if (!page->mapping) { atomic_dec(&buffermem_pages); goto made_buffer_progress; } @@ -299,14 +298,13 @@ int shrink_mmap(int priority, int gfp_mask) } /* is it a page-cache page? */ - if (page->inode) - { + if (page->mapping) { dispose = &old; if (!pgcache_under_min()) { remove_page_from_inode_queue(page); remove_page_from_hash_queue(page); - page->inode = NULL; + page->mapping = NULL; spin_unlock(&pagecache_lock); goto made_inode_progress; } @@ -358,7 +356,7 @@ out: return ret; } -static inline struct page * __find_page_nolock(struct inode * inode, unsigned long offset, struct page *page) +static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page) { goto inside; @@ -367,7 +365,7 @@ static inline struct page * __find_page_nolock(struct inode * inode, unsigned lo inside: if (!page) goto not_found; - if (page->inode != inode) + if (page->mapping != mapping) continue; if (page->offset == offset) break; @@ -418,7 +416,7 @@ static int do_buffer_fdatasync(struct inode *inode, unsigned long start, unsigne struct page *page; int retval = 0; - head = &inode->i_pages; + head = &inode->i_data.pages; start &= PAGE_MASK; spin_lock(&pagecache_lock); @@ -469,7 +467,7 @@ int generic_buffer_fdatasync(struct inode *inode, unsigned long start, unsigned * owned by us, referenced, but not uptodate and with no errors. */ static inline void __add_to_page_cache(struct page * page, - struct inode * inode, unsigned long offset, + struct address_space *mapping, unsigned long offset, struct page **hash) { struct page *alias; @@ -477,37 +475,36 @@ static inline void __add_to_page_cache(struct page * page, flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced)); page->flags = flags | (1 << PG_locked); - page->owner = current; /* REMOVEME */ get_page(page); page->offset = offset; - add_page_to_inode_queue(inode, page); + add_page_to_inode_queue(mapping, page); __add_page_to_hash_queue(page, hash); lru_cache_add(page); - alias = __find_page_nolock(inode, offset, *hash); + alias = __find_page_nolock(mapping, offset, *hash); if (alias != page) BUG(); } -void add_to_page_cache(struct page * page, struct inode * inode, unsigned long offset) +void add_to_page_cache(struct page * page, struct address_space * mapping, unsigned long offset) { spin_lock(&pagecache_lock); - __add_to_page_cache(page, inode, offset, page_hash(inode, offset)); + __add_to_page_cache(page, mapping, offset, page_hash(mapping, offset)); spin_unlock(&pagecache_lock); } int add_to_page_cache_unique(struct page * page, - struct inode * inode, unsigned long offset, + struct address_space *mapping, unsigned long offset, struct page **hash) { int err; struct page *alias; spin_lock(&pagecache_lock); - alias = __find_page_nolock(inode, offset, *hash); + alias = __find_page_nolock(mapping, offset, *hash); err = 1; if (!alias) { - __add_to_page_cache(page,inode,offset,hash); + __add_to_page_cache(page,mapping,offset,hash); err = 0; } @@ -522,11 +519,11 @@ int add_to_page_cache_unique(struct page * page, static inline void page_cache_read(struct file * file, unsigned long offset) { struct inode *inode = file->f_dentry->d_inode; - struct page **hash = page_hash(inode, offset); + struct page **hash = page_hash(&inode->i_data, offset); struct page *page; spin_lock(&pagecache_lock); - page = __find_page_nolock(inode, offset, *hash); + page = __find_page_nolock(&inode->i_data, offset, *hash); spin_unlock(&pagecache_lock); if (page) return; @@ -535,7 +532,7 @@ static inline void page_cache_read(struct file * file, unsigned long offset) if (!page) return; - if (!add_to_page_cache_unique(page, inode, offset, hash)) { + if (!add_to_page_cache_unique(page, &inode->i_data, offset, hash)) { inode->i_op->readpage(file, page); page_cache_release(page); return; @@ -605,7 +602,7 @@ void lock_page(struct page *page) * a rather lightweight function, finding and getting a reference to a * hashed page atomically, waiting for it if it's locked. */ -struct page * __find_get_page (struct inode * inode, +struct page * __find_get_page (struct address_space *mapping, unsigned long offset, struct page **hash) { struct page *page; @@ -616,7 +613,7 @@ struct page * __find_get_page (struct inode * inode, */ repeat: spin_lock(&pagecache_lock); - page = __find_page_nolock(inode, offset, *hash); + page = __find_page_nolock(mapping, offset, *hash); if (page) get_page(page); spin_unlock(&pagecache_lock); @@ -655,7 +652,7 @@ repeat: /* * Get the lock to a page atomically. */ -struct page * __find_lock_page (struct inode * inode, +struct page * __find_lock_page (struct address_space *mapping, unsigned long offset, struct page **hash) { struct page *page; @@ -666,7 +663,7 @@ struct page * __find_lock_page (struct inode * inode, */ repeat: spin_lock(&pagecache_lock); - page = __find_page_nolock(inode, offset, *hash); + page = __find_page_nolock(mapping, offset, *hash); if (page) get_page(page); spin_unlock(&pagecache_lock); @@ -1005,10 +1002,10 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * /* * Try to find the data in the page cache.. */ - hash = page_hash(inode, pos & PAGE_CACHE_MASK); + hash = page_hash(&inode->i_data, pos & PAGE_CACHE_MASK); spin_lock(&pagecache_lock); - page = __find_page_nolock(inode, pos & PAGE_CACHE_MASK, *hash); + page = __find_page_nolock(&inode->i_data, pos & PAGE_CACHE_MASK, *hash); if (!page) goto no_cached_page; found_page: @@ -1104,7 +1101,7 @@ no_cached_page: * dropped the page cache lock. Check for that. */ spin_lock(&pagecache_lock); - page = __find_page_nolock(inode, pos & PAGE_CACHE_MASK, *hash); + page = __find_page_nolock(&inode->i_data, pos & PAGE_CACHE_MASK, *hash); if (page) goto found_page; } @@ -1113,7 +1110,7 @@ no_cached_page: * Ok, add the new page to the hash-queues... */ page = cached_page; - __add_to_page_cache(page, inode, pos & PAGE_CACHE_MASK, hash); + __add_to_page_cache(page, &inode->i_data, pos & PAGE_CACHE_MASK, hash); spin_unlock(&pagecache_lock); cached_page = NULL; @@ -1316,9 +1313,9 @@ static struct page * filemap_nopage(struct vm_area_struct * area, /* * Do we have something in the page cache already? */ - hash = page_hash(inode, offset); + hash = page_hash(&inode->i_data, offset); retry_find: - page = __find_get_page(inode, offset, hash); + page = __find_get_page(&inode->i_data, offset, hash); if (!page) goto no_cached_page; @@ -1441,27 +1438,25 @@ static inline int do_write_page(struct inode * inode, struct file * file, return retval; } -static int filemap_write_page(struct vm_area_struct * vma, +static int filemap_write_page(struct file *file, unsigned long offset, struct page * page, int wait) { int result; - struct file * file; struct dentry * dentry; struct inode * inode; - file = vma->vm_file; dentry = file->f_dentry; inode = dentry->d_inode; /* * If a task terminates while we're swapping the page, the vma and - * and file could be released ... increment the count to be safe. + * and file could be released: try_to_swap_out has done a get_file. + * vma/file is guaranteed to exist in the unmap/sync cases because + * mmap_sem is held. */ - get_file(file); result = do_write_page(inode, file, page, offset); - fput(file); return result; } @@ -1472,9 +1467,9 @@ static int filemap_write_page(struct vm_area_struct * vma, * at the same time.. */ extern void wakeup_bdflush(int); -int filemap_swapout(struct vm_area_struct * vma, struct page * page) +int filemap_swapout(struct page * page, struct file * file) { - int retval = filemap_write_page(vma, page->offset, page, 0); + int retval = filemap_write_page(file, page->offset, page, 0); wakeup_bdflush(0); return retval; } @@ -1515,7 +1510,7 @@ static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma, } if (PageHighMem(page)) BUG(); - error = filemap_write_page(vma, address - vma->vm_start + vma->vm_offset, page, 1); + error = filemap_write_page(vma->vm_file, address - vma->vm_start + vma->vm_offset, page, 1); page_cache_free(page); return error; } @@ -1821,9 +1816,9 @@ generic_file_write(struct file *file, const char *buf, if (bytes > count) bytes = count; - hash = page_hash(inode, pgpos); + hash = page_hash(&inode->i_data, pgpos); repeat_find: - page = __find_lock_page(inode, pgpos, hash); + page = __find_lock_page(&inode->i_data, pgpos, hash); if (!page) { if (!cached_page) { cached_page = page_cache_alloc(); @@ -1833,7 +1828,7 @@ repeat_find: break; } page = cached_page; - if (add_to_page_cache_unique(page,inode,pgpos,hash)) + if (add_to_page_cache_unique(page,&inode->i_data,pgpos,hash)) goto repeat_find; cached_page = NULL; @@ -1842,10 +1837,6 @@ repeat_find: /* We have exclusive IO access to the page.. */ if (!PageLocked(page)) { PAGE_BUG(page); - } else { - if (page->owner != current) { - PAGE_BUG(page); - } } status = write_one_page(file, page, offset, bytes, buf); @@ -687,11 +687,6 @@ int do_munmap(unsigned long addr, size_t len) end = end > mpnt->vm_end ? mpnt->vm_end : end; size = end - st; - /* - * The lock_kernel interlocks with kswapd try_to_swap_out - * invoking a driver swapout() method, and being able to - * guarantee vma existance. - */ lock_kernel(); if (mpnt->vm_ops && mpnt->vm_ops->unmap) mpnt->vm_ops->unmap(mpnt, st, size); diff --git a/mm/page_io.c b/mm/page_io.c index 3ce1a186c..c5ed3ed74 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -136,7 +136,7 @@ void rw_swap_page(int rw, struct page *page, int wait) PAGE_BUG(page); if (!PageSwapCache(page)) PAGE_BUG(page); - if (page->inode != &swapper_inode) + if (page->mapping != &swapper_space) PAGE_BUG(page); if (!rw_swap_page_base(rw, entry, page, wait)) UnlockPage(page); diff --git a/mm/swap_state.c b/mm/swap_state.c index c3f6b271c..d79b7bffb 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -17,42 +17,12 @@ #include <asm/pgtable.h> -/* - * Keep a reserved false inode which we will use to mark pages in the - * page cache are acting as swap cache instead of file cache. - * - * We only need a unique pointer to satisfy the page cache, but we'll - * reserve an entire zeroed inode structure for the purpose just to - * ensure that any mistaken dereferences of this structure cause a - * kernel oops. - */ - -static struct inode_operations swapper_inode_operations = { - NULL, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - block_flushpage, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; - -struct inode swapper_inode = { - i_op: &swapper_inode_operations, - i_pages: {&swapper_inode.i_pages,&swapper_inode.i_pages} +struct address_space swapper_space = { + { /* pages */ + &swapper_space.pages, /* .next */ + &swapper_space.pages /* .prev */ + }, + 0 /* nrpages */ }; #ifdef SWAP_CACHE_INFO @@ -77,9 +47,9 @@ void add_to_swap_cache(struct page *page, pte_t entry) #endif if (PageTestandSetSwapCache(page)) BUG(); - if (page->inode) + if (page->mapping) BUG(); - add_to_page_cache(page, &swapper_inode, pte_val(entry)); + add_to_page_cache(page, &swapper_space, pte_val(entry)); } /* @@ -173,11 +143,9 @@ bad_unused: static inline void remove_from_swap_cache(struct page *page) { - struct inode *inode = page->inode; + struct address_space *mapping = page->mapping; - if (!inode) - BUG(); - if (inode != &swapper_inode) + if (mapping != &swapper_space) BUG(); if (!PageSwapCache(page)) PAGE_BUG(page); @@ -205,8 +173,7 @@ void __delete_from_swap_cache(struct page *page) static void delete_from_swap_cache_nolock(struct page *page) { - if (!swapper_inode.i_op->flushpage || - swapper_inode.i_op->flushpage(&swapper_inode, page, 0)) + if (block_flushpage(NULL, page, 0)) lru_cache_del(page); __delete_from_swap_cache(page); @@ -267,10 +234,10 @@ struct page * lookup_swap_cache(pte_t entry) /* * Right now the pagecache is 32-bit only. */ - found = find_lock_page(&swapper_inode, pte_val(entry)); + found = find_lock_page(&swapper_space, pte_val(entry)); if (!found) return 0; - if (found->inode != &swapper_inode || !PageSwapCache(found)) + if (found->mapping != &swapper_space || !PageSwapCache(found)) goto out_bad; #ifdef SWAP_CACHE_INFO swap_cache_find_success++; diff --git a/mm/swapfile.c b/mm/swapfile.c index 76aea7b7e..bcd7b4587 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -779,23 +779,26 @@ out: void si_swapinfo(struct sysinfo *val) { - unsigned int i, j; + unsigned int i; + unsigned long freeswap = 0; + unsigned long totalswap = 0; - val->freeswap = val->totalswap = 0; for (i = 0; i < nr_swapfiles; i++) { + unsigned int j; if ((swap_info[i].flags & SWP_WRITEOK) != SWP_WRITEOK) continue; - for (j = 0; j < swap_info[i].max; ++j) + for (j = 0; j < swap_info[i].max; ++j) { switch (swap_info[i].swap_map[j]) { case SWAP_MAP_BAD: continue; case 0: - ++val->freeswap; + freeswap++; default: - ++val->totalswap; + totalswap++; } + } } - val->freeswap <<= PAGE_SHIFT; - val->totalswap <<= PAGE_SHIFT; + val->freeswap = freeswap; + val->totalswap = totalswap; return; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 1c436af20..0978f544c 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -42,7 +42,7 @@ static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned lo __free_page(mem_map + map_nr); continue; } - printk("Whee.. Swapped out page in kernel page table\n"); + printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n"); } while (address < end); } @@ -96,7 +96,7 @@ static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned lo do { struct page * page; if (!pte_none(*pte)) - printk("alloc_area_pte: page already exists\n"); + printk(KERN_ERR "alloc_area_pte: page already exists\n"); page = get_free_highpage(GFP_KERNEL|__GFP_HIGHMEM); if (!page) return -ENOMEM; @@ -184,7 +184,7 @@ void vfree(void * addr) if (!addr) return; if ((PAGE_SIZE-1) & (unsigned long) addr) { - printk("Trying to vfree() bad address (%p)\n", addr); + printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr); return; } for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { @@ -195,7 +195,7 @@ void vfree(void * addr) return; } } - printk("Trying to vfree() nonexistent vm area (%p)\n", addr); + printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr); } void * vmalloc_prot(unsigned long size, pgprot_t prot) diff --git a/mm/vmscan.c b/mm/vmscan.c index 83d987a9f..9db9ce6f9 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -18,6 +18,7 @@ #include <linux/pagemap.h> #include <linux/init.h> #include <linux/highmem.h> +#include <linux/file.h> #include <asm/pgtable.h> @@ -36,6 +37,7 @@ static int try_to_swap_out(struct vm_area_struct* vma, unsigned long address, pt { pte_t pte, entry; struct page * page; + int (*swapout)(struct page *, struct file *); pte = *page_table; if (!pte_present(pte)) @@ -126,13 +128,16 @@ drop_pte: * That would get rid of a lot of problems. */ flush_cache_page(vma, address); - if (vma->vm_ops && vma->vm_ops->swapout) { + if (vma->vm_ops && (swapout = vma->vm_ops->swapout)) { int error; + struct file *file = vma->vm_file; + if (file) get_file(file); pte_clear(page_table); vma->vm_mm->rss--; flush_tlb_page(vma, address); vmlist_access_unlock(vma->vm_mm); - error = vma->vm_ops->swapout(vma, page); + error = swapout(page, file); + if (file) fput(file); if (!error) goto out_free_success; __free_page(page); diff --git a/net/core/dev.c b/net/core/dev.c index 2f9edda09..078caeb99 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -374,6 +374,7 @@ struct net_device *dev_alloc(const char *name, int *err) *err=-ENOBUFS; return NULL; } + memset(dev, 0, sizeof(struct net_device)); dev->name=(char *)(dev+1); /* Name string space */ *err=dev_alloc_name(dev,name); if(*err<0) diff --git a/net/decnet/Config.in b/net/decnet/Config.in index 6e992c0a8..323ae86f7 100644 --- a/net/decnet/Config.in +++ b/net/decnet/Config.in @@ -2,7 +2,7 @@ # DECnet configuration # bool ' DECnet: SIOCGIFCONF support' CONFIG_DECNET_SIOCGIFCONF -if [ "$CONFIG_EXPERIMENTAL" ]; then +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' DECnet: router support (EXPERIMENTAL)' CONFIG_DECNET_ROUTER fi bool ' DECnet: raw socket support' CONFIG_DECNET_RAW diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 96060aa88..7a01c28ea 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -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 Sep 27 20:11:52 1999 + * Modified at: Fri Oct 1 19:11:04 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc. * @@ -76,7 +76,7 @@ static int irda_data_indication(void *instance, void *sap, struct sk_buff *skb) err = sock_queue_rcv_skb(sk, skb); if (err) { - DEBUG(1, __FUNCTION__ "(), error: no more mem!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), error: no more mem!\n"); self->rx_flow = FLOW_STOP; /* When we return error, TTP will need to requeue the skb */ @@ -98,7 +98,7 @@ static void irda_disconnect_indication(void *instance, void *sap, struct irda_sock *self; struct sock *sk; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_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(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); self = (struct irda_sock *) instance; @@ -145,7 +145,7 @@ static void irda_connect_confirm(void *instance, void *sap, else self->max_data_size = max_sdu_size; - DEBUG(1, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size); + IRDA_DEBUG(1, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size); memcpy(&self->qos_tx, qos, sizeof(struct qos_info)); @@ -173,7 +173,7 @@ static void irda_connect_indication(void *instance, void *sap, struct irda_sock *self; struct sock *sk; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); self = (struct irda_sock *) instance; @@ -189,7 +189,7 @@ static void irda_connect_indication(void *instance, void *sap, else self->max_data_size = max_sdu_size; - DEBUG(1, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size); + IRDA_DEBUG(1, __FUNCTION__ "(), max_data_size=%d\n", self->max_data_size); memcpy(&self->qos_tx, qos, sizeof(struct qos_info)); @@ -212,13 +212,13 @@ void irda_connect_response(struct irda_sock *self) { struct sk_buff *skb; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); skb = dev_alloc_skb(64); if (skb == NULL) { - DEBUG(0, __FUNCTION__ "() Unable to allocate sk_buff!\n"); + IRDA_DEBUG(0, __FUNCTION__ "() Unable to allocate sk_buff!\n"); return; } @@ -239,7 +239,7 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) struct irda_sock *self; struct sock *sk; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); self = (struct irda_sock *) instance; ASSERT(self != NULL, return;); @@ -249,16 +249,16 @@ static void irda_flow_indication(void *instance, void *sap, LOCAL_FLOW flow) switch (flow) { case FLOW_STOP: - DEBUG(1, __FUNCTION__ "(), IrTTP wants us to slow down\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), IrTTP wants us to slow down\n"); self->tx_flow = flow; break; case FLOW_START: self->tx_flow = flow; - DEBUG(1, __FUNCTION__ "(), IrTTP wants us to start again\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), IrTTP wants us to start again\n"); wake_up_interruptible(sk->sleep); break; default: - DEBUG( 0, __FUNCTION__ "(), Unknown flow command!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown flow command!\n"); } } @@ -273,7 +273,7 @@ static void irda_get_value_confirm(int result, __u16 obj_id, { struct irda_sock *self; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(priv != NULL, return;); self = (struct irda_sock *) priv; @@ -283,7 +283,7 @@ static void irda_get_value_confirm(int result, __u16 obj_id, /* Check if request succeeded */ if (result != IAS_SUCCESS) { - DEBUG(0, __FUNCTION__ "(), IAS query failed!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), IAS query failed!\n"); self->errno = result; @@ -295,7 +295,7 @@ static void irda_get_value_confirm(int result, __u16 obj_id, switch (value->type) { case IAS_INTEGER: - DEBUG(4, __FUNCTION__ "() int=%d\n", value->t.integer); + IRDA_DEBUG(4, __FUNCTION__ "() int=%d\n", value->t.integer); if (value->t.integer != -1) { self->dtsap_sel = value->t.integer; @@ -303,7 +303,7 @@ static void irda_get_value_confirm(int result, __u16 obj_id, self->dtsap_sel = 0; break; default: - DEBUG(0, __FUNCTION__ "(), bad type!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), bad type!\n"); break; } /* Wake up any processes waiting for result */ @@ -318,7 +318,7 @@ static void irda_get_value_confirm(int result, __u16 obj_id, */ static void irda_discovery_indication(hashbin_t *log) { - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); cachelog = log; @@ -349,7 +349,7 @@ static int irda_open_tsap(struct irda_sock *self, __u8 tsap_sel, char *name) self->tsap = irttp_open_tsap(tsap_sel, DEFAULT_INITIAL_CREDIT, ¬ify); if (self->tsap == NULL) { - DEBUG( 0, __FUNCTION__ "(), Unable to allocate TSAP!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to allocate TSAP!\n"); return -1; } /* Remember which TSAP selector we actually got */ @@ -366,7 +366,7 @@ static int irda_open_tsap(struct irda_sock *self, __u8 tsap_sel, char *name) */ static int irda_find_lsap_sel(struct irda_sock *self, char *name) { - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); @@ -408,8 +408,8 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, saddr.sir_addr = sk->protinfo.irda->saddr; } - DEBUG(1, __FUNCTION__ "(), tsap_sel = %#x\n", saddr.sir_lsap_sel); - DEBUG(1, __FUNCTION__ "(), addr = %08x\n", saddr.sir_addr); + IRDA_DEBUG(1, __FUNCTION__ "(), tsap_sel = %#x\n", saddr.sir_lsap_sel); + IRDA_DEBUG(1, __FUNCTION__ "(), addr = %08x\n", saddr.sir_addr); if (*uaddr_len > sizeof (struct sockaddr_irda)) *uaddr_len = sizeof (struct sockaddr_irda); @@ -493,7 +493,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) struct sk_buff *skb; int err; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); self = sk->protinfo.irda; ASSERT(self != NULL, return -1;); @@ -538,7 +538,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) /* Now attach up the new socket */ new->tsap = irttp_dup(self->tsap, new); if (!new->tsap) { - DEBUG(0, __FUNCTION__ "(), dup failed!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), dup failed!\n"); return -1; } @@ -610,12 +610,12 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, return -EINVAL; self->daddr = addr->sir_addr; - DEBUG(1, __FUNCTION__ "(), daddr = %08x\n", self->daddr); + IRDA_DEBUG(1, __FUNCTION__ "(), daddr = %08x\n", self->daddr); /* Query remote LM-IAS */ err = irda_find_lsap_sel(self, addr->sir_name); if (err) { - DEBUG(0, __FUNCTION__ "(), connect failed!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n"); return err; } @@ -632,7 +632,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, self->saddr, self->daddr, NULL, self->max_sdu_size_rx, NULL); if (err) { - DEBUG(0, __FUNCTION__ "(), connect failed!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), connect failed!\n"); return err; } @@ -676,7 +676,7 @@ static int irda_create(struct socket *sock, int protocol) struct sock *sk; struct irda_sock *self; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); /* Check for valid socket type */ switch (sock->type) { @@ -730,7 +730,7 @@ static int irda_create(struct socket *sock, int protocol) */ void irda_destroy_socket(struct irda_sock *self) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); @@ -766,7 +766,7 @@ static int irda_release(struct socket *sock) { struct sock *sk = sock->sk; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); if (sk == NULL) return 0; @@ -800,7 +800,7 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len, unsigned char *asmptr; int err; - DEBUG(4, __FUNCTION__ "(), len=%d\n", len); + IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len); if (msg->msg_flags & ~MSG_DONTWAIT) return -EINVAL; @@ -815,7 +815,7 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len, /* Check if IrTTP is wants us to slow down */ while (self->tx_flow == FLOW_STOP) { - DEBUG(2, __FUNCTION__ "(), IrTTP is busy, going to sleep!\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), IrTTP is busy, going to sleep!\n"); interruptible_sleep_on(sk->sleep); /* Check if we are still connected */ @@ -825,7 +825,7 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len, /* Check that we don't send out to big frames */ if (len > self->max_data_size) { - DEBUG(0, __FUNCTION__ "(), Warning to much data! " + IRDA_DEBUG(0, __FUNCTION__ "(), Warning to much data! " "Chopping frame from %d to %d bytes!\n", len, self->max_data_size); len = self->max_data_size; @@ -838,7 +838,7 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len, skb_reserve(skb, self->max_header_size); - DEBUG(4, __FUNCTION__ "(), appending user data\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), appending user data\n"); asmptr = skb->h.raw = skb_put(skb, len); memcpy_fromiovec(asmptr, msg->msg_iov, len); @@ -848,7 +848,7 @@ static int irda_sendmsg(struct socket *sock, struct msghdr *msg, int len, */ err = irttp_data_request(self->tsap, skb); if (err) { - DEBUG(0, __FUNCTION__ "(), err=%d\n", err); + IRDA_DEBUG(0, __FUNCTION__ "(), err=%d\n", err); return err; } return len; @@ -868,7 +868,7 @@ static int irda_recvmsg_dgram(struct socket *sock, struct msghdr *msg, struct sk_buff *skb; int copied, err; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); self = sk->protinfo.irda; ASSERT(self != NULL, return -1;); @@ -897,7 +897,7 @@ static int irda_recvmsg_dgram(struct socket *sock, struct msghdr *msg, */ if (self->rx_flow == FLOW_STOP) { if ((atomic_read(&sk->rmem_alloc) << 2) <= sk->rcvbuf) { - DEBUG(2, __FUNCTION__ "(), Starting IrTTP\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), Starting IrTTP\n"); self->rx_flow = FLOW_START; irttp_flow_request(self->tsap, FLOW_START); } @@ -936,7 +936,7 @@ static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, int copied = 0; int target = 1; - DEBUG(3, __FUNCTION__ "()\n"); + IRDA_DEBUG(3, __FUNCTION__ "()\n"); self = sk->protinfo.irda; ASSERT(self != NULL, return -1;); @@ -1021,7 +1021,7 @@ static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, /* put the skb back if we didn't use it up.. */ if (skb->len) { - DEBUG(1, __FUNCTION__ "(), back on q!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), back on q!\n"); skb_queue_head(&sk->receive_queue, skb); break; } @@ -1031,7 +1031,7 @@ static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, /* if (scm->fp) */ /* break; */ } else { - DEBUG(0, __FUNCTION__ "() questionable!?\n"); + IRDA_DEBUG(0, __FUNCTION__ "() questionable!?\n"); /* It is questionable, see note in unix_dgram_recvmsg. */ /* if (UNIXCB(skb).fp) */ /* scm->fp = scm_fp_dup(UNIXCB(skb).fp); */ @@ -1050,7 +1050,7 @@ static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, */ if (self->rx_flow == FLOW_STOP) { if ((atomic_read(&sk->rmem_alloc) << 2) <= sk->rcvbuf) { - DEBUG(2, __FUNCTION__ "(), Starting IrTTP\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), Starting IrTTP\n"); self->rx_flow = FLOW_START; irttp_flow_request(self->tsap, FLOW_START); } @@ -1069,7 +1069,7 @@ static int irda_recvmsg_stream(struct socket *sock, struct msghdr *msg, */ static int irda_shutdown( struct socket *sk, int how) { - DEBUG( 0, __FUNCTION__ "()\n"); + IRDA_DEBUG( 0, __FUNCTION__ "()\n"); /* FIXME - generate DM and RNR states */ return -EOPNOTSUPP; @@ -1087,7 +1087,7 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, struct sock *sk = sock->sk; unsigned int mask; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); poll_wait(file, sk->sleep, wait); mask = 0; @@ -1126,7 +1126,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; - DEBUG(4, __FUNCTION__ "(), cmd=%#x\n", cmd); + IRDA_DEBUG(4, __FUNCTION__ "(), cmd=%#x\n", cmd); switch (cmd) { case TIOCOUTQ: { @@ -1173,7 +1173,7 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCSIFMETRIC: return -EINVAL; default: - DEBUG(1, __FUNCTION__ "(), doing device ioctl!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), doing device ioctl!\n"); return dev_ioctl(cmd, (void *) arg); } @@ -1208,10 +1208,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname, switch (optname) { case IRLMP_IAS_SET: - DEBUG(0, __FUNCTION__ "(), sorry not impl. yet!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), sorry not impl. yet!\n"); return 0; case IRTTP_MAX_SDU_SIZE: - DEBUG(2, __FUNCTION__ "(), setting max_sdu_size = %d\n", opt); + IRDA_DEBUG(2, __FUNCTION__ "(), setting max_sdu_size = %d\n", opt); self->max_sdu_size_rx = opt; break; default: @@ -1265,7 +1265,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, offset = sizeof(struct irda_device_list) - sizeof(struct irda_device_info); - total = offset; /* Initialized to size of the device list */ + total = offset; /* Initialized to size of the device list */ list.len = 0; /* Initialize lenght of list */ /* @@ -1279,7 +1279,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, if (discovery->hints.word & self->mask) { /* Check if room for this device entry */ - if (len - total >= sizeof(struct irda_device_info)) + if (len - total < sizeof(struct irda_device_info)) break; /* Copy discovery information */ @@ -1291,7 +1291,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, strncpy(info->info, discovery->nickname, NICKNAME_MAX_LEN); - if (copy_to_user(optval+offset, &info, + if (copy_to_user(optval+offset, info, sizeof(struct irda_device_info))) return -EFAULT; list.len++; @@ -1313,7 +1313,7 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, break; case IRTTP_MAX_SDU_SIZE: val = self->max_data_size; - DEBUG(2, __FUNCTION__ "(), getting max_sdu_size = %d\n", val); + IRDA_DEBUG(2, __FUNCTION__ "(), getting max_sdu_size = %d\n", val); len = sizeof(int); if (put_user(len, optlen)) return -EFAULT; @@ -1397,11 +1397,11 @@ static int irda_device_event(struct notifier_block *this, unsigned long event, switch (event) { case NETDEV_UP: - DEBUG(3, __FUNCTION__ "(), NETDEV_UP\n"); + IRDA_DEBUG(3, __FUNCTION__ "(), NETDEV_UP\n"); /* irda_dev_device_up(dev); */ break; case NETDEV_DOWN: - DEBUG(3, __FUNCTION__ "(), NETDEV_DOWN\n"); + IRDA_DEBUG(3, __FUNCTION__ "(), NETDEV_DOWN\n"); /* irda_kill_by_device(dev); */ /* irda_rt_device_down(dev); */ /* irda_dev_device_down(dev); */ diff --git a/net/irda/discovery.c b/net/irda/discovery.c index 2419a62f2..957426154 100644 --- a/net/irda/discovery.c +++ b/net/irda/discovery.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Apr 6 15:33:50 1999 - * Modified at: Mon Aug 23 09:48:40 1999 + * Modified at: Sat Oct 9 17:11: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> @@ -32,7 +32,6 @@ #include <linux/string.h> #include <linux/socket.h> -#include <linux/irda.h> #include <net/irda/irda.h> #include <net/irda/irlmp.h> @@ -78,7 +77,7 @@ void irlmp_add_discovery(hashbin_t *cachelog, discovery_t *new) /* Insert the new and updated version */ - hashbin_insert(cachelog, (QUEUE *) new, new->daddr, NULL); + hashbin_insert(cachelog, (queue_t *) new, new->daddr, NULL); spin_unlock_irqrestore(&irlmp->lock, flags); } @@ -93,7 +92,7 @@ void irlmp_add_discovery_log(hashbin_t *cachelog, hashbin_t *log) { discovery_t *discovery; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* * If log is missing this means that IrLAP was unable to perform the @@ -126,7 +125,7 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force) { discovery_t *discovery, *curr; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); discovery = (discovery_t *) hashbin_get_first(log); while (discovery != NULL) { @@ -160,10 +159,10 @@ void irlmp_dump_discoveries(hashbin_t *log) discovery = (discovery_t *) hashbin_get_first(log); while (discovery != NULL) { - DEBUG(0, "Discovery:\n"); - DEBUG(0, " daddr=%08x\n", discovery->daddr); - DEBUG(0, " saddr=%08x\n", discovery->saddr); - DEBUG(0, " nickname=%s\n", discovery->nickname); + IRDA_DEBUG(0, "Discovery:\n"); + IRDA_DEBUG(0, " daddr=%08x\n", discovery->daddr); + IRDA_DEBUG(0, " saddr=%08x\n", discovery->saddr); + IRDA_DEBUG(0, " nickname=%s\n", discovery->nickname); discovery = (discovery_t *) hashbin_get_next(log); } @@ -186,9 +185,9 @@ __u32 irlmp_find_device(hashbin_t *cachelog, char *name, __u32 *saddr) /* Look at all discoveries for that link */ d = (discovery_t *) hashbin_get_first(cachelog); while (d != NULL) { - DEBUG(1, "Discovery:\n"); - DEBUG(1, " daddr=%08x\n", d->daddr); - DEBUG(1, " nickname=%s\n", d->nickname); + IRDA_DEBUG(1, "Discovery:\n"); + IRDA_DEBUG(1, " daddr=%08x\n", d->daddr); + IRDA_DEBUG(1, " nickname=%s\n", d->nickname); if (strcmp(name, d->nickname) == 0) { *saddr = d->saddr; diff --git a/net/irda/ircomm/ircomm_core.c b/net/irda/ircomm/ircomm_core.c index a1fd0223a..e7c1f5064 100644 --- a/net/irda/ircomm/ircomm_core.c +++ b/net/irda/ircomm/ircomm_core.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 20:37:34 1999 - * Modified at: Tue Aug 17 11:05:41 1999 + * Modified at: Tue Oct 5 11:37:11 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -128,7 +128,7 @@ struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line) self->service_type = service_type; self->line = line; - hashbin_insert(ircomm, (QUEUE *) self, line, NULL); + hashbin_insert(ircomm, (queue_t *) self, line, NULL); ircomm_next_state(self, IRCOMM_IDLE); diff --git a/net/irda/ircomm/ircomm_param.c b/net/irda/ircomm/ircomm_param.c index 4294dbdb2..b6012d511 100644 --- a/net/irda/ircomm/ircomm_param.c +++ b/net/irda/ircomm/ircomm_param.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Jun 7 10:25:11 1999 - * Modified at: Fri Sep 3 09:28:20 1999 + * Modified at: Mon Oct 4 09:36:53 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -236,7 +236,7 @@ static int ircomm_param_port_type(void *instance, param_t *param, int get) /* * Function ircomm_param_port_name (self, param) * - * + * Exchange port name * */ static int ircomm_param_port_name(void *instance, param_t *param, int get) @@ -259,7 +259,7 @@ static int ircomm_param_port_name(void *instance, param_t *param, int get) /* * Function ircomm_param_data_rate (self, param) * - * + * Exchange data rate to be used in this session * */ static int ircomm_param_data_rate(void *instance, param_t *param, int get) @@ -282,7 +282,7 @@ static int ircomm_param_data_rate(void *instance, param_t *param, int get) /* * Function ircomm_param_data_format (self, param) * - * + * Exchange data format to be used in this session * */ static int ircomm_param_data_format(void *instance, param_t *param, int get) @@ -303,7 +303,7 @@ static int ircomm_param_data_format(void *instance, param_t *param, int get) /* * Function ircomm_param_flow_control (self, param) * - * + * Exchange flow control settings to be used in this session * */ static int ircomm_param_flow_control(void *instance, param_t *param, int get) @@ -326,12 +326,26 @@ static int ircomm_param_flow_control(void *instance, param_t *param, int get) /* * Function ircomm_param_xon_xoff (self, param) * - * + * Exchange XON/XOFF characters * */ static int ircomm_param_xon_xoff(void *instance, param_t *param, int get) { - DEBUG(2, __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.s = self->session.xonxoff[0]; + param->pv.s |= self->session.xonxoff[1] << 8; + } else { + self->session.xonxoff[0] = param->pv.s & 0xff; + self->session.xonxoff[1] = param->pv.s >> 8; + } + + DEBUG(0, __FUNCTION__ "(), XON/XOFF = 0x%02x\n,0x%02x", + param->pv.s & 0xff, param->pv.s >> 8); return 0; } @@ -339,12 +353,26 @@ static int ircomm_param_xon_xoff(void *instance, param_t *param, int get) /* * Function ircomm_param_enq_ack (self, param) * - * + * Exchange ENQ/ACK characters * */ static int ircomm_param_enq_ack(void *instance, param_t *param, int get) { - DEBUG(2, __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.s = self->session.enqack[0]; + param->pv.s |= self->session.enqack[1] << 8; + } else { + self->session.enqack[0] = param->pv.s & 0xff; + self->session.enqack[1] = param->pv.s >> 8; + } + + DEBUG(0, __FUNCTION__ "(), ENQ/ACK = 0x%02x,0x%02x\n", + param->pv.s & 0xff, param->pv.s >> 8); return 0; } diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 8df8d876e..14da65d89 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Jun 6 21:00:56 1999 - * Modified at: Tue Sep 21 11:46:59 1999 + * Modified at: Tue Oct 19 21:32:04 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * Sources: serial.c and previous IrCOMM work by Takahide Higuchi * @@ -408,7 +408,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) tty->termios->c_oflag = 0; /* Insert into hash */ - hashbin_insert(ircomm_tty, (QUEUE *) self, line, NULL); + hashbin_insert(ircomm_tty, (queue_t *) self, line, NULL); } self->open_count++; @@ -796,7 +796,7 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) orig_jiffies = jiffies; /* Set poll time to 200 ms */ - poll_time = MIN(timeout, MSECS_TO_JIFFIES(200)); + poll_time = IRDA_MIN(timeout, MSECS_TO_JIFFIES(200)); while (self->tx_skb && self->tx_skb->len) { current->state = TASK_INTERRUPTIBLE; @@ -939,8 +939,6 @@ static void ircomm_tty_hangup(struct tty_struct *tty) */ static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch) { - struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; - DEBUG(0, __FUNCTION__"(), not impl\n"); } @@ -1082,7 +1080,7 @@ static int ircomm_tty_control_indication(void *instance, void *sap, clen = skb->data[0]; - irda_param_extract_all(self, skb->data+1, MIN(skb->len-1, clen), + irda_param_extract_all(self, skb->data+1, IRDA_MIN(skb->len-1, clen), &ircomm_param_info); dev_kfree_skb(skb); diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c index f2466d68c..52a6ec5e9 100644 --- a/net/irda/ircomm/ircomm_tty_attach.c +++ b/net/irda/ircomm/ircomm_tty_attach.c @@ -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 Sep 8 11:54:27 1999 + * Modified at: Tue Oct 19 21:32:17 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -208,7 +208,6 @@ 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); @@ -243,13 +242,24 @@ static int ircomm_tty_send_initial_parameters(struct ircomm_tty_cb *self) if (self->service_type & IRCOMM_3_WIRE_RAW) return 0; - /* Set default values */ - self->session.data_rate = 9600; - self->session.data_format = IRCOMM_WSIZE_8; /* 8N1 */ - self->session.flow_control = 0; /* None */ + /* + * Set default values, but only if the application for some reason + * haven't set them already + */ + DEBUG(2, __FUNCTION__ "(), data-rate = %d\n", self->session.data_rate); + if (!self->session.data_rate) + self->session.data_rate = 9600; + DEBUG(2, __FUNCTION__ "(), data-format = %d\n", + self->session.data_format); + if (!self->session.data_format) + self->session.data_format = IRCOMM_WSIZE_8; /* 8N1 */ + + DEBUG(2, __FUNCTION__ "(), flow-control = %d\n", + self->session.flow_control); + /*self->session.flow_control = IRCOMM_RTS_CTS_IN|IRCOMM_RTS_CTS_OUT;*/ /* Do not set delta values for the initial parameters */ - self->session.dte = (IRCOMM_DTR| IRCOMM_RTS); + self->session.dte = IRCOMM_DTR | IRCOMM_RTS; ircomm_param_request(self, IRCOMM_SERVICE_TYPE, FALSE); ircomm_param_request(self, IRCOMM_DATA_RATE, FALSE); @@ -430,7 +440,8 @@ void ircomm_tty_connect_indication(void *instance, void *sap, clen = skb->data[0]; if (clen) - irda_param_extract_all(self, skb->data+1, MIN(skb->len, clen), + irda_param_extract_all(self, skb->data+1, + IRDA_MIN(skb->len, clen), &ircomm_param_info); ircomm_tty_do_event(self, IRCOMM_TTY_CONNECT_INDICATION, NULL, NULL); diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c index 6937d62f3..b4c6e6905 100644 --- a/net/irda/irda_device.c +++ b/net/irda/irda_device.c @@ -1,26 +1,30 @@ /********************************************************************* * * Filename: irda_device.c - * Version: 0.6 - * Description: Abstract device driver layer and helper functions + * Version: 0.9 + * Description: Utility functions used by the device drivers * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> - * Created at: Wed Sep 2 20:22:08 1998 - * Modified at: Tue Sep 28 08:40:31 1999 + * Created at: Sat Oct 9 09:22:27 1999 + * Modified at: Mon Oct 18 22:40:10 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> * - * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. - * + * Copyright (c) 1999 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. - * - * Neither Dag Brattli nor University of Tromsø admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA * ********************************************************************/ @@ -46,7 +50,7 @@ #include <net/pkt_sched.h> #include <net/irda/irda_device.h> -#include <net/irda/irlap_frame.h> +#include <net/irda/irlap.h> #include <net/irda/timer.h> #include <net/irda/wrapper.h> @@ -58,33 +62,38 @@ extern int tekram_init(void); extern int actisys_init(void); extern int girbil_init(void); -static hashbin_t *irda_device = NULL; static hashbin_t *dongles = NULL; +static hashbin_t *tasks = NULL; + +const char *infrared_mode[] = { + "IRDA_IRLAP", + "IRDA_RAW", + "SHARP_ASK", + "TV_REMOTE", +}; + +static const char *task_state[] = { + "IRDA_TASK_INIT", + "IRDA_TASK_DONE", + "IRDA_TASK_WAIT", + "IRDA_TASK_WAIT1", + "IRDA_TASK_WAIT2", + "IRDA_TASK_WAIT3", + "IRDA_TASK_CHILD_INIT", + "IRDA_TASK_CHILD_WAIT", + "IRDA_TASK_CHILD_DONE", +}; + +static void irda_task_timer_expired(void *data); -/* Netdevice functions */ -static int irda_device_net_rebuild_header(struct sk_buff *skb); -static int irda_device_net_hard_header(struct sk_buff *skb, - struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len); -static int irda_device_net_set_config(struct net_device *dev, struct ifmap *map); -static int irda_device_net_change_mtu(struct net_device *dev, int new_mtu); -static int irda_device_net_ioctl(struct net_device *dev, struct ifreq *rq,int cmd); #ifdef CONFIG_PROC_FS -int irda_device_proc_read( char *buf, char **start, off_t offset, int len, - int unused); +int irda_device_proc_read(char *buf, char **start, off_t offset, int len, + int unused); #endif /* CONFIG_PROC_FS */ int __init irda_device_init( void) { - /* Allocate master array */ - irda_device = hashbin_new( HB_LOCAL); - if (irda_device == NULL) { - WARNING("IrDA: Can't allocate irda_device hashbin!\n"); - return -ENOMEM; - } - dongles = hashbin_new(HB_LOCAL); if (dongles == NULL) { printk(KERN_WARNING @@ -92,6 +101,13 @@ int __init irda_device_init( void) return -ENOMEM; } + tasks = hashbin_new(HB_LOCAL); + if (tasks == NULL) { + printk(KERN_WARNING + "IrDA: Can't allocate tasks hashbin!\n"); + return -ENOMEM; + } + /* * Call the init function of the device drivers that has not been * compiled as a module @@ -134,287 +150,215 @@ int __init irda_device_init( void) void irda_device_cleanup(void) { - DEBUG(4, __FUNCTION__ "()\n"); - - ASSERT(irda_device != NULL, return;); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); + hashbin_delete(tasks, NULL); hashbin_delete(dongles, NULL); - hashbin_delete(irda_device, (FREE_FUNC) irda_device_close); } /* - * Function irda_device_open (self) - * - * Open a new IrDA port device + * Function irda_device_set_media_busy (self, status) * + * Called when we have detected that another station is transmiting + * in contention mode. */ -int irda_device_open(struct irda_device *self, char *name, void *priv) -{ - int result; - int i=0; - - /* Allocate memory if needed */ - if (self->rx_buff.truesize > 0) { - 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); - if (self->tx_buff.head == NULL) { - kfree(self->rx_buff.head); - return -ENOMEM; - } - - memset(self->tx_buff.head, 0, self->tx_buff.truesize); - } - - self->magic = IRDA_DEVICE_MAGIC; - - self->rx_buff.in_frame = FALSE; - self->rx_buff.state = OUTSIDE_FRAME; - self->tx_buff.data = self->tx_buff.head; - self->rx_buff.data = self->rx_buff.head; +void irda_device_set_media_busy(struct net_device *dev, int status) +{ + struct irlap_cb *self; - /* Initialize timers */ - init_timer(&self->media_busy_timer); + IRDA_DEBUG(4, __FUNCTION__ "(%s)\n", status ? "TRUE" : "FALSE"); - self->lock = SPIN_LOCK_UNLOCKED; + self = (struct irlap_cb *) dev->atalk_ptr; - /* A pointer to the low level implementation */ - self->priv = priv; + ASSERT(self != NULL, return;); + ASSERT(self->magic == LAP_MAGIC, return;); - /* Initialize IrDA net device */ - do { - sprintf(self->name, "%s%d", "irda", i++); - } while (dev_get(self->name)); - - self->netdev.name = self->name; - self->netdev.priv = (void *) self; - self->netdev.next = NULL; - - result = register_netdev(&self->netdev); - if (result) { - ERROR(__FUNCTION__ "(), register_netdev() failed!\n"); - return -1; + if (status) { + self->media_busy = TRUE; + irlap_start_mbusy_timer(self); + IRDA_DEBUG( 4, "Media busy!\n"); + } else { + self->media_busy = FALSE; + del_timer(&self->media_busy_timer); } - - /* - * Make the description for the device. self->netdev.name will get - * a name like "irda0" and the self->descriptin will get a name - * like "irda0 <-> irtty0" - */ - strncpy(self->description, self->name, 5); - strcat(self->description, " <-> "); - strncat(self->description, name, 23); - - hashbin_insert(irda_device, (QUEUE *) self, (int) self, NULL); - - MESSAGE("IrDA: Registered device %s\n", self->name); - - irda_device_set_media_busy(&self->netdev, FALSE); - - return 0; } -/* - * Function irda_device_close (self) - * - * Close this instance of the irda_device, just deallocate buffers - * - */ -void __irda_device_close(struct irda_device *self) -{ - DEBUG(4, __FUNCTION__ "()\n"); +int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts) +{ + struct if_irda_req req; + int ret; - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); - /* We do this test to know if the device has been registered at all */ - if (self->netdev.type == ARPHRD_IRDA) { - /* Remove netdevice */ - unregister_netdev(&self->netdev); + if (!dev->do_ioctl) { + ERROR(__FUNCTION__ "(), do_ioctl not impl. by " + "device driver\n"); + return -1; } - /* Stop timers */ - del_timer(&self->media_busy_timer); - - if (self->tx_buff.head) - kfree(self->tx_buff.head); + req.ifr_dtr = dtr; + req.ifr_rts = rts; - if (self->rx_buff.head) - kfree(self->rx_buff.head); + ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSDTRRTS); - self->magic = 0; + return ret; } /* - * Function irda_device_close (self) + * Function irda_device_is_receiving (dev) * - * Close the device + * Check if the device driver is currently receiving data * */ -void irda_device_close(struct irda_device *self) +int irda_device_is_receiving(struct net_device *dev) { - DEBUG(4, __FUNCTION__ "()\n"); + struct if_irda_req req; + int ret; - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); - /* We are not using any dongle anymore! */ - if (self->dongle) - self->dongle->close(self); + if (!dev->do_ioctl) { + ERROR(__FUNCTION__ "(), do_ioctl not impl. by " + "device driver\n"); + return -1; + } - hashbin_remove(irda_device, (int) self, NULL); + ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCGRECEIVING); + if (ret < 0) + return ret; - __irda_device_close(self); + return req.ifr_receiving; } -/* - * Function irda_device_set_media_busy (self, status) - * - * Called when we have detected that another station is transmiting - * in contention mode. - */ -void irda_device_set_media_busy(struct net_device *dev, int status) +void irda_task_next_state(struct irda_task *task, TASK_STATE state) { - struct irda_device *self; - - DEBUG(4, __FUNCTION__ "(%s)\n", status ? "TRUE" : "FALSE"); + IRDA_DEBUG(2, __FUNCTION__ "(), state = %s\n", task_state[state]); - self = dev->priv; - - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;); - - if (status) { - self->media_busy = TRUE; - irda_device_start_mbusy_timer(self); - DEBUG( 4, "Media busy!\n"); - } else { - self->media_busy = FALSE; - del_timer(&self->media_busy_timer); - } + task->state = state; } /* - * Function __irda_device_change_speed (self, speed) + * Function irda_task_kick (task) * - * When this function is called, we will have a process context so its - * possible for us to sleep, wait or whatever :-) + * Tries to execute a task possible multiple times until the task is either + * finished, or askes for a timeout. When a task is finished, we do post + * processing, and notify the parent task, that is waiting for this task + * to complete. */ -static void __irda_device_change_speed(struct irda_device *self, int speed) +int irda_task_kick(struct irda_task *task) { - int n = 0; + int timeout; + int ret = 0; + int count = 0; - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;); - - /* - * Is is possible to change speed yet? Wait until the last byte - * has been transmitted. - */ - if (!self->wait_until_sent) { - ERROR("IrDA: wait_until_sent() " - "has not implemented by the IrDA device driver!\n"); - return; - } - - /* Make sure all transmitted data has actually been sent */ - self->wait_until_sent(self); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); - /* Make sure nobody tries to transmit during the speed change */ - while (irda_lock((void *) &self->netdev.tbusy) == FALSE) { - WARNING(__FUNCTION__ "(), device locked!\n"); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(MSECS_TO_JIFFIES(10)); + ASSERT(task != NULL, return -1;); + ASSERT(task->magic == IRDA_TASK_MAGIC, return -1;); - if (n++ > 10) { - WARNING(__FUNCTION__ "(), breaking loop!\n"); - return; - } + /* Execute task until it's finished, or askes for a timeout */ + do { + timeout = task->function(task); + if (count++ > 100) { + ERROR(__FUNCTION__ "(), error in task handler!\n"); + return -1; + } + } while ((timeout == 0) && (task->state != IRDA_TASK_DONE)); + + if (timeout < 0) { + ERROR(__FUNCTION__ "(), Error executing task!\n"); + return -1; } - - /* Change speed of dongle */ - if (self->dongle) - self->dongle->change_speed(self, speed); - - /* Change speed of IrDA port */ - if (self->change_speed) { - self->change_speed(self, speed); - - /* Update the QoS value only */ - self->qos.baud_rate.value = speed; + + /* Check if we are finished */ + if (task->state == IRDA_TASK_DONE) { + del_timer(&task->timer); + + /* Do post processing */ + if (task->finished) + task->finished(task); + + /* Notify parent */ + if (task->parent) { + /* Check if parent is waiting for us to complete */ + if (task->parent->state == IRDA_TASK_CHILD_WAIT) { + task->parent->state = IRDA_TASK_CHILD_DONE; + + /* Stop timer now that we are here */ + del_timer(&task->parent->timer); + + /* Kick parent task */ + irda_task_kick(task->parent); + } + } + /* Unregister task */ + hashbin_remove(tasks, (int) task, NULL); + + kfree(task); + } else if (timeout > 0) { + irda_start_timer(&task->timer, timeout, (void *) task, + irda_task_timer_expired); + ret = 1; + } else { + IRDA_DEBUG(0, __FUNCTION__ "(), not finished, and no timeout!\n"); + ret = 1; } - self->netdev.tbusy = FALSE; + + return ret; } /* - * Function irda_device_change_speed (self, speed) - * - * Change the speed of the currently used irda_device + * Function irda_task_execute (instance, function, finished) * + * This function registers and tries to execute tasks that may take some + * time to complete. We do it this hairy way since we may have been + * called from interrupt context, so it's not possible to use + * schedule_timeout() */ -void irda_device_change_speed(struct irda_device *self, int speed) +int irda_task_execute(void *instance, TASK_CALLBACK function, + TASK_CALLBACK finished, struct irda_task *parent, + void *param) { - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;); + struct irda_task *task; - irda_execute_as_process(self, - (TODO_CALLBACK) __irda_device_change_speed, - speed); -} + IRDA_DEBUG(2, __FUNCTION__ "()\n"); -int irda_device_is_media_busy(struct net_device *dev) -{ - struct irda_device *self; - - self = dev->priv; + task = kmalloc(sizeof(struct irda_task), GFP_ATOMIC); + if (!task) + return -ENOMEM; - ASSERT(self != NULL, return FALSE;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return FALSE;); - - return self->media_busy; -} + task->state = IRDA_TASK_INIT; + task->instance = instance; + task->function = function; + task->finished = finished; + task->parent = parent; + task->param = param; + task->magic = IRDA_TASK_MAGIC; -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;); + init_timer(&task->timer); - if (self->is_receiving) - return self->is_receiving(self); - else - return FALSE; + /* Register task */ + hashbin_insert(tasks, (queue_t *) task, (int) task, NULL); + + /* No time to waste, so lets get going! */ + return irda_task_kick(task); } -struct qos_info *irda_device_get_qos(struct net_device *dev) +/* + * Function irda_task_timer_expired (data) + * + * Task time has expired. We now try to execute task (again), and restart + * the timer if the task has not finished yet + */ +static void irda_task_timer_expired(void *data) { - 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;); + struct irda_task *task; - return &self->qos; -} + IRDA_DEBUG(2, __FUNCTION__ "()\n"); -static struct enet_statistics *irda_device_get_stats(struct net_device *dev) -{ - struct irda_device *priv = (struct irda_device *) dev->priv; + task = (struct irda_task *) data; - return &priv->stats; + irda_task_kick(task); } /* @@ -425,24 +369,14 @@ static struct enet_statistics *irda_device_get_stats(struct net_device *dev) */ int irda_device_setup(struct net_device *dev) { - struct irda_device *self; - ASSERT(dev != NULL, return -1;); - self = (struct irda_device *) dev->priv; - - ASSERT(self != NULL, return -1;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;); - - dev->get_stats = irda_device_get_stats; - dev->rebuild_header = irda_device_net_rebuild_header; - dev->set_config = irda_device_net_set_config; - dev->change_mtu = irda_device_net_change_mtu; -/* dev->hard_header = irda_device_net_hard_header; */ - dev->do_ioctl = irda_device_net_ioctl; dev->hard_header_len = 0; dev->addr_len = 0; + dev->new_style = 1; + /* dev->destructor = irda_device_destructor; */ + dev->type = ARPHRD_IRDA; dev->tx_queue_len = 8; /* Window size + 1 s-frame */ @@ -458,314 +392,72 @@ int irda_device_setup(struct net_device *dev) return 0; } -int irda_device_net_open(struct net_device *dev) -{ - struct irda_device *self; - - ASSERT(dev != NULL, return -1;); - - self = dev->priv; - - ASSERT(self != NULL, return 0;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;); - - /* Ready to play! */ - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - - /* - * Open new IrLAP layer instance, now that everything should be - * initialized properly - */ - self->irlap = irlap_open(dev); - - /* It's now safe to initilize the saddr */ - memcpy(self->netdev.dev_addr, &self->irlap->saddr, 4); - - return 0; -} - -int irda_device_net_close(struct net_device *dev) -{ - struct irda_device *self; - - ASSERT(dev != NULL, return -1;); - - self = dev->priv; - - ASSERT(self != NULL, return 0;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;); - - /* Stop device */ - dev->tbusy = 1; - dev->start = 0; - - /* Stop and remove instance of IrLAP */ - if (self->irlap) - irlap_close(self->irlap); - self->irlap = NULL; - - return 0; -} - -/* - * Function irda_device_net_rebuild_header (buff, dev, dst, skb) - * - * - * - */ -static int irda_device_net_rebuild_header( struct sk_buff *skb) -{ - DEBUG( 4, __FUNCTION__ "()\n"); - - return 0; -} - -static int irda_device_net_hard_header(struct sk_buff *skb, - struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len) -{ - DEBUG( 0, __FUNCTION__ "()\n"); - - skb->mac.raw = skb->data; - /* skb_push(skb,PPP_HARD_HDR_LEN); */ - /* return PPP_HARD_HDR_LEN; */ - - return 0; -} - -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) -{ - DEBUG( 0, __FUNCTION__ "()\n"); - - return 0; -} - -static int irda_device_net_ioctl(struct net_device *dev, /* ioctl device */ - struct ifreq *rq, /* Data passed */ - int cmd) /* Ioctl number */ -{ - unsigned long flags; - int ret = 0; -#ifdef WIRELESS_EXT - struct iwreq *wrq = (struct iwreq *) rq; -#endif - struct irda_device *self; - - ASSERT(dev != NULL, return -1;); - - self = dev->priv; - - ASSERT(self != NULL, return -1;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;); - - DEBUG(0, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd); - - /* Disable interrupts & save flags */ - save_flags(flags); - cli(); - - /* Look what is the request */ - switch (cmd) { -#ifdef WIRELESS_EXT - case SIOCGIWNAME: - /* Get name */ - strcpy(wrq->u.name, self->name); - break; - case SIOCSIWNWID: - /* Set domain */ - if (wrq->u.nwid.on) { - - } break; - case SIOCGIWNWID: - /* Read domain*/ -/* wrq->u.nwid.nwid = domain; */ -/* wrq->u.nwid.on = 1; */ - break; - case SIOCGIWENCODE: - /* Get scramble key */ - /* wrq->u.encoding.code = scramble_key; */ -/* wrq->u.encoding.method = 1; */ - break; - case SIOCSIWENCODE: - /* Set scramble key */ - /* scramble_key = wrq->u.encoding.code; */ - break; - case SIOCGIWRANGE: - /* Basic checking... */ - if(wrq->u.data.pointer != (caddr_t) 0) { - struct iw_range range; - - /* Verify the user buffer */ - ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer, - sizeof(struct iw_range)); - if(ret) - break; - - /* Set the length (useless : its constant...) */ - wrq->u.data.length = sizeof(struct iw_range); - - /* Set information in the range struct */ - range.throughput = 1.6 * 1024 * 1024; /* don't argue on this ! */ - range.min_nwid = 0x0000; - range.max_nwid = 0x01FF; - - range.num_channels = range.num_frequency = 0; - - range.sensitivity = 0x3F; - range.max_qual.qual = 255; - range.max_qual.level = 255; - range.max_qual.noise = 0; - - /* Copy structure to the user buffer */ - copy_to_user(wrq->u.data.pointer, &range, - sizeof(struct iw_range)); - } - break; - case SIOCGIWPRIV: - /* Basic checking... */ -#if 0 - if (wrq->u.data.pointer != (caddr_t) 0) { - struct iw_priv_args priv[] = - { /* cmd, set_args, get_args, name */ - { SIOCGIPSNAP, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 0, - sizeof(struct site_survey), - "getsitesurvey" }, - }; - - /* Verify the user buffer */ - ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer, - sizeof(priv)); - if (ret) - break; - - /* Set the number of ioctl available */ - wrq->u.data.length = 1; - - /* Copy structure to the user buffer */ - copy_to_user(wrq->u.data.pointer, (u_char *) priv, - sizeof(priv)); - } -#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; - } - - restore_flags(flags); - - return ret; -} - /* - * Function irda_device_txqueue_empty (irda_device) + * Function irda_device_txqueue_empty (dev) * * Check if there is still some frames in the transmit queue for this * device. Maybe we should use: q->q.qlen == 0. * */ -int irda_device_txqueue_empty(struct irda_device *self) +int irda_device_txqueue_empty(struct net_device *dev) { - ASSERT(self != NULL, return -1;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;); - - if (skb_queue_len(&self->netdev.qdisc->q)) + if (skb_queue_len(&dev->qdisc->q)) return FALSE; return TRUE; } /* - * Function irda_device_init_dongle (self, type) + * Function irda_device_init_dongle (self, type, qos) * - * Initialize attached dongle. Warning, must be called with a process - * context! + * Initialize attached dongle. */ -void irda_device_init_dongle(struct irda_device *self, int type) +dongle_t *irda_device_dongle_init(struct net_device *dev, int type) { - struct dongle_q *node; + struct dongle_reg *reg; + char modname[32]; + dongle_t *dongle; - ASSERT(self != NULL, return;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;); + ASSERT(dev != NULL, return NULL;); #ifdef CONFIG_KMOD /* Try to load the module needed */ - switch (type) { - case ESI_DONGLE: - MESSAGE("IrDA: Initializing ESI dongle!\n"); - request_module("esi"); - break; - case TEKRAM_DONGLE: - MESSAGE("IrDA: Initializing Tekram dongle!\n"); - request_module("tekram"); - break; - case ACTISYS_DONGLE: /* FALLTHROUGH */ - case ACTISYS_PLUS_DONGLE: - MESSAGE("IrDA: Initializing ACTiSYS dongle!\n"); - request_module("actisys"); - break; - case GIRBIL_DONGLE: - MESSAGE("IrDA: Initializing GIrBIL dongle!\n"); - request_module("girbil"); - break; - case LITELINK_DONGLE: - MESSAGE("IrDA: Initializing Litelink dongle!\n"); - request_module("litelink"); - break; - case AIRPORT_DONGLE: - MESSAGE("IrDA: Initializing Airport dongle!\n"); - request_module("airport"); - break; - default: - ERROR("Unknown dongle type!\n"); - return; - } + sprintf(modname, "irda-dongle-%d", type); + request_module(modname); #endif /* CONFIG_KMOD */ - node = hashbin_find(dongles, type, NULL); - if (!node) { + if (!(reg = hashbin_find(dongles, type, NULL))) { ERROR("IrDA: Unable to find requested dongle\n"); - return; - } - - /* Check if we're already using a dongle */ - if (self->dongle) { - self->dongle->close(self); + return NULL; } - /* Set the dongle to be used by this driver */ - self->dongle = node->dongle; + /* Allocate dongle info for this instance */ + dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL); + if (!dongle) + return NULL; - /* Now initialize the dongle! */ - node->dongle->open(self, type); - node->dongle->qos_init(self, &self->qos); - - /* Reset dongle */ - node->dongle->reset(self); + /* Bind the registration info to this particular instance */ + dongle->issue = reg; + dongle->dev = dev; - /* Set to default baudrate */ - irda_device_change_speed(self, 9600); + return dongle; +} + +/* + * Function irda_device_dongle_cleanup (dongle) + * + * + * + */ +int irda_device_dongle_cleanup(dongle_t *dongle) +{ + ASSERT(dongle != NULL, return -1;); + + dongle->issue->close(dongle); + + kfree(dongle); + + return 0; } /* @@ -774,26 +466,16 @@ void irda_device_init_dongle(struct irda_device *self, int type) * * */ -int irda_device_register_dongle(struct dongle *dongle) +int irda_device_register_dongle(struct dongle_reg *new) { - struct dongle_q *new; - /* Check if this dongle has been registred before */ - if (hashbin_find(dongles, dongle->type, NULL)) { + if (hashbin_find(dongles, new->type, NULL)) { MESSAGE(__FUNCTION__ "(), Dongle already registered\n"); return 0; } - /* Make new IrDA dongle */ - new = (struct dongle_q *) kmalloc(sizeof(struct dongle_q), GFP_KERNEL); - if (new == NULL) - return -1; - - memset(new, 0, sizeof( struct dongle_q)); - new->dongle = dongle; - /* Insert IrDA dongle into hashbin */ - hashbin_insert(dongles, (QUEUE *) new, dongle->type, NULL); + hashbin_insert(dongles, (queue_t *) new, new->type, NULL); return 0; } @@ -801,44 +483,44 @@ int irda_device_register_dongle(struct dongle *dongle) /* * Function irda_device_unregister_dongle (dongle) * - * + * Unregister dongle, and remove dongle from list of registred dongles * */ -void irda_device_unregister_dongle(struct dongle *dongle) +void irda_device_unregister_dongle(struct dongle_reg *dongle) { - struct dongle_q *node; + struct dongle *node; node = hashbin_remove(dongles, dongle->type, NULL); if (!node) { ERROR(__FUNCTION__ "(), dongle not found!\n"); return; } - kfree(node); } /* - * Function irda_device_set_raw_mode (self, status) + * Function irda_device_set_raw_mode (self, mode) * * * */ -int irda_device_set_raw_mode(struct irda_device* self, int status) +int irda_device_set_raw_mode(struct net_device* dev, int mode) { - DEBUG(2, __FUNCTION__ "()\n"); + struct if_irda_req req; + int ret; - ASSERT(self != NULL, return -1;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return -1;); - - if (self->set_raw_mode == NULL) { + IRDA_DEBUG(0, __FUNCTION__ "()\n"); + + if (!dev->do_ioctl) { ERROR(__FUNCTION__ "(), set_raw_mode not impl. by " "device driver\n"); return -1; } - self->raw_mode = status; - self->set_raw_mode(self, status); + req.ifr_raw_mode = mode; + + ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSRAWMODE); - return 0; + return ret; } /* @@ -862,88 +544,3 @@ void setup_dma(int channel, char *buffer, int count, int mode) release_dma_lock(flags); } - -#ifdef CONFIG_PROC_FS - -int irda_device_print_flags(struct irda_device *idev, char *buf) -{ - int len=0; - - len += sprintf( buf+len, "\t"); - - if (idev->netdev.flags & IFF_UP) - len += sprintf( buf+len, "UP "); - if (!idev->netdev.tbusy) - len += sprintf( buf+len, "RUNNING "); - - if (idev->flags & IFF_SIR) - len += sprintf( buf+len, "SIR "); - if (idev->flags & IFF_MIR) - len += sprintf( buf+len, "MIR "); - if (idev->flags & IFF_FIR) - len += sprintf( buf+len, "FIR "); - if (idev->flags & IFF_PIO) - len += sprintf( buf+len, "PIO "); - if (idev->flags & IFF_DMA) - len += sprintf( buf+len, "DMA "); - if (idev->flags & IFF_SHM) - len += sprintf( buf+len, "SHM "); - if (idev->flags & IFF_DONGLE) - len += sprintf( buf+len, "DONGLE "); - - len += sprintf( buf+len, "\n"); - - return len; -} - -/* - * Function irda_device_proc_read (buf, start, offset, len, unused) - * - * Give some info to the /proc file system - * - */ -int irda_device_proc_read(char *buf, char **start, off_t offset, int len, - int unused) -{ - struct irda_device *self; - unsigned long flags; - - save_flags(flags); - cli(); - - len = 0; - - self = (struct irda_device *) hashbin_get_first(irda_device); - while ( self != NULL) { - len += sprintf(buf+len, "\n%s,", self->name); - len += sprintf(buf+len, "\tbinding: %s\n", - self->description); - - len += irda_device_print_flags(self, buf+len); - len += sprintf(buf+len, "\tbps\tmaxtt\tdsize\twinsize\taddbofs\tmintt\tldisc\n"); - - len += sprintf(buf+len, "\t%d\t", - self->qos.baud_rate.value); - len += sprintf(buf+len, "%d\t", - self->qos.max_turn_time.value); - len += sprintf(buf+len, "%d\t", - self->qos.data_size.value); - len += sprintf(buf+len, "%d\t", - self->qos.window_size.value); - len += sprintf(buf+len, "%d\t", - self->qos.additional_bofs.value); - len += sprintf(buf+len, "%d\t", - self->qos.min_turn_time.value); - len += sprintf(buf+len, "%d", - self->qos.link_disc_time.value); - len += sprintf(buf+len, "\n"); - - self = (struct irda_device *) hashbin_get_next(irda_device); - } - restore_flags(flags); - - return len; -} - -#endif /* CONFIG_PROC_FS */ - diff --git a/net/irda/iriap.c b/net/irda/iriap.c index 508e1d9d6..10fdd4627 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Thu Aug 21 00:02:07 1997 - * Modified at: Fri Aug 20 10:26:39 1999 + * Modified at: Sat Oct 9 17:00:56 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -28,7 +28,6 @@ #include <linux/skbuff.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/irda.h> #include <asm/byteorder.h> #include <asm/unaligned.h> @@ -146,7 +145,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode) struct lsap_cb *lsap; notify_t notify; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); self = kmalloc(sizeof(struct iriap_cb), GFP_ATOMIC); if (!self) { @@ -184,7 +183,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode) init_timer(&self->watchdog_timer); - hashbin_insert(iriap, (QUEUE*) self, slsap_sel, NULL); + hashbin_insert(iriap, (queue_t *) self, slsap_sel, NULL); /* Initialize state machines */ iriap_next_client_state(self, S_DISCONNECT); @@ -203,7 +202,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode) */ static void __iriap_close(struct iriap_cb *self) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IAS_MAGIC, return;); @@ -251,7 +250,7 @@ static void iriap_disconnect_indication(void *instance, void *sap, { struct iriap_cb *self; - DEBUG(4, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]); + IRDA_DEBUG(4, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]); self = (struct iriap_cb *) instance; @@ -263,7 +262,7 @@ static void iriap_disconnect_indication(void *instance, void *sap, del_timer(&self->watchdog_timer); if (self->mode == IAS_CLIENT) { - DEBUG(4, __FUNCTION__ "(), disconnect as client\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), disconnect as client\n"); /* * Inform service user that the request failed by sending @@ -279,7 +278,7 @@ static void iriap_disconnect_indication(void *instance, void *sap, iriap_close(self); } else { - DEBUG(4, __FUNCTION__ "(), disconnect as server\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), disconnect as server\n"); iriap_do_server_event(self, IAP_LM_DISCONNECT_INDICATION, NULL); } @@ -298,14 +297,14 @@ void iriap_disconnect_request(struct iriap_cb *self) { struct sk_buff *skb; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IAS_MAGIC, return;); skb = dev_alloc_skb(64); if (skb == NULL) { - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ "(), Could not allocate an sk_buff of length %d\n", 64); return; } @@ -320,27 +319,27 @@ void iriap_disconnect_request(struct iriap_cb *self) void iriap_getinfobasedetails_request(void) { - DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); } void iriap_getinfobasedetails_confirm(void) { - DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); } void iriap_getobjects_request(void) { - DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); } void iriap_getobjects_confirm(void) { - DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); } void iriap_getvalue(void) { - DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented!\n"); } /* @@ -434,13 +433,13 @@ void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb) /* Get length, MSB first */ len = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2; - DEBUG(4, __FUNCTION__ "(), len=%d\n", len); + IRDA_DEBUG(4, __FUNCTION__ "(), len=%d\n", len); /* Get object ID, MSB first */ obj_id = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2; type = fp[n++]; - DEBUG(4, __FUNCTION__ "(), Value type = %d\n", type); + IRDA_DEBUG(4, __FUNCTION__ "(), Value type = %d\n", type); switch (type) { case IAS_INTEGER: @@ -449,7 +448,7 @@ void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb) value = irias_new_integer_value(tmp_cpu32); /* Legal values restricted to 0x01-0x6f, page 15 irttp */ - DEBUG(4, __FUNCTION__ "(), lsap=%d\n", value->t.integer); + IRDA_DEBUG(4, __FUNCTION__ "(), lsap=%d\n", value->t.integer); break; case IAS_STRING: charset = fp[n++]; @@ -468,19 +467,19 @@ void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb) /* case CS_ISO_8859_9: */ /* case CS_UNICODE: */ default: - DEBUG(0, __FUNCTION__"(), charset %s, not supported\n", + IRDA_DEBUG(0, __FUNCTION__"(), charset %s, not supported\n", ias_charset_types[charset]); return; /* break; */ } value_len = fp[n++]; - DEBUG(4, __FUNCTION__ "(), strlen=%d\n", value_len); + IRDA_DEBUG(4, __FUNCTION__ "(), strlen=%d\n", value_len); ASSERT(value_len < 64, return;); /* Make sure the string is null-terminated */ fp[n+value_len] = 0x00; - DEBUG(4, "Got string %s\n", fp+n); + IRDA_DEBUG(4, "Got string %s\n", fp+n); value = irias_new_string_value(fp+n); break; case IAS_OCT_SEQ: @@ -517,7 +516,7 @@ void iriap_getvaluebyclass_response(struct iriap_cb *self, __u16 obj_id, __u32 tmp_be32, tmp_be16; __u8 *fp; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IAS_MAGIC, return;); @@ -578,12 +577,12 @@ void iriap_getvaluebyclass_response(struct iriap_cb *self, __u16 obj_id, memcpy(fp+n, value->t.oct_seq, value->len); n+=value->len; break; case IAS_MISSING: - DEBUG( 3, __FUNCTION__ ": sending IAS_MISSING\n"); + IRDA_DEBUG( 3, __FUNCTION__ ": sending IAS_MISSING\n"); skb_put( skb, 1); fp[n++] = value->type; break; default: - DEBUG(0, __FUNCTION__ "(), type not implemented!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), type not implemented!\n"); break; } iriap_do_r_connect_event(self, IAP_CALL_RESPONSE, skb); @@ -607,7 +606,7 @@ void iriap_getvaluebyclass_indication(struct iriap_cb *self, __u8 *fp; int n; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IAS_MAGIC, return;); @@ -629,26 +628,26 @@ void iriap_getvaluebyclass_indication(struct iriap_cb *self, /* * Now, do some advanced parsing! :-) */ - DEBUG(4, "LM-IAS: Looking up %s: %s\n", name, attr); + IRDA_DEBUG(4, "LM-IAS: Looking up %s: %s\n", name, attr); obj = irias_find_object(name); if (obj == NULL) { - DEBUG(0, "LM-IAS: Object not found\n"); + IRDA_DEBUG(0, "LM-IAS: Object not found\n"); iriap_getvaluebyclass_response(self, 0x1235, IAS_CLASS_UNKNOWN, &missing); return; } - DEBUG(4, "LM-IAS: found %s, id=%d\n", obj->name, obj->id); + IRDA_DEBUG(4, "LM-IAS: found %s, id=%d\n", obj->name, obj->id); attrib = irias_find_attrib(obj, attr); if (attrib == NULL) { - DEBUG(0, "LM-IAS: Attribute %s not found\n", attr); + IRDA_DEBUG(0, "LM-IAS: Attribute %s not found\n", attr); iriap_getvaluebyclass_response(self, obj->id, IAS_ATTRIB_UNKNOWN, &missing); return; } - DEBUG(4, "LM-IAS: found %s\n", attrib->name); + IRDA_DEBUG(4, "LM-IAS: found %s\n", attrib->name); /* * We have a match; send the value. @@ -670,7 +669,7 @@ void iriap_send_ack(struct iriap_cb *self) struct sk_buff *skb; __u8 *frame; - DEBUG(6, __FUNCTION__ "()\n"); + IRDA_DEBUG(6, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IAS_MAGIC, return;); @@ -707,7 +706,7 @@ static void iriap_connect_confirm(void *instance, void *sap, ASSERT(self->magic == IAS_MAGIC, return;); ASSERT(userdata != NULL, return;); - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); del_timer(&self->watchdog_timer); @@ -748,7 +747,7 @@ static int iriap_data_indication(void *instance, void *sap, __u8 *frame; __u8 opcode; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); self = (struct iriap_cb *) instance; @@ -761,7 +760,7 @@ static int iriap_data_indication(void *instance, void *sap, if (self->mode == IAS_SERVER) { /* Call server */ - DEBUG(4, __FUNCTION__ "(), Calling server!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), Calling server!\n"); iriap_do_r_connect_event( self, IAP_RECV_F_LST, skb); return 0; @@ -775,7 +774,7 @@ static int iriap_data_indication(void *instance, void *sap, /* Check for ack frames since they don't contain any data */ if (opcode & IAP_ACK) { - DEBUG(0, __FUNCTION__ "() Got ack frame!\n"); + IRDA_DEBUG(0, __FUNCTION__ "() Got ack frame!\n"); return 0; } @@ -783,7 +782,7 @@ static int iriap_data_indication(void *instance, void *sap, switch (opcode) { case GET_INFO_BASE: - DEBUG(0, "IrLMP GetInfoBaseDetails not implemented!\n"); + IRDA_DEBUG(0, "IrLMP GetInfoBaseDetails not implemented!\n"); break; case GET_VALUE_BY_CLASS: switch (frame[1]) { @@ -818,7 +817,7 @@ static int iriap_data_indication(void *instance, void *sap, iriap_close(self); break; default: - DEBUG(0, __FUNCTION__ "(), Unknown op-code: %02x\n", opcode); + IRDA_DEBUG(0, __FUNCTION__ "(), Unknown op-code: %02x\n", opcode); break; } return 0; @@ -835,7 +834,7 @@ void iriap_call_indication(struct iriap_cb *self, struct sk_buff *skb) __u8 *fp; __u8 opcode; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == IAS_MAGIC, return;); @@ -938,7 +937,7 @@ int irias_proc_read(char *buf, char **start, off_t offset, int len, int unused) len += sprintf(buf+len, "missing\n"); break; default: - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ "(), Unknown value type!\n"); return -1; } diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c index 18a70fec3..6fc2ead68 100644 --- a/net/irda/iriap_event.c +++ b/net/irda/iriap_event.c @@ -95,9 +95,9 @@ void iriap_next_client_state( struct iriap_cb *self, IRIAP_STATE state) ASSERT( self->magic == IAS_MAGIC, return;); switch ( state) { - /* case S_DISCONNECT: DEBUG( 0, "IAP Client = S_DISCONNECT\n"); break; */ -/* case S_CONNECTING: DEBUG( 0, "IAP Client = S_CONNECTING\n"); break; */ -/* case S_CALL: DEBUG( 0, "IAP Client = S_CALL\n"); break; */ + /* case S_DISCONNECT: IRDA_DEBUG( 0, "IAP Client = S_DISCONNECT\n"); break; */ +/* case S_CONNECTING: IRDA_DEBUG( 0, "IAP Client = S_CONNECTING\n"); break; */ +/* case S_CALL: IRDA_DEBUG( 0, "IAP Client = S_CALL\n"); break; */ default: break; } @@ -110,12 +110,12 @@ void iriap_next_call_state( struct iriap_cb *self, IRIAP_STATE state) ASSERT( self->magic == IAS_MAGIC, return;); /* switch ( state) { */ -/* case S_MAKE_CALL: DEBUG( 0, "IAP Call = S_MAKE_CALL\n"); break; */ -/* case S_CALLING: DEBUG( 0, "IAP Call = S_CALLING\n"); break; */ -/* case S_OUTSTANDING: DEBUG( 0, "IAP Call = S_OUTSTANDING\n");break; */ -/* case S_REPLYING: DEBUG( 0, "IAP Call = S_REPLYING\n"); break; */ -/* case S_WAIT_FOR_CALL: DEBUG( 0, "IAP Call = S_WAIT_FOR_CALL\n"); break; */ -/* case S_WAIT_ACTIVE: DEBUG( 0, "IAP Call = S_WAIT_ACTIVE\n"); break; */ +/* case S_MAKE_CALL: IRDA_DEBUG( 0, "IAP Call = S_MAKE_CALL\n"); break; */ +/* case S_CALLING: IRDA_DEBUG( 0, "IAP Call = S_CALLING\n"); break; */ +/* case S_OUTSTANDING: IRDA_DEBUG( 0, "IAP Call = S_OUTSTANDING\n");break; */ +/* case S_REPLYING: IRDA_DEBUG( 0, "IAP Call = S_REPLYING\n"); break; */ +/* case S_WAIT_FOR_CALL: IRDA_DEBUG( 0, "IAP Call = S_WAIT_FOR_CALL\n"); break; */ +/* case S_WAIT_ACTIVE: IRDA_DEBUG( 0, "IAP Call = S_WAIT_ACTIVE\n"); break; */ /* default: */ /* break; */ /* } */ @@ -200,7 +200,7 @@ static void state_s_disconnect( struct iriap_cb *self, IRIAP_EVENT event, case IAP_LM_DISCONNECT_INDICATION: break; default: - DEBUG( 0, __FUNCTION__"(), Unknown event %d\n", event); + IRDA_DEBUG( 0, __FUNCTION__"(), Unknown event %d\n", event); break; } } @@ -232,7 +232,7 @@ static void state_s_connecting( struct iriap_cb *self, IRIAP_EVENT event, iriap_next_client_state( self, S_DISCONNECT); break; default: - DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event); break; } } @@ -256,7 +256,7 @@ static void state_s_call( struct iriap_cb *self, IRIAP_EVENT event, iriap_next_client_state( self, S_DISCONNECT); break; default: - DEBUG( 0, "state_s_call: Unknown event %d\n", event); + IRDA_DEBUG( 0, "state_s_call: Unknown event %d\n", event); break; } } @@ -278,7 +278,7 @@ static void state_s_make_call( struct iriap_cb *self, IRIAP_EVENT event, iriap_next_call_state( self, S_OUTSTANDING); break; default: - DEBUG( 0, "state_s_make_call: Unknown event %d\n", event); + IRDA_DEBUG( 0, "state_s_make_call: Unknown event %d\n", event); break; } if ( skb) { @@ -295,7 +295,7 @@ static void state_s_make_call( struct iriap_cb *self, IRIAP_EVENT event, static void state_s_calling( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); } /* @@ -318,7 +318,7 @@ static void state_s_outstanding( struct iriap_cb *self, IRIAP_EVENT event, iriap_next_call_state( self, S_WAIT_FOR_CALL); break; default: - DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event); break; } } @@ -331,7 +331,7 @@ static void state_s_outstanding( struct iriap_cb *self, IRIAP_EVENT event, static void state_s_replying( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); } /* @@ -343,7 +343,7 @@ static void state_s_replying( struct iriap_cb *self, IRIAP_EVENT event, static void state_s_wait_for_call( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); } @@ -356,7 +356,7 @@ static void state_s_wait_for_call( struct iriap_cb *self, IRIAP_EVENT event, static void state_s_wait_active( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); } /************************************************************************** @@ -380,7 +380,7 @@ static void state_r_disconnect( struct iriap_cb *self, IRIAP_EVENT event, case IAP_LM_CONNECT_INDICATION: tx_skb = dev_alloc_skb( 64); if ( tx_skb == NULL) { - DEBUG( 0,"state_r_disconnect: " + IRDA_DEBUG( 0,"state_r_disconnect: " "Could not allocate an sk_buff of length %d\n", 64); return; @@ -405,7 +405,7 @@ static void state_r_disconnect( struct iriap_cb *self, IRIAP_EVENT event, break; default: - DEBUG( 0, "state_r_disconnect: Unknown event %d\n", event); + IRDA_DEBUG( 0, "state_r_disconnect: Unknown event %d\n", event); break; } } @@ -419,7 +419,7 @@ static void state_r_disconnect( struct iriap_cb *self, IRIAP_EVENT event, static void state_r_call( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 4, "state_r_call()\n"); + IRDA_DEBUG( 4, "state_r_call()\n"); switch( event) { case IAP_LM_DISCONNECT_INDICATION: @@ -429,7 +429,7 @@ static void state_r_call( struct iriap_cb *self, IRIAP_EVENT event, break; default: - DEBUG( 0, "state_r_call, unknown event!\n"); + IRDA_DEBUG( 0, "state_r_call, unknown event!\n"); break; } } @@ -447,13 +447,13 @@ static void state_r_call( struct iriap_cb *self, IRIAP_EVENT event, static void state_r_waiting( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); } static void state_r_wait_active( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n"); } /* @@ -465,7 +465,7 @@ static void state_r_wait_active( struct iriap_cb *self, static void state_r_receiving( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); switch( event) { case IAP_RECV_F_LST: @@ -474,7 +474,7 @@ static void state_r_receiving( struct iriap_cb *self, IRIAP_EVENT event, iriap_call_indication( self, skb); break; default: - DEBUG( 0, __FUNCTION__ "(), unknown event!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), unknown event!\n"); break; } @@ -489,12 +489,12 @@ static void state_r_receiving( struct iriap_cb *self, IRIAP_EVENT event, static void state_r_execute( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); ASSERT( skb != NULL, return;); if ( !self || self->magic != IAS_MAGIC) { - DEBUG( 0, "state_r_execute: bad pointer self\n"); + IRDA_DEBUG( 0, "state_r_execute: bad pointer self\n"); return; } @@ -509,7 +509,7 @@ static void state_r_execute( struct iriap_cb *self, IRIAP_EVENT event, irlmp_data_request( self->lsap, skb); break; default: - DEBUG( 0, __FUNCTION__ "(), unknown event!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), unknown event!\n"); break; } } @@ -517,7 +517,7 @@ static void state_r_execute( struct iriap_cb *self, IRIAP_EVENT event, static void state_r_returning( struct iriap_cb *self, IRIAP_EVENT event, struct sk_buff *skb) { - DEBUG( 0, __FUNCTION__ "(), event=%d\n", event); + IRDA_DEBUG( 0, __FUNCTION__ "(), event=%d\n", event); switch( event) { case IAP_RECV_F_LST: diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c index 8621c43b6..c83bb855b 100644 --- a/net/irda/irias_object.c +++ b/net/irda/irias_object.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Thu Oct 1 22:50:04 1998 - * Modified at: Mon Jun 21 16:11:13 1999 + * Modified at: Sat Oct 9 17:11:16 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -24,7 +24,6 @@ #include <linux/string.h> #include <linux/socket.h> -#include <linux/irda.h> #include <net/irda/irda.h> #include <net/irda/irmod.h> @@ -71,12 +70,12 @@ struct ias_object *irias_new_object( char *name, int id) { struct ias_object *obj; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); obj = (struct ias_object *) kmalloc( sizeof( struct ias_object), GFP_ATOMIC); if (obj == NULL) { - DEBUG(0, __FUNCTION__ "(), Unable to allocate object!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Unable to allocate object!\n"); return NULL; } memset(obj, 0, sizeof( struct ias_object)); @@ -156,12 +155,10 @@ int irias_delete_object(struct ias_object *obj) */ void irias_insert_object(struct ias_object *obj) { - DEBUG(4, __FUNCTION__ "()\n"); - ASSERT(obj != NULL, return;); ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); - hashbin_insert(objects, (QUEUE *) obj, 0, obj->name); + hashbin_insert(objects, (queue_t *) obj, 0, obj->name); } /* @@ -183,18 +180,16 @@ struct ias_object *irias_find_object(char *name) * Find named attribute in object * */ -struct ias_attrib *irias_find_attrib( struct ias_object *obj, char *name) +struct ias_attrib *irias_find_attrib(struct ias_object *obj, char *name) { struct ias_attrib *attrib; - DEBUG( 4, __FUNCTION__ "()\n"); - - ASSERT( obj != NULL, return NULL;); - ASSERT( obj->magic == IAS_OBJECT_MAGIC, return NULL;); - ASSERT( name != NULL, return NULL;); + ASSERT(obj != NULL, return NULL;); + ASSERT(obj->magic == IAS_OBJECT_MAGIC, return NULL;); + ASSERT(name != NULL, return NULL;); - attrib = hashbin_find( obj->attribs, 0, name); - if ( attrib == NULL) + attrib = hashbin_find(obj->attribs, 0, name); + if (attrib == NULL) return NULL; return attrib; @@ -208,15 +203,13 @@ struct ias_attrib *irias_find_attrib( struct ias_object *obj, char *name) */ void irias_add_attrib( struct ias_object *obj, struct ias_attrib *attrib) { - DEBUG( 4, __FUNCTION__ "()\n"); - - ASSERT( obj != NULL, return;); - ASSERT( obj->magic == IAS_OBJECT_MAGIC, return;); + ASSERT(obj != NULL, return;); + ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); - ASSERT( attrib != NULL, return;); - ASSERT( attrib->magic == IAS_ATTRIB_MAGIC, return;); + ASSERT(attrib != NULL, return;); + ASSERT(attrib->magic == IAS_ATTRIB_MAGIC, return;); - hashbin_insert( obj->attribs, (QUEUE *) attrib, 0, attrib->name); + hashbin_insert(obj->attribs, (queue_t *) attrib, 0, attrib->name); } /* @@ -225,36 +218,36 @@ void irias_add_attrib( struct ias_object *obj, struct ias_attrib *attrib) * Change the value of an objects attribute. * */ -int irias_object_change_attribute( char *obj_name, char *attrib_name, - struct ias_value *new_value) +int irias_object_change_attribute(char *obj_name, char *attrib_name, + struct ias_value *new_value) { struct ias_object *obj; struct ias_attrib *attrib; /* Find object */ - obj = hashbin_find( objects, 0, obj_name); - if ( obj == NULL) { - DEBUG( 0, __FUNCTION__ "(), Unable to find object: %s\n", - obj_name); + obj = hashbin_find(objects, 0, obj_name); + if (obj == NULL) { + WARNING(__FUNCTION__ "(), Unable to find object: %s\n", + obj_name); return -1; } /* Find attribute */ - attrib = hashbin_find( obj->attribs, 0, attrib_name); - if ( attrib == NULL) { - DEBUG( 0, __FUNCTION__ "(), Unable to find attribute: %s\n", - attrib_name); + attrib = hashbin_find(obj->attribs, 0, attrib_name); + if (attrib == NULL) { + WARNING(__FUNCTION__ "(), Unable to find attribute: %s\n", + attrib_name); return -1; } - + if ( attrib->value->type != new_value->type) { - DEBUG( 0, __FUNCTION__ + IRDA_DEBUG( 0, __FUNCTION__ "(), changing value type not allowed!\n"); return -1; } /* Delete old value */ - irias_delete_value( attrib->value); + irias_delete_value(attrib->value); /* Insert new value */ attrib->value = new_value; @@ -269,31 +262,29 @@ int irias_object_change_attribute( char *obj_name, char *attrib_name, * Add an integer attribute to an LM-IAS object * */ -void irias_add_integer_attrib( struct ias_object *obj, char *name, int value) +void irias_add_integer_attrib(struct ias_object *obj, char *name, int value) { struct ias_attrib *attrib; - ASSERT( obj != NULL, return;); - ASSERT( obj->magic == IAS_OBJECT_MAGIC, return;); - ASSERT( name != NULL, return;); + ASSERT(obj != NULL, return;); + ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); + ASSERT(name != NULL, return;); - attrib = (struct ias_attrib *) kmalloc( sizeof( struct ias_attrib), - GFP_ATOMIC); - if ( attrib == NULL) { - DEBUG( 0, __FUNCTION__ - "(), Unable to allocate attribute!\n"); + attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib), + GFP_ATOMIC); + if (attrib == NULL) { + WARNING(__FUNCTION__ "(), Unable to allocate attribute!\n"); return; } - memset( attrib, 0, sizeof( struct ias_attrib)); + memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; - attrib->name = strdup( name); -/* attrib->attr = NULL; */ + attrib->name = strdup(name); /* Insert value */ - attrib->value = irias_new_integer_value( value); + attrib->value = irias_new_integer_value(value); - irias_add_attrib( obj, attrib); + irias_add_attrib(obj, attrib); } /* @@ -303,33 +294,32 @@ void irias_add_integer_attrib( struct ias_object *obj, char *name, int value) * */ -void irias_add_octseq_attrib( struct ias_object *obj, char *name, - __u8 *octets, int len) +void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, + int len) { struct ias_attrib *attrib; - ASSERT( obj != NULL, return;); - ASSERT( obj->magic == IAS_OBJECT_MAGIC, return;); + ASSERT(obj != NULL, return;); + ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); - ASSERT( name != NULL, return;); - ASSERT( octets != NULL, return;); - ASSERT( len < 55, return;); /* FIXME: must be 1024, but... */ + ASSERT(name != NULL, return;); + ASSERT(octets != NULL, return;); - attrib = (struct ias_attrib *) kmalloc( sizeof( struct ias_attrib), - GFP_ATOMIC); - if ( attrib == NULL) { - DEBUG( 0, __FUNCTION__ - "(), Unable to allocate attribute!\n"); + attrib = (struct ias_attrib *) kmalloc(sizeof(struct ias_attrib), + GFP_ATOMIC); + if (attrib == NULL) { + WARNING(__FUNCTION__ + "(), Unable to allocate attribute!\n"); return; } - memset( attrib, 0, sizeof( struct ias_attrib)); + memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; attrib->name = strdup( name); attrib->value = irias_new_octseq_value( octets, len); - irias_add_attrib( obj, attrib); + irias_add_attrib(obj, attrib); } /* @@ -338,31 +328,30 @@ void irias_add_octseq_attrib( struct ias_object *obj, char *name, * Add a string attribute to an LM-IAS object * */ -void irias_add_string_attrib( struct ias_object *obj, char *name, char *value) +void irias_add_string_attrib(struct ias_object *obj, char *name, char *value) { struct ias_attrib *attrib; - ASSERT( obj != NULL, return;); - ASSERT( obj->magic == IAS_OBJECT_MAGIC, return;); + ASSERT(obj != NULL, return;); + ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); - ASSERT( name != NULL, return;); - ASSERT( value != NULL, return;); + ASSERT(name != NULL, return;); + ASSERT(value != NULL, return;); - attrib = (struct ias_attrib *) kmalloc( sizeof( struct ias_attrib), - GFP_ATOMIC); - if ( attrib == NULL) { - DEBUG( 0, __FUNCTION__ - "(), Unable to allocate attribute!\n"); + attrib = (struct ias_attrib *) kmalloc(sizeof( struct ias_attrib), + GFP_ATOMIC); + if (attrib == NULL) { + WARNING(__FUNCTION__ "(), Unable to allocate attribute!\n"); return; } - memset( attrib, 0, sizeof( struct ias_attrib)); + memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; - attrib->name = strdup( name); + attrib->name = strdup(name); - attrib->value = irias_new_string_value( value); + attrib->value = irias_new_string_value(value); - irias_add_attrib( obj, attrib); + irias_add_attrib(obj, attrib); } /* @@ -371,16 +360,16 @@ void irias_add_string_attrib( struct ias_object *obj, char *name, char *value) * Create new IAS integer value * */ -struct ias_value *irias_new_integer_value( int integer) +struct ias_value *irias_new_integer_value(int integer) { struct ias_value *value; - value = kmalloc( sizeof( struct ias_value), GFP_ATOMIC); - if ( value == NULL) { - DEBUG( 0, __FUNCTION__ "(), Unable to kmalloc!\n"); + value = kmalloc(sizeof( struct ias_value), GFP_ATOMIC); + if (value == NULL) { + WARNING(__FUNCTION__ "(), Unable to kmalloc!\n"); return NULL; } - memset( value, 0, sizeof( struct ias_value)); + memset(value, 0, sizeof(struct ias_value)); value->type = IAS_INTEGER; value->len = 4; @@ -395,21 +384,21 @@ struct ias_value *irias_new_integer_value( int integer) * Create new IAS string value * */ -struct ias_value *irias_new_string_value( char *string) +struct ias_value *irias_new_string_value(char *string) { struct ias_value *value; - value = kmalloc( sizeof( struct ias_value), GFP_ATOMIC); - if ( value == NULL) { - DEBUG( 0, __FUNCTION__ "(), Unable to kmalloc!\n"); + value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); + if (value == NULL) { + WARNING(__FUNCTION__ "(), Unable to kmalloc!\n"); return NULL; } memset( value, 0, sizeof( struct ias_value)); value->type = IAS_STRING; value->charset = CS_ASCII; - value->len = strlen( string); - value->t.string = strdup( string); + value->len = strlen(string); + value->t.string = strdup(string); return value; } @@ -421,25 +410,23 @@ struct ias_value *irias_new_string_value( char *string) * Create new IAS octet-sequence value * */ -struct ias_value *irias_new_octseq_value( __u8 *octseq , int len) +struct ias_value *irias_new_octseq_value(__u8 *octseq , int len) { struct ias_value *value; - ASSERT(len <= 55, return NULL;); /*FIXME: must be 1024, but.....*/ - - value = kmalloc( sizeof( struct ias_value), GFP_ATOMIC); - if ( value == NULL) { - DEBUG( 0, __FUNCTION__ "(), Unable to kmalloc!\n"); + value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); + if (value == NULL) { + WARNING(__FUNCTION__ "(), Unable to kmalloc!\n"); return NULL; } - memset( value, 0, sizeof( struct ias_value)); + memset(value, 0, sizeof( struct ias_value)); value->type = IAS_OCT_SEQ; value->len = len; value->t.oct_seq = kmalloc(len, GFP_ATOMIC); - if( value->t.oct_seq == NULL){ - DEBUG(0, __FUNCTION__"(), Unable to kmalloc!\n"); + if (value->t.oct_seq == NULL){ + WARNING(__FUNCTION__"(), Unable to kmalloc!\n"); return NULL; } memcpy(value->t.oct_seq, octseq , len); @@ -452,32 +439,32 @@ struct ias_value *irias_new_octseq_value( __u8 *octseq , int len) * Delete IAS value * */ -void irias_delete_value( struct ias_value *value) +void irias_delete_value(struct ias_value *value) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); - ASSERT( value != NULL, return;); + ASSERT(value != NULL, return;); - switch( value->type) { + switch (value->type) { case IAS_INTEGER: /* Fallthrough */ case IAS_MISSING: /* No need to deallocate */ break; case IAS_STRING: /* If string, deallocate string */ - if ( value->t.string != NULL) - kfree( value->t.string); + if (value->t.string != NULL) + kfree(value->t.string); break; case IAS_OCT_SEQ: /* If byte stream, deallocate byte stream */ - if ( value->t.oct_seq != NULL) + if (value->t.oct_seq != NULL) kfree(value->t.oct_seq); break; default: - DEBUG( 0, __FUNCTION__ "(), Unknown value type!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Unknown value type!\n"); break; } - kfree( value); + kfree(value); } diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index 894034353..0e80c0db8 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:37 1997 - * Modified at: Thu Sep 9 11:39:43 1999 + * Modified at: Tue Oct 5 11:36:11 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, @@ -296,7 +296,7 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr, int netdev) init_timer(&self->watchdog_timer); init_timer(&self->client.kick_timer); - hashbin_insert(irlan, (QUEUE *) self, daddr, NULL); + hashbin_insert(irlan, (queue_t *) self, daddr, NULL); skb_queue_head_init(&self->client.txq); diff --git a/net/irda/irlap.c b/net/irda/irlap.c index 2b59a1efc..ffa3665e3 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -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 Sep 20 11:04:32 1999 + * Modified at: Fri Oct 8 23:17:36 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved. @@ -74,14 +74,15 @@ int __init irlap_init(void) /* Allocate master array */ irlap = hashbin_new(HB_LOCAL); if (irlap == NULL) { - printk(KERN_WARNING "IrLAP: Can't allocate irlap hashbin!\n"); + ERROR(__FUNCTION__ "(), can't allocate irlap hashbin!\n"); return -ENOMEM; } #ifdef CONFIG_IRDA_COMPRESSION irlap_compressors = hashbin_new(HB_LOCAL); if (irlap_compressors == NULL) { - printk(KERN_WARNING "IrLAP: Can't allocate compressors hashbin!\n"); + WARNING(__FUNCTION__ + "(), can't allocate compressors hashbin!\n"); return -ENOMEM; } #endif @@ -106,11 +107,11 @@ void irlap_cleanup(void) * Initialize IrLAP layer * */ -struct irlap_cb *irlap_open(struct net_device *dev) +struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos) { struct irlap_cb *self; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Initialize the irlap structure. */ self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL); @@ -122,6 +123,10 @@ struct irlap_cb *irlap_open(struct net_device *dev) /* Make a binding between the layers */ self->netdev = dev; + self->qos_dev = qos; + + /* FIXME: should we get our own field? */ + dev->atalk_ptr = self; irlap_next_state(self, LAP_OFFLINE); @@ -131,6 +136,7 @@ struct irlap_cb *irlap_open(struct net_device *dev) /* My unique IrLAP device address! */ get_random_bytes(&self->saddr, sizeof(self->saddr)); + memcpy(dev->dev_addr, &self->saddr, 4); /* * Generate random connection address for this session, which must @@ -148,12 +154,13 @@ struct irlap_cb *irlap_open(struct net_device *dev) init_timer(&self->poll_timer); init_timer(&self->wd_timer); init_timer(&self->backoff_timer); + init_timer(&self->media_busy_timer); irlap_apply_default_connection_parameters(self); irlap_next_state(self, LAP_NDM); - hashbin_insert(irlap, (QUEUE *) self, self->saddr, NULL); + hashbin_insert(irlap, (queue_t *) self, self->saddr, NULL); irlmp_register_link(self, self->saddr, &self->notify); @@ -179,6 +186,7 @@ static void __irlap_close(struct irlap_cb *self) del_timer(&self->poll_timer); del_timer(&self->wd_timer); del_timer(&self->backoff_timer); + del_timer(&self->media_busy_timer); irlap_flush_all_queues(self); @@ -197,7 +205,7 @@ void irlap_close(struct irlap_cb *self) { struct irlap_cb *lap; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -210,7 +218,7 @@ void irlap_close(struct irlap_cb *self) /* Be sure that we manage to remove ourself from the hash */ lap = hashbin_remove(irlap, self->saddr, NULL); if (!lap) { - DEBUG(1, __FUNCTION__ "(), Didn't find myself!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Didn't find myself!\n"); return; } __irlap_close(lap); @@ -224,7 +232,7 @@ void irlap_close(struct irlap_cb *self) */ void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -243,7 +251,7 @@ void irlap_connect_indication(struct irlap_cb *self, struct sk_buff *skb) */ void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); irlap_do_event(self, CONNECT_RESPONSE, skb, NULL); } @@ -258,7 +266,7 @@ void irlap_connect_response(struct irlap_cb *self, struct sk_buff *skb) void irlap_connect_request(struct irlap_cb *self, __u32 daddr, struct qos_info *qos_user, int sniff) { - DEBUG(3, __FUNCTION__ "(), daddr=0x%08x\n", daddr); + IRDA_DEBUG(3, __FUNCTION__ "(), daddr=0x%08x\n", daddr); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -271,8 +279,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->netdev)) + if ((self->state == LAP_NDM) && !self->media_busy) irlap_do_event(self, CONNECT_REQUEST, NULL, NULL); else self->connect_pending = TRUE; @@ -286,7 +293,7 @@ void irlap_connect_request(struct irlap_cb *self, __u32 daddr, */ void irlap_connect_confirm(struct irlap_cb *self, struct sk_buff *skb) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -310,7 +317,7 @@ inline void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb) if (self->qos_tx.compression.value) { skb = irlap_decompress_frame(self, skb); if (!skb) { - DEBUG(1, __FUNCTION__ "(), Decompress error!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Decompress error!\n"); return; } } @@ -326,7 +333,7 @@ inline void irlap_data_indication(struct irlap_cb *self, struct sk_buff *skb) */ void irlap_unit_data_indication(struct irlap_cb *self, struct sk_buff *skb) { - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -340,7 +347,7 @@ void irlap_unit_data_indication(struct irlap_cb *self, struct sk_buff *skb) skb = irlap_decompress_frame(self, skb); if (!skb) { - DEBUG(1, __FUNCTION__ "(), Decompress error!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Decompress error!\n"); return; } } @@ -364,7 +371,7 @@ inline void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb, if (self->qos_tx.compression.value) { skb = irlap_compress_frame(self, skb); if (!skb) { - DEBUG(1, __FUNCTION__ "(), Compress error!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Compress error!\n"); return; } } @@ -381,7 +388,7 @@ inline void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb, if (reliable) skb->data[1] = I_FRAME; else { - DEBUG(4, __FUNCTION__ "(), queueing unreliable frame\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), queueing unreliable frame\n"); skb->data[1] = UI_FRAME; } @@ -412,7 +419,7 @@ inline void irlap_data_request(struct irlap_cb *self, struct sk_buff *skb, */ void irlap_disconnect_request(struct irlap_cb *self) { - DEBUG(3, __FUNCTION__ "()\n"); + IRDA_DEBUG(3, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -434,7 +441,7 @@ void irlap_disconnect_request(struct irlap_cb *self) irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL); break; default: - DEBUG(2, __FUNCTION__ "(), disconnect pending!\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), disconnect pending!\n"); self->disconnect_pending = TRUE; break; } @@ -448,7 +455,7 @@ void irlap_disconnect_request(struct irlap_cb *self) */ void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) { - DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]); + IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -461,7 +468,7 @@ void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) switch(reason) { case LAP_RESET_INDICATION: - DEBUG(1, __FUNCTION__ "(), Sending reset request!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Sending reset request!\n"); irlap_do_event(self, RESET_REQUEST, NULL, NULL); break; case LAP_NO_RESPONSE: /* FALLTROUGH */ @@ -472,7 +479,7 @@ void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) reason, NULL); break; default: - DEBUG(1, __FUNCTION__ "(), Reason %d not implemented!\n", + IRDA_DEBUG(1, __FUNCTION__ "(), Reason %d not implemented!\n", reason); } } @@ -491,7 +498,7 @@ void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery) ASSERT(self->magic == LAP_MAGIC, return;); ASSERT(discovery != NULL, return;); - DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots); + IRDA_DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots); ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) || (discovery->nslots == 8) || (discovery->nslots == 16), @@ -535,7 +542,7 @@ void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery) irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info); } else { - DEBUG(4, __FUNCTION__ + IRDA_DEBUG(4, __FUNCTION__ "(), discovery only possible in NDM mode\n"); irlap_discovery_confirm(self, NULL); } @@ -559,7 +566,7 @@ void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log) * the media busy condition (irlap p.94). This should allow us to make * connection attempts much easier. */ - if (discovery_log && hashbin_get_size(discovery_log) > 0) + if (discovery_log && HASHBIN_GET_SIZE(discovery_log) > 0) irda_device_set_media_busy(self->netdev, FALSE); /* Inform IrLMP */ @@ -574,7 +581,7 @@ void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log) */ void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -595,10 +602,10 @@ void irlap_status_indication(int quality_of_link) { switch (quality_of_link) { case STATUS_NO_ACTIVITY: - printk(KERN_INFO "IrLAP, no activity on link!\n"); + MESSAGE("IrLAP, no activity on link!\n"); break; case STATUS_NOISY: - printk(KERN_INFO "IrLAP, noisy link!\n"); + MESSAGE("IrLAP, noisy link!\n"); break; default: break; @@ -614,7 +621,7 @@ void irlap_status_indication(int quality_of_link) */ void irlap_reset_indication(struct irlap_cb *self) { - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -633,7 +640,7 @@ void irlap_reset_indication(struct irlap_cb *self) */ void irlap_reset_confirm(void) { - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); } /* @@ -728,7 +735,7 @@ int irlap_validate_nr_received(struct irlap_cb *self, int nr) { /* nr as expected? */ if (nr == self->vs) { - DEBUG(4, __FUNCTION__ "(), expected!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), expected!\n"); return NR_EXPECTED; } @@ -756,7 +763,7 @@ int irlap_validate_nr_received(struct irlap_cb *self, int nr) */ void irlap_initiate_connection_state(struct irlap_cb *self) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -783,9 +790,9 @@ void irlap_initiate_connection_state(struct irlap_cb *self) */ void irlap_wait_min_turn_around(struct irlap_cb *self, struct qos_info *qos) { - int usecs; - int speed; - int bytes ; + __u32 speed; + __u32 usecs; + __u32 bytes ; /* Get QoS values. */ speed = qos->baud_rate.value; @@ -844,25 +851,12 @@ 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); + IRDA_DEBUG(4, __FUNCTION__ "(), setting speed to %d\n", speed); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); - if (!self->netdev) { - DEBUG(1, __FUNCTION__ "(), driver missing!\n"); - return; - } - - /* - * 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); - + /* Must use the same speed in both directions */ self->qos_rx.baud_rate.value = speed; self->qos_tx.baud_rate.value = speed; } @@ -883,24 +877,24 @@ void irlap_init_comp_qos_capabilities(struct irlap_cb *self) * actually been loaded. Ths is sort of hairy code but that is what * you get when you do a little bit flicking :-) */ - DEBUG(4, __FUNCTION__ "(), comp bits 0x%02x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), comp bits 0x%02x\n", self->qos_rx.compression.bits); mask = 0x80; /* Start with testing MSB */ for (i=0;i<8;i++) { - DEBUG(4, __FUNCTION__ "(), testing bit %d\n", 8-i); + IRDA_DEBUG(4, __FUNCTION__ "(), testing bit %d\n", 8-i); if (self->qos_rx.compression.bits & mask) { - DEBUG(4, __FUNCTION__ "(), bit %d is set by defalt\n", + IRDA_DEBUG(4, __FUNCTION__ "(), bit %d is set by defalt\n", 8-i); comp = hashbin_find(irlap_compressors, compression[ msb_index(mask)], NULL); if (!comp) { /* Protocol not supported, so clear the bit */ - DEBUG(4, __FUNCTION__ "(), Compression " + IRDA_DEBUG(4, __FUNCTION__ "(), Compression " "protocol %d has not been loaded!\n", compression[msb_index(mask)]); self->qos_rx.compression.bits &= ~mask; - DEBUG(4, __FUNCTION__ + IRDA_DEBUG(4, __FUNCTION__ "(), comp bits 0x%02x\n", self->qos_rx.compression.bits); } @@ -934,8 +928,7 @@ void irlap_init_qos_capabilities(struct irlap_cb *self, #endif /* Apply drivers QoS capabilities */ - irda_qos_compute_intersection(&self->qos_rx, - irda_device_get_qos(self->netdev)); + irda_qos_compute_intersection(&self->qos_rx, self->qos_dev); /* * Check for user supplied QoS parameters. The service user is only @@ -943,7 +936,7 @@ void irlap_init_qos_capabilities(struct irlap_cb *self, * user may not have set all of them. */ if (qos_user) { - DEBUG(1, __FUNCTION__ "(), Found user specified QoS!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Found user specified QoS!\n"); if (qos_user->baud_rate.bits) self->qos_rx.baud_rate.bits &= qos_user->baud_rate.bits; @@ -986,7 +979,7 @@ void irlap_init_qos_capabilities(struct irlap_cb *self, */ void irlap_apply_default_connection_parameters(struct irlap_cb *self) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -1019,7 +1012,7 @@ void irlap_apply_default_connection_parameters(struct irlap_cb *self) void irlap_apply_connection_parameters(struct irlap_cb *self, struct qos_info *qos) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -1036,7 +1029,7 @@ void irlap_apply_connection_parameters(struct irlap_cb *self, */ self->window_bytes = qos->baud_rate.value * qos->max_turn_time.value / 10000; - DEBUG(4, "Setting window_bytes = %d\n", self->window_bytes); + IRDA_DEBUG(4, "Setting window_bytes = %d\n", self->window_bytes); /* * Set N1 to 0 if Link Disconnect/Threshold Time = 3 and set it to @@ -1049,10 +1042,10 @@ void irlap_apply_connection_parameters(struct irlap_cb *self, else self->N1 = 3000 / qos->max_turn_time.value; - DEBUG(4, "Setting N1 = %d\n", self->N1); + IRDA_DEBUG(4, "Setting N1 = %d\n", self->N1); self->N2 = qos->link_disc_time.value * 1000 / qos->max_turn_time.value; - DEBUG(4, "Setting N2 = %d\n", self->N2); + IRDA_DEBUG(4, "Setting N2 = %d\n", self->N2); /* * Initialize timeout values, some of the rules are listed on @@ -1064,7 +1057,7 @@ void irlap_apply_connection_parameters(struct irlap_cb *self, #ifdef CONFIG_IRDA_COMPRESSION if (qos->compression.value) { - DEBUG(1, __FUNCTION__ "(), Initializing compression\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Initializing compression\n"); irda_set_compression(self, qos->compression.value); irlap_compressor_init(self, 0); @@ -1080,14 +1073,14 @@ void irlap_apply_connection_parameters(struct irlap_cb *self, */ void irlap_set_local_busy(struct irlap_cb *self, int status) { - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); self->local_busy = status; if (status) - DEBUG(0, __FUNCTION__ "(), local busy ON\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), local busy ON\n"); else - DEBUG(0, __FUNCTION__ "(), local busy OFF\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), local busy OFF\n"); } #ifdef CONFIG_PROC_FS diff --git a/net/irda/irlap_comp.c b/net/irda/irlap_comp.c index 299d1705c..942949ac8 100644 --- a/net/irda/irlap_comp.c +++ b/net/irda/irlap_comp.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Fri Oct 9 09:18:07 1998 - * Modified at: Sun May 9 11:37:06 1999 + * Modified at: Tue Oct 5 11:34:52 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> @@ -45,11 +45,11 @@ int irda_register_compressor( struct compressor *cp) { struct irda_compressor *new; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); /* Check if this compressor has been registred before */ if ( hashbin_find ( irlap_compressors, cp->compress_proto, NULL)) { - DEBUG( 0, __FUNCTION__ "(), Compressor already registered\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Compressor already registered\n"); return 0; } @@ -63,7 +63,7 @@ int irda_register_compressor( struct compressor *cp) new->cp = cp; /* Insert IrDA compressor into hashbin */ - hashbin_insert( irlap_compressors, (QUEUE *) new, cp->compress_proto, + hashbin_insert( irlap_compressors, (queue_t *) new, cp->compress_proto, NULL); return 0; @@ -79,11 +79,11 @@ void irda_unregister_compressor ( struct compressor *cp) { struct irda_compressor *node; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); node = hashbin_remove( irlap_compressors, cp->compress_proto, NULL); if ( !node) { - DEBUG( 0, __FUNCTION__ "(), compressor not found!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), compressor not found!\n"); return; } kfree( node); @@ -102,7 +102,7 @@ int irda_set_compression( struct irlap_cb *self, int proto) __u8 options[CILEN_DEFLATE]; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); ASSERT( self != NULL, return -ENODEV;); ASSERT( self->magic == LAP_MAGIC, return -EBADR;); @@ -115,7 +115,7 @@ int irda_set_compression( struct irlap_cb *self, int proto) comp = hashbin_find( irlap_compressors, proto, NULL); if ( !comp) { - DEBUG( 0, __FUNCTION__ "(), Unable to find compressor\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Unable to find compressor\n"); return -1; } @@ -130,7 +130,7 @@ int irda_set_compression( struct irlap_cb *self, int proto) self->compressor.cp = cp; self->compressor.state = cp->comp_alloc( options, sizeof( options)); if ( self->compressor.state == NULL) { - DEBUG( 0, __FUNCTION__ "(), Failed!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Failed!\n"); return -ENOBUFS; } @@ -145,7 +145,7 @@ int irda_set_compression( struct irlap_cb *self, int proto) self->decompressor.cp = cp; self->decompressor.state = cp->decomp_alloc( options, sizeof( options)); if ( self->decompressor.state == NULL) { - DEBUG( 0, __FUNCTION__ "(), Failed!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Failed!\n"); return -ENOBUFS; } return 0; @@ -159,7 +159,7 @@ int irda_set_compression( struct irlap_cb *self, int proto) */ void irda_free_compression( struct irlap_cb *self) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); if ( self->compressor.state) { irda_comp_free( self->compressor.state); @@ -183,7 +183,7 @@ void irlap_compressor_init( struct irlap_cb *self, int compress) int debug = TRUE; __u8 options[CILEN_DEFLATE]; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT( self != NULL, return;); ASSERT( self->magic == LAP_MAGIC, return;); @@ -198,7 +198,7 @@ void irlap_compressor_init( struct irlap_cb *self, int compress) * We're agreeing to send compressed packets. */ if ( self->compressor.state == NULL) { - DEBUG( 0, __FUNCTION__ "(), state == NULL\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n"); return; } @@ -206,7 +206,7 @@ void irlap_compressor_init( struct irlap_cb *self, int compress) options, sizeof( options), 0, 0, debug)) { - DEBUG( 0, __FUNCTION__ "(), Compressor running!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Compressor running!\n"); /* ppp->flags |= SC_COMP_RUN; */ } @@ -214,7 +214,7 @@ void irlap_compressor_init( struct irlap_cb *self, int compress) * Initialize decompressor */ if ( self->decompressor.state == NULL) { - DEBUG( 0, __FUNCTION__ "(), state == NULL\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), state == NULL\n"); return; } @@ -222,7 +222,7 @@ void irlap_compressor_init( struct irlap_cb *self, int compress) options, sizeof( options), 0, 0, 0, debug)) { - DEBUG( 0, __FUNCTION__ "(), Decompressor running!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Decompressor running!\n"); /* ppp->flags |= SC_DECOMP_RUN; */ /* ppp->flags &= ~(SC_DC_ERROR | SC_DC_FERROR); */ @@ -243,7 +243,7 @@ struct sk_buff *irlap_compress_frame( struct irlap_cb *self, ASSERT( skb != NULL, return NULL;); - DEBUG(4, __FUNCTION__ "() skb->len=%d, jiffies=%ld\n", (int) skb->len, + IRDA_DEBUG(4, __FUNCTION__ "() skb->len=%d, jiffies=%ld\n", (int) skb->len, jiffies); ASSERT( self != NULL, return NULL;); @@ -270,7 +270,7 @@ struct sk_buff *irlap_compress_frame( struct irlap_cb *self, skb->data, new_skb->data, skb->len, new_skb->len); if( count <= 0) { - DEBUG(4, __FUNCTION__ "(), Unable to compress frame!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), Unable to compress frame!\n"); dev_kfree_skb( new_skb); /* Tell peer that this frame is not compressed */ @@ -287,7 +287,7 @@ struct sk_buff *irlap_compress_frame( struct irlap_cb *self, dev_kfree_skb( skb); - DEBUG(4, __FUNCTION__ "() new_skb->len=%d\n, jiffies=%ld", + IRDA_DEBUG(4, __FUNCTION__ "() new_skb->len=%d\n, jiffies=%ld", (int) new_skb->len, jiffies); return new_skb; @@ -305,7 +305,7 @@ struct sk_buff *irlap_decompress_frame( struct irlap_cb *self, struct sk_buff *new_skb; int count; - DEBUG( 4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len); + IRDA_DEBUG( 4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len); ASSERT( self != NULL, return NULL;); ASSERT( self->magic == LAP_MAGIC, return NULL;); @@ -339,7 +339,7 @@ struct sk_buff *irlap_decompress_frame( struct irlap_cb *self, count = irda_decompress( self->decompressor.state, skb->data, skb->len, new_skb->data, new_skb->len); if ( count <= 0) { - DEBUG( 4, __FUNCTION__ "(), Unable to decompress frame!\n"); + IRDA_DEBUG( 4, __FUNCTION__ "(), Unable to decompress frame!\n"); dev_kfree_skb( new_skb); return skb; @@ -347,7 +347,7 @@ struct sk_buff *irlap_decompress_frame( struct irlap_cb *self, skb_trim( new_skb, count); - DEBUG( 4, __FUNCTION__ "() new_skb->len=%d\n", (int) new_skb->len); + IRDA_DEBUG( 4, __FUNCTION__ "() new_skb->len=%d\n", (int) new_skb->len); return new_skb; } diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c index 203b7360f..fa9369863 100644 --- a/net/irda/irlap_event.c +++ b/net/irda/irlap_event.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Aug 16 00:59:29 1997 - * Modified at: Mon Sep 20 12:30:31 1999 + * Modified at: Sun Oct 10 11:14:22 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -200,7 +200,7 @@ void irlap_start_poll_timer(struct irlap_cb *self, int timeout) } else self->fast_RR = FALSE; - DEBUG(4, __FUNCTION__ "(), Timeout=%d\n", timeout); + IRDA_DEBUG(4, __FUNCTION__ "(), Timeout=%d\n", timeout); #endif if (timeout == 0) irlap_do_event(self, POLL_TIMER_EXPIRED, NULL, NULL); @@ -223,7 +223,7 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, if (!self || self->magic != LAP_MAGIC) return; - DEBUG(4, __FUNCTION__ "(), event = %s, state = %s\n", + IRDA_DEBUG(4, __FUNCTION__ "(), event = %s, state = %s\n", irlap_event[event], irlap_state[self->state]); ret = (*state[self->state])(self, event, skb, info); @@ -256,9 +256,7 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, break; case LAP_NDM: /* Check if we should try to connect */ - if ((self->connect_pending) && - !irda_device_is_media_busy(self->netdev)) - { + if ((self->connect_pending) && !self->media_busy) { self->connect_pending = FALSE; ret = (*state[self->state])(self, CONNECT_REQUEST, @@ -284,7 +282,7 @@ void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state) if (!self || self->magic != LAP_MAGIC) return; - DEBUG(4, "next LAP state = %s\n", irlap_state[ state]); + IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[ state]); self->state = state; @@ -317,8 +315,8 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, case CONNECT_REQUEST: ASSERT(self->netdev != NULL, return -1;); - if (irda_device_is_media_busy(self->netdev)) { - DEBUG(0, __FUNCTION__ + if (self->media_busy) { + IRDA_DEBUG(0, __FUNCTION__ "(), CONNECT_REQUEST: media busy!\n"); /* Always switch state before calling upper layers */ @@ -345,7 +343,7 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, irlap_connect_indication(self, skb); } else { - DEBUG(0, __FUNCTION__ "(), SNRM frame does not contain" + IRDA_DEBUG(0, __FUNCTION__ "(), SNRM frame does not contain" " and I field!\n"); dev_kfree_skb(skb); } @@ -353,8 +351,8 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, case DISCOVERY_REQUEST: ASSERT(info != NULL, return -1;); - if (irda_device_is_media_busy(self->netdev)) { - DEBUG(0, __FUNCTION__ "(), media busy!\n"); + if (self->media_busy) { + IRDA_DEBUG(0, __FUNCTION__ "(), media busy!\n"); /* irlap->log.condition = MEDIA_BUSY; */ /* Always switch state before calling upper layers */ @@ -382,7 +380,7 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, /* self->daddr = info->daddr; */ self->slot = irlap_generate_rand_time_slot(info->S, info->s); - DEBUG(4, "XID_CMD: S=%d, s=%d, slot %d\n", info->S, + IRDA_DEBUG(4, "XID_CMD: S=%d, s=%d, slot %d\n", info->S, info->s, self->slot); if (self->slot == info->s) { @@ -418,11 +416,11 @@ static int irlap_state_ndm(struct irlap_cb *self, IRLAP_EVENT event, dev_kfree_skb(skb); break; case RECV_TEST_RSP: - DEBUG(0, __FUNCTION__ "() not implemented!\n"); + IRDA_DEBUG(0, __FUNCTION__ "() not implemented!\n"); dev_kfree_skb(skb); break; default: - DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", + IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); if (skb) @@ -453,7 +451,7 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event, ASSERT(info != NULL, return -1;); ASSERT(info->discovery != NULL, return -1;); - DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", info->discovery->daddr); if (!self->discovery_log) { @@ -463,7 +461,7 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event, break; } hashbin_insert(self->discovery_log, - (QUEUE *) info->discovery, + (queue_t *) info->discovery, info->discovery->daddr, NULL); dev_kfree_skb(skb); @@ -501,7 +499,7 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event, } break; default: - DEBUG(2, __FUNCTION__ "(), Unknown event %d, %s\n", event, + IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); if (skb) @@ -526,14 +524,14 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event, discovery_t *discovery_rsp; int ret=0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); switch (event) { case QUERY_TIMER_EXPIRED: - DEBUG(2, __FUNCTION__ "(), QUERY_TIMER_EXPIRED <%ld>\n", + IRDA_DEBUG(2, __FUNCTION__ "(), QUERY_TIMER_EXPIRED <%ld>\n", jiffies); irlap_next_state(self, LAP_NDM); break; @@ -565,7 +563,7 @@ static int irlap_state_reply(struct irlap_cb *self, IRLAP_EVENT event, dev_kfree_skb(skb); break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); if ( skb) @@ -589,7 +587,7 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event, { int ret = 0; - DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); + IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); @@ -622,7 +620,7 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state( self, LAP_NRM_S); break; case RECV_DISCOVERY_XID_CMD: - DEBUG( 3, __FUNCTION__ "(), event RECV_DISCOVER_XID_CMD!\n"); + IRDA_DEBUG( 3, __FUNCTION__ "(), event RECV_DISCOVER_XID_CMD!\n"); irlap_next_state( self, LAP_NDM); break; case DISCONNECT_REQUEST: @@ -630,7 +628,7 @@ static int irlap_state_conn(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state( self, LAP_CONN); break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); if (skb) @@ -655,7 +653,7 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, { int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); @@ -685,7 +683,7 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, break; case RECV_SNRM_CMD: - DEBUG(4, __FUNCTION__ "(), SNRM battle!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), SNRM battle!\n"); ASSERT(skb != NULL, return 0;); ASSERT(info != NULL, return 0;); @@ -759,7 +757,7 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, /* DM handled in irlap_frame.c, irlap_driver_rcv() */ default: - DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, %s\n", event, irlap_event[event]); if (skb) @@ -780,7 +778,7 @@ static int irlap_state_setup(struct irlap_cb *self, IRLAP_EVENT event, static int irlap_state_offline(struct irlap_cb *self, IRLAP_EVENT event, struct sk_buff *skb, struct irlap_info *info) { - DEBUG( 0, __FUNCTION__ "(), Unknown event\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event\n"); return -1; } @@ -811,7 +809,7 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, * speed and turn-around-time. */ if ((skb->len+self->bofs_count) > self->bytes_left) { - DEBUG(4, __FUNCTION__ "(), Not allowed to " + IRDA_DEBUG(4, __FUNCTION__ "(), Not allowed to " "transmit more bytes!\n"); skb_queue_head(&self->tx_list, skb); @@ -851,7 +849,7 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, self->fast_RR = FALSE; #endif } else { - DEBUG(4, __FUNCTION__ + IRDA_DEBUG(4, __FUNCTION__ "(), Unable to send! remote busy?\n"); skb_queue_head(&self->tx_list, skb); @@ -877,7 +875,7 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state(self, LAP_PCLOSE); break; default: - DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", + IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); if (skb) @@ -899,7 +897,7 @@ static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event, { int ret = 0; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); @@ -935,7 +933,7 @@ static int irlap_state_pclose(struct irlap_cb *self, IRLAP_EVENT event, } break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d\n", event); if (skb) dev_kfree_skb(skb); @@ -1044,7 +1042,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, /* Keep state */ irlap_next_state(self, LAP_NRM_P); } else { - DEBUG( 4, __FUNCTION__ + IRDA_DEBUG( 4, __FUNCTION__ "(), missing or duplicate frame!\n"); /* Update Nr received */ @@ -1110,7 +1108,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, if ((ns_status == NS_UNEXPECTED) && (nr_status == NR_UNEXPECTED)) { - DEBUG( 4, "IrLAP: unexpected nr and ns!\n"); + IRDA_DEBUG( 4, "IrLAP: unexpected nr and ns!\n"); if (info->pf) { /* Resend rejected frames */ irlap_resend_rejected_frames(self, CMD_FRAME); @@ -1149,8 +1147,8 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, } break; } - DEBUG(1, __FUNCTION__ "(), Not implemented!\n"); - DEBUG(1, __FUNCTION__ + IRDA_DEBUG(1, __FUNCTION__ "(), Not implemented!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), event=%s, ns_status=%d, nr_status=%d\n", irlap_event[ event], ns_status, nr_status); break; @@ -1204,7 +1202,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, /* Update Nr received */ irlap_update_nr_received(self, info->nr); - DEBUG(4, "RECV_RR_FRAME: Retrans:%d, nr=%d, va=%d, " + IRDA_DEBUG(4, "RECV_RR_FRAME: Retrans:%d, nr=%d, va=%d, " "vs=%d, vr=%d\n", self->retry_count, info->nr, self->va, self->vs, self->vr); @@ -1214,7 +1212,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state(self, LAP_NRM_P); } else if (ret == NR_INVALID) { - DEBUG(1, __FUNCTION__ "(), Received RR with " + IRDA_DEBUG(1, __FUNCTION__ "(), Received RR with " "invalid nr !\n"); del_timer(&self->final_timer); @@ -1227,7 +1225,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, dev_kfree_skb(skb); break; case RECV_RNR_FRAME: - DEBUG(4, "irlap_state_nrm_p: RECV_RNR_FRAME: Retrans:%d, " + IRDA_DEBUG(4, "irlap_state_nrm_p: RECV_RNR_FRAME: Retrans:%d, " "nr=%d, va=%d, vs=%d, vr=%d\n", self->retry_count, info->nr, self->va, self->vs, self->vr); @@ -1264,7 +1262,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, * we only do this once for each frame. */ if (irda_device_is_receiving(self->netdev) && !self->add_wait) { - DEBUG(4, "FINAL_TIMER_EXPIRED when receiving a " + IRDA_DEBUG(4, "FINAL_TIMER_EXPIRED when receiving a " "frame! Waiting a little bit more!\n"); irlap_start_final_timer(self, MSECS_TO_JIFFIES(300)); @@ -1287,7 +1285,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_final_timer(self, self->final_timeout); self->retry_count++; - DEBUG(4, "irlap_state_nrm_p: FINAL_TIMER_EXPIRED:" + IRDA_DEBUG(4, "irlap_state_nrm_p: FINAL_TIMER_EXPIRED:" " retry_count=%d\n", self->retry_count); /* Keep state */ } else if (self->retry_count == self->N1) { @@ -1298,7 +1296,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_final_timer(self, self->final_timeout); self->retry_count++; - DEBUG(4, "retry count = N1; retry_count=%d\n", + IRDA_DEBUG(4, "retry count = N1; retry_count=%d\n", self->retry_count); /* Keep state */ } else if (self->retry_count >= self->N2) { @@ -1310,7 +1308,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, } break; case RECV_DISC_FRAME: /* FIXME: Check how this is in the standard! */ - DEBUG(1, __FUNCTION__ "(), RECV_DISC_FRAME()\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), RECV_DISC_FRAME()\n"); /* Always switch state before calling upper layers */ irlap_next_state(self, LAP_NDM); @@ -1330,7 +1328,7 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event, break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); if (skb) @@ -1354,7 +1352,7 @@ static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event, { int ret = 0; - DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]); + IRDA_DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); @@ -1380,7 +1378,7 @@ static int irlap_state_reset_wait(struct irlap_cb *self, IRLAP_EVENT event, irlap_next_state( self, LAP_PCLOSE); break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); if (skb) dev_kfree_skb(skb); @@ -1403,7 +1401,7 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, { int ret = 0; - DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]); + IRDA_DEBUG(3, __FUNCTION__ "(), event = %s\n", irlap_event[event]); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); @@ -1438,7 +1436,7 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, irlap_wait_min_turn_around(self, &self->qos_tx); ASSERT(self->netdev != NULL, return -1;); - irlap_send_snrm_frame(self, irda_device_get_qos(self->netdev)); + irlap_send_snrm_frame(self, self->qos_dev); self->retry_count++; /* Experimental!! */ @@ -1459,7 +1457,7 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, * state */ if (!info) { - DEBUG(3, __FUNCTION__ "(), RECV_SNRM_CMD\n"); + IRDA_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); @@ -1467,13 +1465,13 @@ static int irlap_state_reset(struct irlap_cb *self, IRLAP_EVENT event, irlap_start_wd_timer(self, self->wd_timeout); irlap_next_state(self, LAP_NDM); } else { - DEBUG(0, __FUNCTION__ "(), SNRM frame contained an I " + IRDA_DEBUG(0, __FUNCTION__ "(), SNRM frame contained an I " "field!\n"); dev_kfree_skb(skb); } break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); if (skb) @@ -1497,7 +1495,7 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, { int ret = 0; - DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); + IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); ASSERT(self != NULL, return -ENODEV;); ASSERT(self->magic == LAP_MAGIC, return -EBADR;); @@ -1547,13 +1545,13 @@ static int irlap_state_xmit_s(struct irlap_cb *self, IRLAP_EVENT event, ret = -EPROTO; } } else { - DEBUG(1, __FUNCTION__ "(), Unable to send!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unable to send!\n"); skb_queue_head( &self->tx_list, skb); ret = -EPROTO; } break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %s\n", irlap_event[event]); if (skb) dev_kfree_skb(skb); @@ -1578,7 +1576,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, int nr_status; int ret = 0; - DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); + IRDA_DEBUG(4, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LAP_MAGIC, return -1;); @@ -1586,7 +1584,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, switch (event) { case RECV_I_CMD: /* Optimize for the common case */ /* FIXME: must check for remote_busy below */ - DEBUG(4, __FUNCTION__ "(), event=%s nr=%d, vs=%d, ns=%d, " + IRDA_DEBUG(4, __FUNCTION__ "(), event=%s nr=%d, vs=%d, ns=%d, " "vr=%d, pf=%d\n", irlap_event[event], info->nr, self->vs, info->ns, self->vr, info->pf); @@ -1690,7 +1688,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, if ((ns_status == NS_EXPECTED) && (nr_status == NR_UNEXPECTED)) { if (info->pf) { - DEBUG(4, "RECV_I_RSP: frame(s) lost\n"); + IRDA_DEBUG(4, "RECV_I_RSP: frame(s) lost\n"); self->vr = (self->vr + 1) % 8; @@ -1726,10 +1724,10 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, } if (ret == NR_INVALID) { - DEBUG(0, "NRM_S, NR_INVALID not implemented!\n"); + IRDA_DEBUG(0, "NRM_S, NR_INVALID not implemented!\n"); } if (ret == NS_INVALID) { - DEBUG(0, "NRM_S, NS_INVALID not implemented!\n"); + IRDA_DEBUG(0, "NRM_S, NS_INVALID not implemented!\n"); } break; case RECV_UI_FRAME: @@ -1805,7 +1803,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, /* Keep state */ irlap_next_state(self, LAP_NRM_S); } else { - DEBUG(1, __FUNCTION__ "(), invalid nr not implemented!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), invalid nr not implemented!\n"); } if (skb) dev_kfree_skb(skb); @@ -1815,12 +1813,12 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, /* SNRM frame is not allowed to contain an I-field */ if (!info) { del_timer(&self->wd_timer); - DEBUG(1, __FUNCTION__ "(), received SNRM cmd\n"); + IRDA_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 " + IRDA_DEBUG(0, __FUNCTION__ "(), SNRM frame contained an " "I-field!\n"); dev_kfree_skb(skb); } @@ -1830,7 +1828,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, * Wait until retry_count * n matches negotiated threshold/ * disconnect time (note 2 in IrLAP p. 82) */ - DEBUG(1, __FUNCTION__ "(), retry_count = %d\n", + IRDA_DEBUG(1, __FUNCTION__ "(), retry_count = %d\n", self->retry_count); if ((self->retry_count < (self->N2/2)) && @@ -1885,7 +1883,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, dev_kfree_skb(skb); break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", event, irlap_event[event]); ret = -1; break; @@ -1902,7 +1900,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event, static int irlap_state_sclose( struct irlap_cb *self, IRLAP_EVENT event, struct sk_buff *skb, struct irlap_info *info) { - DEBUG( 0, __FUNCTION__ "(), Not implemented!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented!\n"); return -1; } @@ -1913,7 +1911,7 @@ static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event, { int ret = 0; - DEBUG(1, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); + IRDA_DEBUG(1, __FUNCTION__ "(), event=%s\n", irlap_event[ event]); ASSERT( self != NULL, return -ENODEV;); ASSERT( self->magic == LAP_MAGIC, return -EBADR;); @@ -1933,7 +1931,7 @@ static int irlap_state_reset_check( struct irlap_cb *self, IRLAP_EVENT event, irlap_start_wd_timer( self, WD_TIMEOUT); break; default: - DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown event %d, (%s)\n", event, irlap_event[event]); ret = -1; break; diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c index 303bc3b12..160690889 100644 --- a/net/irda/irlap_frame.c +++ b/net/irda/irlap_frame.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Aug 19 10:27:26 1997 - * Modified at: Tue Sep 28 08:49:58 1999 + * Modified at: Sat Oct 9 09:42:11 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -43,23 +43,25 @@ #include <net/irda/qos.h> /* - * Function irlap_insert_mtt (self, skb) + * Function irlap_insert_info (self, skb) * - * Insert minimum turnaround time relevant information into the skb. We + * Insert minimum turnaround time and speed information into the skb. We * need to do this since it's per packet relevant information. * */ -static inline void irlap_insert_mtt(struct irlap_cb *self, struct sk_buff *skb) +static inline void irlap_insert_info(struct irlap_cb *self, + struct sk_buff *skb) { struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb; - /* - * Insert MTT (min. turn time) into skb, so that the device driver - * knows which MTT to use - */ + /* + * Insert MTT (min. turn time) and speed into skb, so that the + * device driver knows which settings to use + */ cb->magic = LAP_MAGIC; cb->mtt = self->mtt_required; - + cb->speed = self->qos_tx.baud_rate.value; + /* Reset */ self->mtt_required = 0; @@ -94,10 +96,9 @@ void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb) skb->protocol = htons(ETH_P_IRDA); skb->priority = TC_PRIO_BESTEFFORT; - irlap_insert_mtt(self, skb); + irlap_insert_info(self, skb); dev_queue_xmit(skb); - self->stats.tx_packets++; } /* @@ -169,7 +170,7 @@ static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb, /* Check if the new connection address is valid */ if ((info->caddr == 0x00) || (info->caddr == 0xfe)) { - DEBUG(3, __FUNCTION__ + IRDA_DEBUG(3, __FUNCTION__ "(), invalid connection address!\n"); dev_kfree_skb(skb); return; @@ -181,7 +182,7 @@ static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb, /* Only accept if addressed directly to us */ if (info->saddr != self->saddr) { - DEBUG(2, __FUNCTION__ "(), not addressed to us!\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), not addressed to us!\n"); dev_kfree_skb(skb); return; } @@ -203,7 +204,7 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos) struct ua_frame *frame; int ret; - DEBUG(2, __FUNCTION__ "() <%ld>\n", jiffies); + IRDA_DEBUG(2, __FUNCTION__ "() <%ld>\n", jiffies); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -280,7 +281,7 @@ void irlap_send_disc_frame(struct irlap_cb *self) struct sk_buff *skb = NULL; __u8 *frame; - DEBUG(3, __FUNCTION__ "()\n"); + IRDA_DEBUG(3, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -312,7 +313,7 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s, __u32 bcast = BROADCAST; __u8 *info; - DEBUG(4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S, command); + IRDA_DEBUG(4, __FUNCTION__ "(), s=%d, S=%d, command=%d\n", s, S, command); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -404,7 +405,7 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, __u8 *discovery_info; char *text; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -417,7 +418,7 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, /* 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"); + IRDA_DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n"); return; } @@ -431,14 +432,14 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, discovery->saddr = self->saddr; discovery->timestamp = jiffies; - DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", discovery->daddr); + IRDA_DEBUG(4, __FUNCTION__ "(), daddr=%08x\n", discovery->daddr); discovery_info = skb_pull(skb, sizeof(struct xid_frame)); /* Get info returned from peer */ discovery->hints.byte[0] = discovery_info[0]; if (discovery_info[0] & HINT_EXTENSION) { - DEBUG(4, "EXTENSION\n"); + IRDA_DEBUG(4, "EXTENSION\n"); discovery->hints.byte[1] = discovery_info[1]; discovery->charset = discovery_info[2]; text = (char *) &discovery_info[3]; @@ -482,7 +483,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, /* 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"); + IRDA_DEBUG(0, __FUNCTION__ "(), frame is not addressed to us!\n"); dev_kfree_skb(skb); return; } @@ -619,7 +620,7 @@ void irlap_send_frmr_frame( struct irlap_cb *self, int command) frame[2] = 0; - DEBUG( 4, __FUNCTION__ "(), vr=%d, %ld\n",self->vr, jiffies); + IRDA_DEBUG( 4, __FUNCTION__ "(), vr=%d, %ld\n",self->vr, jiffies); irlap_queue_xmit(self, skb); } @@ -641,7 +642,7 @@ static void irlap_recv_rnr_frame( struct irlap_cb *self, struct sk_buff *skb, frame = skb->data; info->nr = frame[1] >> 5; - DEBUG( 4, __FUNCTION__ "(), nr=%d, %ld\n", info->nr, jiffies); + IRDA_DEBUG( 4, __FUNCTION__ "(), nr=%d, %ld\n", info->nr, jiffies); irlap_do_event( self, RECV_RNR_FRAME, skb, info); } @@ -700,7 +701,7 @@ void irlap_send_data_primary(struct irlap_cb *self, struct sk_buff *skb) irlap_send_i_frame( self, tx_skb, CMD_FRAME); } else { - DEBUG( 4, __FUNCTION__ "(), sending unreliable frame\n"); + IRDA_DEBUG( 4, __FUNCTION__ "(), sending unreliable frame\n"); irlap_send_ui_frame(self, skb, CMD_FRAME); self->window -= 1; } @@ -759,7 +760,7 @@ void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb) irlap_send_i_frame(self, tx_skb, CMD_FRAME); } else { - DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), sending unreliable frame\n"); del_timer(&self->poll_timer); @@ -959,7 +960,7 @@ void irlap_resend_rejected_frames(struct irlap_cb *self, int command) while (skb_queue_len( &self->tx_list) > 0) { - DEBUG(0, __FUNCTION__ "(), sending additional frames!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), sending additional frames!\n"); if ((skb_queue_len( &self->tx_list) > 0) && (self->window > 0)) { skb = skb_dequeue( &self->tx_list); @@ -991,7 +992,7 @@ void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb, { __u8 *frame; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -1056,7 +1057,7 @@ static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb, { __u8 *frame; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); frame = skb->data; @@ -1077,7 +1078,7 @@ static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb, __u8 *frame; int w, x, y, z; - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LAP_MAGIC, return;); @@ -1096,20 +1097,20 @@ static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb, z = frame[3] & 0x08; if (w) { - DEBUG(0, "Rejected control field is undefined or not " + IRDA_DEBUG(0, "Rejected control field is undefined or not " "implemented.\n"); } if (x) { - DEBUG(0, "Rejected control field was invalid because it " + IRDA_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 " + IRDA_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 " + IRDA_DEBUG(0, "Rejected control field control field contained an " "invalid Nr count.\n"); } irlap_do_event(self, RECV_FRMR_RSP, skb, info); @@ -1168,10 +1169,10 @@ void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb, { struct test_frame *frame; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); if (skb->len < sizeof(struct test_frame)) { - DEBUG(0, __FUNCTION__ "() test frame to short!\n"); + IRDA_DEBUG(0, __FUNCTION__ "() test frame to short!\n"); return; } @@ -1205,12 +1206,11 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, { struct irlap_info info; struct irlap_cb *self; - struct irda_device *idev; int command; __u8 control; - idev = (struct irda_device *) dev->priv; - self = idev->irlap; + /* FIXME: should we get our own field? */ + self = (struct irlap_cb *) dev->atalk_ptr; /* If the net device is down, then IrLAP is gone! */ if (!self || self->magic != LAP_MAGIC) { @@ -1235,7 +1235,7 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, /* First we check if this frame has a valid connection address */ if ((info.caddr != self->caddr) && (info.caddr != CBROADCAST)) { - DEBUG(0, __FUNCTION__ "(), wrong connection address!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), wrong connection address!\n"); dev_kfree_skb(skb); return 0; } @@ -1245,7 +1245,6 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, */ if (~control & 0x01) { irlap_recv_i_frame(self, skb, &info, command); - self->stats.rx_packets++; return 0; } /* @@ -1260,17 +1259,15 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, switch (control & 0x0f) { case RR: irlap_recv_rr_frame(self, skb, &info, command); - self->stats.rx_packets++; break; case RNR: irlap_recv_rnr_frame(self, skb, &info); - self->stats.rx_packets++; break; case REJ: - DEBUG( 0, "*** REJ frame received! ***\n"); + IRDA_DEBUG( 0, "*** REJ frame received! ***\n"); break; case SREJ: - DEBUG( 0, "*** SREJ frame received! ***\n"); + IRDA_DEBUG( 0, "*** SREJ frame received! ***\n"); break; default: WARNING(__FUNCTION__ @@ -1294,7 +1291,7 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, irlap_recv_snrm_cmd(self, skb, &info); break; case DM_RSP: - DEBUG( 0, "DM rsp frame received!\n"); + IRDA_DEBUG( 0, "DM rsp frame received!\n"); irlap_next_state(self, LAP_NDM); break; case DISC_CMD: @@ -1310,7 +1307,6 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, irlap_recv_frmr_frame(self, skb, &info); break; case UI_FRAME: - DEBUG(4, "UI-frame received!\n"); irlap_recv_ui_frame(self, skb, &info); break; default: @@ -1319,7 +1315,5 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev, dev_kfree_skb( skb); break; } - self->stats.rx_packets++; - return 0; } diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 8b63351ed..bd2f906f9 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -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 Sep 27 11:15:20 1999 + * Modified at: Sat Oct 9 17:00:49 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -32,7 +32,6 @@ #include <linux/init.h> #include <linux/kmod.h> #include <linux/random.h> -#include <linux/irda.h> #include <net/irda/irda.h> #include <net/irda/irmod.h> @@ -189,7 +188,7 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify) /* * Insert into queue of unconnected LSAPs */ - hashbin_insert(irlmp->unconnected_lsaps, (QUEUE *) self, (int) self, + hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) self, (int) self, NULL); return self; @@ -202,7 +201,7 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify) */ static void __irlmp_close_lsap(struct lsap_cb *self) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LSAP_MAGIC, return;); @@ -249,7 +248,7 @@ void irlmp_close_lsap(struct lsap_cb *self) NULL); } if (!lsap) { - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ "(), Looks like somebody has removed me already!\n"); return; } @@ -294,7 +293,7 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) /* * Insert into queue of unconnected LSAPs */ - hashbin_insert(irlmp->links, (QUEUE *) lap, lap->saddr, NULL); + hashbin_insert(irlmp->links, (queue_t *) lap, lap->saddr, NULL); /* * We set only this variable so IrLAP can tell us on which link the @@ -314,7 +313,7 @@ void irlmp_unregister_link(__u32 saddr) { struct lap_cb *link; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); link = hashbin_remove(irlmp->links, saddr, NULL); if (link) { @@ -348,7 +347,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, ASSERT(self != NULL, return -EBADR;); ASSERT(self->magic == LMP_LSAP_MAGIC, return -EBADR;); - DEBUG(2, __FUNCTION__ + IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x, saddr=%08x, daddr=%08x\n", self->slsap_sel, dlsap_sel, saddr, daddr); @@ -391,14 +390,14 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, } lap = hashbin_find(irlmp->links, saddr, NULL); if (lap == NULL) { - DEBUG(1, __FUNCTION__ "(), Unable to find a usable link!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unable to find a usable link!\n"); return -EHOSTUNREACH; } if (lap->daddr == DEV_ADDR_ANY) lap->daddr = daddr; else if (lap->daddr != daddr) { - DEBUG(0, __FUNCTION__ "(), sorry, but link is busy!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), sorry, but link is busy!\n"); return -EBUSY; } @@ -415,7 +414,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, ASSERT(lsap->lap != NULL, return -1;); ASSERT(lsap->lap->magic == LMP_LAP_MAGIC, return -1;); - hashbin_insert(self->lap->lsaps, (QUEUE *) self, (int) self, NULL); + hashbin_insert(self->lap->lsaps, (queue_t *) self, (int) self, NULL); self->connected = TRUE; @@ -447,19 +446,19 @@ void irlmp_connect_indication(struct lsap_cb *self, struct sk_buff *skb) ASSERT(skb != NULL, return;); ASSERT(self->lap != NULL, return;); - DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", + IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", self->slsap_sel, self->dlsap_sel); 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); + IRDA_DEBUG(2, __FUNCTION__ "(), max_seg_size=%d\n", max_seg_size); - lap_header_size = irlap_get_header_size(self->lap->irlap); + 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); + IRDA_DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", max_header_size); /* Hide LMP_CONTROL_HEADER header from layer above */ skb_pull(skb, LMP_CONTROL_HEADER); @@ -484,7 +483,7 @@ int irlmp_connect_response(struct lsap_cb *self, struct sk_buff *userdata) self->connected = TRUE; - DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", + IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", self->slsap_sel, self->dlsap_sel); /* Make room for MUX control header ( 3 bytes) */ @@ -507,7 +506,7 @@ void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb) int lap_header_size; int max_seg_size; - DEBUG(3, __FUNCTION__ "()\n"); + IRDA_DEBUG(3, __FUNCTION__ "()\n"); ASSERT(skb != NULL, return;); ASSERT(self != NULL, return;); @@ -517,10 +516,10 @@ void irlmp_connect_confirm(struct lsap_cb *self, struct sk_buff *skb) self->qos = *self->lap->qos; max_seg_size = self->lap->qos->data_size.value-LMP_HEADER; - lap_header_size = irlap_get_header_size(self->lap->irlap); + 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); + IRDA_DEBUG(2, __FUNCTION__ "(), max_header_size=%d\n", max_header_size); /* Hide LMP_CONTROL_HEADER header from layer above */ skb_pull(skb, LMP_CONTROL_HEADER); @@ -543,16 +542,16 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) { struct lsap_cb *new; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); /* Only allowed to duplicate unconnected LSAP's */ if (!hashbin_find(irlmp->unconnected_lsaps, (int) orig, NULL)) { - DEBUG(0, __FUNCTION__ "(), unable to find LSAP\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), unable to find LSAP\n"); return NULL; } new = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC); if (!new) { - DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n"); return NULL; } /* Dup */ @@ -561,7 +560,7 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance) init_timer(&new->watchdog_timer); - hashbin_insert(irlmp->unconnected_lsaps, (QUEUE *) new, (int) new, + hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) new, (int) new, NULL); /* Make sure that we invalidate the cache */ @@ -616,7 +615,7 @@ int irlmp_disconnect_request(struct lsap_cb *self, struct sk_buff *userdata) ASSERT(lsap->magic == LMP_LSAP_MAGIC, return -1;); ASSERT(lsap == self, return -1;); - hashbin_insert(irlmp->unconnected_lsaps, (QUEUE *) self, (int) self, + hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) self, (int) self, NULL); /* Reset some values */ @@ -637,13 +636,13 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, { struct lsap_cb *lsap; - DEBUG(1, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]); + IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lmp_reasons[reason]); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LSAP_MAGIC, return;); ASSERT(self->connected == TRUE, return;); - DEBUG(3, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", + IRDA_DEBUG(3, __FUNCTION__ "(), slsap_sel=%02x, dlsap_sel=%02x\n", self->slsap_sel, self->dlsap_sel); self->connected = FALSE; @@ -663,7 +662,7 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, ASSERT(lsap != NULL, return;); ASSERT(lsap == self, return;); - hashbin_insert(irlmp->unconnected_lsaps, (QUEUE *) lsap, (int) lsap, + hashbin_insert(irlmp->unconnected_lsaps, (queue_t *) lsap, (int) lsap, NULL); self->lap = NULL; @@ -691,7 +690,7 @@ void irlmp_do_discovery(int nslots) if ((nslots != 1) && (nslots != 6) && (nslots != 8) && (nslots != 16)) { - printk(KERN_WARNING __FUNCTION__ + WARNING(__FUNCTION__ "(), invalid value for number of slots!\n"); nslots = sysctl_discovery_slots = 8; } @@ -768,8 +767,8 @@ void irlmp_check_services(discovery_t *discovery) __u8 service; int i = 0; - DEBUG(1, "IrDA Discovered: %s\n", discovery->info); - DEBUG(1, " Services: "); + IRDA_DEBUG(1, "IrDA Discovered: %s\n", discovery->info); + IRDA_DEBUG(1, " Services: "); service_log = irlmp_hint_to_service(discovery->hints.byte); if (!service_log) @@ -779,10 +778,10 @@ void irlmp_check_services(discovery_t *discovery) * Check all services on the device */ while ((service = service_log[i++]) != S_END) { - DEBUG( 4, "service=%02x\n", service); + IRDA_DEBUG( 4, "service=%02x\n", service); client = hashbin_find(irlmp->registry, service, NULL); if (entry && entry->discovery_callback) { - DEBUG( 4, "discovery_callback!\n"); + IRDA_DEBUG( 4, "discovery_callback!\n"); entry->discovery_callback(discovery); } else { @@ -814,7 +813,7 @@ void irlmp_notify_client(irlmp_client_t *client, hashbin_t *log) { discovery_t *discovery; - DEBUG(3, __FUNCTION__ "()\n"); + IRDA_DEBUG(3, __FUNCTION__ "()\n"); /* Check if client wants the whole log */ if (client->callback2) @@ -826,7 +825,7 @@ void irlmp_notify_client(irlmp_client_t *client, hashbin_t *log) */ discovery = (discovery_t *) hashbin_get_first(log); while (discovery != NULL) { - DEBUG(3, "discovery->daddr = 0x%08x\n", discovery->daddr); + IRDA_DEBUG(3, "discovery->daddr = 0x%08x\n", discovery->daddr); /* * Any common hint bits? Remember to mask away the extension @@ -851,11 +850,11 @@ void irlmp_discovery_confirm(hashbin_t *log) { irlmp_client_t *client; - DEBUG(3, __FUNCTION__ "()\n"); + IRDA_DEBUG(3, __FUNCTION__ "()\n"); ASSERT(log != NULL, return;); - if (!hashbin_get_size(log)) + if (!(HASHBIN_GET_SIZE(log))) return; client = (irlmp_client_t *) hashbin_get_first(irlmp->clients); @@ -875,7 +874,7 @@ void irlmp_discovery_confirm(hashbin_t *log) */ discovery_t *irlmp_get_discovery_response() { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(irlmp != NULL, return NULL;); @@ -936,7 +935,7 @@ inline void irlmp_data_indication(struct lsap_cb *self, struct sk_buff *skb) */ inline void irlmp_udata_request(struct lsap_cb *self, struct sk_buff *skb) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(skb != NULL, return;); @@ -955,7 +954,7 @@ inline void irlmp_udata_request(struct lsap_cb *self, struct sk_buff *skb) */ void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LSAP_MAGIC, return;); @@ -976,7 +975,7 @@ void irlmp_udata_indication(struct lsap_cb *self, struct sk_buff *skb) */ void irlmp_connectionless_data_request( struct sk_buff *skb) { - DEBUG( 1, __FUNCTION__ "(), Sorry not implemented\n"); + IRDA_DEBUG( 1, __FUNCTION__ "(), Sorry not implemented\n"); } /* @@ -987,17 +986,17 @@ void irlmp_connectionless_data_request( struct sk_buff *skb) */ void irlmp_connectionless_data_indication(struct sk_buff *skb) { - DEBUG( 1, __FUNCTION__ "()\n"); + IRDA_DEBUG( 1, __FUNCTION__ "()\n"); } void irlmp_status_request(void) { - DEBUG(0, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n"); } void irlmp_status_indication(LINK_STATUS link, LOCK_STATUS lock) { - DEBUG(1, __FUNCTION__ "(), Not implemented\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Not implemented\n"); } /* @@ -1017,31 +1016,31 @@ __u8 *irlmp_hint_to_service(__u8 *hint) */ service = kmalloc(16, GFP_ATOMIC); if (!service) { - DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n"); return NULL; } if (!hint[0]) { - DEBUG(1, "<None>\n"); + IRDA_DEBUG(1, "<None>\n"); kfree(service); return NULL; } if (hint[0] & HINT_PNP) - DEBUG(1, "PnP Compatible "); + IRDA_DEBUG(1, "PnP Compatible "); if (hint[0] & HINT_PDA) - DEBUG(1, "PDA/Palmtop "); + IRDA_DEBUG(1, "PDA/Palmtop "); if (hint[0] & HINT_COMPUTER) - DEBUG(1, "Computer "); + IRDA_DEBUG(1, "Computer "); if (hint[0] & HINT_PRINTER) { - DEBUG(1, "Printer "); + IRDA_DEBUG(1, "Printer "); service[i++] = S_PRINTER; } if (hint[0] & HINT_MODEM) - DEBUG(1, "Modem "); + IRDA_DEBUG(1, "Modem "); if (hint[0] & HINT_FAX) - DEBUG(1, "Fax "); + IRDA_DEBUG(1, "Fax "); if (hint[0] & HINT_LAN) { - DEBUG(1, "LAN Access "); + IRDA_DEBUG(1, "LAN Access "); service[i++] = S_LAN; } /* @@ -1051,21 +1050,21 @@ __u8 *irlmp_hint_to_service(__u8 *hint) */ if (hint[0] & HINT_EXTENSION) { if (hint[1] & HINT_TELEPHONY) { - DEBUG(1, "Telephony "); + IRDA_DEBUG(1, "Telephony "); service[i++] = S_TELEPHONY; } if (hint[1] & HINT_FILE_SERVER) - DEBUG(1, "File Server "); + IRDA_DEBUG(1, "File Server "); if (hint[1] & HINT_COMM) { - DEBUG(1, "IrCOMM "); + IRDA_DEBUG(1, "IrCOMM "); service[i++] = S_COMM; } if (hint[1] & HINT_OBEX) { - DEBUG(1, "IrOBEX "); + IRDA_DEBUG(1, "IrOBEX "); service[i++] = S_OBEX; } } - DEBUG(1, "\n"); + IRDA_DEBUG(1, "\n"); /* So that client can be notified about any discovery */ service[i++] = S_ANY; @@ -1123,7 +1122,7 @@ __u16 irlmp_service_to_hint(int service) hint.word = 0xffff; break; default: - DEBUG( 1, __FUNCTION__ "(), Unknown service!\n"); + IRDA_DEBUG( 1, __FUNCTION__ "(), Unknown service!\n"); break; } return hint.word; @@ -1140,7 +1139,7 @@ __u32 irlmp_register_service(__u16 hints) irlmp_service_t *service; __u32 handle; - DEBUG(4, __FUNCTION__ "(), hints = %04x\n", hints); + IRDA_DEBUG(4, __FUNCTION__ "(), hints = %04x\n", hints); /* Get a unique handle for this service */ get_random_bytes(&handle, sizeof(handle)); @@ -1152,11 +1151,11 @@ __u32 irlmp_register_service(__u16 hints) /* Make a new registration */ service = kmalloc(sizeof(irlmp_service_t), GFP_ATOMIC); if (!service) { - DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unable to kmalloc!\n"); return 0; } service->hints = hints; - hashbin_insert(irlmp->services, (QUEUE*) service, handle, NULL); + hashbin_insert(irlmp->services, (queue_t *) service, handle, NULL); return handle; } @@ -1172,14 +1171,14 @@ int irlmp_unregister_service(__u32 handle) { irlmp_service_t *service; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); if (!handle) return -1; service = hashbin_find(irlmp->services, handle, NULL); if (!service) { - DEBUG(1, __FUNCTION__ "(), Unknown service!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown service!\n"); return -1; } @@ -1221,7 +1220,7 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 callback1, /* Make a new registration */ client = kmalloc(sizeof(irlmp_client_t), GFP_ATOMIC); if (!client) { - DEBUG( 1, __FUNCTION__ "(), Unable to kmalloc!\n"); + IRDA_DEBUG( 1, __FUNCTION__ "(), Unable to kmalloc!\n"); return 0; } @@ -1231,7 +1230,7 @@ __u32 irlmp_register_client(__u16 hint_mask, DISCOVERY_CALLBACK1 callback1, client->callback1 = callback1; client->callback2 = callback2; - hashbin_insert(irlmp->clients, (QUEUE *) client, handle, NULL); + hashbin_insert(irlmp->clients, (queue_t *) client, handle, NULL); return handle; } @@ -1255,7 +1254,7 @@ int irlmp_update_client(__u32 handle, __u16 hint_mask, client = hashbin_find(irlmp->clients, handle, NULL); if (!client) { - DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); return -1; } @@ -1276,18 +1275,18 @@ int irlmp_unregister_client(__u32 handle) { struct irlmp_client *client; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); if (!handle) return -1; client = hashbin_find(irlmp->clients, handle, NULL); if (!client) { - DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown client!\n"); return -1; } - DEBUG( 4, __FUNCTION__ "(), removing client!\n"); + IRDA_DEBUG( 4, __FUNCTION__ "(), removing client!\n"); client = hashbin_remove( irlmp->clients, handle, NULL); if (client) kfree(client); @@ -1309,7 +1308,7 @@ int irlmp_slsap_inuse(__u8 slsap_sel) ASSERT(irlmp->magic == LMP_MAGIC, return TRUE;); ASSERT(slsap_sel != LSAP_ANY, return TRUE;); - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Valid values are between 0 and 127 */ if (slsap_sel > 127) @@ -1329,7 +1328,7 @@ int irlmp_slsap_inuse(__u8 slsap_sel) ASSERT(self->magic == LMP_LSAP_MAGIC, return TRUE;); if ((self->slsap_sel == slsap_sel)) { - DEBUG(4, "Source LSAP selector=%02x in use\n", + IRDA_DEBUG(4, "Source LSAP selector=%02x in use\n", self->slsap_sel); return TRUE; } @@ -1369,7 +1368,7 @@ __u8 irlmp_find_free_slsap(void) return 0; } } - DEBUG(4, __FUNCTION__ "(), next free lsap_sel=%02x\n", lsap_sel); + IRDA_DEBUG(4, __FUNCTION__ "(), next free lsap_sel=%02x\n", lsap_sel); return lsap_sel; } @@ -1387,25 +1386,25 @@ LM_REASON irlmp_convert_lap_reason( LAP_REASON lap_reason) switch (lap_reason) { case LAP_DISC_INDICATION: /* Received a disconnect request from peer */ - DEBUG( 1, __FUNCTION__ "(), LAP_DISC_INDICATION\n"); + IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_DISC_INDICATION\n"); reason = LM_USER_REQUEST; break; case LAP_NO_RESPONSE: /* To many retransmits without response */ - DEBUG( 1, __FUNCTION__ "(), LAP_NO_RESPONSE\n"); + IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_NO_RESPONSE\n"); reason = LM_LAP_DISCONNECT; break; case LAP_RESET_INDICATION: - DEBUG( 1, __FUNCTION__ "(), LAP_RESET_INDICATION\n"); + IRDA_DEBUG( 1, __FUNCTION__ "(), LAP_RESET_INDICATION\n"); reason = LM_LAP_RESET; break; case LAP_FOUND_NONE: case LAP_MEDIA_BUSY: case LAP_PRIMARY_CONFLICT: - DEBUG(1, __FUNCTION__ "(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), LAP_FOUND_NONE, LAP_MEDIA_BUSY or LAP_PRIMARY_CONFLICT\n"); reason = LM_CONNECT_FAILURE; break; default: - DEBUG(1, __FUNCTION__ + IRDA_DEBUG(1, __FUNCTION__ "(), Unknow IrLAP disconnect reason %d!\n", lap_reason); reason = LM_LAP_DISCONNECT; break; diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c index ee41e54f4..122affe25 100644 --- a/net/irda/irlmp_event.c +++ b/net/irda/irlmp_event.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Aug 4 20:40:53 1997 - * Modified at: Tue Sep 21 13:04:33 1999 + * Modified at: Tue Oct 5 13:47:53 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -120,7 +120,7 @@ int irlmp_do_lsap_event(struct lsap_cb *self, IRLMP_EVENT event, ASSERT(self != NULL, return -1;); ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); - DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n", + IRDA_DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n", irlmp_event[ event], irlmp_state[ self->lsap_state]); return (*lsap_state[self->lsap_state]) (self, event, skb); @@ -138,7 +138,7 @@ void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event, ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LAP_MAGIC, return;); - DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n", + IRDA_DEBUG(4, __FUNCTION__ "(), EVENT = %s, STATE = %s\n", irlmp_event[event], irlmp_state[self->lap_state]); @@ -147,7 +147,7 @@ void irlmp_do_lap_event(struct lap_cb *self, IRLMP_EVENT event, void irlmp_discovery_timer_expired(void *data) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); if (sysctl_discovery) irlmp_do_discovery(sysctl_discovery_slots); @@ -160,7 +160,7 @@ void irlmp_watchdog_timer_expired(void *data) { struct lsap_cb *self = (struct lsap_cb *) data; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LSAP_MAGIC, return;); @@ -172,7 +172,7 @@ void irlmp_idle_timer_expired(void *data) { struct lap_cb *self = (struct lap_cb *) data; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LAP_MAGIC, return;); @@ -195,7 +195,7 @@ 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"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self->irlap != NULL, return;); switch (event) { @@ -219,7 +219,7 @@ static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event, irlap_connect_response(self->irlap, skb); break; case LM_LAP_CONNECT_REQUEST: - DEBUG(4, __FUNCTION__ "() LS_CONNECT_REQUEST\n"); + IRDA_DEBUG(4, __FUNCTION__ "() LS_CONNECT_REQUEST\n"); /* FIXME: need to set users requested QoS */ irlap_connect_request(self->irlap, self->daddr, NULL, 0); @@ -227,13 +227,13 @@ static void irlmp_state_standby(struct lap_cb *self, IRLMP_EVENT event, irlmp_next_lap_state(self, LAP_U_CONNECT); break; case LM_LAP_DISCONNECT_INDICATION: - DEBUG(4, __FUNCTION__ + IRDA_DEBUG(4, __FUNCTION__ "(), Error LM_LAP_DISCONNECT_INDICATION\n"); irlmp_next_lap_state( self, LAP_STANDBY); break; default: - DEBUG(4, __FUNCTION__ "(), Unknown event\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event\n"); break; } } @@ -251,7 +251,7 @@ 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]); + IRDA_DEBUG(2, __FUNCTION__ "(), event=%s\n", irlmp_event[event]); switch (event) { case LM_LAP_CONNECT_CONFIRM: @@ -265,7 +265,7 @@ static void irlmp_state_u_connect( struct lap_cb *self, IRLMP_EVENT event, } break; case LM_LAP_DISCONNECT_INDICATION: - DEBUG(2, __FUNCTION__ "(), IRLAP_DISCONNECT_INDICATION\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), IRLAP_DISCONNECT_INDICATION\n"); irlmp_next_lap_state(self, LAP_STANDBY); @@ -285,7 +285,7 @@ static void irlmp_state_u_connect( struct lap_cb *self, IRLMP_EVENT event, } break; case LM_LAP_DISCONNECT_REQUEST: - DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), LM_LAP_DISCONNECT_REQUEST\n"); irlmp_next_lap_state(self, LAP_STANDBY); @@ -293,7 +293,7 @@ static void irlmp_state_u_connect( struct lap_cb *self, IRLMP_EVENT event, /* irlap_disconnect_request( self->irlap); */ break; default: - DEBUG(4, __FUNCTION__ "(), Unknown event\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event\n"); break; } } @@ -310,11 +310,11 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, struct lsap_cb *lsap; struct lsap_cb *lsap_current; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); switch( event) { case LM_LAP_CONNECT_REQUEST: - DEBUG( 4, __FUNCTION__ "(), LS_CONNECT_REQUEST\n"); + IRDA_DEBUG( 4, __FUNCTION__ "(), LS_CONNECT_REQUEST\n"); /* * LAP connection allready active, just bounce back! Since we @@ -347,7 +347,7 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, * must be the one that tries to close IrLAP. It will be * removed later and moved to the list of unconnected LSAPs */ - if (hashbin_get_size(self->lsaps) > 0) + if (HASHBIN_GET_SIZE(self->lsaps) > 0) irlmp_start_idle_timer(self, LM_IDLE_TIMEOUT); else { /* No more connections, so close IrLAP */ @@ -356,7 +356,7 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, } break; case LM_LAP_IDLE_TIMEOUT: - if (hashbin_get_size(self->lsaps) == 0) { + if (HASHBIN_GET_SIZE(self->lsaps) == 0) { irlmp_next_lap_state(self, LAP_STANDBY); irlap_disconnect_request(self->irlap); } @@ -381,7 +381,7 @@ static void irlmp_state_active(struct lap_cb *self, IRLMP_EVENT event, } break; default: - DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); break; } } @@ -403,14 +403,14 @@ static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event, { int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); switch (event) { case LM_CONNECT_REQUEST: - DEBUG(4, __FUNCTION__ "(), LM_CONNECT_REQUEST\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), LM_CONNECT_REQUEST\n"); irlmp_next_lsap_state(self, LSAP_SETUP_PEND); irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, NULL); @@ -424,7 +424,7 @@ static int irlmp_state_disconnected(struct lsap_cb *self, IRLMP_EVENT event, irlmp_do_lap_event(self->lap, LM_LAP_CONNECT_REQUEST, skb); break; default: - DEBUG( 4, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG( 4, __FUNCTION__ "(), Unknown event %d\n", event); break; } return ret; @@ -442,7 +442,7 @@ static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event, struct lsap_cb *lsap; int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); @@ -460,7 +460,7 @@ static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event, ASSERT(self->lap != NULL, return -1;); ASSERT(self->lap->lsaps != NULL, return -1;); - hashbin_insert(self->lap->lsaps, (QUEUE *) self, (int) self, + hashbin_insert(self->lap->lsaps, (queue_t *) self, (int) self, NULL); irlmp_send_lcf_pdu(self->lap, self->dlsap_sel, @@ -471,7 +471,7 @@ static int irlmp_state_connect(struct lsap_cb *self, IRLMP_EVENT event, irlmp_next_lsap_state(self, LSAP_DATA_TRANSFER_READY); break; default: - DEBUG( 4, __FUNCTION__ "(), Unknown event\n"); + IRDA_DEBUG( 4, __FUNCTION__ "(), Unknown event\n"); break; } return ret; @@ -488,7 +488,7 @@ static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event, { int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); @@ -498,22 +498,22 @@ static int irlmp_state_connect_pend(struct lsap_cb *self, IRLMP_EVENT event, /* Keep state */ break; case LM_CONNECT_RESPONSE: - DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, " + IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, " "no indication issued yet\n"); /* Keep state */ break; case LM_DISCONNECT_REQUEST: - DEBUG(0, __FUNCTION__ "(), LM_DISCONNECT_REQUEST, " + IRDA_DEBUG(0, __FUNCTION__ "(), LM_DISCONNECT_REQUEST, " "not yet bound to IrLAP connection\n"); /* Keep state */ break; case LM_LAP_CONNECT_CONFIRM: - DEBUG(4, __FUNCTION__ "(), LS_CONNECT_CONFIRM\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), LS_CONNECT_CONFIRM\n"); irlmp_next_lsap_state(self, LSAP_CONNECT); irlmp_connect_indication(self, skb); break; default: - DEBUG( 4, __FUNCTION__ "Unknown event %d\n", event); + IRDA_DEBUG( 4, __FUNCTION__ "Unknown event %d\n", event); break; } return ret; @@ -531,7 +531,7 @@ static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event, LM_REASON reason; int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); @@ -557,12 +557,12 @@ static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event, /* irlmp_next_lsap_state( DATA_TRANSFER_READY, info->handle);*/ break; case LM_CONNECT_REQUEST: - DEBUG(0, __FUNCTION__ "(), LM_CONNECT_REQUEST, " + IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_REQUEST, " "error, LSAP already connected\n"); /* Keep state */ break; case LM_CONNECT_RESPONSE: - DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, " + IRDA_DEBUG(0, __FUNCTION__ "(), LM_CONNECT_RESPONSE, " "error, LSAP allready connected\n"); /* Keep state */ break; @@ -573,7 +573,7 @@ static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event, /* Try to close the LAP connection if its still there */ if (self->lap) { - DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n"); irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL); @@ -597,13 +597,13 @@ static int irlmp_state_dtr(struct lsap_cb *self, IRLMP_EVENT event, reason = skb->data[3]; /* Try to close the LAP connection */ - DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n"); + IRDA_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; default: - DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); break; } return ret; @@ -625,7 +625,7 @@ static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event, ASSERT(self != NULL, return -1;); ASSERT(self->magic == LMP_LSAP_MAGIC, return -1;); - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); switch (event) { case LM_CONNECT_CONFIRM: @@ -646,7 +646,7 @@ static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event, reason = skb->data[3]; /* Try to close the LAP connection */ - DEBUG(4, __FUNCTION__ "(), trying to close IrLAP\n"); + IRDA_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); @@ -664,7 +664,7 @@ static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event, irlmp_disconnect_indication(self, reason, skb); break; case LM_WATCHDOG_TIMEOUT: - DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n"); + IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n"); ASSERT(self->lap != NULL, return -1;); irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL); @@ -673,7 +673,7 @@ static int irlmp_state_setup(struct lsap_cb *self, IRLMP_EVENT event, irlmp_disconnect_indication(self, LM_CONNECT_FAILURE, NULL); break; default: - DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); break; } return ret; @@ -693,7 +693,7 @@ static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event, LM_REASON reason; int ret = 0; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(irlmp != NULL, return -1;); @@ -706,7 +706,7 @@ static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event, irlmp_next_lsap_state(self, LSAP_SETUP); break; case LM_WATCHDOG_TIMEOUT: - DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n"); + IRDA_DEBUG(0, __FUNCTION__ "() WATCHDOG_TIMEOUT!\n"); ASSERT(self->lap != NULL, return -1;); irlmp_do_lap_event(self->lap, LM_LAP_DISCONNECT_REQUEST, NULL); @@ -724,7 +724,7 @@ static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event, irlmp_disconnect_indication(self, reason, NULL); break; default: - DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); + IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event); break; } return ret; @@ -732,7 +732,7 @@ static int irlmp_state_setup_pend(struct lsap_cb *self, IRLMP_EVENT event, void irlmp_next_lap_state(struct lap_cb *self, IRLMP_STATE state) { - DEBUG(4, __FUNCTION__ "(), LMP LAP = %s\n", irlmp_state[state]); + IRDA_DEBUG(4, __FUNCTION__ "(), LMP LAP = %s\n", irlmp_state[state]); self->lap_state = state; } @@ -740,6 +740,6 @@ void irlmp_next_lsap_state(struct lsap_cb *self, LSAP_STATE state) { ASSERT(self != NULL, return;); - DEBUG(4, __FUNCTION__ "(), LMP LSAP = %s\n", irlsap_state[state]); + IRDA_DEBUG(4, __FUNCTION__ "(), LMP LSAP = %s\n", irlsap_state[state]); self->lsap_state = state; } diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c index 135f82752..7a71005bf 100644 --- a/net/irda/irlmp_frame.c +++ b/net/irda/irlmp_frame.c @@ -44,7 +44,7 @@ inline void irlmp_send_data_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, skb->data[1] = slsap; if (expedited) { - DEBUG(4, __FUNCTION__ "(), sending expedited data\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), sending expedited data\n"); irlap_data_request(self->irlap, skb, FALSE); } else irlap_data_request(self->irlap, skb, TRUE); @@ -60,7 +60,7 @@ void irlmp_send_lcf_pdu(struct lap_cb *self, __u8 dlsap, __u8 slsap, { __u8 *frame; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LAP_MAGIC, return;); @@ -114,7 +114,7 @@ void irlmp_link_data_indication(struct lap_cb *self, int reliable, * it in a different way than other established connections. */ if ((fp[0] & CONTROL_BIT) && (fp[2] == CONNECT_CMD)) { - DEBUG(3,"Incoming connection, source LSAP=%d, dest LSAP=%d\n", + IRDA_DEBUG(3,"Incoming connection, source LSAP=%d, dest LSAP=%d\n", slsap_sel, dlsap_sel); /* Try to find LSAP among the unconnected LSAPs */ @@ -130,15 +130,15 @@ void irlmp_link_data_indication(struct lap_cb *self, int reliable, self->lsaps); if (lsap == NULL) { - DEBUG(2, "IrLMP, Sorry, no LSAP for received frame!\n"); - DEBUG(2, __FUNCTION__ + IRDA_DEBUG(2, "IrLMP, Sorry, no LSAP for received frame!\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), slsap_sel = %02x, dlsap_sel = %02x\n", slsap_sel, dlsap_sel); if (fp[0] & CONTROL_BIT) { - DEBUG(2, __FUNCTION__ + IRDA_DEBUG(2, __FUNCTION__ "(), received control frame %02x\n", fp[2]); } else { - DEBUG(2, __FUNCTION__ "(), received data frame\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), received data frame\n"); } dev_kfree_skb(skb); return; @@ -157,18 +157,18 @@ void irlmp_link_data_indication(struct lap_cb *self, int reliable, irlmp_do_lsap_event(lsap, LM_CONNECT_CONFIRM, skb); break; case DISCONNECT: - DEBUG( 4, __FUNCTION__ "(), Disconnect indication!\n"); + IRDA_DEBUG( 4, __FUNCTION__ "(), Disconnect indication!\n"); irlmp_do_lsap_event(lsap, LM_DISCONNECT_INDICATION, skb); break; case ACCESSMODE_CMD: - DEBUG( 0, "Access mode cmd not implemented!\n"); + IRDA_DEBUG( 0, "Access mode cmd not implemented!\n"); break; case ACCESSMODE_CNF: - DEBUG( 0, "Access mode cnf not implemented!\n"); + IRDA_DEBUG( 0, "Access mode cnf not implemented!\n"); break; default: - DEBUG( 0, __FUNCTION__ + IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown control frame %02x\n", fp[2]); break; } @@ -198,7 +198,7 @@ void irlmp_link_disconnect_indication(struct lap_cb *lap, LAP_REASON reason, struct sk_buff *userdata) { - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); ASSERT(lap != NULL, return;); ASSERT(lap->magic == LMP_LAP_MAGIC, return;); @@ -224,7 +224,7 @@ void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr, __u32 daddr, struct qos_info *qos, struct sk_buff *skb) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Copy QoS settings for this session */ self->qos = qos; @@ -245,7 +245,7 @@ void irlmp_link_connect_indication(struct lap_cb *self, __u32 saddr, void irlmp_link_connect_confirm(struct lap_cb *self, struct qos_info *qos, struct sk_buff *userdata) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LAP_MAGIC, return;); @@ -287,7 +287,7 @@ void irlmp_link_discovery_indication(struct lap_cb *self, */ void irlmp_link_discovery_confirm(struct lap_cb *self, hashbin_t *log) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == LMP_LAP_MAGIC, return;); diff --git a/net/irda/irmod.c b/net/irda/irmod.c index e5c5d72ef..7a2fa169a 100644 --- a/net/irda/irmod.c +++ b/net/irda/irmod.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Dec 15 13:55:39 1997 - * Modified at: Mon Sep 20 09:27:25 1999 + * Modified at: Mon Oct 18 14:54:35 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved. @@ -173,28 +173,31 @@ EXPORT_SYMBOL(hashbin_get_next); EXPORT_SYMBOL(hashbin_get_first); /* IrLAP */ +EXPORT_SYMBOL(irlap_open); +EXPORT_SYMBOL(irlap_close); #ifdef CONFIG_IRDA_COMPRESSION EXPORT_SYMBOL(irda_unregister_compressor); EXPORT_SYMBOL(irda_register_compressor); #endif /* CONFIG_IRDA_COMPRESSION */ EXPORT_SYMBOL(irda_init_max_qos_capabilies); EXPORT_SYMBOL(irda_qos_bits_to_value); -EXPORT_SYMBOL(irda_device_open); -EXPORT_SYMBOL(irda_device_close); EXPORT_SYMBOL(irda_device_setup); EXPORT_SYMBOL(irda_device_set_media_busy); EXPORT_SYMBOL(irda_device_txqueue_empty); -EXPORT_SYMBOL(irda_device_net_open); -EXPORT_SYMBOL(irda_device_net_close); -EXPORT_SYMBOL(irda_device_init_dongle); +EXPORT_SYMBOL(irda_device_dongle_init); +EXPORT_SYMBOL(irda_device_dongle_cleanup); EXPORT_SYMBOL(irda_device_register_dongle); EXPORT_SYMBOL(irda_device_unregister_dongle); +EXPORT_SYMBOL(irda_task_execute); +EXPORT_SYMBOL(irda_task_kick); +EXPORT_SYMBOL(irda_task_next_state); EXPORT_SYMBOL(async_wrap_skb); EXPORT_SYMBOL(async_unwrap_char); EXPORT_SYMBOL(irda_start_timer); EXPORT_SYMBOL(setup_dma); +EXPORT_SYMBOL(infrared_mode); #ifdef CONFIG_IRTTY EXPORT_SYMBOL(irtty_set_dtr_rts); @@ -205,7 +208,7 @@ EXPORT_SYMBOL(irtty_set_packet_mode); int __init irda_init(void) { - printk(KERN_INFO "IrDA (tm) Protocols for Linux-2.3 (Dag Brattli)\n"); + MESSAGE("IrDA (tm) Protocols for Linux-2.3 (Dag Brattli)\n"); irlmp_init(); irlap_init(); @@ -344,7 +347,7 @@ void irda_execute_as_process( void *self, TODO_CALLBACK callback, __u32 param) new->param = param; /* Queue todo */ - enqueue_last(&irda.todo_queue, (QUEUE *) new); + enqueue_last(&irda.todo_queue, (queue_t *) new); event.event = EVENT_NEED_PROCESS_CONTEXT; @@ -362,7 +365,7 @@ void irmanager_notify( struct irmanager_event *event) { struct irda_event *new; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Make sure irmanager is running */ if (!irda.in_use) { @@ -380,7 +383,7 @@ void irmanager_notify( struct irmanager_event *event) new->event = *event; /* Queue event */ - enqueue_last(&irda.event_queue, (QUEUE *) new); + enqueue_last(&irda.event_queue, (queue_t *) new); /* Wake up irmanager sleeping on read */ wake_up_interruptible(&irda.wait_queue); @@ -388,10 +391,10 @@ void irmanager_notify( struct irmanager_event *event) static int irda_open( struct inode * inode, struct file *file) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); if ( irda.in_use) { - DEBUG( 0, __FUNCTION__ "(), irmanager is already running!\n"); + IRDA_DEBUG( 0, __FUNCTION__ "(), irmanager is already running!\n"); return -1; } irda.in_use = TRUE; @@ -414,7 +417,7 @@ static int irda_ioctl( struct inode *inode, struct file *filp, int err = 0; int size = _IOC_SIZE(cmd); - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); if ( _IOC_DIR(cmd) & _IOC_READ) err = verify_area( VERIFY_WRITE, (void *) arg, size); @@ -426,7 +429,7 @@ 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"); + IRDA_DEBUG(4, __FUNCTION__ "(), got process context!\n"); while ((todo = (struct irda_todo *) dequeue_first( &irda.todo_queue)) != NULL) @@ -446,7 +449,7 @@ static int irda_ioctl( struct inode *inode, struct file *filp, static int irda_close(struct inode *inode, struct file *file) { - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); MOD_DEC_USE_COUNT; @@ -462,7 +465,7 @@ static ssize_t irda_read(struct file *file, char *buffer, size_t count, unsigned long flags; int len; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* * Go to sleep and wait for event if there is no event to be read! */ save_flags( flags); @@ -494,14 +497,14 @@ static ssize_t irda_read(struct file *file, char *buffer, size_t count, static ssize_t irda_write(struct file *file, const char *buffer, size_t count, loff_t *noidea) { - DEBUG(0, __FUNCTION__ "()\n"); + IRDA_DEBUG(0, __FUNCTION__ "()\n"); return 0; } static u_int irda_poll(struct file *file, poll_table *wait) { - DEBUG(0, __FUNCTION__ "(), Sorry not implemented yet!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), Sorry not implemented yet!\n"); return 0; } diff --git a/net/irda/irproc.c b/net/irda/irproc.c index cb361a787..940aacf7c 100644 --- a/net/irda/irproc.c +++ b/net/irda/irproc.c @@ -6,10 +6,11 @@ * Status: Experimental. * Author: Thomas Davis, <ratbert@radiks.net> * Created at: Sat Feb 21 21:33:24 1998 - * Modified at: Fri Jun 4 09:39:49 1999 + * Modified at: Fri Oct 8 09:26:46 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> - * - * Copyright (c) 1998-1999, Thomas Davis, <ratbert@radiks.net>, + * + * Copyright (c) 1998-1999, Dag Brattli <dagb@cs.uit.no> + * Copyright (c) 1998, Thomas Davis, <ratbert@radiks.net>, * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -30,8 +31,6 @@ #include <net/irda/irlap.h> #include <net/irda/irlmp.h> -extern int irda_device_proc_read(char *buf, char **start, off_t offset, - int len, int unused); extern int irlap_proc_read(char *buf, char **start, off_t offset, int len, int unused); extern int irlmp_proc_read(char *buf, char **start, off_t offset, int len, @@ -43,16 +42,6 @@ extern int irias_proc_read(char *buf, char **start, off_t offset, int len, extern int discovery_proc_read(char *buf, char **start, off_t offset, int len, int unused); -/* enum irda_directory_inos { */ -/* PROC_IRDA_LAP = 1, */ -/* PROC_IRDA_LMP, */ -/* PROC_IRDA_TTP, */ -/* PROC_IRDA_LPT, */ -/* PROC_IRDA_COMM, */ -/* PROC_IRDA_IRDA_DEVICE, */ -/* PROC_IRDA_IRIAS */ -/* }; */ - struct irda_entry { char *name; int (*fn)(char*, char**, off_t, int, int); @@ -62,7 +51,6 @@ struct proc_dir_entry *proc_irda; static struct irda_entry dir[] = { {"discovery", discovery_proc_read}, - {"irda_device", irda_device_proc_read}, {"irttp", irttp_proc_read}, {"irlmp", irlmp_proc_read}, {"irlap", irlap_proc_read}, diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c index 4b9532f1b..91a7a6f85 100644 --- a/net/irda/irqueue.c +++ b/net/irda/irqueue.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Jun 9 13:29:31 1998 - * Modified at: Thu Jun 10 11:00:12 1999 + * Modified at: Tue Oct 5 09:02:15 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (C) 1998-1999, Aage Kvalnes <aage@cs.uit.no> @@ -36,7 +36,7 @@ #include <net/irda/irqueue.h> #include <net/irda/irmod.h> -static QUEUE *dequeue_general( QUEUE **queue, QUEUE* element); +static queue_t *dequeue_general( queue_t **queue, queue_t* element); static __u32 hash( char* name); /* @@ -79,7 +79,7 @@ hashbin_t *hashbin_new(int type) */ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func) { - QUEUE* queue; + queue_t* queue; int i; ASSERT(hashbin != NULL, return -1;); @@ -89,12 +89,12 @@ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func) * Free the entries in the hashbin */ for ( i = 0; i < HASHBIN_SIZE; i ++ ) { - queue = dequeue_first( (QUEUE**) &hashbin->hb_queue[ i]); + queue = dequeue_first( (queue_t**) &hashbin->hb_queue[ i]); while( queue ) { if ( free_func) (*free_func)( queue ); queue = dequeue_first( - (QUEUE**) &hashbin->hb_queue[ i]); + (queue_t**) &hashbin->hb_queue[ i]); } } hashbin->hb_size = 0; @@ -112,7 +112,7 @@ int hashbin_clear( hashbin_t* hashbin, FREE_FUNC free_func) */ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) { - QUEUE* queue; + queue_t* queue; int i; ASSERT(hashbin != NULL, return -1;); @@ -123,12 +123,12 @@ int hashbin_delete( hashbin_t* hashbin, FREE_FUNC free_func) * it has been shown to work */ for (i = 0; i < HASHBIN_SIZE; i ++ ) { - queue = dequeue_first((QUEUE**) &hashbin->hb_queue[i]); + queue = dequeue_first((queue_t**) &hashbin->hb_queue[i]); while (queue ) { if (free_func) (*free_func)(queue); queue = dequeue_first( - (QUEUE**) &hashbin->hb_queue[i]); + (queue_t**) &hashbin->hb_queue[i]); } } @@ -152,7 +152,7 @@ void hashbin_lock(hashbin_t* hashbin, __u32 hashv, char* name, { int bin; - DEBUG(0, "hashbin_lock\n"); + IRDA_DEBUG(0, "hashbin_lock\n"); ASSERT(hashbin != NULL, return;); ASSERT(hashbin->magic == HB_MAGIC, return;); @@ -184,7 +184,7 @@ void hashbin_unlock(hashbin_t* hashbin, __u32 hashv, char* name, { int bin; - DEBUG(0, "hashbin_unlock()\n"); + IRDA_DEBUG(0, "hashbin_unlock()\n"); ASSERT(hashbin != NULL, return;); ASSERT(hashbin->magic == HB_MAGIC, return;); @@ -210,12 +210,12 @@ void hashbin_unlock(hashbin_t* hashbin, __u32 hashv, char* name, * Insert an entry into the hashbin * */ -void hashbin_insert( hashbin_t* hashbin, QUEUE* entry, __u32 hashv, char* name) +void hashbin_insert( hashbin_t* hashbin, queue_t* entry, __u32 hashv, char* name) { unsigned long flags = 0; int bin; - DEBUG( 4, __FUNCTION__"()\n"); + IRDA_DEBUG( 4, __FUNCTION__"()\n"); ASSERT( hashbin != NULL, return;); ASSERT( hashbin->magic == HB_MAGIC, return;); @@ -250,7 +250,7 @@ void hashbin_insert( hashbin_t* hashbin, QUEUE* entry, __u32 hashv, char* name) */ if ( hashbin->hb_type & HB_SORTED) { } else { - enqueue_first( (QUEUE**) &hashbin->hb_queue[ bin ], + enqueue_first( (queue_t**) &hashbin->hb_queue[ bin ], entry); } hashbin->hb_size++; @@ -275,9 +275,9 @@ void* hashbin_find( hashbin_t* hashbin, __u32 hashv, char* name ) { int bin, found = FALSE; unsigned long flags = 0; - QUEUE* entry; + queue_t* entry; - DEBUG( 4, "hashbin_find()\n"); + IRDA_DEBUG( 4, "hashbin_find()\n"); ASSERT( hashbin != NULL, return NULL;); ASSERT( hashbin->magic == HB_MAGIC, return NULL;); @@ -342,7 +342,7 @@ void* hashbin_find( hashbin_t* hashbin, __u32 hashv, char* name ) void *hashbin_remove_first( hashbin_t *hashbin) { unsigned long flags; - QUEUE *entry = NULL; + queue_t *entry = NULL; save_flags(flags); cli(); @@ -367,9 +367,9 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) { int bin, found = FALSE; unsigned long flags = 0; - QUEUE* entry; + queue_t* entry; - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); ASSERT( hashbin != NULL, return NULL;); ASSERT( hashbin->magic == HB_MAGIC, return NULL;); @@ -421,8 +421,8 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) * If entry was found, dequeue it */ if ( found ) { - dequeue_general( (QUEUE**) &hashbin->hb_queue[ bin ], - (QUEUE*) entry ); + dequeue_general( (queue_t**) &hashbin->hb_queue[ bin ], + (queue_t*) entry ); hashbin->hb_size--; /* @@ -457,9 +457,9 @@ void* hashbin_remove( hashbin_t* hashbin, __u32 hashv, char* name) * called before any calls to hashbin_get_next()! * */ -QUEUE *hashbin_get_first( hashbin_t* hashbin) +queue_t *hashbin_get_first( hashbin_t* hashbin) { - QUEUE *entry; + queue_t *entry; int i; ASSERT( hashbin != NULL, return NULL;); @@ -489,9 +489,9 @@ QUEUE *hashbin_get_first( hashbin_t* hashbin) * NULL when all items have been traversed * */ -QUEUE *hashbin_get_next( hashbin_t *hashbin) +queue_t *hashbin_get_next( hashbin_t *hashbin) { - QUEUE* entry; + queue_t* entry; int bin; int i; @@ -542,9 +542,9 @@ QUEUE *hashbin_get_next( hashbin_t *hashbin) * Insert item into end of queue. * */ -static void __enqueue_last( QUEUE **queue, QUEUE* element) +static void __enqueue_last( queue_t **queue, queue_t* element) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); /* * Check if queue is empty. @@ -566,7 +566,7 @@ static void __enqueue_last( QUEUE **queue, QUEUE* element) } } -inline void enqueue_last( QUEUE **queue, QUEUE* element) +inline void enqueue_last( queue_t **queue, queue_t* element) { unsigned long flags; @@ -584,10 +584,10 @@ inline void enqueue_last( QUEUE **queue, QUEUE* element) * Insert item first in queue. * */ -void enqueue_first(QUEUE **queue, QUEUE* element) +void enqueue_first(queue_t **queue, queue_t* element) { - DEBUG( 4, __FUNCTION__ "()\n"); + IRDA_DEBUG( 4, __FUNCTION__ "()\n"); /* * Check if queue is empty. @@ -616,9 +616,9 @@ void enqueue_first(QUEUE **queue, QUEUE* element) * Insert a queue (list) into the start of the first queue * */ -void enqueue_queue( QUEUE** queue, QUEUE** list ) +void enqueue_queue( queue_t** queue, queue_t** list ) { - QUEUE* tmp; + queue_t* tmp; /* * Check if queue is empty @@ -643,9 +643,9 @@ void enqueue_queue( QUEUE** queue, QUEUE** list ) * */ #if 0 -static void enqueue_second(QUEUE **queue, QUEUE* element) +static void enqueue_second(queue_t **queue, queue_t* element) { - DEBUG( 0, "enqueue_second()\n"); + IRDA_DEBUG( 0, "enqueue_second()\n"); /* * Check if queue is empty. @@ -674,11 +674,11 @@ static void enqueue_second(QUEUE **queue, QUEUE* element) * Remove first entry in queue * */ -QUEUE *dequeue_first(QUEUE **queue) +queue_t *dequeue_first(queue_t **queue) { - QUEUE *ret; + queue_t *ret; - DEBUG( 4, "dequeue_first()\n"); + IRDA_DEBUG( 4, "dequeue_first()\n"); /* * Set return value @@ -715,11 +715,11 @@ QUEUE *dequeue_first(QUEUE **queue) * * */ -static QUEUE *dequeue_general(QUEUE **queue, QUEUE* element) +static queue_t *dequeue_general(queue_t **queue, queue_t* element) { - QUEUE *ret; + queue_t *ret; - DEBUG( 4, "dequeue_general()\n"); + IRDA_DEBUG( 4, "dequeue_general()\n"); /* * Set return value diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 43fb65380..304f39e10 100644 --- a/net/irda/irttp.c +++ b/net/irda/irttp.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sun Aug 31 20:14:31 1997 - * Modified at: Mon Sep 27 12:02:52 1999 + * Modified at: Tue Oct 19 21:40:00 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -90,7 +90,7 @@ int __init irttp_init(void) irttp->tsaps = hashbin_new(HB_LOCAL); if (!irttp->tsaps) { - printk(KERN_WARNING "IrDA: Can't allocate IrTTP hashbin!\n"); + ERROR(__FUNCTION__ "(), can't allocate IrTTP hashbin!\n"); return -ENOMEM; } @@ -140,7 +140,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC); if (self == NULL) { - DEBUG(0, __FUNCTION__ "(), unable to kmalloc!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc!\n"); return NULL; } memset(self, 0, sizeof(struct tsap_cb)); @@ -168,7 +168,7 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) */ lsap = irlmp_open_lsap(stsap_sel, &ttp_notify); if (lsap == NULL) { - printk(KERN_ERR "IrTTP, Unable to get LSAP!!\n"); + WARNING(__FUNCTION__ "(), unable to allocate LSAP!!\n"); return NULL; } @@ -178,12 +178,12 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) * the stsap_sel we have might not be valid anymore */ self->stsap_sel = lsap->slsap_sel; - DEBUG(4, __FUNCTION__ "(), stsap_sel=%02x\n", self->stsap_sel); + IRDA_DEBUG(4, __FUNCTION__ "(), stsap_sel=%02x\n", self->stsap_sel); self->notify = *notify; self->lsap = lsap; - hashbin_insert(irttp->tsaps, (QUEUE *) self, (int) self, NULL); + hashbin_insert(irttp->tsaps, (queue_t *) self, (int) self, NULL); if (credit > TTP_MAX_QUEUE) self->initial_credit = TTP_MAX_QUEUE; @@ -227,7 +227,7 @@ int irttp_close_tsap(struct tsap_cb *self) { struct tsap_cb *tsap; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return -1;); ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;); @@ -236,7 +236,7 @@ int irttp_close_tsap(struct tsap_cb *self) if (self->connected) { /* Check if disconnect is not pending */ if (!self->disconnect_pend) { - DEBUG(0, __FUNCTION__ "(), TSAP still connected!\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), TSAP still connected!\n"); irttp_disconnect_request(self, NULL, P_NORMAL); } self->close_pend = TRUE; @@ -272,16 +272,16 @@ int irttp_udata_request(struct tsap_cb *self, struct sk_buff *skb) ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;); ASSERT(skb != NULL, return -1;); - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); /* Check that nothing bad happens */ if ((skb->len == 0) || (!self->connected)) { - DEBUG(1, __FUNCTION__ "(), No data, or not connected\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), No data, or not connected\n"); return -1; } if (skb->len > self->max_seg_size) { - DEBUG(1, __FUNCTION__ "(), UData is to large for IrLAP!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), UData is to large for IrLAP!\n"); return -1; } @@ -476,7 +476,7 @@ void irttp_give_credit(struct tsap_cb *self) ASSERT(self != NULL, return;); ASSERT(self->magic == TTP_TSAP_MAGIC, return;); - DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", + IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", self->send_credit, self->avail_credit, self->remote_credit); /* Give credit to peer */ @@ -524,7 +524,7 @@ static int irttp_udata_indication(void *instance, void *sap, { struct tsap_cb *self; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); self = (struct tsap_cb *) instance; @@ -610,24 +610,24 @@ static int irttp_data_indication(void *instance, void *sap, */ void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow) { - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == TTP_TSAP_MAGIC, return;); switch (flow) { case FLOW_STOP: - DEBUG(1, __FUNCTION__ "(), flow stop\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), flow stop\n"); self->rx_sdu_busy = TRUE; break; case FLOW_START: - DEBUG(1, __FUNCTION__ "(), flow start\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), flow start\n"); self->rx_sdu_busy = FALSE; irttp_run_rx_queue(self); break; default: - DEBUG(1, __FUNCTION__ "(), Unknown flow command!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Unknown flow command!\n"); } } @@ -646,7 +646,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, __u8 *frame; __u8 n; - DEBUG(4, __FUNCTION__ "(), max_sdu_size=%d\n", max_sdu_size); + IRDA_DEBUG(4, __FUNCTION__ "(), max_sdu_size=%d\n", max_sdu_size); ASSERT(self != NULL, return -EBADR;); ASSERT(self->magic == TTP_TSAP_MAGIC, return -EBADR;); @@ -738,7 +738,7 @@ static void irttp_connect_confirm(void *instance, void *sap, __u8 plen; __u8 n; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); self = (struct tsap_cb *) instance; @@ -754,15 +754,15 @@ static void irttp_connect_confirm(void *instance, void *sap, * negotiated QoS for the link. */ if (qos) { - DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %02x\n", + IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %02x\n", qos->baud_rate.bits); - DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %d bps.\n", + IRDA_DEBUG(4, "IrTTP, Negotiated BAUD_RATE: %d bps.\n", qos->baud_rate.value); } n = skb->data[0] & 0x7f; - DEBUG(4, __FUNCTION__ "(), Initial send_credit=%d\n", n); + IRDA_DEBUG(4, __FUNCTION__ "(), Initial send_credit=%d\n", n); self->send_credit = n; self->tx_max_sdu_size = 0; @@ -777,7 +777,7 @@ static void irttp_connect_confirm(void *instance, void *sap, plen = skb->data[0]; ret = irda_param_extract_all(self, skb->data+1, - MIN(skb->len-1, plen), + IRDA_MIN(skb->len-1, plen), ¶m_info); /* Any errors in the parameter list? */ @@ -790,13 +790,13 @@ static void irttp_connect_confirm(void *instance, void *sap, return; } /* Remove parameters */ - skb_pull(skb, MIN(skb->len, plen+1)); + skb_pull(skb, IRDA_MIN(skb->len, plen+1)); } - DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", + IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", self->send_credit, self->avail_credit, self->remote_credit); - DEBUG(2, __FUNCTION__ "(), MaxSduSize=%d\n", self->tx_max_sdu_size); + IRDA_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, @@ -833,7 +833,7 @@ void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos, self->max_seg_size = max_seg_size; self->max_header_size = max_header_size+TTP_HEADER; - DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel); + IRDA_DEBUG(4, __FUNCTION__ "(), TSAP sel=%02x\n", self->stsap_sel); /* Need to update dtsap_sel if its equal to LSAP_ANY */ self->dtsap_sel = lsap->dlsap_sel; @@ -852,7 +852,7 @@ void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos, plen = skb->data[0]; ret = irda_param_extract_all(self, skb->data+1, - MIN(skb->len-1, plen), + IRDA_MIN(skb->len-1, plen), ¶m_info); /* Any errors in the parameter list? */ @@ -866,7 +866,7 @@ void irttp_connect_indication(void *instance, void *sap, struct qos_info *qos, } /* Remove parameters */ - skb_pull(skb, MIN(skb->len, plen+1)); + skb_pull(skb, IRDA_MIN(skb->len, plen+1)); } if (self->notify.connect_indication) { @@ -894,7 +894,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, ASSERT(self != NULL, return -1;); ASSERT(self->magic == TTP_TSAP_MAGIC, return -1;); - DEBUG(4, __FUNCTION__ "(), Source TSAP selector=%02x\n", + IRDA_DEBUG(4, __FUNCTION__ "(), Source TSAP selector=%02x\n", self->stsap_sel); /* Any userdata supplied? */ @@ -972,15 +972,15 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) { struct tsap_cb *new; - DEBUG(1, __FUNCTION__ "()\n"); + IRDA_DEBUG(1, __FUNCTION__ "()\n"); if (!hashbin_find(irttp->tsaps, (int) orig, NULL)) { - DEBUG(0, __FUNCTION__ "(), unable to find TSAP\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), unable to find TSAP\n"); return NULL; } new = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC); if (!new) { - DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), unable to kmalloc\n"); return NULL; } /* Dup */ @@ -995,7 +995,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb *orig, void *instance) skb_queue_head_init(&new->tx_queue); skb_queue_head_init(&new->rx_fragments); - hashbin_insert(irttp->tsaps, (QUEUE *) new, (int) new, NULL); + hashbin_insert(irttp->tsaps, (queue_t *) new, (int) new, NULL); return new; } @@ -1018,13 +1018,13 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata, /* Already disconnected? */ if (!self->connected) { - DEBUG(4, __FUNCTION__ "(), already disconnected!\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), already disconnected!\n"); return -1; } /* Disconnect already pending? */ if (self->disconnect_pend) { - DEBUG(1, __FUNCTION__ "(), disconnect already pending\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), disconnect already pending\n"); if (userdata) { dev_kfree_skb(userdata); } @@ -1039,7 +1039,7 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata, */ if (skb_queue_len(&self->tx_queue) > 0) { if (priority == P_HIGH) { - DEBUG(1, __FUNCTION__ "High priority!!()\n" ); + IRDA_DEBUG(1, __FUNCTION__ "High priority!!()\n" ); /* * No need to send the queued data, if we are @@ -1065,7 +1065,7 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata, return -1; } } - DEBUG(1, __FUNCTION__ "(), Disconnecting ...\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Disconnecting ...\n"); self->connected = FALSE; @@ -1097,7 +1097,7 @@ void irttp_disconnect_indication(void *instance, void *sap, LM_REASON reason, { struct tsap_cb *self; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); self = (struct tsap_cb *) instance; @@ -1132,7 +1132,7 @@ void irttp_do_data_indication(struct tsap_cb *self, struct sk_buff *skb) * give an error back */ if (err == -ENOMEM) { - DEBUG(0, __FUNCTION__ "() requeueing skb!\n"); + IRDA_DEBUG(0, __FUNCTION__ "() requeueing skb!\n"); /* Make sure we take a break */ self->rx_sdu_busy = TRUE; @@ -1157,7 +1157,7 @@ void irttp_run_rx_queue(struct tsap_cb *self) struct sk_buff *skb; int more = 0; - DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", + IRDA_DEBUG(4, __FUNCTION__ "() send=%d,avail=%d,remote=%d\n", self->send_credit, self->avail_credit, self->remote_credit); if (irda_lock(&self->rx_queue_lock) == FALSE) @@ -1197,7 +1197,7 @@ void irttp_run_rx_queue(struct tsap_cb *self) * limits of the maximum size of the rx_sdu */ if (self->rx_sdu_size <= self->rx_max_sdu_size) { - DEBUG(4, __FUNCTION__ "(), queueing frag\n"); + IRDA_DEBUG(4, __FUNCTION__ "(), queueing frag\n"); skb_queue_tail(&self->rx_fragments, skb); } else { /* Free the part of the SDU that is too big */ @@ -1227,7 +1227,7 @@ void irttp_run_rx_queue(struct tsap_cb *self) /* Now we can deliver the reassembled skb */ irttp_do_data_indication(self, skb); } else { - DEBUG(1, __FUNCTION__ "(), Truncated frame\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), Truncated frame\n"); /* Free the part of the SDU that is too big */ dev_kfree_skb(skb); @@ -1252,7 +1252,7 @@ void irttp_flush_queues(struct tsap_cb *self) { struct sk_buff* skb; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == TTP_TSAP_MAGIC, return;); @@ -1285,7 +1285,7 @@ static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self) ASSERT(self != NULL, return NULL;); ASSERT(self->magic == TTP_TSAP_MAGIC, return NULL;); - DEBUG(4, __FUNCTION__ "(), self->rx_sdu_size=%d\n", + IRDA_DEBUG(4, __FUNCTION__ "(), self->rx_sdu_size=%d\n", self->rx_sdu_size); skb = dev_alloc_skb(self->rx_sdu_size); @@ -1308,10 +1308,10 @@ static struct sk_buff *irttp_reassemble_skb(struct tsap_cb *self) dev_kfree_skb(frag); } - DEBUG(4, __FUNCTION__ "(), frame len=%d\n", n); + IRDA_DEBUG(4, __FUNCTION__ "(), frame len=%d\n", n); /* Set the new length */ - DEBUG(4, __FUNCTION__ "(), rx_sdu_size=%d\n", self->rx_sdu_size); + IRDA_DEBUG(4, __FUNCTION__ "(), rx_sdu_size=%d\n", self->rx_sdu_size); ASSERT(n <= self->rx_sdu_size, return NULL;); skb_trim(skb, n); @@ -1331,7 +1331,7 @@ static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb) struct sk_buff *frag; __u8 *frame; - DEBUG(4, __FUNCTION__ "()\n"); + IRDA_DEBUG(4, __FUNCTION__ "()\n"); ASSERT(self != NULL, return;); ASSERT(self->magic == TTP_TSAP_MAGIC, return;); @@ -1346,7 +1346,7 @@ static void irttp_fragment_skb(struct tsap_cb *self, struct sk_buff *skb) * queue what is left of the original skb */ if (skb->len < self->max_seg_size) { - DEBUG(4, __FUNCTION__ + IRDA_DEBUG(4, __FUNCTION__ "(), queuing last segment\n"); frame = skb_push(skb, TTP_HEADER); @@ -1399,7 +1399,7 @@ static int irttp_param_max_sdu_size(void *instance, param_t *param, int get) else self->tx_max_sdu_size = param->pv.i; - DEBUG(0, __FUNCTION__ "(), MaxSduSize=%d\n", param->pv.i); + IRDA_DEBUG(0, __FUNCTION__ "(), MaxSduSize=%d\n", param->pv.i); return 0; } diff --git a/net/irda/parameters.c b/net/irda/parameters.c index 630618bdb..9ca443f02 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -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:31:32 1999 + * Modified at: Tue Oct 5 11:52:54 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1999 Dag Brattli, All Rights Reserved. @@ -29,6 +29,7 @@ ********************************************************************/ #include <asm/unaligned.h> +#include <asm/byteorder.h> #include <net/irda/irda.h> #include <net/irda/parameters.h> @@ -148,13 +149,13 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, */ if (p.pl == 0) { if (p.pv.i < 0xff) { - DEBUG(2, __FUNCTION__ "(), using 1 byte\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), using 1 byte\n"); p.pl = 1; } else if (p.pv.i < 0xffff) { - DEBUG(2, __FUNCTION__ "(), using 2 bytes\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), using 2 bytes\n"); p.pl = 2; } else { - DEBUG(2, __FUNCTION__ "(), using 4 bytes\n"); + IRDA_DEBUG(2, __FUNCTION__ "(), using 4 bytes\n"); p.pl = 4; /* Default length */ } } @@ -163,7 +164,7 @@ static int irda_insert_integer(void *self, __u8 *buf, int len, __u8 pi, WARNING(__FUNCTION__ "(), buffer to short for insertion!\n"); return -1; } - DEBUG(2, __FUNCTION__ "(), pi=%#x, pl=%d, pi=%d\n", p.pi, p.pl, p.pv.i); + IRDA_DEBUG(2, __FUNCTION__ "(), pi=%#x, pl=%d, pi=%d\n", p.pi, p.pl, p.pv.i); switch (p.pl) { case 1: n += irda_param_pack(buf, "bbb", p.pi, p.pl, p.pv.b); @@ -275,12 +276,12 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, param_t p; int err; - DEBUG(2, __FUNCTION__ "()\n"); + IRDA_DEBUG(2, __FUNCTION__ "()\n"); p.pi = pi; /* In case handler needs to know */ p.pl = buf[1]; /* Extract lenght of value */ - DEBUG(2, __FUNCTION__ "(), pi=%#x, pl=%d\n", p.pi, p.pl); + IRDA_DEBUG(2, __FUNCTION__ "(), pi=%#x, pl=%d\n", p.pi, p.pl); /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { @@ -293,7 +294,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, * checked that the buffer is long enough */ strncpy(str, buf+2, p.pl); - DEBUG(2, __FUNCTION__ "(), str=0x%02x 0x%02x\n", (__u8) str[0], + IRDA_DEBUG(2, __FUNCTION__ "(), str=0x%02x 0x%02x\n", (__u8) str[0], (__u8) str[1]); /* Null terminate string */ @@ -330,7 +331,7 @@ static int irda_extract_octseq(void *self, __u8 *buf, int len, __u8 pi, return -1; } - DEBUG(0, __FUNCTION__ "(), not impl\n"); + IRDA_DEBUG(0, __FUNCTION__ "(), not impl\n"); return p.pl+2; /* Extracted pl+2 bytes */ } @@ -454,7 +455,7 @@ int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, if ((pi_major > info->len-1) || (pi_minor > info->tables[pi_major].len-1)) { - DEBUG(0, __FUNCTION__ + IRDA_DEBUG(0, __FUNCTION__ "(), no handler for parameter=0x%02x\n", pi); /* Skip this parameter */ @@ -467,7 +468,7 @@ int irda_param_insert(void *self, __u8 pi, __u8 *buf, int len, /* Find expected data type for this parameter identifier (pi)*/ type = pi_minor_info->type; - DEBUG(3, __FUNCTION__ "(), pi=[%d,%d], type=%d\n", + IRDA_DEBUG(3, __FUNCTION__ "(), pi=[%d,%d], type=%d\n", pi_major, pi_minor, type); /* Check if handler has been implemented */ @@ -509,7 +510,7 @@ int irda_param_extract(void *self, __u8 *buf, int len, pi_param_info_t *info) if ((pi_major > info->len-1) || (pi_minor > info->tables[pi_major].len-1)) { - DEBUG(0, __FUNCTION__ "(), no handler for parameter=0x%02x\n", + IRDA_DEBUG(0, __FUNCTION__ "(), no handler for parameter=0x%02x\n", buf[0]); /* Skip this parameter */ @@ -525,7 +526,7 @@ int irda_param_extract(void *self, __u8 *buf, int len, pi_param_info_t *info) /* Find expected data type for this parameter identifier (pi)*/ type = pi_minor_info->type; - DEBUG(3, __FUNCTION__ "(), pi=[%d,%d], type=%d\n", + IRDA_DEBUG(3, __FUNCTION__ "(), pi=[%d,%d], type=%d\n", pi_major, pi_minor, type); /* Check if handler has been implemented */ diff --git a/net/irda/qos.c b/net/irda/qos.c index 6af865bac..0d9a2550b 100644 --- a/net/irda/qos.c +++ b/net/irda/qos.c @@ -7,7 +7,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Tue Sep 9 00:00:26 1997 - * Modified at: Wed Sep 1 09:14:55 1999 + * Modified at: Tue Oct 5 11:50:41 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, @@ -167,7 +167,7 @@ int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb) #ifdef CONFIG_IRDA_COMPRESSION if (!comp_seen) { - DEBUG( 4, __FUNCTION__ "(), Compression not seen!\n"); + IRDA_DEBUG( 4, __FUNCTION__ "(), Compression not seen!\n"); self->qos_tx.compression.bits = 0x00; self->qos_rx.compression.bits = 0x00; } @@ -177,22 +177,22 @@ int irlap_qos_negotiate(struct irlap_cb *self, struct sk_buff *skb) irda_qos_bits_to_value(&self->qos_tx); irda_qos_bits_to_value(&self->qos_rx); - DEBUG(2, "Setting BAUD_RATE to %d bps.\n", + IRDA_DEBUG(2, "Setting BAUD_RATE to %d bps.\n", self->qos_tx.baud_rate.value); - DEBUG(2, "Setting DATA_SIZE to %d bytes\n", + IRDA_DEBUG(2, "Setting DATA_SIZE to %d bytes\n", self->qos_tx.data_size.value); - DEBUG(2, "Setting WINDOW_SIZE to %d\n", + IRDA_DEBUG(2, "Setting WINDOW_SIZE to %d\n", self->qos_tx.window_size.value); - DEBUG(2, "Setting XBOFS to %d\n", + IRDA_DEBUG(2, "Setting XBOFS to %d\n", self->qos_tx.additional_bofs.value); - DEBUG(2, "Setting MAX_TURN_TIME to %d ms.\n", + IRDA_DEBUG(2, "Setting MAX_TURN_TIME to %d ms.\n", self->qos_tx.max_turn_time.value); - DEBUG(2, "Setting MIN_TURN_TIME to %d usecs.\n", + IRDA_DEBUG(2, "Setting MIN_TURN_TIME to %d usecs.\n", self->qos_tx.min_turn_time.value); - DEBUG(2, "Setting LINK_DISC to %d secs.\n", + IRDA_DEBUG(2, "Setting LINK_DISC to %d secs.\n", self->qos_tx.link_disc_time.value); #ifdef CONFIG_IRDA_COMPRESSION - DEBUG(2, "Setting COMPRESSION to %d\n", + IRDA_DEBUG(2, "Setting COMPRESSION to %d\n", self->qos_tx.compression.value); #endif return ret; @@ -278,16 +278,16 @@ 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(2, __FUNCTION__ "(), baud rate = 0x%02x\n", param->pv.i); + IRDA_DEBUG(2, __FUNCTION__ "(), baud rate = 0x%02x\n", param->pv.i); } else { /* * Stations must agree on baud rate, so calculate * intersection */ - DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", param->pv.s); + IRDA_DEBUG(2, "Requested BAUD_RATE: 0x%04x\n", param->pv.s); final = param->pv.s & self->qos_rx.baud_rate.bits; - DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final); + IRDA_DEBUG(2, "Final BAUD_RATE: 0x%04x\n", final); self->qos_tx.baud_rate.bits = final; self->qos_rx.baud_rate.bits = final; } @@ -317,10 +317,10 @@ static int irlap_param_link_disconnect(void *instance, param_t *param, int get) * Stations must agree on link disconnect/threshold * time. */ - DEBUG(2, "LINK_DISC: %02x\n", param->pv.b); + IRDA_DEBUG(2, "LINK_DISC: %02x\n", param->pv.b); final = param->pv.b & self->qos_rx.link_disc_time.bits; - DEBUG(2, "Final LINK_DISC: %02x\n", final); + IRDA_DEBUG(2, "Final LINK_DISC: %02x\n", final); self->qos_tx.link_disc_time.bits = final; self->qos_rx.link_disc_time.bits = final; } @@ -435,7 +435,7 @@ static int irlap_param_min_turn_time(void *instance, param_t *param, int get) return 0; } -__u32 byte_value(__u8 byte, int *array) +__u32 byte_value(__u8 byte, __u32 *array) { int index; @@ -472,7 +472,7 @@ int msb_index (__u16 word) * * Returns the index to the value in the specified array */ -int value_index(__u32 value, int *array) +int value_index(__u32 value, __u32 *array) { int i; @@ -488,7 +488,7 @@ int value_index(__u32 value, int *array) * Returns value to index in array, easy! * */ -__u32 index_value(int index, int *array) +__u32 index_value(int index, __u32 *array) { return array[index]; } diff --git a/net/irda/timer.c b/net/irda/timer.c index fab26fd37..974863721 100644 --- a/net/irda/timer.c +++ b/net/irda/timer.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Aug 16 00:59:29 1997 - * Modified at: Mon Sep 20 11:32:37 1999 + * Modified at: Thu Oct 7 12:30:19 1999 * Modified by: Dag Brattli <dagb@cs.uit.no> * * Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, @@ -32,13 +32,13 @@ #include <net/irda/irlap.h> #include <net/irda/irlmp_event.h> -static void irlap_slot_timer_expired( void* data); -static void irlap_query_timer_expired( void* data); -static void irlap_final_timer_expired( void* data); -static void irlap_wd_timer_expired( void* data); -static void irlap_backoff_timer_expired( void* data); +static void irlap_slot_timer_expired(void* data); +static void irlap_query_timer_expired(void* data); +static void irlap_final_timer_expired(void* data); +static void irlap_wd_timer_expired(void* data); +static void irlap_backoff_timer_expired(void* data); -static void irda_device_media_busy_expired( void* data); +static void irlap_media_busy_expired(void* data); /* * Function irda_start_timer (timer, timeout) * @@ -63,57 +63,55 @@ void irda_start_timer(struct timer_list *ptimer, int timeout, void *data, add_timer(ptimer); } -inline void irlap_start_slot_timer(struct irlap_cb *self, int timeout) +void irlap_start_slot_timer(struct irlap_cb *self, int timeout) { irda_start_timer(&self->slot_timer, timeout, (void *) self, irlap_slot_timer_expired); } -inline void irlap_start_query_timer(struct irlap_cb *self, int timeout) +void irlap_start_query_timer(struct irlap_cb *self, int timeout) { irda_start_timer( &self->query_timer, timeout, (void *) self, irlap_query_timer_expired); } -inline void irlap_start_final_timer(struct irlap_cb *self, int timeout) +void irlap_start_final_timer(struct irlap_cb *self, int timeout) { irda_start_timer(&self->final_timer, timeout, (void *) self, irlap_final_timer_expired); } -inline void irlap_start_wd_timer(struct irlap_cb *self, int timeout) +void irlap_start_wd_timer(struct irlap_cb *self, int timeout) { irda_start_timer(&self->wd_timer, timeout, (void *) self, irlap_wd_timer_expired); } -inline void irlap_start_backoff_timer(struct irlap_cb *self, int timeout) +void irlap_start_backoff_timer(struct irlap_cb *self, int timeout) { irda_start_timer(&self->backoff_timer, timeout, (void *) self, irlap_backoff_timer_expired); } -inline void irda_device_start_mbusy_timer(struct irda_device *self) +void irlap_start_mbusy_timer(struct irlap_cb *self) { irda_start_timer(&self->media_busy_timer, MEDIABUSY_TIMEOUT, - (void *) self, - irda_device_media_busy_expired); - + (void *) self, irlap_media_busy_expired); } -inline void irlmp_start_watchdog_timer(struct lsap_cb *self, int timeout) +void irlmp_start_watchdog_timer(struct lsap_cb *self, int timeout) { irda_start_timer(&self->watchdog_timer, timeout, (void *) self, irlmp_watchdog_timer_expired); } -inline void irlmp_start_discovery_timer(struct irlmp_cb *self, int timeout) +void irlmp_start_discovery_timer(struct irlmp_cb *self, int timeout) { irda_start_timer(&self->discovery_timer, timeout, (void *) self, irlmp_discovery_timer_expired); } -inline void irlmp_start_idle_timer(struct lap_cb *self, int timeout) +void irlmp_start_idle_timer(struct lap_cb *self, int timeout) { irda_start_timer(&self->idle_timer, timeout, (void *) self, irlmp_idle_timer_expired); @@ -205,12 +203,11 @@ static void irlap_backoff_timer_expired(void *data) * * */ -void irda_device_media_busy_expired(void* data) +void irlap_media_busy_expired(void* data) { - struct irda_device *self = (struct irda_device *) data; + struct irlap_cb *self = (struct irlap_cb *) data; ASSERT(self != NULL, return;); - ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;); - irda_device_set_media_busy(&self->netdev, FALSE); + irda_device_set_media_busy(self->netdev, FALSE); } diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c index 5f5ed14f3..f884290f7 100644 --- a/net/irda/wrapper.c +++ b/net/irda/wrapper.c @@ -6,7 +6,7 @@ * Status: Experimental. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Mon Aug 4 20:40:53 1997 - * Modified at: Mon Sep 20 11:18:44 1999 + * Modified at: Mon Oct 18 15:51:58 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> @@ -39,12 +39,17 @@ static inline int stuff_byte(__u8 byte, __u8 *buf); -static void state_outside_frame(struct irda_device *idev, __u8 byte); -static void state_begin_frame(struct irda_device *idev, __u8 byte); -static void state_link_escape(struct irda_device *idev, __u8 byte); -static void state_inside_frame(struct irda_device *idev, __u8 byte); +static int state_outside_frame(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte); +static int state_begin_frame(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte); +static int state_link_escape(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte); +static int state_inside_frame(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte); -static void (*state[])(struct irda_device *idev, __u8 byte) = +static int (*state[])(struct net_device *dev, struct iobuff_t *rx_buff, + __u8 byte) = { state_outside_frame, state_begin_frame, @@ -60,9 +65,9 @@ static void (*state[])(struct irda_device *idev, __u8 byte) = */ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) { + int xbofs; int i; int n; - int xbofs; union { __u16 value; __u8 bytes[2]; @@ -77,7 +82,7 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) * additional XBOFS */ if (((struct irda_skb_cb *)(skb->cb))->magic != LAP_MAGIC) { - DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n"); + IRDA_DEBUG(1, __FUNCTION__ "(), wrong magic in skb!\n"); xbofs = 10; } else xbofs = ((struct irda_skb_cb *)(skb->cb))->xbofs; @@ -116,40 +121,6 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize) } /* - * Function async_bump (idev, buf, len) - * - * Got a frame, make a copy of it, and pass it up the stack! - * - */ -static inline void async_bump(struct irda_device *idev, __u8 *buf, int len) -{ - struct sk_buff *skb; - - skb = dev_alloc_skb(len+1); - if (!skb) { - idev->stats.rx_dropped++; - return; - } - - /* Align IP header to 20 bytes */ - skb_reserve(skb, 1); - - /* Copy data without CRC */ - memcpy(skb_put(skb, len-2), buf, len-2); - - /* - * Feed it to IrLAP layer - */ - skb->dev = &idev->netdev; - skb->mac.raw = skb->data; - skb->protocol = htons(ETH_P_IRDA); - - netif_rx(skb); - idev->stats.rx_packets++; - idev->stats.rx_bytes += skb->len; -} - -/* * Function stuff_byte (byte, buf) * * Byte stuff one single byte and put the result in buffer pointed to by @@ -176,38 +147,77 @@ static inline int stuff_byte(__u8 byte, __u8 *buf) } /* - * Function async_unwrap_char (idev, byte) + * Function async_bump (buf, len, stats) + * + * Got a frame, make a copy of it, and pass it up the stack! + * + */ +int async_bump(struct net_device *dev, __u8 *buf, int len) +{ + struct net_device_stats *stats = dev->get_stats(dev); + struct sk_buff *skb; + + skb = dev_alloc_skb(len+1); + if (!skb) { + stats->rx_dropped++; + return -ENOMEM; + } + + /* Align IP header to 20 bytes */ + skb_reserve(skb, 1); + + /* Copy data without CRC */ + memcpy(skb_put(skb, len-2), buf, len-2); + + /* Feed it to IrLAP layer */ + skb->dev = dev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + + netif_rx(skb); + + stats->rx_packets++; + stats->rx_bytes += len; + + return skb->len; +} + +/* + * Function async_unwrap_char (dev, rx_buff, byte) * * Parse and de-stuff frame received from the IrDA-port * */ -inline void async_unwrap_char(struct irda_device *idev, __u8 byte) +inline int async_unwrap_char(struct net_device *dev, struct iobuff_t *rx_buff, + __u8 byte) { - (*state[idev->rx_buff.state]) (idev, byte); + return (*state[rx_buff->state])(dev, rx_buff, byte); } /* - * Function state_outside_frame (idev, byte) + * Function state_outside_frame (dev, rx_buff, byte) * * * */ -static void state_outside_frame(struct irda_device *idev, __u8 byte) +static int state_outside_frame(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte) { switch (byte) { case BOF: - idev->rx_buff.state = BEGIN_FRAME; - idev->rx_buff.in_frame = TRUE; + rx_buff->state = BEGIN_FRAME; + rx_buff->in_frame = TRUE; break; case XBOF: /* idev->xbofs++; */ break; case EOF: - irda_device_set_media_busy(&idev->netdev, TRUE); + irda_device_set_media_busy(dev, TRUE); break; default: break; } + return 0; } /* @@ -216,38 +226,39 @@ static void state_outside_frame(struct irda_device *idev, __u8 byte) * Begin of frame detected * */ -static void state_begin_frame(struct irda_device *idev, __u8 byte) +static int state_begin_frame(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte) { + struct net_device_stats *stats = dev->get_stats(dev); + + /* Time to initialize receive buffer */ + rx_buff->data = rx_buff->head; + rx_buff->len = 0; + rx_buff->fcs = INIT_FCS; + switch (byte) { case BOF: /* Continue */ break; case CE: /* Stuffed byte */ - idev->rx_buff.state = LINK_ESCAPE; - - /* Time to initialize receive buffer */ - idev->rx_buff.data = idev->rx_buff.head; - idev->rx_buff.len = 0; + rx_buff->state = LINK_ESCAPE; break; case EOF: /* Abort frame */ - idev->rx_buff.state = OUTSIDE_FRAME; - - idev->stats.rx_errors++; - idev->stats.rx_frame_errors++; - break; - default: - /* Time to initialize receive buffer */ - idev->rx_buff.data = idev->rx_buff.head; - idev->rx_buff.len = 0; + rx_buff->state = OUTSIDE_FRAME; - idev->rx_buff.data[idev->rx_buff.len++] = byte; + stats->rx_errors++; + stats->rx_frame_errors++; + break; + default: + rx_buff->data[rx_buff->len++] = byte; - idev->rx_buff.fcs = irda_fcs(INIT_FCS, byte); - idev->rx_buff.state = INSIDE_FRAME; + rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); + rx_buff->state = INSIDE_FRAME; break; } + return 0; } /* @@ -256,18 +267,19 @@ static void state_begin_frame(struct irda_device *idev, __u8 byte) * * */ -static void state_link_escape(struct irda_device *idev, __u8 byte) +static int state_link_escape(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte) { switch (byte) { case BOF: /* New frame? */ - idev->rx_buff.state = BEGIN_FRAME; - irda_device_set_media_busy(&idev->netdev, TRUE); + rx_buff->state = BEGIN_FRAME; + irda_device_set_media_busy(dev, TRUE); break; case CE: - DEBUG(4, "WARNING: State not defined\n"); + IRDA_DEBUG(4, "WARNING: State not defined\n"); break; case EOF: /* Abort frame */ - idev->rx_buff.state = OUTSIDE_FRAME; + rx_buff->state = OUTSIDE_FRAME; break; default: /* @@ -275,17 +287,18 @@ static void state_link_escape(struct irda_device *idev, __u8 byte) * following CE, IrLAP p.114 */ byte ^= IRDA_TRANS; - if (idev->rx_buff.len < idev->rx_buff.truesize) { - idev->rx_buff.data[idev->rx_buff.len++] = byte; - idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte); - idev->rx_buff.state = INSIDE_FRAME; + if (rx_buff->len < rx_buff->truesize) { + rx_buff->data[rx_buff->len++] = byte; + rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); + rx_buff->state = INSIDE_FRAME; } else { - DEBUG(1, __FUNCTION__ + IRDA_DEBUG(1, __FUNCTION__ "(), Rx buffer overflow, aborting\n"); - idev->rx_buff.state = OUTSIDE_FRAME; + rx_buff->state = OUTSIDE_FRAME; } break; } + return 0; } /* @@ -294,43 +307,50 @@ static void state_link_escape(struct irda_device *idev, __u8 byte) * Handle bytes received within a frame * */ -static void state_inside_frame(struct irda_device *idev, __u8 byte) +static int state_inside_frame(struct net_device *dev, + struct iobuff_t *rx_buff, __u8 byte) { + struct net_device_stats *stats = dev->get_stats(dev); + int ret = 0; + switch (byte) { case BOF: /* New frame? */ - idev->rx_buff.state = BEGIN_FRAME; - irda_device_set_media_busy(&idev->netdev, TRUE); + rx_buff->state = BEGIN_FRAME; + irda_device_set_media_busy(dev, TRUE); break; case CE: /* Stuffed char */ - idev->rx_buff.state = LINK_ESCAPE; + rx_buff->state = LINK_ESCAPE; break; case EOF: /* End of frame */ - idev->rx_buff.state = OUTSIDE_FRAME; - idev->rx_buff.in_frame = FALSE; + rx_buff->state = OUTSIDE_FRAME; + rx_buff->in_frame = FALSE; - /* Test FCS and deliver frame if it's good */ - if (idev->rx_buff.fcs == GOOD_FCS) { - async_bump(idev, idev->rx_buff.data, - idev->rx_buff.len); + /* Test FCS and signal success if the frame is good */ + if (rx_buff->fcs == GOOD_FCS) { + /* Deliver frame */ + async_bump(dev, rx_buff->data, rx_buff->len); + ret = TRUE; + break; } else { /* Wrong CRC, discard frame! */ - irda_device_set_media_busy(&idev->netdev, TRUE); - - idev->stats.rx_errors++; - idev->stats.rx_crc_errors++; + irda_device_set_media_busy(dev, TRUE); + + stats->rx_errors++; + stats->rx_crc_errors++; } break; default: /* Must be the next byte of the frame */ - if (idev->rx_buff.len < idev->rx_buff.truesize) { - idev->rx_buff.data[idev->rx_buff.len++] = byte; - idev->rx_buff.fcs = irda_fcs(idev->rx_buff.fcs, byte); + if (rx_buff->len < rx_buff->truesize) { + rx_buff->data[rx_buff->len++] = byte; + rx_buff->fcs = irda_fcs(rx_buff->fcs, byte); } else { - DEBUG(1, __FUNCTION__ + IRDA_DEBUG(1, __FUNCTION__ "(), Rx buffer overflow, aborting\n"); - idev->rx_buff.state = OUTSIDE_FRAME; + rx_buff->state = OUTSIDE_FRAME; } break; } + return 0; } |