diff -u --recursive --new-file v2.3.26/linux/CREDITS linux/CREDITS --- v2.3.26/linux/CREDITS Sun Nov 7 16:37:33 1999 +++ linux/CREDITS Wed Nov 10 10:55:31 1999 @@ -508,8 +508,8 @@ S: Belgium N: Cort Dougan -E: cort@cs.nmt.edu -W: http://www.cs.nmt.edu/~cort/ +E: cort@ppc.kernel.org +W: http://www.ppc.kernel.org/~cort/ D: PowerPC S: Computer Science Department S: New Mexico Tech diff -u --recursive --new-file v2.3.26/linux/Documentation/Changes linux/Documentation/Changes --- v2.3.26/linux/Documentation/Changes Sun Nov 7 16:37:33 1999 +++ linux/Documentation/Changes Sun Nov 7 16:34:00 1999 @@ -63,6 +63,7 @@ - Pcmcia-cs 3.1.2 ; cardmgr -V - PPP 2.3.9 ; pppd --version - Util-linux 2.9i ; chsh -v +- isdn4k-utils v3.1beta7 ; isdnctrl 2>&1|grep version Upgrade notes ************* @@ -245,9 +246,6 @@ DHCP clients for 2.0 do not work with the new networking code in the 2.2 kernel. You will need to upgrade your dhcpcd / dhcpclient. - The ISDN code in the stock 2.2 kernel may not work for you. If it -doesn't, look in ftp://ftp.suse.com/pub/isdn4linux for updated versions. - In 2.0.x the kernel could be configured to drop source routed IP packets via a compile time configuration option. In 2.2.x, this has been replaced by a sysctl. See Documentation/networking/ip-sysctl.txt @@ -494,6 +492,15 @@ so be sure to check that when you recompile. +ISDN4Linux +========== +Since 2.3.27 here is a new length of the phonenumber field, old utils +have to recompile, a upgrade to isdn4k-utils.v3.1beta7 or later is +recomented. +Older isdn4k-utils versions don't support EXTRAVERSION into kernel version +string. + + Where to get the files ********************** @@ -774,6 +781,11 @@ The 2.5 release: ftp://ftp.gnu.org/gnu/patch/patch-2.5.tar.gz + +ISDN4Linux +========== +The v3.1beta7 release: +ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/testing/isdn4k-utils.v3.1beta7.tar.gz Other Info ========== diff -u --recursive --new-file v2.3.26/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.3.26/linux/Documentation/Configure.help Sun Nov 7 16:37:33 1999 +++ linux/Documentation/Configure.help Thu Nov 11 16:03:36 1999 @@ -1680,6 +1680,29 @@ Say Y here to enable support in the dumb serial driver to support the HUB6 card. +PCMCIA serial device support +CONFIG_PCMCIA_SERIAL_CS + Say Y here to enable support for 16-bit PCMCIA serial devices, + including serial port cards, modems, and the modem functions of + multifunction ethernet/modem cards. + + This driver 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 serial_cs.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt. If unsure, + say N. + +CardBus serial device support +CONFIG_PCMCIA_SERIAL_CB + Say Y here to enable support for CardBus serial devices, including + the modem functions of multifunction ethernet/modem devices. + + This driver 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 serial_cb.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt. If unsure, + say N. + PCI support CONFIG_PCI Find out whether you have a PCI motherboard. PCI is the name of a @@ -5607,6 +5630,36 @@ module, say M here and read Documentation/modules.txt. If unsure, say N. +3Com 3c575 CardBus support +CONFIG_PCMCIA_3C575 + This driver supports the 3Com 3c575 series of CardBus Fast Ethernet + adapters. + + This driver can only be compiled as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called 3c575_cb.o. If you want to do that, say M + here and read Documentation/modules.txt. If unsure, say N. + +DEC Tulip CardBus support +CONFIG_PCMCIA_TULIP + This driver supports CardBus Fast Ethernet adapters based on DEC + Tulip and compatible chipsets. + + This driver can only be compiled as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called tulip_cb.o. If you want to do that, say M + here and read Documentation/modules.txt. If unsure, say N. + +SMC EPIC CardBus support +CONFIG_PCMCIA_EPIC100 + This driver supports CardBus Fast Ethernet adapters based on the SMC + EPIC chipset. + + This driver can only be compiled as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called epic100_cb.o. If you want to do that, say + M here and read Documentation/modules.txt. If unsure, say N. + Aviator/Raytheon 2.4MHz wireless support CONFIG_PCMCIA_RAYCS Say Y here if you intend to attach an Aviator/Raytheon PCMCIA @@ -7919,23 +7972,11 @@ Note that you must say Y to "/proc filesystem support" below for this to work. -Generic ACPI support +ACPI support CONFIG_ACPI Advanced Configuration and Power Interface (ACPI) is an interface specification to support power management of peripherals. If your system supports it, say Y here. - - 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 acpi.o. If you want to compile it as a - module, say M here and read Documentation/modules.txt. - -PIIX4 ACPI support -CONFIG_PIIX4_ACPI - If you have a PIIX4 based motherboard (PCI ISA IDE Xcelerator - (PIIX4) is a multi-function PCI device) and you want support for - Advanced Configuration and Power Interface (ACPI) to support power - management of peripherals, say Y here. Minix fs support CONFIG_MINIX_FS diff -u --recursive --new-file v2.3.26/linux/Documentation/acpi.txt linux/Documentation/acpi.txt --- v2.3.26/linux/Documentation/acpi.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/acpi.txt Wed Nov 10 20:01:03 1999 @@ -0,0 +1,125 @@ +ACPI Driver Interface +--------------------- + +Overview: +1) Register each instance of a device with "acpi_register" +2) Call "acpi_access" before accessing the hardware. + (this will ensure that the hardware is awake and ready) +3) "acpi_transition" callback is called before entering D1-D3 + or after entering D0 +4) Call "acpi_dev_idle" when the device is not being used + (not required by will improve idle detection) +5) When unloaded, unregister the device with "acpi_unregister" + +/* + * Description: Register a device with the ACPI subsystem + * + * Parameters: + * info - static device information + * type - device type + * hid - PnP identifier (or 0 if unknown) + * trans - device state transition callback + * adr - bus number and address or unique id + * + * Returns: Registered ACPI device or NULL on error + * + * Details: The device type, bus number, and bus address should be + * enough information to reconstruct the device tree and + * identify device dependencies + * + * Examples: + * struct acpi_dev_info info = {ACPI_SYS_DEV, ACPI_VGA_HID, vga_trans}; + * dev = acpi_register(&info, 0); + * + * struct pci_dev *pci_dev = pci_find_dev(...); + * struct acpi_dev_info info = {ACPI_PCI_DEV, 0, trans}; + * dev = acpi_register(&info, ACPI_PCI_ADR(pci_dev)); + */ +struct acpi_dev *acpi_register(struct acpi_dev_info *info, unsigned long adr); + +/* + * Description: Unregister a device with ACPI + * + * Parameters: + * dev - ACPI device previously returned from acpi_register + */ +void acpi_unregister(struct acpi_dev *dev); + +/* + * Device idle/use detection + * + * In general, drivers for all devices should call "acpi_access" + * before accessing the hardware (ie. before reading or modifying + * a hardware register). Request or packet-driven drivers should + * additionally call "acpi_idle" when a device is not being used. + * + * Examples: + * 1) A keyboard driver would call acpi_access whenever a key is pressed + * 2) A network driver would call acpi_access before submitting + * a packet for transmit or receive and acpi_idle when its + * transfer and receive queues are empty. + * 3) A VGA driver would call acpi_access before it accesses any + * of the video controller registers + * + * Ultimately, the ACPI policy manager uses the access and idle + * information to decide when to transition devices between + * device states. + */ + +/* + * Description: Update device access time and wake up device, if necessary + * + * Parameters: + * dev - ACPI device previously returned from acpi_register + * + * Details: If called from an interrupt handler acpi_access updates + * access time but should never need to wake up the device + * (if device is generating interrupts, it should be awake + * already) This is important as we can not wake up + * devices (run AML, etc.) from an interrupt handler. + */ +void acpi_access(struct acpi_dev *dev); + +/* + * Description: Identify device as currently being idle + * + * Parameters: + * dev - ACPI device previously returned from acpi_register + * + * Details: A call to acpi_idle might signal to the policy manager + * to put a device to sleep. If a new device request arrives + * between the call to acpi_idle and the acpi_transition + * callback, the driver should fail the acpi_transition request. + */ +void acpi_dev_idle(struct acpi_dev *dev); + +/* + * Transition function + * + * Parameters: + * dev - ACPI device previously returned from acpi_register + * state - the device state being entered + * + * Returns: 0 if the state transition is possible and context saved + * EINVAL if the requested device state is not supported + * EBUSY if the device is now busy and can not transition + * ENOMEM if the device was unable to save context (out of memory) + * + * Details: The device state transition function will be called + * before the device is transitioned into the D1-D3 states + * or after the device is transitioned into the D0 state. + * The device driver should save (D1-D3) or restore (D0) + * device context when the transition function is called. + * + * For system devices, the ACPI subsystem will perform + * the actual hardware state transition itself. For bus + * devices, after the driver's acpi_transition function + * is called, the bus driver's acpi_transition function + * is called to perform the actual hardware state transition. + * + * Once a driver returns 0 (success) from a transition + * to D1-3 request, it should not process any further + * requests or access the device hardware until a + * call to "acpi_access" is made. + */ +typedef int (*acpi_transition)(struct acpi_dev *dev, acpi_dstate_t state); diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/00-INDEX linux/Documentation/isdn/00-INDEX --- v2.3.26/linux/Documentation/isdn/00-INDEX Wed Apr 1 16:20:56 1998 +++ linux/Documentation/isdn/00-INDEX Sun Nov 7 16:34:00 1999 @@ -6,12 +6,18 @@ - description of Linklevel and Hardwarelevel ISDN interface. README - general info on what you need and what to do for Linux ISDN. +README.FAQ + - general info for FAQ. README.audio - info for running audio over ISDN. +README.fax + - info for using Fax over ISDN. README.icn - info on the ICN-ISDN-card and its driver. README.HiSax - info on the HiSax driver which replaces the old teles. +README.hfc-pci + - info on hfc-pci based cards. README.pcbit - info on the PCBIT-D ISDN adapter and driver. README.syncppp @@ -22,8 +28,12 @@ - info on driver for AVM-B1 ISDN card. README.act2000 - info on driver for IBM ACT-2000 card. +README.eicon + - info on driver for Eicon active cards. README.concap - info on "CONCAP" ecapsulation protocol interface used for X.25. +README.diversion + - info on module for isdn diversion services. README.sc - info on driver for Spellcaster cards. README.x25 diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/CREDITS linux/Documentation/isdn/CREDITS --- v2.3.26/linux/Documentation/isdn/CREDITS Thu Aug 12 09:42:32 1999 +++ linux/Documentation/isdn/CREDITS Sun Nov 7 16:34:00 1999 @@ -15,8 +15,11 @@ For contribution of man-pages, the imontty-tool and a perfect maintaining of the mailing-list at hub-wue. +Matthias Hessler (hessler@isdn4linux.de) + For creating and maintaining the FAQ. + Bernhard Hailer (Bernhard.Hailer@lrz.uni-muenchen.de) - For maintaining the FAQ. + For creating the FAQ, and the leafsite HOWTO. Michael 'Ghandi' Herold (michael@abadonna.franken.de) For contribution of the vbox answering machine. diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README linux/Documentation/isdn/README --- v2.3.26/linux/Documentation/isdn/README Thu Aug 12 09:42:33 1999 +++ linux/Documentation/isdn/README Sun Nov 7 16:34:00 1999 @@ -11,7 +11,7 @@ necessary. Those programs and some contributed utilities are available at - ftp.franken.de + ftp.isdn4linux.de /pub/isdn4linux/isdn4k-utils-.tar.gz @@ -22,19 +22,23 @@ reasons, the mailing-list's primary language is german. However mails written in english have been welcome all the time. - to subscribe: write a email to majordomo@hub-wue.franken.de, + to subscribe: write a email to majordomo@listserv.isdn4linux.de, Subject irrelevant, in the message body: subscribe isdn4linux - To write to the mailing-list, write to isdn4linux@hub-wue.franken.de + To write to the mailing-list, write to isdn4linux@listserv.isdn4linux.de This mailinglist is bidirectionally gated to the newsgroup de.alt.comm.isdn4linux - There is also a well maintained FAQ (both english and german) available - at ftp.franken.de in /pub/isdn4linux/FAQ/ - This FAQ is also available at http://www.lrz-muenchen.de/~ui161ab/www/isdn/ + There is also a well maintained FAQ in English available at + http://www.mhessler.de/i4lfaq/ + It can be viewed online, or downloaded in sgml/text/html format. + The FAQ can also be viewed online at + http://www.isdn4inux.de/faq/ + or downloaded from + ftp://ftp.isdn4linux.de/pub/isdn4linux/FAQ/ 1.1 Technical details @@ -266,6 +270,8 @@ 23 0 Bit coded register: Bit 0: 0 = Add CPN to RING message off 1 = Add CPN to RING message on + Bit 1: 0 = Add CPN to FCON message off + 1 = Add CPN to FCON message on Last but not least a (at the moment fairly primitive) device to request the line-status (/dev/isdninfo) is made available. @@ -581,7 +587,7 @@ If other drivers will not be affected, I will include the changes in the next release. For developers only, there is a second mailing-list. Write to me - (fritz@wuemaus.franken.de), if you want to join that list. + (fritz@isdn4linux.de), if you want to join that list. Have fun! diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README.FAQ linux/Documentation/isdn/README.FAQ --- v2.3.26/linux/Documentation/isdn/README.FAQ Wed Dec 31 16:00:00 1969 +++ linux/Documentation/isdn/README.FAQ Sun Nov 7 16:34:00 1999 @@ -0,0 +1,26 @@ + +The FAQ for isdn4linux +====================== + +Please note that there is a big FAQ available in the isdn4k-utils. +You find it in: + isdn4k-utils/FAQ/i4lfaq.sgml + +In case you just want to see the FAQ online, or download the newest version, +you can have a look at my website: +http://www.mhessler.de/i4lfaq/ (view + download) +or: +http://www.isdn4linux.de/faq/ (view) + +As the extension tells, the FAQ is in SGML format, and you can convert it +into text/html/... format by using the sgml2txt/sgml2html/... tools. +Alternatively, you can also do a 'configure; make all' in the FAQ directory. + + +Please have a look at the FAQ before posting anything in the Mailinglist, +or the newsgroup! + + +Matthias Hessler +hessler@isdn4linux.de + diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README.HiSax linux/Documentation/isdn/README.HiSax --- v2.3.26/linux/Documentation/isdn/README.HiSax Thu Aug 26 13:05:34 1999 +++ linux/Documentation/isdn/README.HiSax Sun Nov 7 16:34:00 1999 @@ -63,6 +63,7 @@ Scitel Quadro Gazel ISDN cards HFC-PCI based cards +Winbond W6692 based cards Note: PCF, PCF-Pro: up to now, only the ISDN part is supported PCC-8: not tested yet @@ -182,6 +183,7 @@ 34 Gazel ISDN cards (ISA) irq,io 34 Gazel ISDN cards (PCI) none 35 HFC 2BDS0 PCI none + 36 W6692 based PCI cards none At the moment IRQ sharing is only possible with PCI cards. Please make sure @@ -285,6 +287,7 @@ 34 Gazel ISDN cards (ISA) pa=irq, pb=io 34 Gazel ISDN cards (PCI) no parameter 35 HFC 2BDS0 PCI no parameter + 36 W6692 based PCI cards none Running the driver ------------------ @@ -425,6 +428,7 @@ Klaus Lichtenwalder (Klaus.Lichtenwalder@WebForum.DE), for ELSA PCMCIA support Enrik Berkhan (enrik@starfleet.inka.de) for S0BOX specific stuff Ton van Rosmalen for Teles PCI + Petr Novak for Winbond W6692 support and more people who are hunting bugs. (If I forgot somebody, please send me a mail). diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README.avmb1 linux/Documentation/isdn/README.avmb1 --- v2.3.26/linux/Documentation/isdn/README.avmb1 Thu Aug 12 09:42:33 1999 +++ linux/Documentation/isdn/README.avmb1 Sun Nov 7 16:34:00 1999 @@ -169,7 +169,7 @@ Questions --------- -Check out the FAQ (ftp.franken.de) or subscribe to the +Check out the FAQ (ftp.isdn4linux.de) or subscribe to the linux-avmb1@calle.in-berlin.de mailing list by sending a mail to majordomo@calle.in-berlin.de with subscribe linux-avmb1 diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README.eicon linux/Documentation/isdn/README.eicon --- v2.3.26/linux/Documentation/isdn/README.eicon Thu Aug 12 09:42:33 1999 +++ linux/Documentation/isdn/README.eicon Sun Nov 7 16:34:00 1999 @@ -1,6 +1,6 @@ -$Id: README.eicon,v 1.4 1999/07/11 17:17:30 armin Exp $ +$Id: README.eicon,v 1.5 1999/10/11 18:13:25 armin Exp $ -(c) 1999 Cytronics & Melware +(c) 1999 Cytronics & Melware (info@melware.de) This document describes the eicon driver for the Eicon.Diehl active ISDN cards. @@ -24,17 +24,26 @@ Supported Cards ---------------- +=============== +Old ISA type +------------ - S-Card ISA - SX-Card ISA - SXn-Card ISA - SCOM-Card ISA - Quadro-Card ISA - S2M-Card ISA + +DIVA Server family +------------------ - DIVA Server BRI/PCI 2M - DIVA Server PRI/PCI 2M (9M 23M 30M) - (Only analog modem functions of the DSPs are currently implemented) + supported functions of onboard DSPs: + - analog modem + - fax group 2/3 (Fax Class 2 commands) + - DTMF detection + ISDN D-Channel Protocols ------------------------ @@ -76,6 +85,10 @@ Details about using the eiconctrl utility are in 'man eiconctrl' or will be printed by starting eiconctrl without any parameters. +Thanks to + Deutsche Mailbox Saar-Lor-Lux GmbH + for sponsoring and testing fax + capabilities with Diva Server cards. Any reports about bugs, errors and even wishes are welcome. diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README.fax linux/Documentation/isdn/README.fax --- v2.3.26/linux/Documentation/isdn/README.fax Thu Aug 12 09:42:33 1999 +++ linux/Documentation/isdn/README.fax Sun Nov 7 16:34:00 1999 @@ -9,7 +9,7 @@ - You need the commands as dummy, because you are using hylafax (with patch) for AVM capi. -- You want to use the fax capabillities of your isdn-card. +- You want to use the fax capabilities of your isdn-card. (supported cards are listed below) @@ -21,8 +21,12 @@ Supported ISDN-Cards -------------------- -Eicon DIVA Server BRI/PCI (will be ready soon) -Eicon DIVA Server PRI/PCI (will be ready soon) +Eicon DIVA Server BRI/PCI + - full support with both B-channels. + +Eicon DIVA Server PRI/PCI + - full support on amount of B-channels + depending on DSPs on board. diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README.hfc-pci linux/Documentation/isdn/README.hfc-pci --- v2.3.26/linux/Documentation/isdn/README.hfc-pci Thu Aug 12 09:42:33 1999 +++ linux/Documentation/isdn/README.hfc-pci Sun Nov 7 16:34:00 1999 @@ -20,6 +20,21 @@ devices show a output with a line beginning of HEX: for the providers exchange and ECHO: for isdn devices sending to the provider. +If more than one HFC-PCI cards are installed, a specific card may be selected +at the hisax module load command line. Supply the load command with the desired +IO-address of the desired card. +Example: +There tree cards installed in your machine at IO-base addresses 0xd000, 0xd400 +and 0xdc00 +If you want to use the card at 0xd400 standalone you should supply the insmod +or depmod with type=35 io=0xd400. +If you want to use all three cards, but the order needs to be at 0xdc00,0xd400, +0xd000 you may give the parameters type=35,35,35 io=0xdc00,0xd400,0xd00 +Then the desired card will be the initialised in the desired order. +If the io parameter is used the io addresses of all used cards should be +supplied else the parameter is assumed 0 and a auto search for a free card is +invoked which may not give the wanted result. + Comments and reports to werner@isdn4linux.de or werner@titro.de . diff -u --recursive --new-file v2.3.26/linux/Documentation/isdn/README.pcbit linux/Documentation/isdn/README.pcbit --- v2.3.26/linux/Documentation/isdn/README.pcbit Tue Apr 28 14:22:04 1998 +++ linux/Documentation/isdn/README.pcbit Sun Nov 7 16:34:00 1999 @@ -32,7 +32,7 @@ the manufacturer in order to solve this problem. Information/hints/help can be obtained in the linux isdn -mailing list (isdn4linux@hub-wue.franken.de) or directly from me. +mailing list (isdn4linux@listserv.isdn4linux.de) or directly from me. regards, Pedro. diff -u --recursive --new-file v2.3.26/linux/Documentation/oops-tracing.txt linux/Documentation/oops-tracing.txt --- v2.3.26/linux/Documentation/oops-tracing.txt Mon Oct 4 15:49:29 1999 +++ linux/Documentation/oops-tracing.txt Mon Nov 8 10:29:52 1999 @@ -16,6 +16,37 @@ linux-kernel@vger.rutgers.edu. Thanks for your help in making Linux as stable as humanly possible. +Where is the_oops.txt? +---------------------- + +Normally the Oops text is read from the kernel buffers by klogd and +handed to syslogd which writes it to a syslog file, typically +/var/log/messages (depends on /etc/syslog.conf). Sometimes klogd dies, +in which case you can run dmesg > file to read the data from the kernel +buffers and save it. Or you can cat /proc/kmsg > file, however you +have to break in to stop the transfer, kmsg is a "never ending file". +If the machine has crashed so badly that you cannot enter commands or +the disk is not available then you have three options :- + +(1) Hand copy the text from the screen and type it in after the machine + has restarted. Messy but it is the only option if you have not + planned for a crash. + +(2) Boot with a serial console (see Documentation/serial-console.txt), + run a null modem to a second machine and capture the output there + using your favourite communication program. Minicom works well. + +(3) Patch the kernel with one of the crash dump patches. These save + data to a floppy disk or video rom or a swap partition. None of + these are standard kernel patches so you have to find and apply + them yourself. Search kernel archives for kmsgdump, lkcd and + oops+smram. + +No matter how you capture the log output, feed the resulting file to +ksymoops along with /proc/ksyms and /proc/modules that applied at the +time of the crash. /var/log/ksymoops can be useful to capture the +latter, man ksymoops for details. + Full Information ---------------- diff -u --recursive --new-file v2.3.26/linux/MAINTAINERS linux/MAINTAINERS --- v2.3.26/linux/MAINTAINERS Sun Nov 7 16:37:33 1999 +++ linux/MAINTAINERS Wed Nov 10 10:55:31 1999 @@ -482,10 +482,18 @@ M: perex@suse.cz S: Maintained -ISDN SUBSYSTEM +ISDN SUBSYSTEM (general) P: Fritz Elfert -M: fritz@wuemaus.franken.de -L: isdn4linux@hub-wue.franken.de +M: fritz@isdn4linux.de +L: isdn4linux@listserv.isdn4linux.de +W: http://www.isdn4linux.de +S: Maintained + +ISDN SUBSYSTEM (card drivers) +P: Karsten Keil +M: kkeil@suse.de +L: isdn4linux@listserv.isdn4linux.de +W: http://www.isdn4linux.de S: Maintained JOYSTICK DRIVER @@ -514,10 +522,10 @@ L: linux-x25@vger.rutgers.edu S: Maintained -LINUX FOR POWERPC (PREP) +LINUX FOR POWERPC P: Cort Dougan -M: cort@cs.nmt.edu -W: http://linuxppc.cs.nmt.edu/ +M: cort@ppc.kernel.org +W: http://www.ppc.kernel.org/ S: Maintained LINUX FOR POWER MACINTOSH diff -u --recursive --new-file v2.3.26/linux/Makefile linux/Makefile --- v2.3.26/linux/Makefile Sun Nov 7 16:37:33 1999 +++ linux/Makefile Thu Nov 11 16:03:36 1999 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 26 +SUBLEVEL = 27 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) @@ -166,6 +166,10 @@ DRIVERS := $(DRIVERS) drivers/net/pcmcia/pcmcia_net.o endif +ifeq ($(CONFIG_PCMCIA_CHRDEV),y) +DRIVERS := $(DRIVERS) drivers/char/pcmcia/pcmcia_char.o +endif + ifdef CONFIG_DIO DRIVERS := $(DRIVERS) drivers/dio/dio.a endif @@ -329,7 +333,7 @@ modules: $(patsubst %, _mod_%, $(SUBDIRS)) modules/MARKER: - mkdir modules + mkdir -p modules touch modules/MARKER $(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h include/config/MARKER modules/MARKER @@ -362,6 +366,8 @@ if [ -f IRDA_MODULES ]; then inst_mod IRDA_MODULES net; fi; \ if [ -f USB_MODULES ]; then inst_mod USB_MODULES usb; fi; \ if [ -f PCMCIA_MODULES ]; then inst_mod PCMCIA_MODULES pcmcia; fi; \ + if [ -f PCMCIA_NET_MODULES ]; then inst_mod PCMCIA_NET_MODULES pcmcia; fi; \ + if [ -f PCMCIA_CHAR_MODULES ]; then inst_mod PCMCIA_CHAR_MODULES pcmcia; fi; \ \ ls *.o > $$MODLIB/.allmods; \ echo $$MODULES | tr ' ' '\n' | sort | comm -23 $$MODLIB/.allmods - > $$MODLIB/.misc; \ @@ -390,6 +396,7 @@ rm -f .tmp* rm -f drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c rm -f drivers/char/conmakehash + rm -f drivers/pci/devlist.h drivers/pci/gen-devlist rm -f drivers/sound/bin2hex drivers/sound/hex2hex rm -f net/khttpd/make_times_h rm -f net/khttpd/times.h diff -u --recursive --new-file v2.3.26/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c --- v2.3.26/linux/arch/alpha/kernel/alpha_ksyms.c Mon Oct 11 15:38:14 1999 +++ linux/arch/alpha/kernel/alpha_ksyms.c Mon Nov 8 14:28:34 1999 @@ -206,3 +206,5 @@ EXPORT_SYMBOL_NOVERS(__remqu); EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memset); + +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.3.26/linux/arch/alpha/kernel/process.c Tue Aug 31 17:29:12 1999 +++ linux/arch/alpha/kernel/process.c Mon Nov 8 14:28:34 1999 @@ -406,3 +406,35 @@ unlock_kernel(); return error; } + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long schedule_frame; + unsigned long pc; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + /* + * This one depends on the frame size of schedule(). Do a + * "disass schedule" in gdb to find the frame size. Also, the + * code assumes that sleep_on() follows immediately after + * interruptible_sleep_on() and that add_timer() follows + * immediately after interruptible_sleep(). Ugly, isn't it? + * Maybe adding a wchan field to task_struct would be better, + * after all... + */ + + pc = thread_saved_pc(&p->thread); + if (pc >= first_sched && pc < last_sched) { + schedule_frame = ((unsigned long *)p->thread.ksp)[6]; + return ((unsigned long *)schedule_frame)[12]; + } + return pc; +} diff -u --recursive --new-file v2.3.26/linux/arch/arm/kernel/armksyms.c linux/arch/arm/kernel/armksyms.c --- v2.3.26/linux/arch/arm/kernel/armksyms.c Mon Nov 1 13:56:26 1999 +++ linux/arch/arm/kernel/armksyms.c Mon Nov 8 14:28:34 1999 @@ -237,3 +237,5 @@ EXPORT_SYMBOL_NOVERS(__down_interruptible_failed); EXPORT_SYMBOL_NOVERS(__down_trylock_failed); EXPORT_SYMBOL_NOVERS(__up_wakeup); + +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c --- v2.3.26/linux/arch/arm/kernel/process.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/process.c Mon Nov 8 14:28:34 1999 @@ -337,3 +337,31 @@ return __ret; } +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long fp, lr; + unsigned long stack_page; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + stack_page = 4096 + (unsigned long)p; + fp = get_css_fp(&p->thread); + do { + if (fp < stack_page || fp > 4092+stack_page) + return 0; + lr = pc_pointer (((unsigned long *)fp)[-1]); + if (lr < first_sched || lr > last_sched) + return lr; + fp = *(unsigned long *) (fp - 12); + } while (count ++ < 16); + return 0; +} diff -u --recursive --new-file v2.3.26/linux/arch/arm/mm/small_page.c linux/arch/arm/mm/small_page.c --- v2.3.26/linux/arch/arm/mm/small_page.c Mon Nov 1 13:56:26 1999 +++ linux/arch/arm/mm/small_page.c Thu Nov 11 10:33:42 1999 @@ -33,7 +33,7 @@ * second level page tables on 32-bit ARMs. * * Theory: - * We "misuse" the Linux memory management system. We use __get_pages + * We "misuse" the Linux memory management system. We use alloc_page * to allocate a page and then mark it as reserved. The Linux memory * management system will then ignore the "offset", "next_hash" and * "pprev_hash" entries in the mem_map for this page. @@ -119,7 +119,7 @@ return page_address(page) + (offset << order->shift); need_new_page: - page = __get_pages(priority, 0); + page = alloc_page(priority); if (!order->queue) { if (!page) goto no_page; diff -u --recursive --new-file v2.3.26/linux/arch/i386/boot/compressed/misc.c linux/arch/i386/boot/compressed/misc.c --- v2.3.26/linux/arch/i386/boot/compressed/misc.c Thu Aug 26 13:05:34 1999 +++ linux/arch/i386/boot/compressed/misc.c Thu Nov 11 10:33:42 1999 @@ -9,6 +9,7 @@ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ +#include #include #include diff -u --recursive --new-file v2.3.26/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.3.26/linux/arch/i386/defconfig Sun Nov 7 16:37:33 1999 +++ linux/arch/i386/defconfig Thu Nov 11 16:39:48 1999 @@ -299,6 +299,9 @@ # CONFIG_PCMCIA_NMCLAN is not set # CONFIG_PCMCIA_SMC91C92 is not set # CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_3C575 is not set +# CONFIG_PCMCIA_TULIP is not set +# CONFIG_PCMCIA_EPIC100 is not set CONFIG_PCMCIA_RAYCS=y # CONFIG_PCMCIA_NETWAVE is not set # CONFIG_PCMCIA_WAVELAN is not set @@ -345,6 +348,10 @@ # CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set # CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -366,6 +373,12 @@ # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set + +# +# PCMCIA character device support +# +# CONFIG_PCMCIA_SERIAL_CS is not set +# CONFIG_PCMCIA_SERIAL_CB is not set # # USB drivers - not for the faint of heart diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v2.3.26/linux/arch/i386/kernel/Makefile Sat Oct 9 11:47:50 1999 +++ linux/arch/i386/kernel/Makefile Thu Nov 11 11:39:13 1999 @@ -59,7 +59,4 @@ O_OBJS += visws_apic.o endif -head.o: head.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o - include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c --- v2.3.26/linux/arch/i386/kernel/apm.c Sun Nov 7 16:37:34 1999 +++ linux/arch/i386/kernel/apm.c Mon Nov 8 10:18:45 1999 @@ -1367,8 +1367,10 @@ /* Install our power off handler.. */ if (power_off_enabled) acpi_power_off = apm_power_off; - sysrq_power_off = apm_power_off; +#ifdef CONFIG_MAGIC_SYSRQ + sysrq_power_off = apm_power_off; +#endif apm_mainloop(); return 0; } diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- v2.3.26/linux/arch/i386/kernel/head.S Fri Oct 22 13:21:45 1999 +++ linux/arch/i386/kernel/head.S Thu Nov 11 10:33:42 1999 @@ -8,6 +8,7 @@ */ .text +#include #include #include #include diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.3.26/linux/arch/i386/kernel/i386_ksyms.c Mon Nov 1 13:56:26 1999 +++ linux/arch/i386/kernel/i386_ksyms.c Mon Nov 8 10:19:19 1999 @@ -129,3 +129,4 @@ EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.3.26/linux/arch/i386/kernel/irq.c Fri Oct 22 13:21:45 1999 +++ linux/arch/i386/kernel/irq.c Mon Nov 8 10:47:28 1999 @@ -650,6 +650,19 @@ int retval; struct irqaction * action; +#if 1 + /* + * Sanity-check: shared interrupts should REALLY pass in + * a real dev-ID, otherwise we'll have trouble later trying + * to figure out which interrupt is which (messes up the + * interrupt freeing logic etc). + */ + if (irqflags & SA_SHIRQ) { + if (!dev_id) + printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]); + } +#endif + if (irq >= NR_IRQS) return -EINVAL; if (!handler) diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/mca.c linux/arch/i386/kernel/mca.c --- v2.3.26/linux/arch/i386/kernel/mca.c Mon Nov 1 13:56:26 1999 +++ linux/arch/i386/kernel/mca.c Tue Nov 9 11:56:37 1999 @@ -29,6 +29,9 @@ * David Weinehall March 24th, 1999 * - Fixed the output of 'Driver Installed' in /proc/mca/pos * - Made the Integrated Video & SCSI show up even if they have id 0000 + * + * AV November 9th, 1999 + * - switched to regular procfs methods. */ #include @@ -105,52 +108,7 @@ /*--------------------------------------------------------------------*/ #ifdef CONFIG_PROC_FS - static void mca_do_proc_init(void); -static int mca_default_procfn(char* buf, int slot); - -static ssize_t proc_mca_read(struct file*, char*, size_t, loff_t *); - -static struct file_operations proc_mca_operations = { - NULL, /* llseek */ - proc_mca_read, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* open */ - NULL, /* flush */ - NULL, /* release */ - NULL, /* fsync */ - NULL, /* fascync */ - NULL, /* check_media_change */ - NULL, /* revalidate */ - NULL /* lock */ -}; - -static struct inode_operations proc_mca_inode_operations = { - &proc_mca_operations, /* default file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; #endif /*--------------------------------------------------------------------*/ @@ -657,7 +615,8 @@ #ifdef CONFIG_PROC_FS -int get_mca_info(char *buf) +int get_mca_info(char *page, char **start, off_t off, + int count, int *eof, void *data) { int i, j, len = 0; @@ -667,101 +626,45 @@ for(i=0; islot[i].pos[j]); - len += sprintf(buf+len, " %s\n", mca_info->slot[i].name); + len += sprintf(page+len, "%02x ", mca_info->slot[i].pos[j]); + len += sprintf(page+len, " %s\n", mca_info->slot[i].name); } /* Format POS registers of integrated video subsystem */ - len += sprintf(buf+len, "Video : "); + len += sprintf(page+len, "Video : "); for(j=0; j<8; j++) - len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]); - len += sprintf(buf+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name); + len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]); + len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name); /* Format POS registers of integrated SCSI subsystem */ - len += sprintf(buf+len, "SCSI : "); + len += sprintf(page+len, "SCSI : "); for(j=0; j<8; j++) - len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]); - len += sprintf(buf+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name); + len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]); + len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name); } else { /* Leave it empty if MCA not detected - this should *never* * happen! */ } + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; return len; } - -/*--------------------------------------------------------------------*/ - -void __init mca_do_proc_init(void) -{ - int i; - struct proc_dir_entry* node = NULL; - - if(mca_info == NULL) return; /* Should never happen */ - - proc_register(proc_mca, &(struct proc_dir_entry) { - PROC_MCA_REGISTERS, 3, "pos", S_IFREG|S_IRUGO, - 1, 0, 0, 0, &proc_mca_inode_operations,}); - - proc_register(proc_mca, &(struct proc_dir_entry) { - PROC_MCA_MACHINE, 7, "machine", S_IFREG|S_IRUGO, - 1, 0, 0, 0, &proc_mca_inode_operations,}); - - /* Initialize /proc/mca entries for existing adapters */ - - for(i = 0; i < MCA_NUMADAPTERS; i++) { - mca_info->slot[i].procfn = 0; - mca_info->slot[i].dev = 0; - - if(!mca_isadapter(i)) continue; - - node = (struct proc_dir_entry *)kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL); - - if(node == NULL) { - printk("Failed to allocate memory for MCA proc-entries!"); - return; - } - memset(node, 0, sizeof(struct proc_dir_entry)); - - if(i < MCA_MAX_SLOT_NR) { - node->low_ino = PROC_MCA_SLOT + i; - node->namelen = sprintf(mca_info->slot[i].procname, - "slot%d", i+1); - } else if(i == MCA_INTEGVIDEO) { - node->low_ino = PROC_MCA_VIDEO; - node->namelen = sprintf(mca_info->slot[i].procname, - "video"); - } else if(i == MCA_INTEGSCSI) { - node->low_ino = PROC_MCA_SCSI; - node->namelen = sprintf(mca_info->slot[i].procname, - "scsi"); - } - node->name = mca_info->slot[i].procname; - node->mode = S_IFREG | S_IRUGO; - node->ops = &proc_mca_inode_operations; - proc_register(proc_mca, node); - } - -} /* mca_do_proc_init() */ - /*--------------------------------------------------------------------*/ -int mca_default_procfn(char* buf, int slot) +static int mca_default_procfn(char* buf, struct MCA_adapter *p) { int len = 0, i; - - /* This really shouldn't happen... */ - - if(mca_info == NULL) { - *buf = 0; - return 0; - } + int slot = p - mca_info->slot; /* Print out the basic information */ @@ -772,21 +675,21 @@ } else if(slot == MCA_INTEGVIDEO) { len += sprintf(buf+len, "Integrated Video Adapter\n"); } - if(mca_info->slot[slot].name[0]) { + if(p->name[0]) { /* Drivers might register a name without /proc handler... */ len += sprintf(buf+len, "Adapter Name: %s\n", - mca_info->slot[slot].name); + p->name); } else { len += sprintf(buf+len, "Adapter Name: Unknown\n"); } len += sprintf(buf+len, "Id: %02x%02x\n", - mca_info->slot[slot].pos[1], mca_info->slot[slot].pos[0]); + p->pos[1], p->pos[0]); len += sprintf(buf+len, "Enabled: %s\nPOS: ", mca_isenabled(slot) ? "Yes" : "No"); for(i=0; i<8; i++) { - len += sprintf(buf+len, "%02x ", mca_info->slot[slot].pos[i]); + len += sprintf(buf+len, "%02x ", p->pos[i]); } len += sprintf(buf+len, "\nDriver Installed: %s", mca_is_adapter_used(slot) ? "Yes" : "No"); @@ -796,111 +699,80 @@ return len; } /* mca_default_procfn() */ -static int get_mca_machine_info(char* buf) +static int get_mca_machine_info(char* page, char **start, off_t off, + int count, int *eof, void *data) { int len = 0; - len += sprintf(buf+len, "Model Id: 0x%x\n", machine_id); - len += sprintf(buf+len, "Submodel Id: 0x%x\n", machine_submodel_id); - len += sprintf(buf+len, "BIOS Revision: 0x%x\n", BIOS_revision); - + len += sprintf(page+len, "Model Id: 0x%x\n", machine_id); + len += sprintf(page+len, "Submodel Id: 0x%x\n", machine_submodel_id); + len += sprintf(page+len, "BIOS Revision: 0x%x\n", BIOS_revision); + + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; return len; } -static int mca_fill(char* page, int pid, int type, char** start, - loff_t *offset, int length) +static int mca_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) { + struct MCA_adapter *p = (struct MCA_adapter *)data; int len = 0; - int slot = 0; - - switch(type) { - case PROC_MCA_REGISTERS: - return get_mca_info(page); - case PROC_MCA_MACHINE: - return get_mca_machine_info(page); - case PROC_MCA_VIDEO: - slot = MCA_INTEGVIDEO; - break; - case PROC_MCA_SCSI: - slot = MCA_INTEGSCSI; - break; - default: - if(type < PROC_MCA_SLOT || type >= PROC_MCA_LAST) { - return -EBADF; - } - slot = type - PROC_MCA_SLOT; - break; - } - - /* If we made it here, we better have a valid slot */ /* Get the standard info */ - len = mca_default_procfn(page, slot); + len = mca_default_procfn(page, p); /* Do any device-specific processing, if there is any */ - if(mca_info->slot[slot].procfn) { - len += mca_info->slot[slot].procfn(page+len, slot, - mca_info->slot[slot].dev); + if(p->procfn) { + len += p->procfn(page+len, p-mca_info->slot, p->dev); } - + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; return len; -} /* mca_fill() */ - -/* Blatantly stolen from fs/proc/array.c, and thus is probably overkill */ +} /* mca_read_proc() */ -#define PROC_BLOCK_SIZE (3*1024) +/*--------------------------------------------------------------------*/ -static ssize_t proc_mca_read(struct file* file, - char* buf, size_t count, loff_t *ppos) +void __init mca_do_proc_init(void) { - unsigned long page; - char *start; - int length; - int end; - unsigned int type, pid; - struct proc_dir_entry *dp; - struct inode *inode = file->f_dentry->d_inode; - - if(count < 0) - return -EINVAL; - if(count > PROC_BLOCK_SIZE) - count = PROC_BLOCK_SIZE; - if(!(page = __get_free_page(GFP_KERNEL))) - return -ENOMEM; - type = inode->i_ino; - pid = type >> 16; - type &= 0x0000ffff; - start = NULL; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - length = mca_fill((char *) page, pid, type, - &start, ppos, count); - if(length < 0) { - free_page(page); - return length; - } - if(start != NULL) { - /* We have had block-adjusting processing! */ - - copy_to_user(buf, start, length); - *ppos += length; - count = length; - } else { - /* Static 4kB (or whatever) block capacity */ + int i; + struct proc_dir_entry* node = NULL; + struct MCA_adapter *p; + + if(mca_info == NULL) return; /* Should never happen */ + + create_proc_read_entry("pos",0,proc_mca,get_mca_info,NULL); + create_proc_read_entry("machine",0,proc_mca,get_mca_machine_info,NULL); + + /* Initialize /proc/mca entries for existing adapters */ + + for(i = 0; i < MCA_NUMADAPTERS; i++) { + p = &mca_info->slot[i]; + p->procfn = 0; + + if(i < MCA_MAX_SLOT_NR) sprintf(p->procname,"slot%d", i+1); + else if(i == MCA_INTEGVIDEO) sprintf(p->procname,"video"); + else if(i == MCA_INTEGSCSI) sprintf(p->procname,"scsi"); + + if(!mca_isadapter(i)) continue; - if(*ppos >= length) { - free_page(page); - return 0; - } - if(count + *ppos > length) - count = length - *ppos; - end = count + *ppos; - copy_to_user(buf, (char *) page + *ppos, count); - *ppos = end; - } - free_page(page); - return count; -} /* proc_mca_read() */ + node = create_proc_read_entry(p->procname, 0, proc_mca, + mca_read_proc, (void *)p); + + if(node == NULL) { + printk("Failed to allocate memory for MCA proc-entries!"); + return; + } + } + +} /* mca_do_proc_init() */ #endif diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c --- v2.3.26/linux/arch/i386/kernel/mtrr.c Mon Nov 1 13:56:26 1999 +++ linux/arch/i386/kernel/mtrr.c Thu Nov 11 09:33:36 1999 @@ -1204,7 +1204,7 @@ i = (*get_free_region) (base, size); if (i < 0) { - spin_unlock (&main_lock); + up(&main_lock); printk ("mtrr: no more MTRRs available\n"); return i; } diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.3.26/linux/arch/i386/kernel/process.c Mon Nov 1 13:56:26 1999 +++ linux/arch/i386/kernel/process.c Mon Nov 8 10:19:19 1999 @@ -685,3 +685,37 @@ unlock_kernel(); return error; } + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long ebp, esp, eip; + unsigned long stack_page; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + stack_page = (unsigned long)p; + esp = p->thread.esp; + if (!stack_page || esp < stack_page || esp > 8188+stack_page) + return 0; + /* include/asm-i386/system.h:switch_to() pushes ebp last. */ + ebp = *(unsigned long *) esp; + do { + if (ebp < stack_page || ebp > 8184+stack_page) + return 0; + eip = *(unsigned long *) (ebp+4); + if (eip < first_sched || eip >= last_sched) + return eip; + ebp = *(unsigned long *) ebp; + } while (count++ < 16); + return 0; +} +#undef last_sched +#undef first_sched diff -u --recursive --new-file v2.3.26/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- v2.3.26/linux/arch/i386/kernel/setup.c Wed Oct 27 16:34:12 1999 +++ linux/arch/i386/kernel/setup.c Mon Nov 8 22:10:43 1999 @@ -583,6 +583,7 @@ #define VMALLOC_RESERVE (unsigned long)(128 << 20) #define MAXMEM (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE) #define MAXMEM_PFN PFN_DOWN(MAXMEM) +#define MAX_NONPAE_PFN (1 << 20) /* * partially used pages are not usable - thus @@ -608,8 +609,26 @@ * Determine low and high memory ranges: */ max_low_pfn = max_pfn; - if (max_low_pfn > MAXMEM_PFN) + if (max_low_pfn > MAXMEM_PFN) { max_low_pfn = MAXMEM_PFN; +#ifndef CONFIG_HIGHMEM + /* Maximum memory usable is what is directly addressable */ + printk(KERN_WARNING "Warning only %ldMB will be used.\n", + MAXMEM>>20); + if (max_pfn > MAX_NONPAE_PFN) + printk(KERN_WARNING "Use a PAE enabled kernel.\n"); + else + printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); +#else /* !CONFIG_HIGHMEM */ +#ifndef CONFIG_X86_PAE + if (max_pfn > MAX_NONPAE_PFN) { + max_pfn = MAX_NONPAE_PFN; + printk(KERN_WARNING "Warning only 4GB will be used.\n"); + printk(KERN_WARNING "Use a PAE enabled kernel.\n"); + } +#endif /* !CONFIG_X86_PAE */ +#endif /* !CONFIG_HIGHMEM */ + } #ifdef CONFIG_HIGHMEM highstart_pfn = highend_pfn = max_pfn; diff -u --recursive --new-file v2.3.26/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v2.3.26/linux/arch/i386/mm/init.c Sun Nov 7 16:37:34 1999 +++ linux/arch/i386/mm/init.c Thu Nov 11 10:33:42 1999 @@ -171,9 +171,11 @@ return freed; } -/* NOTE: fixmap_init alloc all the fixmap pagetables contigous on the - physical space so we can cache the place of the first one and move - around without checking the pgd every time. */ +/* + * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the + * physical space so we can cache the place of the first one and move + * around without checking the pgd every time. + */ #if CONFIG_HIGHMEM pte_t *kmap_pte; @@ -268,6 +270,44 @@ set_pte_phys (address,phys); } +static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + int i, j; + + i = __pgd_offset(start); + j = __pmd_offset(start); + pgd = pgd_base + i; + + for ( ; (i < PTRS_PER_PGD) && (start != end); pgd++, i++) { +#if CONFIG_X86_PAE + if (pgd_none(*pgd)) { + pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); + memset((void*)pmd, 0, PAGE_SIZE); + pgd_val(*pgd) = __pa(pmd) + 0x1; + if (pmd != pmd_offset(pgd, start)) + BUG(); + } + pmd = pmd_offset(pgd, start); +#else + pmd = (pmd_t *)pgd; +#endif + for (; (j < PTRS_PER_PMD) && start; pmd++, j++) { + if (pmd_none(*pmd)) { + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + memset((void*)pte, 0, PAGE_SIZE); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); + if (pte != pte_offset(pmd, 0)) + BUG(); + } + start += PMD_SIZE; + } + j = 0; + } +} + static void __init pagetable_init(void) { pgd_t *pgd, *pgd_base; @@ -331,37 +371,21 @@ * Fixed mappings, only the page table structure has to be * created - mappings will be set by set_fixmap(): */ - vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; - i = __pgd_offset(vaddr); - j = __pmd_offset(vaddr); - pgd = pgd_base + i; + fixrange_init(vaddr, 0, pgd_base); - for ( ; (i < PTRS_PER_PGD) && vaddr; pgd++, i++) { -#if CONFIG_X86_PAE - if (pgd_none(*pgd)) { - pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); - memset((void*)pmd, 0, PAGE_SIZE); - pgd_val(*pgd) = __pa(pmd) + 0x1; - if (pmd != pmd_offset(pgd, vaddr)) - BUG(); - } - pmd = pmd_offset(pgd, vaddr); -#else - pmd = (pmd_t *)pgd; +#if CONFIG_HIGHMEM + /* + * Permanent kmaps: + */ + vaddr = PKMAP_BASE; + fixrange_init(vaddr, vaddr + 4*1024*1024, pgd_base); + + pgd = swapper_pg_dir + __pgd_offset(vaddr); + pmd = pmd_offset(pgd, vaddr); + pte = pte_offset(pmd, vaddr); + pkmap_page_table = pte; #endif - for (; (j < PTRS_PER_PMD) && vaddr; pmd++, j++) { - if (pmd_none(*pmd)) { - pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); - memset((void*)pte, 0, PAGE_SIZE); - pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); - if (pte != pte_offset(pmd, 0)) - BUG(); - } - vaddr += PMD_SIZE; - } - j = 0; - } #if CONFIG_X86_PAE /* @@ -389,6 +413,7 @@ */ for (i = 0; i < USER_PTRS_PER_PGD; i++) pgd_val(swapper_pg_dir[i]) = 0; + flush_tlb_all(); } /* @@ -420,13 +445,18 @@ #endif #ifdef CONFIG_HIGHMEM - kmap_init(); /* run after fixmap_init */ -#endif -#ifdef CONFIG_HIGHMEM - free_area_init(highend_pfn); -#else - free_area_init(max_low_pfn); + kmap_init(); #endif + { + unsigned int zones_size[3]; + + zones_size[0] = virt_to_phys((char *)MAX_DMA_ADDRESS) + >> PAGE_SHIFT; + zones_size[1] = max_low_pfn - zones_size[0]; + zones_size[2] = highend_pfn - zones_size[0] - zones_size[1]; + + free_area_init(zones_size); + } return; } @@ -441,7 +471,6 @@ /* * Ok, all PAE-capable CPUs are definitely handling the WP bit right. */ -//#ifndef CONFIG_X86_PAE const unsigned long vaddr = PAGE_OFFSET; pgd_t *pgd; pmd_t *pmd; @@ -478,7 +507,6 @@ #endif } else printk(".\n"); -//#endif } static inline int page_is_ram (unsigned long pagenr) @@ -541,7 +569,7 @@ totalram_pages += totalhigh_pages; #endif printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n", - (unsigned long) nr_free_pages << (PAGE_SHIFT-10), + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), reservedpages << (PAGE_SHIFT-10), @@ -572,7 +600,7 @@ void free_initmem(void) { unsigned long addr; - + addr = (unsigned long)(&__init_begin); for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { ClearPageReserved(mem_map + MAP_NR(addr)); @@ -587,10 +615,10 @@ { val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages; + val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); val->totalhigh = totalhigh_pages; - val->freehigh = nr_free_highpages; + val->freehigh = nr_free_highpages(); val->mem_unit = PAGE_SIZE; return; } diff -u --recursive --new-file v2.3.26/linux/arch/m68k/kernel/m68k_ksyms.c linux/arch/m68k/kernel/m68k_ksyms.c --- v2.3.26/linux/arch/m68k/kernel/m68k_ksyms.c Tue Sep 7 12:14:06 1999 +++ linux/arch/m68k/kernel/m68k_ksyms.c Mon Nov 8 14:28:34 1999 @@ -75,3 +75,5 @@ EXPORT_SYMBOL_NOVERS(__down_failed_interruptible); EXPORT_SYMBOL_NOVERS(__down_failed_trylock); EXPORT_SYMBOL_NOVERS(__up_wakeup); + +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c --- v2.3.26/linux/arch/m68k/kernel/process.c Sun Nov 7 16:37:34 1999 +++ linux/arch/m68k/kernel/process.c Mon Nov 8 14:28:34 1999 @@ -346,3 +346,34 @@ unlock_kernel(); return error; } + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long fp, pc; + unsigned long stack_page; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + stack_page = (unsigned long)p; + fp = ((struct switch_stack *)p->thread.ksp)->a6; + do { + if (fp < stack_page+sizeof(struct task_struct) || + fp >= 8184+stack_page) + return 0; + pc = ((unsigned long *)fp)[1]; + /* FIXME: This depends on the order of these functions. */ + if (pc < first_sched || pc >= last_sched) + return pc; + fp = *(unsigned long *) fp; + } while (count++ < 16); + return 0; +} diff -u --recursive --new-file v2.3.26/linux/arch/m68k/math-emu/fp_emu.h linux/arch/m68k/math-emu/fp_emu.h --- v2.3.26/linux/arch/m68k/math-emu/fp_emu.h Sun Aug 15 11:47:29 1999 +++ linux/arch/m68k/math-emu/fp_emu.h Wed Nov 10 10:00:48 1999 @@ -38,10 +38,11 @@ #ifndef _FP_EMU_H #define _FP_EMU_H -#ifndef __ASSEMBLY__ - +#include "../kernel/m68k_defs.h" #include +#ifndef __ASSEMBLY__ + #define IS_INF(a) ((a)->exp == 0x7fff) #define IS_ZERO(a) ((a)->mant.m64 == 0) @@ -113,9 +114,6 @@ }) #else /* __ASSEMBLY__ */ - -#include "../kernel/m68k_defs.h" -#include /* * set, reset or clear a bit in the fp status register diff -u --recursive --new-file v2.3.26/linux/arch/mips/kernel/mips_ksyms.c linux/arch/mips/kernel/mips_ksyms.c --- v2.3.26/linux/arch/mips/kernel/mips_ksyms.c Fri Jun 25 17:40:12 1999 +++ linux/arch/mips/kernel/mips_ksyms.c Mon Nov 8 14:28:34 1999 @@ -122,3 +122,4 @@ EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c --- v2.3.26/linux/arch/mips/kernel/process.c Fri Jun 25 17:40:12 1999 +++ linux/arch/mips/kernel/process.c Mon Nov 8 14:28:34 1999 @@ -182,3 +182,28 @@ return retval; } + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long schedule_frame; + unsigned long pc; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + /* + * The same comment as on the Alpha applies here, too ... + */ + pc = thread_saved_pc(&p->tss); + if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) { + schedule_frame = ((unsigned long *)(long)p->tss.reg30)[16]; + return (unsigned long)((unsigned long *)schedule_frame)[11]; + } + return pc; +} diff -u --recursive --new-file v2.3.26/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c --- v2.3.26/linux/arch/ppc/amiga/config.c Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/amiga/config.c Wed Nov 10 22:18:38 1999 @@ -6,7 +6,6 @@ void (*mach_kbd_reset_setup) (char *, int) __initdata = 0; #include -#include /* * linux/arch/m68k/amiga/config.c diff -u --recursive --new-file v2.3.26/linux/arch/ppc/config.in linux/arch/ppc/config.in --- v2.3.26/linux/arch/ppc/config.in Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/config.in Tue Nov 9 07:13:17 1999 @@ -44,7 +44,7 @@ fi bool 'Symmetric multi-processing support' CONFIG_SMP -if [ "$CONFIG_6xx" != "y" ];then +if [ "$CONFIG_6xx" = "y" ];then bool 'AltiVec Support' CONFIG_ALTIVEC fi diff -u --recursive --new-file v2.3.26/linux/arch/ppc/defconfig linux/arch/ppc/defconfig --- v2.3.26/linux/arch/ppc/defconfig Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/defconfig Mon Nov 8 12:32:50 1999 @@ -3,6 +3,11 @@ # # +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# # Platform support # CONFIG_PPC=y @@ -10,55 +15,55 @@ # 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 is not set -CONFIG_GEMINI=y +CONFIG_ALL_PPC=y +# CONFIG_GEMINI is not set # CONFIG_APUS is not set # CONFIG_SMP is not set -CONFIG_MACH_SPECIFIC=y CONFIG_6xx=y # -# General setup +# Loadable module support # -CONFIG_EXPERIMENTAL=y CONFIG_MODULES=y CONFIG_MODVERSIONS=y CONFIG_KMOD=y + +# +# General setup +# CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_KCORE_AOUT is not set -CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y # CONFIG_BINFMT_MISC is not set + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set # CONFIG_PARPORT is not set -# 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_VGA_CONSOLE=y +CONFIG_FB=y +CONFIG_FB_COMPAT_XPMAC=y +CONFIG_PMAC_PBOOK=y +CONFIG_MAC_FLOPPY=y +CONFIG_MAC_SERIAL=y +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_MACIO=y +CONFIG_ADB_PMU=y +CONFIG_ADB_KEYBOARD=y +CONFIG_PROC_DEVICETREE=y # CONFIG_TOTALMP is not set -# CONFIG_BOOTX_TEXT is not set +CONFIG_BOOTX_TEXT=y # CONFIG_MOTOROLA_HOTSWAP is not set +# CONFIG_CMDLINE_BOOL is not set # # Plug and Play configuration @@ -68,26 +73,48 @@ # # Block devices # -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_IDE is not set +CONFIG_BLK_DEV_FD=y +CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # -# CONFIG_BLK_DEV_HD_ONLY is not set +# 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_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# 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_CPQ_DA is not set # # Additional Block Devices # -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set -# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_INITRD=y # 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 is not set +CONFIG_BLK_DEV_IDE_MODES=y # CONFIG_BLK_DEV_HD is not set # @@ -124,7 +151,7 @@ # # # CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_ATALK=m # CONFIG_DECNET is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set @@ -149,7 +176,7 @@ # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set +CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y # CONFIG_CHR_DEV_SG is not set @@ -169,7 +196,11 @@ # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX 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_IPS is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set @@ -183,12 +214,11 @@ # 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 # CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_NCR53C7xx is not set # CONFIG_SCSI_NCR53C8XX is not set CONFIG_SCSI_SYM53C8XX=y @@ -212,8 +242,9 @@ # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_ULTRASTOR is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_MESH is not set -# CONFIG_SCSI_MAC53C94 is not set +CONFIG_SCSI_MESH=y +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_MAC53C94=y # # Network device support @@ -233,28 +264,63 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_MACE is not set -# CONFIG_BMAC is not set -CONFIG_NCR885E=y +CONFIG_MACE=y +CONFIG_BMAC=y +# CONFIG_NCR885E is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_YELLOWFIN is not set # CONFIG_RTL8139 is not set # CONFIG_SIS900 is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_ACENIC is not set +# CONFIG_DM9102 is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set # CONFIG_NET_ISA is not set -# CONFIG_NET_EISA is not set +CONFIG_NET_EISA=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_ACENIC is not set +# 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_NET_POCKET is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -# CONFIG_PPP 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_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set # CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# # CONFIG_NET_RADIO is not set # -# Token ring devices +# Token Ring driver support # # CONFIG_TR is not set # CONFIG_NET_FC is not set @@ -264,10 +330,7 @@ # # Wan interfaces # -# CONFIG_HOSTESS_SV11 is not set -# CONFIG_COSA is not set -# CONFIG_SEALEVEL_4021 is not set -# CONFIG_DLCI is not set +# CONFIG_WAN is not set # # Amateur Radio support @@ -289,12 +352,50 @@ # # +# Frame-buffer support +# +CONFIG_FB=y +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_ATY128 is not set +# CONFIG_FB_3DFX is not set +# 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=y -CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL=m # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y @@ -307,13 +408,14 @@ # CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_LOGIBUSMOUSE is not set # CONFIG_MS_BUSMOUSE is not set +# CONFIG_ADBMOUSE 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 is not set +CONFIG_NVRAM=y # CONFIG_RTC is not set # @@ -333,14 +435,6 @@ # 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 # @@ -352,11 +446,14 @@ # Filesystems # # CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS_FS=y # 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_HFS_FS=y +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set @@ -369,6 +466,7 @@ # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y +# CONFIG_BFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set @@ -376,10 +474,11 @@ # Network File Systems # # CONFIG_CODA_FS is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set +CONFIG_NFS_FS=y +CONFIG_NFSD=y +# CONFIG_NFSD_SUN is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set @@ -394,16 +493,86 @@ # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set # # Sound # -# CONFIG_SOUND is not set +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_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +CONFIG_SOUND_CS4232=m +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MSS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SOFTOSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_UART6850 is not set + +# +# Additional low level sound drivers +# +# CONFIG_LOWLEVEL_SOUND is not set # # Kernel hacking # -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set -# CONFIG_XMON is not set +CONFIG_XMON=y diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c --- v2.3.26/linux/arch/ppc/kernel/chrp_setup.c Wed Oct 27 16:34:12 1999 +++ linux/arch/ppc/kernel/chrp_setup.c Wed Nov 10 22:18:38 1999 @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -576,9 +575,10 @@ ppc_md.calibrate_decr = chrp_calibrate_decr; #ifdef CONFIG_VT -#ifdef CONFIG_MAC_KEYBOAD +#ifdef CONFIG_MAC_KEYBOARD if (adb_driver == NULL) { +#endif /* CONFIG_MAC_KEYBOAD */ ppc_md.kbd_setkeycode = pckbd_setkeycode; ppc_md.kbd_getkeycode = pckbd_getkeycode; ppc_md.kbd_translate = pckbd_translate; @@ -588,7 +588,8 @@ #ifdef CONFIG_MAGIC_SYSRQ ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; SYSRQ_KEY = 0x54; -#endif +#endif /* CONFIG_MAGIC_SYSRQ */ +#ifdef CONFIG_MAC_KEYBOARD } else { @@ -601,24 +602,13 @@ #ifdef CONFIG_MAGIC_SYSRQ ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; SYSRQ_KEY = 0x69; -#endif +#endif /* CONFIG_MAGIC_SYSRQ */ } -#else - ppc_md.kbd_setkeycode = pckbd_setkeycode; - ppc_md.kbd_getkeycode = pckbd_getkeycode; - ppc_md.kbd_translate = pckbd_translate; - ppc_md.kbd_unexpected_up = pckbd_unexpected_up; - ppc_md.kbd_leds = pckbd_leds; - ppc_md.kbd_init_hw = pckbd_init_hw; -#ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; - SYSRQ_KEY = 0x54; -#endif +#endif /* CONFIG_MAC_KEYBOARD */ +#endif /* CONFIG_VT */ if ( rtas_data ) ppc_md.progress = chrp_progress; -#endif -#endif - + #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.insw = chrp_ide_insw; ppc_ide_md.outsw = chrp_ide_outsw; diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S --- v2.3.26/linux/arch/ppc/kernel/entry.S Sat Oct 9 11:47:50 1999 +++ linux/arch/ppc/kernel/entry.S Wed Nov 10 10:55:31 1999 @@ -411,9 +411,9 @@ addis r7,r7,-KERNELBASE@h lis r8,rtas_entry@ha lwz r8,rtas_entry@l(r8) - addis r5,r8,-KERNELBASE@h mfmsr r9 stw r9,8(r1) + li r0,0 ori r0,r0,MSR_EE|MSR_SE|MSR_BE andc r0,r9,r0 andi. r9,r9,MSR_ME|MSR_RI diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S --- v2.3.26/linux/arch/ppc/kernel/head.S Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/kernel/head.S Mon Nov 8 12:32:50 1999 @@ -817,6 +817,15 @@ srwi r4,r4,16 cmpi 0,r4,12 bnelr + + /* enable altivec so we can save */ + mfmsr r4 + oris r4,r4,MSR_VEC@h + mtmsr r4 + + /* make sure our tsk pointer is valid */ + cmpi 0,r3,0 + beqlr /* save altivec regs */ addi r4,r3,THREAD+THREAD_VRSAVE @@ -830,6 +839,11 @@ lis r6,MSR_VEC@h andi. r5,r5,r6 stw r5,_MSR(r4) + + /* we've given up the altivec - clear the pointer */ + li r3,0 + lis r4,last_task_used_altivec@h + stw r3,last_task_used_altivec@l(r4) #endif /* CONFIG_ALTIVEC */ blr diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c --- v2.3.26/linux/arch/ppc/kernel/pmac_setup.c Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/kernel/pmac_setup.c Wed Nov 10 22:18:38 1999 @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c --- v2.3.26/linux/arch/ppc/kernel/ppc_ksyms.c Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/kernel/ppc_ksyms.c Mon Nov 8 14:28:34 1999 @@ -268,3 +268,4 @@ void ppc_irq_dispatch_handler(struct pt_regs *, int); EXPORT_SYMBOL(ppc_irq_dispatch_handler); EXPORT_SYMBOL(decrementer_count); +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c --- v2.3.26/linux/arch/ppc/kernel/prep_setup.c Fri Oct 22 13:21:45 1999 +++ linux/arch/ppc/kernel/prep_setup.c Wed Nov 10 22:18:39 1999 @@ -210,7 +210,7 @@ } void __init -prep_setup_arch() +prep_setup_arch(void) { extern char cmd_line[]; unsigned char reg; diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c --- v2.3.26/linux/arch/ppc/kernel/process.c Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/kernel/process.c Wed Nov 10 10:55:31 1999 @@ -210,6 +210,11 @@ prev->last_processor = prev->processor; current_set[smp_processor_id()] = new; #endif /* __SMP__ */ + /* Avoid the trap. On smp this this never happens since + * we don't set last_task_used_altivec -- Cort + */ + if ( last_task_used_altivec == new ) + new->thread.regs->msr |= MSR_VEC; new_thread = &new->thread; old_thread = ¤t->thread; *last = _switch(old_thread, new_thread); @@ -574,3 +579,32 @@ orig_y = y; } #endif + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long ip, sp; + unsigned long stack_page = (unsigned long) p; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + sp = p->thread.ksp; + do { + sp = *(unsigned long *)sp; + if (sp < stack_page || sp >= stack_page + 8188) + return 0; + if (count > 0) { + ip = *(unsigned long *)(sp + 4); + if (ip < first_sched || ip >= last_sched) + return ip; + } + } while (count++ < 16); + return 0; +} diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c --- v2.3.26/linux/arch/ppc/kernel/setup.c Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/kernel/setup.c Wed Nov 10 10:55:31 1999 @@ -389,12 +389,10 @@ if ( have_of ) { -#ifdef CONFIG_MACH_SPECIFIC /* prom_init has already been called from __start */ if (boot_infos) relocate_nodes(); finish_device_tree(); -#endif /* CONFIG_MACH_SPECIFIC */ /* * If we were booted via quik, r3 points to the physical * address of the command-line parameters. @@ -450,7 +448,7 @@ int_control.int_cli = __no_use_cli; int_control.int_save_flags = __no_use_save_flags; int_control.int_restore_flags = __no_use_restore_flags; - + switch (_machine) { case _MACH_Pmac: diff -u --recursive --new-file v2.3.26/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c --- v2.3.26/linux/arch/ppc/kernel/traps.c Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/kernel/traps.c Mon Nov 8 12:32:50 1999 @@ -149,19 +149,19 @@ show_regs(regs); panic("Kernel Used Altivec with MSR_VEC off!\n"); } -#ifdef __SMP__ - printk("User Mode altivec trap should not happen in SMP!\n"); -#else + if ( last_task_used_altivec != current ) { if ( last_task_used_altivec ) giveup_altivec(current); load_up_altivec(current); + /* on SMP we always save/restore on switch */ +#ifndef __SMP__ last_task_used_altivec = current; +#endif } /* enable altivec for the task on return */ regs->msr |= MSR_VEC; -#endif } void diff -u --recursive --new-file v2.3.26/linux/arch/ppc/mm/extable.c linux/arch/ppc/mm/extable.c --- v2.3.26/linux/arch/ppc/mm/extable.c Fri Feb 20 18:28:21 1998 +++ linux/arch/ppc/mm/extable.c Wed Nov 10 22:18:39 1999 @@ -43,13 +43,18 @@ #else /* The kernel is the last "module" -- no need to treat it special. */ struct module *mp; + read_lock(&modlist_lock); for (mp = module_list; mp != NULL; mp = mp->next) { if (mp->ex_table_start == NULL) continue; ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, addr); - if (ret) return ret; + if (ret) { + read_unlock(&modlist_lock); + return ret; + } } + read_unlock(&modlist_lock); #endif return 0; diff -u --recursive --new-file v2.3.26/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c --- v2.3.26/linux/arch/ppc/mm/init.c Sun Nov 7 16:37:34 1999 +++ linux/arch/ppc/mm/init.c Wed Nov 10 22:18:39 1999 @@ -348,7 +348,7 @@ i = max_mapnr; val->totalram = 0; val->sharedram = 0; - val->freeram = nr_free_pages << PAGE_SHIFT; + val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); while (i-- > 0) { if (PageReserved(mem_map+i)) @@ -1215,8 +1215,6 @@ */ empty_bad_page = alloc_bootmem_pages(PAGE_SIZE); empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE); - - free_area_init(max_low_pfn); } void __init mem_init(void) diff -u --recursive --new-file v2.3.26/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c --- v2.3.26/linux/arch/sparc/kernel/process.c Tue Aug 31 17:29:13 1999 +++ linux/arch/sparc/kernel/process.c Mon Nov 8 14:28:34 1999 @@ -702,3 +702,37 @@ "g1", "g2", "g3", "o0", "o1", "memory", "cc"); return retval; } + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long pc, fp, bias = 0; + unsigned long task_base = (unsigned long) p; + struct reg_window *rw; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + fp = p->thread.ksp + bias; + do { + /* Bogus frame pointer? */ + if (fp < (task_base + sizeof(struct task_struct)) || + fp >= (task_base + (2 * PAGE_SIZE))) + break; + rw = (struct reg_window *) fp; + pc = rw->ins[7]; + if (pc < first_sched || pc >= last_sched) + return pc; + fp = rw->ins[6] + bias; + } while (++count < 16); + return 0; +} +#undef last_sched +#undef first_sched diff -u --recursive --new-file v2.3.26/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c --- v2.3.26/linux/arch/sparc/kernel/sparc_ksyms.c Fri Sep 10 23:57:28 1999 +++ linux/arch/sparc/kernel/sparc_ksyms.c Mon Nov 8 14:28:34 1999 @@ -279,3 +279,5 @@ EXPORT_SYMBOL_DOT(umul); EXPORT_SYMBOL_DOT(div); EXPORT_SYMBOL_DOT(udiv); + +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c --- v2.3.26/linux/arch/sparc64/kernel/process.c Tue Aug 31 17:29:13 1999 +++ linux/arch/sparc64/kernel/process.c Mon Nov 8 14:28:34 1999 @@ -802,3 +802,35 @@ unlock_kernel(); return error; } + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long pc, fp, bias = 0; + unsigned long task_base = (unsigned long) p; + struct reg_window *rw; + int count = 0; + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + bias = STACK_BIAS; + fp = p->thread.ksp + bias; + do { + /* Bogus frame pointer? */ + if (fp < (task_base + sizeof(struct task_struct)) || + fp >= (task_base + (2 * PAGE_SIZE))) + break; + rw = (struct reg_window *) fp; + pc = rw->ins[7]; + if (pc < first_sched || pc >= last_sched) + return pc; + fp = rw->ins[6] + bias; + } while (++count < 16); + return 0; +} diff -u --recursive --new-file v2.3.26/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c --- v2.3.26/linux/arch/sparc64/kernel/sparc64_ksyms.c Fri Sep 10 23:57:28 1999 +++ linux/arch/sparc64/kernel/sparc64_ksyms.c Mon Nov 8 14:28:34 1999 @@ -311,3 +311,5 @@ EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL_NOVERS(memmove); + +EXPORT_SYMBOL(get_wchan); diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/acornscsi.c linux/drivers/acorn/scsi/acornscsi.c --- v2.3.26/linux/drivers/acorn/scsi/acornscsi.c Mon Aug 2 10:19:52 1999 +++ linux/drivers/acorn/scsi/acornscsi.c Thu Nov 11 16:57:30 1999 @@ -190,10 +190,6 @@ unsigned int sdtr_period = SDTR_PERIOD; unsigned int sdtr_size = SDTR_SIZE; -static struct proc_dir_entry proc_scsi_acornscsi = { - PROC_SCSI_EATA, 9, "acornscsi", S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - static void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result); static int acornscsi_reconnect_finish(AS_Host *host); static void acornscsi_dma_cleanup(AS_Host *host); @@ -2875,7 +2871,7 @@ struct Scsi_Host *instance; AS_Host *host; - tpnt->proc_dir = &proc_scsi_acornscsi; + tpnt->proc_name = "acornscsi"; for (i = 0; i < MAX_ECARDS; i++) ecs[i] = NULL; diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/acornscsi.h linux/drivers/acorn/scsi/acornscsi.h --- v2.3.26/linux/drivers/acorn/scsi/acornscsi.h Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/scsi/acornscsi.h Thu Nov 11 16:57:30 1999 @@ -23,10 +23,7 @@ #define CAN_QUEUE 16 #endif -#ifndef PROC_SCSI_AKA30 #include "linux/proc_fs.h" -#define PROC_SCSI_AKA30 PROC_SCSI_EATA -#endif #include diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/arxescsi.c linux/drivers/acorn/scsi/arxescsi.c --- v2.3.26/linux/drivers/acorn/scsi/arxescsi.c Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/scsi/arxescsi.c Thu Nov 11 16:57:30 1999 @@ -58,11 +58,6 @@ static struct expansion_card *ecs[MAX_ECARDS]; -static struct proc_dir_entry proc_scsi_arxescsi = { - PROC_SCSI_QLOGICFAS, 6, "arxescsi", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* * Function: int arxescsi_dma_setup(host, SCpnt, direction, min_type) * Purpose : initialises DMA/PIO @@ -223,7 +218,7 @@ int count = 0; struct Scsi_Host *host; - tpnt->proc_dir = &proc_scsi_arxescsi; + tpnt->proc_name = "arxescsi"; memset(ecs, 0, sizeof (ecs)); ecard_startfind(); diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/cumana_1.c linux/drivers/acorn/scsi/cumana_1.c --- v2.3.26/linux/drivers/acorn/scsi/cumana_1.c Sat Jul 18 11:55:24 1998 +++ linux/drivers/acorn/scsi/cumana_1.c Thu Nov 11 16:57:30 1999 @@ -69,10 +69,6 @@ { 0xffff, 0xffff } }; -static struct proc_dir_entry proc_scsi_cumana1 = { - PROC_SCSI_T128, 12, "CumanaSCSI-1", S_IFDIR | S_IRUGO, S_IXUGO, 2 -}; - /* * Function : cumanascsi_setup(char *str, int *ints) * @@ -106,7 +102,7 @@ int count = 0; struct Scsi_Host *instance; - tpnt->proc_dir = &proc_scsi_cumana1; + tpnt->proc_name = "CumanaSCSI-1"; memset (ecs, 0, sizeof (ecs)); diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/cumana_2.c linux/drivers/acorn/scsi/cumana_2.c --- v2.3.26/linux/drivers/acorn/scsi/cumana_2.c Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/scsi/cumana_2.c Thu Nov 11 16:57:30 1999 @@ -84,11 +84,6 @@ */ int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; -static struct proc_dir_entry proc_scsi_cumanascsi_2 = { - PROC_SCSI_QLOGICFAS, 6, "cumanascs2", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* Prototype: void cumanascsi_2_irqenable(ec, irqnr) * Purpose : Enable interrupts on Cumana SCSI 2 card * Params : ec - expansion card structure @@ -329,7 +324,7 @@ int count = 0; struct Scsi_Host *host; - tpnt->proc_dir = &proc_scsi_cumanascsi_2; + tpnt->proc_name = "cumanascs2"; memset(ecs, 0, sizeof (ecs)); ecard_startfind(); diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/ecoscsi.c linux/drivers/acorn/scsi/ecoscsi.c --- v2.3.26/linux/drivers/acorn/scsi/ecoscsi.c Sat Jul 18 11:55:24 1998 +++ linux/drivers/acorn/scsi/ecoscsi.c Thu Nov 11 16:57:30 1999 @@ -57,10 +57,6 @@ #include "../../scsi/NCR5380.h" #include "../../scsi/constants.h" -static struct proc_dir_entry proc_scsi_ecoscsi = { - PROC_SCSI_GENERIC_NCR5380, 7, "ecoscsi", S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - static char ecoscsi_read(struct Scsi_Host *instance, int reg) { int iobase = instance->io_port; @@ -104,7 +100,7 @@ { struct Scsi_Host *instance; - tpnt->proc_dir = &proc_scsi_ecoscsi; + tpnt->proc_name = "ecoscsi"; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); instance->io_port = 0x80ce8000; diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/eesox.c linux/drivers/acorn/scsi/eesox.c --- v2.3.26/linux/drivers/acorn/scsi/eesox.c Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/scsi/eesox.c Thu Nov 11 16:57:30 1999 @@ -81,11 +81,6 @@ */ int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; -static struct proc_dir_entry proc_scsi_eesox = { - PROC_SCSI_QLOGICISP, 5, "eesox", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* Prototype: void eesoxscsi_irqenable(ec, irqnr) * Purpose : Enable interrupts on EESOX SCSI card * Params : ec - expansion card structure @@ -334,7 +329,7 @@ int count = 0; struct Scsi_Host *host; - tpnt->proc_dir = &proc_scsi_eesox; + tpnt->proc_name = "eesox"; memset(ecs, 0, sizeof (ecs)); ecard_startfind(); diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/oak.c linux/drivers/acorn/scsi/oak.c --- v2.3.26/linux/drivers/acorn/scsi/oak.c Sat Jul 18 11:55:24 1998 +++ linux/drivers/acorn/scsi/oak.c Thu Nov 11 16:57:30 1999 @@ -71,10 +71,6 @@ { 0xffff, 0xffff } }; -static struct proc_dir_entry proc_scsi_oakscsi = { - PROC_SCSI_PAS16, 7, "oakscsi", S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define OAK_ADDRESS(card) (ecard_address((card), ECARD_MEMC, 0)) #define OAK_IRQ(card) (IRQ_NONE) /* @@ -95,7 +91,7 @@ int count = 0; struct Scsi_Host *instance; - tpnt->proc_dir = &proc_scsi_oakscsi; + tpnt->proc_name = "oakscsi"; memset (ecs, 0, sizeof (ecs)); diff -u --recursive --new-file v2.3.26/linux/drivers/acorn/scsi/powertec.c linux/drivers/acorn/scsi/powertec.c --- v2.3.26/linux/drivers/acorn/scsi/powertec.c Thu Jun 17 01:11:35 1999 +++ linux/drivers/acorn/scsi/powertec.c Thu Nov 11 16:57:30 1999 @@ -81,11 +81,6 @@ */ int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; -static struct proc_dir_entry proc_scsi_powertec = { - PROC_SCSI_QLOGICISP, 8, "powertec", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* Prototype: void powertecscsi_irqenable(ec, irqnr) * Purpose : Enable interrupts on Powertec SCSI card * Params : ec - expansion card structure @@ -236,7 +231,7 @@ int count = 0; struct Scsi_Host *host; - tpnt->proc_dir = &proc_scsi_powertec; + tpnt->proc_name = "powertec"; memset(ecs, 0, sizeof (ecs)); ecard_startfind(); diff -u --recursive --new-file v2.3.26/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c --- v2.3.26/linux/drivers/block/amiflop.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/block/amiflop.c Mon Nov 8 11:03:20 1999 @@ -1821,13 +1821,13 @@ return -ENOMEM; } - if (!request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) { + if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) { printk("fd: cannot get irq for dma\n"); amiga_chip_free(raw_buf); unregister_blkdev(MAJOR_NR,"fd"); return -EBUSY; } - if (!request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) { + if (request_irq(IRQ_AMIGA_CIAA_TB, ms_isr, 0, "floppy_timer", NULL)) { printk("fd: cannot get irq for timer\n"); free_irq(IRQ_AMIGA_DSKBLK, NULL); amiga_chip_free(raw_buf); diff -u --recursive --new-file v2.3.26/linux/drivers/block/ide.c linux/drivers/block/ide.c --- v2.3.26/linux/drivers/block/ide.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/block/ide.c Thu Nov 11 16:03:36 1999 @@ -307,6 +307,7 @@ struct hd_driveid *id = drive->id; if (drive->removable && id != NULL) { + if (id->config == 0x848a) return 1; /* CompactFlash */ if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */ || !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */ || !strncmp(id->model, "SunDisk SDCFB", 13) /* SunDisk */ diff -u --recursive --new-file v2.3.26/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.3.26/linux/drivers/block/ll_rw_blk.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/block/ll_rw_blk.c Thu Nov 11 10:33:42 1999 @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -491,6 +492,15 @@ won't clear the mapped bit under us. */ if (!buffer_mapped(bh)) BUG(); + + /* + * Temporary solution - in 2.5 this will be done by the lowlevel + * driver. Create a bounce buffer if the buffer data points into + * high memory - keep the original buffer otherwise. + */ +#if CONFIG_HIGHMEM + bh = create_bounce(rw, bh); +#endif /* look for a free request. */ /* Loop uses two requests, 1 for loop and 1 for the real device. diff -u --recursive --new-file v2.3.26/linux/drivers/block/nbd.c linux/drivers/block/nbd.c --- v2.3.26/linux/drivers/block/nbd.c Mon Jul 5 20:07:02 1999 +++ linux/drivers/block/nbd.c Wed Nov 10 12:38:13 1999 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -105,6 +106,7 @@ do { + sock->sk->allocation = GFP_ATOMIC; iov.iov_base = buf; iov.iov_len = size; msg.msg_name = NULL; diff -u --recursive --new-file v2.3.26/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- v2.3.26/linux/drivers/cdrom/cdrom.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/cdrom/cdrom.c Thu Nov 11 16:57:30 1999 @@ -2531,23 +2531,6 @@ static struct ctl_table_header *cdrom_sysctl_header; -/* - * This is called as the fill_inode function when an inode - * is going into (fill = 1) or out of service (fill = 0). - * We use it here to manage the module use counts. - * - * Note: only the top-level directory needs to do this; if - * a lower level is referenced, the parent will be as well. - */ -static void cdrom_procfs_modcount(struct inode *inode, int fill) -{ - if (fill) { - MOD_INC_USE_COUNT; - } else { - MOD_DEC_USE_COUNT; - } -} - static void cdrom_sysctl_register(void) { static int initialized = 0; @@ -2556,7 +2539,7 @@ return; cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 1); - cdrom_root_table->child->de->fill_inode = &cdrom_procfs_modcount; + cdrom_root_table->child->de->owner = THIS_MODULE; /* set the defaults */ cdrom_sysctl_settings.autoclose = autoclose; diff -u --recursive --new-file v2.3.26/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.3.26/linux/drivers/char/Config.in Mon Nov 1 13:56:26 1999 +++ linux/drivers/char/Config.in Wed Nov 10 22:23:28 1999 @@ -6,7 +6,7 @@ bool 'Virtual terminal' CONFIG_VT if [ "$CONFIG_VT" = "y" ]; then - bool 'Support for console on virtual terminal' CONFIG_VT_CONSOLE + bool ' Support for console on virtual terminal' CONFIG_VT_CONSOLE fi tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL if [ "$CONFIG_SERIAL" = "y" ]; then @@ -22,103 +22,101 @@ fi bool 'Non-standard serial port support' CONFIG_SERIAL_NONSTANDARD if [ "$CONFIG_SERIAL_NONSTANDARD" = "y" ]; then - tristate 'Comtrol Rocketport support' CONFIG_ROCKETPORT - tristate 'Digiboard Intelligent Async Support' CONFIG_DIGIEPCA + tristate ' Comtrol Rocketport support' CONFIG_ROCKETPORT + tristate ' Digiboard Intelligent Async Support' CONFIG_DIGIEPCA if [ "$CONFIG_DIGIEPCA" = "n" ]; then - tristate 'Digiboard PC/Xx Support' CONFIG_DIGI + tristate ' Digiboard PC/Xx Support' CONFIG_DIGI fi - tristate 'Cyclades async mux support' CONFIG_CYCLADES + tristate ' Cyclades async mux support' CONFIG_CYCLADES if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_CYCLADES" != "n" ]; then - bool ' Cyclades-Z interrupt mode operation (EXPERIMENTAL)' CONFIG_CYZ_INTR + bool ' Cyclades-Z interrupt mode operation (EXPERIMENTAL)' CONFIG_CYZ_INTR fi - bool 'Stallion multiport serial support' CONFIG_STALDRV + bool ' Stallion multiport serial support' CONFIG_STALDRV if [ "$CONFIG_STALDRV" = "y" ]; then - tristate ' Stallion EasyIO or EC8/32 support' CONFIG_STALLION - tristate ' Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION + tristate ' Stallion EasyIO or EC8/32 support' CONFIG_STALLION + tristate ' Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION fi - tristate 'SDL RISCom/8 card support' CONFIG_RISCOM8 - tristate 'Computone IntelliPort Plus serial support' CONFIG_COMPUTONE - tristate 'Specialix IO8+ card support' CONFIG_SPECIALIX + tristate ' SDL RISCom/8 card support' CONFIG_RISCOM8 + tristate ' Computone IntelliPort Plus serial support' CONFIG_COMPUTONE + tristate ' Specialix IO8+ card support' CONFIG_SPECIALIX if [ "$CONFIG_SPECIALIX" != "n" ]; then - bool 'Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS + bool ' Specialix DTR/RTS pin is RTS' CONFIG_SPECIALIX_RTSCTS fi - tristate 'Specialix SX (and SI) card support' CONFIG_SX - tristate 'Hayes ESP serial port support' CONFIG_ESPSERIAL + tristate ' Specialix SX (and SI) card support' CONFIG_SX + tristate ' Hayes ESP serial port support' CONFIG_ESPSERIAL if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'Multi-Tech multiport card support' CONFIG_ISI m + dep_tristate ' Multi-Tech multiport card support (EXPERIMENTAL)' CONFIG_ISI m fi - dep_tristate 'Microgate SyncLink card support' CONFIG_SYNCLINK m - dep_tristate 'HDLC line discipline support' CONFIG_N_HDLC m + dep_tristate ' Microgate SyncLink card support' CONFIG_SYNCLINK m + dep_tristate ' HDLC line discipline support' CONFIG_N_HDLC m fi bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then - int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 fi if [ "$CONFIG_PARPORT" != "n" ]; then - dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT - if [ "$CONFIG_PRINTER" != "n" ]; then - bool ' Support for console on line printer' CONFIG_LP_CONSOLE - fi - dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT + dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT + if [ "$CONFIG_PRINTER" != "n" ]; then + bool ' Support for console on line printer' CONFIG_LP_CONSOLE + fi + dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT fi mainmenu_option next_comment comment 'Mice' tristate 'Bus Mouse Support' CONFIG_BUSMOUSE if [ "$CONFIG_BUSMOUSE" != "n" ]; then - dep_tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE $CONFIG_BUSMOUSE - dep_tristate 'Logitech busmouse support' CONFIG_LOGIBUSMOUSE $CONFIG_BUSMOUSE - dep_tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE $CONFIG_BUSMOUSE - if [ "$CONFIG_ADB" = "y" ]; then - dep_tristate 'Apple Desktop Bus mouse support' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE - fi + dep_tristate ' ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE $CONFIG_BUSMOUSE + dep_tristate ' Logitech busmouse support' CONFIG_LOGIBUSMOUSE $CONFIG_BUSMOUSE + dep_tristate ' Microsoft busmouse support' CONFIG_MS_BUSMOUSE $CONFIG_BUSMOUSE + if [ "$CONFIG_ADB" = "y" ]; then + dep_tristate ' Apple Desktop Bus mouse support' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE + fi fi tristate 'Mouse Support (not serial and bus mice)' CONFIG_MOUSE if [ "$CONFIG_MOUSE" != "n" ]; then - bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE - tristate 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE - tristate 'PC110 digitizer pad support' CONFIG_PC110_PAD + bool ' PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE + tristate ' C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE + tristate ' PC110 digitizer pad support' CONFIG_PC110_PAD fi endmenu tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE if [ "$CONFIG_QIC02_TAPE" != "n" ]; then - bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF - if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then - comment ' Edit configuration parameters in ./include/linux/tpqic02.h!' - else - comment ' Setting runtime QIC-02 configuration is done with qic02conf' - comment ' from the tpqic02-support package. It is available at' - comment ' metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/' - fi - dep_tristate 'Zoran ZR36057/36060 support' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV - dep_tristate ' Include support for Iomega Buz' CONFIG_VIDEO_BUZ $CONFIG_VIDEO_ZORAN + bool ' Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF + if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then + comment ' Edit configuration parameters in ./include/linux/tpqic02.h!' + else + comment ' Setting runtime QIC-02 configuration is done with qic02conf' + comment ' from the tpqic02-support package. It is available at' + comment ' metalab.unc.edu or ftp://titus.cfw.com/pub/Linux/util/' + fi fi +mainmenu_option next_comment +comment 'Watchdog Cards' bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then - mainmenu_option next_comment - comment 'Watchdog Cards' - bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT - tristate ' WDT Watchdog timer' CONFIG_WDT - if [ "$CONFIG_WDT" != "n" ]; then - bool ' WDT501 features' CONFIG_WDT_501 - if [ "$CONFIG_WDT_501" = "y" ]; then + bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT + tristate ' WDT Watchdog timer' CONFIG_WDT + if [ "$CONFIG_WDT" != "n" ]; then + bool ' WDT501 features' CONFIG_WDT_501 + if [ "$CONFIG_WDT_501" = "y" ]; then bool ' Fan Tachometer' CONFIG_WDT_501_FAN - fi - fi - tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG - tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG - tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT - endmenu + fi + fi + tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG + tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG + tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT fi +endmenu tristate '/dev/nvram support' CONFIG_NVRAM bool 'Enhanced Real Time Clock Support' CONFIG_RTC if [ "$CONFIG_ALPHA_BOOK1" = "y" ]; then - bool 'Tadpole ANA H8 Support' CONFIG_H8 + bool 'Tadpole ANA H8 Support' CONFIG_H8 fi mainmenu_option next_comment @@ -126,68 +124,76 @@ tristate 'Video For Linux' CONFIG_VIDEO_DEV if [ "$CONFIG_VIDEO_DEV" != "n" ]; then - dep_tristate 'ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV - dep_tristate 'AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then - hex ' RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f - fi - dep_tristate 'AIMSlab RadioTrack II support' CONFIG_RADIO_RTRACK2 $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_RTRACK2" = "y" ]; then - hex ' RadioTrack II i/o port (0x20c or 0x30c)' CONFIG_RADIO_RTRACK2_PORT 30c - fi - dep_tristate 'Aztech/Packard Bell Radio' CONFIG_RADIO_AZTECH $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then - hex ' Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350 - fi - dep_tristate 'GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then - hex ' GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c - fi - dep_tristate 'Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV - dep_tristate 'TerraTec ActiveRadio ISA Standalone' CONFIG_RADIO_TERRATEC $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_TERRATEC" = "y" ]; then - hex ' Terratec i/o port (normally 0x590)' CONFIG_RADIO_TERRATEC_PORT 590 - fi - dep_tristate 'Trust FM radio card' CONFIG_RADIO_TRUST $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_TRUST" = "y" ]; then - hex ' Trust i/o port (usually 0x350 or 0x358)' CONFIG_RADIO_TRUST_PORT 350 - fi - if [ "$CONFIG_PCI" != "n" ]; then - dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV - fi - if [ "$CONFIG_PARPORT" != "n" ]; then - dep_tristate 'Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT - dep_tristate 'Colour QuickCam Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_CQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_SGI" = "y" ]; then - dep_tristate 'SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV - fi - fi - dep_tristate 'Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV - if [ "$CONFIG_PMAC" = "y" ]; then - dep_tristate 'PlanB Video-In on PowerMac' CONFIG_VIDEO_PLANB $CONFIG_VIDEO_DEV - fi - dep_tristate 'SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV - dep_tristate 'SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then - hex ' SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284 - fi - dep_tristate 'Typhoon Radio (a.k.a. EcoRadio)' CONFIG_RADIO_TYPHOON $CONFIG_VIDEO_DEV - if [ "$CONFIG_PROC_FS" = "y" ]; then + dep_tristate ' I2C on parallel port' CONFIG_I2C_PARPORT $CONFIG_PARPORT + comment 'Radio/Video Adapters' + dep_tristate ' ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV + dep_tristate ' AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then + hex ' RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f + fi + dep_tristate ' AIMSlab RadioTrack II support' CONFIG_RADIO_RTRACK2 $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_RTRACK2" = "y" ]; then + hex ' RadioTrack II i/o port (0x20c or 0x30c)' CONFIG_RADIO_RTRACK2_PORT 30c + fi + dep_tristate ' Aztech/Packard Bell Radio' CONFIG_RADIO_AZTECH $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then + hex ' Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350 + fi + if [ "$CONFIG_PCI" != "n" ]; then + dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV + fi + dep_tristate ' GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then + hex ' GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c + fi + dep_tristate ' Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV + dep_tristate ' Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV + if [ "$CONFIG_PMAC" = "y" ]; then + dep_tristate ' PlanB Video-In on PowerMac' CONFIG_VIDEO_PLANB $CONFIG_VIDEO_DEV + fi + if [ "$CONFIG_PARPORT" != "n" ]; then + dep_tristate ' Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' QuickCam Colour Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_CQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT + fi + fi + dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV + dep_tristate ' SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then + hex ' SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284 + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_SGI" = "y" ]; then + dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV + fi + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV + fi + dep_tristate ' TerraTec ActiveRadio ISA Standalone' CONFIG_RADIO_TERRATEC $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_TERRATEC" = "y" ]; then + hex ' Terratec i/o port (normally 0x590)' CONFIG_RADIO_TERRATEC_PORT 590 + fi + dep_tristate ' Trust FM radio card' CONFIG_RADIO_TRUST $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_TRUST" = "y" ]; then + hex ' Trust i/o port (usually 0x350 or 0x358)' CONFIG_RADIO_TRUST_PORT 350 + fi + dep_tristate ' Typhoon Radio (a.k.a. EcoRadio)' CONFIG_RADIO_TYPHOON $CONFIG_VIDEO_DEV + if [ "$CONFIG_PROC_FS" = "y" ]; then if [ "$CONFIG_RADIO_TYPHOON" != "n" ]; then - bool ' Support for /proc/radio-typhoon' CONFIG_RADIO_TYPHOON_PROC_FS + bool ' Support for /proc/radio-typhoon' CONFIG_RADIO_TYPHOON_PROC_FS fi - fi - if [ "$CONFIG_RADIO_TYPHOON" = "y" ]; then - hex ' Typhoon I/O port (0x316 or 0x336)' CONFIG_RADIO_TYPHOON_PORT 316 - int ' Typhoon frequency set when muting the device (kHz)' CONFIG_RADIO_TYPHOON_MUTEFREQ 87500 - fi - dep_tristate 'Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV - if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then - hex ' ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c - fi - dep_tristate 'IIC on parallel port' CONFIG_I2C_PARPORT $CONFIG_PARPORT + fi + if [ "$CONFIG_RADIO_TYPHOON" = "y" ]; then + hex ' Typhoon I/O port (0x316 or 0x336)' CONFIG_RADIO_TYPHOON_PORT 316 + int ' Typhoon frequency set when muting the device (kHz)' CONFIG_RADIO_TYPHOON_MUTEFREQ 87500 + fi + dep_tristate ' Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV + if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then + hex ' ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c + fi + dep_tristate ' Zoran ZR36057/36060 support' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV + dep_tristate ' Include support for Iomega Buz' CONFIG_VIDEO_BUZ $CONFIG_VIDEO_ZORAN fi endmenu @@ -197,7 +203,7 @@ tristate 'Joystick support' CONFIG_JOYSTICK if [ "$CONFIG_JOYSTICK" != "n" ]; then - source drivers/char/joystick/Config.in + source drivers/char/joystick/Config.in fi endmenu @@ -210,15 +216,19 @@ comment 'Ftape, the floppy tape device driver' tristate 'Ftape (QIC-80/Travan) support' CONFIG_FTAPE if [ "$CONFIG_FTAPE" != "n" ]; then - source drivers/char/ftape/Config.in + source drivers/char/ftape/Config.in fi endmenu if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM - if [ "$CONFIG_DRM" = "y" ]; then - dep_tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA m - fi + bool 'Direct Rendering Manager (XFree86 DRI support) (EXPERIMENTAL)' CONFIG_DRM + if [ "$CONFIG_DRM" = "y" ]; then + dep_tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA m + fi +fi + +if [ "$CONFIG_PCMCIA" != "n" ]; then + source drivers/char/pcmcia/Config.in fi endmenu diff -u --recursive --new-file v2.3.26/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.3.26/linux/drivers/char/Makefile Sun Nov 7 16:37:34 1999 +++ linux/drivers/char/Makefile Thu Nov 11 16:03:36 1999 @@ -11,7 +11,7 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) ftape joystick +ALL_SUB_DIRS := $(SUB_DIRS) ftape joystick pcmcia # # This file contains the font map for the default (hardware) font @@ -450,6 +450,14 @@ endif endif +ifeq ($(CONFIG_VIDEO_STRADIS),y) +O_OBJS += vino.o +else + ifeq ($(CONFIG_VIDEO_STRADIS),m) + M_OBJS += stradis.o + endif +endif + ifeq ($(CONFIG_RADIO_AZTECH),y) O_OBJS += radio-aztech.o else @@ -581,6 +589,15 @@ ifeq ($(CONFIG_DRM),y) ALL_SUB_DIRS += drm MOD_SUB_DIRS += drm +endif + +ifeq ($(CONFIG_PCMCIA),y) + SUB_DIRS += pcmcia + MOD_IN_SUB_DIRS += pcmcia +else + ifeq ($(CONFIG_PCMCIA),m) + MOD_IN_SUB_DIRS += pcmcia + endif endif include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.26/linux/drivers/char/console.c linux/drivers/char/console.c --- v2.3.26/linux/drivers/char/console.c Fri Oct 22 13:21:48 1999 +++ linux/drivers/char/console.c Wed Nov 10 20:01:03 1999 @@ -95,6 +95,7 @@ #include #endif #include +#include #include #include @@ -201,6 +202,11 @@ #define DO_UPDATE IS_VISIBLE #endif +static int acpi_con_transition(struct acpi_dev *dev, acpi_dstate_t state); +static struct acpi_dev_info acpi_con_info + = {ACPI_SYS_DEV, ACPI_VGA_HID, acpi_con_transition}; +static struct acpi_dev *acpi_con = NULL; + static inline unsigned short *screenpos(int currcons, int offset, int viewed) { unsigned short *p; @@ -654,6 +660,9 @@ screenbuf = (unsigned short *) q; kmalloced = 1; vc_init(currcons, video_num_lines, video_num_columns, 1); + + if (!acpi_con) + acpi_con = acpi_register(&acpi_con_info, 0); } return 0; } @@ -1991,6 +2000,8 @@ if (!printable || test_and_set_bit(0, &printing)) return; + acpi_access(acpi_con); + if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) currcons = kmsg_redirect - 1; @@ -2148,6 +2159,7 @@ { int retval; + acpi_access(acpi_con); retval = do_con_write(tty, from_user, buf, count); con_flush_chars(tty); @@ -2156,6 +2168,7 @@ static void con_put_char(struct tty_struct *tty, unsigned char ch) { + acpi_access(acpi_con); do_con_write(tty, 0, &ch, 1); } @@ -2221,6 +2234,7 @@ { struct vt_struct *vt = (struct vt_struct *)tty->driver_data; + acpi_access(acpi_con); set_cursor(vt->vc_num); } @@ -2806,6 +2820,21 @@ } } +static int acpi_con_transition(struct acpi_dev *dev, acpi_dstate_t state) +{ + switch (state) + { + case ACPI_D0: + unblank_screen(); + break; + case ACPI_D1: + case ACPI_D2: + case ACPI_D3: + do_blank_screen(0); + break; + } + return 0; +} /* * Visible symbols for modules diff -u --recursive --new-file v2.3.26/linux/drivers/char/cs8420.h linux/drivers/char/cs8420.h --- v2.3.26/linux/drivers/char/cs8420.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/cs8420.h Wed Nov 10 13:58:46 1999 @@ -0,0 +1,50 @@ +/* cs8420.h - cs8420 initializations + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ +#ifndef __CS8420_H__ +#define __CS8420_H__ + +/* Initialization Sequence */ + +static __u8 init8420[] = { + 1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46, + 5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13, +}; + +#define INIT8420LEN (sizeof(init8420)/2) + +static __u8 mode8420pro[] = { /* professional output mode */ + 32, 0xa1, 33, 0x00, 34, 0x00, 35, 0x00, + 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00, + 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00, + 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00, + 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00, + 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00, +}; +#define MODE8420LEN (sizeof(mode8420pro)/2) + +static __u8 mode8420con[] = { /* consumer output mode */ + 32, 0x20, 33, 0x00, 34, 0x00, 35, 0x48, + 36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00, + 40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00, + 44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00, + 48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00, + 52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00, +}; + +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/char/dn_keyb.c linux/drivers/char/dn_keyb.c --- v2.3.26/linux/drivers/char/dn_keyb.c Mon Oct 11 15:38:14 1999 +++ linux/drivers/char/dn_keyb.c Mon Nov 8 11:03:20 1999 @@ -1,4 +1,3 @@ -#include #include #include #include @@ -18,8 +17,9 @@ #include #include +#include "busmouse.h" -extern void handle_scancode(unsigned char); +/* extern void handle_scancode(unsigned char,int ); */ #define DNKEY_CAPS 0x7e #define BREAK_FLAG 0x80 @@ -37,18 +37,12 @@ #define APOLLO_KBD_MODE_MOUSE 0x02 #define APOLLO_KBD_MODE_CHANGE 0xff -#define MSE_UPDATE_ON() mouse_update_allowed=1 -#define MSE_UPDATE_OFF() mouse_update_allowed=0 - static u_char keyb_cmds[APOLLO_KEYB_CMD_ENTRIES]; static short keyb_cmd_read=0, keyb_cmd_write=0; static int keyb_cmd_transmit=0; +static int msedev; static unsigned int kbd_mode=APOLLO_KBD_MODE_KEYB; -static short mouse_dx,mouse_dy,mouse_buttons; -static int mouse_ready=0,mouse_update_allowed=0,mouse_active=0; -static DECLARE_WAIT_QUEUE_HEAD(mouse_wait); -static struct fasync_struct *mouse_fasyncptr=NULL; #if 0 static void debug_keyb_timer_handler(unsigned long ignored); @@ -302,103 +296,6 @@ } #endif -static unsigned int mouse_poll(struct file *file, poll_table * wait) -{ - poll_wait(&mouse_wait, wait); - if (mouse_ready) - return POLLIN | POLLRDNORM; - return 0; -} - -static ssize_t write_mouse(struct file * file, const char * buffer, - size_t count, loff_t *ppos) -{ - return -EINVAL; -} - -static ssize_t read_mouse(struct file * file, char * buffer, - size_t count, loff_t *ppos) -{ - int dx,dy,r; - unsigned char buttons; - - if (count < 3) - return -EINVAL; - if ((r = verify_area(VERIFY_WRITE, buffer, count))) - return r; - if (!mouse_ready) - return -EAGAIN; - - MSE_UPDATE_OFF(); - dx=mouse_dx; - dy=mouse_dy; - if (dx < -127) - dx = -127; - else - if (dx > 127) - dx = 127; - if (dy < -127) - dy = -127; - else - if (dy > 127) - dy = 127; - buttons=(mouse_buttons & 1 ? 4 : 0) | - (mouse_buttons & 2 ? 1 : 0) | - (mouse_buttons & 4 ? 2 : 0); - - mouse_dx-=dx; - mouse_dy-=dy; - MSE_UPDATE_ON(); - - if (put_user(buttons | 0x80, buffer++) || - put_user((char)dx, buffer++) || - put_user((char)dy, buffer++)) - return -EINVAL; - - if (count > 3) - if (clear_user(buffer, count - 3)) - return -EFAULT; - return count; -} - -static int fasync_mouse(int fd, struct file *filp, int on) -{ - int retval; - - retval = fasync_helper(fd, filp, on, &mouse_fasyncptr); - if (retval < 0) - return retval; - return 0; -} - - -static int release_mouse(struct inode * inode, struct file * file) -{ - fasync_mouse(-1, file, 0); - if (--mouse_active) - return 0; - MSE_UPDATE_OFF(); - MOD_DEC_USE_COUNT; - return 0; -} - -static int open_mouse(struct inode * inode, struct file * file) -{ - if (mouse_active++) - return 0; - /* - * use VBL to poll mouse deltas - */ - - mouse_dx = 0; - mouse_dy = 0; - mouse_buttons = 0; - mouse_active = 1; - MOD_INC_USE_COUNT; - MSE_UPDATE_ON(); - return 0; -} - static void dn_keyb_process_key_event(unsigned char scancode) { static unsigned char lastscancode; @@ -411,7 +308,7 @@ if(prev_scancode==APOLLO_KBD_MODE_CHANGE) { kbd_mode=scancode; -/* printk("modechange: %d\n",scancode);*/ +/* printk("modechange: %d\n",scancode); */ } else if((scancode & (~BREAK_FLAG)) == DNKEY_CAPS) { /* printk("handle_scancode: %02x\n",DNKEY_CAPS); */ @@ -440,7 +337,8 @@ static short mouse_byte_count=0; static u_char mouse_packet[3]; - + short mouse_buttons; + mouse_packet[mouse_byte_count++]=mouse_data; if(mouse_byte_count==3) { @@ -552,23 +450,20 @@ } -struct file_operations apollo_mouse_fops = { - NULL, /* mouse_seek */ - read_mouse, - write_mouse, - NULL, /* mouse_readdir */ - mouse_poll, /* mouse_poll */ - NULL, /* mouse_ioctl */ - NULL, /* mouse_mmap */ - open_mouse, - NULL, /* flush */ - release_mouse, - NULL, - fasync_mouse, -}; +static int release_mouse(struct inode * inode, struct file * file) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +static int open_mouse(struct inode * inode, struct file * file) +{ + MOD_INC_USE_COUNT; + return 0; +} -static struct miscdevice apollo_mouse = { - APOLLO_MOUSE_MINOR, "apollomouse", &apollo_mouse_fops +static struct busmouse apollo_mouse = { + APOLLO_MOUSE_MINOR, "apollomouse", open_mouse, release_mouse,7 }; int __init dn_keyb_init(void){ @@ -583,12 +478,12 @@ memcpy(key_maps[8], dnalt_map, sizeof(plain_map)); memcpy(key_maps[12], dnctrl_alt_map, sizeof(plain_map)); - mouse_dx=0; - mouse_dy=0; - mouse_buttons=0; - mouse_wait=NULL; - misc_register(&apollo_mouse); + msedev=register_busmouse(&apollo_mouse); + if (msedev < 0) + printk(KERN_WARNING "Unable to install Apollo mouse driver.\n"); + else + printk(KERN_INFO "Apollo mouse installed.\n"); /* program UpDownMode */ diff -u --recursive --new-file v2.3.26/linux/drivers/char/drm/sigio.c linux/drivers/char/drm/sigio.c --- v2.3.26/linux/drivers/char/drm/sigio.c Fri Sep 10 23:57:29 1999 +++ linux/drivers/char/drm/sigio.c Wed Nov 10 10:00:48 1999 @@ -35,7 +35,6 @@ # include "xf86.h" # include "xf86drm.h" # include "xf86_OSlib.h" -# include "xf86drm.h" #else # include # include diff -u --recursive --new-file v2.3.26/linux/drivers/char/dsp56k.c linux/drivers/char/dsp56k.c --- v2.3.26/linux/drivers/char/dsp56k.c Mon Aug 9 12:32:28 1999 +++ linux/drivers/char/dsp56k.c Mon Nov 8 11:03:20 1999 @@ -73,13 +73,13 @@ m = min(count, maxio); \ for (i = 0; i < m; i++) { \ for (t = 0; t < timeout && !ENABLE; t++) \ - wait_some(2); \ + wait_some(HZ/50); \ if(!ENABLE) \ return -EIO; \ f; \ } \ count -= m; \ - if (m == maxio) wait_some(2); \ + if (m == maxio) wait_some(HZ/50); \ } \ } @@ -87,7 +87,7 @@ { \ int t; \ for(t = 0; t < n && !DSP56K_TRANSMIT; t++) \ - wait_some(1); \ + wait_some(HZ/100); \ if(!DSP56K_TRANSMIT) { \ return -EIO; \ } \ @@ -97,7 +97,7 @@ { \ int t; \ for(t = 0; t < n && !DSP56K_RECEIVE; t++) \ - wait_some(1); \ + wait_some(HZ/100); \ if(!DSP56K_RECEIVE) { \ return -EIO; \ } \ diff -u --recursive --new-file v2.3.26/linux/drivers/char/ftape/lowlevel/ftape-proc.c linux/drivers/char/ftape/lowlevel/ftape-proc.c --- v2.3.26/linux/drivers/char/ftape/lowlevel/ftape-proc.c Tue Jul 6 19:16:55 1999 +++ linux/drivers/char/ftape/lowlevel/ftape-proc.c Tue Nov 9 19:39:02 1999 @@ -22,245 +22,25 @@ * * This file contains the procfs interface for the * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux. + + * Old code removed, switched to dynamic proc entry. */ #include #if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) -/* adding proc entries from inside a module is REALLY complicated - * for pre-2.1.28 kernels. I don't want to care about it. - */ - #include #include -#if LINUX_VERSION_CODE <= KERNEL_VER(1,2,13) /* bail out */ -#error \ -Please disable CONFIG_FT_PROC_FS in "MCONFIG" or upgrade to a newer kernel! -#endif -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,16) #include -#else -#define __initdata -#define __initfunc(__arg) __arg -#endif #include - #include "../lowlevel/ftape-io.h" #include "../lowlevel/ftape-ctl.h" #include "../lowlevel/ftape-proc.h" #include "../lowlevel/ftape-tracing.h" -static int ftape_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -#if LINUX_VERSION_CODE < KERNEL_VER(2,1,28) - -#include /* for memcpy_tofs() */ - -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0) -static long ftape_proc_read(struct inode* inode, struct file* file, - char* buf, unsigned long count); -#else -static int ftape_proc_read(struct inode* inode, struct file* file, - char* buf, int count); -#endif - -#define FT_PROC_REGISTER(parent, child) proc_register_dynamic(parent, child) - -/* - * Structures for interfacing with the /proc filesystem. - * Router creates its own directory /proc/net/router with the folowing - * entries: - * config device configuration - * status global device statistics - * entry for each WAN device - */ - -/* - * Generic /proc/net/ftape/ file and inode operations - */ - - -static struct file_operations ftape_proc_fops = -{ - NULL, /* lseek */ - ftape_proc_read, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL, /* can't fsync */ -}; - -static struct inode_operations ftape_proc_inode_operations = -{ - &ftape_proc_fops, - 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 */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL, /* revalidate */ -}; - -/* - * Proc filesystem directory entries. - */ - -static int ftape_get_info(char *page, char **start, off_t off, - int count, int dummy) -{ - int dummy_eof; - - return ftape_read_proc(page, start, off, count, &dummy_eof, NULL); -} - -static struct proc_dir_entry proc_ftape = { - 0, /* low_ino */ - sizeof("ftape")-1, /* namelen */ - "ftape", /* name */ - S_IFREG | S_IRUGO, /* mode */ - 1, /* nlink */ - 0, /* uid */ - 0, /* gid */ - 0, /* size */ - &ftape_proc_inode_operations, /* ops */ - ftape_get_info, /* get_info */ - NULL, /* fill_inode */ - NULL, /* next */ - NULL, /* parent */ - NULL, /* subdir */ - NULL /* data */ -}; - -/* Read ftape proc directory entry. - */ - -#define PROC_BLOCK_SIZE PAGE_SIZE - -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0) -static long ftape_proc_read(struct inode * inode, struct file * file, - char * buf, unsigned long nbytes) -#else -static int ftape_proc_read(struct inode * inode, struct file * file, - char * buf, int nbytes) -#endif -{ - char *page; - int retval=0; - int eof=0; - int n, count; - char *start; - struct proc_dir_entry * dp; - - if (nbytes < 0) - return -EINVAL; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if (!(page = (char*) __get_free_page(GFP_KERNEL))) - return -ENOMEM; - - while ((nbytes > 0) && !eof) - { - count = PROC_BLOCK_SIZE <= nbytes ? PROC_BLOCK_SIZE : nbytes; - - start = NULL; - if (dp->get_info) { - /* - * Handle backwards compatibility with the old net - * routines. - * - * XXX What gives with the file->f_flags & O_ACCMODE - * test? Seems stupid to me.... - */ - n = dp->get_info(page, &start, file->f_pos, count, - (file->f_flags & O_ACCMODE) == O_RDWR); - if (n < count) - eof = 1; - } else - break; - - if (!start) { - /* - * For proc files that are less than 4k - */ - start = page + file->f_pos; - n -= file->f_pos; - if (n <= 0) - break; - if (n > count) - n = count; - } - if (n == 0) - break; /* End of file */ - if (n < 0) { - if (retval == 0) - retval = n; - break; - } -#if LINUX_VERSION_CODE > KERNEL_VER(2,1,3) - copy_to_user(buf, start, n); -#else - memcpy_tofs(buf, start, n); -#endif - file->f_pos += n; /* Move down the file */ - nbytes -= n; - buf += n; - retval += n; - } - free_page((unsigned long) page); - return retval; -} - -#else /* LINUX_VERSION_CODE < KERNEL_VER(2,1,28) */ - -#define FT_PROC_REGISTER(parent, child) proc_register(parent, child) - -/* - * Proc filesystem directory entries. - */ - -static struct proc_dir_entry proc_ftape = { - 0, /* low_ino */ - sizeof("ftape")-1, /* namelen */ - "ftape", /* name */ - S_IFREG | S_IRUGO, /* mode */ - 1, /* nlink */ - 0, /* uid */ - 0, /* gid */ - 0, /* size */ - NULL, /* ops */ - NULL, /* get_info */ - NULL, /* fill_inode */ - NULL, /* next */ - NULL, /* parent */ - NULL, /* subdir */ - NULL, /* data */ - ftape_read_proc, /* read_proc */ - NULL /* write_proc */ -}; - -#endif - static size_t get_driver_info(char *buf) { const char *debug_level[] = { "bugs" , @@ -423,13 +203,14 @@ int __init ftape_proc_init(void) { - return FT_PROC_REGISTER(&proc_root, &proc_ftape); + return create_proc_read_entry("ftape", 0, &proc_root, + ftape_read_proc, NULL) != NULL; } #ifdef MODULE void ftape_proc_destroy(void) { - proc_unregister(&proc_root, proc_ftape.low_ino); + remove_proc_entry("ftape", &proc_root); } #endif diff -u --recursive --new-file v2.3.26/linux/drivers/char/ibmmpeg2.h linux/drivers/char/ibmmpeg2.h --- v2.3.26/linux/drivers/char/ibmmpeg2.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/ibmmpeg2.h Wed Nov 10 13:58:46 1999 @@ -0,0 +1,94 @@ +/* ibmmpeg2.h - IBM MPEGCD21 definitions */ + +#ifndef __IBM_MPEG2__ +#define __IBM_MPEG2__ + +/* Define all MPEG Decoder registers */ +/* Chip Control and Status */ +#define IBM_MP2_CHIP_CONTROL 0x200*2 +#define IBM_MP2_CHIP_MODE 0x201*2 +/* Timer Control and Status */ +#define IBM_MP2_SYNC_STC2 0x202*2 +#define IBM_MP2_SYNC_STC1 0x203*2 +#define IBM_MP2_SYNC_STC0 0x204*2 +#define IBM_MP2_SYNC_PTS2 0x205*2 +#define IBM_MP2_SYNC_PTS1 0x206*2 +#define IBM_MP2_SYNC_PTS0 0x207*2 +/* Video FIFO Control */ +#define IBM_MP2_FIFO 0x208*2 +#define IBM_MP2_FIFOW 0x100*2 +#define IBM_MP2_FIFO_STAT 0x209*2 +#define IBM_MP2_RB_THRESHOLD 0x22b*2 +/* Command buffer */ +#define IBM_MP2_COMMAND 0x20a*2 +#define IBM_MP2_CMD_DATA 0x20b*2 +#define IBM_MP2_CMD_STAT 0x20c*2 +#define IBM_MP2_CMD_ADDR 0x20d*2 +/* Internal Processor Control and Status */ +#define IBM_MP2_PROC_IADDR 0x20e*2 +#define IBM_MP2_PROC_IDATA 0x20f*2 +#define IBM_MP2_WR_PROT 0x235*2 +/* DRAM Access */ +#define IBM_MP2_DRAM_ADDR 0x210*2 +#define IBM_MP2_DRAM_DATA 0x212*2 +#define IBM_MP2_DRAM_CMD_STAT 0x213*2 +#define IBM_MP2_BLOCK_SIZE 0x23b*2 +#define IBM_MP2_SRC_ADDR 0x23c*2 +/* Onscreen Display */ +#define IBM_MP2_OSD_ADDR 0x214*2 +#define IBM_MP2_OSD_DATA 0x215*2 +#define IBM_MP2_OSD_MODE 0x217*2 +#define IBM_MP2_OSD_LINK_ADDR 0x229*2 +#define IBM_MP2_OSD_SIZE 0x22a*2 +/* Interrupt Control */ +#define IBM_MP2_HOST_INT 0x218*2 +#define IBM_MP2_MASK0 0x219*2 +#define IBM_MP2_HOST_INT1 0x23e*2 +#define IBM_MP2_MASK1 0x23f*2 +/* Audio Control */ +#define IBM_MP2_AUD_IADDR 0x21a*2 +#define IBM_MP2_AUD_IDATA 0x21b*2 +#define IBM_MP2_AUD_FIFO 0x21c*2 +#define IBM_MP2_AUD_FIFOW 0x101*2 +#define IBM_MP2_AUD_CTL 0x21d*2 +#define IBM_MP2_BEEP_CTL 0x21e*2 +#define IBM_MP2_FRNT_ATTEN 0x22d*2 +/* Display Control */ +#define IBM_MP2_DISP_MODE 0x220*2 +#define IBM_MP2_DISP_DLY 0x221*2 +#define IBM_MP2_VBI_CTL 0x222*2 +#define IBM_MP2_DISP_LBOR 0x223*2 +#define IBM_MP2_DISP_TBOR 0x224*2 +/* Polarity Control */ +#define IBM_MP2_INFC_CTL 0x22c*2 + +/* control commands */ +#define IBM_MP2_PLAY 0 +#define IBM_MP2_PAUSE 1 +#define IBM_MP2_SINGLE_FRAME 2 +#define IBM_MP2_FAST_FORWARD 3 +#define IBM_MP2_SLOW_MOTION 4 +#define IBM_MP2_IMED_NORM_PLAY 5 +#define IBM_MP2_RESET_WINDOW 6 +#define IBM_MP2_FREEZE_FRAME 7 +#define IBM_MP2_RESET_VID_RATE 8 +#define IBM_MP2_CONFIG_DECODER 9 +#define IBM_MP2_CHANNEL_SWITCH 10 +#define IBM_MP2_RESET_AUD_RATE 11 +#define IBM_MP2_PRE_OP_CHN_SW 12 +#define IBM_MP2_SET_STILL_MODE 14 + +/* Define Xilinx FPGA Internal Registers */ + +/* general control register 0 */ +#define XILINX_CTL0 0x600 +/* genlock delay resister 1 */ +#define XILINX_GLDELAY 0x602 +/* send 16 bits to CS3310 port */ +#define XILINX_CS3310 0x604 +/* send 16 bits to CS3310 and complete */ +#define XILINX_CS3310_CMPLT 0x60c +/* pulse width modulator control */ +#define XILINX_PWM 0x606 + +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/char/ip2main.c linux/drivers/char/ip2main.c --- v2.3.26/linux/drivers/char/ip2main.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/char/ip2main.c Tue Nov 9 19:39:02 1999 @@ -74,16 +74,6 @@ int ip2_read_procmem(char *, char **, off_t, int, int ); int ip2_read_proc(char *, char **, off_t, int, int *, void * ); -struct proc_dir_entry ip2_proc_entry = { - 0, - 6,"ip2mem", - S_IFREG | S_IRUGO, - 1, 0, 0, - 0, - NULL, - ip2_read_procmem -}; - /********************/ /* Type Definitions */ /********************/ @@ -429,9 +419,7 @@ if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) { printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err); } - if ( ( err = proc_unregister( &proc_root, ip2_proc_entry.low_ino ) ) ) { - printk(KERN_ERR "IP2: failed to unregister read_procmem (%d)\n", err); - } + remove_proc_entry("ip2mem", &proc_root); // free memory for (i = 0; i < IP2_MAX_BOARDS; i++) { @@ -673,8 +661,8 @@ printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); } else /* Register the read_procmem thing */ - if ( ( err = proc_register( &proc_root, &ip2_proc_entry ) ) ) { - printk(KERN_ERR "IP2: failed to register read_procmem (%d)\n", err ); + if (!create_proc_info_entry("ip2mem",0,&proc_root,ip2_read_procmem)) { + printk(KERN_ERR "IP2: failed to register read_procmem\n"); } else { #ifdef IP2DEBUG_TRACE diff -u --recursive --new-file v2.3.26/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c --- v2.3.26/linux/drivers/char/keyboard.c Fri Oct 15 15:25:13 1999 +++ linux/drivers/char/keyboard.c Wed Nov 10 20:01:03 1999 @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -42,6 +41,7 @@ #include #include #include +#include #define SIZE(x) (sizeof(x)/sizeof((x)[0])) @@ -159,6 +159,9 @@ int sysrq_enabled = 1; #endif +static struct acpi_dev_info acpi_kbd_info = {ACPI_SYS_DEV, ACPI_KBC_HID, NULL}; +static struct acpi_dev *acpi_kbd = NULL; + /* * Many other routines do put_queue, but I think either * they produce ASCII, or they produce some user-assigned @@ -201,6 +204,8 @@ char up_flag = down ? 0 : 0200; char raw_mode; + acpi_access(acpi_kbd); + do_poke_blanked_console = 1; mark_bh(CONSOLE_BH); add_keyboard_randomness(scancode | up_flag); @@ -923,5 +928,8 @@ kbd_init_hw(); init_bh(KEYBOARD_BH, kbd_bh); mark_bh(KEYBOARD_BH); + + acpi_kbd = acpi_register(&acpi_kbd_info, 0); + return 0; } diff -u --recursive --new-file v2.3.26/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.3.26/linux/drivers/char/mem.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/char/mem.c Wed Nov 10 08:40:04 1999 @@ -56,6 +56,9 @@ #ifdef CONFIG_USB extern void usb_init(void); #endif +#ifdef CONFIG_PPDEV +extern int pp_init(void); +#endif static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp, const char * buf, size_t count, loff_t *ppos) @@ -672,6 +675,9 @@ #endif #ifdef CONFIG_VIDEO_DEV videodev_init(); +#endif +#ifdef CONFIG_PPDEV + pp_init(); #endif return 0; } diff -u --recursive --new-file v2.3.26/linux/drivers/char/n_hdlc.c linux/drivers/char/n_hdlc.c --- v2.3.26/linux/drivers/char/n_hdlc.c Mon Oct 11 15:38:14 1999 +++ linux/drivers/char/n_hdlc.c Wed Nov 10 10:00:48 1999 @@ -105,7 +105,6 @@ #include #include #include -#include /* to get the struct task_struct */ #include /* used in new tty drivers */ #include /* used in new tty drivers */ #include diff -u --recursive --new-file v2.3.26/linux/drivers/char/pcmcia/Config.in linux/drivers/char/pcmcia/Config.in --- v2.3.26/linux/drivers/char/pcmcia/Config.in Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/pcmcia/Config.in Thu Nov 11 16:03:36 1999 @@ -0,0 +1,31 @@ +# +# PCMCIA character device configuration +# + +mainmenu_option next_comment +comment 'PCMCIA character device support' + +if [ "$CONFIG_SERIAL" = "y" ]; then + dep_tristate ' PCMCIA serial device support' \ + CONFIG_PCMCIA_SERIAL_CS $CONFIG_PCMCIA + if [ "$CONFIG_CARDBUS" = "y" ]; then + dep_tristate ' CardBus serial device support' \ + CONFIG_PCMCIA_SERIAL_CB $CONFIG_PCMCIA + fi +fi + +if [ "$CONFIG_SERIAL" = "m" ]; then + dep_tristate ' PCMCIA serial device support' \ + CONFIG_PCMCIA_SERIAL_CS m + if [ "$CONFIG_CARDBUS" = "y" ]; then + dep_tristate ' CardBus serial device support' \ + CONFIG_PCMCIA_SERIAL_CB m + fi +fi + +if [ "$CONFIG_PCMCIA_SERIAL_CS" = "y" -o \ + "$CONFIG_PCMCIA_SERIAL_CB" = "y" ]; then + define_bool CONFIG_PCMCIA_CHRDEV y +fi + +endmenu diff -u --recursive --new-file v2.3.26/linux/drivers/char/pcmcia/Makefile linux/drivers/char/pcmcia/Makefile --- v2.3.26/linux/drivers/char/pcmcia/Makefile Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/pcmcia/Makefile Thu Nov 11 16:03:36 1999 @@ -0,0 +1,27 @@ +# +# drivers/char/pcmcia/Makefile +# +# Makefile for the Linux PCMCIA char device drivers. +# + +SUB_DIRS := +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) + +O_TARGET := pcmcia_char.o +MOD_LIST_NAME := PCMCIA_CHAR_MODULES + +obj-y := +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_PCMCIA_SERIAL_CS) += serial_cs.o +obj-$(CONFIG_PCMCIA_SERIAL_CB) += serial_cb.o + +O_OBJS := $(obj-y) +OX_OBJS := +M_OBJS := $(obj-m) +MX_OBJS := + +include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.26/linux/drivers/char/pcmcia/serial_cb.c linux/drivers/char/pcmcia/serial_cb.c --- v2.3.26/linux/drivers/char/pcmcia/serial_cb.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/pcmcia/serial_cb.c Thu Nov 11 16:03:36 1999 @@ -0,0 +1,150 @@ +/*====================================================================== + + A driver for CardBus serial devices + + serial_cb.c 1.14 1999/11/11 02:18:08 + + Copyright 1998, 1999 by Donald Becker and David Hinds + + This software may be used and distributed according to the terms + of the GNU Public License, incorporated herein by reference. + All other rights reserved. + + This driver is an activator for CardBus serial cards, as + found on multifunction (e.g. Ethernet and Modem) CardBus cards. + + Donald Becker may be reached as becker@CESDIS.edu, or C/O + USRA Center of Excellence in Space Data and Information Sciences + Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771 + David Hinds may be reached at dhinds@pcmcia.sourceforge.org + +======================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) +static char *version = +"serial_cb.c 1.14 1999/11/11 02:18:08 (David Hinds)"; +#else +#define DEBUG(n, args...) +#endif + +/*====================================================================== + + Card-specific configuration hacks + +======================================================================*/ + +static void device_setup(u_char bus, u_char devfn, u_int ioaddr) +{ + u_short a, b; + + pcibios_read_config_word(bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &a); + pcibios_read_config_word(bus, devfn, PCI_SUBSYSTEM_ID, &b); + if ((a == 0x13a2) && (b == 0x8007)) { + /* Ositech Jack of Spades */ + DEBUG(0, " 83c175 NVCTL_m = 0x%4.4x.\n", inl(ioaddr+0x80)); + outl(0x4C00, ioaddr + 0x80); + outl(0x4C80, ioaddr + 0x80); + } + DEBUG(0, " modem registers are %2.2x %2.2x %2.2x " + "%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x.\n", + inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2), + inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5), + inb(ioaddr + 6), inb(ioaddr + 7), inb(ioaddr + 8)); +} + +/*====================================================================== + + serial_attach() creates a serial device "instance" and registers + it with the kernel serial driver, and serial_detach() unregisters + an instance. + +======================================================================*/ + +static dev_node_t *serial_attach(dev_locator_t *loc) +{ + u_int io; + u_char bus, devfn, irq; + int line; + struct serial_struct serial; + + if (loc->bus != LOC_PCI) return NULL; + bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; + printk(KERN_INFO "serial_attach(bus %d, fn %d)\n", bus, devfn); + pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io); + pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq); + if (io & PCI_BASE_ADDRESS_SPACE_IO) { + io &= PCI_BASE_ADDRESS_IO_MASK; + } else { + printk(KERN_NOTICE "serial_cb: PCI base address 0 is not IO\n"); + return NULL; + } + device_setup(bus, devfn, io); + memset(&serial, 0, sizeof(serial)); + serial.port = io; serial.irq = irq; + serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ; + + /* Some devices seem to need extra time */ + __set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/50); + + line = register_serial(&serial); + if (line < 0) { + printk(KERN_NOTICE "serial_cb: register_serial() at 0x%04x, " + "irq %d failed\n", serial.port, serial.irq); + return NULL; + } else { + dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL); + sprintf(node->dev_name, "ttyS%d", line); + node->major = TTY_MAJOR; node->minor = 0x40 + line; + node->next = NULL; + MOD_INC_USE_COUNT; + return node; + } +} + +static void serial_detach(dev_node_t *node) +{ + DEBUG(0, "serial_detach(tty%02d)\n", node->minor - 0x40); + unregister_serial(node->minor - 0x40); + kfree(node); + MOD_DEC_USE_COUNT; +} + +/*====================================================================*/ + +struct driver_operations serial_ops = { + "serial_cb", serial_attach, NULL, NULL, serial_detach +}; + +static int __init init_serial_cb(void) +{ + DEBUG(0, "%s\n", version); + register_driver(&serial_ops); + return 0; +} + +static void __exit exit_serial_cb(void) +{ + DEBUG(0, "serial_cb: unloading\n"); + unregister_driver(&serial_ops); +} + +module_init(init_serial_cb); +module_exit(exit_serial_cb); diff -u --recursive --new-file v2.3.26/linux/drivers/char/pcmcia/serial_cs.c linux/drivers/char/pcmcia/serial_cs.c --- v2.3.26/linux/drivers/char/pcmcia/serial_cs.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/pcmcia/serial_cs.c Thu Nov 11 16:03:36 1999 @@ -0,0 +1,667 @@ +/*====================================================================== + + A driver for PCMCIA serial devices + + serial_cs.c 1.114 1999/11/11 00:54:46 + + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + + Alternatively, the contents of this file may be used under the + terms of the GNU Public License version 2 (the "GPL"), in which + case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + +======================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) +static char *version = +"serial_cs.c 1.114 1999/11/11 00:54:46 (David Hinds)"; +#else +#define DEBUG(n, args...) +#endif + +/*====================================================================*/ + +/* Parameters that can be set with 'insmod' */ + +/* Bit map of interrupts to choose from */ +static u_int irq_mask = 0xdeb8; +static int irq_list[4] = { -1 }; + +/* Enable the speaker? */ +static int do_sound = 1; + +MODULE_PARM(irq_mask, "i"); +MODULE_PARM(irq_list, "1-4i"); +MODULE_PARM(do_sound, "i"); + +/*====================================================================*/ + +/* Table of multi-port card ID's */ + +typedef struct { + u_short manfid; + u_short prodid; + int multi; /* 1 = multifunction, > 1 = # ports */ +} multi_id_t; + +static multi_id_t multi_id[] = { + { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 }, + { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 }, + { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 }, + { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 }, + { MANFID_SOCKET, PRODID_SOCKET_DUAL_RS232, 2 }, + { MANFID_INTEL, PRODID_INTEL_DUAL_RS232, 2 }, + { MANFID_NATINST, PRODID_NATINST_QUAD_RS232, 4 } +}; +#define MULTI_COUNT (sizeof(multi_id)/sizeof(multi_id_t)) + +typedef struct serial_info_t { + int ndev; + int multi; + int slave; + int manfid; + dev_node_t node[4]; + int line[4]; +} serial_info_t; + +static void serial_config(dev_link_t *link); +static void serial_release(u_long arg); +static int serial_event(event_t event, int priority, + event_callback_args_t *args); + +static dev_info_t dev_info = "serial_cs"; + +static dev_link_t *serial_attach(void); +static void serial_detach(dev_link_t *); + +static dev_link_t *dev_list = NULL; + +/*====================================================================*/ + +static void cs_error(client_handle_t handle, int func, int ret) +{ + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); +} + +/*====================================================================== + + serial_attach() creates an "instance" of the driver, allocating + local data structures for one device. The device is registered + with Card Services. + +======================================================================*/ + +static dev_link_t *serial_attach(void) +{ + client_reg_t client_reg; + dev_link_t *link; + int i, ret; + + DEBUG(0, "serial_attach()\n"); + + /* Create new serial device */ + link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); + memset(link, 0, sizeof(struct dev_link_t)); + link->release.function = &serial_release; + link->release.data = (u_long)link; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.NumPorts1 = 8; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + if (do_sound) { + link->conf.Attributes |= CONF_ENABLE_SPKR; + link->conf.Status = CCSR_AUDIO_ENA; + } + link->conf.IntType = INT_MEMORY_AND_IO; + link->priv = kmalloc(sizeof(struct serial_info_t), GFP_KERNEL); + memset(link->priv, 0, sizeof(struct serial_info_t)); + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &serial_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != CS_SUCCESS) { + cs_error(link->handle, RegisterClient, ret); + serial_detach(link); + return NULL; + } + + return link; +} /* serial_attach */ + +/*====================================================================== + + This deletes a driver "instance". The device is de-registered + with Card Services. If it has been released, all local data + structures are freed. Otherwise, the structures will be freed + when the device is released. + +======================================================================*/ + +static void serial_detach(dev_link_t *link) +{ + dev_link_t **linkp; + long flags; + int ret; + + DEBUG(0, "serial_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; + + save_flags(flags); + cli(); + if (link->state & DEV_RELEASE_PENDING) { + del_timer(&link->release); + link->state &= ~DEV_RELEASE_PENDING; + } + restore_flags(flags); + + if (link->state & DEV_CONFIG) + serial_release((u_long)link); + + if (link->handle) { + ret = CardServices(DeregisterClient, link->handle); + if (ret != CS_SUCCESS) + cs_error(link->handle, DeregisterClient, ret); + } + + /* Unlink device structure, free bits */ + *linkp = link->next; + kfree_s(link->priv, sizeof(serial_info_t)); + kfree_s(link, sizeof(struct dev_link_t)); + +} /* serial_detach */ + +/*====================================================================*/ + +static int setup_serial(serial_info_t *info, ioaddr_t port, int irq) +{ + struct serial_struct serial; + int line; + + memset(&serial, 0, sizeof(serial)); + serial.port = port; + serial.irq = irq; + serial.flags = ASYNC_SKIP_TEST; + serial.flags |= (info->multi || info->slave) ? ASYNC_SHARE_IRQ : 0; + line = register_serial(&serial); + if (line < 0) { + printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04x, " + "irq %d failed\n", serial.port, serial.irq); + return -1; + } + + info->line[info->ndev] = line; + sprintf(info->node[info->ndev].dev_name, "ttyS%d", line); + info->node[info->ndev].major = TTY_MAJOR; + info->node[info->ndev].minor = 0x40+line; + if (info->ndev > 0) + info->node[info->ndev-1].next = &info->node[info->ndev]; + info->ndev++; + + return 0; +} + +/*====================================================================*/ + +static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, + cisparse_t *parse) +{ + int i; + i = CardServices(fn, handle, tuple); + if (i != CS_SUCCESS) return CS_NO_MORE_ITEMS; + i = CardServices(GetTupleData, handle, tuple); + if (i != CS_SUCCESS) return i; + return CardServices(ParseTuple, handle, tuple, parse); +} + +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c) +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c) + +/*====================================================================*/ + +static int simple_config(dev_link_t *link) +{ + static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; + client_handle_t handle = link->handle; + serial_info_t *info = link->priv; + tuple_t tuple; + u_char buf[256]; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; + config_info_t config; + int i, j; + + /* If the card is already configured, look up the port and irq */ + i = CardServices(GetConfigurationInfo, handle, &config); + if ((i == CS_SUCCESS) && + (config.Attributes & CONF_VALID_CLIENT)) { + ioaddr_t port = 0; + if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { + port = config.BasePort2; + info->slave = 1; + } else if ((info->manfid == MANFID_OSITECH) && + (config.NumPorts1 == 0x40)) { + port = config.BasePort1 + 0x28; + info->slave = 1; + } + if (info->slave) + return setup_serial(info, port, config.AssignedIRQ); + } + link->conf.Vcc = config.Vcc; + + /* First pass: look for a config entry that looks normal. */ + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + i = first_tuple(handle, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if (i != CS_SUCCESS) goto next_entry; + if (cf->vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = + cf->vpp1.param[CISTPL_POWER_VNOM]/10000; + if ((cf->io.nwin > 0) && ((cf->io.win[0].base & 0xf) == 8)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; + i = CardServices(RequestIO, link->handle, &link->io); + if (i == CS_SUCCESS) goto found_port; + } + next_entry: + i = next_tuple(handle, &tuple, &parse); + } + + /* Second pass: try to find an entry that isn't picky about + its base address, then try to grab any standard serial port + address, and finally try to get any free port. */ + i = first_tuple(handle, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && + ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { + link->conf.ConfigIndex = cf->index; + for (j = 0; j < 5; j++) { + link->io.BasePort1 = base[j]; + i = CardServices(RequestIO, link->handle, + &link->io); + if (i == CS_SUCCESS) goto found_port; + } + } + i = next_tuple(handle, &tuple, &parse); + } + +found_port: + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestIO, i); + return -1; + } + + i = CardServices(RequestIRQ, link->handle, &link->irq); + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestIRQ, i); + link->irq.AssignedIRQ = 0; + } + if (info->multi && (info->manfid == MANFID_3COM)) + link->conf.ConfigIndex &= ~(0x08); + i = CardServices(RequestConfiguration, link->handle, &link->conf); + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestConfiguration, i); + return -1; + } + + return setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); +} + +static int multi_config(dev_link_t *link) +{ + client_handle_t handle = link->handle; + serial_info_t *info = link->priv; + tuple_t tuple; + u_char buf[256]; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; + int i, base2 = 0; + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + + /* First, look for a generic full-sized window */ + link->io.NumPorts1 = info->multi * 8; + i = first_tuple(handle, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + /* The quad port cards have bad CIS's, so just look for a + window larger than 8 ports and assume it will be right */ + if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && + (cf->io.win[0].len > 8)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; + i = CardServices(RequestIO, link->handle, &link->io); + base2 = link->io.BasePort1 + 8; + if (i == CS_SUCCESS) break; + } + i = next_tuple(handle, &tuple, &parse); + } + + /* If that didn't work, look for two windows */ + if (i != CS_SUCCESS) { + link->io.NumPorts1 = link->io.NumPorts2 = 8; + info->multi = 2; + i = first_tuple(handle, &tuple, &parse); + while (i != CS_NO_MORE_ITEMS) { + if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.BasePort2 = cf->io.win[1].base; + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; + i = CardServices(RequestIO, link->handle, &link->io); + base2 = link->io.BasePort2; + if (i == CS_SUCCESS) break; + } + i = next_tuple(handle, &tuple, &parse); + } + } + + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestIO, i); + return -1; + } + + i = CardServices(RequestIRQ, link->handle, &link->irq); + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestIRQ, i); + link->irq.AssignedIRQ = 0; + } + /* Socket Dual IO: this enables irq's for second port */ + if (info->multi && (info->manfid == MANFID_SOCKET)) { + link->conf.Present |= PRESENT_EXT_STATUS; + link->conf.ExtStatus = ESR_REQ_ATTN_ENA; + } + i = CardServices(RequestConfiguration, link->handle, &link->conf); + if (i != CS_SUCCESS) { + cs_error(link->handle, RequestConfiguration, i); + return -1; + } + + setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); + for (i = 0; i < info->multi-1; i++) + setup_serial(info, base2+(8*i), link->irq.AssignedIRQ); + + return 0; +} + +/*====================================================================== + + serial_config() is scheduled to run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + serial device available to the system. + +======================================================================*/ + +#define CS_CHECK(fn, args...) \ +while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed + +void serial_config(dev_link_t *link) +{ + client_handle_t handle; + serial_info_t *info; + tuple_t tuple; + u_short buf[128]; + cisparse_t parse; + cistpl_cftable_entry_t *cf = &parse.cftable_entry; + int i, last_ret, last_fn; + + sti(); + handle = link->handle; + info = link->priv; + + DEBUG(0, "serial_config(0x%p)\n", link); + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + /* Get configuration register information */ + tuple.DesiredTuple = CISTPL_CONFIG; + last_ret = first_tuple(handle, &tuple, &parse); + if (last_ret != CS_SUCCESS) { + last_fn = ParseTuple; + goto cs_failed; + } + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Is this a compliant multifunction card? */ + tuple.DesiredTuple = CISTPL_LONGLINK_MFC; + tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; + info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS); + + /* Is this a multiport card? */ + tuple.DesiredTuple = CISTPL_MANFID; + if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) { + info->manfid = le16_to_cpu(buf[0]); + for (i = 0; i < MULTI_COUNT; i++) + if ((info->manfid == multi_id[i].manfid) && + (le16_to_cpu(buf[1]) == multi_id[i].prodid)) + break; + if (i < MULTI_COUNT) + info->multi = multi_id[i].multi; + } + + /* Another check for dual-serial cards: look for either serial or + multifunction cards that ask for appropriate IO port ranges */ + tuple.DesiredTuple = CISTPL_FUNCID; + if ((info->multi == 0) && + ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) || + (parse.funcid.func == CISTPL_FUNCID_MULTI) || + (parse.funcid.func == CISTPL_FUNCID_SERIAL))) { + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + if ((first_tuple(handle, &tuple, &parse) == CS_SUCCESS) && + (((cf->io.nwin == 1) && (cf->io.win[0].len == 16)) || + ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && + (cf->io.win[1].len == 8)))) + info->multi = 2; + } + + if (info->multi > 1) + multi_config(link); + else + simple_config(link); + + if (info->ndev == 0) + goto failed; + + if (info->manfid == MANFID_IBM) { + conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; + CS_CHECK(AccessConfigurationRegister, link->handle, ®); + reg.Action = CS_WRITE; + reg.Value = reg.Value | 1; + CS_CHECK(AccessConfigurationRegister, link->handle, ®); + } + + link->dev = &info->node[0]; + link->state &= ~DEV_CONFIG_PENDING; + return; + +cs_failed: + cs_error(link->handle, last_fn, last_ret); +failed: + serial_release((u_long)link); + +} /* serial_config */ + +/*====================================================================== + + After a card is removed, serial_release() will unregister the net + device, and release the PCMCIA configuration. + +======================================================================*/ + +void serial_release(u_long arg) +{ + dev_link_t *link = (dev_link_t *)arg; + serial_info_t *info = link->priv; + int i; + + sti(); + + DEBUG(0, "serial_release(0x%p)\n", link); + + for (i = 0; i < info->ndev; i++) { + unregister_serial(info->line[i]); + } + link->dev = NULL; + + if (!info->slave) { + CardServices(ReleaseConfiguration, link->handle); + CardServices(ReleaseIO, link->handle, &link->io); + CardServices(ReleaseIRQ, link->handle, &link->irq); + } + + link->state &= ~DEV_CONFIG; + +} /* serial_release */ + +/*====================================================================== + + The card status event handler. Mostly, this schedules other + stuff to run after an event is received. A CARD_REMOVAL event + also sets some flags to discourage the serial drivers from + talking to the ports. + +======================================================================*/ + +static int serial_event(event_t event, int priority, + event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + serial_info_t *info = link->priv; + + DEBUG(1, "serial_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) { + link->release.expires = jiffies + HZ/20; + link->state |= DEV_RELEASE_PENDING; + add_timer(&link->release); + } + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + serial_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if ((link->state & DEV_CONFIG) && !info->slave) + CardServices(ReleaseConfiguration, link->handle); + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (DEV_OK(link) && !info->slave) + CardServices(RequestConfiguration, link->handle, &link->conf); + break; + } + return 0; +} /* serial_event */ + +/*====================================================================*/ + +static int __init init_serial_cs(void) +{ + servinfo_t serv; + DEBUG(0, "%s\n", version); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "serial_cs: Card Services release " + "does not match!\n"); + return -1; + } + register_pccard_driver(&dev_info, &serial_attach, &serial_detach); + return 0; +} + +static void __exit exit_serial_cs(void) +{ + DEBUG(0, "serial_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) + serial_detach(dev_list); +} + +module_init(init_serial_cs); +module_exit(exit_serial_cs); diff -u --recursive --new-file v2.3.26/linux/drivers/char/pms.c linux/drivers/char/pms.c --- v2.3.26/linux/drivers/char/pms.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/char/pms.c Wed Nov 10 13:39:06 1999 @@ -624,7 +624,7 @@ { int y; int dw = 2*dev->width; - char *src = (char *)bus_to_virt(mem_base); + u32 src = mem_base; char tmp[dw+32]; /* using a temp buffer is faster than direct */ int cnt = 0; @@ -639,8 +639,14 @@ for (y = 0; y < dev->height; y++ ) { - *src = 0; /* synchronisiert neue Zeile */ - memcpy(tmp, src, dw+32); /* discard 16 word */ + isa_writeb(0, src); /* synchronisiert neue Zeile */ + + /* + * This is in truth a fifo, be very careful as if you + * forgot this odd things will occur 8) + */ + + isa_memcpy_fromio(tmp, src, dw+32); /* discard 16 word */ cnt -= dev->height; while (cnt <= 0) { diff -u --recursive --new-file v2.3.26/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c --- v2.3.26/linux/drivers/char/ppdev.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/char/ppdev.c Tue Nov 9 09:29:52 1999 @@ -505,14 +505,14 @@ if (minor >= PARPORT_MAX) return -ENXIO; - pp = kmalloc (GFP_KERNEL, sizeof (struct pp_struct)); + pp = kmalloc (sizeof (struct pp_struct), GFP_KERNEL); if (!pp) return -ENOMEM; - memset (pp, 0, sizeof (struct pp_struct)); pp->state.mode = IEEE1284_MODE_COMPAT; pp->state.phase = init_phase (pp->state.mode); pp->flags = 0; + pp->irqresponse = 0; atomic_set (&pp->irqc, 0); init_waitqueue_head (&pp->irq_wait); @@ -539,8 +539,9 @@ } if (pp->pdev) { + const char *name = pp->pdev->name; parport_unregister_device (pp->pdev); - kfree (pp->pdev->name); + kfree (name); pp->pdev = NULL; printk (KERN_DEBUG CHRDEV "%x: unregistered pardevice\n", minor); diff -u --recursive --new-file v2.3.26/linux/drivers/char/saa7121.h linux/drivers/char/saa7121.h --- v2.3.26/linux/drivers/char/saa7121.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/saa7121.h Wed Nov 10 13:58:46 1999 @@ -0,0 +1,132 @@ +/* saa7121.h - saa7121 initializations + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ +#ifndef __SAA7121_H__ +#define __SAA7121_H__ + +#define NTSC_BURST_START 0x19 /* 28 */ +#define NTSC_BURST_END 0x1d /* 29 */ +#define NTSC_CHROMA_PHASE 0x67 /* 5a */ +#define NTSC_GAINU 0x76 /* 5b */ +#define NTSC_GAINV 0xa5 /* 5c */ +#define NTSC_BLACK_LEVEL 0x2a /* 5d */ +#define NTSC_BLANKING_LEVEL 0x2e /* 5e */ +#define NTSC_VBI_BLANKING 0x2e /* 5f */ +#define NTSC_DAC_CONTROL 0x11 /* 61 */ +#define NTSC_BURST_AMP 0x3f /* 62 */ +#define NTSC_SUBC3 0x1f /* 63 */ +#define NTSC_SUBC2 0x7c /* 64 */ +#define NTSC_SUBC1 0xf0 /* 65 */ +#define NTSC_SUBC0 0x21 /* 66 */ +#define NTSC_HTRIG 0x72 /* 6c */ +#define NTSC_VTRIG 0x00 /* 6c */ +#define NTSC_MULTI 0x30 /* 6e */ +#define NTSC_CCTTX 0x11 /* 6f */ +#define NTSC_FIRST_ACTIVE 0x12 /* 7a */ +#define NTSC_LAST_ACTIVE 0x02 /* 7b */ +#define NTSC_MSB_VERTICAL 0x40 /* 7c */ + +#define PAL_BURST_START 0x21 /* 28 */ +#define PAL_BURST_END 0x1d /* 29 */ +#define PAL_CHROMA_PHASE 0x3f /* 5a */ +#define PAL_GAINU 0x7d /* 5b */ +#define PAL_GAINV 0xaf /* 5c */ +#define PAL_BLACK_LEVEL 0x23 /* 5d */ +#define PAL_BLANKING_LEVEL 0x35 /* 5e */ +#define PAL_VBI_BLANKING 0x35 /* 5f */ +#define PAL_DAC_CONTROL 0x02 /* 61 */ +#define PAL_BURST_AMP 0x2f /* 62 */ +#define PAL_SUBC3 0xcb /* 63 */ +#define PAL_SUBC2 0x8a /* 64 */ +#define PAL_SUBC1 0x09 /* 65 */ +#define PAL_SUBC0 0x2a /* 66 */ +#define PAL_HTRIG 0x86 /* 6c */ +#define PAL_VTRIG 0x04 /* 6d */ +#define PAL_MULTI 0x20 /* 6e */ +#define PAL_CCTTX 0x15 /* 6f */ +#define PAL_FIRST_ACTIVE 0x16 /* 7a */ +#define PAL_LAST_ACTIVE 0x36 /* 7b */ +#define PAL_MSB_VERTICAL 0x40 /* 7c */ + +/* Initialization Sequence */ + +static __u8 init7121ntsc[] = { + 0x26, 0x0, 0x27, 0x0, + 0x28, NTSC_BURST_START, 0x29, NTSC_BURST_END, + 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0, + 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0, + 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0, + 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0, + 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0, + 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0, + 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0, + 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0, + 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0, + 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0, + 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0, + 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0, + 0x5a, NTSC_CHROMA_PHASE, 0x5b, NTSC_GAINU, + 0x5c, NTSC_GAINV, 0x5d, NTSC_BLACK_LEVEL, + 0x5e, NTSC_BLANKING_LEVEL, 0x5f, NTSC_VBI_BLANKING, + 0x60, 0x0, 0x61, NTSC_DAC_CONTROL, + 0x62, NTSC_BURST_AMP, 0x63, NTSC_SUBC3, + 0x64, NTSC_SUBC2, 0x65, NTSC_SUBC1, + 0x66, NTSC_SUBC0, 0x67, 0x80, 0x68, 0x80, + 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29, + 0x6c, NTSC_HTRIG, 0x6d, NTSC_VTRIG, + 0x6e, NTSC_MULTI, 0x6f, NTSC_CCTTX, + 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0, + 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0, + 0x78, 0x0, 0x79, 0x0, 0x7a, NTSC_FIRST_ACTIVE, + 0x7b, NTSC_LAST_ACTIVE, 0x7c, NTSC_MSB_VERTICAL, + 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0 +}; +#define INIT7121LEN (sizeof(init7121ntsc)/2) + +static __u8 init7121pal[] = { + 0x26, 0x0, 0x27, 0x0, + 0x28, PAL_BURST_START, 0x29, PAL_BURST_END, + 0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0, + 0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0, + 0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0, + 0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0, + 0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0, + 0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0, + 0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0, + 0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0, + 0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0, + 0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0, + 0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0, + 0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0, + 0x5a, PAL_CHROMA_PHASE, 0x5b, PAL_GAINU, + 0x5c, PAL_GAINV, 0x5d, PAL_BLACK_LEVEL, + 0x5e, PAL_BLANKING_LEVEL, 0x5f, PAL_VBI_BLANKING, + 0x60, 0x0, 0x61, PAL_DAC_CONTROL, + 0x62, PAL_BURST_AMP, 0x63, PAL_SUBC3, + 0x64, PAL_SUBC2, 0x65, PAL_SUBC1, + 0x66, PAL_SUBC0, 0x67, 0x80, 0x68, 0x80, + 0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29, + 0x6c, PAL_HTRIG, 0x6d, PAL_VTRIG, + 0x6e, PAL_MULTI, 0x6f, PAL_CCTTX, + 0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0, + 0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0, + 0x78, 0x0, 0x79, 0x0, 0x7a, PAL_FIRST_ACTIVE, + 0x7b, PAL_LAST_ACTIVE, 0x7c, PAL_MSB_VERTICAL, + 0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0 +}; +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/char/saa7146.h linux/drivers/char/saa7146.h --- v2.3.26/linux/drivers/char/saa7146.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/saa7146.h Wed Nov 10 13:58:46 1999 @@ -0,0 +1,117 @@ +/* + saa7146.h - definitions philips saa7146 based cards + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SAA7146__ +#define __SAA7146__ + +#define SAA7146_VERSION_CODE 0x000101 + +#include +#include + +#include +#include + +#ifndef O_NONCAP +#define O_NONCAP O_TRUNC +#endif + +#define MAX_GBUFFERS 2 +#define FBUF_SIZE 0x190000 + +#ifdef __KERNEL__ + +struct saa7146_window +{ + int x, y; + ushort width, height; + ushort bpp, bpl; + ushort swidth, sheight; + short cropx, cropy; + ushort cropwidth, cropheight; + unsigned long vidadr; + int color_fmt; + ushort depth; +}; + +/* Per-open data for handling multiple opens on one device */ +struct device_open +{ + int isopen; + int noncapturing; + struct saa7146 *dev; +}; +#define MAX_OPENS 3 + +struct saa7146 +{ + struct video_device video_dev; + struct video_picture picture; + struct video_audio audio_dev; + struct video_info vidinfo; + int user; + int cap; + int capuser; + int irqstate; /* irq routine is state driven */ + int writemode; + int playmode; + unsigned int nr; + unsigned long irq; /* IRQ used by SAA7146 card */ + unsigned short id; + struct i2c_bus i2c; + struct pci_dev *dev; + unsigned char revision; + unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */ + unsigned long saa7146_adr; /* bus address of IO mem from PCI BIOS */ + struct saa7146_window win; + unsigned char *saa7146_mem; /* pointer to mapped IO memory */ + struct device_open open_data[MAX_OPENS]; +#define MAX_MARKS 16 + /* for a/v sync */ + int endmark[MAX_MARKS], endmarkhead, endmarktail; + u32 *dmaRPS1, *pageRPS1, *dmaRPS2, *pageRPS2, *dmavid1, *dmavid2, + *dmavid3, *dmaa1in, *dmaa1out, *dmaa2in, *dmaa2out, + *pagedebi, *pagevid1, *pagevid2, *pagevid3, *pagea1in, + *pagea1out, *pagea2in, *pagea2out; + wait_queue_head_t i2cq, debiq, audq, vidq; + u8 *vidbuf, *audbuf, *osdbuf, *dmadebi; + int audhead, vidhead, osdhead, audtail, vidtail, osdtail; + spinlock_t lock; /* the device lock */ +}; +#endif + +#ifdef _ALPHA_SAA7146 +#define saawrite(dat,adr) writel((dat),(char *) (saa->saa7146_adr+(adr))) +#define saaread(adr) readl(saa->saa7146_adr+(adr)) +#else +#define saawrite(dat,adr) writel((dat), (char *) (saa->saa7146_mem+(adr))) +#define saaread(adr) readl(saa->saa7146_mem+(adr)) +#endif + +#define saaand(dat,adr) saawrite((dat) & saaread(adr), adr) +#define saaor(dat,adr) saawrite((dat) | saaread(adr), adr) +#define saaaor(dat,mask,adr) saawrite((dat) | ((mask) & saaread(adr)), adr) + +/* bitmask of attached hardware found */ +#define SAA7146_UNKNOWN 0x00000000 +#define SAA7146_SAA7111 0x00000001 +#define SAA7146_SAA7121 0x00000002 +#define SAA7146_IBMMPEG 0x00000004 + +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/char/saa7146reg.h linux/drivers/char/saa7146reg.h --- v2.3.26/linux/drivers/char/saa7146reg.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/saa7146reg.h Wed Nov 10 13:58:46 1999 @@ -0,0 +1,283 @@ +/* + saa7146.h - definitions philips saa7146 based cards + Copyright (C) 1999 Nathan Laredo (laredo@gnu.org) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SAA7146_REG__ +#define __SAA7146_REG__ +#define SAA7146_BASE_ODD1 0x00 +#define SAA7146_BASE_EVEN1 0x04 +#define SAA7146_PROT_ADDR1 0x08 +#define SAA7146_PITCH1 0x0c +#define SAA7146_PAGE1 0x10 +#define SAA7146_NUM_LINE_BYTE1 0x14 +#define SAA7146_BASE_ODD2 0x18 +#define SAA7146_BASE_EVEN2 0x1c +#define SAA7146_PROT_ADDR2 0x20 +#define SAA7146_PITCH2 0x24 +#define SAA7146_PAGE2 0x28 +#define SAA7146_NUM_LINE_BYTE2 0x2c +#define SAA7146_BASE_ODD3 0x30 +#define SAA7146_BASE_EVEN3 0x34 +#define SAA7146_PROT_ADDR3 0x38 +#define SAA7146_PITCH3 0x3c +#define SAA7146_PAGE3 0x40 +#define SAA7146_NUM_LINE_BYTE3 0x44 +#define SAA7146_PCI_BT_V1 0x48 +#define SAA7146_PCI_BT_V2 0x49 +#define SAA7146_PCI_BT_V3 0x4a +#define SAA7146_PCI_BT_DEBI 0x4b +#define SAA7146_PCI_BT_A 0x4c +#define SAA7146_DD1_INIT 0x50 +#define SAA7146_DD1_STREAM_B 0x54 +#define SAA7146_DD1_STREAM_A 0x56 +#define SAA7146_BRS_CTRL 0x58 +#define SAA7146_HPS_CTRL 0x5c +#define SAA7146_HPS_V_SCALE 0x60 +#define SAA7146_HPS_V_GAIN 0x64 +#define SAA7146_HPS_H_PRESCALE 0x68 +#define SAA7146_HPS_H_SCALE 0x6c +#define SAA7146_BCS_CTRL 0x70 +#define SAA7146_CHROMA_KEY_RANGE 0x74 +#define SAA7146_CLIP_FORMAT_CTRL 0x78 +#define SAA7146_DEBI_CONFIG 0x7c +#define SAA7146_DEBI_COMMAND 0x80 +#define SAA7146_DEBI_PAGE 0x84 +#define SAA7146_DEBI_AD 0x88 +#define SAA7146_I2C_TRANSFER 0x8c +#define SAA7146_I2C_STATUS 0x90 +#define SAA7146_BASE_A1_IN 0x94 +#define SAA7146_PROT_A1_IN 0x98 +#define SAA7146_PAGE_A1_IN 0x9C +#define SAA7146_BASE_A1_OUT 0xa0 +#define SAA7146_PROT_A1_OUT 0xa4 +#define SAA7146_PAGE_A1_OUT 0xa8 +#define SAA7146_BASE_A2_IN 0xac +#define SAA7146_PROT_A2_IN 0xb0 +#define SAA7146_PAGE_A2_IN 0xb4 +#define SAA7146_BASE_A2_OUT 0xb8 +#define SAA7146_PROT_A2_OUT 0xbc +#define SAA7146_PAGE_A2_OUT 0xc0 +#define SAA7146_RPS_PAGE0 0xc4 +#define SAA7146_RPS_PAGE1 0xc8 +#define SAA7146_RPS_THRESH0 0xcc +#define SAA7146_RPS_THRESH1 0xd0 +#define SAA7146_RPS_TOV0 0xd4 +#define SAA7146_RPS_TOV1 0xd8 +#define SAA7146_IER 0xdc +#define SAA7146_GPIO_CTRL 0xe0 +#define SAA7146_EC1SSR 0xe4 +#define SAA7146_EC2SSR 0xe8 +#define SAA7146_ECT1R 0xec +#define SAA7146_ECT2R 0xf0 +#define SAA7146_ACON1 0xf4 +#define SAA7146_ACON2 0xf8 +#define SAA7146_MC1 0xfc +#define SAA7146_MC2 0x100 +#define SAA7146_RPS_ADDR0 0x104 +#define SAA7146_RPS_ADDR1 0x108 +#define SAA7146_ISR 0x10c +#define SAA7146_PSR 0x110 +#define SAA7146_SSR 0x114 +#define SAA7146_EC1R 0x118 +#define SAA7146_EC2R 0x11c +#define SAA7146_VDP1 0x120 +#define SAA7146_VDP2 0x124 +#define SAA7146_VDP3 0x128 +#define SAA7146_ADP1 0x12c +#define SAA7146_ADP2 0x130 +#define SAA7146_ADP3 0x134 +#define SAA7146_ADP4 0x138 +#define SAA7146_DDP 0x13c +#define SAA7146_LEVEL_REP 0x140 +#define SAA7146_FB_BUFFER1 0x144 +#define SAA7146_FB_BUFFER2 0x148 +#define SAA7146_A_TIME_SLOT1 0x180 +#define SAA7146_A_TIME_SLOT2 0x1C0 + +/* bitfield defines */ +#define MASK_31 0x80000000 +#define MASK_30 0x40000000 +#define MASK_29 0x20000000 +#define MASK_28 0x10000000 +#define MASK_27 0x08000000 +#define MASK_26 0x04000000 +#define MASK_25 0x02000000 +#define MASK_24 0x01000000 +#define MASK_23 0x00800000 +#define MASK_22 0x00400000 +#define MASK_21 0x00200000 +#define MASK_20 0x00100000 +#define MASK_19 0x00080000 +#define MASK_18 0x00040000 +#define MASK_17 0x00020000 +#define MASK_16 0x00010000 +#define MASK_15 0x00008000 +#define MASK_14 0x00004000 +#define MASK_13 0x00002000 +#define MASK_12 0x00001000 +#define MASK_11 0x00000800 +#define MASK_10 0x00000400 +#define MASK_09 0x00000200 +#define MASK_08 0x00000100 +#define MASK_07 0x00000080 +#define MASK_06 0x00000040 +#define MASK_05 0x00000020 +#define MASK_04 0x00000010 +#define MASK_03 0x00000008 +#define MASK_02 0x00000004 +#define MASK_01 0x00000002 +#define MASK_00 0x00000001 +#define MASK_B0 0x000000ff +#define MASK_B1 0x0000ff00 +#define MASK_B2 0x00ff0000 +#define MASK_B3 0xff000000 +#define MASK_W0 0x0000ffff +#define MASK_W1 0xffff0000 +#define MASK_PA 0xfffffffc +#define MASK_PR 0xfffffffe +#define MASK_ER 0xffffffff +#define MASK_NONE 0x00000000 + +#define SAA7146_PAGE_MAP_EN MASK_11 +/* main control register 1 */ +#define SAA7146_MC1_MRST_N MASK_15 +#define SAA7146_MC1_ERPS1 MASK_13 +#define SAA7146_MC1_ERPS0 MASK_12 +#define SAA7146_MC1_EDP MASK_11 +#define SAA7146_MC1_EVP MASK_10 +#define SAA7146_MC1_EAP MASK_09 +#define SAA7146_MC1_EI2C MASK_08 +#define SAA7146_MC1_TR_E_DEBI MASK_07 +#define SAA7146_MC1_TR_E_1 MASK_06 +#define SAA7146_MC1_TR_E_2 MASK_05 +#define SAA7146_MC1_TR_E_3 MASK_04 +#define SAA7146_MC1_TR_E_A2_OUT MASK_03 +#define SAA7146_MC1_TR_E_A2_IN MASK_02 +#define SAA7146_MC1_TR_E_A1_OUT MASK_01 +#define SAA7146_MC1_TR_E_A1_IN MASK_00 +/* main control register 2 */ +#define SAA7146_MC2_RPS_SIG4 MASK_15 +#define SAA7146_MC2_RPS_SIG3 MASK_14 +#define SAA7146_MC2_RPS_SIG2 MASK_13 +#define SAA7146_MC2_RPS_SIG1 MASK_12 +#define SAA7146_MC2_RPS_SIG0 MASK_11 +#define SAA7146_MC2_UPLD_D1_B MASK_10 +#define SAA7146_MC2_UPLD_D1_A MASK_09 +#define SAA7146_MC2_UPLD_BRS MASK_08 +#define SAA7146_MC2_UPLD_HPS_H MASK_06 +#define SAA7146_MC2_UPLD_HPS_V MASK_05 +#define SAA7146_MC2_UPLD_DMA3 MASK_04 +#define SAA7146_MC2_UPLD_DMA2 MASK_03 +#define SAA7146_MC2_UPLD_DMA1 MASK_02 +#define SAA7146_MC2_UPLD_DEBI MASK_01 +#define SAA7146_MC2_UPLD_I2C MASK_00 +/* Primary Status Register and Interrupt Enable/Status Registers */ +#define SAA7146_PSR_PPEF MASK_31 +#define SAA7146_PSR_PABO MASK_30 +#define SAA7146_PSR_PPED MASK_29 +#define SAA7146_PSR_RPS_I1 MASK_28 +#define SAA7146_PSR_RPS_I0 MASK_27 +#define SAA7146_PSR_RPS_LATE1 MASK_26 +#define SAA7146_PSR_RPS_LATE0 MASK_25 +#define SAA7146_PSR_RPS_E1 MASK_24 +#define SAA7146_PSR_RPS_E0 MASK_23 +#define SAA7146_PSR_RPS_TO1 MASK_22 +#define SAA7146_PSR_RPS_TO0 MASK_21 +#define SAA7146_PSR_UPLD MASK_20 +#define SAA7146_PSR_DEBI_S MASK_19 +#define SAA7146_PSR_DEBI_E MASK_18 +#define SAA7146_PSR_I2C_S MASK_17 +#define SAA7146_PSR_I2C_E MASK_16 +#define SAA7146_PSR_A2_IN MASK_15 +#define SAA7146_PSR_A2_OUT MASK_14 +#define SAA7146_PSR_A1_IN MASK_13 +#define SAA7146_PSR_A1_OUT MASK_12 +#define SAA7146_PSR_AFOU MASK_11 +#define SAA7146_PSR_V_PE MASK_10 +#define SAA7146_PSR_VFOU MASK_09 +#define SAA7146_PSR_FIDA MASK_08 +#define SAA7146_PSR_FIDB MASK_07 +#define SAA7146_PSR_PIN3 MASK_06 +#define SAA7146_PSR_PIN2 MASK_05 +#define SAA7146_PSR_PIN1 MASK_04 +#define SAA7146_PSR_PIN0 MASK_03 +#define SAA7146_PSR_ECS MASK_02 +#define SAA7146_PSR_EC3S MASK_01 +#define SAA7146_PSR_EC0S MASK_00 +/* Secondary Status Register */ +#define SAA7146_SSR_PRQ MASK_31 +#define SAA7146_SSR_PMA MASK_30 +#define SAA7146_SSR_RPS_RE1 MASK_29 +#define SAA7146_SSR_RPS_PE1 MASK_28 +#define SAA7146_SSR_RPS_A1 MASK_27 +#define SAA7146_SSR_RPS_RE0 MASK_26 +#define SAA7146_SSR_RPS_PE0 MASK_25 +#define SAA7146_SSR_RPS_A0 MASK_24 +#define SAA7146_SSR_DEBI_TO MASK_23 +#define SAA7146_SSR_DEBI_EF MASK_22 +#define SAA7146_SSR_I2C_EA MASK_21 +#define SAA7146_SSR_I2C_EW MASK_20 +#define SAA7146_SSR_I2C_ER MASK_19 +#define SAA7146_SSR_I2C_EL MASK_18 +#define SAA7146_SSR_I2C_EF MASK_17 +#define SAA7146_SSR_V3P MASK_16 +#define SAA7146_SSR_V2P MASK_15 +#define SAA7146_SSR_V1P MASK_14 +#define SAA7146_SSR_VF3 MASK_13 +#define SAA7146_SSR_VF2 MASK_12 +#define SAA7146_SSR_VF1 MASK_11 +#define SAA7146_SSR_AF2_IN MASK_10 +#define SAA7146_SSR_AF2_OUT MASK_09 +#define SAA7146_SSR_AF1_IN MASK_08 +#define SAA7146_SSR_AF1_OUT MASK_07 +#define SAA7146_SSR_VGT MASK_05 +#define SAA7146_SSR_LNQG MASK_04 +#define SAA7146_SSR_EC5S MASK_03 +#define SAA7146_SSR_EC4S MASK_02 +#define SAA7146_SSR_EC2S MASK_01 +#define SAA7146_SSR_EC1S MASK_00 +/* I2C status register */ +#define SAA7146_I2C_ABORT MASK_07 +#define SAA7146_I2C_SPERR MASK_06 +#define SAA7146_I2C_APERR MASK_05 +#define SAA7146_I2C_DTERR MASK_04 +#define SAA7146_I2C_DRERR MASK_03 +#define SAA7146_I2C_AL MASK_02 +#define SAA7146_I2C_ERR MASK_01 +#define SAA7146_I2C_BUSY MASK_00 +/* output formats */ +#define SAA7146_YUV422 0 +#define SAA7146_RGB16 0 +#define SAA7146_YUV444 1 +#define SAA7146_RGB24 1 +#define SAA7146_ARGB32 2 +#define SAA7146_YUV411 3 +#define SAA7146_ARGB15 3 +#define SAA7146_YUV2 4 +#define SAA7146_RGAB15 4 +#define SAA7146_Y8 6 +#define SAA7146_YUV8 7 +#define SAA7146_RGB8 7 +#define SAA7146_YUV444p 8 +#define SAA7146_YUV422p 9 +#define SAA7146_YUV420p 10 +#define SAA7146_YUV1620 11 +#define SAA7146_Y1 13 +#define SAA7146_Y2 14 +#define SAA7146_YUV1 15 +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/char/serial.c linux/drivers/char/serial.c --- v2.3.26/linux/drivers/char/serial.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/char/serial.c Mon Nov 8 15:04:10 1999 @@ -3457,11 +3457,13 @@ } if (state->type == PORT_16550A) { /* Check for Oxford Semiconductor 16C950 */ + unsigned char scratch4; + scratch = serial_icr_read(info, UART_ID1); - scratch2 = serial_icr_read(info, UART_ID2); + scratch4 = serial_icr_read(info, UART_ID2); scratch3 = serial_icr_read(info, UART_ID3); - if (scratch == 0x16 && scratch2 == 0xC9 && + if (scratch == 0x16 && scratch4 == 0xC9 && (scratch3 == 0x50 || scratch3 == 0x52 || scratch3 == 0x54)) { state->type = PORT_16C950; diff -u --recursive --new-file v2.3.26/linux/drivers/char/stradis.c linux/drivers/char/stradis.c --- v2.3.26/linux/drivers/char/stradis.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/stradis.c Thu Nov 11 10:07:21 1999 @@ -0,0 +1,2286 @@ +/* + * stradis.c - stradis 4:2:2 mpeg decoder driver + * + * Stradis 4:2:2 MPEG-2 Decoder Driver + * Copyright (C) 1999 Nathan Laredo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "saa7146.h" +#include "saa7146reg.h" +#include "ibmmpeg2.h" +#include "saa7121.h" +#include "cs8420.h" + +#define DEBUG(x) /* debug driver */ +#undef IDEBUG(x) /* debug irq handler */ +#undef MDEBUG(x) /* debug memory management */ + +#define SAA7146_MAX 6 + +static struct saa7146 saa7146s[SAA7146_MAX]; + +static int saa_num = 0; /* number of SAA7146s in use */ + +#define nDebNormal 0x00480000 +#define nDebNoInc 0x00480000 +#define nDebVideo 0xd0480000 +#define nDebAudio 0xd0400000 +#define nDebDMA 0x02c80000 + +#define oDebNormal 0x13c80000 +#define oDebNoInc 0x13c80000 +#define oDebVideo 0xd1080000 +#define oDebAudio 0xd1080000 +#define oDebDMA 0x03080000 + +#define NewCard (saa->boardcfg[3]) +#define ChipControl (saa->boardcfg[1]) +#define NTSCFirstActive (saa->boardcfg[4]) +#define PALFirstActive (saa->boardcfg[5]) +#define NTSCLastActive (saa->boardcfg[54]) +#define PALLastActive (saa->boardcfg[55]) +#define Have2MB (saa->boardcfg[18] & 0x40) +#define HaveCS8420 (saa->boardcfg[18] & 0x04) +#define IBMMPEGCD20 (saa->boardcfg[18] & 0x20) +#define HaveCS3310 (saa->boardcfg[18] & 0x01) +#define CS3310MaxLvl ((saa->boardcfg[30] << 8) | saa->boardcfg[31]) +#define HaveCS4341 (saa->boardcfg[40] == 2) +#define SDIType (saa->boardcfg[27]) +#define CurrentMode (saa->boardcfg[2]) + +#define debNormal (NewCard ? nDebNormal : oDebNormal) +#define debNoInc (NewCard ? nDebNoInc : oDebNoInc) +#define debVideo (NewCard ? nDebVideo : oDebVideo) +#define debAudio (NewCard ? nDebAudio : oDebAudio) +#define debDMA (NewCard ? nDebDMA : oDebDMA) + +#ifdef DEBUG +int stradis_driver(void) /* for the benefit of ksymoops */ +{ + return 1; +} +#endif + +#ifdef USE_RESCUE_EEPROM_SDM275 +static unsigned char rescue_eeprom[64] = { +0x00,0x01,0x04,0x13,0x26,0x0f,0x10,0x00,0x00,0x00,0x43,0x63,0x22,0x01,0x29,0x15,0x73,0x00,0x1f, 'd', 'e', 'c', 'x', 'l', 'd', 'v', 'a',0x02,0x00,0x01,0x00,0xcc,0xa4,0x63,0x09,0xe2,0x10,0x00,0x0a,0x00,0x02,0x02, 'd', 'e', 'c', 'x', 'l', 'a',0x00,0x00,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +#endif + +/* ----------------------------------------------------------------------- */ +/* Hardware I2C functions */ +static void I2CWipe(struct saa7146 *saa) +{ + int i; + /* set i2c to ~=100kHz, abort transfer, clear busy */ + saawrite(0x600 | SAA7146_I2C_ABORT, SAA7146_I2C_STATUS); + saawrite((SAA7146_MC2_UPLD_I2C << 16) | + SAA7146_MC2_UPLD_I2C, SAA7146_MC2); + /* wait for i2c registers to be programmed */ + for (i = 0; i < 1000 && + !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++) + schedule(); + saawrite(0x600, SAA7146_I2C_STATUS); + saawrite((SAA7146_MC2_UPLD_I2C << 16) | + SAA7146_MC2_UPLD_I2C, SAA7146_MC2); + /* wait for i2c registers to be programmed */ + for (i = 0; i < 1000 && + !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++) + schedule(); + saawrite(0x600, SAA7146_I2C_STATUS); + saawrite((SAA7146_MC2_UPLD_I2C << 16) | + SAA7146_MC2_UPLD_I2C, SAA7146_MC2); + /* wait for i2c registers to be programmed */ + for (i = 0; i < 1000 && + !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++) + schedule(); +} +/* read I2C */ +static int I2CRead(struct i2c_bus *bus, unsigned char addr, + unsigned char subaddr, int dosub) +{ + struct saa7146 *saa = (struct saa7146 *) bus->data; + int i; + + + if (saaread(SAA7146_I2C_STATUS) & 0x3c) + I2CWipe(saa); + for (i = 0; i < 1000 && + (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++) + schedule(); + if (i == 1000) + I2CWipe(saa); + if (dosub) + saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 8) | + ((subaddr & 0xff) << 16) | 0xed, SAA7146_I2C_TRANSFER); + else + saawrite(((addr & 0xfe) << 24) | (((addr | 1) & 0xff) << 16) | + 0xf1, SAA7146_I2C_TRANSFER); + saawrite((SAA7146_MC2_UPLD_I2C << 16) | + SAA7146_MC2_UPLD_I2C, SAA7146_MC2); + /* wait for i2c registers to be programmed */ + for (i = 0; i < 1000 && + !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++) + schedule(); + /* wait for valid data */ + for (i = 0; i < 1000 && + (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++) + schedule(); + if (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_ERR) + return -1; + if (i == 1000) + printk("i2c setup read timeout\n"); + saawrite(0x41, SAA7146_I2C_TRANSFER); + saawrite((SAA7146_MC2_UPLD_I2C << 16) | + SAA7146_MC2_UPLD_I2C, SAA7146_MC2); + /* wait for i2c registers to be programmed */ + for (i = 0; i < 1000 && + !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_I2C); i++) + schedule(); + /* wait for valid data */ + for (i = 0; i < 1000 && + (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_BUSY); i++) + schedule(); + if (saaread(SAA7146_I2C_TRANSFER) & SAA7146_I2C_ERR) + return -1; + if (i == 1000) + printk("i2c read timeout\n"); + return ((saaread(SAA7146_I2C_TRANSFER) >> 24) & 0xff); +} +static int I2CReadOld(struct i2c_bus *bus, unsigned char addr) +{ + return I2CRead(bus, addr, 0, 0); +} + +/* set both to write both bytes, reset it to write only b1 */ + +static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1, + unsigned char b2, int both) +{ + struct saa7146 *saa = (struct saa7146 *) bus->data; + int i; + u32 data; + + if (saaread(SAA7146_I2C_STATUS) & 0x3c) + I2CWipe(saa); + for (i = 0; i < 1000 && + (saaread(SAA7146_I2C_STATUS) & SAA7146_I2C_BUSY); i++) + schedule(); + if (i == 1000) + I2CWipe(saa); + data = ((addr & 0xfe) << 24) | ((b1 & 0xff) << 16); + if (both) + data |= ((b2 & 0xff) << 8) | 0xe5; + else + data |= 0xd1; + saawrite(data, SAA7146_I2C_TRANSFER); + saawrite((SAA7146_MC2_UPLD_I2C << 16) | SAA7146_MC2_UPLD_I2C, + SAA7146_MC2); + return 0; +} + +static void attach_inform(struct i2c_bus *bus, int id) +{ + struct saa7146 *saa = (struct saa7146 *) bus->data; + int i; + + DEBUG(printk(KERN_DEBUG "stradis%d: i2c: device found=%02x\n", saa->nr, id)); + if (id == 0xa0) { /* we have rev2 or later board, fill in info */ + for (i = 0; i < 64; i++) + saa->boardcfg[i] = I2CRead(bus, 0xa0, i, 1); +#ifdef USE_RESCUE_EEPROM_SDM275 + if (saa->boardcfg[0] != 0) { + printk("stradis%d: WARNING: EEPROM STORED VALUES HAVE BEEN IGNORED\n", saa->nr); + for (i = 0; i < 64; i++) + saa->boardcfg[i] = rescue_eeprom[i]; + } +#endif + printk("stradis%d: config =", saa->nr); + for (i = 0; i < 51; i++) { + printk(" %02x",saa->boardcfg[i]); + } + printk("\n"); + } +} + +static void detach_inform(struct i2c_bus *bus, int id) +{ + struct saa7146 *saa = (struct saa7146 *) bus->data; + int i; + i = saa->nr; +} + +static void I2CBusScan(struct i2c_bus *bus) +{ + int i; + for (i = 0; i < 0xff; i += 2) + if ((I2CRead(bus, i, 0, 0)) >= 0) + attach_inform(bus, i); +} + +static struct i2c_bus saa7146_i2c_bus_template = +{ + "saa7146", + I2C_BUSID_BT848, + NULL, + SPIN_LOCK_UNLOCKED, + attach_inform, + detach_inform, + NULL, + NULL, + I2CReadOld, + I2CWrite, +}; + +static int debiwait_maxwait = 0; + +static int wait_for_debi_done(struct saa7146 *saa) +{ + int i; + + /* wait for registers to be programmed */ + for (i = 0; i < 100000 && + !(saaread(SAA7146_MC2) & SAA7146_MC2_UPLD_DEBI); i++) + saaread(SAA7146_MC2); + /* wait for transfer to complete */ + for (i = 0; i < 500000 && + (saaread(SAA7146_PSR) & SAA7146_PSR_DEBI_S); i++) + saaread(SAA7146_MC2); + if (i > debiwait_maxwait) + printk("wait-for-debi-done maxwait: %d\n", + debiwait_maxwait = i); + + if (i == 500000) + return -1; + return 0; +} + +static int debiwrite(struct saa7146 *saa, u32 config, int addr, + u32 val, int count) +{ + u32 cmd; + if (count <= 0 || count > 32764) + return -1; + if (wait_for_debi_done(saa) < 0) + return -1; + saawrite(config, SAA7146_DEBI_CONFIG); + if (count <= 4) /* immediate transfer */ + saawrite(val, SAA7146_DEBI_AD); + else /* block transfer */ + saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD); + saawrite((cmd = (count << 17) | (addr & 0xffff)), SAA7146_DEBI_COMMAND); + saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI, + SAA7146_MC2); + return 0; +} + +static u32 debiread(struct saa7146 *saa, u32 config, int addr, int count) +{ + u32 result = 0; + + if (count > 32764 || count <= 0) + return 0; + if (wait_for_debi_done(saa) < 0) + return 0; + saawrite(virt_to_bus(saa->dmadebi), SAA7146_DEBI_AD); + saawrite((count << 17) | 0x10000 | (addr & 0xffff), + SAA7146_DEBI_COMMAND); + saawrite(config, SAA7146_DEBI_CONFIG); + saawrite((SAA7146_MC2_UPLD_DEBI << 16) | SAA7146_MC2_UPLD_DEBI, + SAA7146_MC2); + if (count > 4) /* not an immediate transfer */ + return count; + wait_for_debi_done(saa); + result = saaread(SAA7146_DEBI_AD); + if (count == 1) + result &= 0xff; + if (count == 2) + result &= 0xffff; + if (count == 3) + result &= 0xffffff; + return result; +} + +/* MUST be a multiple of 8 bytes and 8-byte aligned and < 32768 bytes */ +/* data copied into saa->dmadebi buffer, caller must re-enable interrupts */ +static void ibm_block_dram_read(struct saa7146 *saa, int address, int bytes) +{ + int i, j; + u32 *buf; + buf = (u32 *) saa->dmadebi; + if (bytes > 0x7000) + bytes = 0x7000; + saawrite(0, SAA7146_IER); /* disable interrupts */ + for (i=0; i < 10000 && + (debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2) + & 0x8000); i++) + saaread(SAA7146_MC2); + if (i == 10000) + printk(KERN_ERR "stradis%d: dram_busy never cleared\n", + saa->nr); + debiwrite(saa, debNormal, IBM_MP2_SRC_ADDR, (address<<16) | + (address>>16), 4); + debiwrite(saa, debNormal, IBM_MP2_BLOCK_SIZE, bytes, 2); + debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 0x8a10, 2); + for (j = 0; j < bytes/4; j++) { + for (i = 0; i < 10000 && + (!(debiread(saa, debNormal, IBM_MP2_DRAM_CMD_STAT, 2) + & 0x4000)); i++) + saaread(SAA7146_MC2); + if (i == 10000) + printk(KERN_ERR "stradis%d: dram_ready never set\n", + saa->nr); + buf[j] = debiread(saa, debNormal, IBM_MP2_DRAM_DATA, 4); + } +} + +static void do_irq_send_data(struct saa7146 *saa) +{ + int split, audbytes, vidbytes; + + saawrite(SAA7146_PSR_PIN1, SAA7146_IER); + /* if special feature mode in effect, disable audio sending */ + if (saa->playmode != VID_PLAY_NORMAL) + saa->audtail = saa->audhead = 0; + if (saa->audhead <= saa->audtail) + audbytes = saa->audtail - saa->audhead; + else + audbytes = 65536 - (saa->audhead - saa->audtail); + if (saa->vidhead <= saa->vidtail) + vidbytes = saa->vidtail - saa->vidhead; + else + vidbytes = 524288 - (saa->vidhead - saa->vidtail); + if (audbytes == 0 && vidbytes == 0 && saa->osdtail == saa->osdhead) { + saawrite(0, SAA7146_IER); + return; + } + /* if at least 1 block audio waiting and audio fifo isn't full */ + if (audbytes >= 2048 && (debiread(saa, debNormal, + IBM_MP2_AUD_FIFO, 2) & 0xff) < 60) { + if (saa->audhead > saa->audtail) + split = 65536 - saa->audhead; + else + split = 0; + audbytes = 2048; + if (split > 0 && split < 2048) { + memcpy(saa->dmadebi, saa->audbuf + saa->audhead, + split); + saa->audhead = 0; + audbytes -= split; + } else + split = 0; + memcpy(saa->dmadebi + split, saa->audbuf + saa->audhead, + audbytes); + saa->audhead += audbytes; + saa->audhead &= 0xffff; + debiwrite(saa, debAudio, (NewCard? IBM_MP2_AUD_FIFO : + IBM_MP2_AUD_FIFOW), 0, 2048); + wake_up_interruptible(&saa->audq); + /* if at least 1 block video waiting and video fifo isn't full */ + } else if (vidbytes >= 30720 && (debiread(saa, debNormal, + IBM_MP2_FIFO, 2)) < 16384) { + if (saa->vidhead > saa->vidtail) + split = 524288 - saa->vidhead; + else + split = 0; + vidbytes = 30720; + if (split > 0 && split < 30720) { + memcpy(saa->dmadebi, saa->vidbuf + saa->vidhead, + split); + saa->vidhead = 0; + vidbytes -= split; + } else + split = 0; + memcpy(saa->dmadebi + split, saa->vidbuf + saa->vidhead, + vidbytes); + saa->vidhead += vidbytes; + saa->vidhead &= 0x7ffff; + debiwrite(saa, debVideo, (NewCard ? IBM_MP2_FIFO : + IBM_MP2_FIFOW), 0, 30720); + wake_up_interruptible(&saa->vidq); + } + saawrite(SAA7146_PSR_DEBI_S | SAA7146_PSR_PIN1, SAA7146_IER); +} + +static void send_osd_data(struct saa7146 *saa) +{ + int size = saa->osdtail - saa->osdhead; + if (size > 30720) + size = 30720; + /* ensure some multiple of 8 bytes is transferred */ + size = 8 * ((size + 8)>>3); + if (size) { + debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, + (saa->osdhead>>3), 2); + memcpy(saa->dmadebi, &saa->osdbuf[saa->osdhead], size); + saa->osdhead += size; + /* block transfer of next 8 bytes to ~32k bytes */ + debiwrite(saa, debNormal, IBM_MP2_OSD_DATA, 0, size); + } + if (saa->osdhead >= saa->osdtail) { + saa->osdhead = saa->osdtail = 0; + debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2); + } +} + +static void saa7146_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct saa7146 *saa = (struct saa7146 *) dev_id; + u32 stat, astat; + int count; + + count = 0; + while (1) { + /* get/clear interrupt status bits */ + stat = saaread(SAA7146_ISR); + astat = stat & saaread(SAA7146_IER); + if (!astat) + return; + saawrite(astat, SAA7146_ISR); + if (astat & SAA7146_PSR_DEBI_S) { + do_irq_send_data(saa); + } + if (astat & SAA7146_PSR_PIN1) { + int istat; + /* the following read will trigger DEBI_S */ + istat = debiread(saa, debNormal, IBM_MP2_HOST_INT, 2); + if (istat & 1) { + saawrite(0, SAA7146_IER); + send_osd_data(saa); + saawrite(SAA7146_PSR_DEBI_S | + SAA7146_PSR_PIN1, SAA7146_IER); + } + if (istat & 0x20) { /* Video Start */ + saa->vidinfo.frame_count++; + } + if (istat & 0x400) { /* Picture Start */ + /* update temporal reference */ + } + if (istat & 0x200) { /* Picture Resolution Change */ + /* read new resolution */ + } + if (istat & 0x100) { /* New User Data found */ + /* read new user data */ + } + if (istat & 0x1000) { /* new GOP/SMPTE */ + /* read new SMPTE */ + } + if (istat & 0x8000) { /* Sequence Start Code */ + /* reset frame counter, load sizes */ + saa->vidinfo.frame_count = 0; + saa->vidinfo.h_size = 704; + saa->vidinfo.v_size = 480; +#if 0 + if (saa->endmarkhead != saa->endmarktail) { + saa->audhead = + saa->endmark[saa->endmarkhead]; + saa->endmarkhead++; + if (saa->endmarkhead >= MAX_MARKS) + saa->endmarkhead = 0; + } +#endif + } + if (istat & 0x4000) { /* Sequence Error Code */ + if (saa->endmarkhead != saa->endmarktail) { + saa->audhead = + saa->endmark[saa->endmarkhead]; + saa->endmarkhead++; + if (saa->endmarkhead >= MAX_MARKS) + saa->endmarkhead = 0; + } + } + } +#ifdef IDEBUG + if (astat & SAA7146_PSR_PPEF) { + IDEBUG(printk("stradis%d irq: PPEF\n", saa->nr)); + } + if (astat & SAA7146_PSR_PABO) { + IDEBUG(printk("stradis%d irq: PABO\n", saa->nr)); + } + if (astat & SAA7146_PSR_PPED) { + IDEBUG(printk("stradis%d irq: PPED\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_I1) { + IDEBUG(printk("stradis%d irq: RPS_I1\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_I0) { + IDEBUG(printk("stradis%d irq: RPS_I0\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_LATE1) { + IDEBUG(printk("stradis%d irq: RPS_LATE1\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_LATE0) { + IDEBUG(printk("stradis%d irq: RPS_LATE0\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_E1) { + IDEBUG(printk("stradis%d irq: RPS_E1\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_E0) { + IDEBUG(printk("stradis%d irq: RPS_E0\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_TO1) { + IDEBUG(printk("stradis%d irq: RPS_TO1\n", saa->nr)); + } + if (astat & SAA7146_PSR_RPS_TO0) { + IDEBUG(printk("stradis%d irq: RPS_TO0\n", saa->nr)); + } + if (astat & SAA7146_PSR_UPLD) { + IDEBUG(printk("stradis%d irq: UPLD\n", saa->nr)); + } + if (astat & SAA7146_PSR_DEBI_E) { + IDEBUG(printk("stradis%d irq: DEBI_E\n", saa->nr)); + } + if (astat & SAA7146_PSR_I2C_S) { + IDEBUG(printk("stradis%d irq: I2C_S\n", saa->nr)); + } + if (astat & SAA7146_PSR_I2C_E) { + IDEBUG(printk("stradis%d irq: I2C_E\n", saa->nr)); + } + if (astat & SAA7146_PSR_A2_IN) { + IDEBUG(printk("stradis%d irq: A2_IN\n", saa->nr)); + } + if (astat & SAA7146_PSR_A2_OUT) { + IDEBUG(printk("stradis%d irq: A2_OUT\n", saa->nr)); + } + if (astat & SAA7146_PSR_A1_IN) { + IDEBUG(printk("stradis%d irq: A1_IN\n", saa->nr)); + } + if (astat & SAA7146_PSR_A1_OUT) { + IDEBUG(printk("stradis%d irq: A1_OUT\n", saa->nr)); + } + if (astat & SAA7146_PSR_AFOU) { + IDEBUG(printk("stradis%d irq: AFOU\n", saa->nr)); + } + if (astat & SAA7146_PSR_V_PE) { + IDEBUG(printk("stradis%d irq: V_PE\n", saa->nr)); + } + if (astat & SAA7146_PSR_VFOU) { + IDEBUG(printk("stradis%d irq: VFOU\n", saa->nr)); + } + if (astat & SAA7146_PSR_FIDA) { + IDEBUG(printk("stradis%d irq: FIDA\n", saa->nr)); + } + if (astat & SAA7146_PSR_FIDB) { + IDEBUG(printk("stradis%d irq: FIDB\n", saa->nr)); + } + if (astat & SAA7146_PSR_PIN3) { + IDEBUG(printk("stradis%d irq: PIN3\n", saa->nr)); + } + if (astat & SAA7146_PSR_PIN2) { + IDEBUG(printk("stradis%d irq: PIN2\n", saa->nr)); + } + if (astat & SAA7146_PSR_PIN0) { + IDEBUG(printk("stradis%d irq: PIN0\n", saa->nr)); + } + if (astat & SAA7146_PSR_ECS) { + IDEBUG(printk("stradis%d irq: ECS\n", saa->nr)); + } + if (astat & SAA7146_PSR_EC3S) { + IDEBUG(printk("stradis%d irq: EC3S\n", saa->nr)); + } + if (astat & SAA7146_PSR_EC0S) { + IDEBUG(printk("stradis%d irq: EC0S\n", saa->nr)); + } +#endif + count++; + if (count > 15) + printk(KERN_WARNING "stradis%d: irq loop %d\n", + saa->nr, count); + if (count > 20) { + saawrite(0, SAA7146_IER); + printk(KERN_ERR + "stradis%d: IRQ loop cleared\n", saa->nr); + } + } +} + +static int ibm_send_command(struct saa7146 *saa, + int command, int data, int chain) +{ + int i; + + if (chain) + debiwrite(saa, debNormal, IBM_MP2_COMMAND, (command << 1) | 1, 2); + else + debiwrite(saa, debNormal, IBM_MP2_COMMAND, command << 1, 2); + debiwrite(saa, debNormal, IBM_MP2_CMD_DATA, data, 2); + debiwrite(saa, debNormal, IBM_MP2_CMD_STAT, 1, 2); + for (i = 0; i < 100 && + (debiread(saa, debNormal, IBM_MP2_CMD_STAT, 2) & 1); i++) + schedule(); + if (i == 100) + return -1; + return 0; +} + +static void cs4341_setlevel(struct saa7146 *saa, int left, int right) +{ + I2CWrite(&(saa->i2c), 0x22, 0x03, + left > 94 ? 94 : left, 2); + I2CWrite(&(saa->i2c), 0x22, 0x04, + right > 94 ? 94 : right, 2); +} + +static void initialize_cs4341(struct saa7146 *saa) +{ + int i; + for (i = 0; i < 200; i++) { + /* auto mute off, power on, no de-emphasis */ + /* I2S data up to 24-bit 64xFs internal SCLK */ + I2CWrite(&(saa->i2c), 0x22, 0x01, 0x11, 2); + /* ATAPI mixer setings */ + I2CWrite(&(saa->i2c), 0x22, 0x02, 0x49, 2); + /* attenuation left 3db */ + I2CWrite(&(saa->i2c), 0x22, 0x03, 0x00, 2); + /* attenuation right 3db */ + I2CWrite(&(saa->i2c), 0x22, 0x04, 0x00, 2); + I2CWrite(&(saa->i2c), 0x22, 0x01, 0x10, 2); + if (I2CRead(&(saa->i2c), 0x22, 0x02, 1) == 0x49) + break; + schedule(); + } + printk("stradis%d: CS4341 initialized (%d)\n", saa->nr, i); + return; +} + +static void initialize_cs8420(struct saa7146 *saa, int pro) +{ + int i; + u8 *sequence; + if (pro) + sequence = mode8420pro; + else + sequence = mode8420con; + for (i = 0; i < INIT8420LEN; i++) + I2CWrite(&(saa->i2c), 0x20, init8420[i * 2], + init8420[i * 2 + 1], 2); + for (i = 0; i < MODE8420LEN; i++) + I2CWrite(&(saa->i2c), 0x20, sequence[i * 2], + sequence[i * 2 + 1], 2); + printk("stradis%d: CS8420 initialized\n", saa->nr); +} + +static void initialize_saa7121(struct saa7146 *saa, int dopal) +{ + int i, mod; + u8 *sequence; + if (dopal) + sequence = init7121pal; + else + sequence = init7121ntsc; + mod = saaread(SAA7146_PSR) & 0x08; + /* initialize PAL/NTSC video encoder */ + for (i = 0; i < INIT7121LEN; i++) { + if (NewCard) { /* handle new card encoder differences */ + if (sequence[i*2] == 0x3a) + I2CWrite(&(saa->i2c), 0x88, 0x3a, 0x13, 2); + else if (sequence[i*2] == 0x6b) + I2CWrite(&(saa->i2c), 0x88, 0x6b, 0x20, 2); + else if (sequence[i*2] == 0x6c) + I2CWrite(&(saa->i2c), 0x88, 0x6c, + dopal ? 0x09 : 0xf5, 2); + else if (sequence[i*2] == 0x6d) + I2CWrite(&(saa->i2c), 0x88, 0x6d, + dopal ? 0x20 : 0x00, 2); + else if (sequence[i*2] == 0x7a) + I2CWrite(&(saa->i2c), 0x88, 0x7a, + dopal ? (PALFirstActive - 1) : + (NTSCFirstActive - 4), 2); + else if (sequence[i*2] == 0x7b) + I2CWrite(&(saa->i2c), 0x88, 0x7b, + dopal ? PALLastActive : + NTSCLastActive, 2); + else I2CWrite(&(saa->i2c), 0x88, sequence[i * 2], + sequence[i * 2 + 1], 2); + } else { + if (sequence[i*2] == 0x6b && mod) + I2CWrite(&(saa->i2c), 0x88, 0x6b, + (sequence[i * 2 + 1] ^ 0x09), 2); + else if (sequence[i*2] == 0x7a) + I2CWrite(&(saa->i2c), 0x88, 0x7a, + dopal ? (PALFirstActive - 1) : + (NTSCFirstActive - 4), 2); + else if (sequence[i*2] == 0x7b) + I2CWrite(&(saa->i2c), 0x88, 0x7b, + dopal ? PALLastActive : + NTSCLastActive, 2); + else + I2CWrite(&(saa->i2c), 0x88, sequence[i * 2], + sequence[i * 2 + 1], 2); + } + } +} + +static void set_genlock_offset(struct saa7146 *saa, int noffset) +{ + int nCode; + int PixelsPerLine = 858; + if (CurrentMode == VIDEO_MODE_PAL) + PixelsPerLine = 864; + if (noffset > 500) + noffset = 500; + else if (noffset < -500) + noffset = -500; + nCode = noffset + 0x100; + if (nCode == 1) + nCode = 0x401; + else if (nCode < 1) nCode = 0x400 + PixelsPerLine + nCode; + debiwrite(saa, debNormal, XILINX_GLDELAY, nCode, 2); +} + +static void set_out_format(struct saa7146 *saa, int mode) +{ + initialize_saa7121(saa, (mode == VIDEO_MODE_NTSC ? 0 : 1)); + saa->boardcfg[2] = mode; + /* do not adjust analog video parameters here, use saa7121 init */ + /* you will affect the SDI output on the new card */ + if (mode == VIDEO_MODE_PAL) { /* PAL */ + debiwrite(saa, debNormal, XILINX_CTL0, 0x0808, 2); + mdelay(50); + saawrite(0x012002c0, SAA7146_NUM_LINE_BYTE1); + if (NewCard) { + debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, + 0xe100, 2); + mdelay(50); + } + debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, + NewCard ? 0xe500: 0x6500, 2); + debiwrite(saa, debNormal, IBM_MP2_DISP_DLY, + (1 << 8) | + (NewCard ? PALFirstActive : PALFirstActive-6), 2); + } else { /* NTSC */ + debiwrite(saa, debNormal, XILINX_CTL0, 0x0800, 2); + mdelay(50); + saawrite(0x00f002c0, SAA7146_NUM_LINE_BYTE1); + debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, + NewCard ? 0xe100: 0x6100, 2); + debiwrite(saa, debNormal, IBM_MP2_DISP_DLY, + (1 << 8) | + (NewCard ? NTSCFirstActive : NTSCFirstActive-6), 2); + } +} + + +/* Intialize bitmangler to map from a byte value to the mangled word that + * must be output to program the Xilinx part through the DEBI port. + * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0 + * transfer FPGA code, init IBM chip, transfer IBM microcode + * rev2 card mangles: 0->7 1->6 2->5 3->4 4->3 5->2 6->1 7->0 + */ +static u16 bitmangler[256]; + +static int initialize_fpga(struct video_code *bitdata) +{ + int i, num, startindex, failure = 0, loadtwo, loadfile = 0; + u16 *dmabuf; + u8 *newdma; + struct saa7146 *saa; + + /* verify fpga code */ + for (startindex = 0; startindex < bitdata->datasize; startindex++) + if (bitdata->data[startindex] == 255) + break; + if (startindex == bitdata->datasize) { + printk(KERN_INFO "stradis: bad fpga code\n"); + return -1; + } + /* initialize all detected cards */ + for (num = 0; num < saa_num; num++) { + saa = &saa7146s[num]; + if (saa->boardcfg[0] > 20) + continue; /* card was programmed */ + loadtwo = (saa->boardcfg[18] & 0x10); + if (!NewCard) /* we have an old board */ + for (i = 0; i < 256; i++) + bitmangler[i] = ((i & 0x01) << 15) | + ((i & 0x02) << 6) | ((i & 0x04) << 4) | + ((i & 0x08) << 9) | ((i & 0x10) << 7) | + ((i & 0x20) >> 3) | ((i & 0x40) >> 5) | + ((i & 0x80) >> 7); + else /* else we have a new board */ + for (i = 0; i < 256; i++) + bitmangler[i] = ((i & 0x01) << 7) | + ((i & 0x02) << 5) | ((i & 0x04) << 3) | + ((i & 0x08) << 1) | ((i & 0x10) >> 1) | + ((i & 0x20) >> 3) | ((i & 0x40) >> 5) | + ((i & 0x80) >> 7); + + dmabuf = (u16 *) saa->dmadebi; + newdma = (u8 *) saa->dmadebi; + if (NewCard) { /* SDM2xxx */ + if (!strncmp(bitdata->loadwhat, "decoder2", 8)) + continue; /* fpga not for this card */ + if (!strncmp(&saa->boardcfg[42], + bitdata->loadwhat, 8)) { + loadfile = 1; + } else if (loadtwo && !strncmp(&saa->boardcfg[19], + bitdata->loadwhat, 8)) { + loadfile = 2; + } else if (!saa->boardcfg[42] && /* special */ + !strncmp("decxl", bitdata->loadwhat, 8)) { + loadfile = 1; + } else + continue; /* fpga not for this card */ + if (loadfile != 1 && loadfile != 2) { + continue; /* skip to next card */ + } + if (saa->boardcfg[0] && loadfile == 1 ) + continue; /* skip to next card */ + if (saa->boardcfg[0] != 1 && loadfile == 2) + continue; /* skip to next card */ + saa->boardcfg[0]++; /* mark fpga handled */ + printk("stradis%d: loading %s\n", saa->nr, + bitdata->loadwhat); + if (loadtwo && loadfile == 2) + goto send_fpga_stuff; + /* turn on the Audio interface to set PROG low */ + saawrite(0x00400040, SAA7146_GPIO_CTRL); + saaread(SAA7146_PSR); /* ensure posted write */ + /* wait for everyone to reset */ + mdelay(10); + saawrite(0x00400000, SAA7146_GPIO_CTRL); + } else { /* original card */ + if (strncmp(bitdata->loadwhat, "decoder2", 8)) + continue; /* fpga not for this card */ + /* Pull the Xilinx PROG signal WS3 low */ + saawrite(0x02000200, SAA7146_MC1); + /* Turn on the Audio interface so can set PROG low */ + saawrite(0x000000c0, SAA7146_ACON1); + /* Pull the Xilinx INIT signal (GPIO2) low */ + saawrite(0x00400000, SAA7146_GPIO_CTRL); + /* Make sure everybody resets */ + saaread(SAA7146_PSR); /* ensure posted write */ + mdelay(10); + /* Release the Xilinx PROG signal */ + saawrite(0x00000000, SAA7146_ACON1); + /* Turn off the Audio interface */ + saawrite(0x02000000, SAA7146_MC1); + } + /* Release Xilinx INIT signal (WS2) */ + saawrite(0x00000000, SAA7146_GPIO_CTRL); + /* Wait for the INIT to go High */ + for (i = 0; i < 10000 && + !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++) + schedule(); + if (i == 1000) { + printk(KERN_INFO "stradis%d: no fpga INIT\n", saa->nr); + return -1; + } +send_fpga_stuff: + if (NewCard) { + for (i = startindex; i < bitdata->datasize; i++) + newdma[i - startindex] = + bitmangler[bitdata->data[i]]; + debiwrite(saa, 0x01420000, 0, 0, + ((bitdata->datasize - startindex) + 5)); + if (loadtwo) { + if (loadfile == 1) { + printk("stradis%d: " + "awaiting 2nd FPGA bitfile\n", + saa->nr); + continue; /* skip to next card */ + } + + } + } else { + for (i = startindex; i < bitdata->datasize; i++) + dmabuf[i - startindex] = + bitmangler[bitdata->data[i]]; + debiwrite(saa, 0x014a0000, 0, 0, + ((bitdata->datasize - startindex) + 5) * 2); + } + for (i = 0; i < 1000 && + !(saaread(SAA7146_PSR) & SAA7146_PSR_PIN2); i++) + schedule(); + if (i == 1000) { + printk(KERN_INFO "stradis%d: FPGA load failed\n", + saa->nr); + failure++; + continue; + } + if (!NewCard) { + /* Pull the Xilinx INIT signal (GPIO2) low */ + saawrite(0x00400000, SAA7146_GPIO_CTRL); + saaread(SAA7146_PSR); /* ensure posted write */ + mdelay(2); + saawrite(0x00000000, SAA7146_GPIO_CTRL); + mdelay(2); + } + printk(KERN_INFO "stradis%d: FPGA Loaded\n", saa->nr); + saa->boardcfg[0] = 26; /* mark fpga programmed */ + /* set VXCO to its lowest frequency */ + debiwrite(saa, debNormal, XILINX_PWM, 0, 2); + if (NewCard) { + /* mute CS3310 */ + if (HaveCS3310) + debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, + 0, 2); + /* set VXCO to PWM mode, release reset, blank on */ + debiwrite(saa, debNormal, XILINX_CTL0, 0xffc4, 2); + mdelay(10); + /* unmute CS3310 */ + if (HaveCS3310) + debiwrite(saa, debNormal, XILINX_CTL0, + 0x2020, 2); + } + /* set source Black */ + debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2); + saa->boardcfg[4] = 22; /* set NTSC First Active Line */ + saa->boardcfg[5] = 23; /* set PAL First Active Line */ + saa->boardcfg[54] = 2; /* set NTSC Last Active Line - 256 */ + saa->boardcfg[55] = 54; /* set PAL Last Active Line - 256 */ + set_out_format(saa, VIDEO_MODE_NTSC); + mdelay(50); + /* begin IBM chip init */ + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2); + saaread(SAA7146_PSR); /* wait for reset */ + mdelay(5); + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2); + debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2); + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0x10, 2); + debiwrite(saa, debNormal, IBM_MP2_CMD_ADDR, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2); + if (NewCard) { + mdelay(5); + /* set i2s rate converter to 48KHz */ + debiwrite(saa, debNormal, 0x80c0, 6, 2); + /* we must init CS8420 first since rev b pulls i2s */ + /* master clock low and CS4341 needs i2s master to */ + /* run the i2c port. */ + if (HaveCS8420) { + /* 0=consumer, 1=pro */ + initialize_cs8420(saa, 0); + } + mdelay(5); + if (HaveCS4341) + initialize_cs4341(saa); + } + debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2); + debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2); + debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2); + if (NewCard) + set_genlock_offset(saa, 0); + debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2); +#if 0 + /* enable genlock */ + debiwrite(saa, debNormal, XILINX_CTL0, 0x8000, 2); +#else + /* disable genlock */ + debiwrite(saa, debNormal, XILINX_CTL0, 0x8080, 2); +#endif + } + return failure; +} + +static int do_ibm_reset(struct saa7146 *saa) +{ + /* failure if decoder not previously programmed */ + if (saa->boardcfg[0] < 37) + return -EIO; + /* mute CS3310 */ + if (HaveCS3310) + debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, 0, 2); + /* disable interrupts */ + saawrite(0, SAA7146_IER); + saa->audhead = saa->audtail = 0; + saa->vidhead = saa->vidtail = 0; + /* tristate debi bus, disable debi transfers */ + saawrite(0x00880000, SAA7146_MC1); + /* ensure posted write */ + saaread(SAA7146_MC1); + mdelay(50); + /* re-enable debi transfers */ + saawrite(0x00880088, SAA7146_MC1); + /* set source Black */ + debiwrite(saa, debNormal, XILINX_CTL0, 0x1707, 2); + /* begin IBM chip init */ + set_out_format(saa, CurrentMode); + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 4, 2); + saaread(SAA7146_PSR); /* wait for reset */ + mdelay(5); + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, 0, 2); + debiread(saa, debNormal, IBM_MP2_CHIP_CONTROL, 2); + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2); + debiwrite(saa, debNormal, IBM_MP2_CHIP_MODE, 0x2e, 2); + if (NewCard) { + mdelay(5); + /* set i2s rate converter to 48KHz */ + debiwrite(saa, debNormal, 0x80c0, 6, 2); + /* we must init CS8420 first since rev b pulls i2s */ + /* master clock low and CS4341 needs i2s master to */ + /* run the i2c port. */ + if (HaveCS8420) { + /* 0=consumer, 1=pro */ + initialize_cs8420(saa, 1); + } + mdelay(5); + if (HaveCS4341) + initialize_cs4341(saa); + } + debiwrite(saa, debNormal, IBM_MP2_INFC_CTL, 0x48, 2); + debiwrite(saa, debNormal, IBM_MP2_BEEP_CTL, 0xa000, 2); + debiwrite(saa, debNormal, IBM_MP2_DISP_LBOR, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_DISP_TBOR, 0, 2); + if (NewCard) + set_genlock_offset(saa, 0); + debiwrite(saa, debNormal, IBM_MP2_FRNT_ATTEN, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2); + debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2); + if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER, + (ChipControl == 0x43 ? 0xe800 : 0xe000), 1)) { + printk(KERN_ERR "stradis%d: IBM config failed\n", saa->nr); + } + if (HaveCS3310) { + int i = CS3310MaxLvl; + debiwrite(saa, debNormal, XILINX_CS3310_CMPLT, ((i<<8)|i), 2); + } + /* start video decoder */ + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, ChipControl, 2); + /* 256k vid, 3520 bytes aud */ + debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, 0x4037, 2); + debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2); + ibm_send_command(saa, IBM_MP2_PLAY, 0, 0); + /* enable buffer threshold irq */ + debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2); + /* clear pending interrupts */ + debiread(saa, debNormal, IBM_MP2_HOST_INT, 2); + debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2); + return 0; +} + +/* load the decoder microcode */ +static int initialize_ibmmpeg2(struct video_code *microcode) +{ + int i, num; + struct saa7146 *saa; + + for (num = 0; num < saa_num; num++) { + saa = &saa7146s[num]; + /* check that FPGA is loaded */ + debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0xa55a, 2); + if ((i = debiread(saa, debNormal, IBM_MP2_OSD_SIZE, 2)) != + 0xa55a) { + printk(KERN_INFO "stradis%d: %04x != 0xa55a\n", + saa->nr, i); +#if 0 + return -1; +#endif + } + if (!strncmp(microcode->loadwhat, "decoder.vid", 11)) { + if (saa->boardcfg[0] > 27) + continue; /* skip to next card */ + /* load video control store */ + saa->boardcfg[1] = 0x13; /* no-sync default */ + debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2); + debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2); + for (i = 0; i < microcode->datasize / 2; i++) + debiwrite(saa, debNormal, IBM_MP2_PROC_IDATA, + (microcode->data[i * 2] << 8) | + microcode->data[i * 2 + 1], 2); + debiwrite(saa, debNormal, IBM_MP2_PROC_IADDR, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, + ChipControl, 2); + saa->boardcfg[0] = 28; + } + if (!strncmp(microcode->loadwhat, "decoder.aud", 11)) { + if (saa->boardcfg[0] > 35) + continue; /* skip to next card */ + /* load audio control store */ + debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 1, 2); + debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2); + for (i = 0; i < microcode->datasize; i++) + debiwrite(saa, debNormal, IBM_MP2_AUD_IDATA, + microcode->data[i], 1); + debiwrite(saa, debNormal, IBM_MP2_AUD_IADDR, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_WR_PROT, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_OSD_SIZE, 0x2000, 2); + debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4552, 2); + if (ibm_send_command(saa, IBM_MP2_CONFIG_DECODER, + 0xe000, 1)) { + printk(KERN_ERR + "stradis%d: IBM config failed\n", + saa->nr); + return -1; + } + /* set PWM to center value */ + if (NewCard) { + debiwrite(saa, debNormal, XILINX_PWM, + saa->boardcfg[14] + + (saa->boardcfg[13]<<8), 2); + } else + debiwrite(saa, debNormal, XILINX_PWM, + 0x46, 2); + if (HaveCS3310) { + i = CS3310MaxLvl; + debiwrite(saa, debNormal, + XILINX_CS3310_CMPLT, ((i<<8)|i), 2); + } + printk(KERN_INFO + "stradis%d: IBM MPEGCD%d Initialized\n", + saa->nr, 18 + (debiread(saa, debNormal, + IBM_MP2_CHIP_CONTROL, 2) >> 12)); + /* start video decoder */ + debiwrite(saa, debNormal, IBM_MP2_CHIP_CONTROL, + ChipControl, 2); + debiwrite(saa, debNormal, IBM_MP2_RB_THRESHOLD, + 0x4037, 2); /* 256k vid, 3520 bytes aud */ + debiwrite(saa, debNormal, IBM_MP2_AUD_CTL, 0x4573, 2); + ibm_send_command(saa, IBM_MP2_PLAY, 0, 0); + /* enable buffer threshold irq */ + debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00c, 2); + debiread(saa, debNormal, IBM_MP2_HOST_INT, 2); + /* enable gpio irq */ + saawrite(0x00002000, SAA7146_GPIO_CTRL); + /* enable decoder output to HPS */ + debiwrite(saa, debNormal, XILINX_CTL0, 0x1711, 2); + saa->boardcfg[0] = 37; + } + } + return 0; +} + +static u32 palette2fmt[] = +{ /* some of these YUV translations are wrong */ + 0xffffffff, 0x86000000, 0x87000000, 0x80000000, 0x8100000, 0x82000000, + 0x83000000, 0x00000000, 0x03000000, 0x03000000, 0x0a00000, 0x03000000, + 0x06000000, 0x00000000, 0x03000000, 0x0a000000, 0x0300000 +}; +static int bpp2fmt[4] = +{ + VIDEO_PALETTE_HI240, VIDEO_PALETTE_RGB565, VIDEO_PALETTE_RGB24, + VIDEO_PALETTE_RGB32 +}; + +/* I wish I could find a formula to calculate these... */ +static u32 h_prescale[64] = +{ + 0x10000000, 0x18040202, 0x18080000, 0x380c0606, 0x38100204, 0x38140808, + 0x38180000, 0x381c0000, 0x3820161c, 0x38242a3b, 0x38281230, 0x382c4460, + 0x38301040, 0x38340080, 0x38380000, 0x383c0000, 0x3840fefe, 0x3844ee9f, + 0x3848ee9f, 0x384cee9f, 0x3850ee9f, 0x38542a3b, 0x38581230, 0x385c0000, + 0x38600000, 0x38640000, 0x38680000, 0x386c0000, 0x38700000, 0x38740000, + 0x38780000, 0x387c0000, 0x30800000, 0x38840000, 0x38880000, 0x388c0000, + 0x38900000, 0x38940000, 0x38980000, 0x389c0000, 0x38a00000, 0x38a40000, + 0x38a80000, 0x38ac0000, 0x38b00000, 0x38b40000, 0x38b80000, 0x38bc0000, + 0x38c00000, 0x38c40000, 0x38c80000, 0x38cc0000, 0x38d00000, 0x38d40000, + 0x38d80000, 0x38dc0000, 0x38e00000, 0x38e40000, 0x38e80000, 0x38ec0000, + 0x38f00000, 0x38f40000, 0x38f80000, 0x38fc0000, +}; +static u32 v_gain[64] = +{ + 0x016000ff, 0x016100ff, 0x016100ff, 0x016200ff, 0x016200ff, 0x016200ff, + 0x016200ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, 0x016300ff, + 0x016300ff, 0x016300ff, 0x016300ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, + 0x016400ff, 0x016400ff, 0x016400ff, 0x016400ff, +}; + + +static void saa7146_set_winsize(struct saa7146 *saa) +{ + u32 format; + int offset, yacl, ysci; + saa->win.color_fmt = format = + (saa->win.depth == 15) ? palette2fmt[VIDEO_PALETTE_RGB555] : + palette2fmt[bpp2fmt[(saa->win.bpp - 1) & 3]]; + offset = saa->win.x * saa->win.bpp + saa->win.y * saa->win.bpl; + saawrite(saa->win.vidadr + offset, SAA7146_BASE_EVEN1); + saawrite(saa->win.vidadr + offset + saa->win.bpl, SAA7146_BASE_ODD1); + saawrite(saa->win.bpl * 2, SAA7146_PITCH1); + saawrite(saa->win.vidadr + saa->win.bpl * saa->win.sheight, + SAA7146_PROT_ADDR1); + saawrite(0, SAA7146_PAGE1); + saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL); + offset = (704 / (saa->win.width - 1)) & 0x3f; + saawrite(h_prescale[offset], SAA7146_HPS_H_PRESCALE); + offset = (720896 / saa->win.width) / (offset + 1); + saawrite((offset<<12)|0x0c, SAA7146_HPS_H_SCALE); + if (CurrentMode == VIDEO_MODE_NTSC) { + yacl = /*(480 / saa->win.height - 1) & 0x3f*/ 0; + ysci = 1024 - (saa->win.height * 1024 / 480); + } else { + yacl = /*(576 / saa->win.height - 1) & 0x3f*/ 0; + ysci = 1024 - (saa->win.height * 1024 / 576); + } + saawrite((1<<31)|(ysci<<21)|(yacl<<15), SAA7146_HPS_V_SCALE); + saawrite(v_gain[yacl], SAA7146_HPS_V_GAIN); + saawrite(((SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_HPS_V | + SAA7146_MC2_UPLD_HPS_H) << 16) | (SAA7146_MC2_UPLD_DMA1 | + SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_HPS_H), + SAA7146_MC2); +} + +/* clip_draw_rectangle(cm,x,y,w,h) -- handle clipping an area + * bitmap is fixed width, 128 bytes (1024 pixels represented) + * arranged most-sigificant-bit-left in 32-bit words + * based on saa7146 clipping hardware, it swaps bytes if LE + * much of this makes up for egcs brain damage -- so if you + * are wondering "why did he do this?" it is because the C + * was adjusted to generate the optimal asm output without + * writing non-portable __asm__ directives. + */ + +static void clip_draw_rectangle(u32 *clipmap, int x, int y, int w, int h) +{ + register int startword, endword; + register u32 bitsleft, bitsright; + u32 *temp; + if (x < 0) { + w += x; + x = 0; + } + if (y < 0) { + h += y; + y = 0; + } + if (w <= 0 || h <= 0 || x > 1023 || y > 639) + return; /* throw away bad clips */ + if (x + w > 1024) + w = 1024 - x; + if (y + h > 640) + h = 640 - y; + startword = (x >> 5); + endword = ((x + w) >> 5); + bitsleft = (0xffffffff >> (x & 31)); + bitsright = (0xffffffff << (~((x + w) - (endword<<5)))); + temp = &clipmap[(y<<5) + startword]; + w = endword - startword; + if (!w) { + bitsleft |= bitsright; + for (y = 0; y < h; y++) { + *temp |= bitsleft; + temp += 32; + } + } else { + for (y = 0; y < h; y++) { + *temp++ |= bitsleft; + for (x = 1; x < w; x++) + *temp++ = 0xffffffff; + *temp |= bitsright; + temp += (32 - w); + } + } +} + +static void make_clip_tab(struct saa7146 *saa, struct video_clip *cr, int ncr) +{ + int i, width, height; + u32 *clipmap; + + clipmap = saa->dmavid2; + if((width=saa->win.width)>1023) + width = 1023; /* sanity check */ + if((height=saa->win.height)>640) + height = 639; /* sanity check */ + if (ncr > 0) { /* rectangles pased */ + /* convert rectangular clips to a bitmap */ + memset(clipmap, 0, VIDEO_CLIPMAP_SIZE); /* clear map */ + for (i = 0; i < ncr; i++) + clip_draw_rectangle(clipmap, cr[i].x, cr[i].y, + cr[i].width, cr[i].height); + } + /* clip against viewing window AND screen + so we do not have to rely on the user program + */ + clip_draw_rectangle(clipmap,(saa->win.x+width>saa->win.swidth) ? + (saa->win.swidth-saa->win.x) : width, 0, 1024, 768); + clip_draw_rectangle(clipmap,0,(saa->win.y+height>saa->win.sheight) ? + (saa->win.sheight-saa->win.y) : height,1024,768); + if (saa->win.x<0) + clip_draw_rectangle(clipmap, 0, 0, -(saa->win.x), 768); + if (saa->win.y<0) + clip_draw_rectangle(clipmap, 0, 0, 1024, -(saa->win.y)); +} + +static int saa_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +{ + struct saa7146 *saa = (struct saa7146 *) dev; + switch (cmd) { + case VIDIOCGCAP: + { + struct video_capability b; + strcpy(b.name, saa->video_dev.name); + b.type = VID_TYPE_CAPTURE | + VID_TYPE_OVERLAY | + VID_TYPE_CLIPPING | + VID_TYPE_FRAMERAM | + VID_TYPE_SCALES; + b.channels = 1; + b.audios = 1; + b.maxwidth = 768; + b.maxheight = 576; + b.minwidth = 32; + b.minheight = 32; + if (copy_to_user(arg, &b, sizeof(b))) + return -EFAULT; + return 0; + } + case VIDIOCGPICT: + { + struct video_picture p = saa->picture; + if (saa->win.depth == 8) + p.palette = VIDEO_PALETTE_HI240; + if (saa->win.depth == 15) + p.palette = VIDEO_PALETTE_RGB555; + if (saa->win.depth == 16) + p.palette = VIDEO_PALETTE_RGB565; + if (saa->win.depth == 24) + p.palette = VIDEO_PALETTE_RGB24; + if (saa->win.depth == 32) + p.palette = VIDEO_PALETTE_RGB32; + if (copy_to_user(arg, &p, sizeof(p))) + return -EFAULT; + return 0; + } + case VIDIOCSPICT: + { + struct video_picture p; + u32 format; + if (copy_from_user(&p, arg, sizeof(p))) + return -EFAULT; + if (p.palette < sizeof(palette2fmt) / sizeof(u32)) { + format = palette2fmt[p.palette]; + saa->win.color_fmt = format; + saawrite(format|0x60, SAA7146_CLIP_FORMAT_CTRL); + } + saawrite(((p.brightness & 0xff00) << 16) | + ((p.contrast & 0xfe00) << 7) | + ((p.colour & 0xfe00) >> 9), SAA7146_BCS_CTRL); + saa->picture = p; + /* upload changed registers */ + saawrite(((SAA7146_MC2_UPLD_HPS_H | + SAA7146_MC2_UPLD_HPS_V) << 16) | + SAA7146_MC2_UPLD_HPS_H | SAA7146_MC2_UPLD_HPS_V, + SAA7146_MC2); + return 0; + } + case VIDIOCSWIN: + { + struct video_window vw; + struct video_clip *vcp = NULL; + + if (copy_from_user(&vw, arg, sizeof(vw))) + return -EFAULT; + + if (vw.flags || vw.width < 16 || vw.height < 16) { /* stop capture */ + saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1); + return -EINVAL; + } + if (saa->win.bpp < 4) { /* 32-bit align start and adjust width */ + int i = vw.x; + vw.x = (vw.x + 3) & ~3; + i = vw.x - i; + vw.width -= i; + } + saa->win.x = vw.x; + saa->win.y = vw.y; + saa->win.width = vw.width; + if (saa->win.width > 768) + saa->win.width = 768; + saa->win.height = vw.height; + if (CurrentMode == VIDEO_MODE_NTSC) { + if (saa->win.height > 480) + saa->win.height = 480; + } else { + if (saa->win.height > 576) + saa->win.height = 576; + } + + /* stop capture */ + saawrite((SAA7146_MC1_TR_E_1 << 16), SAA7146_MC1); + saa7146_set_winsize(saa); + + /* + * Do any clips. + */ + if (vw.clipcount < 0) { + if (copy_from_user(saa->dmavid2, vw.clips, + VIDEO_CLIPMAP_SIZE)) + return -EFAULT; + } else if (vw.clipcount > 0) { + if ((vcp = vmalloc(sizeof(struct video_clip) * + (vw.clipcount))) == NULL) + return -ENOMEM; + if (copy_from_user(vcp, vw.clips, + sizeof(struct video_clip) * + vw.clipcount)) { + vfree(vcp); + return -EFAULT; + } + } else /* nothing clipped */ + memset(saa->dmavid2, 0, VIDEO_CLIPMAP_SIZE); + make_clip_tab(saa, vcp, vw.clipcount); + if (vw.clipcount > 0) + vfree(vcp); + + /* start capture & clip dma if we have an address */ + if ((saa->cap & 3) && saa->win.vidadr != 0) + saawrite(((SAA7146_MC1_TR_E_1 | + SAA7146_MC1_TR_E_2) << 16) | 0xffff, + SAA7146_MC1); + return 0; + } + case VIDIOCGWIN: + { + struct video_window vw; + vw.x = saa->win.x; + vw.y = saa->win.y; + vw.width = saa->win.width; + vw.height = saa->win.height; + vw.chromakey = 0; + vw.flags = 0; + if (copy_to_user(arg, &vw, sizeof(vw))) + return -EFAULT; + return 0; + } + case VIDIOCCAPTURE: + { + int v; + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if (v == 0) { + saa->cap &= ~1; + saawrite((SAA7146_MC1_TR_E_1 << 16), + SAA7146_MC1); + } else { + if (saa->win.vidadr == 0 || saa->win.width == 0 + || saa->win.height == 0) + return -EINVAL; + saa->cap |= 1; + saawrite((SAA7146_MC1_TR_E_1 << 16) | 0xffff, + SAA7146_MC1); + } + return 0; + } + case VIDIOCGFBUF: + { + struct video_buffer v; + v.base = (void *) saa->win.vidadr; + v.height = saa->win.sheight; + v.width = saa->win.swidth; + v.depth = saa->win.depth; + v.bytesperline = saa->win.bpl; + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + + } + case VIDIOCSFBUF: + { + struct video_buffer v; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + if (v.depth != 8 && v.depth != 15 && v.depth != 16 && + v.depth != 24 && v.depth != 32 && v.width > 16 && + v.height > 16 && v.bytesperline > 16) + return -EINVAL; + if (v.base) + saa->win.vidadr = (unsigned long) v.base; + saa->win.sheight = v.height; + saa->win.swidth = v.width; + saa->win.bpp = ((v.depth + 7) & 0x38) / 8; + saa->win.depth = v.depth; + saa->win.bpl = v.bytesperline; + + DEBUG(printk("Display at %p is %d by %d, bytedepth %d, bpl %d\n", + v.base, v.width, v.height, saa->win.bpp, saa->win.bpl)); + saa7146_set_winsize(saa); + return 0; + } + case VIDIOCKEY: + { + /* Will be handled higher up .. */ + return 0; + } + + case VIDIOCGAUDIO: + { + struct video_audio v; + v = saa->audio_dev; + v.flags &= ~(VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); + v.flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; + strcpy(v.name, "MPEG"); + v.mode = VIDEO_SOUND_STEREO; + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCSAUDIO: + { + struct video_audio v; + int i; + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + i = (~(v.volume>>8))&0xff; + if (!HaveCS4341) { + if (v.flags & VIDEO_AUDIO_MUTE) { + debiwrite(saa, debNormal, + IBM_MP2_FRNT_ATTEN, + 0xffff, 2); + } + if (!(v.flags & VIDEO_AUDIO_MUTE)) + debiwrite(saa, debNormal, + IBM_MP2_FRNT_ATTEN, + 0x0000, 2); + if (v.flags & VIDEO_AUDIO_VOLUME) + debiwrite(saa, debNormal, + IBM_MP2_FRNT_ATTEN, + (i<<8)|i, 2); + } else { + if (v.flags & VIDEO_AUDIO_MUTE) + cs4341_setlevel(saa, 0xff, 0xff); + if (!(v.flags & VIDEO_AUDIO_MUTE)) + cs4341_setlevel(saa, 0, 0); + if (v.flags & VIDEO_AUDIO_VOLUME) + cs4341_setlevel(saa, i, i); + } + saa->audio_dev = v; + return 0; + } + + case VIDIOCGUNIT: + { + struct video_unit vu; + vu.video = saa->video_dev.minor; + vu.vbi = VIDEO_NO_UNIT; + vu.radio = VIDEO_NO_UNIT; + vu.audio = VIDEO_NO_UNIT; + vu.teletext = VIDEO_NO_UNIT; + if (copy_to_user((void *) arg, (void *) &vu, sizeof(vu))) + return -EFAULT; + return 0; + } + case VIDIOCSPLAYMODE: + { + struct video_play_mode pmode; + if (copy_from_user((void *) &pmode, arg, + sizeof(struct video_play_mode))) + return -EFAULT; + switch (pmode.mode) { + case VID_PLAY_VID_OUT_MODE: + if (pmode.p1 != VIDEO_MODE_NTSC && + pmode.p1 != VIDEO_MODE_PAL) + return -EINVAL; + set_out_format(saa, pmode.p1); + return 0; + case VID_PLAY_GENLOCK: + debiwrite(saa, debNormal, + XILINX_CTL0, + (pmode.p1 ? 0x8000 : 0x8080), + 2); + if (NewCard) + set_genlock_offset(saa, + pmode.p2); + return 0; + case VID_PLAY_NORMAL: + debiwrite(saa, debNormal, + IBM_MP2_CHIP_CONTROL, + ChipControl, 2); + ibm_send_command(saa, + IBM_MP2_PLAY, 0, 0); + saa->playmode = pmode.mode; + return 0; + case VID_PLAY_PAUSE: + /* IBM removed the PAUSE command */ + /* they say use SINGLE_FRAME now */ + case VID_PLAY_SINGLE_FRAME: + ibm_send_command(saa, + IBM_MP2_SINGLE_FRAME, + 0, 0); + if (saa->playmode == pmode.mode) { + debiwrite(saa, debNormal, + IBM_MP2_CHIP_CONTROL, + ChipControl, 2); + } + saa->playmode = pmode.mode; + return 0; + case VID_PLAY_FAST_FORWARD: + ibm_send_command(saa, + IBM_MP2_FAST_FORWARD, 0, 0); + saa->playmode = pmode.mode; + return 0; + case VID_PLAY_SLOW_MOTION: + ibm_send_command(saa, + IBM_MP2_SLOW_MOTION, + pmode.p1, 0); + saa->playmode = pmode.mode; + return 0; + case VID_PLAY_IMMEDIATE_NORMAL: + /* ensure transfers resume */ + debiwrite(saa, debNormal, + IBM_MP2_CHIP_CONTROL, + ChipControl, 2); + ibm_send_command(saa, + IBM_MP2_IMED_NORM_PLAY, 0, 0); + saa->playmode = VID_PLAY_NORMAL; + return 0; + case VID_PLAY_SWITCH_CHANNELS: + saa->audhead = saa->audtail = 0; + saa->vidhead = saa->vidtail = 0; + ibm_send_command(saa, + IBM_MP2_FREEZE_FRAME, 0, 1); + ibm_send_command(saa, + IBM_MP2_RESET_AUD_RATE, 0, 1); + debiwrite(saa, debNormal, + IBM_MP2_CHIP_CONTROL, 0, 2); + ibm_send_command(saa, + IBM_MP2_CHANNEL_SWITCH, 0, 1); + debiwrite(saa, debNormal, + IBM_MP2_CHIP_CONTROL, + ChipControl, 2); + ibm_send_command(saa, + IBM_MP2_PLAY, 0, 0); + saa->playmode = VID_PLAY_NORMAL; + return 0; + case VID_PLAY_FREEZE_FRAME: + ibm_send_command(saa, + IBM_MP2_FREEZE_FRAME, 0, 0); + saa->playmode = pmode.mode; + return 0; + case VID_PLAY_STILL_MODE: + ibm_send_command(saa, + IBM_MP2_SET_STILL_MODE, 0, 0); + saa->playmode = pmode.mode; + return 0; + case VID_PLAY_MASTER_MODE: + if (pmode.p1 == VID_PLAY_MASTER_NONE) + saa->boardcfg[1] = 0x13; + else if (pmode.p1 == + VID_PLAY_MASTER_VIDEO) + saa->boardcfg[1] = 0x23; + else if (pmode.p1 == + VID_PLAY_MASTER_AUDIO) + saa->boardcfg[1] = 0x43; + else + return -EINVAL; + debiwrite(saa, debNormal, + IBM_MP2_CHIP_CONTROL, + ChipControl, 2); + return 0; + case VID_PLAY_ACTIVE_SCANLINES: + if (CurrentMode == VIDEO_MODE_PAL) { + if (pmode.p1 < 1 || + pmode.p2 > 625) + return -EINVAL; + saa->boardcfg[5] = pmode.p1; + saa->boardcfg[55] = (pmode.p1 + + (pmode.p2/2) - 1) & + 0xff; + } else { + if (pmode.p1 < 4 || + pmode.p2 > 525) + return -EINVAL; + saa->boardcfg[4] = pmode.p1; + saa->boardcfg[54] = (pmode.p1 + + (pmode.p2/2) - 4) & + 0xff; + } + set_out_format(saa, CurrentMode); + case VID_PLAY_RESET: + return do_ibm_reset(saa); + case VID_PLAY_END_MARK: + if (saa->endmarktail < + saa->endmarkhead) { + if (saa->endmarkhead - + saa->endmarktail < 2) + return -ENOSPC; + } else if (saa->endmarkhead <= + saa->endmarktail) { + if (saa->endmarktail - + saa->endmarkhead > + (MAX_MARKS - 2)) + return -ENOSPC; + } else + return -ENOSPC; + saa->endmark[saa->endmarktail] = + saa->audtail; + saa->endmarktail++; + if (saa->endmarktail >= MAX_MARKS) + saa->endmarktail = 0; + } + return -EINVAL; + } + case VIDIOCSWRITEMODE: + { + int mode; + if (copy_from_user((void *) &mode, arg, sizeof(int))) + return -EFAULT; + if (mode == VID_WRITE_MPEG_AUD || + mode == VID_WRITE_MPEG_VID || + mode == VID_WRITE_CC || + mode == VID_WRITE_TTX || + mode == VID_WRITE_OSD) { + saa->writemode = mode; + return 0; + } + return -EINVAL; + } + case VIDIOCSMICROCODE: + { + struct video_code ucode; + __u8 *udata; + int i; + if (copy_from_user((void *) &ucode, arg, + sizeof(ucode))) + return -EFAULT; + if (ucode.datasize > 65536 || ucode.datasize < 1024 || + strncmp(ucode.loadwhat, "dec", 3)) + return -EINVAL; + if ((udata = vmalloc(ucode.datasize)) == NULL) + return -ENOMEM; + if (copy_from_user((void *) udata, ucode.data, + ucode.datasize)) { + vfree(udata); + return -EFAULT; + } + ucode.data = udata; + if (!strncmp(ucode.loadwhat, "decoder.aud", 11) + || !strncmp(ucode.loadwhat, "decoder.vid", 11)) + i = initialize_ibmmpeg2(&ucode); + else + i = initialize_fpga(&ucode); + vfree(udata); + if (i) + return -EINVAL; + return 0; + + } + case VIDIOCGCHAN: /* this makes xawtv happy */ + { + struct video_channel v; + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + v.flags = VIDEO_VC_AUDIO; + v.tuners = 0; + v.type = VID_TYPE_MPEG_DECODER; + v.norm = CurrentMode; + strcpy(v.name, "MPEG2"); + if (copy_to_user(arg, &v, sizeof(v))) + return -EFAULT; + return 0; + } + case VIDIOCSCHAN: /* this makes xawtv happy */ + { + struct video_channel v; + if (copy_from_user(&v, arg, sizeof(v))) + return -EFAULT; + /* do nothing */ + return 0; + } + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static int saa_init_done(struct video_device *dev) +{ + return 0; +} + +static int saa_mmap(struct video_device *dev, const char *adr, + unsigned long size) +{ + struct saa7146 *saa = (struct saa7146 *) dev; + printk(KERN_DEBUG "stradis%d: saa_mmap called\n", saa->nr); + return -EINVAL; +} + +static long saa_read(struct video_device *dev, char *buf, + unsigned long count, int nonblock) +{ + return -EINVAL; +} + +static long saa_write(struct video_device *dev, const char *buf, + unsigned long count, int nonblock) +{ + struct saa7146 *saa = (struct saa7146 *) dev; + unsigned long todo = count; + int blocksize, split; + unsigned long flags; + + while (todo > 0) { + if (saa->writemode == VID_WRITE_MPEG_AUD) { + spin_lock_irqsave(&saa->lock, flags); + if (saa->audhead <= saa->audtail) + blocksize = 65536-(saa->audtail - saa->audhead); + else + blocksize = saa->audhead - saa->audtail; + spin_unlock_irqrestore(&saa->lock, flags); + if (blocksize < 16384) { + saawrite(SAA7146_PSR_DEBI_S | + SAA7146_PSR_PIN1, SAA7146_IER); + saawrite(SAA7146_PSR_PIN1, SAA7146_PSR); + /* wait for buffer space to open */ + interruptible_sleep_on(&saa->audq); + } + spin_lock_irqsave(&saa->lock, flags); + if (saa->audhead <= saa->audtail) { + blocksize = 65536-(saa->audtail - saa->audhead); + split = 65536 - saa->audtail; + } else { + blocksize = saa->audhead - saa->audtail; + split = 65536; + } + spin_unlock_irqrestore(&saa->lock, flags); + blocksize--; + if (blocksize > todo) + blocksize = todo; + /* double check that we really have space */ + if (!blocksize) + return -ENOSPC; + if (split < blocksize) { + if (copy_from_user(saa->audbuf + + saa->audtail, buf, split)) + return -EFAULT; + buf += split; + todo -= split; + blocksize -= split; + saa->audtail = 0; + } + if (copy_from_user(saa->audbuf + saa->audtail, buf, + blocksize)) + return -EFAULT; + saa->audtail += blocksize; + todo -= blocksize; + buf += blocksize; + saa->audtail &= 0xffff; + } else if (saa->writemode == VID_WRITE_MPEG_VID) { + spin_lock_irqsave(&saa->lock, flags); + if (saa->vidhead <= saa->vidtail) + blocksize=524288-(saa->vidtail - saa->vidhead); + else + blocksize = saa->vidhead - saa->vidtail; + spin_unlock_irqrestore(&saa->lock, flags); + if (blocksize < 65536) { + saawrite(SAA7146_PSR_DEBI_S | + SAA7146_PSR_PIN1, SAA7146_IER); + saawrite(SAA7146_PSR_PIN1, SAA7146_PSR); + /* wait for buffer space to open */ + interruptible_sleep_on(&saa->vidq); + } + spin_lock_irqsave(&saa->lock, flags); + if (saa->vidhead <= saa->vidtail) { + blocksize=524288-(saa->vidtail - saa->vidhead); + split = 524288 - saa->vidtail; + } else { + blocksize = saa->vidhead - saa->vidtail; + split = 524288; + } + spin_unlock_irqrestore(&saa->lock, flags); + blocksize--; + if (blocksize > todo) + blocksize = todo; + /* double check that we really have space */ + if (!blocksize) + return -ENOSPC; + if (split < blocksize) { + if (copy_from_user(saa->vidbuf + + saa->vidtail, buf, split)) + return -EFAULT; + buf += split; + todo -= split; + blocksize -= split; + saa->vidtail = 0; + } + if (copy_from_user(saa->vidbuf + saa->vidtail, buf, + blocksize)) + return -EFAULT; + saa->vidtail += blocksize; + todo -= blocksize; + buf += blocksize; + saa->vidtail &= 0x7ffff; + } else if (saa->writemode == VID_WRITE_OSD) { + if (count > 131072) + return -ENOSPC; + if (copy_from_user(saa->osdbuf, buf, count)) + return -EFAULT; + buf += count; + saa->osdhead = 0; + saa->osdtail = count; + debiwrite(saa, debNormal, IBM_MP2_OSD_ADDR, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_OSD_LINK_ADDR, 0, 2); + debiwrite(saa, debNormal, IBM_MP2_MASK0, 0xc00d, 2); + debiwrite(saa, debNormal, IBM_MP2_DISP_MODE, + debiread(saa, debNormal, + IBM_MP2_DISP_MODE, 2) | 1, 2); + /* trigger osd data transfer */ + saawrite(SAA7146_PSR_DEBI_S | + SAA7146_PSR_PIN1, SAA7146_IER); + saawrite(SAA7146_PSR_PIN1, SAA7146_PSR); + } + } + return count; +} + +static int saa_open(struct video_device *dev, int flags) +{ + struct saa7146 *saa = (struct saa7146 *) dev; + + saa->video_dev.busy = 0; + saa->user++; + if (saa->user > 1) + return 0; /* device open already, don't reset */ + saa->writemode = VID_WRITE_MPEG_VID; /* default to video */ + return 0; +} + +static void saa_close(struct video_device *dev) +{ + struct saa7146 *saa = (struct saa7146 *) dev; + saa->user--; + saa->video_dev.busy = 0; + if (saa->user > 0) /* still someone using device */ + return; + saawrite(0x007f0000, SAA7146_MC1); /* stop all overlay dma */ +} + +/* template for video_device-structure */ +static struct video_device saa_template = +{ + "SAA7146A", + VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, + VID_HARDWARE_SAA7146, + saa_open, + saa_close, + saa_read, + saa_write, + NULL, /* poll */ + saa_ioctl, + saa_mmap, + saa_init_done, + NULL, + 0, + 0 +}; + +static int configure_saa7146(struct pci_dev *dev, int num) +{ + int result; + struct saa7146 *saa; + + saa = &saa7146s[num]; + + saa->endmarkhead = saa->endmarktail = 0; + saa->win.x = saa->win.y = 0; + saa->win.width = saa->win.cropwidth = 720; + saa->win.height = saa->win.cropheight = 480; + saa->win.cropx = saa->win.cropy = 0; + saa->win.bpp = 2; + saa->win.depth = 16; + saa->win.color_fmt = palette2fmt[VIDEO_PALETTE_RGB565]; + saa->win.bpl = 1024 * saa->win.bpp; + saa->win.swidth = 1024; + saa->win.sheight = 768; + saa->picture.brightness = 32768; + saa->picture.contrast = 38768; + saa->picture.colour = 32768; + saa->cap = 0; + saa->dev = dev; + saa->nr = num; + saa->playmode = VID_PLAY_NORMAL; + memset(saa->boardcfg, 0, 64); /* clear board config area */ + saa->saa7146_mem = NULL; + saa->dmavid1 = saa->dmavid2 = saa->dmavid3 = saa->dmaa1in = + saa->dmaa1out = saa->dmaa2in = saa->dmaa2out = + saa->pagevid1 = saa->pagevid2 = saa->pagevid3 = saa->pagea1in = + saa->pagea1out = saa->pagea2in = saa->pagea2out = + saa->pagedebi = saa->dmaRPS1 = saa->dmaRPS2 = saa->pageRPS1 = + saa->pageRPS2 = NULL; + saa->audbuf = saa->vidbuf = saa->osdbuf = saa->dmadebi = NULL; + saa->audhead = saa->vidtail = 0; + + init_waitqueue_head(&saa->i2cq); + init_waitqueue_head(&saa->audq); + init_waitqueue_head(&saa->debiq); + init_waitqueue_head(&saa->vidq); + spin_lock_init(&saa->lock); + + saa->id = dev->device; + saa->irq = dev->irq; + saa->video_dev.minor = -1; + saa->saa7146_adr = dev->resource[0].start; + pci_read_config_byte(dev, PCI_CLASS_REVISION, &saa->revision); + saa->saa7146_mem = ioremap(((saa->saa7146_adr) & + PCI_BASE_ADDRESS_MEM_MASK), 0x200); + memcpy(&(saa->i2c), &saa7146_i2c_bus_template, sizeof(struct i2c_bus)); + memcpy(&saa->video_dev, &saa_template, sizeof(saa_template)); + sprintf(saa->i2c.name, "stradis%d", num); + saa->i2c.data = saa; + saawrite(0, SAA7146_IER); /* turn off all interrupts */ + result = request_irq(saa->irq, saa7146_irq, + SA_SHIRQ | SA_INTERRUPT, "stradis", (void *) saa); + if (result == -EINVAL) + printk(KERN_ERR "stradis%d: Bad irq number or handler\n", + num); + if (result == -EBUSY) + printk(KERN_ERR "stradis%d: IRQ %ld busy, change your PnP" + " config in BIOS\n", num, saa->irq); + if (result < 0) + return result; + pci_set_master(dev); + if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER) < 0) + return -1; +#if 0 + /* i2c generic interface is currently BROKEN */ + i2c_register_bus(&saa->i2c); +#endif + return 0; +} + +static int init_saa7146(int i) +{ + struct saa7146 *saa = &saa7146s[i]; + + saa->user = 0; + /* reset the saa7146 */ + saawrite(0xffff0000, SAA7146_MC1); + mdelay(5); + /* enable debi and i2c transfers and pins */ + saawrite(((SAA7146_MC1_EDP | SAA7146_MC1_EI2C | + SAA7146_MC1_TR_E_DEBI) << 16) | 0xffff, SAA7146_MC1); + /* ensure proper state of chip */ + saawrite(0x00000000, SAA7146_PAGE1); + saawrite(0x00f302c0, SAA7146_NUM_LINE_BYTE1); + saawrite(0x00000000, SAA7146_PAGE2); + saawrite(0x01400080, SAA7146_NUM_LINE_BYTE2); + saawrite(0x00000000, SAA7146_DD1_INIT); + saawrite(0x00000000, SAA7146_DD1_STREAM_B); + saawrite(0x00000000, SAA7146_DD1_STREAM_A); + saawrite(0x00000000, SAA7146_BRS_CTRL); + saawrite(0x80400040, SAA7146_BCS_CTRL); + saawrite(0x0000e000 /*| (1<<29)*/, SAA7146_HPS_CTRL); + saawrite(0x00000060, SAA7146_CLIP_FORMAT_CTRL); + saawrite(0x00000000, SAA7146_ACON1); + saawrite(0x00000000, SAA7146_ACON2); + saawrite(0x00000600, SAA7146_I2C_STATUS); + saawrite(((SAA7146_MC2_UPLD_D1_B | SAA7146_MC2_UPLD_D1_A | + SAA7146_MC2_UPLD_BRS | SAA7146_MC2_UPLD_HPS_H | + SAA7146_MC2_UPLD_HPS_V | SAA7146_MC2_UPLD_DMA2 | + SAA7146_MC2_UPLD_DMA1 | SAA7146_MC2_UPLD_I2C) << 16) | 0xffff, + SAA7146_MC2); + /* setup arbitration control registers */ + saawrite(0x1412121a, SAA7146_PCI_BT_V1); + + /* allocate 32k dma buffer + 4k for page table */ + if ((saa->dmadebi = kmalloc(32768 + 4096, GFP_KERNEL)) == NULL) { + printk(KERN_ERR "stradis%d: debi kmalloc failed\n", i); + return -1; + } +#if 0 + saa->pagedebi = saa->dmadebi + 32768; /* top 4k is for mmu */ + saawrite(virt_to_bus(saa->pagedebi) /*|0x800 */ , SAA7146_DEBI_PAGE); + for (i = 0; i < 12; i++) /* setup mmu page table */ + saa->pagedebi[i] = virt_to_bus((saa->dmadebi + i * 4096)); +#endif + saa->audhead = saa->vidhead = saa->osdhead = 0; + saa->audtail = saa->vidtail = saa->osdtail = 0; + if (saa->vidbuf == NULL) + if ((saa->vidbuf = vmalloc(524288)) == NULL) { + printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr); + return -ENOMEM; + } + if (saa->audbuf == NULL) + if ((saa->audbuf = vmalloc(65536)) == NULL) { + printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr); + vfree(saa->vidbuf); + saa->vidbuf = NULL; + return -ENOMEM; + } + if (saa->osdbuf == NULL) + if ((saa->osdbuf = vmalloc(131072)) == NULL) { + printk(KERN_ERR "stradis%d: malloc failed\n", saa->nr); + vfree(saa->vidbuf); + vfree(saa->audbuf); + saa->vidbuf = saa->audbuf = NULL; + return -ENOMEM; + } + /* allocate 81920 byte buffer for clipping */ + if ((saa->dmavid2 = kmalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) { + printk(KERN_ERR "stradis%d: clip kmalloc failed\n", saa->nr); + vfree(saa->vidbuf); + vfree(saa->audbuf); + vfree(saa->osdbuf); + saa->vidbuf = saa->audbuf = saa->osdbuf = NULL; + saa->dmavid2 = NULL; + return -1; + } + memset(saa->dmavid2, 0x00, VIDEO_CLIPMAP_SIZE); /* clip everything */ + /* setup clipping registers */ + saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2); + saawrite(virt_to_bus(saa->dmavid2) + 128, SAA7146_BASE_ODD2); + saawrite(virt_to_bus(saa->dmavid2) + VIDEO_CLIPMAP_SIZE, + SAA7146_PROT_ADDR2); + saawrite(256, SAA7146_PITCH2); + saawrite(4, SAA7146_PAGE2); /* dma direction: read, no byteswap */ + saawrite(((SAA7146_MC2_UPLD_DMA2) << 16) | SAA7146_MC2_UPLD_DMA2, + SAA7146_MC2); + I2CBusScan(&(saa->i2c)); + return 0; +} + +static void release_saa(void) +{ + u8 command; + int i; + struct saa7146 *saa; + + for (i = 0; i < saa_num; i++) { + saa = &saa7146s[i]; + + /* turn off all capturing, DMA and IRQs */ + saawrite(0xffff0000, SAA7146_MC1); /* reset chip */ + saawrite(0, SAA7146_MC2); + saawrite(0, SAA7146_IER); + saawrite(0xffffffffUL, SAA7146_ISR); +#if 0 + /* unregister i2c_bus */ + i2c_unregister_bus((&saa->i2c)); +#endif + + /* disable PCI bus-mastering */ + pci_read_config_byte(saa->dev, PCI_COMMAND, &command); + /* Should this be &=~ ?? */ + command &= ~PCI_COMMAND_MASTER; + pci_write_config_byte(saa->dev, PCI_COMMAND, command); + /* unmap and free memory */ + saa->audhead = saa->audtail = saa->osdhead = 0; + saa->vidhead = saa->vidtail = saa->osdtail = 0; + if (saa->vidbuf) + vfree(saa->vidbuf); + if (saa->audbuf) + vfree(saa->audbuf); + if (saa->osdbuf) + vfree(saa->osdbuf); + if (saa->dmavid2) + kfree((void *) saa->dmavid2); + saa->audbuf = saa->vidbuf = saa->osdbuf = NULL; + saa->dmavid2 = NULL; + if (saa->dmadebi) + kfree((void *) saa->dmadebi); + if (saa->dmavid1) + kfree((void *) saa->dmavid1); + if (saa->dmavid2) + kfree((void *) saa->dmavid2); + if (saa->dmavid3) + kfree((void *) saa->dmavid3); + if (saa->dmaa1in) + kfree((void *) saa->dmaa1in); + if (saa->dmaa1out) + kfree((void *) saa->dmaa1out); + if (saa->dmaa2in) + kfree((void *) saa->dmaa2in); + if (saa->dmaa2out) + kfree((void *) saa->dmaa2out); + if (saa->dmaRPS1) + kfree((void *) saa->dmaRPS1); + if (saa->dmaRPS2) + kfree((void *) saa->dmaRPS2); + free_irq(saa->irq, saa); + if (saa->saa7146_mem) + iounmap(saa->saa7146_mem); + if (saa->video_dev.minor != -1) + video_unregister_device(&saa->video_dev); + } +} + +#ifdef MODULE +int init_module(void) +{ +#else +int init_stradis_cards(struct video_init *unused) +{ +#endif + struct pci_dev *dev = pci_devices; + int result = 0, i; + u32 newcard; + + saa_num = 0; + + while (dev) { + if (dev->vendor == PCI_VENDOR_ID_PHILIPS) + if (dev->device == PCI_DEVICE_ID_PHILIPS_SAA7146) { + pci_read_config_dword(dev, + PCI_SUBSYSTEM_VENDOR_ID, &newcard); + if (!newcard) + printk(KERN_INFO "stradis%d: rev1 decoder\n", saa_num); + else + printk(KERN_INFO "stradis%d: SDM2xx found\n", saa_num); + result = configure_saa7146(dev, saa_num++); + } + if (result) + return result; + dev = dev->next; + } + if (saa_num) + printk(KERN_INFO "stradis: %d card(s) found.\n", saa_num); + else + return -EINVAL; + for (i = 0; i < saa_num; i++) + if (init_saa7146(i) < 0) { + release_saa(); + return -EIO; + } + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + release_saa(); + printk(KERN_INFO "stradis: module cleanup complete\n"); +} + +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/char/videodev.c linux/drivers/char/videodev.c --- v2.3.26/linux/drivers/char/videodev.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/char/videodev.c Wed Nov 10 16:09:01 1999 @@ -60,6 +60,9 @@ {"i2c-tuner", i2c_tuner_init}, {"bttv", init_bttv_cards}, #endif +#ifdef CONFIG_VIDEO_STRADIS + {"stradis", init_stradis_cards}, +#endif #ifdef CONFIG_VIDEO_BWQCAM {"bw-qcam", init_bw_qcams}, #endif diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/README linux/drivers/i2o/README --- v2.3.26/linux/drivers/i2o/README Mon Oct 4 15:49:29 1999 +++ linux/drivers/i2o/README Wed Nov 10 09:52:18 1999 @@ -9,13 +9,13 @@ AUTHORS (so far) -Alan Cox, Building Number Three Ltd. +Alan Cox, Building Number Three Ltd. Core code, SCSI and Block OSMs -Steve Ralston, LSI Logic Corp. +Steve Ralston, LSI Logic Corp. Debugging SCSI and Block OSM -Deepak Saxena, Intel Corp. +Deepak Saxena, Intel Corp. /proc interface, bug fixes Ioctl interfaces for control Debugging LAN OSM @@ -23,18 +23,21 @@ Philip Rumpf Fixed assorted dumb SMP locking bugs -Juha Sievanen, University of Helsinki Finland +Juha Sievanen, University of Helsinki Finland LAN OSM code /proc interface to LAN class Bug fixes Core code extensions -Auvo Häkkinen, University of Helsinki Finland +Auvo Häkkinen, University of Helsinki Finland LAN OSM code /Proc interface to LAN class Bug fixes Core code extensions +Taneli Vähäkangas, University of Helsinki Finland + Fixes to i2o_config + CREDITS This work was made possible by @@ -75,6 +78,7 @@ o PCI IOP's without interrupts are not supported yet o Push FAIL handling into the core o DDM control interfaces for module load etc +o Event handling Block: o Real error handler @@ -87,7 +91,8 @@ o Find the right way to associate drives/luns/busses Lan: Batch mode sends - Fix the "killing interrupt handler" in i2o_set_multicast_list + Performance tuning + Event handling Tape: o Anyone seen anything implementing this ? diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/README.ioctl linux/drivers/i2o/README.ioctl --- v2.3.26/linux/drivers/i2o/README.ioctl Mon Oct 4 15:49:29 1999 +++ linux/drivers/i2o/README.ioctl Wed Nov 10 09:52:18 1999 @@ -208,18 +208,16 @@ DESCRIPTION - This function downloads the software pointed by sw->buf to the - iop identified by sw->iop. The DownloadFlags, SwID, SwType and SwSize - fields of the ExecSwDownload message are filled in with the values of - sw->flags, sw->sw_id, sw->sw_type and *(sw->swlen). - - Once the ioctl() is called and software transfer begins, the - user can read the value *(sw->maxfrag) and *(sw->curfrag) to - determine the status of the software transfer. As the IOP - is very slow when it comes to SW transfers, this can be - used by a separate thread to report status to the user. The - user _should not_ write to this memory location until the ioctl() - has returned. + This function downloads a software fragment pointed by sw->buf + to the iop identified by sw->iop. The DownloadFlags, SwID, SwType + and SwSize fields of the ExecSwDownload message are filled in with + the values of sw->flags, sw->sw_id, sw->sw_type and *(sw->swlen). + + The fragments _must_ be sent in order and be 8K in size. The last + fragment _may_ be shorter, however. The kernel will compute its + size based on information in the sw->swlen field. + + Please note that SW transfers can take a long time. RETURNS @@ -234,7 +232,7 @@ IX. Uploading Software SYNOPSIS - + ioctl(fd, I2OSWUL, struct i2o_sw_xfer *sw); struct i2o_sw_xfer @@ -251,19 +249,17 @@ DESCRIPTION - This function uploads software from the IOP identified by sw->iop - and places it in the buffer pointed to by sw->buf. The length of the - buffer is given in *(sw->swlen). The UploadFlags, SwID and SwType - fields of the ExecSwUpload message are filled in - with the values of sw->flags, sw->sw_id and sw->sw_type. - - Once the ioctl() is called and software transfer begins, the - user can read the value *(sw->maxfrag) and *(sw->curfrag) to - determine the status of the software transfer. As the IOP - is very slow when it comes to SW transfers, this can be - used by a separate thread to report status to the user. The - user _should not_ write to this memory location until the ioctl() - has returned. + This function uploads a software fragment from the IOP identified + by sw->iop, sw->sw_type, sw->sw_id and optionally sw->swlen fields. + The UploadFlags, SwID, SwType and SwSize fields of the ExecSwUpload + message are filled in with the values of sw->flags, sw->sw_id, + sw->sw_type and *(sw->swlen). + + The fragments _must_ be requested in order and be 8K in size. The + user is responsible for allocating memory pointed by sw->buf. The + last fragment _may_ be shorter. + + Please note that SW transfers can take a long time. RETURNS diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_config.c linux/drivers/i2o/i2o_config.c --- v2.3.26/linux/drivers/i2o/i2o_config.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/i2o/i2o_config.c Wed Nov 10 09:52:18 1999 @@ -11,7 +11,11 @@ * - Added software download ioctl (still testing) * Modified 09/10/1999 by Auvo Häkkinen * - Changes to i2o_cfg_reply(), ioctl_parms() - * - Added ioct_validate() (not yet tested) + * - Added ioct_validate() + * Modified 09/30/1999 by Taneli Vähäkangas + * - Fixed ioctl_swdl() + * Modified 10/04/1999 by Taneli Vähäkangas + * - Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel() * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -33,8 +37,6 @@ #include #include -#include "i2o_proc.h" - static int i2o_cfg_token = 0; static int i2o_cfg_context = -1; static void *page_buf; @@ -196,7 +198,7 @@ struct i2o_controller *c; struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg; struct i2o_cmd_hrtlct kcmd; - pi2o_hrt hrt; + i2o_hrt *hrt; int len; u32 reslen; int ret = 0; @@ -214,7 +216,7 @@ if(!c) return -ENXIO; - hrt = (pi2o_hrt)c->hrt; + hrt = (i2o_hrt *)c->hrt; i2o_unlock_controller(c); @@ -235,7 +237,7 @@ struct i2o_controller *c; struct i2o_cmd_hrtlct *cmd = (struct i2o_cmd_hrtlct*)arg; struct i2o_cmd_hrtlct kcmd; - pi2o_lct lct; + i2o_lct *lct; int len; int ret = 0; u32 reslen; @@ -253,7 +255,7 @@ if(!c) return -ENXIO; - lct = (pi2o_lct)c->lct; + lct = (i2o_lct *)c->lct; i2o_unlock_controller(c); len = (unsigned int)lct->table_size << 2; @@ -317,14 +319,14 @@ return -ENOMEM; } - len = i2o_issue_params(i2o_cmd, c, kcmd.tid, - ops, kcmd.oplen, res, 65536); + len = i2o_issue_params(i2o_cmd, c, kcmd.tid, + ops, kcmd.oplen, res, sizeof(res)); i2o_unlock_controller(c); kfree(ops); - if (len) { + if (len < 0) { kfree(res); - return len; /* -DetailedStatus || -ETIMEDOUT */ + return len; /* -DetailedStatus */ } put_user(len, kcmd.reslen); @@ -414,7 +416,7 @@ } token = i2o_post_wait(c, msg, 9*4, 10); - if(token) + if(token != I2O_POST_WAIT_OK) { i2o_unlock_controller(c); kfree(res); @@ -437,139 +439,175 @@ return ret; } - + int ioctl_swdl(unsigned long arg) { struct i2o_sw_xfer kxfer; struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg; - unsigned char maxfrag = 0, curfrag = 0; - unsigned char buffer[8192]; + unsigned char maxfrag = 0, curfrag = 1; + unsigned char *buffer; u32 msg[9]; - unsigned int token = 0, diff = 0, swlen = 0, swxfer = 0; + unsigned int status = 0, swlen = 0, fragsize = 8192; struct i2o_controller *c; - int foo = 0; - printk("*** foo%d ***\n", foo++); if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer))) - { - printk( "i2o_config: can't copy i2o_sw cmd @ %p\n", pxfer); return -EFAULT; - } - printk("*** foo%d ***\n", foo++); - printk("Attempting to copy swlen from %p\n", kxfer.swlen); if(get_user(swlen, kxfer.swlen) < 0) - { - printk( "i2o_config: can't copy swlen\n"); return -EFAULT; - } - printk("*** foo%d ***\n", foo++); - - maxfrag = swlen >> 13; // Transfer in 8k fragments - printk("Attempting to write maxfrag @ %p\n", kxfer.maxfrag); - if(put_user(maxfrag, kxfer.maxfrag) < 0) - { - printk( "i2o_config: can't write maxfrag\n"); + if(get_user(maxfrag, kxfer.maxfrag) < 0) return -EFAULT; - } - printk("*** foo%d ***\n", foo++); - printk("Attempting to write curfrag @ %p\n", kxfer.curfrag); - if(put_user(curfrag, kxfer.curfrag) < 0) - { - printk( "i2o_config: can't write curfrag\n"); + if(get_user(curfrag, kxfer.curfrag) < 0) return -EFAULT; - } - printk("*** foo%d ***\n", foo++); - if(!kxfer.buf) - { - printk( "i2o_config: NULL software buffer\n"); + if(curfrag==maxfrag) fragsize = swlen-(maxfrag-1)*8192; + + if(!kxfer.buf || !access_ok(VERIFY_READ, kxfer.buf, fragsize)) return -EFAULT; - } - printk("*** foo%d ***\n", foo++); - // access_ok doesn't check for NULL... - if(!access_ok(VERIFY_READ, kxfer.buf, swlen)) - { - printk( "i2o_config: Cannot read sw buffer\n"); - return -EFAULT; - } - printk("*** foo%d ***\n", foo++); - c = i2o_find_controller(kxfer.iop); if(!c) return -ENXIO; - printk("*** foo%d ***\n", foo++); + + buffer=kmalloc(fragsize, GFP_KERNEL); + if (buffer==NULL) + { + i2o_unlock_controller(c); + return -ENOMEM; + } + __copy_from_user(buffer, kxfer.buf, fragsize); msg[0]= NINE_WORD_MSG_SIZE | SGL_OFFSET_7; msg[1]= I2O_CMD_SW_DOWNLOAD<<24 | HOST_TID<<12 | ADAPTER_TID; msg[2]= (u32)cfg_handler.context; msg[3]= 0; - msg[4]= ((u32)kxfer.flags)<<24|((u32)kxfer.sw_type)<<16|((u32)maxfrag)<<8|((u32)curfrag); + msg[4]= (((u32)kxfer.flags)<<24) | (((u32)kxfer.sw_type)<<16) | + (((u32)maxfrag)<<8) | (((u32)curfrag)); msg[5]= swlen; msg[6]= kxfer.sw_id; - msg[7]= (0xD0000000 | 8192); + msg[7]= (0xD0000000 | fragsize); msg[8]= virt_to_phys(buffer); - printk("*** foo%d ***\n", foo++); +// printk("i2o_config: swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); + status = i2o_post_wait(c, msg, sizeof(msg), 60); - // - // Loop through all fragments but last and transfer them... - // We already checked memory, so from now we assume it's all good - // - for(curfrag = 0; curfrag < maxfrag-1; curfrag++) - { - printk("Transfering fragment %d\n", curfrag); - - msg[4] |= (u32)curfrag; - - __copy_from_user(buffer, kxfer.buf, 8192); - swxfer += 8192; - - // 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, msg, sizeof(msg), 60); - if (token) // Something very wrong - { - i2o_unlock_controller(c); - printk("Timeout downloading software"); - return -ETIMEDOUT; - } - - __put_user(curfrag, kxfer.curfrag); - } - - // Last frag is special case since it's not exactly 8K - diff = swlen - swxfer; - msg[4] |= (u32)maxfrag; - msg[7] = (0xD0000000 | diff); - __copy_from_user(buffer, kxfer.buf, 8192); - token = i2o_post_wait(c, msg, sizeof(msg), 60); - if(token) // Something very wrong + i2o_unlock_controller(c); + kfree(buffer); + + if (status != I2O_POST_WAIT_OK) { - i2o_unlock_controller(c); - printk("Timeout downloading software"); + // it fails if you try and send frags out of order + // and for some yet unknown reasons too + printk("i2o_config: swdl failed, DetailedStatus = %d\n", status); return -ETIMEDOUT; } - __put_user(curfrag, kxfer.curfrag); - i2o_unlock_controller(c); return 0; } -/* To be written */ int ioctl_swul(unsigned long arg) { - return -EINVAL; + struct i2o_sw_xfer kxfer; + struct i2o_sw_xfer *pxfer = (struct i2o_sw_xfer *)arg; + unsigned char maxfrag = 0, curfrag = 1; + unsigned char *buffer; + u32 msg[9]; + unsigned int status = 0, swlen = 0, fragsize = 8192; + struct i2o_controller *c; + + if(copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer))) + return -EFAULT; + + if(get_user(swlen, kxfer.swlen) < 0) + return -EFAULT; + + if(get_user(maxfrag, kxfer.maxfrag) < 0) + return -EFAULT; + + if(get_user(curfrag, kxfer.curfrag) < 0) + return -EFAULT; + + if(curfrag==maxfrag) fragsize = swlen-(maxfrag-1)*8192; + + if(!kxfer.buf || !access_ok(VERIFY_WRITE, kxfer.buf, fragsize)) + return -EFAULT; + + c = i2o_find_controller(kxfer.iop); + if(!c) + return -ENXIO; + + buffer=kmalloc(fragsize, GFP_KERNEL); + if (buffer==NULL) + { + i2o_unlock_controller(c); + return -ENOMEM; + } + + msg[0]= NINE_WORD_MSG_SIZE | SGL_OFFSET_7; + msg[1]= I2O_CMD_SW_UPLOAD<<24 | HOST_TID<<12 | ADAPTER_TID; + msg[2]= (u32)cfg_handler.context; + msg[3]= 0; + msg[4]= (u32)kxfer.flags<<24|(u32)kxfer.sw_type<<16|(u32)maxfrag<<8|(u32)curfrag; + msg[5]= swlen; + msg[6]= kxfer.sw_id; + msg[7]= (0xD0000000 | fragsize); + msg[8]= virt_to_bus(buffer); + +// printk("i2o_config: swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize); + status = i2o_post_wait(c, msg, sizeof(msg), 60); + i2o_unlock_controller(c); + + if (status != I2O_POST_WAIT_OK) + { + kfree(buffer); + printk("i2o_config: swul failed, DetailedStatus = %d\n", status); + return -ETIMEDOUT; + } + + __copy_to_user(kxfer.buf, buffer, fragsize); + kfree(buffer); + + return 0; } -/* To be written */ int ioctl_swdel(unsigned long arg) { - return -EINVAL; + struct i2o_controller *c; + struct i2o_sw_xfer kxfer, *pxfer = (struct i2o_sw_xfer *)arg; + u32 msg[7]; + unsigned int swlen; + int token; + + if (copy_from_user(&kxfer, pxfer, sizeof(struct i2o_sw_xfer))) + return -EFAULT; + + if (get_user(swlen, kxfer.swlen) < 0) + return -EFAULT; + + c = i2o_find_controller(kxfer.iop); + if (!c) + return -ENXIO; + + msg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0; + msg[1] = I2O_CMD_SW_REMOVE<<24 | HOST_TID<<12 | ADAPTER_TID; + msg[2] = (u32)i2o_cfg_context; + msg[3] = 0; + msg[4] = (u32)kxfer.flags<<24 | (u32)kxfer.sw_type<<16; + msg[5] = swlen; + msg[6] = kxfer.sw_id; + + token = i2o_post_wait(c, msg, sizeof(msg), 10); + i2o_unlock_controller(c); + + if (token != I2O_POST_WAIT_OK) + { + printk("i2o_config: swdel failed, DetailedStatus = %d\n", token); + return -ETIMEDOUT; + } + + return 0; } int ioctl_validate(unsigned long arg) @@ -591,7 +629,7 @@ token = i2o_post_wait(c, msg, sizeof(msg), 10); i2o_unlock_controller(c); - if (token) + if (token != I2O_POST_WAIT_OK) { printk("Can't validate configuration, ErrorStatus = %d\n", token); @@ -644,7 +682,7 @@ int __init i2o_config_init(void) #endif { - printk(KERN_INFO "i2o configuration manager v 0.02\n"); + printk(KERN_INFO "i2o configuration manager v 0.03\n"); if((page_buf = kmalloc(4096, GFP_KERNEL))==NULL) { diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_core.c linux/drivers/i2o/i2o_core.c --- v2.3.26/linux/drivers/i2o/i2o_core.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/i2o/i2o_core.c Wed Nov 10 09:52:18 1999 @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -927,7 +928,7 @@ u32 *p; struct i2o_device *d; char str[22]; - pi2o_lct lct = c->lct; + i2o_lct *lct = c->lct; max = lct->table_size; @@ -1168,6 +1169,9 @@ /* Wait for a reply */ time=jiffies; + + /* DPT driver claims they need this */ + mdelay(5); #ifdef DRIVERDEBUG printk(KERN_INFO "Reset posted, waiting...\n"); @@ -1192,7 +1196,7 @@ { /* * Once the reset is sent, the IOP goes into the INIT state - * which is inditerminate. We need to wait until the IOP + * which is indeterminate. 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 @@ -1230,6 +1234,7 @@ u32 m; u32 *msg; u8 *status_block; + int i; #ifdef DRIVERDEBUG printk(KERN_INFO "Getting status block for iop%d\n", c->unit); @@ -1238,7 +1243,7 @@ kfree(c->status_block); c->status_block = - (pi2o_status_block)kmalloc(sizeof(i2o_status_block),GFP_KERNEL); + (i2o_status_block *)kmalloc(sizeof(i2o_status_block),GFP_KERNEL); if(c->status_block == NULL) { #ifdef DRIVERDEBUG @@ -1248,45 +1253,53 @@ } status_block = (u8*)c->status_block; + + for(i=0;i<5;i++) + { + m=i2o_wait_message(c, "StatusGet"); + if(m==0xFFFFFFFF) + return -ETIMEDOUT; + + memset(status_block, 0, sizeof(i2o_status_block)); + + msg=(u32 *)(c->mem_offset+m); - m=i2o_wait_message(c, "StatusGet"); - if(m==0xFFFFFFFF) - return -ETIMEDOUT; - - msg=(u32 *)(c->mem_offset+m); - - msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID; - msg[2]=core_context; - msg[3]=0; - msg[4]=0; - msg[5]=0; - msg[6]=virt_to_phys(c->status_block); - msg[7]=0; /* 64bit host FIXME */ - msg[8]=88; - - i2o_post_message(c,m); + __raw_writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]); + __raw_writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, &msg[1]); + __raw_writel(0, &msg[2]); + __raw_writel(0, &msg[3]); + __raw_writel(0, &msg[4]); + __raw_writel(0, &msg[5]); + __raw_writel(virt_to_bus(c->status_block), &msg[6]); + __raw_writel(0, &msg[7]); /* 64bit host FIXME */ + __raw_writel(sizeof(i2o_status_block), &msg[8]); + + printk("SB is %d bytes.\n", sizeof(i2o_status_block)); - /* Wait for a reply */ - time=jiffies; + i2o_post_message(c,m); + + /* DPT work around */ + mdelay(5); - while(status_block[87]!=0xFF) - { - if((jiffies-time)>=5*HZ) + /* Wait for a reply */ + time=jiffies; + + while((jiffies-time)<=HZ) { + if(status_block[87]!=0) + { + /* Ok the reply has arrived. Fill in the important stuff */ + c->inbound_size = (status_block[12]|(status_block[13]<<8))*4; + return 0; + } + schedule(); + barrier(); + } #ifdef DRIVERDEBUG - printk(KERN_ERR "IOP get status timeout.\n"); + printk(KERN_ERR "IOP get status timeout.\n"); #endif - return -ETIMEDOUT; - } - schedule(); - barrier(); } - - /* Ok the reply has arrived. Fill in the important stuff */ - c->inbound_size = (status_block[12]|(status_block[13]<<8))*4; - - return 0; + return 0;//-ETIMEDOUT; } @@ -1354,7 +1367,7 @@ */ static void __init i2o_sys_init() { - struct i2o_controller *iop; + struct i2o_controller *iop, *niop; int ret; u32 m; @@ -1362,18 +1375,30 @@ 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) + for(iop = i2o_controller_chain; iop; iop = niop) { + niop = iop->next; #ifdef DRIVERDEBUG printk(KERN_INFO "Getting initial status for iop%d\n", iop->unit); #endif - i2o_status_get(iop); + if(i2o_status_get(iop)<0) + { + printk("Unable to obtain status of IOP, attempting a reset.\n"); + i2o_reset_controller(iop); + if(i2o_status_get(iop)<0) + { + printk("IOP not responding.\n"); + i2o_delete_controller(iop); + continue; + } + } 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); + continue; } if(iop->status_block->iop_state == ADAPTER_STATE_HOLD || @@ -1384,7 +1409,7 @@ int msg[256]; #ifdef DRIVERDEBUG - printk(KERN_INFO "iop%d already running...trying to reboot", + printk(KERN_INFO "iop%d already running...trying to reboot\n", iop->unit); #endif i2o_init_outbound_q(iop); @@ -1396,6 +1421,7 @@ { printk(KERN_CRIT "Failed to initialize iop%d\n", iop->unit); i2o_delete_controller(iop); + continue; } } } @@ -1403,9 +1429,11 @@ /* * Now init the outbound queue for each one. */ - for(iop = i2o_controller_chain; iop; iop = iop->next) + for(iop = i2o_controller_chain; iop; iop = niop) { int i; + + niop = iop->next; if((ret=i2o_init_outbound_q(iop))) { @@ -1413,6 +1441,7 @@ "IOP%d initialization failed: Could not initialize outbound q\n", iop->unit); i2o_delete_controller(iop); + continue; } iop->page_frame = kmalloc(MSG_POOL_SIZE, GFP_KERNEL); @@ -1438,18 +1467,20 @@ /* * OK..parse the HRT */ - for(iop = i2o_controller_chain; iop; iop = iop->next) + for(iop = i2o_controller_chain; iop; iop = niop) { + niop = iop->next; if(i2o_hrt_get(iop)) { printk(KERN_CRIT "iop%d: Could not get HRT!\n", iop->unit); i2o_delete_controller(iop); - break; + continue; } if(i2o_parse_hrt(iop)) { printk(KERN_CRIT "iop%d: Could not parse HRT!\n", iop->unit); i2o_delete_controller(iop); + continue; } } @@ -1466,15 +1497,17 @@ return; } - for(iop = i2o_controller_chain; iop; iop = iop->next) + for(iop = i2o_controller_chain; iop; iop = niop) #ifdef DRIVERDEBUG { + niop = iop->next; printk(KERN_INFO "Sending system table to iop%d\n", iop->unit); #endif if(i2o_systab_send(iop)) { printk(KERN_CRIT "iop%d: Error sending system table\n", iop->unit); i2o_delete_controller(iop); + continue; } #ifdef DRIVERDEBUG } @@ -1483,8 +1516,9 @@ /* * Enable */ - for(iop = i2o_controller_chain; iop; iop = iop->next) + for(iop = i2o_controller_chain; iop; iop = niop) { + niop = iop->next; #ifdef DRIVERDEBUG printk(KERN_INFO "Enableing iop%d\n", iop->unit); #endif @@ -1492,14 +1526,16 @@ { printk(KERN_ERR "Could not enable iop%d\n", iop->unit); i2o_delete_controller(iop); + continue; } } /* * OK..one last thing and we're ready to go! */ - for(iop = i2o_controller_chain; iop; iop = iop->next) + for(iop = i2o_controller_chain; iop; iop = niop) { + niop = iop->next; #ifdef DRIVERDEBUG printk(KERN_INFO "Getting LCT for iop%d\n", iop->unit); #endif @@ -1507,6 +1543,7 @@ { printk(KERN_ERR "Could not get LCT from iop%d\n", iop->unit); i2o_delete_controller(iop); + continue; } else i2o_parse_lct(iop); @@ -1667,7 +1704,7 @@ msg[4]= 4096; /* Host page frame size */ msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size and Initcode */ msg[6]= 0xD0000004; /* Simple SG LE, EOB */ - msg[7]= virt_to_phys(workspace); + msg[7]= virt_to_bus(workspace); *((u32 *)workspace)=0; /* @@ -1685,7 +1722,6 @@ { printk(KERN_ERR "i2o/iop%d: IOP outbound initialise failed.\n", c->unit); - kfree(workspace); return -ETIMEDOUT; } schedule(); @@ -2419,7 +2455,7 @@ case I2O_CMD_UTIL_DEVICE_RELEASE: printk("UTIL_DEVICE_RELEASE, "); break; - case I2O_CMD_UTIL_ACK: + case I2O_CMD_UTIL_EVT_ACK: printk("UTIL_EVENT_ACKNOWLEDGE, "); break; case I2O_CMD_UTIL_EVT_REGISTER: diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_lan.c linux/drivers/i2o/i2o_lan.c --- v2.3.26/linux/drivers/i2o/i2o_lan.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/i2o/i2o_lan.c Wed Nov 10 09:52:18 1999 @@ -1,7 +1,7 @@ /* * linux/drivers/i2o/i2o_lan.c * - * I2O LAN CLASS OSM Prototyping, September 17th 1999 + * I2O LAN CLASS OSM Prototyping, November 8th 1999 * * (C) Copyright 1999 University of Helsinki, * Department of Computer Science @@ -11,7 +11,7 @@ * 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. + * 2 of the License, or (at your option) any later version. * * Authors: Auvo Häkkinen * Juha Sievänen @@ -20,9 +20,7 @@ * Tested: in FDDI environment (using SysKonnect's DDM) * in Ethernet environment (using Intel 82558 DDM proto) * - * TODO: batch mode networking - * - we've not been able to test batch replies and - * batch receives + * TODO: batch mode sends * error checking / timeouts * code / test for other LAN classes */ @@ -39,6 +37,7 @@ #include #include #include +#include #include #include @@ -46,68 +45,65 @@ #include #include "i2o_lan.h" -//#define DRIVERDEBUG +#define DRIVERDEBUG #ifdef DRIVERDEBUG #define dprintk(s, args...) printk(s, ## args) #else #define dprintk(s, args...) #endif -#define MAX_LAN_CARDS 4 +/* Module params */ + +static u32 bucketpost = I2O_BUCKET_COUNT; +static u32 bucketthresh = I2O_BUCKET_THRESH; +static u32 rx_copybreak = 200; + +#define MAX_LAN_CARDS 16 static struct net_device *i2o_landevs[MAX_LAN_CARDS+1]; static int unit = -1; /* device unit number */ struct i2o_lan_local { u8 unit; struct i2o_device *i2o_dev; - int reply_flag; /* needed by scalar/table queries */ - struct fddi_statistics stats; /* see also struct net_device_stats */ + struct fddi_statistics stats; /* see also struct net_device_stats */ unsigned short (*type_trans)(struct sk_buff *, struct net_device *); - /* - * Due to way that interrupts can pile up, we need to keep track - * of buckets ourselves. Otherwise we'll end up flooding - * the DDM with buckets. - */ - u32 bucket_count; - - /* - * Keep track of no. of outstanding TXes - */ - u32 tx_count; - u32 max_tx; - u32 tx_full; - - spinlock_t lock; + u32 bucket_count; /* nbr of buckets sent to DDM */ + u32 tx_count; /* nbr of outstanding TXes */ + u32 max_tx; /* DDM's Tx queue len */ + spinlock_t lock; }; -/* function prototypes */ +static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, + struct i2o_message *m); +static void i2o_lan_event_reply(struct net_device *dev, u32 *msg); static int i2o_lan_receive_post(struct net_device *dev, u32 count); static int i2o_lan_receive_post_reply(struct net_device *dev, u32 *msg); static void i2o_lan_release_buckets(struct net_device *dev, u32 *msg); -/* - * Module params - */ -static u32 bucketpost = I2O_BUCKET_COUNT; -static u32 bucketthresh = I2O_BUCKET_THRESH; -static u32 rx_copybreak = 200; +static struct i2o_handler i2o_lan_handler = { + i2o_lan_reply, + "I2O Lan OSM", + 0, // context + I2O_CLASS_LAN +}; +static int lan_context; -static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, + +static void i2o_lan_reply(struct i2o_handler *h, struct i2o_controller *iop, struct i2o_message *m) -{ +{ u32 *msg = (u32 *)m; u8 unit = (u8)(msg[2]>>16); // InitiatorContext struct net_device *dev = i2o_landevs[unit]; - if (msg[0] & (1<<13)) // Fail bit is set - { - printk(KERN_ERR "IOP failed to process the msg:\n"); + if (msg[0] & (1<<13)) { // Fail bit is set + printk(KERN_ERR "%s: IOP failed to process the msg:\n",dev->name); printk(KERN_ERR " Cmd = 0x%02X, InitiatorTid = %d, TargetTid = %d\n", (msg[1] >> 24) & 0xFF, (msg[1] >> 12) & 0xFFF, msg[1] & 0xFFF); printk(KERN_ERR " FailureCode = 0x%02X\n Severity = 0x%02X\n " "LowestVersion = 0x%02X\n HighestVersion = 0x%02X\n", - msg[4] >> 24, (msg[4] >> 16) & 0xFF, + msg[4] >> 24, (msg[4] >> 16) & 0xFF, (msg[4] >> 8) & 0xFF, msg[4] & 0xFF); printk(KERN_ERR " FailingHostUnit = 0x%04X\n FailingIOP = 0x%03X\n", msg[5] >> 16, msg[5] & 0xFFF); @@ -115,23 +111,21 @@ } #ifndef DRIVERDEBUG - if (msg[4] >> 24) /* ReqStatus != SUCCESS */ + if (msg[4] >> 24) /* ReqStatus != SUCCESS */ #endif i2o_report_status(KERN_INFO, dev->name, msg); - + switch (msg[1] >> 24) { case LAN_RECEIVE_POST: { - if (dev->start) - { - if(!(msg[4]>>24)) - { + if (dev->start) { + if(!(msg[4]>>24)) { i2o_lan_receive_post_reply(dev,msg); break; } // Something VERY wrong if this is happening - printk( KERN_WARNING "i2olan: Device %s rejected bucket post\n", dev->name); + printk( KERN_WARNING "i2olan: Device %s rejected bucket post.\n", dev->name); } // Getting unused buckets back @@ -146,15 +140,16 @@ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; u8 trl_count = msg[3] & 0x000000FF; - do { // The HDM has handled the outgoing packet + while (trl_count) { + // The HDM has handled the outgoing packet dev_kfree_skb((struct sk_buff *)msg[4 + trl_count]); - dprintk(KERN_INFO "%s: Request skb freed (trl_count=%d).\n", + printk(KERN_INFO "%s: Request skb freed (trl_count=%d).\n", dev->name,trl_count); priv->tx_count--; - } while (--trl_count); + trl_count--; + } - if(dev->tbusy) - { + if (dev->tbusy) { clear_bit(0,(void*)&dev->tbusy); mark_bh(NET_BH); /* inform upper layers */ } @@ -162,45 +157,135 @@ break; } - default: - if (msg[2] & 0x80000000) // reply to a UtilParamsGet/Set - { - int *flag = (int *)msg[3]; // flag for i2o_post_wait - if (msg[4] >> 24) // ReqStatus != SUCCESS - *flag = -(msg[4] & 0xFFFF); // DetailedStatus - else - *flag = I2O_POST_WAIT_OK; - } + case LAN_RESET: + case LAN_SUSPEND: + break; + + case I2O_CMD_UTIL_EVT_REGISTER: + case I2O_CMD_UTIL_EVT_ACK: + i2o_lan_event_reply(dev, msg); + break; + + default: + printk(KERN_ERR "%s: Sorry, no handler for the reply.\n", dev->name); + i2o_report_status(KERN_INFO, dev->name, msg); } } + +static void i2o_lan_event_reply(struct net_device *dev, u32 *msg) +{ + struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; + struct i2o_device *i2o_dev = priv->i2o_dev; + struct i2o_controller *iop = i2o_dev->controller; + struct i2o_reply { + u8 version_offset; + u8 msg_flags; + u16 msg_size; + u32 tid:12; + u32 initiator:12; + u32 function:8; + u32 initiator_context; + u32 transaction_context; + u32 evt_indicator; + u32 evt_data[(iop->inbound_size - 20) / 4]; /* max */ + } *evt = (struct i2o_reply *)msg; + + int evt_data_len = (evt->msg_size - 5) * 4; /* real */ + + if (evt->function == I2O_CMD_UTIL_EVT_REGISTER) { + printk(KERN_INFO "%s: I2O event - ", dev->name); + + switch (evt->evt_indicator) { + case I2O_EVT_IND_STATE_CHANGE: + printk("State chance 0x%08X.\n", + evt->evt_data[0]); + break; + case I2O_EVT_IND_GENERAL_WARNING: + printk("General warning 0x%02X.\n", + evt->evt_data[0]); + break; + case I2O_EVT_IND_CONFIGURATION_FLAG: + printk("Configuration requested.\n"); + break; + case I2O_EVT_IND_LOCK_RELEASE: + printk("Lock released.\n"); + break; + case I2O_EVT_IND_CAPABILITY_CHANGE: + printk("Capability change 0x%02X.\n", + evt->evt_data[0]); + break; + case I2O_EVT_IND_DEVICE_RESET: + printk("Device reset.\n"); + break; + case I2O_EVT_IND_EVT_MASK_MODIFIED: + printk("Event mask modified, 0x%08X.\n", + evt->evt_data[0]); + break; + case I2O_EVT_IND_FIELD_MODIFIED: { + u16 *work16 = (u16 *)evt->evt_data; + printk("Group 0x%04X, field %d changed.\n", + work16[0], work16[1]); + break; + } + case I2O_EVT_IND_VENDOR_EVT: { + int i; + printk("Vendor event:\n"); + for (i = 0; i < evt_data_len / 4; i++) + printk(" 0x%08X\n", evt->evt_data[i]); + break; + } + case I2O_EVT_IND_DEVICE_STATE: + printk("Device state changed 0x%08X.\n", + evt->evt_data[0]); + break; + case I2O_LAN_EVT_LINK_DOWN: + printk("Link to the physical device is lost.\n"); + break; + case I2O_LAN_EVT_LINK_UP: + printk("Link to the physical device is (re)established.\n"); + break; + case I2O_LAN_EVT_MEDIA_CHANGE: + printk("Media change.\n"); + break; + default: + printk("Event Indicator = 0x%08X.\n", + evt->evt_indicator); + } + + /* + * EventAck necessary only for events that cause the device + * to syncronize with the user + * + *if (i2o_event_ack(iop, i2o_dev->lct_data->tid, + * priv->unit << 16 | lan_context, + * evt->evt_indicator, + * evt->evt_data, evt_data_len) < 0) + * printk("%s: Event Acknowledge timeout.\n", dev->name); + */ + } + + /* else evt->function == I2O_CMD_UTIL_EVT_ACK) */ + /* Do we need to do something here too? */ +} + + void i2o_lan_release_buckets(struct net_device *dev, u32 *msg) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; u8 trl_count = (u8)(msg[3] & 0x000000FF); u32 *pskb = &msg[6]; - - while (trl_count) - { - dprintk("%s: Releasing unused sk_buff %p\n",dev->name, + + while (trl_count) { + dprintk("%s: Releasing unused sk_buff %p.\n",dev->name, (struct sk_buff*)(*pskb)); - dev_kfree_skb((struct sk_buff*)(*pskb)); + dev_kfree_skb((struct sk_buff*)(*pskb)); pskb++; priv->bucket_count--; trl_count--; } } -static struct i2o_handler i2o_lan_handler = -{ - i2o_lan_reply, - "I2O Lan OSM", - 0, // context - I2O_CLASS_LAN -}; -static int lan_context; - - static int i2o_lan_receive_post_reply(struct net_device *dev, u32 *msg) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; @@ -210,25 +295,21 @@ u8 trl_count = msg[3] & 0x000000FF; struct sk_buff *skb, *newskb; -static int n_calls = 0; -n_calls++; - #if 0 dprintk(KERN_INFO "TrlFlags = 0x%02X, TrlElementSize = %d, TrlCount = %d\n" - "msgsize = %d, buckets_remaining = %d\n", + "msgsize = %d, buckets_remaining = %d\n", msg[3]>>24, msg[3]&0x0000FF00, trl_count, msg[0]>>16, msg[5]); #endif - - while (trl_count--) - { + while (trl_count--) { skb = (struct sk_buff *)(bucket->context); packet = (struct i2o_packet_info *)bucket->packet_info; priv->bucket_count--; +#if 0 dprintk(KERN_INFO "Buckets_remaining = %d, bucket_count = %d, trl_count = %d\n", msg[5], priv->bucket_count, trl_count); -#if 0 - dprintk(KERN)INFO "flags = 0x%02X, offset = 0x%06X, status = 0x%02X, length = %d\n", + + dprintk(KERN_INFO "flags = 0x%02X, offset = 0x%06X, status = 0x%02X, length = %d\n", packet->flags, packet->offset, packet->status, packet->len); #endif if (packet->len < rx_copybreak) { @@ -241,15 +322,15 @@ newskb->protocol = priv->type_trans(newskb, dev); netif_rx(newskb); - dev_kfree_skb(skb); // FIXME: reuse this skb? + dev_kfree_skb(skb); // FIXME: reuse this skb? } else { - printk("I2OLAN-%s: Can't allocate skb.\n", dev->name); + printk("%s: Can't allocate skb.\n", dev->name); return -ENOMEM; } } else { skb_put(skb,packet->len); - skb->dev = dev; + skb->dev = dev; skb->protocol = priv->type_trans(skb, dev); netif_rx(skb); @@ -260,20 +341,17 @@ bucket++; // to next Packet Descriptor Block } - if (priv->bucket_count < bucketpost - bucketthresh) - i2o_lan_receive_post(dev, bucketpost - priv->bucket_count); - if ((msg[4] & 0x000000FF) == I2O_LAN_DSC_BUCKET_OVERRUN) - { - printk(KERN_INFO "%s: DDM out of buckets (count = %d)! " - "Number of posts = %d\n", dev->name, msg[5], n_calls); - n_calls = 0; - } + printk(KERN_INFO "%s: DDM out of buckets (count = %d)!\n", + dev->name, msg[5]); + + if (priv->bucket_count <= bucketpost - bucketthresh) + i2o_lan_receive_post(dev, bucketpost - priv->bucket_count); return 0; } -/* +/* * i2o_lan_receive_post(): Post buckets to receive packets. */ static int i2o_lan_receive_post(struct net_device *dev, u32 count) @@ -289,14 +367,12 @@ int n_elems = (iop->inbound_size - 16 ) / 12; /* msg header + SGLs */ u32 total = 0; int i; - - while (total < count) - { + + while (total < count) { m = I2O_POST_READ32(iop); if (m == 0xFFFFFFFF) return -ETIMEDOUT; - msg = bus_to_virt(iop->mem_offset + m); - + msg = (u32 *)(iop->mem_offset + m); bucket_count = (total + n_elems < count) ? n_elems : count - total; @@ -306,8 +382,7 @@ msg[2] = priv->unit << 16 | lan_context; // InitiatorContext msg[3] = bucket_count; // BucketCount - for (i = 0; i < bucket_count; i++) - { + for (i = 0; i < bucket_count; i++) { skb = dev_alloc_skb(bucket_len + 2); if (skb == NULL) return -ENOMEM; @@ -331,11 +406,11 @@ return 0; } -/* - * i2o_lan_reset(): Reset the LAN adapter into the operational state and +/* + * i2o_lan_reset(): Reset the LAN adapter into the operational state and * restore it to full operation. */ -static int i2o_lan_reset(struct net_device *dev) +static int i2o_lan_reset(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; @@ -351,12 +426,12 @@ if (i2o_post_this(iop, msg, sizeof(msg)) < 0) return -ETIMEDOUT; - return 0; + return 0; } -/* +/* * i2o_lan_suspend(): Put LAN adapter into a safe, non-active state. - * Reply to any LAN class message with status error_no_data_transfer + * Reply to any LAN class message with status error_no_data_transfer * / suspended. */ static int i2o_lan_suspend(struct net_device *dev) @@ -366,14 +441,14 @@ struct i2o_controller *iop = i2o_dev->controller; u32 msg[5]; - dprintk( "%s: LAN SUSPEND MESSAGE\n", dev->name ); + 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->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, msg, sizeof(msg))< 0) + if (i2o_post_this(iop, msg, sizeof(msg)) < 0) return -ETIMEDOUT; return 0; @@ -385,9 +460,9 @@ static void i2o_set_batch_mode(struct net_device *dev) { -/* +/* * NOTE: we have not been able to test batch mode - * since HDMs we have, don't implement it + * since HDMs we have, don't implement it */ struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; @@ -400,11 +475,13 @@ // enable batch mode, toggle automatically val = 0x00000000; // val = 0x00000001; // turn off batch mode - 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 + if (i2o_set_scalar(iop, i2o_dev->lct_data->tid, 0x0003, 0, &val, sizeof(val)) <0) + printk(KERN_WARNING "%s: Unable to enter I2O LAN batch mode.\n", + dev->name); + else dprintk(KERN_INFO "%s: I2O LAN batch mode enabled.\n",dev->name); // dprintk(KERN_INFO "%s: I2O LAN batch mode disabled.\n",dev->name); + /* * When PacketOrphanlimit is same as the maximum packet length, * the packets will never be split into two separate buckets @@ -413,31 +490,39 @@ /* set LAN_OPERATION attributes */ val = dev->mtu + dev->hard_header_len; // PacketOrphanLimit - if (i2o_set_scalar(iop, i2o_dev->lct_data->tid, 0x0004, 2, &val, 4)) - printk(KERN_WARNING "i2o_lan: Unable to set PacketOrphanLimit.\n"); + if (i2o_set_scalar(iop, i2o_dev->lct_data->tid, 0x0004, 2, &val, sizeof(val)) < 0) + printk(KERN_WARNING "%s: Unable to set PacketOrphanLimit.\n", + dev->name); else - dprintk(KERN_INFO "%s: PacketOrphanLimit set to %d\n", + dprintk(KERN_INFO "%s: PacketOrphanLimit set to %d.\n", dev->name,val); - + return; } -/* - * i2o_lan_open(): Open the device to send/receive packets via +/* + * i2o_lan_open(): Open the device to send/receive packets via * the network device. */ static int i2o_lan_open(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; - struct i2o_device *i2o_dev = priv->i2o_dev; + struct i2o_device *i2o_dev = priv->i2o_dev; + struct i2o_controller *iop = i2o_dev->controller; + u32 evt_mask = 0xFFC00007; // All generic events, all lan evenst - if(i2o_claim_device(i2o_dev, &i2o_lan_handler, I2O_CLAIM_PRIMARY)) - { + if (i2o_claim_device(i2o_dev, &i2o_lan_handler, I2O_CLAIM_PRIMARY)) { 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->lct_data->tid); - + dprintk(KERN_INFO "%s: I2O LAN device claimed (tid=%d).\n", + dev->name, i2o_dev->lct_data->tid); +#if 0 + if (i2o_event_register(iop, i2o_dev->lct_data->tid, + priv->unit << 16 | lan_context, evt_mask) < 0) + printk(KERN_WARNING "%s: Unable to set the event mask.\n", + dev->name); +#endif i2o_lan_reset(dev); dev->tbusy = 0; @@ -453,19 +538,26 @@ /* * i2o_lan_close(): End the transfering. - */ + */ static int i2o_lan_close(struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; +//#if 0 + struct i2o_controller *iop = i2o_dev->controller; + if (i2o_event_register(iop, i2o_dev->lct_data->tid, + priv->unit << 16 | lan_context, 0) < 0) + printk(KERN_WARNING "%s: Unable to clear the event mask.\n", + dev->name); +//#endif dev->tbusy = 1; dev->start = 0; i2o_lan_suspend(dev); - if(i2o_release_device(i2o_dev, &i2o_lan_handler, I2O_CLAIM_PRIMARY)) + 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->lct_data->tid); + "(tid=%d).\n", dev->name, i2o_dev->lct_data->tid); MOD_DEC_USE_COUNT; @@ -473,9 +565,9 @@ } #if 0 -/* +/* * i2o_lan_sdu_send(): Send a packet, MAC header added by the HDM. - * Must be supported by Fibre Channel, optional for Ethernet/802.3, + * Must be supported by Fibre Channel, optional for Ethernet/802.3, * Token Ring, FDDI */ static int i2o_lan_sdu_send(struct sk_buff *skb, struct net_device *dev) @@ -484,12 +576,12 @@ } #endif -/* +/* * i2o_lan_packet_send(): Send a packet as is, including the MAC header. - * - * Must be supported by Ethernet/802.3, Token Ring, FDDI, optional for + * + * Must be supported by Ethernet/802.3, Token Ring, FDDI, optional for * Fibre Channel - */ + */ static int i2o_lan_packet_send(struct sk_buff *skb, struct net_device *dev) { struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; @@ -498,14 +590,13 @@ u32 m, *msg; u32 flags = 0; - /* + /* * Keep interrupt from changing dev->tbusy from underneath us * (Do we really need to do this?) */ spin_lock_irqsave(&priv->lock, flags); - if(test_and_set_bit(0,(void*)&dev->tbusy) != 0) - { + if(test_and_set_bit(0,(void*)&dev->tbusy) != 0) { spin_unlock_irqrestore(&priv->lock, flags); return 1; } @@ -515,9 +606,19 @@ spin_unlock_irqrestore(&priv->lock, flags); dev_kfree_skb(skb); return -ETIMEDOUT; - } - msg = bus_to_virt(iop->mem_offset + m); - + } + msg = (u32 *)(iop->mem_offset + m); + +#if 0 + __raw_writel(SEVEN_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4,&msg[0]); + __raw_writel(LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data->tid, &msg[1]); + __raw_writel(priv->unit << 16 | lan_context, &msg[2]); // InitiatorContext + __raw_writel(1 << 4, &msg[3]); // TransmitControlWord + __raw_writel(0xD5000000 | skb->len, &msg[4]); // MAC hdr included + __raw_writel((u32)skb, &msg[5]); // TransactionContext + __raw_writel(virt_to_bus(skb->data),&msg[6]); +#endif + msg[0] = SEVEN_WORD_MSG_SIZE | 1<<12 | SGL_OFFSET_4; msg[1] = LAN_PACKET_SEND<<24 | HOST_TID<<12 | i2o_dev->lct_data->tid; msg[2] = priv->unit << 16 | lan_context; // IntiatorContext @@ -552,8 +653,8 @@ u64 val64[16]; u64 supported_group[4] = { 0, 0, 0, 0 }; - if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0100, -1, - val64, sizeof(val64)) < 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); @@ -566,13 +667,13 @@ priv->stats.rx_dropped = val64[6]; } - if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0180, -1, + 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->lct_data->tid, 0x0183, -1, - val64, sizeof(val64) ) < 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); @@ -582,11 +683,10 @@ } } - if (i2o_dev->lct_data->sub_class == I2O_LAN_ETHERNET) - { + if (i2o_dev->lct_data->sub_class == I2O_LAN_ETHERNET) { u64 supported_stats = 0; - if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0200, -1, + 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 { @@ -596,14 +696,15 @@ priv->stats.tx_carrier_errors = val64[6]; } - 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 (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0280, -1, + &supported_stats, sizeof(supported_stats)) < 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->lct_data->tid, 0x0281, -1, + 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); +; +// 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); if (supported_stats & 0x1) @@ -616,13 +717,12 @@ } #ifdef CONFIG_TR - if (i2o_dev->lct_data->sub_class == I2O_LAN_TR) - { - if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0300, -1, + if (i2o_dev->lct_data->sub_class == I2O_LAN_TR) { + 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 = + struct tr_statistics *stats = (struct tr_statistics *)&priv->stats; // dprintk("%s: LAN_802_5_HISTORICAL_STATS queried.\n",dev->name); @@ -642,9 +742,8 @@ #endif #ifdef CONFIG_FDDI - if (i2o_dev->lct_data->sub_class == I2O_LAN_FDDI) - { - if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0400, -1, + if (i2o_dev->lct_data->sub_class == I2O_LAN_FDDI) { + 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 { @@ -666,90 +765,97 @@ return (struct net_device_stats *)&priv->stats; } - + /* - * i2o_lan_set_multicast_list(): Enable a network device to receive packets - * not send to the protocol address. + * i2o_lan_set_mc_list(): Enable a network device to receive packets + * not send to the protocol address. */ -static void i2o_lan_set_multicast_list(struct net_device *dev) + +static void i2o_lan_set_mc_list(struct net_device *dev) { - struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; - struct i2o_device *i2o_dev = priv->i2o_dev; - struct i2o_controller *iop = i2o_dev->controller; - u32 filter_mask; - u32 work32[64]; + struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; + struct i2o_device *i2o_dev = priv->i2o_dev; + struct i2o_controller *iop = i2o_dev->controller; + u32 filter_mask; + u32 max_size_mc_table; + u32 mc_addr_group[64]; + + if (i2o_query_scalar(iop, i2o_dev->lct_data->tid, 0x0001, -1, + &mc_addr_group, sizeof(mc_addr_group)) < 0 ) { + printk(KERN_WARNING "%s: Unable to query LAN_MAC_ADDRESS group.\n", dev->name); + return; + } - dprintk(KERN_INFO "%s: Entered i2o_lan_set_multicast_list().\n", dev->name); + max_size_mc_table = mc_addr_group[8]; -return; + if (dev->flags & IFF_PROMISC) { + filter_mask = 0x00000002; + dprintk(KERN_INFO "%s: Enabling promiscuous mode...\n", dev->name); + } -/* FIXME: Why does the next call kill the interrupt handler? - * The same piece of code works fine in function lan_open(), and in i2o_proc.c - * - * *because its trying to sleep in an irq - this must be async - Alan - */ + else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > max_size_mc_table) { + filter_mask = 0x00000004; + dprintk(KERN_INFO "%s: Enabling all multicast mode...\n", dev->name); + } - 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"); - return; - } - printk(KERN_INFO "capab mask = 0x%08X, filter mask = 0x%08X\n", - work32[7], work32[6]); + else if (dev->mc_count) { + struct dev_mc_list *mc; + u8 mc_table[2 + 8 * dev->mc_count]; // RowCount, Addresses + u64 *work64 = (u64 *)(mc_table + 2); + + filter_mask = 0x00000000; + dprintk(KERN_INFO "%s: Enabling multicast mode...\n", dev->name); + + /* Fill multicast addr table */ + + memset(mc_table, 0, sizeof(mc_table)); + memcpy(mc_table, &dev->mc_count, 2); + for (mc = dev->mc_list; mc ; mc = mc->next, work64++ ) + memcpy(work64, mc->dmi_addr, mc->dmi_addrlen); + + /* Clear old mc table, copy new table to */ - filter_mask = work32[6]; + if (i2o_clear_table(iop, i2o_dev->lct_data->tid, 0x0002) < 0) + printk("%s: Unable to clear LAN_MULTICAST_MAC_ADDRESS table.\n",dev->name); - if (dev->flags & IFF_PROMISC) - { - filter_mask |= 0x00000002; - dprintk(KERN_INFO "i2o_lan: Enabling promiscuous mode...\n"); + if ((i2o_row_add_table(iop, i2o_dev->lct_data->tid, 0x0002, -1, + mc_table, sizeof(mc_table))) < 0) + printk("%s: Unable to set LAN_MULTICAST_MAC_ADDRESS table.\n",dev->name); } - - else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > work32[5]) - { - filter_mask |= 0x00000000; - dprintk(KERN_INFO "i2o_lan: Enabling all multicast mode...\n"); - } - - else if (dev->mc_count) - { - struct dev_mc_list *mclist; - int i; - u8 *work8 = (u8 *)work32; - - dprintk(KERN_INFO "i2o_lan: Enabling multicast mode...\n"); - filter_mask = 0x00000004; - - /* Fill the multicast addresses */ - mclist = dev->mc_list; - - for (i = 0; i < dev->mc_count; i++) - { - memcpy(work8, mclist->dmi_addr, mclist->dmi_addrlen); - work8 += 8; - mclist = mclist->next; - } - - 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->lct_data->tid, 0x0002, -1, - work32, dev->mc_count*8) < 0) - dprintk("%s: Unable to set LAN_MULTICAST_MAC_ADDRESS table.\n",dev->name); - } - - else { - filter_mask |= 0x00000300; // Broadcast, Multicast disabled - dprintk(KERN_INFO "i2o_lan: Enabling unicast mode...\n"); + + else { + filter_mask = 0x00000300; // Broadcast, Multicast disabled + printk(KERN_INFO "%s: Enabling unicast mode...\n",dev->name); } - 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"); + /* Finally copy new FilterMask to */ + + if (i2o_set_scalar(iop, i2o_dev->lct_data->tid, 0x0001, 3, + &filter_mask, sizeof(filter_mask)) <0) + printk(KERN_WARNING "%s: Unable to set MAC FilterMask.\n",dev->name); - return; + return; +} + +/* + * i2o_lan_set_multicast_list(): + * Queue routine i2o_lan_set_mc_list() to be called later. + * Needs to be async. + */ + +static void i2o_lan_set_multicast_list(struct net_device *dev) +{ + struct tq_struct *task; + + task = (struct tq_struct *)kmalloc(sizeof(struct tq_struct), GFP_KERNEL); + if (task == NULL) + return; + + task->next = NULL; + task->sync = 0; + task->routine = (void *)i2o_lan_set_mc_list; + task->data = (void *)dev; + queue_task(task, &tq_scheduler); } struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev) @@ -761,24 +867,21 @@ unsigned short (*type_trans)(struct sk_buff *, struct net_device *); void (*unregister_dev)(struct net_device *dev); - switch (i2o_dev->lct_data->sub_class) - { + 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; unregister_dev = unregister_netdev; break; - #ifdef CONFIG_ANYLAN case I2O_LAN_100VG: - printk(KERN_ERR "i2o_lan: 100base VG not yet supported\n"); + printk(KERN_ERR "i2o_lan: 100base VG not yet supported.\n"); break; #endif - #ifdef CONFIG_TR case I2O_LAN_TR: dev = init_trdev(NULL, sizeof(struct i2o_lan_local)); @@ -800,8 +903,7 @@ dev->priv = (void *)(dev + 1); dev->name = (char *)(dev + 1) + sizeof(struct i2o_lan_local); - if (dev_alloc_name(dev,"fddi%d") < 0) - { + if (dev_alloc_name(dev,"fddi%d") < 0) { printk(KERN_WARNING "i2o_lan: Too many FDDI devices.\n"); kfree(dev); return NULL; @@ -817,13 +919,13 @@ #ifdef CONFIG_FIBRE_CHANNEL case I2O_LAN_FIBRE_CHANNEL: - printk(KERN_INFO "i2o_lan: Fibre Channel not yet supported\n"); + printk(KERN_INFO "i2o_lan: Fibre Channel not yet supported.\n"); break; #endif case I2O_LAN_UNKNOWN: default: - printk(KERN_ERR "i2o_lan: LAN type 0x%08X not supported\n", + printk(KERN_ERR "i2o_lan: LAN type 0x%08X not supported.\n", i2o_dev->lct_data->sub_class); return NULL; } @@ -838,13 +940,12 @@ priv->unit = unit; 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); + 0x0001, 0, &hw_addr, sizeof(hw_addr)) < 0) { + printk(KERN_ERR "%s: Unable to query hardware address.\n", dev->name); unit--; unregister_dev(dev); kfree(dev); - return NULL; + return NULL; } dprintk("%s: hwaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", @@ -854,18 +955,18 @@ dev->addr_len = 6; memcpy(dev->dev_addr, hw_addr, 6); - 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--; - unregister_dev(dev); - kfree(dev); - return NULL; - } - printk(KERN_INFO "%s: Max TX Outstanding = %d\n", dev->name, max_tx); - priv->max_tx = max_tx; - priv->tx_count = 0; + if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data->tid, + 0x0007, 2, &max_tx, sizeof(max_tx)) < 0) + { + printk(KERN_ERR "%s: Unable to query max TX queue.\n", dev->name); + unit--; + unregister_dev(dev); + kfree(dev); + return NULL; + } + dprintk(KERN_INFO "%s: Max TX Outstanding = %d.\n", dev->name, max_tx); + priv->max_tx = max_tx; + priv->tx_count = 0; priv->lock = SPIN_LOCK_UNLOCKED; @@ -887,43 +988,41 @@ struct net_device *dev; int i; - if (i2o_install_handler(&i2o_lan_handler) < 0) - { - printk(KERN_ERR "Unable to register I2O LAN OSM.\n"); + printk(KERN_INFO "Linux I2O LAN OSM (c) 1999 University of Helsinki.\n"); + + if (i2o_install_handler(&i2o_lan_handler) < 0) { + printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n"); return -EINVAL; - } + } lan_context = i2o_lan_handler.context; for(i=0; i <= MAX_LAN_CARDS; i++) i2o_landevs[i] = NULL; - for (i=0; i < MAX_I2O_CONTROLLERS; i++) - { + for (i=0; i < MAX_I2O_CONTROLLERS; i++) { struct i2o_controller *iop = i2o_find_controller(i); struct i2o_device *i2o_dev; - if (iop==NULL) - continue; + if (iop==NULL) continue; + + for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next) { - for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next) - { - if (i2o_dev->lct_data->class_id != I2O_CLASS_LAN) + if (i2o_dev->lct_data->class_id != I2O_CLASS_LAN) continue; - if(i2o_dev->lct_data->user_tid != 0xFFF) + /* Make sure device not already claimed by an ISM */ + if (i2o_dev->lct_data->user_tid != 0xFFF) continue; - if (unit == MAX_LAN_CARDS) - { + if (unit == MAX_LAN_CARDS) { i2o_unlock_controller(iop); - printk(KERN_WARNING "Too many I2O LAN devices.\n"); + printk(KERN_WARNING "i2o_lan: Too many I2O LAN devices.\n"); return -EINVAL; } dev = i2o_lan_register_device(i2o_dev); - if (dev == NULL) - { - printk(KERN_ERR "Unable to register I2O LAN device\n"); + if (dev == NULL) { + printk(KERN_ERR "i2o_lan: Unable to register I2O LAN device.\n"); continue; // try next one } @@ -947,14 +1046,12 @@ { int i; - for (i = 0; i <= unit; i++) - { + for (i = 0; i <= unit; i++) { struct net_device *dev = i2o_landevs[i]; struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv; struct i2o_device *i2o_dev = priv->i2o_dev; - switch (i2o_dev->lct_data->sub_class) - { + switch (i2o_dev->lct_data->sub_class) { case I2O_LAN_ETHERNET: unregister_netdev(dev); kfree(dev); @@ -976,11 +1073,11 @@ i2o_dev->lct_data->sub_class); } - dprintk(KERN_INFO "%s: I2O LAN device unregistered.\n", + dprintk(KERN_INFO "%s: I2O LAN device unregistered.\n", dev->name); } - i2o_remove_handler(&i2o_lan_handler); + i2o_remove_handler(&i2o_lan_handler); } EXPORT_NO_SYMBOLS; @@ -992,4 +1089,4 @@ MODULE_PARM(bucketthresh, "i"); // Bucket post threshold MODULE_PARM(rx_copybreak, "i"); -#endif +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_lan.h linux/drivers/i2o/i2o_lan.h --- v2.3.26/linux/drivers/i2o/i2o_lan.h Mon Oct 4 15:49:29 1999 +++ linux/drivers/i2o/i2o_lan.h Wed Nov 10 09:52:18 1999 @@ -18,7 +18,7 @@ /* Tunable parameters first */ #define I2O_BUCKET_COUNT 256 -#define I2O_BUCKET_THRESH 16 +#define I2O_BUCKET_THRESH 8 /* LAN types */ #define I2O_LAN_ETHERNET 0x0030 @@ -108,5 +108,11 @@ u32 context; /* FIXME: 64bit support */ struct i2o_packet_info packet_info[1]; }; + +/* Event Indicator Mask Flags for LAN OSM */ + +#define I2O_LAN_EVT_LINK_DOWN 0x01 +#define I2O_LAN_EVT_LINK_UP 0x02 +#define I2O_LAN_EVT_MEDIA_CHANGE 0x04 #endif /* _I2O_LAN_H */ diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_pci.c linux/drivers/i2o/i2o_pci.c --- v2.3.26/linux/drivers/i2o/i2o_pci.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/i2o/i2o_pci.c Wed Nov 10 09:52:18 1999 @@ -5,11 +5,11 @@ * (C) Copyright 1999 Red Hat Software * * Written by Alan Cox, Building Number Three Ltd - * Modified by Deepak Saxena + * Modified by Deepak Saxena * * 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 + * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * TODO: @@ -120,7 +120,7 @@ if(c==NULL) { - printk(KERN_ERR "i2o_pci: insufficient memory to add controller.\n"); + printk(KERN_ERR "i2o: Insufficient memory to add controller.\n"); return -ENOMEM; } memset(c, 0, sizeof(*c)); @@ -137,7 +137,7 @@ if(i==6) { - printk(KERN_ERR "i2o_pci: I2O controller has no memory regions defined.\n"); + printk(KERN_ERR "i2o: I2O controller has no memory regions defined.\n"); kfree(c); return -EINVAL; } @@ -145,11 +145,11 @@ size = dev->resource[i].end-dev->resource[i].start+1; /* Map the I2O controller */ - printk(KERN_INFO "PCI I2O controller at 0x%08X size=%d\n", memptr, size); + printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size); mem = ioremap(memptr, size); if(mem==NULL) { - printk(KERN_ERR "i2o_pci: Unable to map controller.\n"); + printk(KERN_ERR "i2o: Unable to map controller.\n"); kfree(c); return -EINVAL; } @@ -189,7 +189,7 @@ if(i<0) { - printk(KERN_ERR "i2o: unable to install controller.\n"); + printk(KERN_ERR "i2o: Unable to install controller.\n"); kfree(c); iounmap(mem); return i; @@ -216,7 +216,7 @@ } } - printk(KERN_INFO "Installed iop%d at IRQ%d\n", c->unit, dev->irq); + printk(KERN_INFO "%s: Installed at IRQ%d\n", c->name, dev->irq); I2O_IRQ_WRITE32(c,0x0); c->enabled = 1; return 0; @@ -227,7 +227,7 @@ struct pci_dev *dev; int count=0; - printk(KERN_INFO "Checking for PCI I2O controllers...\n"); + printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); for(dev=pci_devices; dev!=NULL; dev=dev->next) { @@ -235,17 +235,17 @@ continue; if((dev->class&0xFF)>1) { - printk(KERN_INFO "I2O controller found but does not support I2O 1.5 (skipping).\n"); + printk(KERN_INFO "i2o: I2O Controller found but does not support I2O 1.5 (skipping).\n"); continue; } - printk(KERN_INFO "I2O controller on bus %d at %d.\n", + printk(KERN_INFO "i2o: I2O controller on bus %d at %d.\n", dev->bus->number, dev->devfn); pci_set_master(dev); if(i2o_pci_install(dev)==0) count++; } if(count) - printk(KERN_INFO "%d I2O controller%s found and installed.\n", count, + printk(KERN_INFO "i2o: %d I2O controller%s found and installed.\n", count, count==1?"":"s"); return count?count:-ENODEV; } @@ -270,7 +270,7 @@ if(i2o_activate_controller(c)) #endif /* MODULE */ { - printk("I2O: Failed to initialize iop%d\n", c->unit); + printk("%s: Failed to initialize.\n", c->name); #ifdef MODULE core->unlock(c); core->delete(c); diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_proc.c linux/drivers/i2o/i2o_proc.c --- v2.3.26/linux/drivers/i2o/i2o_proc.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/i2o/i2o_proc.c Wed Nov 10 09:52:18 1999 @@ -51,9 +51,6 @@ #include #include - -#include "i2o_proc.h" - #include "i2o_lan.h" /* @@ -69,24 +66,34 @@ static int proc_context = 0; - static int i2o_proc_read_lct(char *, char **, off_t, int, int *, void *); static int i2o_proc_read_hrt(char *, char **, off_t, int, int *, void *); -static int i2o_proc_read_stat(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_status(char *, char **, off_t, int, int *, void *); + static int i2o_proc_read_hw(char *, char **, off_t, int, int *, void *); -static int i2o_proc_read_dst(char *, char **, off_t, int, int *, void *); static int i2o_proc_read_ddm_table(char *, char **, off_t, int, int *, void *); -static int i2o_proc_read_ds(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_driver_store(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_drivers_stored(char *, char **, off_t, int, int *, void *); + static int i2o_proc_read_groups(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_phys_device(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_claimed(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_users(char *, char **, off_t, int, int *, void *); static int i2o_proc_read_priv_msgs(char *, char **, off_t, int, int *, void *); -static int i2o_proc_read_dev(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_authorized_users(char *, char **, off_t, int, int *, void *); + static int i2o_proc_read_dev_name(char *, char **, off_t, int, int *, void *); -static int i2o_proc_read_ddm(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_dev_identity(char *, char **, off_t, int, int *, void *); +static int i2o_proc_read_ddm_identity(char *, char **, off_t, int, int *, void *); static int i2o_proc_read_uinfo(char *, char **, off_t, int, int *, void *); static int i2o_proc_read_sgl_limits(char *, char **, off_t, int, int *, void *); + +static int i2o_proc_read_sensors(char *, char **, off_t, int, int *, void *); + static int print_serial_number(char *, int, u8 *, int); -static int i2o_proc_create_entries(void *, - i2o_proc_entry *, struct proc_dir_entry *); + +static int i2o_proc_create_entries(void *, i2o_proc_entry *, + struct proc_dir_entry *); static void i2o_proc_remove_entries(i2o_proc_entry *, struct proc_dir_entry *); static int i2o_proc_add_controller(struct i2o_controller *, struct proc_dir_entry * ); @@ -117,18 +124,8 @@ void *); static int i2o_proc_read_lan_hist_stats(char *, char **, off_t, int, int *, void *); -static int i2o_proc_read_lan_supp_opt_stats(char *, char **, off_t, int, int *, - void *); -static int i2o_proc_read_lan_opt_tx_hist_stats(char *, char **, off_t, int, - int *, void *); -static int i2o_proc_read_lan_opt_rx_hist_stats(char *, char **, off_t, int, - int *, void *); static int i2o_proc_read_lan_eth_stats(char *, char **, off_t, int, int *, void *); -static int i2o_proc_read_lan_supp_eth_stats(char *, char **, off_t, int, int *, - void *); -static int i2o_proc_read_lan_opt_eth_stats(char *, char **, off_t, int, int *, - void *); static int i2o_proc_read_lan_tr_stats(char *, char **, off_t, int, int *, void *); static int i2o_proc_read_lan_fddi_stats(char *, char **, off_t, int, int *, @@ -155,11 +152,11 @@ { {"hrt", S_IFREG|S_IRUGO, i2o_proc_read_hrt, NULL}, {"lct", S_IFREG|S_IRUGO, i2o_proc_read_lct, NULL}, - {"stat", S_IFREG|S_IRUGO, i2o_proc_read_stat, NULL}, + {"status", S_IFREG|S_IRUGO, i2o_proc_read_status, NULL}, {"hw", S_IFREG|S_IRUGO, i2o_proc_read_hw, NULL}, - {"dst", S_IFREG|S_IRUGO, i2o_proc_read_dst, NULL}, {"ddm_table", S_IFREG|S_IRUGO, i2o_proc_read_ddm_table, NULL}, - {"ds", S_IFREG|S_IRUGO, i2o_proc_read_ds, NULL}, + {"driver_store", S_IFREG|S_IRUGO, i2o_proc_read_driver_store, NULL}, + {"drivers_stored", S_IFREG|S_IRUGO, i2o_proc_read_drivers_stored, NULL}, {NULL, 0, NULL, NULL} }; @@ -169,11 +166,16 @@ static i2o_proc_entry generic_dev_entries[] = { {"groups", S_IFREG|S_IRUGO, i2o_proc_read_groups, NULL}, + {"phys_dev", S_IFREG|S_IRUGO, i2o_proc_read_phys_device, NULL}, + {"claimed", S_IFREG|S_IRUGO, i2o_proc_read_claimed, NULL}, + {"users", S_IFREG|S_IRUGO, i2o_proc_read_users, NULL}, {"priv_msgs", S_IFREG|S_IRUGO, i2o_proc_read_priv_msgs, NULL}, - {"dev_identity", S_IFREG|S_IRUGO, i2o_proc_read_dev, NULL}, - {"ddm_identity", S_IFREG|S_IRUGO, i2o_proc_read_ddm, NULL}, - {"sgl_limits", S_IFREG|S_IRUGO, i2o_proc_read_sgl_limits, NULL}, + {"authorized_users", S_IFREG|S_IRUGO, i2o_proc_read_authorized_users, NULL}, + {"dev_identity", S_IFREG|S_IRUGO, i2o_proc_read_dev_identity, NULL}, + {"ddm_identity", S_IFREG|S_IRUGO, i2o_proc_read_ddm_identity, NULL}, {"user_info", S_IFREG|S_IRUGO, i2o_proc_read_uinfo, NULL}, + {"sgl_limits", S_IFREG|S_IRUGO, i2o_proc_read_sgl_limits, NULL}, + {"sensors", S_IFREG|S_IRUGO, i2o_proc_read_sensors, NULL}, {NULL, 0, NULL, NULL} }; @@ -187,22 +189,22 @@ }; #define SCSI_TABLE_SIZE 13 - static char *scsi_devices[] = - { - "Direct-Access Read/Write", - "Sequential-Access Storage", - "Printer", - "Processor", - "WORM Device", - "CD-ROM Device", - "Scanner Device", - "Optical Memory Device", - "Medium Changer Device", - "Communications Device", - "Graphics Art Pre-Press Device", - "Graphics Art Pre-Press Device", - "Array Controller Device" - }; +static char *scsi_devices[] = +{ + "Direct-Access Read/Write", + "Sequential-Access Storage", + "Printer", + "Processor", + "WORM Device", + "CD-ROM Device", + "Scanner Device", + "Optical Memory Device", + "Medium Changer Device", + "Communications Device", + "Graphics Art Pre-Press Device", + "Graphics Art Pre-Press Device", + "Array Controller Device" +}; /* private */ @@ -214,7 +216,6 @@ */ static i2o_proc_entry lan_entries[] = { - /* LAN param groups 0000h-0008h */ {"lan_dev_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_dev_info, NULL}, {"lan_mac_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_mac_addr, NULL}, {"lan_mcast_addr", S_IFREG|S_IRUGO|S_IWUSR, @@ -227,56 +228,30 @@ {"lan_alt_addr", S_IFREG|S_IRUGO, i2o_proc_read_lan_alt_addr, NULL}, {"lan_tx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_tx_info, NULL}, {"lan_rx_info", S_IFREG|S_IRUGO, i2o_proc_read_lan_rx_info, NULL}, - /* LAN param groups 0100h, 0180h, 0182h, 0183h */ - {"lan_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_hist_stats, NULL}, - {"lan_supp_opt_stats", S_IFREG|S_IRUGO, - i2o_proc_read_lan_supp_opt_stats, NULL}, - {"lan_opt_tx_stats", S_IFREG|S_IRUGO, - i2o_proc_read_lan_opt_tx_hist_stats, NULL}, - {"lan_opt_rx_stats", S_IFREG|S_IRUGO, - i2o_proc_read_lan_opt_rx_hist_stats, NULL}, - /* TODO: LAN param group 0184h */ + + {"lan_hist_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_hist_stats, NULL}, {NULL, 0, NULL, NULL} }; /* - * Ethernet specific LAN entries + * Port specific LAN entries * */ static i2o_proc_entry lan_eth_entries[] = { - /* LAN param groups 0200h, 0280h, 0281h */ - {"lan_eth_stat", S_IFREG|S_IRUGO, i2o_proc_read_lan_eth_stats, NULL}, - {"lan_supp_eth_stats", S_IFREG|S_IRUGO, - i2o_proc_read_lan_supp_eth_stats, NULL}, - {"lan_opt_eth_stats", S_IFREG|S_IRUGO, - i2o_proc_read_lan_opt_eth_stats, NULL}, + {"lan_eth_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_eth_stats, NULL}, {NULL, 0, NULL, NULL} }; -/* - * Token Ring specific LAN entries - * - */ static i2o_proc_entry lan_tr_entries[] = { - /* LAN param group 0300h */ - {"lan_tr_stats", S_IFREG|S_IRUGO, - i2o_proc_read_lan_tr_stats, NULL}, - /* TODO: LAN param group 0380h, 0381h */ + {"lan_tr_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_tr_stats, NULL}, {NULL, 0, NULL, NULL} }; -/* - * FDDI specific LAN entries - * - */ static i2o_proc_entry lan_fddi_entries[] = { - /* LAN param group 0400h */ - {"lan_fddi_stats", S_IFREG|S_IRUGO, - i2o_proc_read_lan_fddi_stats, NULL}, - /* TODO: LAN param group 0480h, 0481h */ + {"lan_fddi_stats", S_IFREG|S_IRUGO, i2o_proc_read_lan_fddi_stats, NULL}, {NULL, 0, NULL, NULL} }; @@ -290,6 +265,22 @@ return strncat(tmp, (char *)chars, n); } +static int i2o_report_query_status(char *buf, int block_status, char *group) +{ + switch (block_status) + { + case -ETIMEDOUT: + return sprintf(buf, "Timeout reading group %s.\n",group); + case -ENOMEM: + return sprintf(buf, "No free memory to read the table.\n"); + case -I2O_PARAMS_STATUS_INVALID_GROUP_ID: + return sprintf(buf, "Group %s not supported.\n", group); + default: + return sprintf(buf, "Error reading group %s. BlockStatus 0x%02X\n", + group, -block_status); + } +} + static char* bus_strings[] = { "Local Bus", @@ -314,7 +305,7 @@ int *eof, void *data) { struct i2o_controller *c = (struct i2o_controller *)data; - pi2o_hrt hrt = (pi2o_hrt)c->hrt; + i2o_hrt *hrt = (i2o_hrt *)c->hrt; u32 bus; int count; int i; @@ -342,17 +333,15 @@ } len += sprintf(buf+len, "HRT has %d entries of %d bytes each.\n", - count, hrt->entry_len); + count, hrt->entry_len << 2); for(i = 0; i < count; i++) { len += sprintf(buf+len, "Entry %d:\n", i); len += sprintf(buf+len, " Adapter ID: %0#10x\n", hrt->hrt_entry[i].adapter_id); - len += sprintf(buf+len, " Controlled by: %0#6x\n", + len += sprintf(buf+len, " Controlling tid: %0#6x\n", hrt->hrt_entry[i].parent_tid); - len += sprintf(buf+len, " Bus#%d\n", - hrt->hrt_entry[i].bus_num); if(hrt->hrt_entry[i].bus_type != 0x80) { @@ -425,20 +414,19 @@ int *eof, void *data) { struct i2o_controller *c = (struct i2o_controller*)data; - pi2o_lct lct = (pi2o_lct)c->lct; + i2o_lct *lct = (i2o_lct *)c->lct; int entries; int i; #define BUS_TABLE_SIZE 3 static char *bus_ports[] = - { - "Generic Bus", - "SCSI Bus", - "Fibre Channel Bus" - }; + { + "Generic Bus", + "SCSI Bus", + "Fibre Channel Bus" + }; spin_lock(&i2o_proc_lock); - len = 0; entries = (lct->table_size - 3)/9; @@ -451,8 +439,7 @@ for(i = 0; i < entries; i++) { len += sprintf(buf+len, "Entry %d\n", i); - - len += sprintf(buf+len, " %s", i2o_get_class_name(lct->lct_entry[i].class_id)); + len += sprintf(buf+len, " Class, SubClass : %s", i2o_get_class_name(lct->lct_entry[i].class_id)); /* * Classes which we'll print subclass info for @@ -463,23 +450,23 @@ switch(lct->lct_entry[i].sub_class) { case 0x00: - len += sprintf(buf+len, ": Direct-Access Read/Write"); + len += sprintf(buf+len, ", Direct-Access Read/Write"); break; case 0x04: - len += sprintf(buf+len, ": WORM Drive"); + len += sprintf(buf+len, ", WORM Drive"); break; case 0x05: - len += sprintf(buf+len, ": CD-ROM Drive"); + len += sprintf(buf+len, ", CD-ROM Drive"); break; case 0x07: - len += sprintf(buf+len, ": Optical Memory Device"); + len += sprintf(buf+len, ", Optical Memory Device"); break; default: - len += sprintf(buf+len, ": Unknown (0x%02x)", + len += sprintf(buf+len, ", Unknown (0x%02x)", lct->lct_entry[i].sub_class); break; } @@ -489,27 +476,27 @@ switch(lct->lct_entry[i].sub_class & 0xFF) { case 0x30: - len += sprintf(buf+len, ": Ethernet"); + len += sprintf(buf+len, ", Ethernet"); break; case 0x40: - len += sprintf(buf+len, ": 100base VG"); + len += sprintf(buf+len, ", 100base VG"); break; case 0x50: - len += sprintf(buf+len, ": IEEE 802.5/Token-Ring"); + len += sprintf(buf+len, ", IEEE 802.5/Token-Ring"); break; case 0x60: - len += sprintf(buf+len, ": ANSI X3T9.5 FDDI"); + len += sprintf(buf+len, ", ANSI X3T9.5 FDDI"); break; case 0x70: - len += sprintf(buf+len, ": Fibre Channel"); + len += sprintf(buf+len, ", Fibre Channel"); break; default: - len += sprintf(buf+len, ": Unknown Sub-Class (0x%02x)", + len += sprintf(buf+len, ", Unknown Sub-Class (0x%02x)", lct->lct_entry[i].sub_class & 0xFF); break; } @@ -517,27 +504,27 @@ case I2O_CLASS_SCSI_PERIPHERAL: if(lct->lct_entry[i].sub_class < SCSI_TABLE_SIZE) - len += sprintf(buf+len, ": %s", + len += sprintf(buf+len, ", %s", scsi_devices[lct->lct_entry[i].sub_class]); else - len += sprintf(buf+len, ": Unknown Device Type"); + len += sprintf(buf+len, ", Unknown Device Type"); break; case I2O_CLASS_BUS_ADAPTER_PORT: if(lct->lct_entry[i].sub_class < BUS_TABLE_SIZE) - len += sprintf(buf+len, ": %s", + len += sprintf(buf+len, ", %s", bus_ports[lct->lct_entry[i].sub_class]); else - len += sprintf(buf+len, ": Unknown Bus Type"); + len += sprintf(buf+len, ", Unknown Bus Type"); break; } len += sprintf(buf+len, "\n"); - len += sprintf(buf+len, " Local TID: 0x%03x\n", lct->lct_entry[i].tid); - len += sprintf(buf+len, " User TID: 0x%03x\n", lct->lct_entry[i].user_tid); - len += sprintf(buf+len, " Parent TID: 0x%03x\n", + len += sprintf(buf+len, " Local TID : 0x%03x\n", lct->lct_entry[i].tid); + len += sprintf(buf+len, " User TID : 0x%03x\n", lct->lct_entry[i].user_tid); + len += sprintf(buf+len, " Parent TID : 0x%03x\n", lct->lct_entry[i].parent_tid); - len += sprintf(buf+len, " Identity Tag: 0x%x%x%x%x%x%x%x%x\n", + len += sprintf(buf+len, " Identity Tag : 0x%x%x%x%x%x%x%x%x\n", lct->lct_entry[i].identity_tag[0], lct->lct_entry[i].identity_tag[1], lct->lct_entry[i].identity_tag[2], @@ -546,219 +533,211 @@ lct->lct_entry[i].identity_tag[5], lct->lct_entry[i].identity_tag[6], lct->lct_entry[i].identity_tag[7]); - len += sprintf(buf+len, " Change Indicator: %0#10x\n", + len += sprintf(buf+len, " Change Indicator : %0#10x\n", lct->lct_entry[i].change_ind); - len += sprintf(buf+len, " Device Flags: %0#10x\n", + len += sprintf(buf+len, " Event Capab Mask : %0#10x\n", lct->lct_entry[i].device_flags); } spin_unlock(&i2o_proc_lock); - return len; } -int i2o_proc_read_stat(char *buf, char **start, off_t offset, int len, - int *eof, void *data) +int i2o_proc_read_status(char *buf, char **start, off_t offset, int len, + int *eof, void *data) { struct i2o_controller *c = (struct i2o_controller*)data; - u32 *msg; - u32 m; - u8 *workspace; - u16 *work16; - u32 *work32; - long time; char prodstr[25]; int version; spin_lock(&i2o_proc_lock); - len = 0; - workspace = (u8*)kmalloc(88, GFP_KERNEL); - if(!workspace) - { - len += sprintf(buf, "No memory for status transfer\n"); - spin_unlock(&i2o_proc_lock); - return len; - } - - m = I2O_POST_READ32(c); - if(m == 0xFFFFFFFF) - { - len += sprintf(buf, "Could not get inbound message frame from IOP!\n"); - kfree(workspace); - spin_unlock(&i2o_proc_lock); - return len; - } - - msg = (u32 *)(m+c->mem_offset); - - memset(workspace, 0, 88); - work32 = (u32*)workspace; - work16 = (u16*)workspace; - - msg[0] = NINE_WORD_MSG_SIZE|SGL_OFFSET_0; - msg[1] = I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID; - msg[2] = msg[3] = msg[4] = msg[5] = 0; - msg[6] = virt_to_phys(workspace); - msg[7] = 0; /* FIXME: 64-bit */ - msg[8] = 88; - - /* - * hmm...i2o_post_message should just take ptr to message, and - * determine offset on it's own...less work for OSM developers - */ - i2o_post_message(c, m); - - time = jiffies; - - while(workspace[87] != 0xFF) - { - if(jiffies-time >= 2*HZ) - { - len += sprintf(buf, "Timeout waiting for status reply\n"); - kfree(workspace); - spin_unlock(&i2o_proc_lock); - return len; - } - schedule(); - barrier(); - } + i2o_status_get(c); // reread the status block - len += sprintf(buf+len, "Organization ID: %0#6x\n", work16[0]); + len += sprintf(buf+len,"Organization ID : %0#6x\n", + c->status_block->org_id); - version = workspace[9]&0xF0>>4; - if(version == 0x02) { - len += sprintf(buf+len, "Lowest I2O version supported: "); + version = c->status_block->i2o_version; + +/* FIXME for Spec 2.0 + if (version == 0x02) { + len += sprintf(buf+len,"Lowest I2O version supported: "); switch(workspace[2]) { - case 0x00: - len += sprintf(buf+len, "1.0\n"); - break; - case 0x01: - len += sprintf(buf+len, "1.5\n"); - break; - case 0x02: - len += sprintf(buf+len, "2.0\n"); - break; + case 0x00: + len += sprintf(buf+len,"1.0\n"); + break; + case 0x01: + len += sprintf(buf+len,"1.5\n"); + break; + case 0x02: + len += sprintf(buf+len,"2.0\n"); + break; } len += sprintf(buf+len, "Highest I2O version supported: "); switch(workspace[3]) { + case 0x00: + len += sprintf(buf+len,"1.0\n"); + break; + case 0x01: + len += sprintf(buf+len,"1.5\n"); + break; + case 0x02: + len += sprintf(buf+len,"2.0\n"); + break; + } + } +*/ + len += sprintf(buf+len,"IOP ID : %0#5x\n", + c->status_block->iop_id); + len += sprintf(buf+len,"Host Unit ID : %0#6x\n", + c->status_block->host_unit_id); + len += sprintf(buf+len,"Segment Number : %0#5x\n", + c->status_block->segment_number); + + len += sprintf(buf+len, "I2O version : "); + switch (version) { case 0x00: - len += sprintf(buf+len, "1.0\n"); + len += sprintf(buf+len,"1.0\n"); break; case 0x01: - len += sprintf(buf+len, "1.5\n"); + len += sprintf(buf+len,"1.5\n"); break; case 0x02: - len += sprintf(buf+len, "2.0\n"); + len += sprintf(buf+len,"2.0\n"); break; - } - } - - len += sprintf(buf+len, "IOP ID: %0#5x\n", work16[2]&0xFFF); - len += sprintf(buf+len, "Host Unit ID: %0#6x\n", work16[3]); - len += sprintf(buf+len, "Segment Number: %0#5x\n", work16[4]&0XFFF); - - len += sprintf(buf+len, "I2O version: "); - switch(version) - { - case 0x00: - len += sprintf(buf+len, "1.0\n"); - break; - case 0x01: - len += sprintf(buf+len, "1.5\n"); - break; - case 0x02: - len += sprintf(buf+len, "2.0\n"); - break; - default: - len += sprintf(buf+len, "Unknown version\n"); + default: + len += sprintf(buf+len,"Unknown version\n"); } - len += sprintf(buf+len, "IOP State: "); - switch(workspace[10]) - { + len += sprintf(buf+len, "IOP State : "); + switch (c->status_block->iop_state) { case 0x01: - len += sprintf(buf+len, "Init\n"); + len += sprintf(buf+len,"INIT\n"); break; case 0x02: - len += sprintf(buf+len, "Reset\n"); + len += sprintf(buf+len,"RESET\n"); break; case 0x04: - len += sprintf(buf+len, "Hold\n"); + len += sprintf(buf+len,"HOLD\n"); break; case 0x05: - len += sprintf(buf+len, "Hold\n"); + len += sprintf(buf+len,"READY\n"); break; case 0x08: - len += sprintf(buf+len, "Operational\n"); + len += sprintf(buf+len,"OPERATIONAL\n"); break; case 0x10: - len += sprintf(buf+len, "FAILED\n"); + len += sprintf(buf+len,"FAILED\n"); break; case 0x11: - len += sprintf(buf+len, "FAULTED\n"); + len += sprintf(buf+len,"FAULTED\n"); break; default: - len += sprintf(buf+len, "Unknown\n"); + len += sprintf(buf+len,"Unknown\n"); break; } - /* 0x00 is the only type supported w/spec 1.5 */ - /* Added 2.0 types */ - len += sprintf(buf+len, "Messenger Type: "); - switch (workspace[11]) - { - case 0x00: - len += sprintf(buf+len, "Memory mapped\n"); - break; - case 0x01: - len += sprintf(buf+len, "Memory mapped only\n"); - break; - case 0x02: - len += sprintf(buf+len, "Remote only\n"); - break; - case 0x03: - len += sprintf(buf+len, "Memory mapped and remote\n"); - break; - default: - len += sprintf(buf+len, "Unknown\n"); - break; + len += sprintf(buf+len,"Messenger Type : "); + switch (c->status_block->msg_type) { + case 0x00: + len += sprintf(buf+len,"Memory mapped\n"); + break; + case 0x01: + len += sprintf(buf+len,"Memory mapped only\n"); + break; + case 0x02: + len += sprintf(buf+len,"Remote only\n"); + break; + case 0x03: + len += sprintf(buf+len,"Memory mapped and remote\n"); + break; + default: + len += sprintf(buf+len,"Unknown\n"); } - len += sprintf(buf+len, "Inbound Frame Size: %d bytes\n", work16[6]*4); - len += sprintf(buf+len, "Max Inbound Frames: %d\n", work32[4]); - len += sprintf(buf+len, "Current Inbound Frames: %d\n", work32[5]); - len += sprintf(buf+len, "Max Outbound Frames: %d\n", work32[6]); + + len += sprintf(buf+len,"Inbound Frame Size : %d bytes\n", + c->status_block->inbound_frame_size<<2); + len += sprintf(buf+len,"Max Inbound Frames : %d\n", + c->status_block->max_inbound_frames); + len += sprintf(buf+len,"Current Inbound Frames : %d\n", + c->status_block->cur_inbound_frames); + len += sprintf(buf+len,"Max Outbound Frames : %d\n", + c->status_block->max_outbound_frames); /* Spec doesn't say if NULL terminated or not... */ - memcpy(prodstr, work32+7, 24); + memcpy(prodstr, c->status_block->product_id, 24); prodstr[24] = '\0'; - len += sprintf(buf+len, "Product ID: %s\n", prodstr); - - len += sprintf(buf+len, "LCT Size: %d\n", work32[13]); - - len += sprintf(buf+len, "Desired private memory space: %d kB\n", - work32[15]>>10); - len += sprintf(buf+len, "Allocated private memory space: %d kB\n", - work32[16]>>10); - len += sprintf(buf+len, "Private memory base address: %0#10x\n", - work32[17]); - len += sprintf(buf+len, "Desired private I/O space: %d kB\n", - work32[18]>>10); - len += sprintf(buf+len, "Allocated private I/O space: %d kB\n", - work32[19]>>10); - len += sprintf(buf+len, "Private I/O base address: %0#10x\n", - work32[20]); + len += sprintf(buf+len,"Product ID : %s\n", prodstr); + len += sprintf(buf+len,"Expected LCT Size : %d bytes\n", + c->status_block->expected_lct_size); + + len += sprintf(buf+len,"IOP Capabilities\n"); + len += sprintf(buf+len," Context Field Size Support : "); + switch (c->status_block->iop_capabilities & 0x0000003) { + case 0: + len += sprintf(buf+len,"Supports only 32-bit context fields\n"); + break; + case 1: + len += sprintf(buf+len,"Supports only 64-bit context fields\n"); + break; + case 2: + len += sprintf(buf+len,"Supports 32-bit and 64-bit context fields, " + "but not concurrently\n"); + break; + case 3: + len += sprintf(buf+len,"Supports 32-bit and 64-bit context fields " + "concurrently\n"); + break; + default: + len += sprintf(buf+len,"0x%08x\n",c->status_block->iop_capabilities); + } + len += sprintf(buf+len," Current Context Field Size : "); + switch (c->status_block->iop_capabilities & 0x0000000C) { + case 0: + len += sprintf(buf+len,"not configured\n"); + break; + case 4: + len += sprintf(buf+len,"Supports only 32-bit context fields\n"); + break; + case 8: + len += sprintf(buf+len,"Supports only 64-bit context fields\n"); + break; + case 12: + len += sprintf(buf+len,"Supports both 32-bit or 64-bit context fields " + "concurrently\n"); + break; + default: + len += sprintf(buf+len,"\n"); + } + len += sprintf(buf+len," Inbound Peer Support : %s\n", + (c->status_block->iop_capabilities & 0x00000010) ? "Supported" : "Not supported"); + len += sprintf(buf+len," Outbound Peer Support : %s\n", + (c->status_block->iop_capabilities & 0x00000020) ? "Supported" : "Not supported"); + len += sprintf(buf+len," Peer to Peer Support : %s\n", + (c->status_block->iop_capabilities & 0x00000040) ? "Supported" : "Not supported"); + + len += sprintf(buf+len, "Desired private memory size : %d kB\n", + c->status_block->desired_mem_size>>10); + len += sprintf(buf+len, "Allocated private memory size : %d kB\n", + c->status_block->current_mem_size>>10); + len += sprintf(buf+len, "Private memory base address : %0#10x\n", + c->status_block->current_mem_base); + len += sprintf(buf+len, "Desired private I/O size : %d kB\n", + c->status_block->desired_io_size>>10); + len += sprintf(buf+len, "Allocated private I/O size : %d kB\n", + c->status_block->current_io_size>>10); + len += sprintf(buf+len, "Private I/O base address : %0#10x\n", + c->status_block->current_io_base); - kfree(workspace); spin_unlock(&i2o_proc_lock); return len; @@ -790,25 +769,25 @@ len = 0; - token = i2o_query_scalar(c, ADAPTER_TID, - 0, // ParamGroup 0x0000h - -1, // all fields - &work32, - sizeof(work32)); + token = i2o_query_scalar(c, ADAPTER_TID, 0x0000, -1, &work32, sizeof(work32)); - if(token < 0) - { - len += sprintf(buf, "Error waiting for reply from IOP\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0000 IOP Hardware"); spin_unlock(&i2o_proc_lock); return len; } - len += sprintf(buf, "IOP Hardware Information Table (group = 0x0000)\n"); - - len += sprintf(buf+len, "I2O Vendor ID : %0#6x\n", work16[0]); - len += sprintf(buf+len, "Product ID : %0#6x\n", work16[1]); - len += sprintf(buf+len, "RAM : %dkB\n", work32[1]>>10); - len += sprintf(buf+len, "Non-Volatile Storage : %dkB\n", work32[2]>>10); + len += sprintf(buf+len, "I2O Vendor ID : %0#6x\n", work16[0]); + len += sprintf(buf+len, "Product ID : %0#6x\n", work16[1]); + len += sprintf(buf+len, "CPU : "); + if(work8[16] > 8) + len += sprintf(buf+len, "Unknown\n"); + else + len += sprintf(buf+len, "%s\n", cpu_table[work8[16]]); + /* Anyone using ProcessorVersion? */ + + len += sprintf(buf+len, "RAM : %dkB\n", work32[1]>>10); + len += sprintf(buf+len, "Non-Volatile Mem : %dkB\n", work32[2]>>10); hwcap = work32[3]; len += sprintf(buf+len, "Capabilities :\n"); @@ -823,13 +802,6 @@ if(hwcap&0x00000010) len += sprintf(buf+len, " Battery-backed RAM\n"); - len += sprintf(buf+len, "CPU : "); - if(work8[16] > 8) - len += sprintf(buf+len, "Unknown\n"); - else - len += sprintf(buf+len, "%s\n", cpu_table[work8[16]]); - /* Anyone using ProcessorVersion? */ - spin_unlock(&i2o_proc_lock); return len; @@ -850,11 +822,10 @@ u8 reserved; u16 i2o_vendor_id; u16 module_id; - u8 module_name[24]; - u8 module_version[4]; + u8 module_name_version[28]; u32 data_size; u32 code_size; - } i2o_exec_execute_ddm_table, *pi2o_exec_execute_ddm_table; + } i2o_exec_execute_ddm_table; struct { @@ -879,27 +850,13 @@ NULL, 0, &result, sizeof(result)); - if (token<0) - switch (token) - { - case -ETIMEDOUT: - len += sprintf(buf, "Timeout reading table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - case -ENOMEM: - len += sprintf(buf, "No free memory to read the table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - default: - len += sprintf(buf, "Error reading group. BlockStatus %d\n", - token); - spin_unlock(&i2o_proc_lock); - return len; - } + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0003 Executing DDM List"); + spin_unlock(&i2o_proc_lock); + return len; + } - len += sprintf(buf+len, "Tid Type Vendor Id Name Vrs Data_size Code_size\n"); + len += sprintf(buf+len, "Tid Module_type Vendor Mod_id Module_name Vrs Data_size Code_size\n"); ddm_table=result.ddm_table[0]; for(i=0; i < result.row_count; ddm_table=result.ddm_table[++i]) @@ -918,11 +875,10 @@ len += sprintf(buf+len, " "); } - len += sprintf(buf+len, "%0#7x", ddm_table.i2o_vendor_id); - len += sprintf(buf+len, "%0#7x", ddm_table.module_id); - len += sprintf(buf+len, "%-25s", chtostr(ddm_table.module_name, 24)); - len += sprintf(buf+len, "%-6s", chtostr(ddm_table.module_version,4)); - len += sprintf(buf+len, "%8d ", ddm_table.data_size); + len += sprintf(buf+len, "%-#7x", ddm_table.i2o_vendor_id); + len += sprintf(buf+len, "%-#8x", ddm_table.module_id); + len += sprintf(buf+len, "%-29s", chtostr(ddm_table.module_name_version, 28)); + len += sprintf(buf+len, "%9d ", ddm_table.data_size); len += sprintf(buf+len, "%8d", ddm_table.code_size); len += sprintf(buf+len, "\n"); @@ -935,20 +891,20 @@ /* Executive group 0004h - Driver Store (scalar) */ -int i2o_proc_read_ds(char *buf, char **start, off_t offset, int len, +int i2o_proc_read_driver_store(char *buf, char **start, off_t offset, int len, int *eof, void *data) { struct i2o_controller *c = (struct i2o_controller*)data; u32 work32[8]; + int token; spin_lock(&i2o_proc_lock); len = 0; - if(i2o_query_scalar(c, ADAPTER_TID, 0x0004, -1, &work32, - sizeof(work32)) < 0) - { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + token = i2o_query_scalar(c, ADAPTER_TID, 0x0004, -1, &work32, sizeof(work32)); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0004 Driver Store"); spin_unlock(&i2o_proc_lock); return len; } @@ -966,8 +922,8 @@ /* Executive group 0005h - Driver Store Table (table) */ -int i2o_proc_read_dst(char *buf, char **start, off_t offset, int len, - int *eof, void *data) +int i2o_proc_read_drivers_stored(char *buf, char **start, off_t offset, + int len, int *eof, void *data) { typedef struct _i2o_driver_store { u16 stored_ddm_index; @@ -1005,33 +961,17 @@ len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - c, ADAPTER_TID, - 0x0005, -1, - NULL, 0, + c, ADAPTER_TID, 0x0005, -1, NULL, 0, &result, sizeof(result)); - if (token<0) - switch (token) - { - case -ETIMEDOUT: - len += sprintf(buf, "Timeout reading table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - case -ENOMEM: - len += sprintf(buf, "No free memory to read the table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - default: - len += sprintf(buf, "Error reading group. " - "BlockStatus %d\n",token); - spin_unlock(&i2o_proc_lock); - return len; - } - - len += sprintf(buf+len, "# Type Vendor Id Name Vrs Date Mod_size Par_size Flags\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0005 DRIVER STORE TABLE"); + spin_unlock(&i2o_proc_lock); + return len; + } + len += sprintf(buf+len, "# Module_type Vendor Mod_id Module_name Vrs" + "Date Mod_size Par_size Flags\n"); for(i=0, dst=result.dst[0]; i < result.row_count; dst=result.dst[++i]) { len += sprintf(buf+len, "%-3d", dst.stored_ddm_index); @@ -1052,8 +992,8 @@ len += sprintf(buf+len, "%-d", dst.module_state); #endif - len += sprintf(buf+len, "%#7x", dst.i2o_vendor_id); - len += sprintf(buf+len, "%#8x", dst.module_id); + len += sprintf(buf+len, "%-#7x", dst.i2o_vendor_id); + len += sprintf(buf+len, "%-#8x", dst.module_id); len += sprintf(buf+len, "%-29s", chtostr(dst.module_name_version,28)); len += sprintf(buf+len, "%-9s", chtostr(dst.date,8)); len += sprintf(buf+len, "%8d ", dst.module_size); @@ -1077,81 +1017,69 @@ int i2o_proc_read_groups(char *buf, char **start, off_t offset, int len, int *eof, void *data) { - struct i2o_controller *c = (struct i2o_controller*)data; + struct i2o_device *d = (struct i2o_device*)data; int token; int i; - int rows; - u16 work16[2048]; - u16 *group=work16; - int more; - + u8 properties; + + typedef struct _i2o_group_info + { + u16 group_number; + u16 field_count; + u16 row_count; + u8 properties; + u8 reserved; + } i2o_group_info; + + struct + { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + i2o_group_info group[256]; + } result; + spin_lock(&i2o_proc_lock); len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - c, ADAPTER_TID, - 0xF000, -1, - NULL, 0, - &work16, sizeof(work16)); - - if (token<0) - switch (token) - { - case -ETIMEDOUT: - len += sprintf(buf, "Timeout reading table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - case -ENOMEM: - len += sprintf(buf, "No free memory to read the table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - default: - len += sprintf(buf, "Error reading table. BlockStatus %d\n", - token); - spin_unlock(&i2o_proc_lock); - return len; - } + d->controller, d->lct_data->tid, 0xF000, -1, NULL, 0, + &result, sizeof(result)); - rows=work16[4]; - more=work16[5]; + if (token < 0) { + len = i2o_report_query_status(buf+len, token, "0xF000 Params Descriptor"); + spin_unlock(&i2o_proc_lock); + return len; + } - len += sprintf(buf+len, "\nPARAMS DESCRIPTOR TABLE:\n\n"); len += sprintf(buf+len, "# Group FieldCount RowCount Type Add Del Clear\n"); - group+=64; - - for(i=0; i < rows; i++, group+=16) + for (i=0; i < result.row_count; i++) { len += sprintf(buf+len, "%-3d", i); - - len += sprintf(buf+len, "%#6x ", group[0]); - len += sprintf(buf+len, "%10d ", group[1]); - len += sprintf(buf+len, "%8d ", group[2]); - - if(group[3]&0x1) - len += sprintf(buf+len, "Table "); - else - len += sprintf(buf+len, "Scalar "); - if(group[3]&0x2) - len += sprintf(buf+len, "x "); - else - len += sprintf(buf+len, " "); - if(group[3]&0x4) - len += sprintf(buf+len, "x "); - else - len += sprintf(buf+len, " "); - if(group[3]&0x8) - len += sprintf(buf+len, "x "); - else - len += sprintf(buf+len, " "); + len += sprintf(buf+len, "0x%04X ", result.group[i].group_number); + len += sprintf(buf+len, "%10d ", result.group[i].field_count); + len += sprintf(buf+len, "%8d ", result.group[i].row_count); + + properties = result.group[i].properties; + if (properties & 0x1) len += sprintf(buf+len, "Table "); + else len += sprintf(buf+len, "Scalar "); + if (properties & 0x2) len += sprintf(buf+len, " + "); + else len += sprintf(buf+len, " - "); + if (properties & 0x4) len += sprintf(buf+len, " + "); + else len += sprintf(buf+len, " - "); + if (properties & 0x8) len += sprintf(buf+len, " + "); + else len += sprintf(buf+len, " - "); len += sprintf(buf+len, "\n"); } - if(more) + if (result.more_flag) len += sprintf(buf+len, "There is more...\n"); spin_unlock(&i2o_proc_lock); @@ -1160,74 +1088,283 @@ } -/* Generic group F005h - Private message extensions (table) */ -int i2o_proc_read_priv_msgs(char *buf, char **start, off_t offset, int len, - int *eof, void *data) +/* Generic group F001h - Physical Device Table (table) */ +int i2o_proc_read_phys_device(char *buf, char **start, off_t offset, int len, + int *eof, void *data) { - struct i2o_controller *c = (struct i2o_controller*)data; + struct i2o_device *d = (struct i2o_device*)data; int token; int i; - int rows; - int more; - u16 work16[1024]; - u16 *field=work16; - spin_lock(&i2o_proc_lock); + struct + { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + u32 adapter_id[64]; + } result; + spin_lock(&i2o_proc_lock); len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - c, ADAPTER_TID, - 0xF000, -1, - NULL, 0, - &work16, sizeof(work16)); + d->controller, d->lct_data->tid, + 0xF001, -1, NULL, 0, + &result, sizeof(result)); - if (token<0) - switch (token) - { - case -ETIMEDOUT: - len += sprintf(buf, "Timeout reading table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - case -ENOMEM: - len += sprintf(buf, "No free memory to read the table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - default: - len += sprintf(buf, "Error reading field. BlockStatus %d\n", - token); - spin_unlock(&i2o_proc_lock); - return len; - } + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF001 Physical Device Table"); + spin_unlock(&i2o_proc_lock); + return len; + } - rows=work16[4]; - more=work16[5]; - - len += sprintf(buf+len, "Instance# OrgId FunctionCode\n"); + if (result.row_count) + len += sprintf(buf+len, "# AdapterId\n"); - field+=64; - for(i=0; i < rows; i++, field+=16) + for (i=0; i < result.row_count; i++) { - len += sprintf(buf+len, "%0#9x ", field[0]); - len += sprintf(buf+len, "%0#6x ", work16[1]); - len += sprintf(buf+len, "%0#6x", work16[2]); - - len += sprintf(buf+len, "\n"); + len += sprintf(buf+len, "%-2d", i); + len += sprintf(buf+len, "%#7x\n", result.adapter_id[i]); } - if(more) + if (result.more_flag) len += sprintf(buf+len, "There is more...\n"); spin_unlock(&i2o_proc_lock); - return len; } +/* Generic group F002h - Claimed Table (table) */ +int i2o_proc_read_claimed(char *buf, char **start, off_t offset, int len, + int *eof, void *data) +{ + struct i2o_device *d = (struct i2o_device*)data; + int token; + int i; -int i2o_proc_read_dev(char *buf, char **start, off_t offset, int len, - int *eof, void *data) + struct { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + u16 claimed_tid[64]; + } result; + + spin_lock(&i2o_proc_lock); + len = 0; + + token = i2o_query_table(I2O_PARAMS_TABLE_GET, + d->controller, d->lct_data->tid, + 0xF002, -1, NULL, 0, + &result, sizeof(result)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF002 Claimed Table"); + spin_unlock(&i2o_proc_lock); + return len; + } + + if (result.row_count) + len += sprintf(buf+len, "# ClaimedTid\n"); + + for (i=0; i < result.row_count; i++) + { + len += sprintf(buf+len, "%-2d", i); + len += sprintf(buf+len, "%#7x\n", result.claimed_tid[i]); + } + + if (result.more_flag) + len += sprintf(buf+len, "There is more...\n"); + + spin_unlock(&i2o_proc_lock); + return len; +} + +/* Generic group F003h - User Table (table) */ +int i2o_proc_read_users(char *buf, char **start, off_t offset, int len, + int *eof, void *data) +{ + struct i2o_device *d = (struct i2o_device*)data; + int token; + int i; + + typedef struct _i2o_user_table + { + u16 instance; + u16 user_tid; + u8 claim_type; + u8 reserved1; + u16 reserved2; + } i2o_user_table; + + struct + { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + i2o_user_table user[64]; + } result; + + spin_lock(&i2o_proc_lock); + len = 0; + + token = i2o_query_table(I2O_PARAMS_TABLE_GET, + d->controller, d->lct_data->tid, + 0xF003, -1, NULL, 0, + &result, sizeof(result)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF003 User Table"); + spin_unlock(&i2o_proc_lock); + return len; + } + + len += sprintf(buf+len, "# Instance UserTid ClaimType\n"); + + for(i=0; i < result.row_count; i++) + { + len += sprintf(buf+len, "%-3d", i); + len += sprintf(buf+len, "%#8x ", result.user[i].instance); + len += sprintf(buf+len, "%#7x ", result.user[i].user_tid); + len += sprintf(buf+len, "%#9x\n", result.user[i].claim_type); + } + + if (result.more_flag) + len += sprintf(buf+len, "There is more...\n"); + + spin_unlock(&i2o_proc_lock); + return len; +} + +/* Generic group F005h - Private message extensions (table) (optional) */ +int i2o_proc_read_priv_msgs(char *buf, char **start, off_t offset, int len, + int *eof, void *data) +{ + struct i2o_device *d = (struct i2o_device*)data; + int token; + int i; + + typedef struct _i2o_private + { + u16 ext_instance; + u16 organization_id; + u16 x_function_code; + } i2o_private; + + struct + { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + i2o_private extension[64]; + } result; + + spin_lock(&i2o_proc_lock); + + len = 0; + + token = i2o_query_table(I2O_PARAMS_TABLE_GET, + d->controller, d->lct_data->tid, + 0xF000, -1, + NULL, 0, + &result, sizeof(result)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF005 Private Message Extensions (optional)"); + spin_unlock(&i2o_proc_lock); + return len; + } + + len += sprintf(buf+len, "Instance# OrgId FunctionCode\n"); + + for(i=0; i < result.row_count; i++) + { + len += sprintf(buf+len, "%0#9x ", result.extension[i].ext_instance); + len += sprintf(buf+len, "%0#6x ", result.extension[i].organization_id); + len += sprintf(buf+len, "%0#6x", result.extension[i].x_function_code); + + len += sprintf(buf+len, "\n"); + } + + if(result.more_flag) + len += sprintf(buf+len, "There is more...\n"); + + spin_unlock(&i2o_proc_lock); + + return len; +} + + +/* Generic group F006h - Authorized User Table (table) */ +int i2o_proc_read_authorized_users(char *buf, char **start, off_t offset, int len, + int *eof, void *data) +{ + struct i2o_device *d = (struct i2o_device*)data; + int token; + int i; + + struct + { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + u32 alternate_tid[64]; + } result; + + spin_lock(&i2o_proc_lock); + len = 0; + + token = i2o_query_table(I2O_PARAMS_TABLE_GET, + d->controller, d->lct_data->tid, + 0xF006, -1, + NULL, 0, + &result, sizeof(result)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF006 Autohorized User Table"); + spin_unlock(&i2o_proc_lock); + return len; + } + + if (result.row_count) + len += sprintf(buf+len, "# AlternateTid\n"); + + for(i=0; i < result.row_count; i++) + { + len += sprintf(buf+len, "%-2d", i); + len += sprintf(buf+len, "%#7x ", result.alternate_tid[i]); + } + + if (result.more_flag) + len += sprintf(buf+len, "There is more...\n"); + + spin_unlock(&i2o_proc_lock); + return len; +} + + +/* Generic group F100h - Device Identity (scalar) */ +int i2o_proc_read_dev_identity(char *buf, char **start, off_t offset, int len, + int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; static u32 work32[128]; // allow for "stuff" + up to 256 byte (max) serial number @@ -1240,14 +1377,11 @@ len = 0; token = i2o_query_scalar(d->controller, d->lct_data->tid, - 0xF100, // ParamGroup F100h (Device Identity) - -1, // all fields - &work32, - sizeof(work32)); + 0xF100, -1, + &work32, sizeof(work32)); - if(token < 0) - { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token ,"0xF100 Device Identity"); spin_unlock(&i2o_proc_lock); return len; } @@ -1290,44 +1424,45 @@ } - -int i2o_proc_read_ddm(char *buf, char **start, off_t offset, int len, - int *eof, void *data) +/* Generic group F101h - DDM Identity (scalar) */ +int i2o_proc_read_ddm_identity(char *buf, char **start, off_t offset, int len, + int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; - static u32 work32[128]; - static u16 *work16 = (u16*)work32; int token; + struct + { + u16 ddm_tid; + u8 module_name[24]; + u8 module_rev[8]; + u8 sn_format; + u8 serial_number[12]; + u8 pad[256]; // allow up to 256 byte (max) serial number + } result; + spin_lock(&i2o_proc_lock); len = 0; token = i2o_query_scalar(d->controller, d->lct_data->tid, - 0xF101, // ParamGroup F101h (DDM Identity) - -1, // all fields - &work32, - sizeof(work32)); + 0xF101, -1, + &result, sizeof(result)); - if(token < 0) - { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF101 DDM Identity"); spin_unlock(&i2o_proc_lock); return len; } - len += sprintf(buf, "Registering DDM TID : 0x%03x\n", work16[0]&0xFFF); - len += sprintf(buf+len, "Module name : %s\n", chtostr((u8 *)(work16+1), 24)); - len += sprintf(buf+len, "Module revision : %s\n", chtostr((u8 *)(work16+13), 8)); + len += sprintf(buf, "Registering DDM TID : 0x%03x\n", result.ddm_tid); + len += sprintf(buf+len, "Module name : %s\n", chtostr(result.module_name, 24)); + len += sprintf(buf+len, "Module revision : %s\n", chtostr(result.module_rev, 8)); len += sprintf(buf+len, "Serial number : "); - len = print_serial_number(buf, len, - (u8*)(work16+17), - /* allow for SNLen plus - * possible trailing '\0' - */ - sizeof(work32)-(17*sizeof(u16))-2 - ); + len = print_serial_number(buf, len, result.serial_number, sizeof(result)-36); + /* allow for SNLen plus possible trailing '\0' */ + len += sprintf(buf+len, "\n"); spin_unlock(&i2o_proc_lock); @@ -1335,41 +1470,44 @@ return len; } +/* Generic group F102h - User Information (scalar) */ int i2o_proc_read_uinfo(char *buf, char **start, off_t offset, int len, int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; - static u32 work32[256]; int token; - + + struct + { + u8 device_name[64]; + u8 service_name[64]; + u8 physical_location[64]; + u8 instance_number[4]; + } result; + spin_lock(&i2o_proc_lock); - len = 0; token = i2o_query_scalar(d->controller, d->lct_data->tid, - 0xF102, // ParamGroup F102h (User Information) - -1, // all fields - &work32, - sizeof(work32)); + 0xF102, -1, + &result, sizeof(result)); - if(token < 0) - { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF102 User Information"); spin_unlock(&i2o_proc_lock); return len; } - len += sprintf(buf, "Device name : %s\n", chtostr((u8 *)work32, 64)); - len += sprintf(buf+len, "Service name : %s\n", chtostr((u8 *)(work32+16), 64)); - len += sprintf(buf+len, "Physical name : %s\n", chtostr((u8 *)(work32+32), 64)); - len += sprintf(buf+len, "Instance number : %s\n", chtostr((u8 *)(work32+48), 4)); - - spin_unlock(&i2o_proc_lock); + len += sprintf(buf, "Device name : %s\n", chtostr(result.device_name, 64)); + len += sprintf(buf+len, "Service name : %s\n", chtostr(result.service_name, 64)); + len += sprintf(buf+len, "Physical name : %s\n", chtostr(result.physical_location, 64)); + len += sprintf(buf+len, "Instance number : %s\n", chtostr(result.instance_number, 4)); + spin_unlock(&i2o_proc_lock); return len; } - +/* Generic group F103h - SGL Operating Limits (scalar) */ int i2o_proc_read_sgl_limits(char *buf, char **start, off_t offset, int len, int *eof, void *data) { @@ -1384,14 +1522,11 @@ len = 0; token = i2o_query_scalar(d->controller, d->lct_data->tid, - 0xF103, // ParamGroup F103h (SGL Operating Limits) - -1, // all fields - &work32, - sizeof(work32)); + 0xF103, -1, + &work32, sizeof(work32)); - if(token < 0) - { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF103 SGL Operating Limits"); spin_unlock(&i2o_proc_lock); return len; } @@ -1424,6 +1559,164 @@ return len; } +/* Generic group F200h - Sensors (scalar) */ +int i2o_proc_read_sensors(char *buf, char **start, off_t offset, int len, + int *eof, void *data) +{ + struct i2o_device *d = (struct i2o_device*)data; + int token; + + struct + { + u16 sensor_instance; + u8 component; + u16 component_instance; + u8 sensor_class; + u8 sensor_type; + u8 scaling_exponent; + u32 actual_reading; + u32 minimum_reading; + u32 low2lowcat_treshold; + u32 lowcat2low_treshold; + u32 lowwarn2low_treshold; + u32 low2lowwarn_treshold; + u32 norm2lowwarn_treshold; + u32 lowwarn2norm_treshold; + u32 nominal_reading; + u32 hiwarn2norm_treshold; + u32 norm2hiwarn_treshold; + u32 high2hiwarn_treshold; + u32 hiwarn2high_treshold; + u32 hicat2high_treshold; + u32 hi2hicat_treshold; + u32 maximum_reading; + u8 sensor_state; + u16 event_enable; + } result; + + spin_lock(&i2o_proc_lock); + len = 0; + + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0xF200, -1, + &result, sizeof(result)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0xF200 Sensors (optional)"); + spin_unlock(&i2o_proc_lock); + return len; + } + + len += sprintf(buf+len, "Sensor instance : %d\n", result.sensor_instance); + + len += sprintf(buf+len, "Component : %d = ", result.component); + switch (result.component) + { + case 0: len += sprintf(buf+len, "Other"); + break; + case 1: len += sprintf(buf+len, "Planar logic Board"); + break; + case 2: len += sprintf(buf+len, "CPU"); + break; + case 3: len += sprintf(buf+len, "Chassis"); + break; + case 4: len += sprintf(buf+len, "Power Supply"); + break; + case 5: len += sprintf(buf+len, "Storage"); + break; + case 6: len += sprintf(buf+len, "External"); + break; + } + len += sprintf(buf+len,"\n"); + + len += sprintf(buf+len, "Component instance : %d\n", result.component_instance); + len += sprintf(buf+len, "Sensor class : %s\n", + result.sensor_class ? "Analog" : "Digital"); + + len += sprintf(buf+len, "Sensor type : %d = ",result.sensor_type); + switch (result.sensor_type) + { + case 0: len += sprintf(buf+len, "Other\n"); + break; + case 1: len += sprintf(buf+len, "Thermal\n"); + break; + case 2: len += sprintf(buf+len, "DC voltage (DC volts)\n"); + break; + case 3: len += sprintf(buf+len, "AC voltage (AC volts)\n"); + break; + case 4: len += sprintf(buf+len, "DC current (DC amps)\n"); + break; + case 5: len += sprintf(buf+len, "AC current (AC volts)\n"); + break; + case 6: len += sprintf(buf+len, "Door open\n"); + break; + case 7: len += sprintf(buf+len, "Fan operational\n"); + break; + } + + len += sprintf(buf+len, "Scaling exponent : %d\n", result.scaling_exponent); + len += sprintf(buf+len, "Actual reading : %d\n", result.actual_reading); + len += sprintf(buf+len, "Minimum reading : %d\n", result.minimum_reading); + len += sprintf(buf+len, "Low2LowCat treshold : %d\n", result.low2lowcat_treshold); + len += sprintf(buf+len, "LowCat2Low treshold : %d\n", result.lowcat2low_treshold); + len += sprintf(buf+len, "LowWarn2Low treshold : %d\n", result.lowwarn2low_treshold); + len += sprintf(buf+len, "Low2LowWarn treshold : %d\n", result.low2lowwarn_treshold); + len += sprintf(buf+len, "Norm2LowWarn treshold : %d\n", result.norm2lowwarn_treshold); + len += sprintf(buf+len, "LowWarn2Norm treshold : %d\n", result.lowwarn2norm_treshold); + len += sprintf(buf+len, "Nominal reading : %d\n", result.nominal_reading); + len += sprintf(buf+len, "HiWarn2Norm treshold : %d\n", result.hiwarn2norm_treshold); + len += sprintf(buf+len, "Norm2HiWarn treshold : %d\n", result.norm2hiwarn_treshold); + len += sprintf(buf+len, "High2HiWarn treshold : %d\n", result.high2hiwarn_treshold); + len += sprintf(buf+len, "HiWarn2High treshold : %d\n", result.hiwarn2high_treshold); + len += sprintf(buf+len, "HiCat2High treshold : %d\n", result.hicat2high_treshold); + len += sprintf(buf+len, "High2HiCat treshold : %d\n", result.hi2hicat_treshold); + len += sprintf(buf+len, "Maximum reading : %d\n", result.maximum_reading); + + len += sprintf(buf+len, "Sensor state : %d = ", result.sensor_state); + switch (result.sensor_state) + { + case 0: len += sprintf(buf+len, "Normal\n"); + break; + case 1: len += sprintf(buf+len, "Abnormal\n"); + break; + case 2: len += sprintf(buf+len, "Unknown\n"); + break; + case 3: len += sprintf(buf+len, "Low Catastrophic (LoCat)\n"); + break; + case 4: len += sprintf(buf+len, "Low (Low)\n"); + break; + case 5: len += sprintf(buf+len, "Low Warning (LoWarn)\n"); + break; + case 6: len += sprintf(buf+len, "High Warning (HiWarn)\n"); + break; + case 7: len += sprintf(buf+len, "High (High)\n"); + break; + case 8: len += sprintf(buf+len, "High Catastrophic (HiCat)\n"); + break; + } + + len += sprintf(buf+len, "Event_enable : 0x%02X\n", result.event_enable); + if (result.event_enable & 0x01) + len += sprintf(buf+len, "\tOperational state change. \n"); + if (result.event_enable & 0x02) + len += sprintf(buf+len, "\tLow catastrophic. \n"); + if (result.event_enable & 0x04) + len += sprintf(buf+len, "\tLow reading. \n"); + if (result.event_enable & 0x08) + len += sprintf(buf+len, "\tLow warning. \n"); + if (result.event_enable & 0x10) + len += sprintf(buf+len, "\tChange back to normal from out of range state. \n"); + if (result.event_enable & 0x20) + len += sprintf(buf+len, "\tHigh warning. \n"); + if (result.event_enable & 0x40) + len += sprintf(buf+len, "\tHigh reading. \n"); + if (result.event_enable & 0x80) + len += sprintf(buf+len, "\tHigh catastrophic. \n"); + + spin_unlock(&i2o_proc_lock); + return len; +} + static int print_serial_number(char *buff, int pos, u8 *serialno, int max_len) { @@ -1749,14 +2042,12 @@ int token; spin_lock(&i2o_proc_lock); - len = 0; 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"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token, "0x0000 LAN Device Info"); spin_unlock(&i2o_proc_lock); return len; } @@ -1877,9 +2168,8 @@ 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"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0001 LAN MAC Address"); spin_unlock(&i2o_proc_lock); return len; } @@ -1955,51 +2245,44 @@ int len, int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; - static u32 field32[64]; - static u8 *field8 = (u8 *)field32; - static u16 *field16 = (u16 *)field32; int token; int i; + u8 mc_addr[8]; + + struct + { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + u8 mc_addr[256][8]; + } result; spin_lock(&i2o_proc_lock); len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - d->controller, d->lct_data->tid, 0x0002, -1, - NULL, 0, &field32, sizeof(field32)); - - if (token<0) - switch (token) { - case -ETIMEDOUT: - len += sprintf(buf, "Timeout reading table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - case -ENOMEM: - len += sprintf(buf, "No free memory to read the table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - default: - len += sprintf(buf, "Error reading field. BlockStatus %d\n", - token); - spin_unlock(&i2o_proc_lock); - return len; - } - - len += sprintf(buf, "RowCount=%d, MoreFlag=%d\n", - field16[0], field16[1]); + d->controller, d->lct_data->tid, 0x0002, -1, + NULL, 0, &result, sizeof(result)); - field8=(u8 *)&field16[2]; + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x002 LAN Multicast MAC Address"); + spin_unlock(&i2o_proc_lock); + return len; + } - for(i=0; icontroller, d->lct_data->tid, 0x0003, -1, &work32, 9*4); - if(token < 0) - { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0003 LAN Batch Control"); spin_unlock(&i2o_proc_lock); return len; } @@ -2050,8 +2332,8 @@ work32[4]/10); } - len += sprintf(buf+len, "Max Rx batch count : %d\n", work32[5]); - len += sprintf(buf+len, "Max Rx batch delay : %d\n", work32[6]); + len += sprintf(buf+len, "Max Rx batch count : %d\n", work32[5]); + len += sprintf(buf+len, "Max Rx batch delay : %d\n", work32[6]); if(d->i2oversion == 0x00) { len += sprintf(buf+len, @@ -2079,9 +2361,8 @@ 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"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0004 LAN Operation"); spin_unlock(&i2o_proc_lock); return len; } @@ -2090,7 +2371,7 @@ len += sprintf(buf+len, "Transmission error reporting : %s\n", (work32[1]&1)?"on":"off"); len += sprintf(buf+len, "Bad packet handling : %s\n", - (work32[1]&0x2)?"by host":"by DDM"); + (work32[1]&0x2)?"by host":"by DDM"); len += sprintf(buf+len, "Packet orphan limit : %d\n", work32[2]); len += sprintf(buf+len, "Tx modes :\n"); @@ -2134,52 +2415,72 @@ int len, int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; - static u32 work32[9]; - static u8 *work8 = (u8*)work32; - static u64 *work64 = (u64*)work32; int token; + struct + { + u32 connector_type; + u32 connection_type; + u64 current_tx_wire_speed; + u64 current_rx_wire_speed; + u8 duplex_mode; + u8 link_status; + u8 reserved; + u8 duplex_mode_target; + u32 connector_type_target; + u32 connection_type_target; + } result; + spin_lock(&i2o_proc_lock); len = 0; 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"); + 0x0005, -1, &result, sizeof(result)); + if (token < 0) { + len += i2o_report_query_status(buf+len, token, "0x0005 LAN Media Operation"); spin_unlock(&i2o_proc_lock); return len; } len += sprintf(buf, "Connector type : %s\n", - i2o_get_connector_type(work32[0])); + i2o_get_connector_type(result.connector_type)); len += sprintf(buf+len, "Connection type : %s\n", - i2o_get_connection_type(work32[1])); - - len += sprintf(buf+len, "Current Tx wire speed : %d bps\n", (int)work64[1]); - len += sprintf(buf+len, "Current Rx wire speed : %d bps\n", (int)work64[2]); + i2o_get_connection_type(result.connection_type)); - len += sprintf(buf+len, "Duplex mode : %s duplex\n", - (work8[24]&1)?"Full":"Half"); + len += sprintf(buf+len, "Current Tx wire speed : %d bps\n", (int)result.current_tx_wire_speed); + len += sprintf(buf+len, "Current Rx wire speed : %d bps\n", (int)result.current_rx_wire_speed); + len += sprintf(buf+len, "Duplex mode : %s duplex\n", + (result.duplex_mode)?"Full":"Half"); + len += sprintf(buf+len, "Link status : "); - if(work8[25] == 0x00) + switch (result.link_status) + { + case 0x00: len += sprintf(buf+len, "Unknown\n"); - else if(work8[25] == 0x01) + break; + case 0x01: len += sprintf(buf+len, "Normal\n"); - else if(work8[25] == 0x02) + break; + case 0x02: len += sprintf(buf+len, "Failure\n"); - else if(work8[25] == 0x03) + break; + case 0x03: len += sprintf(buf+len, "Reset\n"); - else + break; + default: len += sprintf(buf+len, "Unspecified\n"); - - if (d->i2oversion == 0x00) { /* Reserved in 1.53 and 2.0 */ + } + + if (d->i2oversion == 0x00) /* Reserved in 1.53 and 2.0 */ + { len += sprintf(buf+len, "Bad packets handled by : %s\n", - (work8[26] == 0xFF)?"host":"DDM"); + (result.reserved == 0xFF)?"host":"DDM"); } - if (d->i2oversion != 0x00) { + else + { len += sprintf(buf+len, "Duplex mode target : "); - switch (work8[27]) { + switch (result.duplex_mode_target) + { case 0: len += sprintf(buf+len, "Half duplex\n"); break; @@ -2188,69 +2489,59 @@ break; default: len += sprintf(buf+len, "\n"); - break; } len += sprintf(buf+len, "Connector type target : %s\n", - i2o_get_connector_type(work32[7])); + i2o_get_connector_type(result.connector_type_target)); len += sprintf(buf+len, "Connection type target : %s\n", - i2o_get_connection_type(work32[8])); + i2o_get_connection_type(result.connection_type_target)); } spin_unlock(&i2o_proc_lock); return len; } -/* LAN group 0006h - Alternate address (table) */ +/* LAN group 0006h - Alternate address (table) (optional) */ int i2o_proc_read_lan_alt_addr(char *buf, char **start, off_t offset, int len, int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; - static u32 field32[64]; - static u8 *field8 = (u8 *)field32; - static u16 *field16 = (u16 *)field32; int token; int i; + u8 alt_addr[8]; + struct + { + u16 result_count; + u16 pad; + u16 block_size; + u8 block_status; + u8 error_info_size; + u16 row_count; + u16 more_flag; + u8 alt_addr[256][8]; + } result; spin_lock(&i2o_proc_lock); len = 0; token = i2o_query_table(I2O_PARAMS_TABLE_GET, - d->controller, d->lct_data->tid, 0x0006, -1, - NULL, 0, &field32, sizeof(field32)); + d->controller, d->lct_data->tid, + 0x0006, -1, NULL, 0, &result, sizeof(result)); - if (token<0) - switch (token) { - case -ETIMEDOUT: - len += sprintf(buf, "Timeout reading table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - case -ENOMEM: - len += sprintf(buf, "No free memory to read the table.\n"); - spin_unlock(&i2o_proc_lock); - return len; - break; - default: - len += sprintf(buf, "Error reading field. BlockStatus %d\n", - token); - spin_unlock(&i2o_proc_lock); - return len; - } - - len += sprintf(buf,"RowCount=%d, MoreFlag=%d\n", field16[0], - field16[1]); - - field8=(u8 *)&field16[2]; + if (token < 0) { + len += i2o_report_query_status(buf+len, token, "0x0006 LAN Alternate Address (optional)"); + spin_unlock(&i2o_proc_lock); + return len; + } - for(i=0; icontroller, d->lct_data->tid, 0x0007, -1, &work32, 8*4); - if(token < 0) - { - len += sprintf(buf, "Timeout waiting for reply from IOP\n"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0007 LAN Transmit Info"); spin_unlock(&i2o_proc_lock); return len; } @@ -2304,12 +2594,15 @@ len += sprintf(buf+len, " RSVP checksum\n"); if(work32[4]&0x00001000) len += sprintf(buf+len, " ICMP checksum\n"); - if (d->i2oversion == 0x00) { + if (d->i2oversion == 0x00) + { if(work32[4]&0x00008000) len += sprintf(buf+len, " Loopback enabled\n"); if(work32[4]&0x00010000) len += sprintf(buf+len, " Loopback suppression enabled\n"); - } else { + } + else + { if(work32[4]&0x00010000) len += sprintf(buf+len, " Loopback enabled\n"); if(work32[4]&0x00020000) @@ -2333,9 +2626,8 @@ 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"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0008 LAN Receive Info"); spin_unlock(&i2o_proc_lock); return len; } @@ -2354,288 +2646,345 @@ return len; } +static int i2o_report_opt_field(char *buf, char *field_name, + int field_nbr, int supp_fields, u64 *value) +{ + if (supp_fields & (1 << field_nbr)) + return sprintf(buf, "%-24s : " FMT_U64_HEX "\n", field_name, U64_VAL(value)); + else + return sprintf(buf, "%-24s : Not supported\n", field_name); +} /* LAN group 0100h - LAN Historical statistics (scalar) */ +/* LAN group 0180h - Supported Optional Historical Statistics (scalar) */ +/* LAN group 0182h - Optional Non Media Specific Transmit Historical Statistics (scalar) */ +/* LAN group 0183h - Optional Non Media Specific Receive Historical Statistics (scalar) */ + int i2o_proc_read_lan_hist_stats(char *buf, char **start, off_t offset, int len, int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; - static u64 work64[9]; int token; + struct + { + u64 tx_packets; + u64 tx_bytes; + u64 rx_packets; + u64 rx_bytes; + u64 tx_errors; + u64 rx_errors; + u64 rx_dropped; + u64 adapter_resets; + u64 adapter_suspends; + } stats; // 0x0100 + + static u64 supp_groups[4]; // 0x0180 + + struct + { + u64 tx_retries; + u64 tx_directed_bytes; + u64 tx_directed_packets; + u64 tx_multicast_bytes; + u64 tx_multicast_packets; + u64 tx_broadcast_bytes; + u64 tx_broadcast_packets; + u64 tx_group_addr_packets; + u64 tx_short_packets; + } tx_stats; // 0x0182 + + struct + { + u64 rx_crc_errors; + u64 rx_directed_bytes; + u64 rx_directed_packets; + u64 rx_multicast_bytes; + u64 rx_multicast_packets; + u64 rx_broadcast_bytes; + u64 rx_broadcast_packets; + u64 rx_group_addr_packets; + u64 rx_short_packets; + u64 rx_long_packets; + u64 rx_runt_packets; + } rx_stats; // 0x0183 + + struct + { + u64 ipv4_generate; + u64 ipv4_validate_success; + u64 ipv4_validate_errors; + u64 tcp_generate; + u64 tcp_validate_success; + u64 tcp_validate_errors; + u64 udp_generate; + u64 udp_validate_success; + u64 udp_validate_errors; + u64 rsvp_generate; + u64 rsvp_validate_success; + u64 rsvp_validate_errors; + u64 icmp_generate; + u64 icmp_validate_success; + u64 icmp_validate_errors; + } chksum_stats; // 0x0184 + spin_lock(&i2o_proc_lock); len = 0; 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"); + 0x0100, -1, &stats, sizeof(stats)); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x100 LAN Statistics"); spin_unlock(&i2o_proc_lock); return len; } - len += sprintf(buf, "Tx packets : " FMT_U64_HEX "\n", - U64_VAL(&work64[0])); + len += sprintf(buf+len, "Tx packets : " FMT_U64_HEX "\n", + U64_VAL(&stats.tx_packets)); len += sprintf(buf+len, "Tx bytes : " FMT_U64_HEX "\n", - U64_VAL(&work64[1])); + U64_VAL(&stats.tx_bytes)); len += sprintf(buf+len, "Rx packets : " FMT_U64_HEX "\n", - U64_VAL(&work64[2])); + U64_VAL(&stats.rx_packets)); len += sprintf(buf+len, "Rx bytes : " FMT_U64_HEX "\n", - U64_VAL(&work64[3])); + U64_VAL(&stats.rx_bytes)); len += sprintf(buf+len, "Tx errors : " FMT_U64_HEX "\n", - U64_VAL(&work64[4])); + U64_VAL(&stats.tx_errors)); len += sprintf(buf+len, "Rx errors : " FMT_U64_HEX "\n", - U64_VAL(&work64[5])); + U64_VAL(&stats.rx_errors)); len += sprintf(buf+len, "Rx dropped : " FMT_U64_HEX "\n", - U64_VAL(&work64[6])); + U64_VAL(&stats.rx_dropped)); len += sprintf(buf+len, "Adapter resets : " FMT_U64_HEX "\n", - U64_VAL(&work64[7])); + U64_VAL(&stats.adapter_resets)); len += sprintf(buf+len, "Adapter suspends : " FMT_U64_HEX "\n", - U64_VAL(&work64[8])); - - spin_unlock(&i2o_proc_lock); - return len; -} - - -/* LAN group 0180h - Supported Optional Historical Statistics (scalar) */ -int i2o_proc_read_lan_supp_opt_stats(char *buf, char **start, off_t offset, - int len, int *eof, void *data) -{ - struct i2o_device *d = (struct i2o_device*)data; - static u64 work64[4]; - int token; + U64_VAL(&stats.adapter_suspends)); - spin_lock(&i2o_proc_lock); - - len = 0; + /* Optional statistics follows */ + /* Get 0x0180 to see which optional groups/fields are supported */ 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"); + 0x0180, -1, &supp_groups, sizeof(supp_groups)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token, "0x180 LAN Supported Optional Statistics"); spin_unlock(&i2o_proc_lock); return len; } - if (d->i2oversion == 0x00) - len += sprintf(buf, "Supported stats : " FMT_U64_HEX " \n", - U64_VAL(&work64[0])); - else + if (supp_groups[1]) /* 0x0182 */ { - len += sprintf(buf, "Supported stats (0182h) : " FMT_U64_HEX " \n", - U64_VAL(&work64[1])); - len += sprintf(buf, "Supported stats (0183h) : " FMT_U64_HEX " \n", - U64_VAL(&work64[2])); - len += sprintf(buf, "Supported stats (0184h) : " FMT_U64_HEX " \n", - U64_VAL(&work64[3])); - } + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0182, -1, &tx_stats, sizeof(tx_stats)); - spin_unlock(&i2o_proc_lock); - return len; -} + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x182 LAN Optional Tx Historical Statistics"); + spin_unlock(&i2o_proc_lock); + return len; + } + len += sprintf(buf+len, "==== Optional TX statistics (group 0182h)\n"); -/* LAN group 0182h - Optional Non Media Specific Transmit Historical Statistics - * (scalar) */ -int i2o_proc_read_lan_opt_tx_hist_stats(char *buf, char **start, off_t offset, - int len, int *eof, void *data) -{ - struct i2o_device *d = (struct i2o_device*)data; - static u64 work64[9]; - int token; - - spin_lock(&i2o_proc_lock); + len += i2o_report_opt_field(buf+len, "Tx RetryCount", + 0, supp_groups[1], &tx_stats.tx_retries); + len += i2o_report_opt_field(buf+len, "Tx DirectedBytes", + 1, supp_groups[1], &tx_stats.tx_directed_bytes); + len += i2o_report_opt_field(buf+len, "Tx DirectedPackets", + 2, supp_groups[1], &tx_stats.tx_directed_packets); + len += i2o_report_opt_field(buf+len, "Tx MulticastBytes", + 3, supp_groups[1], &tx_stats.tx_multicast_bytes); + len += i2o_report_opt_field(buf+len, "Tx MulticastPackets", + 4, supp_groups[1], &tx_stats.tx_multicast_packets); + len += i2o_report_opt_field(buf+len, "Tx BroadcastBytes", + 5, supp_groups[1], &tx_stats.tx_broadcast_bytes); + len += i2o_report_opt_field(buf+len, "Tx BroadcastPackets", + 6, supp_groups[1], &tx_stats.tx_broadcast_packets); + len += i2o_report_opt_field(buf+len, "Tx TotalGroupAddrPackets", + 7, supp_groups[1], &tx_stats.tx_group_addr_packets); + len += i2o_report_opt_field(buf+len, "Tx TotalPacketsTooShort", + 8, supp_groups[1], &tx_stats.tx_short_packets); + } + + if (supp_groups[2]) /* 0x0183 */ + { + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0183, -1, &rx_stats, sizeof(rx_stats)); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x183 LAN Optional Rx Historical Stats"); + spin_unlock(&i2o_proc_lock); + return len; + } - len = 0; + len += sprintf(buf+len, "==== Optional RX statistics (group 0183h)\n"); - 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"); - spin_unlock(&i2o_proc_lock); - return len; + len += i2o_report_opt_field(buf+len, "Rx CRCErrorCount", + 0, supp_groups[2], &rx_stats.rx_crc_errors); + len += i2o_report_opt_field(buf+len, "Rx DirectedBytes", + 1, supp_groups[2], &rx_stats.rx_directed_bytes); + len += i2o_report_opt_field(buf+len, "Rx DirectedPackets", + 2, supp_groups[2], &rx_stats.rx_directed_packets); + len += i2o_report_opt_field(buf+len, "Rx MulticastBytes", + 3, supp_groups[2], &rx_stats.rx_multicast_bytes); + len += i2o_report_opt_field(buf+len, "Rx MulticastPackets", + 4, supp_groups[2], &rx_stats.rx_multicast_packets); + len += i2o_report_opt_field(buf+len, "Rx BroadcastBytes", + 5, supp_groups[2], &rx_stats.rx_broadcast_bytes); + len += i2o_report_opt_field(buf+len, "Rx BroadcastPackets", + 6, supp_groups[2], &rx_stats.rx_broadcast_packets); + len += i2o_report_opt_field(buf+len, "Rx TotalGroupAddrPackets", + 7, supp_groups[2], &rx_stats.rx_group_addr_packets); + len += i2o_report_opt_field(buf+len, "Rx TotalPacketsTooShort", + 8, supp_groups[2], &rx_stats.rx_short_packets); + len += i2o_report_opt_field(buf+len, "Rx TotalPacketsTooLong", + 9, supp_groups[2], &rx_stats.rx_long_packets); + len += i2o_report_opt_field(buf+len, "Rx TotalPacketsRunt", + 10, supp_groups[2], &rx_stats.rx_runt_packets); } + + if (supp_groups[3]) /* 0x0184 */ + { + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0184, -1, &chksum_stats, sizeof(chksum_stats)); - len += sprintf(buf, "TxRetryCount : " FMT_U64_HEX "\n", - U64_VAL(&work64[0])); - len += sprintf(buf+len, "DirectedBytesTx : " FMT_U64_HEX "\n", - U64_VAL(&work64[1])); - len += sprintf(buf+len, "DirectedPacketsTx : " FMT_U64_HEX "\n", - U64_VAL(&work64[2])); - len += sprintf(buf+len, "MulticastBytesTx : " FMT_U64_HEX "\n", - U64_VAL(&work64[3])); - len += sprintf(buf+len, "MulticastPacketsTx : " FMT_U64_HEX "\n", - U64_VAL(&work64[4])); - len += sprintf(buf+len, "BroadcastBytesTx : " FMT_U64_HEX "\n", - U64_VAL(&work64[5])); - len += sprintf(buf+len, "BroadcastPacketsTx : " FMT_U64_HEX "\n", - U64_VAL(&work64[6])); - len += sprintf(buf+len, "TotalGroupAddrTxCount : " FMT_U64_HEX "\n", - U64_VAL(&work64[7])); - len += sprintf(buf+len, "TotalTxPacketsTooShort : " FMT_U64_HEX "\n", - U64_VAL(&work64[8])); - - spin_unlock(&i2o_proc_lock); - return len; -} - -/* LAN group 0183h - Optional Non Media Specific Receive Historical Statistics - * (scalar) */ -int i2o_proc_read_lan_opt_rx_hist_stats(char *buf, char **start, off_t offset, - int len, int *eof, void *data) -{ - struct i2o_device *d = (struct i2o_device*)data; - static u64 work64[11]; - int token; - - spin_lock(&i2o_proc_lock); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x184 LAN Optional Chksum Historical Stats"); + spin_unlock(&i2o_proc_lock); + return len; + } - len = 0; + len += sprintf(buf+len, "==== Optional CHKSUM statistics (group 0x0184)\n"); - 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"); - spin_unlock(&i2o_proc_lock); - return len; + len += i2o_report_opt_field(buf+len, "IPv4 Generate", + 0, supp_groups[3], &chksum_stats.ipv4_generate); + len += i2o_report_opt_field(buf+len, "IPv4 ValidateSuccess", + 1, supp_groups[3], &chksum_stats.ipv4_validate_success); + len += i2o_report_opt_field(buf+len, "IPv4 ValidateError", + 2, supp_groups[3], &chksum_stats.ipv4_validate_errors); + len += i2o_report_opt_field(buf+len, "TCP Generate", + 3, supp_groups[3], &chksum_stats.tcp_generate); + len += i2o_report_opt_field(buf+len, "TCP ValidateSuccess", + 4, supp_groups[3], &chksum_stats.tcp_validate_success); + len += i2o_report_opt_field(buf+len, "TCP ValidateError", + 5, supp_groups[3], &chksum_stats.tcp_validate_errors); + len += i2o_report_opt_field(buf+len, "UDP Generate", + 6, supp_groups[3], &chksum_stats.udp_generate); + len += i2o_report_opt_field(buf+len, "UDP ValidateSuccess", + 7, supp_groups[3], &chksum_stats.udp_validate_success); + len += i2o_report_opt_field(buf+len, "UDP ValidateError", + 8, supp_groups[3], &chksum_stats.udp_validate_errors); + len += i2o_report_opt_field(buf+len, "RSVP Generate", + 9, supp_groups[3], &chksum_stats.rsvp_generate); + len += i2o_report_opt_field(buf+len, "RSVP ValidateSuccess", + 10, supp_groups[3], &chksum_stats.rsvp_validate_success); + len += i2o_report_opt_field(buf+len, "RSVP ValidateError", + 11, supp_groups[3], &chksum_stats.rsvp_validate_errors); + len += i2o_report_opt_field(buf+len, "ICMP Generate", + 12, supp_groups[3], &chksum_stats.icmp_generate); + len += i2o_report_opt_field(buf+len, "ICMP ValidateSuccess", + 13, supp_groups[3], &chksum_stats.icmp_validate_success); + len += i2o_report_opt_field(buf+len, "ICMP ValidateError", + 14, supp_groups[3], &chksum_stats.icmp_validate_errors); } - len += sprintf(buf, "ReceiveCRCErrorCount : " FMT_U64_HEX "\n", - U64_VAL(&work64[0])); - len += sprintf(buf+len, "DirectedBytesRx : " FMT_U64_HEX "\n", - U64_VAL(&work64[1])); - len += sprintf(buf+len, "DirectedPacketsRx : " FMT_U64_HEX "\n", - U64_VAL(&work64[2])); - len += sprintf(buf+len, "MulticastBytesRx : " FMT_U64_HEX "\n", - U64_VAL(&work64[3])); - len += sprintf(buf+len, "MulticastPacketsRx : " FMT_U64_HEX "\n", - U64_VAL(&work64[4])); - len += sprintf(buf+len, "BroadcastBytesRx : " FMT_U64_HEX "\n", - U64_VAL(&work64[5])); - len += sprintf(buf+len, "BroadcastPacketsRx : " FMT_U64_HEX "\n", - U64_VAL(&work64[6])); - len += sprintf(buf+len, "TotalGroupAddrRxCount : " FMT_U64_HEX "\n", - U64_VAL(&work64[7])); - len += sprintf(buf+len, "TotalRxPacketsTooShort : " FMT_U64_HEX "\n", - U64_VAL(&work64[8])); - len += sprintf(buf+len, "TotalRxPacketsTooLong : " FMT_U64_HEX "\n", - U64_VAL(&work64[9])); - len += sprintf(buf+len, "TotalRuntPacketsReceived : " FMT_U64_HEX "\n", - U64_VAL(&work64[10])); - spin_unlock(&i2o_proc_lock); return len; } /* LAN group 0200h - Required Ethernet Statistics (scalar) */ +/* LAN group 0280h - Optional Ethernet Statistics Supported (scalar) */ +/* LAN group 0281h - Optional Ethernet Historical Statistics (scalar) */ int i2o_proc_read_lan_eth_stats(char *buf, char **start, off_t offset, int len, int *eof, void *data) { struct i2o_device *d = (struct i2o_device*)data; - static u64 work64[8]; int token; + struct + { + u64 rx_align_errors; + u64 tx_one_collisions; + u64 tx_multiple_collisions; + u64 tx_deferred; + u64 tx_late_collisions; + u64 tx_max_collisions; + u64 tx_carrier_lost; + u64 tx_excessive_deferrals; + } stats; - spin_lock(&i2o_proc_lock); - + static u64 supp_fields; + struct + { + u64 rx_overrun; + u64 tx_underrun; + u64 tx_heartbeat_failure; + } hist_stats; + + spin_lock(&i2o_proc_lock); len = 0; - 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"); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0200, -1, &stats, sizeof(stats)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0200 LAN Ethernet Statistics"); spin_unlock(&i2o_proc_lock); return len; } - len += sprintf(buf, "Rx alignment errors : " FMT_U64_HEX "\n", - U64_VAL(&work64[0])); + len += sprintf(buf+len, "Rx alignment errors : " FMT_U64_HEX "\n", + U64_VAL(&stats.rx_align_errors)); len += sprintf(buf+len, "Tx one collisions : " FMT_U64_HEX "\n", - U64_VAL(&work64[1])); + U64_VAL(&stats.tx_one_collisions)); len += sprintf(buf+len, "Tx multicollisions : " FMT_U64_HEX "\n", - U64_VAL(&work64[2])); + U64_VAL(&stats.tx_multiple_collisions)); len += sprintf(buf+len, "Tx deferred : " FMT_U64_HEX "\n", - U64_VAL(&work64[3])); + U64_VAL(&stats.tx_deferred)); len += sprintf(buf+len, "Tx late collisions : " FMT_U64_HEX "\n", - U64_VAL(&work64[4])); + U64_VAL(&stats.tx_late_collisions)); len += sprintf(buf+len, "Tx max collisions : " FMT_U64_HEX "\n", - U64_VAL(&work64[5])); + U64_VAL(&stats.tx_max_collisions)); len += sprintf(buf+len, "Tx carrier lost : " FMT_U64_HEX "\n", - U64_VAL(&work64[6])); + U64_VAL(&stats.tx_carrier_lost)); len += sprintf(buf+len, "Tx excessive deferrals : " FMT_U64_HEX "\n", - U64_VAL(&work64[7])); - - spin_unlock(&i2o_proc_lock); - return len; -} - -/* LAN group 0280h - Supported Ethernet Historical Statistics (scalar) */ -int i2o_proc_read_lan_supp_eth_stats(char *buf, char **start, off_t offset, - int len, int *eof, void *data) -{ - struct i2o_device *d = (struct i2o_device*)data; - static u64 work64[1]; - int token; + U64_VAL(&stats.tx_excessive_deferrals)); - spin_lock(&i2o_proc_lock); + /* Optional Ethernet statistics follows */ + /* Get 0x0280 to see which optional fields are supported */ - len = 0; + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0280, -1, &supp_fields, sizeof(supp_fields)); - 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"); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0280 LAN Supported Optional Ethernet Statistics"); spin_unlock(&i2o_proc_lock); return len; } - len += sprintf(buf, "Supported stats : " FMT_U64_HEX "\n", - U64_VAL(&work64[0])); - - spin_unlock(&i2o_proc_lock); - return len; -} - -/* LAN group 0281h - Optional Ethernet Historical Statistics (scalar) */ -int i2o_proc_read_lan_opt_eth_stats(char *buf, char **start, off_t offset, - int len, int *eof, void *data) -{ - struct i2o_device *d = (struct i2o_device*)data; - static u64 work64[3]; - int token; + if (supp_fields) /* 0x0281 */ + { + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0281, -1, &stats, sizeof(stats)); - spin_lock(&i2o_proc_lock); + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0281 LAN Optional Ethernet Statistics"); + spin_unlock(&i2o_proc_lock); + return len; + } - len = 0; + len += sprintf(buf+len, "==== Optional ETHERNET statistics (group 0x0281)\n"); - 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"); - spin_unlock(&i2o_proc_lock); - return len; + len += i2o_report_opt_field(buf+len, "Rx Overrun", + 0, supp_fields, &hist_stats.rx_overrun); + len += i2o_report_opt_field(buf+len, "Tx Underrun", + 1, supp_fields, &hist_stats.tx_underrun); + len += i2o_report_opt_field(buf+len, "Tx HeartbeatFailure", + 2, supp_fields, &hist_stats.tx_heartbeat_failure); } - len += sprintf(buf, "Rx overrun : " FMT_U64_HEX "\n", - U64_VAL(&work64[0])); - len += sprintf(buf, "Tx underrun : " FMT_U64_HEX "\n", - U64_VAL(&work64[1])); - len += sprintf(buf, "Tx heartbeat failure : " FMT_U64_HEX "\n", - U64_VAL(&work64[2])); - spin_unlock(&i2o_proc_lock); return len; } /* LAN group 0300h - Required Token Ring Statistics (scalar) */ +/* LAN group 0380h, 0381h - Optional Statistics not yet defined (TODO) */ int i2o_proc_read_lan_tr_stats(char *buf, char **start, off_t offset, int len, int *eof, void *data) { @@ -2663,15 +3012,14 @@ "Signal Loss" }; - spin_lock(&i2o_proc_lock); - + spin_lock(&i2o_proc_lock); len = 0; - 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"); + token = i2o_query_scalar(d->controller, d->lct_data->tid, + 0x0300, -1, &work64, sizeof(work64)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0300 Token Ring Statistics"); spin_unlock(&i2o_proc_lock); return len; } @@ -2707,6 +3055,7 @@ } /* LAN group 0400h - Required FDDI Statistics (scalar) */ +/* LAN group 0480h, 0481h - Optional Statistics, not yet defined (TODO) */ int i2o_proc_read_lan_fddi_stats(char *buf, char **start, off_t offset, int len, int *eof, void *data) { @@ -2758,19 +3107,18 @@ }; spin_lock(&i2o_proc_lock); - len = 0; 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"); + 0x0400, -1, &work64, sizeof(work64)); + + if (token < 0) { + len += i2o_report_query_status(buf+len, token,"0x0400 FDDI Required Statistics"); spin_unlock(&i2o_proc_lock); return len; } - len += sprintf(buf, "ConfigurationState : %s\n", conf_state[work64[0]]); + len += sprintf(buf+len, "ConfigurationState : %s\n", conf_state[work64[0]]); len += sprintf(buf+len, "UpstreamNode : " FMT_U64_HEX "\n", U64_VAL(&work64[1])); len += sprintf(buf+len, "DownStreamNode : " FMT_U64_HEX "\n", @@ -2780,7 +3128,7 @@ len += sprintf(buf+len, "FramesLost : " FMT_U64_HEX "\n", U64_VAL(&work64[4])); len += sprintf(buf+len, "RingMgmtState : %s\n", ring_state[work64[5]]); - len += sprintf(buf+len, "LCTFailures: " FMT_U64_HEX "\n", + len += sprintf(buf+len, "LCTFailures : " FMT_U64_HEX "\n", U64_VAL(&work64[6])); len += sprintf(buf+len, "LEMRejects : " FMT_U64_HEX "\n", U64_VAL(&work64[7])); diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_proc.h linux/drivers/i2o/i2o_proc.h --- v2.3.26/linux/drivers/i2o/i2o_proc.h Mon Jul 5 20:09:40 1999 +++ linux/drivers/i2o/i2o_proc.h Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -#ifndef i2oproc_h -#define i2oproc_h - -/* - * Fixme: make this dependent on architecture - * The official header files to this already...but we can't use them - */ -#define I2O_64BIT_CONTEXT 0 - -typedef struct _i2o_msg { - u8 ver_offset; - u8 msg_flags; - u16 msg_size; - u32 target_addr:12; - u32 initiator_addr:12; - u32 function:8; - u32 init_context; /* FIXME: 64-bit support! */ -} i2o_msg, *pi2o_msg; - -typedef struct _i2o_reply_message { - i2o_msg msg_frame; - u32 tctx; /* FIXME: 64-bit */ - u16 detailed_status_code; - u8 reserved; - u8 req_status; -} i2o_reply_msg, *pi2o_reply_msg; - -typedef struct _i2o_mult_reply_message { - i2o_msg msg_frame; - u32 tctx; /* FIXME: 64-bit */ - u16 detailed_status_code; - u8 reserved; - u8 req_status; -} i2o_mult_reply_msg, *pi2o_mult_reply_msg; - -#endif /* i2oproc_h */ diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_scsi.c linux/drivers/i2o/i2o_scsi.c --- v2.3.26/linux/drivers/i2o/i2o_scsi.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/i2o/i2o_scsi.c Thu Nov 11 16:57:30 1999 @@ -59,10 +59,6 @@ #define MAXHOSTS 32 -struct proc_dir_entry proc_scsi_i2o_scsi = { - PROC_SCSI_I2O, 8, "i2o_scsi", S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - struct i2o_scsi_host { struct i2o_controller *controller; @@ -587,7 +583,7 @@ m = I2O_POST_READ32(c); } while(m==0xFFFFFFFF); - msg = c->mem_offset + m; + msg = (u32 *)(c->mem_offset + m); /* * Put together a scsi execscb message diff -u --recursive --new-file v2.3.26/linux/drivers/i2o/i2o_scsi.h linux/drivers/i2o/i2o_scsi.h --- v2.3.26/linux/drivers/i2o/i2o_scsi.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/i2o/i2o_scsi.h Thu Nov 11 16:57:30 1999 @@ -14,8 +14,6 @@ #define I2O_SCSI_CAN_QUEUE 4 #define I2O_SCSI_CMD_PER_LUN 6 -extern struct proc_dir_entry proc_scsi_i2o_scsi; - extern int i2o_scsi_detect(Scsi_Host_Template *); extern const char *i2o_scsi_info(struct Scsi_Host *); extern int i2o_scsi_command(Scsi_Cmnd *); @@ -27,7 +25,7 @@ #define I2OSCSI { \ next: NULL, \ - proc_dir: &proc_scsi_i2o_scsi, \ + proc_name: "i2o_scsi", \ name: "I2O SCSI Layer", \ detect: i2o_scsi_detect, \ release: i2o_scsi_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/Config.in linux/drivers/isdn/Config.in --- v2.3.26/linux/drivers/isdn/Config.in Fri Oct 15 15:25:13 1999 +++ linux/drivers/isdn/Config.in Tue Nov 9 10:09:02 1999 @@ -14,7 +14,7 @@ fi bool ' Support isdn diversion services' CONFIG_ISDN_DIVERSION if [ "$CONFIG_X25" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' X.25 PLP on top of ISDN (EXPERIMENTAL)' CONFIG_ISDN_X25 + bool ' X.25 PLP on top of ISDN (EXPERIMENTAL)' CONFIG_ISDN_X25 fi dep_tristate ' ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN dep_tristate ' isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN @@ -52,26 +52,28 @@ bool ' HiSax Support for Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO bool ' HiSax Support for Gazel cards' CONFIG_HISAX_GAZEL bool ' HiSax Support for HFC PCI-Bus cards' CONFIG_HISAX_HFC_PCI - if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' HiSax Support for Winbond W6692 based cards (EXPERIMENTAL)' CONFIG_HISAX_W6692 # bool ' HiSax Support for TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then bool ' HiSax Support for Am7930' CONFIG_HISAX_AMD7930 fi fi fi -if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then - dep_tristate ' Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN - dep_tristate ' IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN + dep_tristate ' IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN fi dep_tristate ' Eicon.Diehl active card support' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN if [ "$CONFIG_ISDN_DRV_EICON" != "n" ]; then - bool ' Eicon S, SX, SCOM, Quadro, S2M support' CONFIG_ISDN_DRV_EICON_ISA + bool ' Eicon S, SX, SCOM, Quadro, S2M support' CONFIG_ISDN_DRV_EICON_ISA fi dep_tristate ' AVM CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN if [ "$CONFIG_ISDN_DRV_AVMB1" != "n" ]; then bool ' AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA bool ' AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI - bool ' AVM T1/T1B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA + bool ' AVM T1/T1-B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA bool ' AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA + bool ' AVM T1/T1-B PCI support' CONFIG_ISDN_DRV_AVMB1_T1PCI bool ' Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON fi diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/act2000/act2000_isa.c linux/drivers/isdn/act2000/act2000_isa.c --- v2.3.26/linux/drivers/isdn/act2000/act2000_isa.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/act2000/act2000_isa.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: act2000_isa.c,v 1.8 1999/01/05 18:29:25 he Exp $ +/* $Id: act2000_isa.c,v 1.10 1999/10/24 18:46:05 fritz Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). * @@ -20,6 +20,13 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: act2000_isa.c,v $ + * Revision 1.10 1999/10/24 18:46:05 fritz + * Changed isa_ prefix to act2000_isa_ to prevent name-clash in latest + * kernels. + * + * Revision 1.9 1999/09/04 06:20:04 keil + * Changes from kernel set_current_state() + * * Revision 1.8 1999/01/05 18:29:25 he * merged remaining schedule_timeout() changes from 2.1.127 * @@ -61,17 +68,17 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static int isa_irqs[] = +static int act2000_isa_irqs[] = { 3, 5, 7, 10, 11, 12, 15 }; -#define ISA_NRIRQS (sizeof(isa_irqs)/sizeof(int)) +#define ISA_NRIRQS (sizeof(act2000_isa_irqs)/sizeof(int)) static void -isa_delay(long t) +act2000_isa_delay(long t) { sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(t); sti(); } @@ -83,7 +90,7 @@ * 0 = Signature not found. */ static int -isa_reset(unsigned short portbase) +act2000_isa_reset(unsigned short portbase) { unsigned char reg; int i; @@ -109,7 +116,7 @@ } int -isa_detect(unsigned short portbase) +act2000_isa_detect(unsigned short portbase) { int ret = 0; unsigned long flags; @@ -117,13 +124,13 @@ save_flags(flags); cli(); if (!check_region(portbase, ISA_REGION)) - ret = isa_reset(portbase); + ret = act2000_isa_reset(portbase); restore_flags(flags); return ret; } static void -isa_interrupt(int irq, void *dev_id, struct pt_regs *regs) +act2000_isa_interrupt(int irq, void *dev_id, struct pt_regs *regs) { act2000_card *card = irq2card_map[irq]; u_char istatus; @@ -138,7 +145,7 @@ /* RX fifo has data */ istatus &= ISA_ISR_OUT_MASK; outb(0, ISA_PORT_SIS); - isa_receive(card); + act2000_isa_receive(card); outb(ISA_SIS_INT, ISA_PORT_SIS); } if (istatus & ISA_ISR_ERR) { @@ -151,7 +158,7 @@ } static void -isa_select_irq(act2000_card * card) +act2000_isa_select_irq(act2000_card * card) { unsigned char reg; @@ -183,9 +190,9 @@ } static void -isa_enable_irq(act2000_card * card) +act2000_isa_enable_irq(act2000_card * card) { - isa_select_irq(card); + act2000_isa_select_irq(card); /* Enable READ irq */ outb(ISA_SIS_INT, ISA_PORT_SIS); } @@ -195,7 +202,7 @@ * If irq is -1, choose next free irq, else irq is given explicitely. */ int -isa_config_irq(act2000_card * card, short irq) +act2000_isa_config_irq(act2000_card * card, short irq) { int i; unsigned long flags; @@ -213,8 +220,8 @@ if (irq == -1) { /* Auto select */ for (i = 0; i < ISA_NRIRQS; i++) { - if (!request_irq(isa_irqs[i], &isa_interrupt, 0, card->regname, NULL)) { - card->irq = isa_irqs[i]; + if (!request_irq(act2000_isa_irqs[i], &act2000_isa_interrupt, 0, card->regname, NULL)) { + card->irq = act2000_isa_irqs[i]; irq2card_map[card->irq] = card; card->flags |= ACT2000_FLAGS_IVALID; break; @@ -222,7 +229,7 @@ } } else { /* Fixed irq */ - if (!request_irq(irq, &isa_interrupt, 0, card->regname, NULL)) { + if (!request_irq(irq, &act2000_isa_interrupt, 0, card->regname, NULL)) { card->irq = irq; irq2card_map[card->irq] = card; card->flags |= ACT2000_FLAGS_IVALID; @@ -234,7 +241,7 @@ "act2000: Could not request irq\n"); return -EBUSY; } else { - isa_select_irq(card); + act2000_isa_select_irq(card); /* Disable READ and WRITE irq */ outb(0, ISA_PORT_SIS); outb(0, ISA_PORT_SOS); @@ -243,7 +250,7 @@ } int -isa_config_port(act2000_card * card, unsigned short portbase) +act2000_isa_config_port(act2000_card * card, unsigned short portbase) { if (card->flags & ACT2000_FLAGS_PVALID) { release_region(card->port, ISA_REGION); @@ -262,7 +269,7 @@ * Release ressources, used by an adaptor. */ void -isa_release(act2000_card * card) +act2000_isa_release(act2000_card * card) { unsigned long flags; @@ -280,7 +287,7 @@ } static int -isa_writeb(act2000_card * card, u_char data) +act2000_isa_writeb(act2000_card * card, u_char data) { u_char timeout = 40; @@ -297,7 +304,7 @@ } static int -isa_readb(act2000_card * card, u_char * data) +act2000_isa_readb(act2000_card * card, u_char * data) { u_char timeout = 40; @@ -314,13 +321,13 @@ } void -isa_receive(act2000_card *card) +act2000_isa_receive(act2000_card *card) { u_char c; if (test_and_set_bit(ACT2000_LOCK_RX, (void *) &card->ilock) != 0) return; - while (!isa_readb(card, &c)) { + while (!act2000_isa_readb(card, &c)) { if (card->idat.isa.rcvidx < 8) { card->idat.isa.rcvhdr[card->idat.isa.rcvidx++] = c; if (card->idat.isa.rcvidx == 8) { @@ -332,7 +339,7 @@ if (card->idat.isa.rcvskb == NULL) { card->idat.isa.rcvignore = 1; printk(KERN_WARNING - "isa_receive: no memory\n"); + "act2000_isa_receive: no memory\n"); test_and_clear_bit(ACT2000_LOCK_RX, (void *) &card->ilock); return; } @@ -341,12 +348,12 @@ } else { card->idat.isa.rcvidx = 0; printk(KERN_WARNING - "isa_receive: Invalid CAPI msg\n"); + "act2000_isa_receive: Invalid CAPI msg\n"); { int i; __u8 *p; __u8 *c; __u8 tmp[30]; for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, c = tmp; i < 8; i++) c += sprintf(c, "%02x ", *(p++)); - printk(KERN_WARNING "isa_receive: %s\n", tmp); + printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp); } } } @@ -377,7 +384,7 @@ } void -isa_send(act2000_card * card) +act2000_isa_send(act2000_card * card) { unsigned long flags; struct sk_buff *skb; @@ -410,11 +417,8 @@ skb = card->sbuf; l = 0; while (skb->len) { - if (isa_writeb(card, *(skb->data))) { + if (act2000_isa_writeb(card, *(skb->data))) { /* Fifo is full, but more data to send */ -#if 0 - printk(KERN_DEBUG "isa_send: %d bytes\n", l); -#endif test_and_clear_bit(ACT2000_LOCK_TX, (void *) &card->ilock); /* Schedule myself */ act2000_schedule_tx(card); @@ -437,9 +441,6 @@ } else dev_kfree_skb(skb); card->sbuf = NULL; -#if 0 - printk(KERN_DEBUG "isa_send: %d bytes\n", l); -#endif } } @@ -447,7 +448,7 @@ * Get firmware ID, check for 'ISDN' signature. */ static int -isa_getid(act2000_card * card) +act2000_isa_getid(act2000_card * card) { act2000_fwid fid; @@ -457,7 +458,7 @@ while (1) { if (count > 510) return -EPROTO; - if (isa_readb(card, p++)) + if (act2000_isa_readb(card, p++)) break; count++; } @@ -476,7 +477,7 @@ printk(KERN_INFO "act2000: Firmware-ID: %s\n", fid.revision); if (card->flags & ACT2000_FLAGS_IVALID) { printk(KERN_DEBUG "Enabling Interrupts ...\n"); - isa_enable_irq(card); + act2000_isa_enable_irq(card); } return 0; } @@ -485,7 +486,7 @@ * Download microcode into card, check Firmware signature. */ int -isa_download(act2000_card * card, act2000_ddef * cb) +act2000_isa_download(act2000_card * card, act2000_ddef * cb) { int length; int ret; @@ -497,9 +498,9 @@ u_char *buf; act2000_ddef cblock; - if (!isa_reset(card->port)) + if (!act2000_isa_reset(card->port)) return -ENXIO; - isa_delay(HZ / 2); + act2000_isa_delay(HZ / 2); if ((ret = verify_area(VERIFY_READ, (void *) cb, sizeof(cblock)))) return ret; copy_from_user(&cblock, (char *) cb, sizeof(cblock)); @@ -517,7 +518,7 @@ b = buf; copy_from_user(buf, p, l); while (c < l) { - if (isa_writeb(card, *b++)) { + if (act2000_isa_writeb(card, *b++)) { printk(KERN_WARNING "act2000: loader timed out" " len=%d c=%d\n", length, c); @@ -530,6 +531,6 @@ p += l; } kfree(buf); - isa_delay(HZ / 2); - return (isa_getid(card)); + act2000_isa_delay(HZ / 2); + return (act2000_isa_getid(card)); } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/act2000/act2000_isa.h linux/drivers/isdn/act2000/act2000_isa.h --- v2.3.26/linux/drivers/isdn/act2000/act2000_isa.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/act2000/act2000_isa.h Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: act2000_isa.h,v 1.2 1998/11/05 22:12:43 fritz Exp $ +/* $Id: act2000_isa.h,v 1.3 1999/10/24 18:46:05 fritz Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version). * @@ -20,6 +20,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: act2000_isa.h,v $ + * Revision 1.3 1999/10/24 18:46:05 fritz + * Changed isa_ prefix to act2000_isa_ to prevent name-clash in latest + * kernels. + * * Revision 1.2 1998/11/05 22:12:43 fritz * Changed mail-address. * @@ -141,12 +145,12 @@ /* Prototypes */ -extern int isa_detect(unsigned short portbase); -extern int isa_config_irq(act2000_card * card, short irq); -extern int isa_config_port(act2000_card * card, unsigned short portbase); -extern int isa_download(act2000_card * card, act2000_ddef * cb); -extern void isa_release(act2000_card * card); -extern void isa_receive(act2000_card *card); -extern void isa_send(act2000_card *card); +extern int act2000_isa_detect(unsigned short portbase); +extern int act2000_isa_config_irq(act2000_card * card, short irq); +extern int act2000_isa_config_port(act2000_card * card, unsigned short portbase); +extern int act2000_isa_download(act2000_card * card, act2000_ddef * cb); +extern void act2000_isa_release(act2000_card * card); +extern void act2000_isa_receive(act2000_card *card); +extern void act2000_isa_send(act2000_card *card); #endif /* act2000_isa_h */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/act2000/capi.c linux/drivers/isdn/act2000/capi.c --- v2.3.26/linux/drivers/isdn/act2000/capi.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/act2000/capi.c Sun Nov 7 16:34:00 1999 @@ -113,10 +113,6 @@ {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"}, {{ 0x86, 0x03}, "DATA_B3_RESP"}, {{ 0xff, 0x03}, "MANUFACTURER_RESP"}, -#if 0 -/* CAPI 2.0 */ - {{ 0x05, 0x80}, "LISTEN_REQ (CAPI 2.0)"}, -#endif #endif {{ 0x00, 0x00}, NULL}, }; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/act2000/capi.h linux/drivers/isdn/act2000/capi.h --- v2.3.26/linux/drivers/isdn/act2000/capi.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/act2000/capi.h Sun Nov 7 16:34:00 1999 @@ -322,19 +322,6 @@ __u16 plci; __u16 info; } select_b3_protocol_conf; -#if 0 - struct listen_req { - __u32 controller; - __u32 infomask; - __u32 cipmask; - __u32 cipmask2; - __u16 dummy; /* 2 Length-bytes of 2 Structs MUST always be 0!!! */ - } listen_req; - struct listen_conf { - __u32 controller; - __u16 info; - } listen_conf; -#else struct listen_req { __u8 controller; __u32 infomask __attribute__ ((packed)); @@ -345,7 +332,6 @@ __u8 controller; __u16 info __attribute__ ((packed)); } listen_conf; -#endif struct data_b3_req { __u16 fakencci; __u16 datalen; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/act2000/module.c linux/drivers/isdn/act2000/module.c --- v2.3.26/linux/drivers/isdn/act2000/module.c Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/act2000/module.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: module.c,v 1.9 1999/04/12 13:13:56 fritz Exp $ +/* $Id: module.c,v 1.11 1999/10/30 09:48:04 keil Exp $ * * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000. * @@ -20,6 +20,13 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: module.c,v $ + * Revision 1.11 1999/10/30 09:48:04 keil + * miss one prefix act2000 + * + * Revision 1.10 1999/10/24 18:46:05 fritz + * Changed isa_ prefix to act2000_isa_ to prevent name-clash in latest + * kernels. + * * Revision 1.9 1999/04/12 13:13:56 fritz * Made cards pointer static to avoid name-clash. * @@ -56,12 +63,12 @@ #include "act2000_isa.h" #include "capi.h" -static unsigned short isa_ports[] = +static unsigned short act2000_isa_ports[] = { 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60, }; -#define ISA_NRPORTS (sizeof(isa_ports)/sizeof(unsigned short)) +#define ISA_NRPORTS (sizeof(act2000_isa_ports)/sizeof(unsigned short)) static act2000_card *cards = (act2000_card *) NULL; @@ -238,7 +245,7 @@ { switch (card->bus) { case ACT2000_BUS_ISA: - isa_send(card); + act2000_isa_send(card); break; case ACT2000_BUS_PCMCIA: case ACT2000_BUS_MCA: @@ -253,7 +260,7 @@ { switch (card->bus) { case ACT2000_BUS_ISA: - isa_receive(card); + act2000_isa_receive(card); break; case ACT2000_BUS_PCMCIA: case ACT2000_BUS_MCA: @@ -296,7 +303,7 @@ case ACT2000_IOCTL_LOADBOOT: switch (card->bus) { case ACT2000_BUS_ISA: - ret = isa_download(card, + ret = act2000_isa_download(card, (act2000_ddef *)a); if (!ret) { card->flags |= ACT2000_FLAGS_LOADED; @@ -701,10 +708,6 @@ card->interface.features = ISDN_FEATURE_L2_X75I | ISDN_FEATURE_L2_HDLC | -#if 0 -/* Not yet! New Firmware is on the way ... */ - ISDN_FEATURE_L2_TRANS | -#endif ISDN_FEATURE_L3_TRANS | ISDN_FEATURE_P_UNKNOWN; card->interface.hl_hdrlen = 20; @@ -762,7 +765,7 @@ card->interface.statcallb(&cmd); switch (card->bus) { case ACT2000_BUS_ISA: - isa_release(card); + act2000_isa_release(card); break; case ACT2000_BUS_MCA: case ACT2000_BUS_PCMCIA: @@ -796,11 +799,11 @@ switch (bus) { case ACT2000_BUS_ISA: for (i = 0; i < ISA_NRPORTS; i++) - if (isa_detect(isa_ports[i])) { + if (act2000_isa_detect(act2000_isa_ports[i])) { printk(KERN_INFO "act2000: Detected ISA card at port 0x%x\n", - isa_ports[i]); - act2000_alloccard(bus, isa_ports[i], irq, id); + act2000_isa_ports[i]); + act2000_alloccard(bus, act2000_isa_ports[i], irq, id); } break; case ACT2000_BUS_MCA: @@ -823,10 +826,10 @@ added++; switch (p->bus) { case ACT2000_BUS_ISA: - if (isa_detect(p->port)) { + if (act2000_isa_detect(p->port)) { if (act2000_registercard(p)) break; - if (isa_config_port(p, p->port)) { + if (act2000_isa_config_port(p, p->port)) { printk(KERN_WARNING "act2000: Could not request port 0x%04x\n", p->port); @@ -834,7 +837,7 @@ p->interface.statcallb = NULL; break; } - if (isa_config_irq(p, p->irq)) { + if (act2000_isa_config_irq(p, p->irq)) { printk(KERN_INFO "act2000: No IRQ available, fallback to polling\n"); /* Fall back to polled operation */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/Makefile linux/drivers/isdn/avmb1/Makefile --- v2.3.26/linux/drivers/isdn/avmb1/Makefile Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/Makefile Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ # -# $Id: Makefile,v 1.6 1999/07/20 06:41:44 calle Exp $ +# $Id: Makefile,v 1.7 1999/09/15 08:16:03 calle Exp $ # # Makefile for the CAPI and AVM-B1 device drivers. # @@ -11,6 +11,9 @@ # parent makes.. # # $Log: Makefile,v $ +# Revision 1.7 1999/09/15 08:16:03 calle +# Implementation of 64Bit extention complete. +# # Revision 1.6 1999/07/20 06:41:44 calle # Bugfix: After the redesign of the AVM B1 driver, the driver didn't even # compile, if not selected as modules. @@ -90,6 +93,12 @@ ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA OX_OBJS += b1pcmcia.o endif + ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI + O_OBJS += t1pci.o + endif + ifdef CONFIG_ISDN_DRV_AVMB1_C4 + O_OBJS += c4.o + endif OX_OBJS += capiutil.o capidrv.o b1.o else ifeq ($(CONFIG_ISDN_DRV_AVMB1),m) @@ -105,10 +114,16 @@ ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA M_OBJS += t1isa.o endif - MX_OBJS += capiutil.o capidrv.o b1.o ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA MX_OBJS += b1pcmcia.o endif + ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI + M_OBJS += t1pci.o + endif + ifdef CONFIG_ISDN_DRV_AVMB1_C4 + M_OBJS += c4.o + endif + MX_OBJS += capiutil.o capidrv.o b1.o endif endif diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/avmcard.h linux/drivers/isdn/avmb1/avmcard.h --- v2.3.26/linux/drivers/isdn/avmb1/avmcard.h Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/avmcard.h Sun Nov 7 16:34:00 1999 @@ -1,9 +1,21 @@ /* - * $Id: avmcard.h,v 1.4 1999/08/04 10:10:08 calle Exp $ + * $Id: avmcard.h,v 1.6 1999/11/05 16:38:01 calle Exp $ * * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: avmcard.h,v $ + * Revision 1.6 1999/11/05 16:38:01 calle + * Cleanups before kernel 2.4: + * - Changed all messages to use card->name or driver->name instead of + * constant string. + * - Moved some data from struct avmcard into new struct avmctrl_info. + * Changed all lowlevel capi driver to match the new structur. + * + * Revision 1.5 1999/09/07 09:02:53 calle + * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and + * DATA_B3_IND is always directly after the CAPI message. The "Data" member + * ist never used inside the kernel. + * * Revision 1.4 1999/08/04 10:10:08 calle * Bugfix: corrected /proc functions, added structure for new AVM cards. * @@ -73,6 +85,7 @@ __u8 sendbuf[128+2048]; } avmcard_dmainfo; + typedef struct avmcard { char name[32]; unsigned int port; @@ -81,25 +94,34 @@ enum avmcardtype cardtype; int cardnr; /* for t1isa */ - int versionlen; - char versionbuf[1024]; - char *version[AVM_MAXVERSION]; - - char cardname[32]; - - char infobuf[128]; /* for function procinfo */ char msgbuf[128]; /* capimsg msg part */ char databuf[2048]; /* capimsg data part */ int interrupt; void *mbase; - __u32 csr; + volatile __u32 csr; avmcard_dmainfo *dma; - struct capi_ctr *ctrl; + struct avmctrl_info { + char cardname[32]; + + int versionlen; + char versionbuf[1024]; + char *version[AVM_MAXVERSION]; + + char infobuf[128]; /* for function procinfo */ + + struct avmcard *card; + struct capi_ctr *capi_ctrl; + + } *ctrlinfo; + + int nlogcontr; } avmcard; +typedef struct avmctrl_info avmctrl_info; + extern int b1_irq_table[16]; /* @@ -540,16 +562,16 @@ } int b1_detect(unsigned int base, enum avmcardtype cardtype); -int b1_load_t4file(unsigned int base, capiloaddatapart * t4file); -int b1_load_config(unsigned int base, capiloaddatapart * config); -int b1_loaded(unsigned int base); +int b1_load_t4file(avmcard *card, capiloaddatapart * t4file); +int b1_load_config(avmcard *card, capiloaddatapart * config); +int b1_loaded(avmcard *card); int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data); void b1_reset_ctr(struct capi_ctr *ctrl); void b1_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp); void b1_release_appl(struct capi_ctr *ctrl, __u16 appl); void b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); -void b1_parse_version(avmcard *card); +void b1_parse_version(avmctrl_info *card); void b1_handle_interrupt(avmcard * card); int b1ctl_read_proc(char *page, char **start, off_t off, diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c --- v2.3.26/linux/drivers/isdn/avmb1/b1.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/avmb1/b1.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,29 @@ /* - * $Id: b1.c,v 1.8 1999/08/22 20:26:22 calle Exp $ + * $Id: b1.c,v 1.12 1999/11/05 16:38:01 calle Exp $ * * Common module for AVM B1 cards. * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: b1.c,v $ + * Revision 1.12 1999/11/05 16:38:01 calle + * Cleanups before kernel 2.4: + * - Changed all messages to use card->name or driver->name instead of + * constant string. + * - Moved some data from struct avmcard into new struct avmctrl_info. + * Changed all lowlevel capi driver to match the new structur. + * + * Revision 1.11 1999/10/11 22:04:12 keil + * COMPAT_NEED_UACCESS (no include in isdn_compat.h) + * + * Revision 1.10 1999/09/15 08:16:03 calle + * Implementation of 64Bit extention complete. + * + * Revision 1.9 1999/09/07 09:02:53 calle + * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and + * DATA_B3_IND is always directly after the CAPI message. The "Data" member + * ist never used inside the kernel. + * * Revision 1.8 1999/08/22 20:26:22 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -62,13 +80,13 @@ #include #include #include -#include +#include #include "capilli.h" #include "avmcard.h" #include "capicmd.h" #include "capiutil.h" -static char *revision = "$Revision: 1.8 $"; +static char *revision = "$Revision: 1.12 $"; /* ------------------------------------------------------------- */ @@ -140,11 +158,12 @@ return 0; } -int b1_load_t4file(unsigned int base, capiloaddatapart * t4file) +int b1_load_t4file(avmcard *card, capiloaddatapart * t4file) { unsigned char buf[256]; unsigned char *dp; int i, left, retval; + unsigned int base = card->port; dp = t4file->data; left = t4file->len; @@ -158,7 +177,8 @@ } for (i = 0; i < sizeof(buf); i++) if (b1_save_put_byte(base, buf[i]) < 0) { - printk(KERN_ERR "b1_load_t4file: corrupted t4 file ?\n"); + printk(KERN_ERR "%s: corrupted firmware file ?\n", + card->name); return -EIO; } left -= sizeof(buf); @@ -174,17 +194,19 @@ } for (i = 0; i < left; i++) if (b1_save_put_byte(base, buf[i]) < 0) { - printk(KERN_ERR "b1_load_t4file: corrupted t4 file ?\n"); + printk(KERN_ERR "%s: corrupted firmware file ?\n", + card->name); return -EIO; } } return 0; } -int b1_load_config(unsigned int base, capiloaddatapart * config) +int b1_load_config(avmcard *card, capiloaddatapart * config) { unsigned char buf[256]; unsigned char *dp; + unsigned int base = card->port; int i, j, left, retval; dp = config->data; @@ -233,8 +255,9 @@ return 0; } -int b1_loaded(unsigned int base) +int b1_loaded(avmcard *card) { + unsigned int base = card->port; unsigned long stop; unsigned char ans; unsigned long tout = 2; @@ -244,7 +267,8 @@ break; } if (!b1_tx_empty(base)) { - printk(KERN_ERR "b1_loaded: tx err, corrupted t4 file ?\n"); + printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?\n", + card->name); return 0; } b1_put_byte(base, SEND_POLL); @@ -253,11 +277,12 @@ if ((ans = b1_get_byte(base)) == RECEIVE_POLL) { return 1; } - printk(KERN_ERR "b1_loaded: got 0x%x, firmware not running\n", ans); + printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not running\n", + card->name, ans); return 0; } } - printk(KERN_ERR "b1_loaded: firmware not running\n"); + printk(KERN_ERR "%s: b1_loaded: firmware not running\n", card->name); return 0; } @@ -265,14 +290,15 @@ int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; unsigned long flags; int retval; b1_reset(port); - if ((retval = b1_load_t4file(port, &data->firmware))) { + if ((retval = b1_load_t4file(card, &data->firmware))) { b1_reset(port); printk(KERN_ERR "%s: failed to load t4file!!\n", card->name); @@ -282,7 +308,7 @@ b1_disable_irq(port); if (data->configuration.len > 0 && data->configuration.data) { - if ((retval = b1_load_config(port, &data->configuration))) { + if ((retval = b1_load_config(card, &data->configuration))) { b1_reset(port); printk(KERN_ERR "%s: failed to load config!!\n", card->name); @@ -290,7 +316,7 @@ } } - if (!b1_loaded(port)) { + if (!b1_loaded(card)) { printk(KERN_ERR "%s: failed to load t4file.\n", card->name); return -EIO; } @@ -309,13 +335,14 @@ void b1_reset_ctr(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; b1_reset(port); b1_reset(port); - memset(card->version, 0, sizeof(card->version)); + memset(cinfo->version, 0, sizeof(cinfo->version)); ctrl->reseted(ctrl); } @@ -323,7 +350,8 @@ __u16 appl, capi_register_params *rp) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; unsigned long flags; int nconn, want = rp->level3cnt; @@ -347,7 +375,8 @@ void b1_release_appl(struct capi_ctr *ctrl, __u16 appl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; unsigned long flags; @@ -360,7 +389,8 @@ void b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; unsigned long flags; __u16 len = CAPIMSG_LEN(skb->data); @@ -384,25 +414,26 @@ /* ------------------------------------------------------------- */ -void b1_parse_version(avmcard *card) +void b1_parse_version(avmctrl_info *cinfo) { - struct capi_ctr *ctrl = card->ctrl; + struct capi_ctr *ctrl = cinfo->capi_ctrl; + avmcard *card = cinfo->card; capi_profile *profp; __u8 *dversion; __u8 flag; int i, j; for (j = 0; j < AVM_MAXVERSION; j++) - card->version[j] = "\0\0" + 1; + cinfo->version[j] = "\0\0" + 1; for (i = 0, j = 0; - j < AVM_MAXVERSION && i < card->versionlen; - j++, i += card->versionbuf[i] + 1) - card->version[j] = &card->versionbuf[i + 1]; + j < AVM_MAXVERSION && i < cinfo->versionlen; + j++, i += cinfo->versionbuf[i] + 1) + cinfo->version[j] = &cinfo->versionbuf[i + 1]; - strncpy(ctrl->serial, card->version[VER_SERIAL], CAPI_SERIAL_LEN); - memcpy(&ctrl->profile, card->version[VER_PROFILE],sizeof(capi_profile)); + strncpy(ctrl->serial, cinfo->version[VER_SERIAL], CAPI_SERIAL_LEN); + memcpy(&ctrl->profile, cinfo->version[VER_PROFILE],sizeof(capi_profile)); strncpy(ctrl->manu, "AVM GmbH", CAPI_MANUFACTURER_LEN); - dversion = card->version[VER_DRIVER]; + dversion = cinfo->version[VER_DRIVER]; ctrl->version.majorversion = 2; ctrl->version.minorversion = 0; ctrl->version.majormanuversion = (((dversion[0] - '0') & 0xf) << 4); @@ -415,23 +446,24 @@ flag = ((__u8 *)(profp->manu))[1]; switch (flag) { - case 0: if (card->version[VER_CARDTYPE]) - strcpy(card->cardname, card->version[VER_CARDTYPE]); - else strcpy(card->cardname, "B1"); + case 0: if (cinfo->version[VER_CARDTYPE]) + strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]); + else strcpy(cinfo->cardname, "B1"); break; - case 3: strcpy(card->cardname,"PCMCIA B"); break; - case 4: strcpy(card->cardname,"PCMCIA M1"); break; - case 5: strcpy(card->cardname,"PCMCIA M2"); break; - case 6: strcpy(card->cardname,"B1 V3.0"); break; - case 7: strcpy(card->cardname,"B1 PCI"); break; - default: sprintf(card->cardname, "AVM?%u", (unsigned int)flag); break; + case 3: strcpy(cinfo->cardname,"PCMCIA B"); break; + case 4: strcpy(cinfo->cardname,"PCMCIA M1"); break; + case 5: strcpy(cinfo->cardname,"PCMCIA M2"); break; + case 6: strcpy(cinfo->cardname,"B1 V3.0"); break; + case 7: strcpy(cinfo->cardname,"B1 PCI"); break; + default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break; } printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n", - card->name, ctrl->cnr, card->cardname); + card->name, ctrl->cnr, cinfo->cardname); flag = ((__u8 *)(profp->manu))[3]; if (flag) - printk(KERN_NOTICE "b1capi: card %d Protocol:%s%s%s%s%s%s%s\n", + printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%s\n", + card->name, ctrl->cnr, (flag & 0x01) ? " DSS1" : "", (flag & 0x02) ? " CT1" : "", @@ -458,7 +490,8 @@ void b1_handle_interrupt(avmcard * card) { - struct capi_ctr *ctrl = card->ctrl; + avmctrl_info *cinfo = &card->ctrlinfo[0]; + struct capi_ctr *ctrl = cinfo->capi_ctrl; unsigned char b1cmd; struct sk_buff *skb; @@ -481,13 +514,17 @@ MsgLen = b1_get_slice(card->port, card->msgbuf); DataB3Len = b1_get_slice(card->port, card->databuf); + if (MsgLen < 30) { /* not CAPI 64Bit */ + memset(card->msgbuf+MsgLen, 0, 30-MsgLen); + MsgLen = 30; + CAPIMSG_SETLEN(card->msgbuf, 30); + } if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); - CAPIMSG_SETDATA(skb->data, skb->data + MsgLen); ctrl->handle_capimsg(ctrl, ApplId, skb); } break; @@ -536,12 +573,12 @@ case RECEIVE_INIT: - card->versionlen = b1_get_slice(card->port, card->versionbuf); - b1_parse_version(card); + cinfo->versionlen = b1_get_slice(card->port, cinfo->versionbuf); + b1_parse_version(cinfo); printk(KERN_INFO "%s: %s-card (%s) now active\n", card->name, - card->version[VER_CARDTYPE], - card->version[VER_DRIVER]); + cinfo->version[VER_CARDTYPE], + cinfo->version[VER_DRIVER]); ctrl->ready(ctrl); break; @@ -581,7 +618,8 @@ int b1ctl_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; __u8 flag; int len = 0; char *s; @@ -603,11 +641,11 @@ len += sprintf(page+len, "%-16s %s\n", "type", s); if (card->cardtype == avm_t1isa) len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr); - if ((s = card->version[VER_DRIVER]) != 0) + if ((s = cinfo->version[VER_DRIVER]) != 0) len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); - if ((s = card->version[VER_CARDTYPE]) != 0) + if ((s = cinfo->version[VER_CARDTYPE]) != 0) len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); - if ((s = card->version[VER_SERIAL]) != 0) + if ((s = cinfo->version[VER_SERIAL]) != 0) len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); if (card->cardtype != avm_m1) { @@ -635,7 +673,7 @@ (flag & 0x04) ? " leased line with D-channel" : "" ); } - len += sprintf(page+len, "%-16s %s\n", "cardname", card->cardname); + len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); if (off+count >= len) *eof = 1; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c --- v2.3.26/linux/drivers/isdn/avmb1/b1isa.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/avmb1/b1isa.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,18 @@ /* - * $Id: b1isa.c,v 1.4 1999/08/22 20:26:24 calle Exp $ + * $Id: b1isa.c,v 1.5 1999/11/05 16:38:01 calle Exp $ * * Module for AVM B1 ISA-card. * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: b1isa.c,v $ + * Revision 1.5 1999/11/05 16:38:01 calle + * Cleanups before kernel 2.4: + * - Changed all messages to use card->name or driver->name instead of + * constant string. + * - Moved some data from struct avmcard into new struct avmctrl_info. + * Changed all lowlevel capi driver to match the new structur. + * * Revision 1.4 1999/08/22 20:26:24 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -49,13 +56,12 @@ #include #include #include -#include #include "capicmd.h" #include "capiutil.h" #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.4 $"; +static char *revision = "$Revision: 1.5 $"; /* ------------------------------------------------------------- */ @@ -92,7 +98,8 @@ static void b1isa_remove_ctr(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; b1_reset(port); @@ -101,6 +108,7 @@ di->detach_ctr(ctrl); free_irq(card->irq, card); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); MOD_DEC_USE_COUNT; @@ -110,6 +118,7 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p) { + avmctrl_info *cinfo; avmcard *card; int retval; @@ -120,6 +129,15 @@ return -ENOMEM; } memset(card, 0, sizeof(avmcard)); + cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC); + if (!cinfo) { + printk(KERN_WARNING "b1isa: no memory.\n"); + kfree(card); + return -ENOMEM; + } + memset(cinfo, 0, sizeof(avmctrl_info)); + card->ctrlinfo = cinfo; + cinfo->card = card; sprintf(card->name, "b1isa-%x", p->port); card->port = p->port; card->irq = p->irq; @@ -129,17 +147,20 @@ printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n", card->port, card->port + AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } if (b1_irq_table[card->irq & 0xf] == 0) { printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq); + kfree(card->ctrlinfo); kfree(card); return -EINVAL; } if ( card->port != 0x150 && card->port != 0x250 && card->port != 0x300 && card->port != 0x340) { printk(KERN_WARNING "b1isa: illegal port 0x%x.\n", card->port); + kfree(card->ctrlinfo); kfree(card); return -EINVAL; } @@ -147,6 +168,7 @@ if ((retval = b1_detect(card->port, card->cardtype)) != 0) { printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n", card->port, retval); + kfree(card->ctrlinfo); kfree(card); return -EIO; } @@ -158,15 +180,17 @@ if (retval) { printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } - card->ctrl = di->attach_ctr(driver, card->name, card); - if (!card->ctrl) { + cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); + if (!cinfo->capi_ctrl) { printk(KERN_ERR "b1isa: attach controller failed.\n"); free_irq(card->irq, card); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } @@ -177,15 +201,17 @@ static char *b1isa_procinfo(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); - if (!card) + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + + if (!cinfo) return ""; - sprintf(card->infobuf, "%s %s 0x%x %d", - card->cardname[0] ? card->cardname : "-", - card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", - card->port, card->irq + sprintf(cinfo->infobuf, "%s %s 0x%x %d", + cinfo->cardname[0] ? cinfo->cardname : "-", + cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", + cinfo->card ? cinfo->card->port : 0x0, + cinfo->card ? cinfo->card->irq : 0 ); - return card->infobuf; + return cinfo->infobuf; } /* ------------------------------------------------------------- */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c --- v2.3.26/linux/drivers/isdn/avmb1/b1pci.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/b1pci.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,21 @@ /* - * $Id: b1pci.c,v 1.16 1999/08/11 21:01:07 keil Exp $ + * $Id: b1pci.c,v 1.18 1999/11/05 16:38:01 calle Exp $ * * Module for AVM B1 PCI-card. * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: b1pci.c,v $ + * Revision 1.18 1999/11/05 16:38:01 calle + * Cleanups before kernel 2.4: + * - Changed all messages to use card->name or driver->name instead of + * constant string. + * - Moved some data from struct avmcard into new struct avmctrl_info. + * Changed all lowlevel capi driver to match the new structur. + * + * Revision 1.17 1999/10/05 06:50:07 calle + * Forgot SA_SHIRQ as argument to request_irq. + * * Revision 1.16 1999/08/11 21:01:07 keil * new PCI codefix * @@ -51,13 +61,12 @@ #include #include #include -#include #include "capicmd.h" #include "capiutil.h" #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.16 $"; +static char *revision = "$Revision: 1.18 $"; /* ------------------------------------------------------------- */ @@ -86,11 +95,11 @@ card = (avmcard *) devptr; if (!card) { - printk(KERN_WARNING "b1_interrupt: wrong device\n"); + printk(KERN_WARNING "b1pci: interrupt: wrong device\n"); return; } if (card->interrupt) { - printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name); + printk(KERN_ERR "%s: reentering interrupt hander.\n", card->name); return; } @@ -104,7 +113,8 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; b1_reset(port); @@ -114,6 +124,7 @@ free_irq(card->irq, card); release_region(card->port, AVMB1_PORTLEN); ctrl->driverdata = 0; + kfree(card->ctrlinfo); kfree(card); MOD_DEC_USE_COUNT; @@ -123,15 +134,17 @@ static char *b1pci_procinfo(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); - if (!card) + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + + if (!cinfo) return ""; - sprintf(card->infobuf, "%s %s 0x%x %d", - card->cardname[0] ? card->cardname : "-", - card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", - card->port, card->irq + sprintf(cinfo->infobuf, "%s %s 0x%x %d", + cinfo->cardname[0] ? cinfo->cardname : "-", + cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", + cinfo->card ? cinfo->card->port : 0x0, + cinfo->card ? cinfo->card->irq : 0 ); - return card->infobuf; + return cinfo->infobuf; } /* ------------------------------------------------------------- */ @@ -139,15 +152,25 @@ static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p) { avmcard *card; + avmctrl_info *cinfo; int retval; card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); if (!card) { - printk(KERN_WARNING "b1pci: no memory.\n"); + printk(KERN_WARNING "%s: no memory.\n", driver->name); return -ENOMEM; } memset(card, 0, sizeof(avmcard)); + cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC); + if (!cinfo) { + printk(KERN_WARNING "%s: no memory.\n", driver->name); + kfree(card); + return -ENOMEM; + } + memset(cinfo, 0, sizeof(avmctrl_info)); + card->ctrlinfo = cinfo; + cinfo->card = card; sprintf(card->name, "b1pci-%x", p->port); card->port = p->port; card->irq = p->irq; @@ -155,15 +178,17 @@ if (check_region(card->port, AVMB1_PORTLEN)) { printk(KERN_WARNING - "b1pci: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); + "%s: ports 0x%03x-0x%03x in use.\n", + driver->name, card->port, card->port + AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } b1_reset(card->port); if ((retval = b1_detect(card->port, card->cardtype)) != 0) { - printk(KERN_NOTICE "b1pci: NO card at 0x%x (%d)\n", - card->port, retval); + printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", + driver->name, card->port, retval); + kfree(card->ctrlinfo); kfree(card); return -EIO; } @@ -171,19 +196,23 @@ request_region(p->port, AVMB1_PORTLEN, card->name); - retval = request_irq(card->irq, b1pci_interrupt, 0, card->name, card); + retval = request_irq(card->irq, b1pci_interrupt, SA_SHIRQ, card->name, card); if (retval) { - printk(KERN_ERR "b1pci: unable to get IRQ %d.\n", card->irq); + printk(KERN_ERR "%s: unable to get IRQ %d.\n", + driver->name, card->irq); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } - card->ctrl = di->attach_ctr(driver, card->name, card); - if (!card->ctrl) { - printk(KERN_ERR "b1pci: attach controller failed.\n"); + cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); + if (!cinfo->capi_ctrl) { + printk(KERN_ERR "%s: attach controller failed.\n", + driver->name); free_irq(card->irq, card); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } @@ -252,7 +281,7 @@ while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) { struct capicardparams param; - param.port = get_pcibase(dev, 1) & PCI_BASE_ADDRESS_IO_MASK; + param.port = dev->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK; param.irq = dev->irq; printk(KERN_INFO "%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n", @@ -277,7 +306,7 @@ printk(KERN_ERR "%s: NO B1-PCI card detected\n", driver->name); return -ESRCH; #else - printk(KERN_ERR "b1pci: kernel not compiled with PCI.\n"); + printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name); return -EIO; #endif } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c --- v2.3.26/linux/drivers/isdn/avmb1/b1pcmcia.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/avmb1/b1pcmcia.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,18 @@ /* - * $Id: b1pcmcia.c,v 1.4 1999/08/22 20:26:26 calle Exp $ + * $Id: b1pcmcia.c,v 1.5 1999/11/05 16:38:01 calle Exp $ * * Module for AVM B1/M1/M2 PCMCIA-card. * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: b1pcmcia.c,v $ + * Revision 1.5 1999/11/05 16:38:01 calle + * Cleanups before kernel 2.4: + * - Changed all messages to use card->name or driver->name instead of + * constant string. + * - Moved some data from struct avmcard into new struct avmctrl_info. + * Changed all lowlevel capi driver to match the new structur. + * * Revision 1.4 1999/08/22 20:26:26 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -50,13 +57,12 @@ #include #include #include -#include #include "capicmd.h" #include "capiutil.h" #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.4 $"; +static char *revision = "$Revision: 1.5 $"; /* ------------------------------------------------------------- */ @@ -75,11 +81,12 @@ card = (avmcard *) devptr; if (!card) { - printk(KERN_WARNING "b1_interrupt: wrong device\n"); + printk(KERN_WARNING "b1pcmcia: interrupt: wrong device\n"); return; } if (card->interrupt) { - printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name); + printk(KERN_ERR "%s: reentering interrupt hander.\n", + card->name); return; } @@ -93,7 +100,8 @@ static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; b1_reset(port); @@ -116,16 +124,26 @@ unsigned irq, enum avmcardtype cardtype) { + avmctrl_info *cinfo; avmcard *card; int retval; card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); if (!card) { - printk(KERN_WARNING "b1pcmcia: no memory.\n"); + printk(KERN_WARNING "%s: no memory.\n", driver->name); return -ENOMEM; } memset(card, 0, sizeof(avmcard)); + cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC); + if (!cinfo) { + printk(KERN_WARNING "%s: no memory.\n", driver->name); + kfree(card); + return -ENOMEM; + } + memset(cinfo, 0, sizeof(avmctrl_info)); + card->ctrlinfo = cinfo; + cinfo->card = card; switch (cardtype) { case avm_m1: sprintf(card->name, "m1-%x", port); break; case avm_m2: sprintf(card->name, "m2-%x", port); break; @@ -137,8 +155,9 @@ b1_reset(card->port); if ((retval = b1_detect(card->port, card->cardtype)) != 0) { - printk(KERN_NOTICE "b1pcmcia: NO card at 0x%x (%d)\n", - card->port, retval); + printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", + driver->name, card->port, retval); + kfree(card->ctrlinfo); kfree(card); return -EIO; } @@ -146,36 +165,42 @@ retval = request_irq(card->irq, b1pcmcia_interrupt, 0, card->name, card); if (retval) { - printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", card->irq); + printk(KERN_ERR "%s: unable to get IRQ %d.\n", + driver->name, card->irq); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } - card->ctrl = di->attach_ctr(driver, card->name, card); - if (!card->ctrl) { - printk(KERN_ERR "b1pcmcia: attach controller failed.\n"); + cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); + if (!cinfo->capi_ctrl) { + printk(KERN_ERR "%s: attach controller failed.\n", + driver->name); free_irq(card->irq, card); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } MOD_INC_USE_COUNT; - return card->ctrl->cnr; + return cinfo->capi_ctrl->cnr; } /* ------------------------------------------------------------- */ static char *b1pcmcia_procinfo(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); - if (!card) + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + + if (!cinfo) return ""; - sprintf(card->infobuf, "%s %s 0x%x %d", - card->cardname[0] ? card->cardname : "-", - card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", - card->port, card->irq + sprintf(cinfo->infobuf, "%s %s 0x%x %d", + cinfo->cardname[0] ? cinfo->cardname : "-", + cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", + cinfo->card ? cinfo->card->port : 0x0, + cinfo->card ? cinfo->card->irq : 0 ); - return card->infobuf; + return cinfo->infobuf; } /* ------------------------------------------------------------- */ @@ -220,7 +245,7 @@ avmcard *card; for (ctrl = b1pcmcia_driver.controller; ctrl; ctrl = ctrl->next) { - card = (avmcard *)(ctrl->driverdata); + card = ((avmctrl_info *)(ctrl->driverdata))->card; if (card->port == port && card->irq == irq) { b1pcmcia_remove_ctr(ctrl); return 0; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c --- v2.3.26/linux/drivers/isdn/avmb1/capi.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/capi.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,20 @@ /* - * $Id: capi.c,v 1.19 1999/07/09 15:05:42 keil Exp $ + * $Id: capi.c,v 1.21 1999/09/10 17:24:18 calle Exp $ * * CAPI 2.0 Interface for Linux * * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capi.c,v $ + * Revision 1.21 1999/09/10 17:24:18 calle + * Changes for proposed standard for CAPI2.0: + * - AK148 "Linux Exention" + * + * Revision 1.20 1999/09/07 09:02:53 calle + * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and + * DATA_B3_IND is always directly after the CAPI message. The "Data" member + * ist never used inside the kernel. + * * Revision 1.19 1999/07/09 15:05:42 keil * compat.h is now isdn_compat.h * @@ -117,7 +126,6 @@ #include #include -#include #include "capiutil.h" #include "capicmd.h" #include "capidev.h" @@ -201,9 +209,6 @@ skb_queue_head(&cdev->recv_queue, skb); return -EMSGSIZE; } - if (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 - && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) - CAPIMSG_SETDATA(skb->data, buf + CAPIMSG_LEN(skb->data)); retval = copy_to_user(buf, skb->data, skb->len); if (retval) { skb_queue_head(&cdev->recv_queue, skb); @@ -429,7 +434,7 @@ return data.errcode; case CAPI_INSTALLED: - if ((*capifuncs->capi_installed) ()) + if ((*capifuncs->capi_isinstalled)() == CAPI_NOERROR) return 0; return -ENXIO; @@ -615,16 +620,12 @@ int capi_init(void) { -#ifdef COMPAT_HAS_NEW_WAITQ int j; -#endif memset(capidevs, 0, sizeof(capidevs)); -#ifdef COMPAT_HAS_NEW_WAITQ for ( j = 0; j < CAPI_MAXMINOR+1; j++ ) { init_waitqueue_head(&capidevs[j].recv_wait); } -#endif if (register_chrdev(capi_major, "capi20", &capi_fops)) { printk(KERN_ERR "capi20: unable to get major %d\n", capi_major); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h --- v2.3.26/linux/drivers/isdn/avmb1/capidev.h Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/capidev.h Sun Nov 7 16:34:00 1999 @@ -44,11 +44,7 @@ int is_registered; __u16 applid; struct sk_buff_head recv_queue; -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t recv_wait; -#else - struct wait_queue *recv_wait; -#endif __u16 errcode; /* Statistic */ unsigned long nopen; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c --- v2.3.26/linux/drivers/isdn/avmb1/capidrv.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/capidrv.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,17 @@ /* - * $Id: capidrv.c,v 1.26 1999/08/06 07:41:16 calle Exp $ + * $Id: capidrv.c,v 1.28 1999/11/05 16:22:37 calle Exp $ * * ISDN4Linux Driver, using capi20 interface (kernelcapi) * * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capidrv.c,v $ + * Revision 1.28 1999/11/05 16:22:37 calle + * Bugfix: Missing break in switch on ISDN_CMD_HANGUP. + * + * Revision 1.27 1999/09/16 15:13:04 calle + * forgot to change paramter type of contr for lower_callback ... + * * Revision 1.26 1999/08/06 07:41:16 calle * Added the "vbox patch". if (si1 == 1) si2 = 0; * @@ -158,12 +164,11 @@ #include #include -#include #include "capiutil.h" #include "capicmd.h" #include "capidrv.h" -static char *revision = "$Revision: 1.26 $"; +static char *revision = "$Revision: 1.28 $"; int debugmode = 0; MODULE_AUTHOR("Carsten Paeth "); @@ -714,8 +719,6 @@ /* P-0.1 */ {ST_PLCI_OUTGOING, ST_PLCI_NONE, EV_PLCI_CONNECT_CONF_ERROR, p0}, {ST_PLCI_OUTGOING, ST_PLCI_ALLOCATED, EV_PLCI_CONNECT_CONF_OK, 0}, - {ST_PLCI_OUTGOING, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, 0}, - {ST_PLCI_OUTGOING, ST_PLCI_DISCONNECTING, EV_PLCI_FACILITY_IND_DOWN, 0}, /* P-1 */ {ST_PLCI_ALLOCATED, ST_PLCI_ACTIVE, EV_PLCI_CONNECT_ACTIVE_IND, 0}, {ST_PLCI_ALLOCATED, ST_PLCI_DISCONNECTING, EV_PLCI_DISCONNECT_REQ, 0}, @@ -1855,14 +1858,19 @@ ); ncci_change_state(card, bchan->nccip, EV_NCCI_DISCONNECT_B3_REQ); send_message(card, &cmdcmsg); + return 0; } else if (bchan->plcip) { - bchan->disconnecting = 1; if (bchan->plcip->state == ST_PLCI_INCOMING) { - /* just ignore, we a called from isdn_status_callback(), - * which will return 0 or 2, this is handled by the - * CONNECT_IND handler + /* + * just ignore, we a called from + * isdn_status_callback(), + * which will return 0 or 2, this is handled + * by the CONNECT_IND handler */ - } else { + bchan->disconnecting = 1; + return 0; + } else if (bchan->plcip->plci) { + bchan->disconnecting = 1; capi_fill_DISCONNECT_REQ(&cmdcmsg, global.appid, card->msgid++, @@ -1874,8 +1882,18 @@ ); plci_change_state(card, bchan->plcip, EV_PLCI_DISCONNECT_REQ); send_message(card, &cmdcmsg); + return 0; + } else { + printk(KERN_ERR "capidrv-%d: chan %ld disconnect request while waiting for CONNECT_CONF\n", + card->contrnr, + c->arg); + return -EINVAL; } } + printk(KERN_ERR "capidrv-%d: chan %ld disconnect request on free channel\n", + card->contrnr, + c->arg); + return -EINVAL; /* ready */ case ISDN_CMD_SETL2: @@ -2022,10 +2040,8 @@ (void)capidrv_del_ack(nccip, datahandle); return 0; } -#if 1 printk(KERN_DEBUG "capidrv-%d: only %d bytes headroom, need %d\n", card->contrnr, skb_headroom(skb), msglen); -#endif memcpy(skb_push(nskb, msglen), sendcmsg.buf, msglen); errcode = (*capifuncs->capi_put_message) (global.appid, nskb); if (errcode == CAPI_NOERROR) { @@ -2211,10 +2227,6 @@ ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | -#if 0 - ISDN_FEATURE_L2_FAX | - ISDN_FEATURE_L3_FAX | -#endif ISDN_FEATURE_P_UNKNOWN; card->interface.hl_hdrlen = 22; /* len of DATA_B3_REQ */ strncpy(card->interface.id, id, sizeof(card->interface.id) - 1); @@ -2309,7 +2321,7 @@ } -static void lower_callback(unsigned int cmd, __u16 contr, void *data) +static void lower_callback(unsigned int cmd, __u32 contr, void *data) { switch (cmd) { diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c --- v2.3.26/linux/drivers/isdn/avmb1/capiutil.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/capiutil.c Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ /* - * $Id: capiutil.c,v 1.9 1999/07/09 15:05:46 keil Exp $ + * $Id: capiutil.c,v 1.10 1999/08/31 11:19:54 paul Exp $ * * CAPI 2.0 convert capi message to capi message struct * @@ -7,6 +7,9 @@ * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capiutil.c,v $ + * Revision 1.10 1999/08/31 11:19:54 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.9 1999/07/09 15:05:46 keil * compat.h is now isdn_compat.h * @@ -70,7 +73,6 @@ #include #include -#include #include "capiutil.h" /* from CAPI2.0 DDK AVM Berlin GmbH */ @@ -97,7 +99,7 @@ case 0x1001: return "Too many applications"; case 0x1002: - return "Logical block size to small, must be at least 128 Bytes"; + return "Logical block size too small, must be at least 128 Bytes"; case 0x1003: return "Buffer exceeds 64 kByte"; case 0x1004: diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/capiutil.h linux/drivers/isdn/avmb1/capiutil.h --- v2.3.26/linux/drivers/isdn/avmb1/capiutil.h Thu May 29 21:53:05 1997 +++ linux/drivers/isdn/avmb1/capiutil.h Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ /* - * $Id: capiutil.h,v 1.2 1997/05/18 09:24:19 calle Exp $ + * $Id: capiutil.h,v 1.4 1999/09/15 08:16:03 calle Exp $ * * CAPI 2.0 defines & types * @@ -7,6 +7,14 @@ * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capiutil.h,v $ + * Revision 1.4 1999/09/15 08:16:03 calle + * Implementation of 64Bit extention complete. + * + * Revision 1.3 1999/09/07 09:02:53 calle + * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and + * DATA_B3_IND is always directly after the CAPI message. The "Data" member + * ist never used inside the kernel. + * * Revision 1.2 1997/05/18 09:24:19 calle * added verbose disconnect reason reporting to avmb1. * some fixes in capi20 interface. @@ -45,12 +53,10 @@ ((__u8 *)m)[3] = ((__u16)(applid) >> 8) & 0xff; \ } while (0) -#define CAPIMSG_SETDATA(m, data) \ +#define CAPIMSG_SETLEN(m, len) \ do { \ - ((__u8 *)m)[12] = (__u32)(data) & 0xff; \ - ((__u8 *)m)[13] = ((__u32)(data) >> 8) & 0xff; \ - ((__u8 *)m)[14] = ((__u32)(data) >> 16) & 0xff; \ - ((__u8 *)m)[15] = ((__u32)(data) >> 24) & 0xff; \ + ((__u8 *)m)[0] = (__u16)(len) & 0xff; \ + ((__u8 *)m)[1] = ((__u16)(len) >> 8) & 0xff; \ } while (0) /*----- basic-type definitions -----*/ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c --- v2.3.26/linux/drivers/isdn/avmb1/kcapi.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/avmb1/kcapi.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,25 @@ /* - * $Id: kcapi.c,v 1.6 1999/07/20 06:41:49 calle Exp $ + * $Id: kcapi.c,v 1.10 1999/10/26 15:30:32 calle Exp $ * * Kernel CAPI 2.0 Module * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: kcapi.c,v $ + * Revision 1.10 1999/10/26 15:30:32 calle + * Generate error message if user want to add card, but driver module is + * not loaded. + * + * Revision 1.9 1999/10/11 22:04:12 keil + * COMPAT_NEED_UACCESS (no include in isdn_compat.h) + * + * Revision 1.8 1999/09/10 17:24:18 calle + * Changes for proposed standard for CAPI2.0: + * - AK148 "Linux Exention" + * + * Revision 1.7 1999/09/04 06:20:05 keil + * Changes from kernel set_current_state() + * * Revision 1.6 1999/07/20 06:41:49 calle * Bugfix: After the redesign of the AVM B1 driver, the driver didn't even * compile, if not selected as modules. @@ -57,7 +71,7 @@ #include #include #include -#include +#include #include "capicmd.h" #include "capiutil.h" #include "capilli.h" @@ -65,7 +79,7 @@ #include #endif -static char *revision = "$Revision: 1.6 $"; +static char *revision = "$Revision: 1.10 $"; /* ------------------------------------------------------------- */ @@ -119,7 +133,7 @@ /* ------------------------------------------------------------- */ static struct capi_version driver_version = {2, 0, 1, 1<<4}; -static char driver_serial[CAPI_SERIAL_LEN] = "4711"; +static char driver_serial[CAPI_SERIAL_LEN] = "0004711"; static char capi_manufakturer[64] = "AVM Berlin"; #define APPL(a) (&applications[(a)-1]) @@ -719,7 +733,7 @@ /* -------- Notifier ------------------------------------------ */ -static void notify_up(__u16 contr) +static void notify_up(__u32 contr) { struct capi_interface_user *p; @@ -730,7 +744,7 @@ } } -static void notify_down(__u16 contr) +static void notify_down(__u32 contr) { struct capi_interface_user *p; printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr); @@ -742,7 +756,7 @@ static void notify_handler(void *dummy) { - __u16 contr; + __u32 contr; for (contr=1; VALID_CARD(contr); contr++) if (test_and_clear_bit(contr, ¬ify_up_set)) @@ -984,14 +998,14 @@ /* -------- CAPI2.0 Interface ---------------------------------- */ /* ------------------------------------------------------------- */ -static int capi_installed(void) +static __u16 capi_isinstalled(void) { int i; for (i = 0; i < CAPI_MAXCONTR; i++) { if (cards[i].cardstate == CARD_RUNNING) - return 1; + return CAPI_NOERROR; } - return 0; + return CAPI_REGNOTINSTALLED; } static __u16 capi_register(capi_register_params * rparam, __u16 * applidp) @@ -1053,7 +1067,7 @@ static __u16 capi_put_message(__u16 applid, struct sk_buff *skb) { struct capi_ncci *np; - int contr; + __u32 contr; int showctl = 0; __u8 cmd, subcmd; @@ -1131,53 +1145,53 @@ return CAPI_NOERROR; } -static __u16 capi_get_manufacturer(__u16 contr, __u8 buf[CAPI_MANUFACTURER_LEN]) +static __u16 capi_get_manufacturer(__u32 contr, __u8 buf[CAPI_MANUFACTURER_LEN]) { if (contr == 0) { strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); return CAPI_NOERROR; } if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) - return 0x2002; + return CAPI_REGNOTINSTALLED; strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN); return CAPI_NOERROR; } -static __u16 capi_get_version(__u16 contr, struct capi_version *verp) +static __u16 capi_get_version(__u32 contr, struct capi_version *verp) { if (contr == 0) { *verp = driver_version; return CAPI_NOERROR; } if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) - return 0x2002; + return CAPI_REGNOTINSTALLED; memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version)); return CAPI_NOERROR; } -static __u16 capi_get_serial(__u16 contr, __u8 serial[CAPI_SERIAL_LEN]) +static __u16 capi_get_serial(__u32 contr, __u8 serial[CAPI_SERIAL_LEN]) { if (contr == 0) { strncpy(serial, driver_serial, CAPI_SERIAL_LEN); return CAPI_NOERROR; } if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) - return 0x2002; + return CAPI_REGNOTINSTALLED; strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN); return CAPI_NOERROR; } -static __u16 capi_get_profile(__u16 contr, struct capi_profile *profp) +static __u16 capi_get_profile(__u32 contr, struct capi_profile *profp) { if (contr == 0) { profp->ncontroller = ncards; return CAPI_NOERROR; } if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) - return 0x2002; + return CAPI_REGNOTINSTALLED; memcpy((void *) profp, &CARD(contr)->profile, sizeof(struct capi_profile)); @@ -1219,7 +1233,12 @@ case AVM_CARDTYPE_T1: driver = t1isa_driver; break; default: driver = 0; } - if (!driver || !driver->add_card) { + if (!driver) { + printk(KERN_ERR "kcapi: driver not loaded.\n"); + return -EIO; + } + if (!driver->add_card) { + printk(KERN_ERR "kcapi: driver has no add card function.\n"); return -EIO; } @@ -1277,7 +1296,7 @@ while (card->cardstate != CARD_RUNNING) { - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/10); /* 0.1 sec */ if (signal_pending(current)) @@ -1302,7 +1321,7 @@ while (card->cardstate > CARD_DETECTED) { - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/10); /* 0.1 sec */ if (signal_pending(current)) @@ -1355,7 +1374,7 @@ while (card->cardstate != CARD_FREE) { - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/10); /* 0.1 sec */ if (signal_pending(current)) @@ -1404,7 +1423,7 @@ struct capi_interface avmb1_interface = { - capi_installed, + capi_isinstalled, capi_register, capi_release, capi_put_message, @@ -1479,6 +1498,12 @@ #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA extern int b1pcmcia_init(void); #endif +#ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI +extern int t1pci_init(void); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_C4 +extern int c4_init(void); +#endif #endif /* @@ -1527,6 +1552,12 @@ #endif #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA (void)b1pcmcia_init(); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI + (void)t1pci_init(); +#endif +#ifdef CONFIG_ISDN_DRV_AVMB1_C4 + (void)c4_init(); #endif #endif return 0; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c --- v2.3.26/linux/drivers/isdn/avmb1/t1isa.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/avmb1/t1isa.c Sun Nov 7 16:34:00 1999 @@ -1,11 +1,26 @@ /* - * $Id: t1isa.c,v 1.5 1999/08/22 20:26:28 calle Exp $ + * $Id: t1isa.c,v 1.8 1999/11/05 16:38:01 calle Exp $ * * Module for AVM T1 HEMA-card. * * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: t1isa.c,v $ + * Revision 1.8 1999/11/05 16:38:01 calle + * Cleanups before kernel 2.4: + * - Changed all messages to use card->name or driver->name instead of + * constant string. + * - Moved some data from struct avmcard into new struct avmctrl_info. + * Changed all lowlevel capi driver to match the new structur. + * + * Revision 1.7 1999/09/15 08:16:03 calle + * Implementation of 64Bit extention complete. + * + * Revision 1.6 1999/09/07 09:02:53 calle + * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and + * DATA_B3_IND is always directly after the CAPI message. The "Data" member + * ist never used inside the kernel. + * * Revision 1.5 1999/08/22 20:26:28 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -53,13 +68,12 @@ #include #include #include -#include #include "capicmd.h" #include "capiutil.h" #include "capilli.h" #include "avmcard.h" -static char *revision = "$Revision: 1.5 $"; +static char *revision = "$Revision: 1.8 $"; /* ------------------------------------------------------------- */ @@ -162,7 +176,8 @@ static void t1_handle_interrupt(avmcard * card) { - struct capi_ctr *ctrl = card->ctrl; + avmctrl_info *cinfo = &card->ctrlinfo[0]; + struct capi_ctr *ctrl = cinfo->capi_ctrl; unsigned char b1cmd; struct sk_buff *skb; @@ -184,12 +199,17 @@ MsgLen = t1_get_slice(card->port, card->msgbuf); DataB3Len = t1_get_slice(card->port, card->databuf); + if (MsgLen < 30) { /* not CAPI 64Bit */ + memset(card->msgbuf+MsgLen, 0, 30-MsgLen); + MsgLen = 30; + CAPIMSG_SETLEN(card->msgbuf, 30); + } if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "t1isa: incoming packet dropped\n"); + printk(KERN_ERR "%s: incoming packet dropped\n", + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); - CAPIMSG_SETDATA(skb->data, skb->data + MsgLen); ctrl->handle_capimsg(ctrl, ApplId, skb); } break; @@ -199,7 +219,8 @@ ApplId = (unsigned) b1_get_word(card->port); MsgLen = t1_get_slice(card->port, card->msgbuf); if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { - printk(KERN_ERR "t1isa: incoming packet dropped\n"); + printk(KERN_ERR "%s: incoming packet dropped\n", + card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); ctrl->handle_capimsg(ctrl, ApplId, skb); @@ -237,12 +258,12 @@ case RECEIVE_INIT: - card->versionlen = t1_get_slice(card->port, card->versionbuf); - b1_parse_version(card); + cinfo->versionlen = t1_get_slice(card->port, cinfo->versionbuf); + b1_parse_version(cinfo); printk(KERN_INFO "%s: %s-card (%s) now active\n", card->name, - card->version[VER_CARDTYPE], - card->version[VER_DRIVER]); + cinfo->version[VER_CARDTYPE], + cinfo->version[VER_DRIVER]); ctrl->ready(ctrl); break; @@ -288,11 +309,12 @@ card = (avmcard *) devptr; if (!card) { - printk(KERN_WARNING "t1_interrupt: wrong device\n"); + printk(KERN_WARNING "t1isa: interrupt: wrong device\n"); return; } if (card->interrupt) { - printk(KERN_ERR "t1_interrupt: reentering interrupt hander (%s)\n", card->name); + printk(KERN_ERR "%s: reentering interrupt hander.\n", + card->name); return; } @@ -306,7 +328,8 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; unsigned long flags; int retval; @@ -314,7 +337,7 @@ t1_disable_irq(port); b1_reset(port); - if ((retval = b1_load_t4file(port, &data->firmware))) { + if ((retval = b1_load_t4file(card, &data->firmware))) { b1_reset(port); printk(KERN_ERR "%s: failed to load t4file!!\n", card->name); @@ -322,7 +345,7 @@ } if (data->configuration.len > 0 && data->configuration.data) { - if ((retval = b1_load_config(port, &data->configuration))) { + if ((retval = b1_load_config(card, &data->configuration))) { b1_reset(port); printk(KERN_ERR "%s: failed to load config!!\n", card->name); @@ -330,7 +353,7 @@ } } - if (!b1_loaded(port)) { + if (!b1_loaded(card)) { printk(KERN_ERR "%s: failed to load t4file.\n", card->name); return -EIO; } @@ -349,20 +372,22 @@ void t1isa_reset_ctr(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; t1_disable_irq(port); b1_reset(port); b1_reset(port); - memset(card->version, 0, sizeof(card->version)); + memset(cinfo->version, 0, sizeof(cinfo->version)); ctrl->reseted(ctrl); } static void t1isa_remove_ctr(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; t1_disable_irq(port); @@ -373,6 +398,7 @@ di->detach_ctr(ctrl); free_irq(card->irq, card); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); MOD_DEC_USE_COUNT; @@ -383,16 +409,26 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) { struct capi_ctr *ctrl; + avmctrl_info *cinfo; avmcard *card; int retval; card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); if (!card) { - printk(KERN_WARNING "t1isa: no memory.\n"); + printk(KERN_WARNING "%s: no memory.\n", driver->name); return -ENOMEM; } memset(card, 0, sizeof(avmcard)); + cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC); + if (!cinfo) { + printk(KERN_WARNING "%s: no memory.\n", driver->name); + kfree(card); + return -ENOMEM; + } + memset(cinfo, 0, sizeof(avmctrl_info)); + card->ctrlinfo = cinfo; + cinfo->card = card; sprintf(card->name, "t1isa-%x", p->port); card->port = p->port; card->irq = p->irq; @@ -400,33 +436,42 @@ card->cardnr = p->cardnr; if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) { - printk(KERN_WARNING "t1isa: illegal port 0x%x.\n", card->port); + printk(KERN_WARNING "%s: illegal port 0x%x.\n", + driver->name, card->port); + kfree(card->ctrlinfo); kfree(card); return -EINVAL; } if (check_region(card->port, AVMB1_PORTLEN)) { printk(KERN_WARNING - "t1isa: ports 0x%03x-0x%03x in use.\n", - card->port, card->port + AVMB1_PORTLEN); + "%s: ports 0x%03x-0x%03x in use.\n", + driver->name, card->port, card->port + AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } if (hema_irq_table[card->irq & 0xf] == 0) { - printk(KERN_WARNING "t1isa: irq %d not valid.\n", card->irq); + printk(KERN_WARNING "%s: irq %d not valid.\n", + driver->name, card->irq); + kfree(card->ctrlinfo); kfree(card); return -EINVAL; } for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) { - if (((avmcard *)(ctrl->driverdata))->cardnr == card->cardnr) { - printk(KERN_WARNING "t1isa: card with number %d already installed.\n", card->cardnr); + avmcard *cardp = ((avmctrl_info *)(ctrl->driverdata))->card; + if (cardp->cardnr == card->cardnr) { + printk(KERN_WARNING "%s: card with number %d already installed at 0x%x.\n", + driver->name, card->cardnr, cardp->port); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } } if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) { - printk(KERN_NOTICE "t1isa: NO card at 0x%x (%d)\n", - card->port, retval); + printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", + driver->name, card->port, retval); + kfree(card->ctrlinfo); kfree(card); return -EIO; } @@ -437,17 +482,21 @@ retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card); if (retval) { - printk(KERN_ERR "t1isa: unable to get IRQ %d.\n", card->irq); + printk(KERN_ERR "%s: unable to get IRQ %d.\n", + driver->name, card->irq); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } - card->ctrl = di->attach_ctr(driver, card->name, card); - if (!card->ctrl) { - printk(KERN_ERR "t1isa: attach controller failed.\n"); + cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); + if (!cinfo->capi_ctrl) { + printk(KERN_ERR "%s: attach controller failed.\n", + driver->name); free_irq(card->irq, card); release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); kfree(card); return -EBUSY; } @@ -458,7 +507,8 @@ static void t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) { - avmcard *card = (avmcard *)(ctrl->driverdata); + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; unsigned int port = card->port; unsigned long flags; __u16 len = CAPIMSG_LEN(skb->data); @@ -483,15 +533,18 @@ static char *t1isa_procinfo(struct capi_ctr *ctrl) { - avmcard *card = (avmcard *)(ctrl->driverdata); - if (!card) + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + + if (!cinfo) return ""; - sprintf(card->infobuf, "%s %s 0x%x %d %d", - card->cardname[0] ? card->cardname : "-", - card->version[VER_DRIVER] ? card->version[VER_DRIVER] : "-", - card->port, card->irq, card->cardnr + sprintf(cinfo->infobuf, "%s %s 0x%x %d %d", + cinfo->cardname[0] ? cinfo->cardname : "-", + cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", + cinfo->card ? cinfo->card->port : 0x0, + cinfo->card ? cinfo->card->irq : 0, + cinfo->card ? cinfo->card->cardnr : 0 ); - return card->infobuf; + return cinfo->infobuf; } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c --- v2.3.26/linux/drivers/isdn/avmb1/t1pci.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/avmb1/t1pci.c Sun Nov 7 16:34:00 1999 @@ -0,0 +1,1164 @@ +/* + * $Id: t1pci.c,v 1.2 1999/11/05 16:38:02 calle Exp $ + * + * Module for AVM T1 PCI-card. + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + * $Log: t1pci.c,v $ + * Revision 1.2 1999/11/05 16:38:02 calle + * Cleanups before kernel 2.4: + * - Changed all messages to use card->name or driver->name instead of + * constant string. + * - Moved some data from struct avmcard into new struct avmctrl_info. + * Changed all lowlevel capi driver to match the new structur. + * + * Revision 1.1 1999/10/26 15:31:42 calle + * Added driver for T1-PCI card. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "compat.h" +#include "capicmd.h" +#include "capiutil.h" +#include "capilli.h" +#include "avmcard.h" + +static char *revision = "$Revision: 1.2 $"; + +#undef CONFIG_T1PCI_DEBUG +#undef CONFIG_T1PCI_POLLDEBUG + +/* ------------------------------------------------------------- */ + +#ifndef PCI_VENDOR_ID_AVM +#define PCI_VENDOR_ID_AVM 0x1244 +#endif + +#ifndef PCI_DEVICE_ID_AVM_T1 +#define PCI_DEVICE_ID_AVM_T1 0x1200 +#endif + +/* ------------------------------------------------------------- */ + +int suppress_pollack = 0; + +MODULE_AUTHOR("Carsten Paeth "); + +MODULE_PARM(suppress_pollack, "0-1i"); + + +/* ------------------------------------------------------------- */ + +static struct capi_driver_interface *di; + +/* ------------------------------------------------------------- */ + +static void t1pci_dispatch_tx(avmcard *card); + +/* ------------------------------------------------------------- */ + +/* S5933 */ + +#define AMCC_RXPTR 0x24 +#define AMCC_RXLEN 0x28 +#define AMCC_TXPTR 0x2c +#define AMCC_TXLEN 0x30 + +#define AMCC_INTCSR 0x38 +# define EN_READ_TC_INT 0x00008000L +# define EN_WRITE_TC_INT 0x00004000L +# define EN_TX_TC_INT EN_READ_TC_INT +# define EN_RX_TC_INT EN_WRITE_TC_INT +# define AVM_FLAG 0x30000000L + +# define ANY_S5933_INT 0x00800000L +# define READ_TC_INT 0x00080000L +# define WRITE_TC_INT 0x00040000L +# define TX_TC_INT READ_TC_INT +# define RX_TC_INT WRITE_TC_INT +# define MASTER_ABORT_INT 0x00100000L +# define TARGET_ABORT_INT 0x00200000L +# define BUS_MASTER_INT 0x00200000L +# define ALL_INT 0x000C0000L + +#define AMCC_MCSR 0x3c +# define A2P_HI_PRIORITY 0x00000100L +# define EN_A2P_TRANSFERS 0x00000400L +# define P2A_HI_PRIORITY 0x00001000L +# define EN_P2A_TRANSFERS 0x00004000L +# define RESET_A2P_FLAGS 0x04000000L +# define RESET_P2A_FLAGS 0x02000000L + +/* ------------------------------------------------------------- */ + +#define t1outmeml(addr, value) writel(value, addr) +#define t1inmeml(addr) readl(addr) +#define t1outmemw(addr, value) writew(value, addr) +#define t1inmemw(addr) readw(addr) +#define t1outmemb(addr, value) writeb(value, addr) +#define t1inmemb(addr) readb(addr) + +/* ------------------------------------------------------------- */ + +static inline int t1pci_tx_empty(unsigned int port) +{ + return inb(port + 0x03) & 0x1; +} + +static inline int t1pci_rx_full(unsigned int port) +{ + return inb(port + 0x02) & 0x1; +} + +static int t1pci_tolink(avmcard *card, void *buf, unsigned int len) +{ + unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ + unsigned char *s = (unsigned char *)buf; + while (len--) { + while ( !t1pci_tx_empty(card->port) + && time_before(jiffies, stop)); + if (!t1pci_tx_empty(card->port)) + return -1; + t1outp(card->port, 0x01, *s++); + } + return 0; +} + +static int t1pci_fromlink(avmcard *card, void *buf, unsigned int len) +{ + unsigned long stop = jiffies + 1 * HZ; /* maximum wait time 1 sec */ + unsigned char *s = (unsigned char *)buf; + while (len--) { + while ( !t1pci_rx_full(card->port) + && time_before(jiffies, stop)); + if (!t1pci_rx_full(card->port)) + return -1; + *s++ = t1inp(card->port, 0x00); + } + return 0; +} + +static int WriteReg(avmcard *card, __u32 reg, __u8 val) +{ + __u8 cmd = 0x00; + if ( t1pci_tolink(card, &cmd, 1) == 0 + && t1pci_tolink(card, ®, 4) == 0) { + __u32 tmp = val; + return t1pci_tolink(card, &tmp, 4); + } + return -1; +} + +static __u8 ReadReg(avmcard *card, __u32 reg) +{ + __u8 cmd = 0x01; + if ( t1pci_tolink(card, &cmd, 1) == 0 + && t1pci_tolink(card, ®, 4) == 0) { + __u32 tmp; + if (t1pci_fromlink(card, &tmp, 4) == 0) + return (__u8)tmp; + } + return 0xff; +} + +/* ------------------------------------------------------------- */ + +static inline void _put_byte(void **pp, __u8 val) +{ + __u8 *s = *pp; + *s++ = val; + *pp = s; +} + +static inline void _put_word(void **pp, __u32 val) +{ + __u8 *s = *pp; + *s++ = val & 0xff; + *s++ = (val >> 8) & 0xff; + *s++ = (val >> 16) & 0xff; + *s++ = (val >> 24) & 0xff; + *pp = s; +} + +static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len) +{ + unsigned i = len; + _put_word(pp, i); + while (i-- > 0) + _put_byte(pp, *dp++); +} + +static inline __u8 _get_byte(void **pp) +{ + __u8 *s = *pp; + __u8 val; + val = *s++; + *pp = s; + return val; +} + +static inline __u32 _get_word(void **pp) +{ + __u8 *s = *pp; + __u32 val; + val = *s++; + val |= (*s++ << 8); + val |= (*s++ << 16); + val |= (*s++ << 24); + *pp = s; + return val; +} + +static inline __u32 _get_slice(void **pp, unsigned char *dp) +{ + unsigned int len, i; + + len = i = _get_word(pp); + while (i-- > 0) *dp++ = _get_byte(pp); + return len; +} + +/* ------------------------------------------------------------- */ + +static void t1pci_reset(avmcard *card) +{ + unsigned long flags; + + save_flags(flags); + cli(); + card->csr = 0x0; + t1outmeml(card->mbase+AMCC_INTCSR, card->csr); + t1outmeml(card->mbase+AMCC_MCSR, 0); + t1outmeml(card->mbase+AMCC_RXLEN, 0); + t1outmeml(card->mbase+AMCC_TXLEN, 0); + + t1outp(card->port, T1_RESETLINK, 0x00); + t1outp(card->port, 0x07, 0x00); + + restore_flags(flags); + + t1outmeml(card->mbase+AMCC_MCSR, 0); + udelay(10 * 1000); + t1outmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */ + udelay(10 * 1000); + t1outmeml(card->mbase+AMCC_MCSR, 0); + udelay(42 * 1000); + +} + +/* ------------------------------------------------------------- */ + +static int t1pci_detect(avmcard *card) +{ + t1outmeml(card->mbase+AMCC_MCSR, 0); + udelay(10 * 1000); + t1outmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */ + udelay(10 * 1000); + t1outmeml(card->mbase+AMCC_MCSR, 0); + udelay(42 * 1000); + + t1outmeml(card->mbase+AMCC_RXLEN, 0); + t1outmeml(card->mbase+AMCC_TXLEN, 0); + card->csr = 0x0; + t1outmeml(card->mbase+AMCC_INTCSR, card->csr); + + if (t1inmeml(card->mbase+AMCC_MCSR) != 0x000000E6) + return 1; + + t1outmeml(card->mbase+AMCC_RXPTR, 0xffffffff); + t1outmeml(card->mbase+AMCC_TXPTR, 0xffffffff); + if ( t1inmeml(card->mbase+AMCC_RXPTR) != 0xfffffffc + || t1inmeml(card->mbase+AMCC_TXPTR) != 0xfffffffc) + return 2; + + t1outmeml(card->mbase+AMCC_RXPTR, 0x0); + t1outmeml(card->mbase+AMCC_TXPTR, 0x0); + if ( t1inmeml(card->mbase+AMCC_RXPTR) != 0x0 + || t1inmeml(card->mbase+AMCC_TXPTR) != 0x0) + return 3; + + t1outp(card->port, T1_RESETLINK, 0x00); + t1outp(card->port, 0x07, 0x00); + + t1outp(card->port, 0x02, 0x02); + t1outp(card->port, 0x03, 0x02); + + if ( (t1inp(card->port, 0x02) & 0xFE) != 0x02 + || t1inp(card->port, 0x3) != 0x03) + return 4; + + t1outp(card->port, 0x02, 0x00); + t1outp(card->port, 0x03, 0x00); + + if ( (t1inp(card->port, 0x02) & 0xFE) != 0x00 + || t1inp(card->port, 0x3) != 0x01) + return 5; + + /* Transputer test */ + + if ( WriteReg(card, 0x80001000, 0x11) != 0 + || WriteReg(card, 0x80101000, 0x22) != 0 + || WriteReg(card, 0x80201000, 0x33) != 0 + || WriteReg(card, 0x80301000, 0x44) != 0) + return 6; + + if ( ReadReg(card, 0x80001000) != 0x11 + || ReadReg(card, 0x80101000) != 0x22 + || ReadReg(card, 0x80201000) != 0x33 + || ReadReg(card, 0x80301000) != 0x44) + return 7; + + if ( WriteReg(card, 0x80001000, 0x55) != 0 + || WriteReg(card, 0x80101000, 0x66) != 0 + || WriteReg(card, 0x80201000, 0x77) != 0 + || WriteReg(card, 0x80301000, 0x88) != 0) + return 8; + + if ( ReadReg(card, 0x80001000) != 0x55 + || ReadReg(card, 0x80101000) != 0x66 + || ReadReg(card, 0x80201000) != 0x77 + || ReadReg(card, 0x80301000) != 0x88) + return 9; + + return 0; +} + +/* ------------------------------------------------------------- */ + +static void t1pci_dispatch_tx(avmcard *card) +{ + avmcard_dmainfo *dma = card->dma; + unsigned long flags; + struct sk_buff *skb; + __u8 cmd, subcmd; + __u16 len; + __u32 txlen; + int inint; + void *p; + + save_flags(flags); + cli(); + + inint = card->interrupt; + + if (card->csr & EN_TX_TC_INT) { /* tx busy */ + restore_flags(flags); + return; + } + + skb = skb_dequeue(&dma->send_queue); + if (!skb) { +#ifdef CONFIG_T1PCI_DEBUG + printk(KERN_DEBUG "tx(%d): underrun\n", inint); +#endif + restore_flags(flags); + return; + } + + len = CAPIMSG_LEN(skb->data); + + if (len) { + cmd = CAPIMSG_COMMAND(skb->data); + subcmd = CAPIMSG_SUBCOMMAND(skb->data); + + p = dma->sendbuf; + + if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { + __u16 dlen = CAPIMSG_DATALEN(skb->data); + _put_byte(&p, SEND_DATA_B3_REQ); + _put_slice(&p, skb->data, len); + _put_slice(&p, skb->data + len, dlen); + } else { + _put_byte(&p, SEND_MESSAGE); + _put_slice(&p, skb->data, len); + } + txlen = (__u8 *)p - (__u8 *)dma->sendbuf; +#ifdef CONFIG_T1PCI_DEBUG + printk(KERN_DEBUG "tx(%d): put msg len=%d\n", + inint, txlen); +#endif + } else { + txlen = skb->len-2; +#ifdef CONFIG_T1PCI_POLLDEBUG + if (skb->data[2] == SEND_POLLACK) + printk(KERN_INFO "%s: ack to t1\n", card->name); +#endif +#ifdef CONFIG_T1PCI_DEBUG + printk(KERN_DEBUG "tx(%d): put 0x%x len=%d\n", + inint, skb->data[2], txlen); +#endif + memcpy(dma->sendbuf, skb->data+2, skb->len-2); + } + txlen = (txlen + 3) & ~3; + + t1outmeml(card->mbase+AMCC_TXPTR, virt_to_phys(dma->sendbuf)); + t1outmeml(card->mbase+AMCC_TXLEN, txlen); + + card->csr |= EN_TX_TC_INT; + + if (!inint) + t1outmeml(card->mbase+AMCC_INTCSR, card->csr); + + restore_flags(flags); + dev_kfree_skb(skb); +} + +/* ------------------------------------------------------------- */ + +static void queue_pollack(avmcard *card) +{ + struct sk_buff *skb; + void *p; + + skb = alloc_skb(3, GFP_ATOMIC); + if (!skb) { + printk(KERN_CRIT "%s: no memory, lost poll ack\n", + card->name); + return; + } + p = skb->data; + _put_byte(&p, 0); + _put_byte(&p, 0); + _put_byte(&p, SEND_POLLACK); + skb_put(skb, (__u8 *)p - (__u8 *)skb->data); + + skb_queue_tail(&card->dma->send_queue, skb); + t1pci_dispatch_tx(card); +} + +/* ------------------------------------------------------------- */ + +static void t1pci_handle_rx(avmcard *card) +{ + avmctrl_info *cinfo = &card->ctrlinfo[0]; + avmcard_dmainfo *dma = card->dma; + struct capi_ctr *ctrl = cinfo->capi_ctrl; + struct sk_buff *skb; + void *p = dma->recvbuf+4; + __u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize; + __u8 b1cmd = _get_byte(&p); + +#ifdef CONFIG_T1PCI_DEBUG + printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen); +#endif + + switch (b1cmd) { + case RECEIVE_DATA_B3_IND: + + ApplId = (unsigned) _get_word(&p); + MsgLen = _get_slice(&p, card->msgbuf); + DataB3Len = _get_slice(&p, card->databuf); + + if (MsgLen < 30) { /* not CAPI 64Bit */ + memset(card->msgbuf+MsgLen, 0, 30-MsgLen); + MsgLen = 30; + CAPIMSG_SETLEN(card->msgbuf, 30); + } + if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) { + printk(KERN_ERR "%s: incoming packet dropped\n", + card->name); + } else { + memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); + memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); + ctrl->handle_capimsg(ctrl, ApplId, skb); + } + break; + + case RECEIVE_MESSAGE: + + ApplId = (unsigned) _get_word(&p); + MsgLen = _get_slice(&p, card->msgbuf); + if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { + printk(KERN_ERR "%s: incoming packet dropped\n", + card->name); + } else { + memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); + ctrl->handle_capimsg(ctrl, ApplId, skb); + } + break; + + case RECEIVE_NEW_NCCI: + + ApplId = _get_word(&p); + NCCI = _get_word(&p); + WindowSize = _get_word(&p); + + ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize); + + break; + + case RECEIVE_FREE_NCCI: + + ApplId = _get_word(&p); + NCCI = _get_word(&p); + + if (NCCI != 0xffffffff) + ctrl->free_ncci(ctrl, ApplId, NCCI); + else ctrl->appl_released(ctrl, ApplId); + break; + + case RECEIVE_START: +#ifdef CONFIG_T1PCI_POLLDEBUG + printk(KERN_INFO "%s: poll from t1\n", card->name); +#endif + if (!suppress_pollack) + queue_pollack(card); + ctrl->resume_output(ctrl); + break; + + case RECEIVE_STOP: + ctrl->suspend_output(ctrl); + break; + + case RECEIVE_INIT: + + cinfo->versionlen = _get_slice(&p, cinfo->versionbuf); + b1_parse_version(cinfo); + printk(KERN_INFO "%s: %s-card (%s) now active\n", + card->name, + cinfo->version[VER_CARDTYPE], + cinfo->version[VER_DRIVER]); + ctrl->ready(ctrl); + break; + + case RECEIVE_TASK_READY: + ApplId = (unsigned) _get_word(&p); + MsgLen = _get_slice(&p, card->msgbuf); + card->msgbuf[MsgLen--] = 0; + while ( MsgLen >= 0 + && ( card->msgbuf[MsgLen] == '\n' + || card->msgbuf[MsgLen] == '\r')) + card->msgbuf[MsgLen--] = 0; + printk(KERN_INFO "%s: task %d \"%s\" ready.\n", + card->name, ApplId, card->msgbuf); + break; + + case RECEIVE_DEBUGMSG: + MsgLen = _get_slice(&p, card->msgbuf); + card->msgbuf[MsgLen--] = 0; + while ( MsgLen >= 0 + && ( card->msgbuf[MsgLen] == '\n' + || card->msgbuf[MsgLen] == '\r')) + card->msgbuf[MsgLen--] = 0; + printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); + break; + + default: + printk(KERN_ERR "%s: t1pci_interrupt: 0x%x ???\n", + card->name, b1cmd); + return; + } +} + +/* ------------------------------------------------------------- */ + +static void t1pci_handle_interrupt(avmcard *card) +{ + __u32 status = t1inmeml(card->mbase+AMCC_INTCSR); + __u32 newcsr; + + if ((status & ANY_S5933_INT) == 0) + return; + + newcsr = card->csr | (status & ALL_INT); + if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT; + if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT; + t1outmeml(card->mbase+AMCC_INTCSR, newcsr); + + if ((status & RX_TC_INT) != 0) { + __u8 *recvbuf = card->dma->recvbuf; + __u32 rxlen; + if (card->dma->recvlen == 0) { + card->dma->recvlen = *((__u32 *)recvbuf); + rxlen = (card->dma->recvlen + 3) & ~3; + t1outmeml(card->mbase+AMCC_RXPTR, + virt_to_phys(recvbuf+4)); + t1outmeml(card->mbase+AMCC_RXLEN, rxlen); + } else { + t1pci_handle_rx(card); + card->dma->recvlen = 0; + t1outmeml(card->mbase+AMCC_RXPTR, virt_to_phys(recvbuf)); + t1outmeml(card->mbase+AMCC_RXLEN, 4); + } + } + + if ((status & TX_TC_INT) != 0) { + card->csr &= ~EN_TX_TC_INT; + t1pci_dispatch_tx(card); + } else if (card->csr & EN_TX_TC_INT) { + if (t1inmeml(card->mbase+AMCC_TXLEN) == 0) { + card->csr &= ~EN_TX_TC_INT; + t1pci_dispatch_tx(card); + } + } + t1outmeml(card->mbase+AMCC_INTCSR, card->csr); +} + +static void t1pci_interrupt(int interrupt, void *devptr, struct pt_regs *regs) +{ + avmcard *card; + + card = (avmcard *) devptr; + + if (!card) { + printk(KERN_WARNING "t1pci: interrupt: wrong device\n"); + return; + } + if (card->interrupt) { + printk(KERN_ERR "%s: reentering interrupt hander\n", card->name); + return; + } + + card->interrupt = 1; + + t1pci_handle_interrupt(card); + + card->interrupt = 0; +} + +/* ------------------------------------------------------------- */ + +static int t1pci_loaded(avmcard *card) +{ + unsigned long stop; + unsigned char ans; + unsigned long tout = 2; + unsigned int base = card->port; + + for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { + if (b1_tx_empty(base)) + break; + } + if (!b1_tx_empty(base)) { + printk(KERN_ERR "%s: t1pci_loaded: tx err, corrupted t4 file ?\n", + card->name); + return 0; + } + b1_put_byte(base, SEND_POLLACK); + for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { + if (b1_rx_full(base)) { + if ((ans = b1_get_byte(base)) == RECEIVE_POLLDWORD) { + return 1; + } + printk(KERN_ERR "%s: t1pci_loaded: got 0x%x, firmware not running in dword mode\n", card->name, ans); + return 0; + } + } + printk(KERN_ERR "%s: t1pci_loaded: firmware not running\n", card->name); + return 0; +} + +/* ------------------------------------------------------------- */ + +static void t1pci_send_init(avmcard *card) +{ + struct sk_buff *skb; + void *p; + + skb = alloc_skb(15, GFP_ATOMIC); + if (!skb) { + printk(KERN_CRIT "%s: no memory, lost register appl.\n", + card->name); + return; + } + p = skb->data; + _put_byte(&p, 0); + _put_byte(&p, 0); + _put_byte(&p, SEND_INIT); + _put_word(&p, AVM_NAPPS); + _put_word(&p, AVM_NCCI_PER_CHANNEL*30); + _put_word(&p, card->cardnr - 1); + skb_put(skb, (__u8 *)p - (__u8 *)skb->data); + + skb_queue_tail(&card->dma->send_queue, skb); + t1pci_dispatch_tx(card); +} + +static int t1pci_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; + unsigned long flags; + int retval; + + t1pci_reset(card); + + if ((retval = b1_load_t4file(card, &data->firmware))) { + t1pci_reset(card); + printk(KERN_ERR "%s: failed to load t4file!!\n", + card->name); + return retval; + } + + if (data->configuration.len > 0 && data->configuration.data) { + if ((retval = b1_load_config(card, &data->configuration))) { + t1pci_reset(card); + printk(KERN_ERR "%s: failed to load config!!\n", + card->name); + return retval; + } + } + + if (!t1pci_loaded(card)) { + t1pci_reset(card); + printk(KERN_ERR "%s: failed to load t4file.\n", card->name); + return -EIO; + } + + save_flags(flags); + cli(); + + card->csr = AVM_FLAG; + t1outmeml(card->mbase+AMCC_INTCSR, card->csr); + t1outmeml(card->mbase+AMCC_MCSR, + EN_A2P_TRANSFERS|EN_P2A_TRANSFERS + |A2P_HI_PRIORITY|P2A_HI_PRIORITY + |RESET_A2P_FLAGS|RESET_P2A_FLAGS); + t1outp(card->port, 0x07, 0x30); + t1outp(card->port, 0x10, 0xF0); + + card->dma->recvlen = 0; + t1outmeml(card->mbase+AMCC_RXPTR, virt_to_phys(card->dma->recvbuf)); + t1outmeml(card->mbase+AMCC_RXLEN, 4); + card->csr |= EN_RX_TC_INT; + t1outmeml(card->mbase+AMCC_INTCSR, card->csr); + restore_flags(flags); + + t1pci_send_init(card); + + return 0; +} + +void t1pci_reset_ctr(struct capi_ctr *ctrl) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; + + t1pci_reset(card); + + memset(cinfo->version, 0, sizeof(cinfo->version)); + ctrl->reseted(ctrl); +} + +static void t1pci_remove_ctr(struct capi_ctr *ctrl) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; + + t1pci_reset(card); + + di->detach_ctr(ctrl); + free_irq(card->irq, card); + iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); + release_region(card->port, AVMB1_PORTLEN); + ctrl->driverdata = 0; + kfree(card->ctrlinfo); + kfree(card->dma); + kfree(card); + + MOD_DEC_USE_COUNT; +} + +/* ------------------------------------------------------------- */ + + +void t1pci_register_appl(struct capi_ctr *ctrl, + __u16 appl, + capi_register_params *rp) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; + struct sk_buff *skb; + int want = rp->level3cnt; + int nconn; + void *p; + + if (want > 0) nconn = want; + else nconn = ctrl->profile.nbchannel * -want; + if (nconn == 0) nconn = ctrl->profile.nbchannel; + + skb = alloc_skb(23, GFP_ATOMIC); + if (!skb) { + printk(KERN_CRIT "%s: no memory, lost register appl.\n", + card->name); + return; + } + p = skb->data; + _put_byte(&p, 0); + _put_byte(&p, 0); + _put_byte(&p, SEND_REGISTER); + _put_word(&p, appl); + _put_word(&p, 1024 * (nconn+1)); + _put_word(&p, nconn); + _put_word(&p, rp->datablkcnt); + _put_word(&p, rp->datablklen); + skb_put(skb, (__u8 *)p - (__u8 *)skb->data); + + skb_queue_tail(&card->dma->send_queue, skb); + t1pci_dispatch_tx(card); + + ctrl->appl_registered(ctrl, appl); +} + +/* ------------------------------------------------------------- */ + +void t1pci_release_appl(struct capi_ctr *ctrl, __u16 appl) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; + struct sk_buff *skb; + void *p; + + skb = alloc_skb(7, GFP_ATOMIC); + if (!skb) { + printk(KERN_CRIT "%s: no memory, lost release appl.\n", + card->name); + return; + } + p = skb->data; + _put_byte(&p, 0); + _put_byte(&p, 0); + _put_byte(&p, SEND_RELEASE); + _put_word(&p, appl); + + skb_put(skb, (__u8 *)p - (__u8 *)skb->data); + skb_queue_tail(&card->dma->send_queue, skb); + t1pci_dispatch_tx(card); +} + +/* ------------------------------------------------------------- */ + + +static void t1pci_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; + skb_queue_tail(&card->dma->send_queue, skb); + t1pci_dispatch_tx(card); +} + +/* ------------------------------------------------------------- */ + +static char *t1pci_procinfo(struct capi_ctr *ctrl) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + + if (!cinfo) + return ""; + sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx", + cinfo->cardname[0] ? cinfo->cardname : "-", + cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", + cinfo->card ? cinfo->card->port : 0x0, + cinfo->card ? cinfo->card->irq : 0, + cinfo->card ? cinfo->card->membase : 0 + ); + return cinfo->infobuf; +} + +static int t1pci_read_proc(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *ctrl) +{ + avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); + avmcard *card = cinfo->card; + unsigned long flags; + __u8 flag; + int len = 0; + char *s; + __u32 txaddr, txlen, rxaddr, rxlen, csr; + + len += sprintf(page+len, "%-16s %s\n", "name", card->name); + len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); + len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); + len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); + switch (card->cardtype) { + case avm_b1isa: s = "B1 ISA"; break; + case avm_b1pci: s = "B1 PCI"; break; + case avm_b1pcmcia: s = "B1 PCMCIA"; break; + case avm_m1: s = "M1"; break; + case avm_m2: s = "M2"; break; + case avm_t1isa: s = "T1 ISA (HEMA)"; break; + case avm_t1pci: s = "T1 PCI"; break; + case avm_c4: s = "C4"; break; + default: s = "???"; break; + } + len += sprintf(page+len, "%-16s %s\n", "type", s); + if ((s = cinfo->version[VER_DRIVER]) != 0) + len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); + if ((s = cinfo->version[VER_CARDTYPE]) != 0) + len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); + if ((s = cinfo->version[VER_SERIAL]) != 0) + len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); + + if (card->cardtype != avm_m1) { + flag = ((__u8 *)(ctrl->profile.manu))[3]; + if (flag) + len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", + "protocol", + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); + } + if (card->cardtype != avm_m1) { + flag = ((__u8 *)(ctrl->profile.manu))[5]; + if (flag) + len += sprintf(page+len, "%-16s%s%s%s%s\n", + "linetype", + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); + } + len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); + + save_flags(flags); + cli(); + + txaddr = (__u32)phys_to_virt(t1inmeml(card->mbase+0x2c)); + txaddr -= (__u32)card->dma->sendbuf; + txlen = t1inmeml(card->mbase+0x30); + + rxaddr = (__u32)phys_to_virt(t1inmeml(card->mbase+0x24)); + rxaddr -= (__u32)card->dma->recvbuf; + rxlen = t1inmeml(card->mbase+0x28); + + csr = t1inmeml(card->mbase+AMCC_INTCSR); + + restore_flags(flags); + + len += sprintf(page+len, "%-16s 0x%lx\n", + "csr (cached)", (unsigned long)card->csr); + len += sprintf(page+len, "%-16s 0x%lx\n", + "csr", (unsigned long)csr); + len += sprintf(page+len, "%-16s %lu\n", + "txoff", (unsigned long)txaddr); + len += sprintf(page+len, "%-16s %lu\n", + "txlen", (unsigned long)txlen); + len += sprintf(page+len, "%-16s %lu\n", + "rxoff", (unsigned long)rxaddr); + len += sprintf(page+len, "%-16s %lu\n", + "rxlen", (unsigned long)rxlen); + + if (off+count >= len) + *eof = 1; + if (len < off) + return 0; + *start = page + off; + return ((count < len-off) ? count : len-off); +} + +/* ------------------------------------------------------------- */ + +static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p) +{ + unsigned long page_offset, base; + avmcard *card; + avmctrl_info *cinfo; + int retval; + + card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); + + if (!card) { + printk(KERN_WARNING "%s: no memory.\n", driver->name); + return -ENOMEM; + } + memset(card, 0, sizeof(avmcard)); + card->dma = (avmcard_dmainfo *) kmalloc(sizeof(avmcard_dmainfo), GFP_ATOMIC); + if (!card->dma) { + printk(KERN_WARNING "%s: no memory.\n", driver->name); + kfree(card); + return -ENOMEM; + } + memset(card->dma, 0, sizeof(avmcard_dmainfo)); + cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC); + if (!cinfo) { + printk(KERN_WARNING "%s: no memory.\n", driver->name); + kfree(card->dma); + kfree(card); + return -ENOMEM; + } + memset(cinfo, 0, sizeof(avmctrl_info)); + card->ctrlinfo = cinfo; + cinfo->card = card; + sprintf(card->name, "t1pci-%x", p->port); + card->port = p->port; + card->irq = p->irq; + card->membase = p->membase; + card->cardtype = avm_t1pci; + + if (check_region(card->port, AVMB1_PORTLEN)) { + printk(KERN_WARNING + "%s: ports 0x%03x-0x%03x in use.\n", + driver->name, card->port, card->port + AVMB1_PORTLEN); + kfree(card->ctrlinfo); + kfree(card->dma); + kfree(card); + return -EBUSY; + } + + base = card->membase & PAGE_MASK; + page_offset = card->membase - base; + card->mbase = ioremap_nocache(base, page_offset + 64); + + t1pci_reset(card); + + if ((retval = t1pci_detect(card)) != 0) { + printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", + driver->name, card->port, retval); + iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); + kfree(card->ctrlinfo); + kfree(card->dma); + kfree(card); + return -EIO; + } + t1pci_reset(card); + + request_region(p->port, AVMB1_PORTLEN, card->name); + + retval = request_irq(card->irq, t1pci_interrupt, SA_SHIRQ, card->name, card); + if (retval) { + printk(KERN_ERR "%s: unable to get IRQ %d.\n", + driver->name, card->irq); + iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); + release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); + kfree(card->dma); + kfree(card); + return -EBUSY; + } + + cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); + if (!cinfo->capi_ctrl) { + printk(KERN_ERR "%s: attach controller failed.\n", driver->name); + iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK)); + free_irq(card->irq, card); + release_region(card->port, AVMB1_PORTLEN); + kfree(card->ctrlinfo); + kfree(card->dma); + kfree(card); + return -EBUSY; + } + card->cardnr = cinfo->capi_ctrl->cnr; + + skb_queue_head_init(&card->dma->send_queue); + + MOD_INC_USE_COUNT; + + return 0; +} + +/* ------------------------------------------------------------- */ + +static struct capi_driver t1pci_driver = { + "t1pci", + "0.0", + t1pci_load_firmware, + t1pci_reset_ctr, + t1pci_remove_ctr, + t1pci_register_appl, + t1pci_release_appl, + t1pci_send_message, + + t1pci_procinfo, + t1pci_read_proc, + 0, /* use standard driver_read_proc */ + + 0, /* no add_card function */ +}; + +#ifdef MODULE +#define t1pci_init init_module +void cleanup_module(void); +#endif + +static int ncards = 0; + +int t1pci_init(void) +{ + struct capi_driver *driver = &t1pci_driver; + struct pci_dev *dev = NULL; + char *p; + int retval; + + if ((p = strchr(revision, ':'))) { + strncpy(driver->revision, p + 1, sizeof(driver->revision)); + p = strchr(driver->revision, '$'); + *p = 0; + } + + printk(KERN_INFO "%s: revision %s\n", driver->name, driver->revision); + + di = attach_capi_driver(driver); + + if (!di) { + printk(KERN_ERR "%s: failed to attach capi_driver\n", + driver->name); + return -EIO; + } + +#ifdef CONFIG_PCI + if (!pci_present()) { + printk(KERN_ERR "%s: no PCI bus present\n", driver->name); + detach_capi_driver(driver); + return -EIO; + } + + while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, dev))) { + struct capicardparams param; + + param.port = dev->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK; + param.irq = dev->irq; + param.membase = dev->resource[ 0].start & PCI_BASE_ADDRESS_MEM_MASK; + + printk(KERN_INFO + "%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n", + driver->name, param.port, param.irq, param.membase); + retval = t1pci_add_card(driver, ¶m); + if (retval != 0) { + printk(KERN_ERR + "%s: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n", + driver->name, param.port, param.irq, param.membase); +#ifdef MODULE + cleanup_module(); +#endif + return retval; + } + ncards++; + } + if (ncards) { + printk(KERN_INFO "%s: %d T1-PCI card(s) detected\n", + driver->name, ncards); + return 0; + } + printk(KERN_ERR "%s: NO T1-PCI card detected\n", driver->name); + return -ESRCH; +#else + printk(KERN_ERR "%s: kernel not compiled with PCI.\n", driver->name); + return -EIO; +#endif +} + +#ifdef MODULE +void cleanup_module(void) +{ + detach_capi_driver(&t1pci_driver); +} +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c --- v2.3.26/linux/drivers/isdn/divert/divert_procfs.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/divert/divert_procfs.c Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ /* - * $Id: divert_procfs.c,v 1.4 1999/08/06 07:42:48 calle Exp $ + * $Id: divert_procfs.c,v 1.5 1999/09/14 20:31:01 werner Exp $ * * Filesystem handling for the diversion supplementary services. * @@ -20,6 +20,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: divert_procfs.c,v $ + * Revision 1.5 1999/09/14 20:31:01 werner + * + * Removed obsoleted functions for proc fs and synced with new ones. + * * Revision 1.4 1999/08/06 07:42:48 calle * Added COMPAT_HAS_NEW_WAITQ for rd_queue for newer kernels. * @@ -38,16 +42,13 @@ #define __NO_VERSION__ #include #include -#if (LINUX_VERSION_CODE >= 0x020117) #include -#endif #ifdef CONFIG_PROC_FS #include #else #include #endif #include -#include #include "isdn_divert.h" /*********************************/ @@ -56,11 +57,7 @@ ulong if_used = 0; /* number of interface users */ static struct divert_info *divert_info_head = NULL; /* head of queue */ static struct divert_info *divert_info_tail = NULL; /* pointer to last entry */ -#ifdef COMPAT_HAS_NEW_WAITQ static wait_queue_head_t rd_queue; -#else -static struct wait_queue *rd_queue = 0; /* Queue IO */ -#endif /*********************************/ /* put an info buffer into queue */ @@ -101,11 +98,7 @@ /**********************************/ /* deflection device read routine */ /**********************************/ -#if (LINUX_VERSION_CODE < 0x020117) -static int isdn_divert_read(struct inode *inode, struct file *file, char *buf, RWARG count) -#else static ssize_t isdn_divert_read(struct file *file, char *buf, size_t count, loff_t *off) -#endif { struct divert_info *inf; int len; @@ -130,11 +123,7 @@ /**********************************/ /* deflection device write routine */ /**********************************/ -#if (LINUX_VERSION_CODE < 0x020117) -static int isdn_divert_write(struct inode *inode, struct file *file, const char *buf, RWARG count) -#else static ssize_t isdn_divert_write(struct file *file, const char *buf, size_t count, loff_t *off) -#endif { return(-ENODEV); } /* isdn_divert_write */ @@ -143,17 +132,6 @@ /***************************************/ /* select routines for various kernels */ /***************************************/ -#if (LINUX_VERSION_CODE < 0x020117) -static int isdn_divert_select(struct inode *inode, struct file *file, int type, select_table * st) -{ - if (*((struct divert_info **)file->private_data)) - return 1; - else - { if (st) select_wait(&(rd_queue), st); - return 0; - } -} /* isdn_divert_select */ -#else static unsigned int isdn_divert_poll(struct file *file, poll_table * wait) { unsigned int mask = 0; @@ -164,7 +142,6 @@ } return mask; } /* isdn_divert_poll */ -#endif /****************/ /* Open routine */ @@ -188,11 +165,7 @@ /*******************/ /* close routine */ /*******************/ -#if (LINUX_VERSION_CODE < 0x020117) -static void isdn_divert_close(struct inode *ino, struct file *filep) -#else static int isdn_divert_close(struct inode *ino, struct file *filep) -#endif { struct divert_info *inf; int flags; @@ -212,10 +185,7 @@ kfree(inf); } MOD_DEC_USE_COUNT; -#if (LINUX_VERSION_CODE < 0x020117) -#else return(0); -#endif } /* isdn_divert_close */ /*********/ @@ -301,34 +271,12 @@ #ifdef CONFIG_PROC_FS -#if (LINUX_VERSION_CODE < 0x020117) -static LSTYPE -isdn_divert_lseek(struct inode *inode, struct file *file, LSARG offset, int orig) -#else static loff_t isdn_divert_lseek(struct file *file, loff_t offset, int orig) -#endif { return -ESPIPE; } -#if (LINUX_VERSION_CODE < 0x020117) -static struct file_operations isdn_fops = -{ - isdn_divert_lseek, - isdn_divert_read, - isdn_divert_write, - NULL, /* isdn_readdir */ - isdn_divert_select, /* isdn_select */ - isdn_divert_ioctl, /* isdn_ioctl */ - NULL, /* isdn_mmap */ - isdn_divert_open, - isdn_divert_close, - NULL /* fsync */ -}; - -#else - static struct file_operations isdn_fops = { isdn_divert_lseek, @@ -343,51 +291,33 @@ isdn_divert_close, NULL /* fsync */ }; -#endif /* kernel >= 2.1 */ - -/* - * proc directories can do almost nothing.. - */ -struct inode_operations proc_isdn_inode_ops = { - &isdn_fops, /* isdn divert special file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* bmap */ - NULL, /* truncate */ - NULL /* permission */ +struct inode_operations divert_file_inode_operations = { + &isdn_fops, /* default proc file-ops */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + NULL, /* readlink */ + NULL, /* follow_link */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* bmap */ + NULL, /* truncate */ + NULL /* permission */ }; + /****************************/ /* isdn subdir in /proc/net */ /****************************/ -static struct proc_dir_entry isdn_proc_entry = - { 0, 4, "isdn", S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, 0, - &proc_dir_inode_operations,NULL,NULL,NULL,NULL,NULL - }; - -static struct proc_dir_entry isdn_divert_entry = -{ 0, 6, "divert",S_IFREG | S_IRUGO, 1, 0, 0, 0, &proc_isdn_inode_ops, - NULL - }; - -/*****************************************************************/ -/* variables used for automatic determining existence of proc fs */ -/*****************************************************************/ -static int (*proc_reg_dynamic)(struct proc_dir_entry *, struct proc_dir_entry *) = NULL; -static int (*proc_unreg)(struct proc_dir_entry *, int) = NULL; - +static struct proc_dir_entry *isdn_proc_entry = NULL; +static struct proc_dir_entry *isdn_divert_entry = NULL; #endif CONFIG_PROC_FS /***************************************************************************/ @@ -396,36 +326,19 @@ int divert_dev_init(void) { int i; -#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&rd_queue); -#endif #ifdef CONFIG_PROC_FS -#if (LINUX_VERSION_CODE < 0x020117) - (void *) proc_reg_dynamic = get_module_symbol("","proc_register_dynamic"); - (void *) proc_unreg = get_module_symbol("","proc_unregister"); - if (proc_unreg) - { i = proc_reg_dynamic(&proc_net,&isdn_proc_entry); - if (i) return(i); - i = proc_reg_dynamic(&isdn_proc_entry,&isdn_divert_entry); - if (i) - { proc_unreg(&proc_net,isdn_proc_entry.low_ino); - return(i); - } - } /* proc exists */ -#else - (void *) proc_reg_dynamic = get_module_symbol("","proc_register"); - (void *) proc_unreg = get_module_symbol("","proc_unregister"); - if (proc_unreg) - { i = proc_reg_dynamic(proc_net,&isdn_proc_entry); - if (i) return(i); - i = proc_reg_dynamic(&isdn_proc_entry,&isdn_divert_entry); - if (i) - { proc_unreg(proc_net,isdn_proc_entry.low_ino); - return(i); - } - } /* proc exists */ -#endif + isdn_proc_entry = create_proc_entry("isdn", S_IFDIR | S_IRUGO | S_IXUGO ,proc_net); + if (!isdn_proc_entry) + return(-1); + isdn_divert_entry = create_proc_entry("divert",S_IFREG | S_IRUGO,isdn_proc_entry); + if (!isdn_divert_entry) + { + remove_proc_entry("isdn",proc_net); + return(-1); + } + isdn_divert_entry->ops = &divert_file_inode_operations; #endif CONFIG_PROC_FS return(0); @@ -439,16 +352,8 @@ { int i; #ifdef CONFIG_PROC_FS - if (proc_unreg) - { i = proc_unreg(&isdn_proc_entry,isdn_divert_entry.low_ino); - if (i) return(i); -#if (LINUX_VERSION_CODE < 0x020117) - i = proc_unreg(&proc_net,isdn_proc_entry.low_ino); -#else - i = proc_unreg(proc_net,isdn_proc_entry.low_ino); -#endif - if (i) return(i); - } /* proc exists */ + remove_proc_entry("divert",isdn_proc_entry); + remove_proc_entry("isdn",proc_net); #endif CONFIG_PROC_FS return(0); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/divert/isdn_divert.c linux/drivers/isdn/divert/isdn_divert.c --- v2.3.26/linux/drivers/isdn/divert/isdn_divert.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/divert/isdn_divert.c Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ /* - * $Id: isdn_divert.c,v 1.4 1999/08/25 20:02:21 werner Exp $ + * $Id: isdn_divert.c,v 1.5 1999/08/31 11:20:04 paul Exp $ * * DSS1 main diversion supplementary handling for i4l. * @@ -20,6 +20,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_divert.c,v $ + * Revision 1.5 1999/08/31 11:20:04 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.4 1999/08/25 20:02:21 werner * Changed return values for stat_icall(w) from 3->4 and 4->5 because of conflicts * with existing software definitions. (PtP incomplete called party number) @@ -513,7 +516,7 @@ if (cs->akt_state == DEFLECT_ALERT) { strcpy(cs->deflect_dest,dv->rule.to_nr); if (!cs->timer.expires) - { strcpy(ic->parm.setup.eazmsn,"Testtext direkt"); + { strcpy(ic->parm.setup.eazmsn,"Testtext direct"); ic->parm.setup.screen = dv->rule.screen; strcpy(ic->parm.setup.phone,dv->rule.to_nr); cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ @@ -769,18 +772,6 @@ } -#if 0 - sprintf(st, "0x%lx 0x%lx",ic->arg, ic->parm.dss1_io.ll_id); - p = st + strlen(st); - p1 = ic->parm.dss1_io.data; - i = ic->parm.dss1_io.datalen; - while ((i > 0) && (p - st < 530)) - { p += sprintf(p," %02x",(*p1++) & 0xFF); - i--; - } - sprintf(p, "\n"); - put_info_buffer(st); -#endif break; default: diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/divert/isdn_divert.h linux/drivers/isdn/divert/isdn_divert.h --- v2.3.26/linux/drivers/isdn/divert/isdn_divert.h Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/divert/isdn_divert.h Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ /* - * $Id: isdn_divert.h,v 1.3 1999/08/22 20:26:37 calle Exp $ + * $Id: isdn_divert.h,v 1.4 1999/09/02 13:24:12 paul Exp $ * * Header for the diversion supplementary ioctl interface. * @@ -20,6 +20,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_divert.h,v $ + * Revision 1.4 1999/09/02 13:24:12 paul + * cosmetics; text following #endif is not ANSI C + * * Revision 1.3 1999/08/22 20:26:37 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -29,12 +32,9 @@ * Revision 1.2 1999/07/04 21:37:33 werner * Ported from kernel version 2.0 * - * - * */ - #include #include @@ -94,12 +94,12 @@ typedef union { int drv_version; /* return of driver version */ struct - { int drvid; /* id of driver */ - char drvnam[30]; /* name of driver */ + { int drvid; /* id of driver */ + char drvnam[30]; /* name of driver */ } getid; struct - { int ruleidx; /* index of rule */ - divert_rule rule; /* rule parms */ + { int ruleidx; /* index of rule */ + divert_rule rule; /* rule parms */ } getsetrule; struct { u_char subcmd; /* 0 = hangup/reject, @@ -125,7 +125,7 @@ #include #include -#define AUTODEL_TIME 30 /* timeout in s to delete internal entrys */ +#define AUTODEL_TIME 30 /* timeout in s to delete internal entries */ /**************************************************/ /* structure keeping ascii info for device output */ @@ -153,12 +153,4 @@ extern int deflect_extern_action(u_char, ulong, char *); extern int cf_command(int, int, u_char, char *, u_char, char *, ulong *); -#endif __KERNEL__ - - - - - - - - +#endif /* __KERNEL__ */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/eicon/eicon.h linux/drivers/isdn/eicon/eicon.h --- v2.3.26/linux/drivers/isdn/eicon/eicon.h Tue Aug 31 17:29:13 1999 +++ linux/drivers/isdn/eicon/eicon.h Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: eicon.h,v 1.11 1999/08/29 17:23:44 armin Exp $ +/* $Id: eicon.h,v 1.17 1999/10/26 21:15:33 armin Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * - * Copyright 1998 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1998,99 by Armin Schindler (mac@melware.de) * Copyright 1999 Cytronics & Melware (info@melware.de) * @@ -21,6 +21,26 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon.h,v $ + * Revision 1.17 1999/10/26 21:15:33 armin + * using define for checking phone number len to avoid buffer overflow. + * + * Revision 1.16 1999/10/08 22:09:33 armin + * Some fixes of cards interface handling. + * Bugfix of NULL pointer occurence. + * Changed a few log outputs. + * + * Revision 1.15 1999/09/26 14:17:53 armin + * Improved debug and log via readstat() + * + * Revision 1.14 1999/09/08 20:17:31 armin + * Added microchannel patch from Erik Weber. + * + * Revision 1.13 1999/09/06 07:29:35 fritz + * Changed my mail-address. + * + * Revision 1.12 1999/09/04 06:20:05 keil + * Changes from kernel set_current_state() + * * Revision 1.11 1999/08/29 17:23:44 armin * New setup compat. * Bugfix if compile as not module. @@ -117,6 +137,7 @@ #define MAX_HEADER_LEN 10 +#define MAX_STATUS_BUFFER 150 /* Struct for adding new cards */ typedef struct eicon_cdef { @@ -224,9 +245,9 @@ #include #include +#include #include -#include typedef struct { __u16 length __attribute__ ((packed)); /* length of data/parameter field */ @@ -237,7 +258,7 @@ /* Macro for delay via schedule() */ #define SLEEP(j) { \ - current->state = TASK_INTERRUPTIBLE; \ + set_current_state(TASK_INTERRUPTIBLE); \ schedule_timeout(j); \ } @@ -472,7 +493,6 @@ typedef struct { int No; /* Channel Number */ - unsigned short callref; /* Call Reference */ unsigned short fsm_state; /* Current D-Channel state */ unsigned short eazmask; /* EAZ-Mask for this Channel */ int queued; /* User-Data Bytes in TX queue */ @@ -489,9 +509,13 @@ entity e; /* Entity */ char cpn[32]; /* remember cpn */ char oad[32]; /* remember oad */ + char dsa[32]; /* remember dsa */ + char osa[32]; /* remember osa */ unsigned char cause[2]; /* Last Cause */ unsigned char si1; unsigned char si2; + unsigned char plan; + unsigned char screen; } eicon_chan; typedef struct { @@ -527,7 +551,7 @@ #define EICON_STATE_LISTEN 15 #define EICON_STATE_WMCONN 16 -#define EICON_MAX_QUEUED 8000 /* 2 * maxbuff */ +#define EICON_MAX_QUEUE 2138 #define EICON_LOCK_TX 0 #define EICON_LOCK_RX 1 @@ -581,6 +605,8 @@ struct sk_buff_head sndq; /* Send-Message queue */ struct sk_buff_head rackq; /* Req-Ack-Message queue */ struct sk_buff_head sackq; /* Data-Ack-Message queue */ + struct sk_buff_head statq; /* Status-Message queue */ + int statq_entries; u_char *ack_msg; /* Ptr to User Data in User skb */ __u16 need_b3ack; /* Flag: Need ACK for current skb */ struct sk_buff *sbuf; /* skb which is currently sent */ @@ -602,8 +628,9 @@ isdn_if interface; /* Interface to upper layer */ char regname[35]; /* Name used for request_region */ #ifdef CONFIG_MCA - int mca_slot; /* # of cards MCA slot */ -#endif + int mca_slot; /* # of cards MCA slot */ + int mca_io; /* MCA cards IO port */ +#endif /* CONFIG_MCA */ } eicon_card; /* -----------------------------------------------------------** @@ -668,6 +695,7 @@ #endif /* CONFIG_MCA */ extern ulong DebugVar; +extern void eicon_log(eicon_card * card, int level, const char *fmt, ...); #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/eicon/eicon_idi.c linux/drivers/isdn/eicon/eicon_idi.c --- v2.3.26/linux/drivers/isdn/eicon/eicon_idi.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/isdn/eicon/eicon_idi.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_idi.c,v 1.15 1999/08/28 21:32:50 armin Exp $ +/* $Id: eicon_idi.c,v 1.24 1999/10/26 21:15:33 armin Exp $ * * ISDN lowlevel-module for Eicon.Diehl active cards. * IDI interface @@ -6,6 +6,11 @@ * Copyright 1998,99 by Armin Schindler (mac@melware.de) * Copyright 1999 Cytronics & Melware (info@melware.de) * + * Thanks to Deutsche Mailbox Saar-Lor-Lux GmbH + * for sponsoring and testing fax + * capabilities with Diva Server cards. + * (dor@deutschemailbox.de) + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -21,6 +26,35 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_idi.c,v $ + * Revision 1.24 1999/10/26 21:15:33 armin + * using define for checking phone number len to avoid buffer overflow. + * + * Revision 1.23 1999/10/11 18:13:25 armin + * Added fax capabilities for Eicon Diva Server cards. + * + * Revision 1.22 1999/10/08 22:09:33 armin + * Some fixes of cards interface handling. + * Bugfix of NULL pointer occurence. + * Changed a few log outputs. + * + * Revision 1.21 1999/09/26 14:17:53 armin + * Improved debug and log via readstat() + * + * Revision 1.20 1999/09/21 20:35:43 armin + * added more error checking. + * + * Revision 1.19 1999/09/21 20:06:40 armin + * Added pointer checks. + * + * Revision 1.18 1999/09/07 12:48:05 armin + * Prepared for sub-address usage. + * + * Revision 1.17 1999/09/07 12:35:39 armin + * Better checking and channel Id handling. + * + * Revision 1.16 1999/09/04 13:44:19 armin + * Fix of V.42 analog Modem negotiation handling. + * * Revision 1.15 1999/08/28 21:32:50 armin * Prepared for fax related functions. * Now compilable without errors/warnings. @@ -96,7 +130,7 @@ #undef EICON_FULL_SERVICE_OKTETT -char *eicon_idi_revision = "$Revision: 1.15 $"; +char *eicon_idi_revision = "$Revision: 1.24 $"; eicon_manifbuf *manbuf; @@ -162,9 +196,14 @@ reqbuf->XBuffer.P[l++] = 5; break; case ISDN_PROTO_L2_TRANS: - case ISDN_PROTO_L2_MODEM: reqbuf->XBuffer.P[l++] = 2; break; + case ISDN_PROTO_L2_MODEM: + if (chan->fsm_state == EICON_STATE_IWAIT) + reqbuf->XBuffer.P[l++] = 9; /* V.42 incoming */ + else + reqbuf->XBuffer.P[l++] = 10; /* V.42 */ + break; case ISDN_PROTO_L2_FAX: if (chan->fsm_state == EICON_STATE_IWAIT) reqbuf->XBuffer.P[l++] = 3; /* autoconnect on incoming */ @@ -275,8 +314,7 @@ reqbuf->XBuffer.P[8] = 0; reqbuf->XBuffer.length = l; reqbuf->Reference = 0; /* Sig Entity */ - if (DebugVar & 8) - printk(KERN_DEBUG"idi_req: Ch%d: Call_Res\n", chan->No); + eicon_log(NULL, 8, "idi_req: Ch%d: Call_Res\n", chan->No); return(0); } @@ -292,8 +330,7 @@ skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); if ((!skb) || (!skb2)) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No); + eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in do_req()\n", chan->No); if (skb) dev_kfree_skb(skb); if (skb2) @@ -305,8 +342,7 @@ chan2->ptr = chan; reqbuf = (eicon_REQ *)skb_put(skb, 270 + sizeof(eicon_REQ)); - if (DebugVar & 8) - printk(KERN_DEBUG "idi_req: Ch%d: req %x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig"); + eicon_log(card, 8, "idi_req: Ch%d: req %x (%s)\n", chan->No, cmd, (layer)?"Net":"Sig"); if (layer) cmd |= 0x700; switch(cmd) { case ASSIGN: @@ -345,8 +381,7 @@ idi_put_req(reqbuf, IDI_N_DISC_ACK, 1); break; default: - if (DebugVar & 1) - printk(KERN_ERR "idi_req: Ch%d: Unknown request\n", chan->No); + eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No); dev_kfree_skb(skb); dev_kfree_skb(skb2); return(-1); @@ -361,8 +396,10 @@ int eicon_idi_listen_req(eicon_card *card, eicon_chan *chan) { - if (DebugVar & 16) - printk(KERN_DEBUG"idi_req: Ch%d: Listen_Req eazmask=0x%x\n",chan->No, chan->eazmask); + if ((!card) || (!chan)) + return 1; + + eicon_log(card, 16, "idi_req: Ch%d: Listen_Req eazmask=0x%x\n",chan->No, chan->eazmask); if (!chan->e.D3Id) { idi_do_req(card, chan, ASSIGN, 0); } @@ -416,15 +453,19 @@ int idi_hangup(eicon_card *card, eicon_chan *chan) { + if ((!card) || (!chan)) + return 1; + if ((chan->fsm_state == EICON_STATE_ACTIVE) || (chan->fsm_state == EICON_STATE_WMCONN)) { if (chan->e.B2Id) idi_do_req(card, chan, IDI_N_DISC, 1); } if (chan->e.B2Id) idi_do_req(card, chan, REMOVE, 1); - idi_do_req(card, chan, HANGUP, 0); - chan->fsm_state = EICON_STATE_NULL; - if (DebugVar & 8) - printk(KERN_DEBUG"idi_req: Ch%d: Hangup\n", chan->No); + if (chan->fsm_state != EICON_STATE_NULL) { + idi_do_req(card, chan, HANGUP, 0); + chan->fsm_state = EICON_STATE_NULL; + } + eicon_log(card, 8, "idi_req: Ch%d: Hangup\n", chan->No); #ifdef CONFIG_ISDN_TTY_FAX chan->fax = 0; #endif @@ -434,10 +475,21 @@ int idi_connect_res(eicon_card *card, eicon_chan *chan) { - chan->fsm_state = EICON_STATE_IWAIT; - idi_do_req(card, chan, CALL_RES, 0); - idi_do_req(card, chan, ASSIGN, 1); - return(0); + if ((!card) || (!chan)) + return 1; + + chan->fsm_state = EICON_STATE_IWAIT; + idi_do_req(card, chan, CALL_RES, 0); + + /* check if old NetID has been removed */ + if (chan->e.B2Id) { + eicon_log(card, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n", + chan->No, chan->e.B2Id); + idi_do_req(card, chan, REMOVE, 1); + } + + idi_do_req(card, chan, ASSIGN, 1); + return(0); } int @@ -447,6 +499,7 @@ int l = 0; int i; unsigned char tmp; + unsigned char *sub, *sp; unsigned char bc[5]; unsigned char hlc[5]; struct sk_buff *skb; @@ -454,12 +507,14 @@ eicon_REQ *reqbuf; eicon_chan_ptr *chan2; + if ((!card) || (!chan)) + return 1; + skb = alloc_skb(270 + sizeof(eicon_REQ), GFP_ATOMIC); skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); if ((!skb) || (!skb2)) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No); + eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in connect_req()\n", chan->No); if (skb) dev_kfree_skb(skb); if (skb2) @@ -475,18 +530,52 @@ reqbuf->ReqCh = 0; reqbuf->ReqId = 1; + sub = NULL; + sp = phone; + while (*sp) { + if (*sp == '.') { + sub = sp + 1; + *sp = 0; + } else + sp++; + } reqbuf->XBuffer.P[l++] = CPN; reqbuf->XBuffer.P[l++] = strlen(phone) + 1; reqbuf->XBuffer.P[l++] = 0x81; for(i=0; iXBuffer.P[l++] = phone[i]; - + reqbuf->XBuffer.P[l++] = phone[i] & 0x7f; + if (sub) { + reqbuf->XBuffer.P[l++] = DSA; + reqbuf->XBuffer.P[l++] = strlen(sub) + 2; + reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */ + reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */ + while (*sub) + reqbuf->XBuffer.P[l++] = *sub++ & 0x7f; + } + + sub = NULL; + sp = eazmsn; + while (*sp) { + if (*sp == '.') { + sub = sp + 1; + *sp = 0; + } else + sp++; + } reqbuf->XBuffer.P[l++] = OAD; reqbuf->XBuffer.P[l++] = strlen(eazmsn) + 2; reqbuf->XBuffer.P[l++] = 0x01; reqbuf->XBuffer.P[l++] = 0x80; for(i=0; iXBuffer.P[l++] = eazmsn[i]; + reqbuf->XBuffer.P[l++] = eazmsn[i] & 0x7f; + if (sub) { + reqbuf->XBuffer.P[l++] = OSA; + reqbuf->XBuffer.P[l++] = strlen(sub) + 2; + reqbuf->XBuffer.P[l++] = 0x80; /* NSAP coded */ + reqbuf->XBuffer.P[l++] = 0x50; /* local IDI format */ + while (*sub) + reqbuf->XBuffer.P[l++] = *sub++ & 0x7f; + } if ((tmp = idi_si2bc(si1, si2, bc, hlc)) > 0) { reqbuf->XBuffer.P[l++] = BC; @@ -500,6 +589,7 @@ reqbuf->XBuffer.P[l++] = hlc[i]; } } + reqbuf->XBuffer.P[l++] = CAI; reqbuf->XBuffer.P[l++] = 6; reqbuf->XBuffer.P[l++] = 0x09; @@ -570,8 +660,7 @@ skb_queue_tail(&card->sndq, skb2); eicon_schedule_tx(card); - if (DebugVar & 8) - printk(KERN_DEBUG"idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone); + eicon_log(card, 8, "idi_req: Ch%d: Conn_Req %s -> %s\n",chan->No, eazmsn, phone); return(0); } @@ -588,9 +677,10 @@ __u16 code; isdn_ctrl cmd; - memset(message, 0, sizeof(idi_ind_message)); + memset(message, 0, sizeof(idi_ind_message)); + + if ((!len) || (!buffer[pos])) return; - if ((!len) || (!buffer[pos])) return; while(pos <= len) { w = buffer[pos++]; if (!w) return; @@ -620,8 +710,18 @@ else code = w; code |= (codeset<<8); + if (pos + wlen > len) { + eicon_log(ccard, 1, "idi_err: Ch%d: IElen %d of %x exceeds Ind_Length (+%d)\n", chan->No, + wlen, code, (pos + wlen) - len); + return; + } + switch(code) { case OAD: + if (wlen > sizeof(message->oad)) { + pos += wlen; + break; + } j = 1; if (wlen) { message->plan = buffer[pos++]; @@ -634,11 +734,14 @@ } for(i=0; i < wlen-j; i++) message->oad[i] = buffer[pos++]; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: OAD=(0x%02x,0x%02x) %s\n", chan->No, - message->plan, message->screen, message->oad); + eicon_log(ccard, 2, "idi_inf: Ch%d: OAD=(0x%02x,0x%02x) %s\n", chan->No, + message->plan, message->screen, message->oad); break; case RDN: + if (wlen > sizeof(message->rdn)) { + pos += wlen; + break; + } j = 1; if (wlen) { if (!(buffer[pos++] & 0x80)) { @@ -648,92 +751,116 @@ } for(i=0; i < wlen-j; i++) message->rdn[i] = buffer[pos++]; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: RDN= %s\n", chan->No, + eicon_log(ccard, 2, "idi_inf: Ch%d: RDN= %s\n", chan->No, message->rdn); break; case CPN: + if (wlen > sizeof(message->cpn)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->cpn[i] = buffer[pos++]; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: CPN=(0x%02x) %s\n", chan->No, - (__u8)message->cpn[0], message->cpn + 1); + eicon_log(ccard, 2, "idi_inf: Ch%d: CPN=(0x%02x) %s\n", chan->No, + (__u8)message->cpn[0], message->cpn + 1); break; case DSA: - pos++; - for(i=0; i < wlen-1; i++) + if (wlen > sizeof(message->dsa)) { + pos += wlen; + break; + } + pos += 2; + for(i=0; i < wlen-2; i++) message->dsa[i] = buffer[pos++]; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: DSA=%s\n", chan->No, message->dsa); + eicon_log(ccard, 2, "idi_inf: Ch%d: DSA=%s\n", chan->No, message->dsa); break; case OSA: - pos++; - for(i=0; i < wlen-1; i++) + if (wlen > sizeof(message->osa)) { + pos += wlen; + break; + } + pos += 2; + for(i=0; i < wlen-2; i++) message->osa[i] = buffer[pos++]; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa); + eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa); break; case BC: + if (wlen > sizeof(message->bc)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->bc[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: BC = 0x%02x 0x%02x 0x%02x\n", chan->No, - message->bc[0],message->bc[1],message->bc[2]); + eicon_log(ccard, 4, "idi_inf: Ch%d: BC = 0x%02x 0x%02x 0x%02x\n", chan->No, + message->bc[0],message->bc[1],message->bc[2]); break; case 0x800|BC: + if (wlen > sizeof(message->e_bc)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->e_bc[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: ESC/BC=%d\n", chan->No, message->bc[0]); + eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/BC=%d\n", chan->No, message->bc[0]); break; case LLC: + if (wlen > sizeof(message->llc)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->llc[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: LLC=%d %d %d %d\n", chan->No, message->llc[0], - message->llc[1],message->llc[2],message->llc[3]); + eicon_log(ccard, 4, "idi_inf: Ch%d: LLC=%d %d %d %d\n", chan->No, message->llc[0], + message->llc[1],message->llc[2],message->llc[3]); break; case HLC: + if (wlen > sizeof(message->hlc)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->hlc[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: HLC=%x %x %x %x %x\n", chan->No, - message->hlc[0], message->hlc[1], - message->hlc[2], message->hlc[3], message->hlc[4]); + eicon_log(ccard, 4, "idi_inf: Ch%d: HLC=%x %x %x %x %x\n", chan->No, + message->hlc[0], message->hlc[1], + message->hlc[2], message->hlc[3], message->hlc[4]); break; case DSP: case 0x600|DSP: + if (wlen > sizeof(message->display)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->display[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: Display: %s\n", chan->No, - message->display); + eicon_log(ccard, 4, "idi_inf: Ch%d: Display: %s\n", chan->No, + message->display); break; case 0x600|KEY: + if (wlen > sizeof(message->keypad)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->keypad[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: Keypad: %s\n", chan->No, - message->keypad); + eicon_log(ccard, 4, "idi_inf: Ch%d: Keypad: %s\n", chan->No, + message->keypad); break; case NI: case 0x600|NI: if (wlen) { - if (DebugVar & 4) { - switch(buffer[pos] & 127) { - case 0: - printk(KERN_DEBUG"idi_inf: Ch%d: User suspended.\n", chan->No); - break; - case 1: - printk(KERN_DEBUG"idi_inf: Ch%d: User resumed.\n", chan->No); - break; - case 2: - printk(KERN_DEBUG"idi_inf: Ch%d: Bearer service change.\n", chan->No); - break; - default: - printk(KERN_DEBUG"idi_inf: Ch%d: Unknown Notification %x.\n", - chan->No, buffer[pos] & 127); - } + switch(buffer[pos] & 127) { + case 0: + eicon_log(ccard, 4, "idi_inf: Ch%d: User suspended.\n", chan->No); + break; + case 1: + eicon_log(ccard, 4, "idi_inf: Ch%d: User resumed.\n", chan->No); + break; + case 2: + eicon_log(ccard, 4, "idi_inf: Ch%d: Bearer service change.\n", chan->No); + break; + default: + eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Notification %x.\n", + chan->No, buffer[pos] & 127); } pos += wlen; } @@ -741,80 +868,91 @@ case PI: case 0x600|PI: if (wlen > 1) { - if (DebugVar & 4) { - switch(buffer[pos+1] & 127) { - case 1: - printk(KERN_DEBUG"idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No); - break; - case 2: - printk(KERN_DEBUG"idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No); - break; - case 3: - printk(KERN_DEBUG"idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No); - break; - case 4: - printk(KERN_DEBUG"idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No); - break; - case 5: - printk(KERN_DEBUG"idi_inf: Ch%d: Interworking has occurred.\n", chan->No); - break; - case 8: - printk(KERN_DEBUG"idi_inf: Ch%d: In-band information available.\n", chan->No); - break; - default: - printk(KERN_DEBUG"idi_inf: Ch%d: Unknown Progress %x.\n", - chan->No, buffer[pos+1] & 127); - } + switch(buffer[pos+1] & 127) { + case 1: + eicon_log(ccard, 4, "idi_inf: Ch%d: Call is not end-to-end ISDN.\n", chan->No); + break; + case 2: + eicon_log(ccard, 4, "idi_inf: Ch%d: Destination address is non ISDN.\n", chan->No); + break; + case 3: + eicon_log(ccard, 4, "idi_inf: Ch%d: Origination address is non ISDN.\n", chan->No); + break; + case 4: + eicon_log(ccard, 4, "idi_inf: Ch%d: Call has returned to the ISDN.\n", chan->No); + break; + case 5: + eicon_log(ccard, 4, "idi_inf: Ch%d: Interworking has occurred.\n", chan->No); + break; + case 8: + eicon_log(ccard, 4, "idi_inf: Ch%d: In-band information available.\n", chan->No); + break; + default: + eicon_log(ccard, 4, "idi_inf: Ch%d: Unknown Progress %x.\n", + chan->No, buffer[pos+1] & 127); } } pos += wlen; break; case CAU: + if (wlen > sizeof(message->cau)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->cau[i] = buffer[pos++]; memcpy(&chan->cause, &message->cau, 2); - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: CAU=%d %d\n", chan->No, - message->cau[0],message->cau[1]); + eicon_log(ccard, 4, "idi_inf: Ch%d: CAU=%d %d\n", chan->No, + message->cau[0],message->cau[1]); break; case 0x800|CAU: + if (wlen > sizeof(message->e_cau)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->e_cau[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: ECAU=%d %d\n", chan->No, - message->e_cau[0],message->e_cau[1]); + eicon_log(ccard, 4, "idi_inf: Ch%d: ECAU=%d %d\n", chan->No, + message->e_cau[0],message->e_cau[1]); break; case 0x800|CHI: + if (wlen > sizeof(message->e_chi)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->e_chi[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: ESC/CHI=%d\n", chan->No, - message->e_cau[0]); + eicon_log(ccard, 4, "idi_inf: Ch%d: ESC/CHI=%d\n", chan->No, + message->e_cau[0]); break; case 0x800|0x7a: pos ++; message->e_mt=buffer[pos++]; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt); + eicon_log(ccard, 4, "idi_inf: Ch%d: EMT=0x%x\n", chan->No, message->e_mt); break; case DT: + if (wlen > sizeof(message->dt)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->dt[i] = buffer[pos++]; - if (DebugVar & 4) - printk(KERN_DEBUG"idi_inf: Ch%d: DT: %02d.%02d.%02d %02d:%02d:%02d\n", chan->No, - message->dt[2], message->dt[1], message->dt[0], - message->dt[3], message->dt[4], message->dt[5]); + eicon_log(ccard, 4, "idi_inf: Ch%d: DT: %02d.%02d.%02d %02d:%02d:%02d\n", chan->No, + message->dt[2], message->dt[1], message->dt[0], + message->dt[3], message->dt[4], message->dt[5]); break; case 0x600|SIN: + if (wlen > sizeof(message->sin)) { + pos += wlen; + break; + } for(i=0; i < wlen; i++) message->sin[i] = buffer[pos++]; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: SIN=%d %d\n", chan->No, - message->sin[0],message->sin[1]); + eicon_log(ccard, 2, "idi_inf: Ch%d: SIN=%d %d\n", chan->No, + message->sin[0],message->sin[1]); break; case 0x600|CPS: - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: Called Party Status in ind\n", chan->No); + eicon_log(ccard, 2, "idi_inf: Ch%d: Called Party Status in ind\n", chan->No); pos += wlen; break; case 0x600|CIF: @@ -822,8 +960,7 @@ if (buffer[pos + i] != '0') break; memcpy(&cmd.parm.num, &buffer[pos + i], wlen - i); cmd.parm.num[wlen - i] = 0; - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: CIF=%s\n", chan->No, cmd.parm.num); + eicon_log(ccard, 2, "idi_inf: Ch%d: CIF=%s\n", chan->No, cmd.parm.num); pos += wlen; cmd.driver = ccard->myid; cmd.command = ISDN_STAT_CINF; @@ -831,8 +968,11 @@ ccard->interface.statcallb(&cmd); break; case 0x600|DATE: - if (DebugVar & 2) - printk(KERN_DEBUG"idi_inf: Ch%d: Date in ind\n", chan->No); + eicon_log(ccard, 2, "idi_inf: Ch%d: Date in ind\n", chan->No); + pos += wlen; + break; + case 0xa1: + eicon_log(ccard, 2, "idi_inf: Ch%d: Sending Complete in ind.\n", chan->No); pos += wlen; break; case 0xe08: @@ -852,8 +992,7 @@ case 0x880: /* Managment Information Element */ if (!manbuf) { - if (DebugVar & 1) - printk(KERN_WARNING"idi_err: manbuf not allocated\n"); + eicon_log(ccard, 1, "idi_err: manbuf not allocated\n"); } else { memcpy(&manbuf->data[manbuf->pos], &buffer[pos], wlen); @@ -865,9 +1004,8 @@ break; default: pos += wlen; - if (DebugVar & 6) - printk(KERN_WARNING"idi_inf: Ch%d: unknown information element 0x%x in ind, len:%x\n", - chan->No, code, wlen); + eicon_log(ccard, 6, "idi_inf: Ch%d: unknown information element 0x%x in ind, len:%x\n", + chan->No, code, wlen); } } } @@ -908,110 +1046,1095 @@ int idi_fill_in_T30(eicon_chan *chan, unsigned char *buffer) { + eicon_t30_s *t30 = (eicon_t30_s *) buffer; - /* TODO , code follows */ + if (!chan->fax) { + eicon_log(NULL, 1,"idi_T30: fill_in with NULL fax struct, ERROR\n"); + return 0; + } + memset(t30, 0, sizeof(eicon_t30_s)); + t30->station_id_len = EICON_FAXID_LEN; + memcpy(&t30->station_id[0], &chan->fax->id[0], EICON_FAXID_LEN); + t30->resolution = chan->fax->resolution; + t30->rate = chan->fax->rate + 1; /* eicon rate starts with 1 */ + t30->format = T30_FORMAT_SFF; + t30->pages_low = 0; + t30->pages_high = 0; + t30->atf = 1; /* optimised for AT+F command set */ + t30->code = 0; + t30->feature_bits_low = 0; + t30->feature_bits_high = 0; + t30->control_bits_low = 0; + t30->control_bits_high = 0; + + if (chan->fax->nbc) { + /* set compression by DCC value */ + switch(chan->fax->compression) { + case (0): /* 1-D modified */ + break; + case (1): /* 2-D modified Read */ + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; + t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; + break; + case (2): /* 2-D uncompressed */ + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR; + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; + t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED; + t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; + break; + case (3): /* 2-D modified Read */ + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING; + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR; + t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED; + t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING; + t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; + t30->feature_bits_low |= T30_FEATURE_BIT_ECM; + break; + } + } else { + /* set compression to best */ + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_T6_CODING; + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_2D_CODING; + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_UNCOMPR; + t30->feature_bits_low |= T30_FEATURE_BIT_UNCOMPR_ENABLED; + t30->feature_bits_low |= T30_FEATURE_BIT_T6_CODING; + t30->feature_bits_low |= T30_FEATURE_BIT_2D_CODING; + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; + t30->feature_bits_low |= T30_FEATURE_BIT_ECM; + } + switch(chan->fax->ecm) { + case (0): /* disable ECM */ + break; + case (1): + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; + t30->control_bits_low |= T30_CONTROL_BIT_ECM_64_BYTES; + t30->feature_bits_low |= T30_FEATURE_BIT_ECM; + t30->feature_bits_low |= T30_FEATURE_BIT_ECM_64_BYTES; + break; + case (2): + t30->control_bits_low |= T30_CONTROL_BIT_ENABLE_ECM; + t30->feature_bits_low |= T30_FEATURE_BIT_ECM; + break; + } - return(0); + if (DebugVar & 128) { + char st[40]; + eicon_log(NULL, 128, "sT30:code = %x\n", t30->code); + eicon_log(NULL, 128, "sT30:rate = %x\n", t30->rate); + eicon_log(NULL, 128, "sT30:res = %x\n", t30->resolution); + eicon_log(NULL, 128, "sT30:format = %x\n", t30->format); + eicon_log(NULL, 128, "sT30:pages_low = %x\n", t30->pages_low); + eicon_log(NULL, 128, "sT30:pages_high = %x\n", t30->pages_high); + eicon_log(NULL, 128, "sT30:atf = %x\n", t30->atf); + eicon_log(NULL, 128, "sT30:control_bits_low = %x\n", t30->control_bits_low); + eicon_log(NULL, 128, "sT30:control_bits_high = %x\n", t30->control_bits_high); + eicon_log(NULL, 128, "sT30:feature_bits_low = %x\n", t30->feature_bits_low); + eicon_log(NULL, 128, "sT30:feature_bits_high = %x\n", t30->feature_bits_high); + //eicon_log(NULL, 128, "sT30:universal_5 = %x\n", t30->universal_5); + //eicon_log(NULL, 128, "sT30:universal_6 = %x\n", t30->universal_6); + //eicon_log(NULL, 128, "sT30:universal_7 = %x\n", t30->universal_7); + eicon_log(NULL, 128, "sT30:station_id_len = %x\n", t30->station_id_len); + eicon_log(NULL, 128, "sT30:head_line_len = %x\n", t30->head_line_len); + strncpy(st, t30->station_id, t30->station_id_len); + st[t30->station_id_len] = 0; + eicon_log(NULL, 128, "sT30:station_id = <%s>\n", st); + } + return(sizeof(eicon_t30_s)); } /* send fax struct */ int idi_send_edata(eicon_card *card, eicon_chan *chan) { + struct sk_buff *skb; + struct sk_buff *skb2; + eicon_REQ *reqbuf; + eicon_chan_ptr *chan2; + + if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) { + eicon_log(card, 1, "idi_snd: Ch%d: send edata on state %d !\n", chan->No, chan->fsm_state); + return -ENODEV; + } + eicon_log(card, 128, "idi_snd: Ch%d: edata (fax)\n", chan->No); - /* TODO , code follows */ + skb = alloc_skb(sizeof(eicon_REQ) + sizeof(eicon_t30_s), GFP_ATOMIC); + skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); + if ((!skb) || (!skb2)) { + eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_edata()\n", chan->No); + if (skb) + dev_kfree_skb(skb); + if (skb2) + dev_kfree_skb(skb2); + return -ENOMEM; + } + + chan2 = (eicon_chan_ptr *)skb_put(skb2, sizeof(eicon_chan_ptr)); + chan2->ptr = chan; + + reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ)); + + reqbuf->Req = IDI_N_EDATA; + reqbuf->ReqCh = 0; + reqbuf->ReqId = 1; + + reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P); + reqbuf->Reference = 1; /* Net Entity */ + + skb_queue_tail(&chan->e.X, skb); + skb_queue_tail(&card->sndq, skb2); + eicon_schedule_tx(card); return (0); } void idi_parse_edata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int len) { + eicon_t30_s *p = (eicon_t30_s *)buffer; + int i; - /* TODO , code follows */ + if (DebugVar & 128) { + char st[40]; + eicon_log(ccard, 128, "rT30:len %d , size %d\n", len, sizeof(eicon_t30_s)); + eicon_log(ccard, 128, "rT30:code = %x\n", p->code); + eicon_log(ccard, 128, "rT30:rate = %x\n", p->rate); + eicon_log(ccard, 128, "rT30:res = %x\n", p->resolution); + eicon_log(ccard, 128, "rT30:format = %x\n", p->format); + eicon_log(ccard, 128, "rT30:pages_low = %x\n", p->pages_low); + eicon_log(ccard, 128, "rT30:pages_high = %x\n", p->pages_high); + eicon_log(ccard, 128, "rT30:atf = %x\n", p->atf); + eicon_log(ccard, 128, "rT30:control_bits_low = %x\n", p->control_bits_low); + eicon_log(ccard, 128, "rT30:control_bits_high = %x\n", p->control_bits_high); + eicon_log(ccard, 128, "rT30:feature_bits_low = %x\n", p->feature_bits_low); + eicon_log(ccard, 128, "rT30:feature_bits_high = %x\n", p->feature_bits_high); + //eicon_log(ccard, 128, "rT30:universal_5 = %x\n", p->universal_5); + //eicon_log(ccard, 128, "rT30:universal_6 = %x\n", p->universal_6); + //eicon_log(ccard, 128, "rT30:universal_7 = %x\n", p->universal_7); + eicon_log(ccard, 128, "rT30:station_id_len = %x\n", p->station_id_len); + eicon_log(ccard, 128, "rT30:head_line_len = %x\n", p->head_line_len); + strncpy(st, p->station_id, p->station_id_len); + st[p->station_id_len] = 0; + eicon_log(ccard, 128, "rT30:station_id = <%s>\n", st); + } + if (!chan->fax) { + eicon_log(ccard, 1, "idi_edata: parse to NULL fax struct, ERROR\n"); + return; + } + chan->fax->code = p->code; + i = (p->station_id_len < FAXIDLEN) ? p->station_id_len : (FAXIDLEN - 1); + memcpy(chan->fax->r_id, p->station_id, i); + chan->fax->r_id[i] = 0; + chan->fax->r_resolution = p->resolution; + chan->fax->r_rate = p->rate - 1; + chan->fax->r_binary = 0; /* no binary support */ + chan->fax->r_width = 0; + chan->fax->r_length = 2; + chan->fax->r_scantime = 0; + chan->fax->r_compression = 0; + chan->fax->r_ecm = 0; + if (p->feature_bits_low & T30_FEATURE_BIT_2D_CODING) { + chan->fax->r_compression = 1; + if (p->feature_bits_low & T30_FEATURE_BIT_UNCOMPR_ENABLED) { + chan->fax->r_compression = 2; + } + } + if (p->feature_bits_low & T30_FEATURE_BIT_T6_CODING) { + chan->fax->r_compression = 3; + } + if (p->feature_bits_low & T30_FEATURE_BIT_ECM) { + chan->fax->r_ecm = 2; + if (p->feature_bits_low & T30_FEATURE_BIT_ECM_64_BYTES) + chan->fax->r_ecm = 1; + } } void idi_fax_send_header(eicon_card *card, eicon_chan *chan, int header) { + static __u16 wd2sff[] = { + 1728, 2048, 2432, 1216, 864 + }; + static __u16 ln2sff[2][3] = { + { 1143, 1401, 0 } , { 2287, 2802, 0 } + }; + struct sk_buff *skb; + eicon_sff_dochead *doc; + eicon_sff_pagehead *page; + u_char *docp; - /* TODO , code follows */ + if (!chan->fax) { + eicon_log(card, 1, "idi_fax: send head with NULL fax struct, ERROR\n"); + return; + } + if (header == 2) { /* DocHeader + PageHeader */ + skb = alloc_skb(sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead), GFP_ATOMIC); + } else { + skb = alloc_skb(sizeof(eicon_sff_pagehead), GFP_ATOMIC); + } + if (!skb) { + eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_header()\n", chan->No); + return; + } + if (header == 2) { /* DocHeader + PageHeader */ + docp = skb_put(skb, sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead)); + doc = (eicon_sff_dochead *) docp; + page = (eicon_sff_pagehead *) (docp + sizeof(eicon_sff_dochead)); + memset(docp, 0,sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead)); + doc->id = 0x66666653; + doc->version = 0x01; + doc->off1pagehead = sizeof(eicon_sff_dochead); + } else { + page = (eicon_sff_pagehead *)skb_put(skb, sizeof(eicon_sff_pagehead)); + memset(page, 0, sizeof(eicon_sff_pagehead)); + } + + switch(header) { + case 1: /* PageHeaderEnd */ + page->pageheadid = 254; + page->pageheadlen = 0; + break; + case 0: /* PageHeader */ + case 2: /* DocHeader + PageHeader */ + page->pageheadid = 254; + page->pageheadlen = sizeof(eicon_sff_pagehead) - 2; + page->resvert = chan->fax->resolution; + page->reshoriz = 0; /* always 203 dpi */ + page->coding = 0; /* always 1D */ + page->linelength = wd2sff[chan->fax->width]; + page->pagelength = ln2sff[chan->fax->resolution][chan->fax->length]; + eicon_log(card, 128, "sSFF-Head: linelength = %d\n", page->linelength); + eicon_log(card, 128, "sSFF-Head: pagelength = %d\n", page->pagelength); + break; + } + idi_send_data(card, chan, 0, skb, 0); } void idi_fax_cmd(eicon_card *card, eicon_chan *chan) { + isdn_ctrl cmd; + + if ((!card) || (!chan)) + return; - /* TODO , code follows */ + if (!chan->fax) { + eicon_log(card, 1, "idi_fax: cmd with NULL fax struct, ERROR\n"); + return; + } + switch (chan->fax->code) { + case ISDN_TTY_FAX_DT: + if (chan->fax->phase == ISDN_FAX_PHASE_B) { + idi_send_edata(card, chan); + break; + } + if (chan->fax->phase == ISDN_FAX_PHASE_D) { + idi_send_edata(card, chan); + break; + } + break; + + case ISDN_TTY_FAX_DR: + if (chan->fax->phase == ISDN_FAX_PHASE_B) { + idi_send_edata(card, chan); + + cmd.driver = card->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_CFR; + card->interface.statcallb(&cmd); + + cmd.driver = card->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_RID; + card->interface.statcallb(&cmd); + + /* telling 1-D compression */ + chan->fax->r_compression = 0; + cmd.driver = card->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_DCS; + card->interface.statcallb(&cmd); + chan->fax2.NextObject = FAX_OBJECT_DOCU; + chan->fax2.PrevObject = FAX_OBJECT_DOCU; + + break; + } + if (chan->fax->phase == ISDN_FAX_PHASE_D) { + idi_send_edata(card, chan); + break; + } + break; + + case ISDN_TTY_FAX_ET: + switch(chan->fax->fet) { + case 0: + case 1: + idi_fax_send_header(card, chan, 0); + break; + case 2: + idi_fax_send_header(card, chan, 1); + break; + } + break; + } } void idi_edata_rcveop(eicon_card *card, eicon_chan *chan) { + isdn_ctrl cmd; - /* TODO , code follows */ - + if (!chan->fax) { + eicon_log(card, 1, "idi_edata: rcveop with NULL fax struct, ERROR\n"); + return; + } + cmd.driver = card->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_ET; + card->interface.statcallb(&cmd); } void idi_reset_fax_stat(eicon_chan *chan) { - - /* TODO , code follows */ - + chan->fax2.LineLen = 0; + chan->fax2.LineData = 0; + chan->fax2.LineDataLen = 0; + chan->fax2.NullByteExist = 0; + chan->fax2.Dle = 0; + chan->fax2.PageCount = 0; + chan->fax2.Eop = 0; } void idi_edata_action(eicon_card *ccard, eicon_chan *chan, char *buffer, int len) { + isdn_ctrl cmd; + + if (!chan->fax) { + eicon_log(ccard, 1, "idi_edata: action with NULL fax struct, ERROR\n"); + return; + } + if (chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) { + idi_parse_edata(ccard, chan, buffer, len); + + if (chan->fax->phase == ISDN_FAX_PHASE_A) { + idi_reset_fax_stat(chan); + + chan->fsm_state = EICON_STATE_ACTIVE; + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_BCONN; + cmd.arg = chan->No; + ccard->interface.statcallb(&cmd); + + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_FCON; + ccard->interface.statcallb(&cmd); + + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_RID; + ccard->interface.statcallb(&cmd); + + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_DIS; + ccard->interface.statcallb(&cmd); + + if (chan->fax->r_compression != 0) { + /* telling fake compression in second DIS message */ + chan->fax->r_compression = 0; + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_DIS; + ccard->interface.statcallb(&cmd); + } + + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_SENT; /* OK message */ + ccard->interface.statcallb(&cmd); + } else + if (chan->fax->phase == ISDN_FAX_PHASE_D) { - /* TODO , code follows */ + if ((chan->fax->code == EDATA_T30_MCF) && + (chan->fax->fet != 2)) { + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_PTS; + ccard->interface.statcallb(&cmd); + } + + switch(chan->fax->fet) { + case 0: /* new page */ + /* stay in phase D , wait on cmd +FDT */ + break; + case 1: /* new document */ + /* link-level switch to phase B */ + break; + case 2: /* session end */ + default: + /* idi_send_edata(ccard, chan); */ + break; + } + } + } + + if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) { + idi_parse_edata(ccard, chan, buffer, len); + + if ((chan->fax->code == EDATA_T30_DCS) && + (chan->fax->phase == ISDN_FAX_PHASE_A)) { + idi_reset_fax_stat(chan); + + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_BCONN; + cmd.arg = chan->No; + ccard->interface.statcallb(&cmd); + + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_FCON_I; + ccard->interface.statcallb(&cmd); + } else + if ((chan->fax->code == EDATA_T30_TRAIN_OK) && + (chan->fax->phase == ISDN_FAX_PHASE_A)) { + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_RID; + ccard->interface.statcallb(&cmd); + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK; + ccard->interface.statcallb(&cmd); + } else + if ((chan->fax->code == EDATA_T30_TRAIN_OK) && + (chan->fax->phase == ISDN_FAX_PHASE_B)) { + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_TRAIN_OK; + ccard->interface.statcallb(&cmd); + } else + if (chan->fax->phase == ISDN_FAX_PHASE_C) { + switch(chan->fax->code) { + case EDATA_T30_TRAIN_OK: + idi_send_edata(ccard, chan); + break; + case EDATA_T30_MPS: + chan->fax->fet = 0; + idi_edata_rcveop(ccard, chan); + break; + case EDATA_T30_EOM: + chan->fax->fet = 1; + idi_edata_rcveop(ccard, chan); + break; + case EDATA_T30_EOP: + chan->fax->fet = 2; + idi_edata_rcveop(ccard, chan); + break; + } + } + } } void fax_put_rcv(eicon_card *ccard, eicon_chan *chan, u_char *Data, int len) { - - /* TODO , code follows */ - + struct sk_buff *skb; + + skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC); + if (!skb) { + eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_put_rcv()\n", chan->No); + return; + } + skb_reserve(skb, MAX_HEADER_LEN); + memcpy(skb_put(skb, len), Data, len); + ccard->interface.rcvcallb_skb(ccard->myid, chan->No, skb); } void idi_faxdata_rcv(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb) { + eicon_OBJBUFFER InBuf; + eicon_OBJBUFFER LineBuf; + unsigned int Length = 0; + unsigned int aLength = 0; + unsigned int ObjectSize = 0; + unsigned int ObjHeadLen = 0; + unsigned int ObjDataLen = 0; + __u8 Recordtype; + __u8 PageHeaderLen; + __u8 Event; + eicon_sff_pagehead *ob_page; + + __u16 Cl2Eol = 0x8000; + +# define EVENT_NONE 0 +# define EVENT_NEEDDATA 1 + + if (!chan->fax) { + eicon_log(ccard, 1, "idi_fax: rcvdata with NULL fax struct, ERROR\n"); + return; + } + + + + if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) { + InBuf.Data = skb->data; + InBuf.Size = skb->len; + InBuf.Len = 0; + InBuf.Next = InBuf.Data; + LineBuf.Data = chan->fax2.abLine; + LineBuf.Size = sizeof(chan->fax2.abLine); + LineBuf.Len = chan->fax2.LineLen; + LineBuf.Next = LineBuf.Data + LineBuf.Len; + + Event = EVENT_NONE; + while (Event == EVENT_NONE) { + switch(chan->fax2.NextObject) { + case FAX_OBJECT_DOCU: + Length = LineBuf.Len + (InBuf.Size - InBuf.Len); + if (Length < sizeof(eicon_sff_dochead)) { + Event = EVENT_NEEDDATA; + break; + } + ObjectSize = sizeof(eicon_sff_dochead); + Length = ObjectSize; + if (LineBuf.Len < Length) { + Length -= LineBuf.Len; + LineBuf.Len = 0; + LineBuf.Next = LineBuf.Data; + InBuf.Len += Length; + InBuf.Next += Length; + } else { + LineBuf.Len -= Length; + LineBuf.Next = LineBuf.Data + LineBuf.Len; + memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len); + } + chan->fax2.PrevObject = FAX_OBJECT_DOCU; + chan->fax2.NextObject = FAX_OBJECT_PAGE; + break; + + case FAX_OBJECT_PAGE: + Length = LineBuf.Len + (InBuf.Size - InBuf.Len); + if (Length < 2) { + Event = EVENT_NEEDDATA; + break; + } + if (LineBuf.Len == 0) { + *LineBuf.Next++ = *InBuf.Next++; + LineBuf.Len++; + InBuf.Len++; + } + if (LineBuf.Len == 1) { + *LineBuf.Next++ = *InBuf.Next++; + LineBuf.Len++; + InBuf.Len++; + } + PageHeaderLen = *(LineBuf.Data + 1); + ObjectSize = (PageHeaderLen == 0) ? 2 : sizeof(eicon_sff_pagehead); + if (Length < ObjectSize) { + Event = EVENT_NEEDDATA; + break; + } + Length = ObjectSize; + /* extract page dimensions */ + if (LineBuf.Len < Length) { + aLength = Length - LineBuf.Len; + memcpy(LineBuf.Next, InBuf.Next, aLength); + LineBuf.Next += aLength; + InBuf.Next += aLength; + LineBuf.Len += aLength; + InBuf.Len += aLength; + } + if (Length > 2) { + ob_page = (eicon_sff_pagehead *)LineBuf.Data; + switch(ob_page->linelength) { + case 2048: + chan->fax->r_width = 1; + break; + case 2432: + chan->fax->r_width = 2; + break; + case 1216: + chan->fax->r_width = 3; + break; + case 864: + chan->fax->r_width = 4; + break; + case 1728: + default: + chan->fax->r_width = 0; + } + switch(ob_page->pagelength) { + case 1143: + case 2287: + chan->fax->r_length = 0; + break; + case 1401: + case 2802: + chan->fax->r_length = 1; + break; + default: + chan->fax->r_length = 2; + } + eicon_log(ccard, 128, "rSFF-Head: linelength = %d\n", ob_page->linelength); + eicon_log(ccard, 128, "rSFF-Head: pagelength = %d\n", ob_page->pagelength); + } + LineBuf.Len -= Length; + LineBuf.Next = LineBuf.Data + LineBuf.Len; + memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len); + + chan->fax2.PrevObject = FAX_OBJECT_PAGE; + chan->fax2.NextObject = FAX_OBJECT_LINE; + break; + + case FAX_OBJECT_LINE: + Length = LineBuf.Len + (InBuf.Size - InBuf.Len); + if (Length < 1) { + Event = EVENT_NEEDDATA; + break; + } + if (LineBuf.Len == 0) { + *LineBuf.Next++ = *InBuf.Next++; + LineBuf.Len++; + InBuf.Len++; + } + Recordtype = *LineBuf.Data; + if (Recordtype == 0) { + /* recordtype pixel row (2 byte length) */ + ObjHeadLen = 3; + if (Length < ObjHeadLen) { + Event = EVENT_NEEDDATA; + break; + } + while (LineBuf.Len < ObjHeadLen) { + *LineBuf.Next++ = *InBuf.Next++; + LineBuf.Len++; + InBuf.Len++; + } + ObjDataLen = *((__u16*) (LineBuf.Data + 1)); + ObjectSize = ObjHeadLen + ObjDataLen; + if (Length < ObjectSize) { + Event = EVENT_NEEDDATA; + break; + } + } else + if ((Recordtype >= 1) && (Recordtype <= 216)) { + /* recordtype pixel row (1 byte length) */ + ObjHeadLen = 1; + ObjDataLen = Recordtype; + ObjectSize = ObjHeadLen + ObjDataLen; + if (Length < ObjectSize) { + Event = EVENT_NEEDDATA; + break; + } + } else + if ((Recordtype >= 217) && (Recordtype <= 253)) { + /* recordtype empty lines */ + ObjHeadLen = 1; + ObjDataLen = 0; + ObjectSize = ObjHeadLen + ObjDataLen; + LineBuf.Len--; + LineBuf.Next = LineBuf.Data + LineBuf.Len; + memmove(LineBuf.Data, LineBuf.Data + 1, LineBuf.Len); + break; + } else + if (Recordtype == 254) { + /* recordtype page header */ + chan->fax2.PrevObject = FAX_OBJECT_LINE; + chan->fax2.NextObject = FAX_OBJECT_PAGE; + break; + } else { + /* recordtype user information */ + ObjHeadLen = 2; + if (Length < ObjHeadLen) { + Event = EVENT_NEEDDATA; + break; + } + while (LineBuf.Len < ObjHeadLen) { + *LineBuf.Next++ = *InBuf.Next++; + LineBuf.Len++; + InBuf.Len++; + } + ObjDataLen = *(LineBuf.Data + 1); + ObjectSize = ObjHeadLen + ObjDataLen; + if (ObjDataLen == 0) { + /* illegal line coding */ + LineBuf.Len -= ObjHeadLen; + LineBuf.Next = LineBuf.Data + LineBuf.Len; + memmove(LineBuf.Data, LineBuf.Data + ObjHeadLen, LineBuf.Len); + break; + } else { + /* user information */ + if (Length < ObjectSize) { + Event = EVENT_NEEDDATA; + break; + } + Length = ObjectSize; + if (LineBuf.Len < Length) { + Length -= LineBuf.Len; + LineBuf.Len = 0; + LineBuf.Next = LineBuf.Data; + InBuf.Len += Length; + InBuf.Next += Length; + } else { + LineBuf.Len -= Length; + LineBuf.Next = LineBuf.Data + LineBuf.Len; + memmove(LineBuf.Data, LineBuf.Data + Length, LineBuf.Len); + } + } + break; + } + Length = ObjectSize; + if (LineBuf.Len > ObjHeadLen) { + fax_put_rcv(ccard, chan, LineBuf.Data + ObjHeadLen, + (LineBuf.Len - ObjHeadLen)); + } + Length -= LineBuf.Len; + LineBuf.Len = 0; + LineBuf.Next = LineBuf.Data; + if (Length > 0) { + fax_put_rcv(ccard, chan, InBuf.Next, Length); + InBuf.Len += Length; + InBuf.Next += Length; + } + fax_put_rcv(ccard, chan, (__u8 *)&Cl2Eol, sizeof(Cl2Eol)); + break; + } /* end of switch (chan->fax2.NextObject) */ + } /* end of while (Event==EVENT_NONE) */ + if (InBuf.Len < InBuf.Size) { + Length = InBuf.Size - InBuf.Len; + if ((LineBuf.Len + Length) > LineBuf.Size) { + eicon_log(ccard, 1, "idi_fax: Ch%d: %d bytes dropping, small buffer\n", chan->No, + Length); + } else { + memcpy(LineBuf.Next, InBuf.Next, Length); + LineBuf.Len += Length; + } + } + chan->fax2.LineLen = LineBuf.Len; + } else { /* CONN_OUT */ + /* On CONN_OUT we do not need incoming data, drop it */ + /* maybe later for polling */ + } - /* TODO , code follows */ +# undef EVENT_NONE +# undef EVENT_NEEDDATA + return; } int idi_fax_send_outbuf(eicon_card *ccard, eicon_chan *chan, eicon_OBJBUFFER *OutBuf) { + struct sk_buff *skb; - /* TODO , code follows */ + skb = alloc_skb(OutBuf->Len, GFP_ATOMIC); + if (!skb) { + eicon_log(ccard, 1, "idi_err: Ch%d: alloc_skb failed in fax_send_outbuf()\n", chan->No); + return(-1); + } + memcpy(skb_put(skb, OutBuf->Len), OutBuf->Data, OutBuf->Len); - return(0); + OutBuf->Len = 0; + OutBuf->Next = OutBuf->Data; + + return(idi_send_data(ccard, chan, 0, skb, 1)); } int idi_faxdata_send(eicon_card *ccard, eicon_chan *chan, struct sk_buff *skb) { + isdn_ctrl cmd; + eicon_OBJBUFFER InBuf; + __u8 InData; + __u8 InMask; + eicon_OBJBUFFER OutBuf; + eicon_OBJBUFFER LineBuf; + __u32 LineData; + unsigned int LineDataLen; + __u8 Byte; + __u8 Event; + int ret = 1; + +# define EVENT_NONE 0 +# define EVENT_EOD 1 +# define EVENT_EOL 2 +# define EVENT_EOP 3 - /* TODO , code follows */ + if ((!ccard) || (!chan)) + return -1; - return(0); + if (!chan->fax) { + eicon_log(ccard, 1, "idi_fax: senddata with NULL fax struct, ERROR\n"); + return -1; + } + + if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) { + /* Simply ignore any data written in data mode when receiving a fax. */ + /* This is not completely correct because only XON's should come here. */ + dev_kfree_skb(skb); + return 1; + } + + if (chan->fax->phase != ISDN_FAX_PHASE_C) { + dev_kfree_skb(skb); + return 1; + } + + if (chan->queued + skb->len > 1200) + return 0; + + InBuf.Data = skb->data; + InBuf.Size = skb->len; + InBuf.Len = 0; + InBuf.Next = InBuf.Data; + InData = 0; + InMask = 0; + + LineBuf.Data = chan->fax2.abLine; + LineBuf.Size = sizeof(chan->fax2.abLine); + LineBuf.Len = chan->fax2.LineLen; + LineBuf.Next = LineBuf.Data + LineBuf.Len; + LineData = chan->fax2.LineData; + LineDataLen = chan->fax2.LineDataLen; + + OutBuf.Data = chan->fax2.abFrame; + OutBuf.Size = sizeof(chan->fax2.abFrame); + OutBuf.Len = 0; + OutBuf.Next = OutBuf.Data; + + Event = EVENT_NONE; + + chan->fax2.Eop = 0; + + for (;;) { + for (;;) { + if (InMask == 0) { + if (InBuf.Len >= InBuf.Size) { + Event = EVENT_EOD; + break; + } + if ((chan->fax2.Dle != _DLE_) && *InBuf.Next == _DLE_) { + chan->fax2.Dle = _DLE_; + InBuf.Next++; + InBuf.Len++; + if (InBuf.Len >= InBuf.Size) { + Event = EVENT_EOD; + break; + } + } + if (chan->fax2.Dle == _DLE_) { + chan->fax2.Dle = 0; + if (*InBuf.Next == _ETX_) { + Event = EVENT_EOP; + break; + } else + if (*InBuf.Next == _DLE_) { + /* do nothing */ + } else { + eicon_log(ccard, 1, + "idi_err: Ch%d: unknown DLE escape %02x found\n", + chan->No, *InBuf.Next); + InBuf.Next++; + InBuf.Len++; + if (InBuf.Len >= InBuf.Size) { + Event = EVENT_EOD; + break; + } + } + } + InBuf.Len++; + InData = *InBuf.Next++; + InMask = (chan->fax->bor) ? 0x80 : 0x01; + } + while (InMask) { + LineData >>= 1; + LineDataLen++; + if (InData & InMask) + LineData |= 0x80000000; + if (chan->fax->bor) + InMask >>= 1; + else + InMask <<= 1; + + if ((LineDataLen >= T4_EOL_BITSIZE) && + ((LineData & T4_EOL_MASK_DWORD) == T4_EOL_DWORD)) { + Event = EVENT_EOL; + if (LineDataLen > T4_EOL_BITSIZE) { + Byte = (__u8) + ((LineData & ~T4_EOL_MASK_DWORD) >> + (32 - LineDataLen)); + if (Byte == 0) { + if (! chan->fax2.NullByteExist) { + chan->fax2.NullBytesPos = LineBuf.Len; + chan->fax2.NullByteExist = 1; + } + } else { + chan->fax2.NullByteExist = 0; + } + if (LineBuf.Len < LineBuf.Size) { + *LineBuf.Next++ = Byte; + LineBuf.Len++; + } + } + LineDataLen = 0; + break; + } + if (LineDataLen >= T4_EOL_BITSIZE + 8) { + Byte = (__u8) + ((LineData & ~T4_EOL_MASK_DWORD) >> + (32 - T4_EOL_BITSIZE - 8)); + LineData &= T4_EOL_MASK_DWORD; + LineDataLen = T4_EOL_BITSIZE; + if (Byte == 0) { + if (! chan->fax2.NullByteExist) { + chan->fax2.NullBytesPos = LineBuf.Len; + chan->fax2.NullByteExist = 1; + } + } else { + chan->fax2.NullByteExist = 0; + } + if (LineBuf.Len < LineBuf.Size) { + *LineBuf.Next++ = Byte; + LineBuf.Len++; + } + } + } + if (Event != EVENT_NONE) + break; + } + + if ((Event != EVENT_EOL) && (Event != EVENT_EOP)) + break; + + if ((Event == EVENT_EOP) && (LineDataLen > 0)) { + LineData >>= 32 - LineDataLen; + LineDataLen = 0; + while (LineData != 0) { + Byte = (__u8) LineData; + LineData >>= 8; + if (Byte == 0) { + if (! chan->fax2.NullByteExist) { + chan->fax2.NullBytesPos = LineBuf.Len; + chan->fax2.NullByteExist = 1; + } + } else { + chan->fax2.NullByteExist = 0; + } + if (LineBuf.Len < LineBuf.Size) { + *LineBuf.Next++ = Byte; + LineBuf.Len++; + } + + } + } + if (chan->fax2.NullByteExist) { + if (chan->fax2.NullBytesPos == 0) { + LineBuf.Len = 0; + } else { + LineBuf.Len = chan->fax2.NullBytesPos + 1; + } + } + if (LineBuf.Len > 0) { + if (OutBuf.Len + LineBuf.Len + SFF_LEN_FLD_SIZE > OutBuf.Size) { + ret = idi_fax_send_outbuf(ccard, chan, &OutBuf); + } + if (LineBuf.Len <= 216) { + *OutBuf.Next++ = (__u8) LineBuf.Len; + OutBuf.Len++; + } else { + *OutBuf.Next++ = 0; + *((__u16 *) OutBuf.Next)++ = (__u16) LineBuf.Len; + OutBuf.Len += 3; + } + memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len); + OutBuf.Next += LineBuf.Len; + OutBuf.Len += LineBuf.Len; + } + LineBuf.Len = 0; + LineBuf.Next = LineBuf.Data; + chan->fax2.NullByteExist = 0; + if (Event == EVENT_EOP) + break; + + Event = EVENT_NONE; + } + + if (Event == EVENT_EOP) { + chan->fax2.Eop = 1; + chan->fax2.PageCount++; + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_EOP; + ccard->interface.statcallb(&cmd); + } + if (OutBuf.Len > 0) { + ret = idi_fax_send_outbuf(ccard, chan, &OutBuf); + } + + chan->fax2.LineLen = LineBuf.Len; + chan->fax2.LineData = LineData; + chan->fax2.LineDataLen = LineDataLen; + +# undef EVENT_NONE +# undef EVENT_EOD +# undef EVENT_EOL +# undef EVENT_EOP + + if (ret >= 0) + dev_kfree_skb(skb); + if (ret == 0) + ret = 1; + return(ret); } void idi_fax_hangup(eicon_card *ccard, eicon_chan *chan) { + isdn_ctrl cmd; - /* TODO , code follows */ - + if (!chan->fax) { + eicon_log(ccard, 1, "idi_fax: hangup with NULL fax struct, ERROR\n"); + return; + } + if ((chan->fax->direction == ISDN_TTY_FAX_CONN_OUT) && + (chan->fax->code == 0)) { + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + chan->fax->r_code = ISDN_TTY_FAX_PTS; + ccard->interface.statcallb(&cmd); + } + if ((chan->fax->code > 1) && (chan->fax->code < 120)) + chan->fax->code += 120; + chan->fax->r_code = ISDN_TTY_FAX_HNG; + cmd.driver = ccard->myid; + cmd.command = ISDN_STAT_FAXIND; + cmd.arg = chan->No; + ccard->interface.statcallb(&cmd); } #endif /******** FAX ********/ @@ -1025,20 +2148,17 @@ eicon_chan_ptr *chan2; if ((chan->fsm_state == EICON_STATE_NULL) || (chan->fsm_state == EICON_STATE_LISTEN)) { - if (DebugVar & 1) - printk(KERN_DEBUG"idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state); + eicon_log(card, 1, "idi_snd: Ch%d: send udata on state %d !\n", chan->No, chan->fsm_state); return -ENODEV; } - if (DebugVar & 8) - printk(KERN_DEBUG"idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No, - UReq, buffer[0], buffer[1], buffer[2], buffer[3]); + eicon_log(card, 8, "idi_snd: Ch%d: udata 0x%x: %d %d %d %d\n", chan->No, + UReq, buffer[0], buffer[1], buffer[2], buffer[3]); skb = alloc_skb(sizeof(eicon_REQ) + len + 1, GFP_ATOMIC); skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); if ((!skb) || (!skb2)) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No); + eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_udata()\n", chan->No); if (skb) dev_kfree_skb(skb); if (skb2) @@ -1072,6 +2192,9 @@ u_char buf[6]; struct enable_dtmf_s *dtmf_buf = (struct enable_dtmf_s *)buf; + if ((!ccard) || (!chan)) + return; + memset(buf, 0, 6); switch(cmd) { case ISDN_AUDIO_SETDD: @@ -1103,14 +2226,15 @@ '1','4','7','*','2','5','8','0','3','6','9','#','A','B','C','D' }; + if ((!ccard) || (!chan)) + return; + switch (buffer[0]) { case DSP_UDATA_INDICATION_SYNC: - if (DebugVar & 16) - printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_SYNC time %d\n", chan->No, p->time); + eicon_log(ccard, 16, "idi_ind: Ch%d: UDATA_SYNC time %d\n", chan->No, p->time); break; case DSP_UDATA_INDICATION_DCD_OFF: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_DCD_OFF time %d\n", chan->No, p->time); + eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_OFF time %d\n", chan->No, p->time); break; case DSP_UDATA_INDICATION_DCD_ON: if ((chan->l2prot == ISDN_PROTO_L2_MODEM) && @@ -1122,31 +2246,24 @@ sprintf(cmd.parm.num, "%d/%s", p->speed, connmsg[p->norm]); ccard->interface.statcallb(&cmd); } - if (DebugVar & 8) { - printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_DCD_ON time %d\n", chan->No, p->time); - printk(KERN_DEBUG"idi_ind: Ch%d: %d %d %d %d\n", chan->No, - p->norm, p->options, p->speed, p->delay); - } + eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DCD_ON time %d\n", chan->No, p->time); + eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No, + p->norm, p->options, p->speed, p->delay); break; case DSP_UDATA_INDICATION_CTS_OFF: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_CTS_OFF time %d\n", chan->No, p->time); + eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_OFF time %d\n", chan->No, p->time); break; case DSP_UDATA_INDICATION_CTS_ON: - if (DebugVar & 8) { - printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_CTS_ON time %d\n", chan->No, p->time); - printk(KERN_DEBUG"idi_ind: Ch%d: %d %d %d %d\n", chan->No, - p->norm, p->options, p->speed, p->delay); - } + eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_CTS_ON time %d\n", chan->No, p->time); + eicon_log(ccard, 8, "idi_ind: Ch%d: %d %d %d %d\n", chan->No, + p->norm, p->options, p->speed, p->delay); break; case DSP_UDATA_INDICATION_DISCONNECT: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]); + eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DISCONNECT cause %d\n", chan->No, buffer[1]); break; case DSP_UDATA_INDICATION_DTMF_DIGITS_RECEIVED: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No, - dtmf_code[buffer[1]]); + eicon_log(ccard, 8, "idi_ind: Ch%d: UDATA_DTMF_REC '%c'\n", chan->No, + dtmf_code[buffer[1]]); cmd.driver = ccard->myid; cmd.command = ISDN_STAT_AUDIO; cmd.parm.num[0] = ISDN_AUDIO_DTMF; @@ -1155,8 +2272,7 @@ ccard->interface.statcallb(&cmd); break; default: - if (DebugVar & 8) - printk(KERN_WARNING "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]); + eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED UDATA Indication 0x%02x\n", chan->No, buffer[0]); } } @@ -1164,23 +2280,35 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb) { int tmp; + char tnum[64]; + int dlev; int free_buff; + ulong flags; struct sk_buff *skb2; eicon_IND *ind = (eicon_IND *)skb->data; eicon_chan *chan; idi_ind_message message; isdn_ctrl cmd; + if (!ccard) { + eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ind\n"); + dev_kfree_skb(skb); + return; + } + if ((chan = ccard->IdTable[ind->IndId]) == NULL) { + eicon_log(ccard, 1, "idi_err: Ch??: null chan in handle_ind\n"); dev_kfree_skb(skb); return; } - if ((DebugVar & 128) || - ((DebugVar & 16) && (ind->Ind != 8))) { - printk(KERN_DEBUG "idi_hdl: Ch%d: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", chan->No, - ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length); - } + if (ind->Ind != 8) + dlev = 144; + else + dlev = 128; + + eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", chan->No, + ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length); free_buff = 1; /* Signal Layer */ @@ -1188,16 +2316,16 @@ idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length); switch(ind->Ind) { case HANGUP: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: Hangup\n", chan->No); + eicon_log(ccard, 8, "idi_ind: Ch%d: Hangup\n", chan->No); while((skb2 = skb_dequeue(&chan->e.X))) { dev_kfree_skb(skb2); } - chan->e.busy = 0; + save_flags(flags); + cli(); chan->queued = 0; chan->waitq = 0; chan->waitpq = 0; - chan->fsm_state = EICON_STATE_NULL; + restore_flags(flags); if (message.e_cau[0] & 0x7f) { cmd.driver = ccard->myid; cmd.arg = chan->No; @@ -1207,58 +2335,83 @@ ccard->interface.statcallb(&cmd); } chan->cause[0] = 0; - cmd.driver = ccard->myid; - cmd.arg = chan->No; - cmd.command = ISDN_STAT_DHUP; - ccard->interface.statcallb(&cmd); - eicon_idi_listen_req(ccard, chan); #ifdef CONFIG_ISDN_TTY_FAX if (!chan->e.B2Id) chan->fax = 0; #endif + if (((chan->fsm_state == EICON_STATE_ACTIVE) || + (chan->fsm_state == EICON_STATE_WMCONN)) || + ((chan->l2prot == ISDN_PROTO_L2_FAX) && + (chan->fsm_state == EICON_STATE_OBWAIT))) { + chan->fsm_state = EICON_STATE_NULL; + } else { + if (chan->e.B2Id) + idi_do_req(ccard, chan, REMOVE, 1); + chan->fsm_state = EICON_STATE_NULL; + cmd.driver = ccard->myid; + cmd.arg = chan->No; + cmd.command = ISDN_STAT_DHUP; + ccard->interface.statcallb(&cmd); + eicon_idi_listen_req(ccard, chan); + } break; case INDICATE_IND: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: Indicate_Ind\n", chan->No); + eicon_log(ccard, 8, "idi_ind: Ch%d: Indicate_Ind\n", chan->No); + if (chan->fsm_state != EICON_STATE_LISTEN) { + eicon_log(ccard, 1, "idi_err: Ch%d: Incoming call on wrong state (%d).\n", + chan->No, chan->fsm_state); + idi_do_req(ccard, chan, HANGUP, 0); + break; + } chan->fsm_state = EICON_STATE_ICALL; idi_bc2si(message.bc, message.hlc, &chan->si1, &chan->si2); strcpy(chan->cpn, message.cpn + 1); - if (strlen(message.dsa)) { - strcat(chan->cpn, "."); - strcat(chan->cpn, message.dsa); - } strcpy(chan->oad, message.oad); + strcpy(chan->dsa, message.dsa); + strcpy(chan->osa, message.osa); + chan->plan = message.plan; + chan->screen = message.screen; try_stat_icall_again: cmd.driver = ccard->myid; cmd.command = ISDN_STAT_ICALL; cmd.arg = chan->No; cmd.parm.setup.si1 = chan->si1; cmd.parm.setup.si2 = chan->si2; - strcpy(cmd.parm.setup.eazmsn, chan->cpn); - strcpy(cmd.parm.setup.phone, chan->oad); - cmd.parm.setup.plan = message.plan; - cmd.parm.setup.screen = message.screen; + strcpy(tnum, chan->cpn); + if (strlen(chan->dsa)) { + strcat(tnum, "."); + strcat(tnum, chan->dsa); + } + tnum[ISDN_MSNLEN - 1] = 0; + strcpy(cmd.parm.setup.eazmsn, tnum); + strcpy(tnum, chan->oad); + if (strlen(chan->osa)) { + strcat(tnum, "."); + strcat(tnum, chan->osa); + } + tnum[ISDN_MSNLEN - 1] = 0; + strcpy(cmd.parm.setup.phone, tnum); + cmd.parm.setup.plan = chan->plan; + cmd.parm.setup.screen = chan->screen; tmp = ccard->interface.statcallb(&cmd); switch(tmp) { case 0: /* no user responding */ idi_do_req(ccard, chan, HANGUP, 0); + chan->fsm_state = EICON_STATE_NULL; break; case 1: /* alert */ - if (DebugVar & 8) - printk(KERN_DEBUG"idi_req: Ch%d: Call Alert\n", chan->No); + eicon_log(ccard, 8, "idi_req: Ch%d: Call Alert\n", chan->No); if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_ICALLW)) { chan->fsm_state = EICON_STATE_ICALL; idi_do_req(ccard, chan, CALL_ALERT, 0); } break; case 2: /* reject */ - if (DebugVar & 8) - printk(KERN_DEBUG"idi_req: Ch%d: Call Reject\n", chan->No); + eicon_log(ccard, 8, "idi_req: Ch%d: Call Reject\n", chan->No); idi_do_req(ccard, chan, REJECT, 0); break; case 3: /* incomplete number */ - if (DebugVar & 8) - printk(KERN_DEBUG"idi_req: Ch%d: Incomplete Number\n", chan->No); + eicon_log(ccard, 8, "idi_req: Ch%d: Incomplete Number\n", chan->No); switch(ccard->type) { case EICON_CTYPE_MAESTRAP: case EICON_CTYPE_S2M: @@ -1272,8 +2425,7 @@ } break; case INFO_IND: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: Info_Ind\n", chan->No); + eicon_log(ccard, 8, "idi_ind: Ch%d: Info_Ind\n", chan->No); if ((chan->fsm_state == EICON_STATE_ICALLW) && (message.cpn[0])) { strcat(chan->cpn, message.cpn + 1); @@ -1281,35 +2433,45 @@ } break; case CALL_IND: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: Call_Ind\n", chan->No); + eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Ind\n", chan->No); if ((chan->fsm_state == EICON_STATE_ICALL) || (chan->fsm_state == EICON_STATE_IWAIT)) { chan->fsm_state = EICON_STATE_IBWAIT; cmd.driver = ccard->myid; cmd.command = ISDN_STAT_DCONN; cmd.arg = chan->No; ccard->interface.statcallb(&cmd); - if (chan->l2prot != ISDN_PROTO_L2_FAX) { - idi_do_req(ccard, chan, IDI_N_CONNECT, 1); - } + switch(chan->l2prot) { + case ISDN_PROTO_L2_FAX: #ifdef CONFIG_ISDN_TTY_FAX - else { - if (chan->fax) - chan->fax->phase = ISDN_FAX_PHASE_A; - } + if (chan->fax) + chan->fax->phase = ISDN_FAX_PHASE_A; #endif + break; + case ISDN_PROTO_L2_MODEM: + /* do nothing, wait for connect */ + break; + default: + idi_do_req(ccard, chan, IDI_N_CONNECT, 1); + } } else idi_hangup(ccard, chan); break; case CALL_CON: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: Call_Con\n", chan->No); + eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Con\n", chan->No); if (chan->fsm_state == EICON_STATE_OCALL) { chan->fsm_state = EICON_STATE_OBWAIT; cmd.driver = ccard->myid; cmd.command = ISDN_STAT_DCONN; cmd.arg = chan->No; ccard->interface.statcallb(&cmd); + + /* check if old NetID has been removed */ + if (chan->e.B2Id) { + eicon_log(ccard, 1, "eicon: Ch%d: old net_id %x still exist, removing.\n", + chan->No, chan->e.B2Id); + idi_do_req(ccard, chan, REMOVE, 1); + } + idi_do_req(ccard, chan, ASSIGN, 1); idi_do_req(ccard, chan, IDI_N_CONNECT, 1); #ifdef CONFIG_ISDN_TTY_FAX @@ -1322,12 +2484,10 @@ idi_hangup(ccard, chan); break; case AOC_IND: - if (DebugVar & 8) - printk(KERN_DEBUG"idi_ind: Ch%d: Advice of Charge\n", chan->No); + eicon_log(ccard, 8, "idi_ind: Ch%d: Advice of Charge\n", chan->No); break; default: - if (DebugVar & 8) - printk(KERN_WARNING "idi_ind: Ch%d: UNHANDLED SigIndication 0x%02x\n", chan->No, ind->Ind); + eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED SigIndication 0x%02x\n", chan->No, ind->Ind); } } /* Network Layer */ @@ -1341,8 +2501,7 @@ else switch(ind->Ind) { case IDI_N_CONNECT_ACK: - if (DebugVar & 16) - printk(KERN_DEBUG"idi_ind: Ch%d: N_Connect_Ack\n", chan->No); + eicon_log(ccard, 16, "idi_ind: Ch%d: N_Connect_Ack\n", chan->No); if (chan->l2prot == ISDN_PROTO_L2_MODEM) { chan->fsm_state = EICON_STATE_WMCONN; break; @@ -1362,8 +2521,7 @@ } } else { - if (DebugVar & 1) - printk(KERN_DEBUG "idi_ind: N_CONNECT_ACK with NULL fax struct, ERROR\n"); + eicon_log(ccard, 1, "idi_ind: N_CONNECT_ACK with NULL fax struct, ERROR\n"); } #endif break; @@ -1375,8 +2533,7 @@ ccard->interface.statcallb(&cmd); break; case IDI_N_CONNECT: - if (DebugVar & 16) - printk(KERN_DEBUG"idi_ind: Ch%d: N_Connect\n", chan->No); + eicon_log(ccard, 16,"idi_ind: Ch%d: N_Connect\n", chan->No); if (chan->e.B2Id) idi_do_req(ccard, chan, IDI_N_CONNECT_ACK, 1); if (chan->l2prot == ISDN_PROTO_L2_FAX) { break; @@ -1392,9 +2549,11 @@ ccard->interface.statcallb(&cmd); break; case IDI_N_DISC: - if (DebugVar & 16) - printk(KERN_DEBUG"idi_ind: Ch%d: N_DISC\n", chan->No); + eicon_log(ccard, 16, "idi_ind: Ch%d: N_DISC\n", chan->No); if (chan->e.B2Id) { + while((skb2 = skb_dequeue(&chan->e.X))) { + dev_kfree_skb(skb2); + } idi_do_req(ccard, chan, IDI_N_DISC_ACK, 1); idi_do_req(ccard, chan, REMOVE, 1); } @@ -1404,23 +2563,26 @@ idi_fax_hangup(ccard, chan); } #endif + save_flags(flags); + cli(); chan->queued = 0; chan->waitq = 0; chan->waitpq = 0; + restore_flags(flags); idi_do_req(ccard, chan, HANGUP, 0); if (chan->fsm_state == EICON_STATE_ACTIVE) { cmd.driver = ccard->myid; cmd.command = ISDN_STAT_BHUP; cmd.arg = chan->No; ccard->interface.statcallb(&cmd); + chan->fsm_state = EICON_STATE_NULL; } #ifdef CONFIG_ISDN_TTY_FAX chan->fax = 0; #endif break; case IDI_N_DISC_ACK: - if (DebugVar & 16) - printk(KERN_DEBUG"idi_ind: Ch%d: N_DISC_ACK\n", chan->No); + eicon_log(ccard, 16, "idi_ind: Ch%d: N_DISC_ACK\n", chan->No); #ifdef CONFIG_ISDN_TTY_FAX if (chan->l2prot == ISDN_PROTO_L2_FAX) { idi_parse_edata(ccard, chan, ind->RBuffer.P, ind->RBuffer.length); @@ -1429,13 +2591,11 @@ #endif break; case IDI_N_DATA_ACK: - if (DebugVar & 16) - printk(KERN_DEBUG"idi_ind: Ch%d: N_DATA_ACK\n", chan->No); + eicon_log(ccard, 16, "idi_ind: Ch%d: N_DATA_ACK\n", chan->No); break; case IDI_N_DATA: skb_pull(skb, sizeof(eicon_IND) - 1); - if (DebugVar & 128) - printk(KERN_DEBUG"idi_rcv: Ch%d: %d bytes\n", chan->No, skb->len); + eicon_log(ccard, 128, "idi_rcv: Ch%d: %d bytes\n", chan->No, skb->len); if (chan->l2prot == ISDN_PROTO_L2_FAX) { #ifdef CONFIG_ISDN_TTY_FAX idi_faxdata_rcv(ccard, chan, skb); @@ -1454,27 +2614,26 @@ break; #endif default: - if (DebugVar & 8) - printk(KERN_WARNING "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind); + eicon_log(ccard, 8, "idi_ind: Ch%d: UNHANDLED NetIndication 0x%02x\n", chan->No, ind->Ind); } } else { - if (DebugVar & 1) - printk(KERN_ERR "idi_ind: Ch%d: Ind is neither SIG nor NET !\n", chan->No); + eicon_log(ccard, 1, "idi_ind: Ch%d: Ind is neither SIG nor NET !\n", chan->No); } - if (free_buff) dev_kfree_skb(skb); + if (free_buff) + dev_kfree_skb(skb); } int idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack) { + ulong flags; isdn_ctrl cmd; if (ack->RcId != ((chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id)) { /* I dont know why this happens, just ignoring this RC */ - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No, - ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id); + eicon_log(ccard, 16, "idi_ack: Ch%d: RcId %d not equal to last %d\n", chan->No, + ack->RcId, (chan->e.ReqCh) ? chan->e.B2Id : chan->e.D3Id); return 1; } @@ -1488,27 +2647,27 @@ /* Remove an Id */ if (chan->e.Req == REMOVE) { if (ack->Reference != chan->e.ref) { - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No, - ack->Reference, chan->e.ref); + eicon_log(ccard, 16, "idi_ack: Ch%d: Rc-Ref %d not equal to stored %d\n", chan->No, + ack->Reference, chan->e.ref); return 0; } + save_flags(flags); + cli(); ccard->IdTable[ack->RcId] = NULL; - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: Removed : Id=%x Ch=%d (%s)\n", chan->No, - ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig"); + eicon_log(ccard, 16, "idi_ack: Ch%d: Removed : Id=%x Ch=%d (%s)\n", chan->No, + ack->RcId, ack->RcCh, (chan->e.ReqCh)? "Net":"Sig"); if (!chan->e.ReqCh) chan->e.D3Id = 0; else chan->e.B2Id = 0; + restore_flags(flags); return 1; } /* Signal layer */ if (!chan->e.ReqCh) { - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No, - ack->RcId, ack->RcCh, ack->Reference); + eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No, + ack->RcId, ack->RcCh, ack->Reference); } else { /* Network layer */ switch(chan->e.Req & 0x0f) { @@ -1522,7 +2681,10 @@ cmd.parm.length = chan->waitpq; ccard->interface.statcallb(&cmd); } + save_flags(flags); + cli(); chan->waitpq = 0; + restore_flags(flags); #ifdef CONFIG_ISDN_TTY_FAX if (chan->l2prot == ISDN_PROTO_L2_FAX) { if (((chan->queued - chan->waitq) < 1) && @@ -1536,20 +2698,21 @@ ccard->interface.statcallb(&cmd); } else { - if (DebugVar & 1) - printk(KERN_DEBUG "idi_ack: Sent with NULL fax struct, ERROR\n"); + eicon_log(ccard, 1, "idi_ack: Sent with NULL fax struct, ERROR\n"); } } } #endif } + save_flags(flags); + cli(); chan->queued -= chan->waitq; if (chan->queued < 0) chan->queued = 0; + restore_flags(flags); break; default: - if (DebugVar & 16) - printk(KERN_DEBUG "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No, - ack->RcId, ack->RcCh, ack->Reference); + eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No, + ack->RcId, ack->RcCh, ack->Reference); } } return 1; @@ -1559,22 +2722,30 @@ idi_handle_ack(eicon_card *ccard, struct sk_buff *skb) { int j; + ulong flags; eicon_RC *ack = (eicon_RC *)skb->data; eicon_chan *chan; isdn_ctrl cmd; int dCh = -1; + if (!ccard) { + eicon_log(ccard, 1, "idi_err: Ch??: null card in handle_ack\n"); + dev_kfree_skb(skb); + return; + } + + save_flags(flags); + cli(); if ((chan = ccard->IdTable[ack->RcId]) != NULL) dCh = chan->No; - + restore_flags(flags); switch (ack->Rc) { case OK_FC: case N_FLOW_CONTROL: case ASSIGN_RC: - if (DebugVar & 1) - printk(KERN_ERR "idi_ack: Ch%d: unhandled RC 0x%x\n", - dCh, ack->Rc); + eicon_log(ccard, 1, "idi_ack: Ch%d: unhandled RC 0x%x\n", + dCh, ack->Rc); break; case READY_INT: case TIMER_INT: @@ -1583,8 +2754,7 @@ case OK: if (!chan) { - if (DebugVar & 1) - printk(KERN_ERR "idi_ack: Ch%d: OK on chan without Id\n", dCh); + eicon_log(ccard, 1, "idi_ack: Ch%d: OK on chan without Id\n", dCh); break; } if (!idi_handle_ack_ok(ccard, chan, ack)) @@ -1593,29 +2763,29 @@ case ASSIGN_OK: if (chan) { - if (DebugVar & 1) - printk(KERN_ERR "idi_ack: Ch%d: ASSIGN-OK on chan already assigned (%x,%x)\n", - chan->No, chan->e.D3Id, chan->e.B2Id); + eicon_log(ccard, 1, "idi_ack: Ch%d: ASSIGN-OK on chan already assigned (%x,%x)\n", + chan->No, chan->e.D3Id, chan->e.B2Id); } + save_flags(flags); + cli(); for(j = 0; j < ccard->nchannels + 1; j++) { - if (ccard->bch[j].e.ref == ack->Reference) { + if ((ccard->bch[j].e.ref == ack->Reference) && + (ccard->bch[j].e.Req == ASSIGN)) { if (!ccard->bch[j].e.ReqCh) ccard->bch[j].e.D3Id = ack->RcId; else ccard->bch[j].e.B2Id = ack->RcId; ccard->IdTable[ack->RcId] = &ccard->bch[j]; - ccard->bch[j].e.busy = 0; - ccard->bch[j].e.ref = 0; - if (DebugVar & 16) - printk(KERN_DEBUG"idi_ack: Ch%d: Id %x assigned (%s)\n", j, - ack->RcId, (ccard->bch[j].e.ReqCh)? "Net":"Sig"); + chan = &ccard->bch[j]; + eicon_log(ccard, 16, "idi_ack: Ch%d: Id %x assigned (%s)\n", j, + ack->RcId, (ccard->bch[j].e.ReqCh)? "Net":"Sig"); break; } } + restore_flags(flags); if (j > ccard->nchannels) { - if (DebugVar & 24) - printk(KERN_DEBUG"idi_ack: Ch??: ref %d not found for Id %d\n", - ack->Reference, ack->RcId); + eicon_log(ccard, 24, "idi_ack: Ch??: ref %d not found for Id %d\n", + ack->Reference, ack->RcId); } break; @@ -1627,9 +2797,19 @@ case UNKNOWN_IE: case WRONG_IE: default: - if (DebugVar & 1) - printk(KERN_ERR "eicon_ack: Ch%d: Not OK !!: Rc=%d Id=%x Ch=%d\n", dCh, - ack->Rc, ack->RcId, ack->RcCh); + if (!chan) { + eicon_log(ccard, 1, "idi_ack: Ch%d: Not OK !! on chan without Id\n", dCh); + break; + } else + switch (chan->e.Req) { + case 12: /* Alert */ + eicon_log(ccard, 2, "eicon_err: Ch%d: Alert Not OK : Rc=%d Id=%x Ch=%d\n", + dCh, ack->Rc, ack->RcId, ack->RcCh); + break; + default: + eicon_log(ccard, 1, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n", + dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req); + } if (dCh == ccard->nchannels) { /* Management */ chan->fsm_state = 2; } else if (dCh >= 0) { @@ -1642,8 +2822,13 @@ ccard->interface.statcallb(&cmd); } } - if (chan) + save_flags(flags); + cli(); + if (chan) { + chan->e.ref = 0; chan->e.busy = 0; + } + restore_flags(flags); dev_kfree_skb(skb); eicon_schedule_tx(ccard); } @@ -1658,21 +2843,25 @@ int len, plen = 0, offset = 0; unsigned long flags; + if ((!card) || (!chan)) { + eicon_log(card, 1, "idi_err: Ch??: null card/chan in send_data\n"); + return -1; + } + if (chan->fsm_state != EICON_STATE_ACTIVE) { - if (DebugVar & 1) - printk(KERN_DEBUG"idi_snd: Ch%d: send bytes on state %d !\n", chan->No, chan->fsm_state); + eicon_log(card, 1, "idi_snd: Ch%d: send bytes on state %d !\n", chan->No, chan->fsm_state); return -ENODEV; } len = skb->len; - if (len > 2138) /* too much for the shared memory */ + if (len > EICON_MAX_QUEUE) /* too much for the shared memory */ return -1; if (!len) return 0; - if (chan->queued + len > ((chan->l2prot == ISDN_PROTO_L2_TRANS) ? 4000 : EICON_MAX_QUEUED)) + if (chan->queued + len > EICON_MAX_QUEUE) return 0; - if (DebugVar & 128) - printk(KERN_DEBUG"idi_snd: Ch%d: %d bytes\n", chan->No, len); + + eicon_log(card, 128, "idi_snd: Ch%d: %d bytes\n", chan->No, len); save_flags(flags); cli(); @@ -1685,8 +2874,7 @@ if ((!xmit_skb) || (!skb2)) { restore_flags(flags); - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: Ch%d: alloc_skb failed in send_data()\n", chan->No); + eicon_log(card, 1, "idi_err: Ch%d: alloc_skb failed in send_data()\n", chan->No); if (xmit_skb) dev_kfree_skb(skb); if (skb2) @@ -1740,8 +2928,7 @@ skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); if ((!skb) || (!skb2)) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: alloc_skb failed in manage_assign()\n"); + eicon_log(card, 1, "idi_err: alloc_skb failed in manage_assign()\n"); if (skb) dev_kfree_skb(skb); if (skb2) @@ -1783,8 +2970,7 @@ skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); if ((!skb) || (!skb2)) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: alloc_skb failed in manage_remove()\n"); + eicon_log(card, 1, "idi_err: alloc_skb failed in manage_remove()\n"); if (skb) dev_kfree_skb(skb); if (skb2) @@ -1850,8 +3036,7 @@ chan->fsm_state = 0; if (!(manbuf = kmalloc(sizeof(eicon_manifbuf), GFP_KERNEL))) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: alloc_manifbuf failed\n"); + eicon_log(card, 1, "idi_err: alloc_manifbuf failed\n"); chan->e.D3Id = 0; return -ENOMEM; } @@ -1865,8 +3050,7 @@ skb2 = alloc_skb(sizeof(eicon_chan_ptr), GFP_ATOMIC); if ((!skb) || (!skb2)) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err_manif: alloc_skb failed in manage()\n"); + eicon_log(card, 1, "idi_err_manif: alloc_skb failed in manage()\n"); if (skb) dev_kfree_skb(skb); if (skb2) diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/eicon/eicon_io.c linux/drivers/isdn/eicon/eicon_io.c --- v2.3.26/linux/drivers/isdn/eicon/eicon_io.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/eicon/eicon_io.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: eicon_io.c,v 1.4 1999/08/22 20:26:47 calle Exp $ +/* $Id: eicon_io.c,v 1.8 1999/10/08 22:09:34 armin Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * Code for communicating with hardware. @@ -24,6 +24,20 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_io.c,v $ + * Revision 1.8 1999/10/08 22:09:34 armin + * Some fixes of cards interface handling. + * Bugfix of NULL pointer occurence. + * Changed a few log outputs. + * + * Revision 1.7 1999/09/26 14:17:53 armin + * Improved debug and log via readstat() + * + * Revision 1.6 1999/09/21 20:35:43 armin + * added more error checking. + * + * Revision 1.5 1999/08/31 11:20:11 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.4 1999/08/22 20:26:47 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -51,19 +65,21 @@ void eicon_io_rcv_dispatch(eicon_card *ccard) { + ulong flags; struct sk_buff *skb, *skb2, *skb_new; eicon_IND *ind, *ind2, *ind_new; eicon_chan *chan; if (!ccard) { - if (DebugVar & 1) - printk(KERN_WARNING "eicon_io_rcv_dispatch: NULL card!\n"); + eicon_log(ccard, 1, "eicon_err: NULL card in rcv_dispatch !\n"); return; } while((skb = skb_dequeue(&ccard->rcvq))) { ind = (eicon_IND *)skb->data; + save_flags(flags); + cli(); if ((chan = ccard->IdTable[ind->IndId]) == NULL) { if (DebugVar & 1) { switch(ind->Ind) { @@ -71,14 +87,16 @@ /* doesn't matter if this happens */ break; default: - printk(KERN_ERR "idi: Indication for unknown channel Ind=%d Id=%x\n", ind->Ind, ind->IndId); - printk(KERN_DEBUG "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", + eicon_log(ccard, 1, "idi: Indication for unknown channel Ind=%d Id=%x\n", ind->Ind, ind->IndId); + eicon_log(ccard, 1, "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length); } } + restore_flags(flags); dev_kfree_skb(skb); continue; } + restore_flags(flags); if (chan->e.complete) { /* check for rec-buffer chaining */ if (ind->MLength == ind->RBuffer.length) { @@ -94,10 +112,12 @@ } } else { + save_flags(flags); + cli(); if (!(skb2 = skb_dequeue(&chan->e.R))) { chan->e.complete = 1; - if (DebugVar & 1) - printk(KERN_ERR "eicon: buffer incomplete, but 0 in queue\n"); + eicon_log(ccard, 1, "eicon: buffer incomplete, but 0 in queue\n"); + restore_flags(flags); dev_kfree_skb(skb); continue; } @@ -105,8 +125,8 @@ skb_new = alloc_skb(((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length), GFP_ATOMIC); if (!skb_new) { - if (DebugVar & 1) - printk(KERN_ERR "eicon_io: skb_alloc failed in rcv_dispatch()\n"); + eicon_log(ccard, 1, "eicon_io: skb_alloc failed in rcv_dispatch()\n"); + restore_flags(flags); dev_kfree_skb(skb); dev_kfree_skb(skb2); continue; @@ -125,12 +145,14 @@ dev_kfree_skb(skb2); if (ind->MLength == ind->RBuffer.length) { chan->e.complete = 2; + restore_flags(flags); idi_handle_ind(ccard, skb_new); continue; } else { chan->e.complete = 0; skb_queue_tail(&chan->e.R, skb_new); + restore_flags(flags); continue; } } @@ -142,8 +164,7 @@ struct sk_buff *skb; if (!ccard) { - if (DebugVar & 1) - printk(KERN_WARNING "eicon_io_ack_dispatch: NULL card!\n"); + eicon_log(ccard, 1, "eicon_err: NULL card in ack_dispatch!\n"); return; } while((skb = skb_dequeue(&ccard->rackq))) { @@ -399,13 +420,13 @@ int scom = 0; int tmp = 0; int quloop = 1; + int dlev = 0; pci_card = &ccard->hwif.pci; isa_card = &ccard->hwif.isa; if (!ccard) { - if (DebugVar & 1) - printk(KERN_WARNING "eicon_transmit: NULL card!\n"); + eicon_log(ccard, 1, "eicon_transmit: NULL card!\n"); return; } @@ -438,7 +459,7 @@ prram = 0; break; default: - printk(KERN_WARNING "eicon_transmit: unsupported card-type!\n"); + eicon_log(ccard, 1, "eicon_transmit: unsupported card-type!\n"); return; } @@ -457,16 +478,14 @@ } restore_flags(flags); skb_queue_head(&ccard->sndq, skb2); - if (DebugVar & 32) - printk(KERN_INFO "eicon: transmit: Card not ready\n"); + eicon_log(ccard, 32, "eicon: transmit: Card not ready\n"); return; } } else { if (!(ram_inb(ccard, &prram->ReqOutput) - ram_inb(ccard, &prram->ReqInput))) { restore_flags(flags); skb_queue_head(&ccard->sndq, skb2); - if (DebugVar & 32) - printk(KERN_INFO "eicon: transmit: Card not ready\n"); + eicon_log(ccard, 32, "eicon: transmit: Card not ready\n"); return; } } @@ -479,8 +498,7 @@ cli(); reqbuf = (eicon_REQ *)skb->data; if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) { - if (DebugVar & 16) - printk(KERN_WARNING "eicon: transmit: error Id=0 on %d (Net)\n", chan->No); + eicon_log(ccard, 16, "eicon: transmit: error Id=0 on %d (Net)\n", chan->No); } else { if (scom) { ram_outw(ccard, &com->XBuffer.length, reqbuf->XBuffer.length); @@ -495,7 +513,7 @@ ram_outb(ccard, &ReqOut->ReqCh, reqbuf->ReqCh); ram_outb(ccard, &ReqOut->Req, reqbuf->Req); } - + dlev = 160; if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */ if (!reqbuf->Reference) { /* Signal Layer */ @@ -517,6 +535,7 @@ ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */ chan->waitq = reqbuf->XBuffer.length; chan->waitpq += reqbuf->XBuffer.length; + dlev = 128; } } @@ -544,13 +563,12 @@ else ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next)); - chan->e.busy = 1; - if (DebugVar & 32) - printk(KERN_DEBUG "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n", - reqbuf->Req, - ram_inb(ccard, &ReqOut->ReqId), - reqbuf->ReqCh, reqbuf->XBuffer.length, - chan->e.ref); + chan->e.busy = 1; + eicon_log(ccard, dlev, "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n", + reqbuf->Req, + ram_inb(ccard, &ReqOut->ReqId), + reqbuf->ReqCh, reqbuf->XBuffer.length, + chan->e.ref); } restore_flags(flags); dev_kfree_skb(skb); @@ -559,8 +577,7 @@ } else { skb_queue_tail(&ccard->sackq, skb2); - if (DebugVar & 32) - printk(KERN_INFO "eicon: transmit: busy chan %d\n", chan->No); + eicon_log(ccard, 128, "eicon: transmit: busy chan %d\n", chan->No); } if (scom) @@ -601,10 +618,11 @@ unsigned char *irqprobe = 0; int scom = 0; int tmp = 0; + int dlev = 0; if (!ccard) { - printk(KERN_WARNING "eicon_irq: spurious interrupt %d\n", irq); + eicon_log(ccard, 1, "eicon_irq: spurious interrupt %d\n", irq); return; } @@ -656,7 +674,7 @@ prram = 0; break; default: - printk(KERN_WARNING "eicon_irq: unsupported card-type!\n"); + eicon_log(ccard, 1, "eicon_irq: unsupported card-type!\n"); return; } @@ -706,24 +724,21 @@ case EICON_CTYPE_QUADRO: case EICON_CTYPE_S2M: if (!(readb(isa_card->intack))) { /* card did not interrupt */ - if (DebugVar & 1) - printk(KERN_DEBUG "eicon: IRQ: card tells no interrupt!\n"); + eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n"); return; } break; #endif case EICON_CTYPE_MAESTRAP: if (!(readb(&ram[0x3fe]))) { /* card did not interrupt */ - if (DebugVar & 1) - printk(KERN_DEBUG "eicon: IRQ: card tells no interrupt!\n"); + eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n"); return; } break; case EICON_CTYPE_MAESTRA: outw(0x3fe, pci_card->PCIreg + M_ADDR); if (!(inb(pci_card->PCIreg + M_DATA))) { /* card did not interrupt */ - if (DebugVar & 1) - printk(KERN_DEBUG "eicon: IRQ: card tells no interrupt!\n"); + eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n"); return; } break; @@ -735,8 +750,7 @@ if ((tmp = ram_inb(ccard, &com->Rc))) { eicon_RC *ack; if (tmp == READY_INT) { - if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Rc=READY_INT\n"); + eicon_log(ccard, 64, "eicon: IRQ Rc=READY_INT\n"); if (ccard->ReadyInt) { ccard->ReadyInt--; ram_outb(ccard, &com->Rc, 0); @@ -744,17 +758,15 @@ } else { skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC); if (!skb) { - if (DebugVar & 1) - printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n"); + eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n"); } else { ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC)); ack->Rc = tmp; ack->RcId = ram_inb(ccard, &com->RcId); ack->RcCh = ram_inb(ccard, &com->RcCh); ack->Reference = ccard->ref_in++; - if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n", - tmp,ack->RcId,ack->RcCh,ack->Reference); + eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n", + tmp,ack->RcId,ack->RcCh,ack->Reference); skb_queue_tail(&ccard->rackq, skb); eicon_schedule_ack(ccard); } @@ -770,8 +782,7 @@ int len = ram_inw(ccard, &com->RBuffer.length); skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC); if (!skb) { - if (DebugVar & 1) - printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n"); + eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n"); } else { ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1)); ind->Ind = tmp; @@ -779,9 +790,12 @@ ind->IndCh = ram_inb(ccard, &com->IndCh); ind->MInd = ram_inb(ccard, &com->MInd); ind->MLength = ram_inw(ccard, &com->MLength); - ind->RBuffer.length = len; - if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", + ind->RBuffer.length = len; + if ((tmp == 1) || (tmp == 8)) + dlev = 128; + else + dlev = 192; + eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len); ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len); skb_queue_tail(&ccard->rcvq, skb); @@ -804,17 +818,15 @@ if((Rc=ram_inb(ccard, &RcIn->Rc))) { skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC); if (!skb) { - if (DebugVar & 1) - printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n"); + eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n"); } else { ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC)); ack->Rc = Rc; ack->RcId = ram_inb(ccard, &RcIn->RcId); ack->RcCh = ram_inb(ccard, &RcIn->RcCh); ack->Reference = ram_inw(ccard, &RcIn->Reference); - if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n", - Rc,ack->RcId,ack->RcCh,ack->Reference); + eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n", + Rc,ack->RcId,ack->RcCh,ack->Reference); skb_queue_tail(&ccard->rackq, skb); eicon_schedule_ack(ccard); } @@ -839,8 +851,7 @@ int len = ram_inw(ccard, &IndIn->RBuffer.length); skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC); if (!skb) { - if (DebugVar & 1) - printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n"); + eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n"); } else { ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1)); ind->Ind = Ind; @@ -849,8 +860,11 @@ ind->MInd = ram_inb(ccard, &IndIn->MInd); ind->MLength = ram_inw(ccard, &IndIn->MLength); ind->RBuffer.length = len; - if (DebugVar & 64) - printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", + if ((Ind == 1) || (Ind == 8)) + dlev = 128; + else + dlev = 192; + eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len); ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len); skb_queue_tail(&ccard->rcvq, skb); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/eicon/eicon_isa.c linux/drivers/isdn/eicon/eicon_isa.c --- v2.3.26/linux/drivers/isdn/eicon/eicon_isa.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/eicon/eicon_isa.c Sun Nov 7 16:34:00 1999 @@ -1,9 +1,9 @@ -/* $Id: eicon_isa.c,v 1.7 1999/08/22 20:26:48 calle Exp $ +/* $Id: eicon_isa.c,v 1.9 1999/09/08 20:17:31 armin Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * Hardware-specific code for old ISA cards. * - * Copyright 1998 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1998,99 by Armin Schindler (mac@melware.de) * Copyright 1999 Cytronics & Melware (info@melware.de) * @@ -22,6 +22,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_isa.c,v $ + * Revision 1.9 1999/09/08 20:17:31 armin + * Added microchannel patch from Erik Weber. + * + * Revision 1.8 1999/09/06 07:29:35 fritz + * Changed my mail-address. + * * Revision 1.7 1999/08/22 20:26:48 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -64,7 +70,9 @@ #define release_shmem release_region #define request_shmem request_region -char *eicon_isa_revision = "$Revision: 1.7 $"; +char *eicon_isa_revision = "$Revision: 1.9 $"; + +#undef EICON_MCA_DEBUG #ifdef CONFIG_ISDN_DRV_EICON_ISA @@ -107,7 +115,7 @@ case EICON_CTYPE_SCOM: case EICON_CTYPE_QUADRO: case EICON_CTYPE_S2M: - printk(KERN_INFO "Eicon %s at 0x%lx, irq %d\n", + printk(KERN_INFO "Eicon %s at 0x%lx, irq %d.\n", eicon_ctype_name[card->type], (unsigned long)card->shmem, card->irq); @@ -210,12 +218,30 @@ return -EBUSY; } request_shmem((unsigned long)card->shmem, card->ramsize, "Eicon ISA ISDN"); +#ifdef EICON_MCA_DEBUG + printk(KERN_INFO "eicon_isa_boot: card->ramsize = %d.\n", card->ramsize); +#endif card->mvalid = 1; /* clear any pending irq's */ readb(card->intack); +#ifdef CONFIG_MCA + if (card->type == EICON_CTYPE_SCOM) { + outb_p(0,card->io+1); + } + else { + printk(KERN_WARNING "eicon_isa_boot: Card type yet not supported.\n"); + return -EINVAL; + }; + +#ifdef EICON_MCA_DEBUG + printk(KERN_INFO "eicon_isa_boot: card->io = %x.\n", card->io); + printk(KERN_INFO "eicon_isa_boot: card->irq = %d.\n", (int)card->irq); +#endif +#else /* set reset-line active */ writeb(0, card->stopcpu); +#endif /* CONFIG_MCA */ /* clear irq-requests */ writeb(0, card->intack); readb(card->intack); @@ -242,7 +268,11 @@ /* Start CPU */ writeb(cbuf.boot_opt, &boot->ctrl); +#ifdef CONFIG_MCA + outb_p(0, card->io); +#else writeb(0, card->startcpu); +#endif /* CONFIG_MCA */ /* Delay 0.2 sec. */ SLEEP(20); @@ -254,7 +284,11 @@ SLEEP(10); } if (readb(&boot->ctrl) != 0) { - printk(KERN_WARNING "eicon_isa_boot: CPU test failed\n"); + printk(KERN_WARNING "eicon_isa_boot: CPU test failed.\n"); +#ifdef EICON_MCA_DEBUG + printk(KERN_INFO "eicon_isa_boot: &boot->ctrl = %d.\n", + readb(&boot->ctrl)); +#endif eicon_isa_release_shmem(card); return -EIO; } @@ -307,7 +341,7 @@ return -EFAULT; if (!(code = kmalloc(cbuf.firmware_len, GFP_KERNEL))) { - printk(KERN_WARNING "eicon_isa_boot: Couldn't allocate code buffer\n"); + printk(KERN_WARNING "eicon_isa_load: Couldn't allocate code buffer\n"); return -ENOMEM; } @@ -323,7 +357,7 @@ /* Check for valid IRQ */ if ((card->irq < 0) || (card->irq > 15) || (!((1 << card->irq) & eicon_isa_valid_irq[card->type & 0x0f]))) { - printk(KERN_WARNING "eicon_isa_boot: illegal irq: %d\n", card->irq); + printk(KERN_WARNING "eicon_isa_load: illegal irq: %d\n", card->irq); eicon_isa_release_shmem(card); kfree(code); return -EINVAL; @@ -332,7 +366,7 @@ if (!request_irq(card->irq, &eicon_irq, 0, "Eicon ISA ISDN", card)) card->ivalid = 1; else { - printk(KERN_WARNING "eicon_isa_boot: irq %d already in use.\n", + printk(KERN_WARNING "eicon_isa_load: irq %d already in use.\n", card->irq); eicon_isa_release_shmem(card); kfree(code); @@ -343,7 +377,7 @@ tmp = readb(&boot->msize); if (tmp != 8 && tmp != 16 && tmp != 24 && tmp != 32 && tmp != 48 && tmp != 60) { - printk(KERN_WARNING "eicon_isa_boot: invalid memsize\n"); + printk(KERN_WARNING "eicon_isa_load: invalid memsize\n"); eicon_isa_release_shmem(card); return -EIO; } @@ -366,7 +400,7 @@ SLEEP(2); } if (readb(&boot->ctrl)) { - printk(KERN_WARNING "eicon_isa_boot: download timeout at 0x%x\n", p-code); + printk(KERN_WARNING "eicon_isa_load: download timeout at 0x%x\n", p-code); eicon_isa_release(card); kfree(code); return -EIO; @@ -389,7 +423,7 @@ SLEEP(2); } if (readw(&boot->signature) != 0x4447) { - printk(KERN_WARNING "eicon_isa_boot: firmware selftest failed %04x\n", + printk(KERN_WARNING "eicon_isa_load: firmware selftest failed %04x\n", readw(&boot->signature)); eicon_isa_release(card); return -EIO; @@ -414,11 +448,15 @@ SLEEP(2); } if (card->irqprobe == 1) { - printk(KERN_WARNING "eicon_isa_boot: IRQ test failed\n"); + printk(KERN_WARNING "eicon_isa_load: IRQ # %d test failed\n", card->irq); eicon_isa_release(card); return -EIO; } } +#ifdef EICON_MCA_DEBUG + printk(KERN_INFO "eicon_isa_load: IRQ # %d test succeeded.\n", card->irq); +#endif + writeb(card->irq, &card->shmem->com.Int); /* initializing some variables */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/eicon/eicon_isa.h linux/drivers/isdn/eicon/eicon_isa.h --- v2.3.26/linux/drivers/isdn/eicon/eicon_isa.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/eicon/eicon_isa.h Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: eicon_isa.h,v 1.3 1999/03/29 11:19:47 armin Exp $ +/* $Id: eicon_isa.h,v 1.5 1999/09/08 20:17:31 armin Exp $ * * ISDN low-level module for Eicon.Diehl active ISDN-Cards. * - * Copyright 1998 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1998,99 by Armin Schindler (mac@melware.de) * Copyright 1999 Cytronics & Melware (info@melware.de) * @@ -21,6 +21,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_isa.h,v $ + * Revision 1.5 1999/09/08 20:17:31 armin + * Added microchannel patch from Erik Weber. + * + * Revision 1.4 1999/09/06 07:29:35 fritz + * Changed my mail-address. + * * Revision 1.3 1999/03/29 11:19:47 armin * I/O stuff now in seperate file (eicon_io.c) * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented. @@ -106,6 +112,9 @@ typedef struct { int ramsize; int irq; /* IRQ */ +#ifdef CONFIG_MCA + int io; /* IO-port for MCA brand */ +#endif /* CONFIG_MCA */ void* card; eicon_isa_shmem* shmem; /* Shared-memory area */ unsigned char* intack; /* Int-Acknowledge */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c --- v2.3.26/linux/drivers/isdn/eicon/eicon_mod.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/eicon/eicon_mod.c Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: eicon_mod.c,v 1.11 1999/08/29 17:23:45 armin Exp $ +/* $Id: eicon_mod.c,v 1.18 1999/10/11 18:13:25 armin Exp $ * * ISDN lowlevel-module for Eicon.Diehl active cards. * - * Copyright 1997 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1998,99 by Armin Schindler (mac@melware.de) * Copyright 1999 Cytronics & Melware (info@melware.de) * @@ -11,6 +11,11 @@ * * Deutsche Telekom AG for S2M support. * + * Deutsche Mailbox Saar-Lor-Lux GmbH + * for sponsoring and testing fax + * capabilities with Diva Server cards. + * (dor@deutschemailbox.de) + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -26,6 +31,30 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: eicon_mod.c,v $ + * Revision 1.18 1999/10/11 18:13:25 armin + * Added fax capabilities for Eicon Diva Server cards. + * + * Revision 1.17 1999/10/08 22:09:34 armin + * Some fixes of cards interface handling. + * Bugfix of NULL pointer occurence. + * Changed a few log outputs. + * + * Revision 1.16 1999/09/26 14:17:53 armin + * Improved debug and log via readstat() + * + * Revision 1.15 1999/09/08 20:17:31 armin + * Added microchannel patch from Erik Weber. + * + * Revision 1.14 1999/09/06 07:29:35 fritz + * Changed my mail-address. + * + * Revision 1.13 1999/09/04 17:37:59 armin + * Removed not used define, did not work and caused error + * in 2.3.16 + * + * Revision 1.12 1999/08/31 11:20:14 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.11 1999/08/29 17:23:45 armin * New setup compat. * Bugfix if compile as not module. @@ -82,7 +111,7 @@ #include #ifdef CONFIG_MCA #include -#endif +#endif /* CONFIG_MCA */ #include "eicon.h" @@ -91,7 +120,7 @@ static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains start of card-list */ -static char *eicon_revision = "$Revision: 1.11 $"; +static char *eicon_revision = "$Revision: 1.18 $"; extern char *eicon_pci_revision; extern char *eicon_isa_revision; @@ -172,8 +201,7 @@ { if ((channel >= 0) && (channel < card->nchannels)) return &(card->bch[channel]); - if (DebugVar & 1) - printk(KERN_WARNING "eicon: Invalid channel %d\n", channel); + eicon_log(card, 1, "eicon: Invalid channel %d\n", channel); return NULL; } @@ -239,87 +267,6 @@ return("\0"); } -#if 0 -/* - * Add or delete an MSN to the MSN list - * - * First character of msneaz is EAZ, rest is MSN. - * If length of eazmsn is 1, delete that entry. - */ -static int -eicon_set_msn(eicon_card *card, char *eazmsn) -{ - struct msn_entry *p = card->msn_list; - struct msn_entry *q = NULL; - unsigned long flags; - int i; - - if (!strlen(eazmsn)) - return 0; - if (strlen(eazmsn) > 16) - return -EINVAL; - for (i = 0; i < strlen(eazmsn); i++) - if (!isdigit(eazmsn[i])) - return -EINVAL; - if (strlen(eazmsn) == 1) { - /* Delete a single MSN */ - while (p) { - if (p->eaz == eazmsn[0]) { - save_flags(flags); - cli(); - if (q) - q->next = p->next; - else - card->msn_list = p->next; - restore_flags(flags); - kfree(p); - if (DebugVar & 8) - printk(KERN_DEBUG - "Mapping for EAZ %c deleted\n", - eazmsn[0]); - return 0; - } - q = p; - p = p->next; - } - return 0; - } - /* Add a single MSN */ - while (p) { - /* Found in list, replace MSN */ - if (p->eaz == eazmsn[0]) { - save_flags(flags); - cli(); - strcpy(p->msn, &eazmsn[1]); - restore_flags(flags); - if (DebugVar & 8) - printk(KERN_DEBUG - "Mapping for EAZ %c changed to %s\n", - eazmsn[0], - &eazmsn[1]); - return 0; - } - p = p->next; - } - /* Not found in list, add new entry */ - p = kmalloc(sizeof(msn_entry), GFP_KERNEL); - if (!p) - return -ENOMEM; - p->eaz = eazmsn[0]; - strcpy(p->msn, &eazmsn[1]); - p->next = card->msn_list; - save_flags(flags); - cli(); - card->msn_list = p; - restore_flags(flags); - if (DebugVar & 8) - printk(KERN_DEBUG - "Mapping %c -> %s added\n", - eazmsn[0], - &eazmsn[1]); - return 0; -} -#endif static void eicon_rcv_dispatch(struct eicon_card *card) @@ -331,9 +278,8 @@ eicon_io_rcv_dispatch(card); break; default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon_ack_dispatch: Illegal bustype %d\n", card->bus); + eicon_log(card, 1, + "eicon_ack_dispatch: Illegal bustype %d\n", card->bus); } } @@ -347,9 +293,8 @@ eicon_io_ack_dispatch(card); break; default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon_ack_dispatch: Illegal bustype %d\n", card->bus); + eicon_log(card, 1, + "eicon_ack_dispatch: Illegal bustype %d\n", card->bus); } } @@ -363,9 +308,8 @@ eicon_io_transmit(card); break; default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon_transmit: Illegal bustype %d\n", card->bus); + eicon_log(card, 1, + "eicon_transmit: Illegal bustype %d\n", card->bus); } } @@ -375,8 +319,7 @@ int ret_val; if (!(xlr = kmalloc(sizeof(xlogreq_t), GFP_KERNEL))) { - if (DebugVar & 1) - printk(KERN_WARNING "idi_err: alloc_xlogreq_t failed\n"); + eicon_log(card, 1, "idi_err: alloc_xlogreq_t failed\n"); return -ENOMEM; } if (copy_from_user(xlr, xlogreq, sizeof(xlogreq_t))) { @@ -406,9 +349,8 @@ int ret = 0; unsigned long flags; - if (DebugVar & 16) - printk(KERN_WARNING "eicon_cmd 0x%x with arg 0x%lx (0x%lx)\n", - c->command, c->arg, (ulong) *c->parm.num); + eicon_log(card, 16, "eicon_cmd 0x%x with arg 0x%lx (0x%lx)\n", + c->command, c->arg, (ulong) *c->parm.num); switch (c->command) { case ISDN_CMD_IOCTL: @@ -428,9 +370,8 @@ return card->hwif.pci.PCIram; #endif default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: Illegal BUS type %d\n", + eicon_log(card, 1, + "eicon: Illegal BUS type %d\n", card->bus); ret = -ENODEV; } @@ -440,17 +381,25 @@ return -EBUSY; switch (card->bus) { case EICON_BUS_ISA: - case EICON_BUS_MCA: if (eicon_isa_find_card(a, card->hwif.isa.irq, card->regname) < 0) return -EFAULT; card->hwif.isa.shmem = (eicon_isa_shmem *)a; return 0; + case EICON_BUS_MCA: +#if CONFIG_MCA + if (eicon_mca_find_card( + 0, a, + card->hwif.isa.irq, + card->regname) < 0) + return -EFAULT; + card->hwif.isa.shmem = (eicon_isa_shmem *)a; + return 0; +#endif /* CONFIG_MCA */ default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: Illegal BUS type %d\n", + eicon_log(card, 1, + "eicon: Illegal BUS type %d\n", card->bus); ret = -ENODEV; } @@ -465,9 +414,8 @@ return card->hwif.pci.irq; #endif default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: Illegal BUS type %d\n", + eicon_log(card, 1, + "eicon: Illegal BUS type %d\n", card->bus); ret = -ENODEV; } @@ -482,9 +430,8 @@ card->hwif.isa.irq = a; return 0; default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: Illegal BUS type %d\n", + eicon_log(card, 1, + "eicon: Illegal BUS type %d\n", card->bus); ret = -ENODEV; } @@ -500,9 +447,8 @@ &(((eicon_codebuf *)a)->isa)); break; default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: Illegal BUS type %d\n", + eicon_log(card, 1, + "eicon: Illegal BUS type %d\n", card->bus); ret = -ENODEV; } @@ -534,9 +480,8 @@ } break; default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: Illegal BUS type %d\n", + eicon_log(card, 1, + "eicon: Illegal BUS type %d\n", card->bus); ret = -ENODEV; } @@ -592,18 +537,6 @@ return ret; } else return -ENODEV; #endif -#if 0 - case EICON_IOCTL_SETMSN: - if ((ret = copy_from_user(tmp, (char *)a, sizeof(tmp)))) - return -EFAULT; - if ((ret = eicon_set_msn(card, tmp))) - return ret; -#if 0 - if (card->flags & EICON_FLAGS_RUNNING) - return(eicon_capi_manufacturer_req_msn(card)); -#endif - return 0; -#endif case EICON_IOCTL_ADDCARD: if ((ret = copy_from_user(&cdef, (char *)a, sizeof(cdef)))) return -EFAULT; @@ -612,7 +545,7 @@ return 0; case EICON_IOCTL_DEBUGVAR: DebugVar = a; - printk(KERN_DEBUG"Eicon: Debug Value set to %ld\n", DebugVar); + eicon_log(card, 1, "Eicon: Debug Value set to %ld\n", DebugVar); return 0; #ifdef MODULE case EICON_IOCTL_FREEIT: @@ -633,8 +566,7 @@ cli(); if ((chan->fsm_state != EICON_STATE_NULL) && (chan->fsm_state != EICON_STATE_LISTEN)) { restore_flags(flags); - if (DebugVar & 1) - printk(KERN_WARNING "Dial on channel %d with state %d\n", + eicon_log(card, 1, "Dial on channel %d with state %d\n", chan->No, chan->fsm_state); return -EBUSY; } @@ -643,7 +575,6 @@ else tmp[0] = c->parm.setup.eazmsn[0]; chan->fsm_state = EICON_STATE_OCALL; - chan->callref = 0xffff; restore_flags(flags); ret = idi_connect_req(card, chan, c->parm.setup.phone, @@ -738,20 +669,17 @@ case ISDN_CMD_GETEAZ: if (!card->flags & EICON_FLAGS_RUNNING) return -ENODEV; - if (DebugVar & 1) - printk(KERN_DEBUG "eicon CMD_GETEAZ not implemented\n"); + eicon_log(card, 1, "eicon CMD_GETEAZ not implemented\n"); return 0; case ISDN_CMD_SETSIL: if (!card->flags & EICON_FLAGS_RUNNING) return -ENODEV; - if (DebugVar & 1) - printk(KERN_DEBUG "eicon CMD_SETSIL not implemented\n"); + eicon_log(card, 1, "eicon CMD_SETSIL not implemented\n"); return 0; case ISDN_CMD_GETSIL: if (!card->flags & EICON_FLAGS_RUNNING) return -ENODEV; - if (DebugVar & 1) - printk(KERN_DEBUG "eicon CMD_GETSIL not implemented\n"); + eicon_log(card, 1, "eicon CMD_GETSIL not implemented\n"); return 0; case ISDN_CMD_LOCK: MOD_INC_USE_COUNT; @@ -817,36 +745,58 @@ static int if_writecmd(const u_char * buf, int len, int user, int id, int channel) { -#if 0 - /* Not yet used */ - eicon_card *card = eicon_findcard(id); - - if (card) { - if (!card->flags & EICON_FLAGS_RUNNING) - return (len); - return (len); - } - printk(KERN_ERR - "eicon: if_writecmd called with invalid driverId!\n"); -#endif return (len); } static int if_readstatus(u_char * buf, int len, int user, int id, int channel) { -#if 0 - /* Not yet used */ + int count = 0; + int cnt = 0; + ulong flags = 0; + u_char *p = buf; + struct sk_buff *skb; + eicon_card *card = eicon_findcard(id); if (card) { if (!card->flags & EICON_FLAGS_RUNNING) return -ENODEV; - return (eicon_readstatus(buf, len, user, card)); + + save_flags(flags); + cli(); + while((skb = skb_dequeue(&card->statq))) { + + if ((skb->len + count) > len) + cnt = len - count; + else + cnt = skb->len; + + if (user) + copy_to_user(p, skb->data, cnt); + else + memcpy(p, skb->data, cnt); + + count += cnt; + p += cnt; + + if (cnt == skb->len) { + dev_kfree_skb(skb); + if (card->statq_entries > 0) + card->statq_entries--; + } else { + skb_pull(skb, cnt); + skb_queue_head(&card->statq, skb); + restore_flags(flags); + return count; + } + } + card->statq_entries = 0; + restore_flags(flags); + return count; } printk(KERN_ERR "eicon: if_readstatus called with invalid driverId!\n"); -#endif return 0; } @@ -861,14 +811,11 @@ len = skb->len; if (card) { - if (!card->flags & EICON_FLAGS_RUNNING) { - dev_kfree_skb(skb); + if (!card->flags & EICON_FLAGS_RUNNING) return -ENODEV; - } - if (!(chan = find_channel(card, channel))) { - dev_kfree_skb(skb); + if (!(chan = find_channel(card, channel))) return -ENODEV; - } + if (chan->fsm_state == EICON_STATE_ACTIVE) { #ifdef CONFIG_ISDN_TTY_FAX if (chan->l2prot == ISDN_PROTO_L2_FAX) { @@ -880,16 +827,115 @@ ret = idi_send_data(card, chan, ack, skb, 1); return (ret); } else { - dev_kfree_skb(skb); return -ENODEV; } } printk(KERN_ERR "eicon: if_sendbuf called with invalid driverId!\n"); - dev_kfree_skb(skb); return -ENODEV; } +/* jiftime() copied from HiSax */ +inline int +jiftime(char *s, long mark) +{ + s += 8; + + *s-- = '\0'; + *s-- = mark % 10 + '0'; + mark /= 10; + *s-- = mark % 10 + '0'; + mark /= 10; + *s-- = '.'; + *s-- = mark % 10 + '0'; + mark /= 10; + *s-- = mark % 6 + '0'; + mark /= 6; + *s-- = ':'; + *s-- = mark % 10 + '0'; + mark /= 10; + *s-- = mark % 10 + '0'; + return(8); +} + +void +eicon_putstatus(eicon_card * card, char * buf) +{ + ulong flags; + int count; + isdn_ctrl cmd; + u_char *p; + struct sk_buff *skb; + + if (!card) + return; + + save_flags(flags); + cli(); + count = strlen(buf); + skb = alloc_skb(count, GFP_ATOMIC); + if (!skb) { + restore_flags(flags); + printk(KERN_ERR "eicon: could not alloc skb in putstatus\n"); + return; + } + p = skb_put(skb, count); + memcpy(p, buf, count); + + skb_queue_tail(&card->statq, skb); + + if (card->statq_entries >= MAX_STATUS_BUFFER) { + if ((skb = skb_dequeue(&card->statq))) { + count -= skb->len; + dev_kfree_skb(skb); + } else + count = 0; + } else + card->statq_entries++; + + restore_flags(flags); + if (count) { + cmd.command = ISDN_STAT_STAVAIL; + cmd.driver = card->myid; + cmd.arg = count; + card->interface.statcallb(&cmd); + } +} + +/* + * Debug and Log + */ +void +eicon_log(eicon_card * card, int level, const char *fmt, ...) +{ + va_list args; + char Line[160]; + u_char *p; + + + if ((DebugVar & level) || (DebugVar & 256)) { + va_start(args, fmt); + + if (DebugVar & level) { + if (DebugVar & 256) { + /* log-buffer */ + p = Line; + p += jiftime(p, jiffies); + *p++ = 32; + p += vsprintf(p, fmt, args); + *p = 0; + eicon_putstatus(card, Line); + } else { + /* printk, syslogd */ + vsprintf(Line, fmt, args); + printk(KERN_DEBUG "%s", Line); + } + } + + va_end(args); + } +} + /* * Allocate a new card-struct, initialize it @@ -912,7 +958,7 @@ qloop = (Type == EICON_CTYPE_QUADRO)?2:0; for (i = 0; i <= qloop; i++) { if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) { - printk(KERN_WARNING + eicon_log(card, 1, "eicon: (%s) Could not allocate card-struct.\n", id); return; } @@ -921,6 +967,8 @@ skb_queue_head_init(&card->rcvq); skb_queue_head_init(&card->rackq); skb_queue_head_init(&card->sackq); + skb_queue_head_init(&card->statq); + card->statq_entries = 0; card->snd_tq.routine = (void *) (void *) eicon_transmit; card->snd_tq.data = card; card->rcv_tq.routine = (void *) (void *) eicon_rcv_dispatch; @@ -992,7 +1040,7 @@ p = p->next; } if (!p) { - printk(KERN_WARNING "eicon_alloccard: Quadro Master not found.\n"); + eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.\n"); kfree(card); return; } @@ -1014,7 +1062,7 @@ ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | ISDN_FEATURE_L2_MODEM | - /* ISDN_FEATURE_L2_FAX | */ + ISDN_FEATURE_L2_FAX | ISDN_FEATURE_L3_TRANSDSP | ISDN_FEATURE_L3_FAX; card->hwif.pci.card = (void *)card; @@ -1038,7 +1086,7 @@ ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038 | ISDN_FEATURE_L2_MODEM | - /* ISDN_FEATURE_L2_FAX | */ + ISDN_FEATURE_L2_FAX | ISDN_FEATURE_L3_TRANSDSP | ISDN_FEATURE_L3_FAX; card->hwif.pci.card = (void *)card; @@ -1087,13 +1135,13 @@ break; #endif default: - printk(KERN_WARNING "eicon_alloccard: Invalid type %d\n", Type); + eicon_log(card, 1, "eicon_alloccard: Invalid type %d\n", Type); kfree(card); return; } if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1) , GFP_KERNEL))) { - printk(KERN_WARNING + eicon_log(card, 1, "eicon: (%s) Could not allocate bch-struct.\n", id); kfree(card); return; @@ -1131,7 +1179,7 @@ case EICON_BUS_MCA: eicon_isa_printpar(&card->hwif.isa); break; -#endif +#endif /* CONFIG_MCA */ #endif case EICON_BUS_PCI: #if CONFIG_PCI @@ -1139,9 +1187,8 @@ break; #endif default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon_registercard: Illegal BUS type %d\n", + eicon_log(card, 1, + "eicon_registercard: Illegal BUS type %d\n", card->bus); return -1; } @@ -1170,7 +1217,7 @@ case EICON_BUS_ISA: #ifdef CONFIG_MCA case EICON_BUS_MCA: -#endif +#endif /* CONFIG_MCA */ eicon_isa_release(&card->hwif.isa); break; #endif @@ -1180,9 +1227,8 @@ break; #endif default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: Invalid BUS type %d\n", + eicon_log(card, 1, + "eicon: Invalid BUS type %d\n", card->bus); break; } @@ -1191,6 +1237,26 @@ static void eicon_freecard(eicon_card *card) { + int i; + struct sk_buff *skb; + + for(i = 0; i < (card->nchannels + 1); i++) { + while((skb = skb_dequeue(&card->bch[i].e.X))) + dev_kfree_skb(skb); + while((skb = skb_dequeue(&card->bch[i].e.R))) + dev_kfree_skb(skb); + } + while((skb = skb_dequeue(&card->sndq))) + dev_kfree_skb(skb); + while((skb = skb_dequeue(&card->rcvq))) + dev_kfree_skb(skb); + while((skb = skb_dequeue(&card->rackq))) + dev_kfree_skb(skb); + while((skb = skb_dequeue(&card->sackq))) + dev_kfree_skb(skb); + while((skb = skb_dequeue(&card->statq))) + dev_kfree_skb(skb); + eicon_clear_msn(card); kfree(card->bch); kfree(card); @@ -1236,9 +1302,8 @@ break; #endif default: - if (DebugVar & 1) - printk(KERN_WARNING - "eicon: addcard: Invalid BUS type %d\n", + printk(KERN_ERR + "eicon: addcard: Invalid BUS type %d\n", p->bus); } } else @@ -1250,7 +1315,7 @@ p = p->next; } else { /* registering failed, remove card from list, free memory */ - printk(KERN_WARNING + printk(KERN_ERR "eicon: Initialization of %s failed\n", p->interface.id); if (q) { @@ -1275,7 +1340,7 @@ #define eicon_init init_module #endif -int __init +int eicon_init(void) { int card_count = 0; @@ -1317,10 +1382,9 @@ printk(KERN_INFO "eicon: No MCA bus, ISDN-interfaces not probed.\n"); } else { - if (DebugVar & 8) - printk(KERN_DEBUG - "eicon_mca_find_card, irq=%d.\n", - irq); + eicon_log(card, 8, + "eicon_mca_find_card, irq=%d.\n", + irq); if (!eicon_mca_find_card(0, membase, irq, id)) card_count++; }; @@ -1361,12 +1425,14 @@ eicon_card *card = cards; eicon_card *last; while (card) { +#ifdef CONFIG_ISDN_DRV_EICON_ISA #ifdef CONFIG_MCA if (MCA_bus) { mca_mark_as_unused (card->mca_slot); mca_set_adapter_procfn(card->mca_slot, NULL, NULL); }; +#endif /* CONFIG_MCA */ #endif unregister_card(card); card = card->next; @@ -1382,7 +1448,6 @@ #else /* no module */ -#ifdef COMPAT_HAS_NEW_SETUP static int __init eicon_setup(char *line) { @@ -1391,12 +1456,6 @@ char *str; str = get_options(line, 4, ints); -#else -void __init -eicon_setup(char *str, int *ints) -{ - int i, argc; -#endif argc = ints[0]; i = 1; @@ -1424,13 +1483,9 @@ #else printk(KERN_INFO "Eicon ISDN active driver setup\n"); #endif -#ifdef COMPAT_HAS_NEW_SETUP return(1); } __setup("eicon=", eicon_setup); -#else -} -#endif #endif /* MODULE */ @@ -1456,10 +1511,9 @@ { int j, curr_slot = 0; - if (DebugVar & 8) - printk(KERN_DEBUG - "eicon_mca_find_card type: %d, membase: %#x, irq %d \n", - type, membase, irq); + eicon_log(card, 8, + "eicon_mca_find_card type: %d, membase: %#x, irq %d \n", + type, membase, irq); /* find a no-driver-assigned eicon card */ for (j=0; eicon_mca_adapters[j].adf_id != 0; j++) { @@ -1524,11 +1578,10 @@ int irq_array1[]={3,4,0,0,2,10,11,12}; adf_pos0 = mca_read_stored_pos(slot,2); - if (DebugVar & 8) - printk(KERN_DEBUG - "eicon_mca_probe irq=%d, membase=%d\n", - irq, - membase); + eicon_log(card, 8, + "eicon_mca_probe irq=%d, membase=%d\n", + irq, + membase); switch (a_idx) { case 0: /* P/2-Adapter (== PRI/S2M ? ) */ cards_membase= 0xC0000+((adf_pos0>>4)*0x4000); @@ -1542,7 +1595,7 @@ if (irq == -1) { irq = cards_irq; } else { - if (irq != irq) + if (irq != cards_irq) return ENODEV; }; cards_io= 0xC00 + ((adf_pos0>>4)*0x10); @@ -1575,7 +1628,7 @@ if (irq == -1) { irq = cards_irq; } else { - if (irq != irq) + if (irq != cards_irq) return ENODEV; }; type = 0; @@ -1591,8 +1644,12 @@ mca_mark_as_used(slot); cards->mca_slot = slot; /* card->io noch setzen oder ?? */ - if (DebugVar & 8) - printk("eicon_addcard: erfolgreich fuer slot: %d.\n", + cards->mca_io = cards_io; + cards->hwif.isa.io = cards_io; + /* reset card */ + outb_p(0,cards_io+1); + + eicon_log(card, 8, "eicon_addcard: successful for slot # %d.\n", cards->mca_slot+1); return 0 ; /* eicon_addcard hat eine Karte zugefuegt */ } else { diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/eicon/eicon_pci.c linux/drivers/isdn/eicon/eicon_pci.c --- v2.3.26/linux/drivers/isdn/eicon/eicon_pci.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/eicon/eicon_pci.c Sun Nov 7 16:34:00 1999 @@ -152,8 +152,8 @@ aparms->type = EICON_CTYPE_MAESTRA; aparms->irq = pdev->irq; - preg = get_pcibase(pdev, 2) & 0xfffffffc; - pcfg = get_pcibase(pdev, 1) & 0xffffff80; + preg = pdev->resource[ 2].start & 0xfffffffc; + pcfg = pdev->resource[ 1].start & 0xffffff80; #ifdef EICON_PCI_DEBUG printk(KERN_DEBUG "eicon_pci: irq=%d\n", aparms->irq); @@ -174,9 +174,9 @@ printk(KERN_INFO "Eicon: DIVA Server PRI/PCI detected !\n"); aparms->type = EICON_CTYPE_MAESTRAP; /*includes 9M,30M*/ aparms->irq = pdev->irq; - pram = get_pcibase(pdev, 0) & 0xfffff000; - preg = get_pcibase(pdev, 2) & 0xfffff000; - pcfg = get_pcibase(pdev, 4) & 0xfffff000; + pram = pdev->resource[ 0].start & 0xfffff000; + preg = pdev->resource[ 2].start & 0xfffff000; + pcfg = pdev->resource[ 4].start & 0xfffff000; #ifdef EICON_PCI_DEBUG printk(KERN_DEBUG "eicon_pci: irq=%d\n", aparms->irq); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/Makefile linux/drivers/isdn/hisax/Makefile --- v2.3.26/linux/drivers/isdn/hisax/Makefile Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/Makefile Sun Nov 7 16:34:00 1999 @@ -30,6 +30,8 @@ HFC_OBJ := HFC_2BDS0 := JADE_OBJ := +W6692_OBJ := + ifeq ($(CONFIG_HISAX_16_0),y) O_OBJS += teles0.o ISAC_OBJ := isac.o @@ -170,6 +172,10 @@ HSCX_OBJ := hscx.o endif +ifeq ($(CONFIG_HISAX_W6692),y) + W6692_OBJ := w6692.o +endif + # ifeq ($(CONFIG_HISAX_TESTEMU),y) # O_OBJS += testemu.o # endif @@ -179,7 +185,7 @@ endif O_OBJS += $(ISAC_OBJ) $(HSCX_OBJ) $(ISAR_OBJ) $(JADE_OBJ) -O_OBJS += $(HFC_OBJ) $(HFC_2BDS0) +O_OBJS += $(HFC_OBJ) $(HFC_2BDS0) $(W6692_OBJ) OX_OBJS += config.o O_TARGET := diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/amd7930.c linux/drivers/isdn/hisax/amd7930.c --- v2.3.26/linux/drivers/isdn/hisax/amd7930.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/amd7930.c Sun Nov 7 16:34:00 1999 @@ -749,8 +749,8 @@ return(0); } -int __init -setup_amd7930(struct IsdnCard *card) +__initfunc(int +setup_amd7930(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/arcofi.c linux/drivers/isdn/hisax/arcofi.c --- v2.3.26/linux/drivers/isdn/hisax/arcofi.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/hisax/arcofi.c Sun Nov 7 16:34:00 1999 @@ -154,8 +154,6 @@ cs->dc.isac.arcofitimer.function = (void *) arcofi_timer; cs->dc.isac.arcofitimer.data = (long) cs; init_timer(&cs->dc.isac.arcofitimer); -#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&cs->dc.isac.arcofi_wait); -#endif test_and_set_bit(HW_ARCOFI, &cs->HW_Flags); } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/asuscom.c linux/drivers/isdn/hisax/asuscom.c --- v2.3.26/linux/drivers/isdn/hisax/asuscom.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/asuscom.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: asuscom.c,v 1.7 1999/07/12 21:04:53 keil Exp $ +/* $Id: asuscom.c,v 1.8 1999/09/04 06:20:05 keil Exp $ * asuscom.c low level stuff for ASUSCOM NETWORK INC. ISDNLink cards * @@ -8,6 +8,9 @@ * * * $Log: asuscom.c,v $ + * Revision 1.8 1999/09/04 06:20:05 keil + * Changes from kernel set_current_state() + * * Revision 1.7 1999/07/12 21:04:53 keil * fix race in IRQ handling * added watchdog for lost IRQs @@ -39,7 +42,7 @@ extern const char *CardType[]; -const char *Asuscom_revision = "$Revision: 1.7 $"; +const char *Asuscom_revision = "$Revision: 1.8 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -288,13 +291,13 @@ byteout(cs->hw.asus.adr, ASUS_RESET); /* Reset On */ save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); if (cs->subtyp == ASUS_IPAC) writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_POTA2, 0x0); else byteout(cs->hw.asus.adr, 0); /* Reset Off */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); if (cs->subtyp == ASUS_IPAC) { writereg(cs->hw.asus.adr, cs->hw.asus.isac, IPAC_CONF, 0x0); @@ -326,8 +329,8 @@ return(0); } -int __init -setup_asuscom(struct IsdnCard *card) +__initfunc(int +setup_asuscom(struct IsdnCard *card)) { int bytecnt; struct IsdnCardState *cs = card->cs; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/avm_a1.c linux/drivers/isdn/hisax/avm_a1.c --- v2.3.26/linux/drivers/isdn/hisax/avm_a1.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/avm_a1.c Sun Nov 7 16:34:00 1999 @@ -227,8 +227,8 @@ return(0); } -int __init -setup_avm_a1(struct IsdnCard *card) +__initfunc(int +setup_avm_a1(struct IsdnCard *card)) { u_char val; struct IsdnCardState *cs = card->cs; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/avm_a1p.c linux/drivers/isdn/hisax/avm_a1p.c --- v2.3.26/linux/drivers/isdn/hisax/avm_a1p.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/avm_a1p.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: avm_a1p.c,v 2.4 1999/07/12 21:04:55 keil Exp $ +/* $Id: avm_a1p.c,v 2.5 1999/09/01 08:26:34 calle Exp $ * * avm_a1p.c low level stuff for the following AVM cards: * A1 PCMCIA @@ -8,6 +8,9 @@ * Author Carsten Paeth (calle@calle.in-berlin.de) * * $Log: avm_a1p.c,v $ + * Revision 2.5 1999/09/01 08:26:34 calle + * Patch from Daniel Beichl to make A1 PCMCIA work again. + * * Revision 2.4 1999/07/12 21:04:55 keil * fix race in IRQ handling * added watchdog for lost IRQs @@ -71,7 +74,7 @@ #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) -static const char *avm_revision = "$Revision: 2.4 $"; +static const char *avm_revision = "$Revision: 2.5 $"; static inline u_char ReadISAC(struct IsdnCardState *cs, u_char offset) @@ -245,6 +248,7 @@ return 0; case CARD_INIT: + byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_TDISABLE|ASL0_W_TRESET|ASL0_W_IRQENABLE); clear_pending_isac_ints(cs); clear_pending_hscx_ints(cs); inithscxisac(cs, 1); @@ -262,8 +266,8 @@ return 0; } -int __init -setup_avm_a1_pcmcia(struct IsdnCard *card) +__initfunc(int +setup_avm_a1_pcmcia(struct IsdnCard *card)) { u_char model, vers; struct IsdnCardState *cs = card->cs; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/avm_pci.c linux/drivers/isdn/hisax/avm_pci.c --- v2.3.26/linux/drivers/isdn/hisax/avm_pci.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/avm_pci.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: avm_pci.c,v 1.11 1999/08/11 21:01:18 keil Exp $ +/* $Id: avm_pci.c,v 1.12 1999/09/04 06:20:05 keil Exp $ * avm_pci.c low level stuff for AVM Fritz!PCI and ISA PnP isdn cards * Thanks to AVM, Berlin for informations @@ -7,6 +7,9 @@ * * * $Log: avm_pci.c,v $ + * Revision 1.12 1999/09/04 06:20:05 keil + * Changes from kernel set_current_state() + * * Revision 1.11 1999/08/11 21:01:18 keil * new PCI codefix * @@ -50,13 +53,10 @@ #include "isac.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif #include extern const char *CardType[]; -static const char *avm_pci_rev = "$Revision: 1.11 $"; +static const char *avm_pci_rev = "$Revision: 1.12 $"; #define AVM_FRITZ_PCI 1 #define AVM_FRITZ_PNP 2 @@ -482,7 +482,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hdlc.count); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->hw.hdlc.count = 0; bcs->tx_skb = NULL; } @@ -609,7 +609,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -734,11 +734,11 @@ save_flags(flags); sti(); outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2); outb(AVM_STATUS1_ENA_IOM | cs->irq, cs->hw.avm.cfg_reg + 3); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ printk(KERN_INFO "AVM PCI/PnP: S1 %x\n", inb(cs->hw.avm.cfg_reg + 3)); } @@ -773,14 +773,10 @@ return(0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_avm __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif -int __init -setup_avm_pcipnp(struct IsdnCard *card) +__initfunc(int +setup_avm_pcipnp(struct IsdnCard *card)) { u_int val, ver; struct IsdnCardState *cs = card->cs; @@ -796,7 +792,6 @@ cs->subtyp = AVM_FRITZ_PNP; } else { #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "FritzPCI: no PCI bus present\n"); return(0); @@ -808,7 +803,7 @@ printk(KERN_WARNING "FritzPCI: No IRQ for PCI card found\n"); return(0); } - cs->hw.avm.cfg_reg = get_pcibase(dev_avm, 1) & + cs->hw.avm.cfg_reg = dev_avm->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK; if (!cs->hw.avm.cfg_reg) { printk(KERN_WARNING "FritzPCI: No IO-Adr for PCI card found\n"); @@ -819,36 +814,6 @@ printk(KERN_WARNING "FritzPCI: No PCI card found\n"); return(0); } -#else - for (; pci_index < 255; pci_index++) { - unsigned char pci_bus, pci_device_fn; - unsigned int ioaddr; - unsigned char irq; - - if (pcibios_find_device (PCI_VENDOR_AVM, - PCI_FRITZPCI_ID, pci_index, - &pci_bus, &pci_device_fn) != 0) { - continue; - } - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &irq); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &ioaddr); - cs->irq = irq; - cs->hw.avm.cfg_reg = ioaddr & PCI_BASE_ADDRESS_IO_MASK; - if (!cs->hw.avm.cfg_reg) { - printk(KERN_WARNING "FritzPCI: No IO-Adr for PCI card found\n"); - return(0); - } - cs->subtyp = AVM_FRITZ_PCI; - break; - } - if (pci_index == 255) { - printk(KERN_WARNING "FritzPCI: No PCI card found\n"); - return(0); - } - pci_index++; -#endif /* COMPAT_HAS_NEW_PCI */ cs->irq_flags |= SA_SHIRQ; #else printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/bkm_a4t.c linux/drivers/isdn/hisax/bkm_a4t.c --- v2.3.26/linux/drivers/isdn/hisax/bkm_a4t.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/bkm_a4t.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: bkm_a4t.c,v 1.7 1999/08/22 20:26:55 calle Exp $ +/* $Id: bkm_a4t.c,v 1.8 1999/09/04 06:20:05 keil Exp $ * bkm_a4t.c low level stuff for T-Berkom A4T * derived from the original file sedlbauer.c * derived from the original file niccy.c @@ -7,6 +7,9 @@ * Author Roland Klabunde (R.Klabunde@Berkom.de) * * $Log: bkm_a4t.c,v $ + * Revision 1.8 1999/09/04 06:20:05 keil + * Changes from kernel set_current_state() + * * Revision 1.7 1999/08/22 20:26:55 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -42,13 +45,10 @@ #include "isdnl1.h" #include "bkm_ax.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif extern const char *CardType[]; -const char *bkm_a4t_revision = "$Revision: 1.7 $"; +const char *bkm_a4t_revision = "$Revision: 1.8 $"; static inline u_char @@ -231,11 +231,11 @@ sti(); /* Issue the I20 soft reset */ pI20_Regs->i20SysControl = 0xFF; /* all in */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Remove the soft reset */ pI20_Regs->i20SysControl = sysRESET | 0xFF; - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Set our configuration */ pI20_Regs->i20SysControl = sysRESET | sysCFG; @@ -246,14 +246,14 @@ g_A4T_ISAC_RES | g_A4T_JADE_BOOTR | g_A4T_ISAR_BOOTR; - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Remove RESET state from ISDN */ pI20_Regs->i20GuestControl &= ~(g_A4T_ISAC_RES | g_A4T_JADE_RES | g_A4T_ISAR_RES); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); restore_flags(flags); } @@ -288,23 +288,16 @@ return (0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_a4t __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif -int __init - setup_bkm_a4t(struct IsdnCard *card) +__initfunc(int + setup_bkm_a4t(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; u_int pci_memaddr = 0, found = 0; I20_REGISTER_FILE *pI20_Regs; #if CONFIG_PCI -#ifndef COMPAT_HAS_NEW_PCI - u_char pci_bus, pci_device_fn, pci_irq = 0; -#endif #endif strcpy(tmp, bkm_a4t_revision); @@ -315,7 +308,6 @@ return (0); #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "bkm_a4t: no PCI bus present\n"); return (0); @@ -327,40 +319,14 @@ &sub_sys_id); if (sub_sys_id == ((A4T_SUBSYS_ID << 16) | A4T_SUBVEN_ID)) { found = 1; - pci_memaddr = get_pcibase(dev_a4t, 0); + pci_memaddr = dev_a4t->resource[ 0].start; cs->irq = dev_a4t->irq; } } -#else - for (; pci_index < 0xff; pci_index++) { - if (pcibios_find_device(I20_VENDOR_ID, - I20_DEVICE_ID, - pci_index, - &pci_bus, - &pci_device_fn) == PCIBIOS_SUCCESSFUL) { - u_int sub_sys_id = 0; - - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_SUBSYSTEM_VENDOR_ID, &sub_sys_id); - if (sub_sys_id == ((A4T_SUBSYS_ID << 16) | A4T_SUBVEN_ID)) { - found = 1; - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - cs->irq = pci_irq; - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_memaddr); - break; - } - } - } -#endif /* COMPAT_HAS_NEW_PCI */ if (!found) { printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]); return (0); } -#ifndef COMPAT_HAS_NEW_PCI - pci_index++; -#endif if (!cs->irq) { /* IRQ range check ?? */ printk(KERN_WARNING "HiSax: %s: No IRQ\n", CardType[card->typ]); return (0); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/bkm_a8.c linux/drivers/isdn/hisax/bkm_a8.c --- v2.3.26/linux/drivers/isdn/hisax/bkm_a8.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/bkm_a8.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: bkm_a8.c,v 1.7 1999/08/22 20:26:58 calle Exp $ +/* $Id: bkm_a8.c,v 1.8 1999/09/04 06:20:05 keil Exp $ * bkm_a8.c low level stuff for Scitel Quadro (4*S0, passive) * derived from the original file sedlbauer.c * derived from the original file niccy.c @@ -7,6 +7,9 @@ * Author Roland Klabunde (R.Klabunde@Berkom.de) * * $Log: bkm_a8.c,v $ + * Revision 1.8 1999/09/04 06:20:05 keil + * Changes from kernel set_current_state() + * * Revision 1.7 1999/08/22 20:26:58 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -41,15 +44,12 @@ #include "isdnl1.h" #include "bkm_ax.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif #define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ extern const char *CardType[]; -const char sct_quadro_revision[] = "$Revision: 1.7 $"; +const char sct_quadro_revision[] = "$Revision: 1.8 $"; /* To survive the startup phase */ typedef struct { @@ -298,13 +298,13 @@ save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); /* Remove the soft reset */ wordout(cs->hw.ax.plx_adr + 0x50, (wordin(cs->hw.ax.plx_adr + 0x50) | 4)); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10 * HZ) / 1000); restore_flags(flags); } @@ -341,14 +341,10 @@ return (0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_a8 __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif -int __init - setup_sct_quadro(struct IsdnCard *card) +__initfunc(int + setup_sct_quadro(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -372,7 +368,6 @@ printk(KERN_WARNING "HiSax: %s: Invalid subcontroller in configuration, default to 1\n", CardType[card->typ]); #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "bkm_a4t: no PCI bus present\n"); return (0); @@ -384,46 +379,18 @@ &sub_sys_id); if (sub_sys_id == ((SCT_SUBSYS_ID << 16) | SCT_SUBVEN_ID)) { found = 1; - pci_ioaddr1 = get_pcibase(dev_a8, 1); + pci_ioaddr1 = dev_a8->resource[ 1].start; pci_irq = dev_a8->irq; pci_bus = dev_a8->bus->number; pci_device_fn = dev_a8->devfn; } } -#else - for (; pci_index < 0xff; pci_index++) { - if (pcibios_find_device( - PLX_VENDOR_ID, - PLX_DEVICE_ID, - pci_index, - &pci_bus, - &pci_device_fn) == PCIBIOS_SUCCESSFUL) { - - u_int sub_sys_id = 0; - - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_SUBSYSTEM_VENDOR_ID, &sub_sys_id); - if (sub_sys_id == ((SCT_SUBSYS_ID << 16) | SCT_SUBVEN_ID)) { - found = 1; - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &pci_ioaddr1); - cs->irq = pci_irq; - break; - } - } - } -#endif /* COMPAT_HAS_NEW_PCI */ if (!found) { printk(KERN_WARNING "HiSax: %s (%s): Card not found\n", CardType[card->typ], sct_quadro_subtypes[cs->subtyp]); return (0); } -#ifndef COMPAT_HAS_NEW_PCI - pci_index++; /* need for more as one card */ -#endif if (!pci_irq) { /* IRQ range check ?? */ printk(KERN_WARNING "HiSax: %s (%s): No IRQ\n", CardType[card->typ], @@ -445,9 +412,7 @@ pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; pcibios_write_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, pci_ioaddr1); -#ifdef COMPAT_HAS_NEW_PCI - get_pcibase(dev_a8, 1) = pci_ioaddr1; -#endif /* COMPAT_HAS_NEW_PCI */ + dev_a8->resource[ 1].start = pci_ioaddr1; } /* End HACK */ #endif diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c --- v2.3.26/linux/drivers/isdn/hisax/callc.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/isdn/hisax/callc.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: callc.c,v 2.34 1999/08/25 20:02:34 werner Exp $ +/* $Id: callc.c,v 2.39 1999/10/14 20:25:28 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * based on the teles driver from Jan den Ouden @@ -11,6 +11,21 @@ * Fritz Elfert * * $Log: callc.c,v $ + * Revision 2.39 1999/10/14 20:25:28 keil + * add a statistic for error monitoring + * + * Revision 2.38 1999/10/11 22:16:27 keil + * Suspend/Resume is possible without explicit ID too + * + * Revision 2.37 1999/09/20 19:49:47 keil + * Fix wrong init of PStack + * + * Revision 2.36 1999/09/20 12:13:13 keil + * Fix hang if no protocol was selected + * + * Revision 2.35 1999/09/04 06:20:05 keil + * Changes from kernel set_current_state() + * * Revision 2.34 1999/08/25 20:02:34 werner * Changed return values for stat_icall(w) from 3->4 and 4->5 because of conflicts * with existing software definitions. (PtP incomplete called party number) @@ -145,15 +160,10 @@ #include "../avmb1/capicmd.h" /* this should be moved in a common place */ #ifdef MODULE -#ifdef COMPAT_HAS_NEW_SYMTAB #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module)) -#else -extern long mod_use_count_; -#define MOD_USE_COUNT mod_use_count_ -#endif /* COMPAT_HAS_NEW_SYMTAB */ #endif /* MODULE */ -const char *lli_revision = "$Revision: 2.34 $"; +const char *lli_revision = "$Revision: 2.39 $"; extern struct IsdnCard cards[]; extern int nrcards; @@ -209,7 +219,7 @@ int ret=0; while ((skb = skb_dequeue(q))) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); ret++; } return(ret); @@ -1122,12 +1132,37 @@ } static void +dummy_pstack(struct PStack *st, int pr, void *arg) { + printk(KERN_WARNING"call to dummy_pstack pr=%04x arg %lx\n", pr, (long)arg); +} + +static void +init_PStack(struct PStack **stp) { + *stp = kmalloc(sizeof(struct PStack), GFP_ATOMIC); + (*stp)->next = NULL; + (*stp)->l1.l1l2 = dummy_pstack; + (*stp)->l1.l1hw = dummy_pstack; + (*stp)->l1.l1tei = dummy_pstack; + (*stp)->l2.l2tei = dummy_pstack; + (*stp)->l2.l2l1 = dummy_pstack; + (*stp)->l2.l2l3 = dummy_pstack; + (*stp)->l3.l3l2 = dummy_pstack; + (*stp)->l3.l3ml3 = dummy_pstack; + (*stp)->l3.l3l4 = dummy_pstack; + (*stp)->lli.l4l3 = dummy_pstack; + (*stp)->ma.layer = dummy_pstack; +} + +static void init_d_st(struct Channel *chanp) { - struct PStack *st = chanp->d_st; + struct PStack *st; struct IsdnCardState *cs = chanp->cs; char tmp[16]; + init_PStack(&chanp->d_st); + st = chanp->d_st; + st->next = NULL; HiSax_addlist(cs, st); setstack_HiSax(st, cs); st->l2.sap = 0; @@ -1166,28 +1201,6 @@ } static void -dummy_pstack(struct PStack *st, int pr, void *arg) { - printk(KERN_WARNING"call to dummy_pstack pr=%04x arg %lx\n", pr, (long)arg); -} - -static void -init_PStack(struct PStack **stp) { - *stp = kmalloc(sizeof(struct PStack), GFP_ATOMIC); - (*stp)->next = NULL; - (*stp)->l1.l1l2 = dummy_pstack; - (*stp)->l1.l1hw = dummy_pstack; - (*stp)->l1.l1tei = dummy_pstack; - (*stp)->l2.l2tei = dummy_pstack; - (*stp)->l2.l2l1 = dummy_pstack; - (*stp)->l2.l2l3 = dummy_pstack; - (*stp)->l3.l3l2 = dummy_pstack; - (*stp)->l3.l3ml3 = dummy_pstack; - (*stp)->l3.l3l4 = dummy_pstack; - (*stp)->lli.l4l3 = dummy_pstack; - (*stp)->ma.layer = dummy_pstack; -} - -static void init_chan(int chan, struct IsdnCardState *csta) { struct Channel *chanp = csta->channel + chan; @@ -1209,10 +1222,6 @@ FsmInitTimer(&chanp->fi, &chanp->dial_timer); FsmInitTimer(&chanp->fi, &chanp->drel_timer); if (!chan || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) { - init_PStack(&chanp->d_st); - if (chan) - csta->channel->d_st->next = chanp->d_st; - chanp->d_st->next = NULL; init_d_st(chanp); } else { chanp->d_st = csta->channel->d_st; @@ -1289,7 +1298,7 @@ if (chanp->data_open) chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb); else { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } break; case (DL_ESTABLISH | INDICATION): @@ -1319,7 +1328,7 @@ chanp->cs->iif.rcvcallb_skb(chanp->cs->myid, chanp->chan, skb); else { link_debug(chanp, 0, "channel not open"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } break; case (PH_ACTIVATE | INDICATION): @@ -1426,7 +1435,7 @@ switch (pr) { case (DL_DATA | REQUEST): link_debug(chanp, 0, "leased line d-channel DATA"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); break; case (DL_ESTABLISH | REQUEST): st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL); @@ -1450,7 +1459,7 @@ switch (pr) { case (PH_DATA | INDICATION): link_debug(chanp, 0, "leased line d-channel DATA"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); break; case (PH_ACTIVATE | INDICATION): case (PH_ACTIVATE | CONFIRM): @@ -1475,11 +1484,6 @@ } static void -channel_report(struct Channel *chanp) -{ -} - -static void distr_debug(struct IsdnCardState *csta, int debugflags) { int i; @@ -1512,7 +1516,6 @@ { char *t = tmpbuf; - t += sprintf(tmpbuf, "%d CAPIMSG", chanp->chan); t += QuickHex(t, (u_char *)cm, (cm->Length>50)? 50: cm->Length); t--; *t= 0; @@ -1529,20 +1532,16 @@ return; switch(cm->para[3]) { case 4: /* Suspend */ - if (cm->para[5]) { - strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1); - FsmEvent(&chanp->fi, EV_SUSPEND, cm); - } + strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1); + FsmEvent(&chanp->fi, EV_SUSPEND, cm); break; case 5: /* Resume */ - if (cm->para[5]) { - strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1); - if (chanp->fi.state == ST_NULL) { - FsmEvent(&chanp->fi, EV_RESUME, cm); - } else { - FsmDelTimer(&chanp->dial_timer, 72); - FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73); - } + strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1); + if (chanp->fi.state == ST_NULL) { + FsmEvent(&chanp->fi, EV_RESUME, cm); + } else { + FsmDelTimer(&chanp->dial_timer, 72); + FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73); } break; } @@ -1694,9 +1693,8 @@ case (ISDN_CMD_IOCTL): switch (ic->arg) { case (0): - HiSax_reportcard(csta->cardnr); - for (i = 0; i < 2; i++) - channel_report(&csta->channel[i]); + num = *(unsigned int *) ic->parm.num; + HiSax_reportcard(csta->cardnr, num); break; case (1): num = *(unsigned int *) ic->parm.num; @@ -1904,7 +1902,7 @@ chanp->bcs->tx_cnt += len; st->l2.l2l1(st, PH_DATA | REQUEST, nskb); } - idev_kfree_skb(skb, FREE_WRITE); + dev_kfree_skb(skb); } else len = 0; restore_flags(flags); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c --- v2.3.26/linux/drivers/isdn/hisax/config.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/config.c Sun Nov 7 16:34:00 1999 @@ -1,10 +1,32 @@ -/* $Id: config.c,v 2.33 1999/08/30 11:57:52 keil Exp $ +/* $Id: config.c,v 2.40 1999/10/30 13:09:45 keil Exp $ * Author Karsten Keil (keil@isdn4linux.de) * based on the teles driver from Jan den Ouden * * * $Log: config.c,v $ + * Revision 2.40 1999/10/30 13:09:45 keil + * Version 3.3c + * + * Revision 2.39 1999/10/16 14:44:45 keil + * Fix module parm if only NICCY was selected + * + * Revision 2.38 1999/10/14 20:25:28 keil + * add a statistic for error monitoring + * + * Revision 2.37 1999/09/20 12:11:08 keil + * Fix hang if no protocol was selected + * + * Revision 2.36 1999/09/07 05:43:58 werner + * + * Added io as parameter 0 for HFC-PCI cards, if manual selection needed. + * + * Revision 2.35 1999/09/04 06:35:09 keil + * Winbond W6692 support + * + * Revision 2.34 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 2.33 1999/08/30 11:57:52 keil * Fix broken avm pcmcia * @@ -126,10 +148,7 @@ #include #include #include -#include -#ifdef COMPAT_HAS_NEW_SETUP #include -#endif #include "hisax.h" #include #include @@ -182,6 +201,8 @@ * 33 Scitel Quadro p0=subcontroller (4*S0, subctrl 1...4) * 34 Gazel ISDN cards * 35 HFC 2BDS0 PCI none + * 36 Winbond 6692 PCI none + * * protocol can be either ISDN_PTYPE_EURO or ISDN_PTYPE_1TR6 or ISDN_PTYPE_NI1 * * @@ -195,7 +216,7 @@ "Compaq ISA", "NETjet", "Teles PCI", "Sedlbauer Speed Star (PCMCIA)", "AMD 7930", "NICCY", "S0Box", "AVM A1 (PCMCIA)", "AVM Fritz PnP/PCI", "Sedlbauer Speed Fax +", "Siemens I-Surf", "Acer P10", "HST Saphir", - "Telekom A4T", "Scitel Quadro", "Gazel", "HFC 2BDS0 PCI", + "Telekom A4T", "Scitel Quadro", "Gazel", "HFC 2BDS0 PCI", "Winbond 6692", }; void HiSax_closecard(int cardnr); @@ -204,15 +225,7 @@ #define DEFAULT_CARD ISDN_CTYPE_ELSA #define DEFAULT_CFG {0,0,0,0} int elsa_init_pcmcia(void*, int, int*, int); -#ifdef COMPAT_HAS_NEW_SYMTAB EXPORT_SYMBOL(elsa_init_pcmcia); -#else -static struct symbol_table hisax_syms_elsa = { -#include - X(elsa_init_pcmcia), -#include -}; -#endif /* COMPAT_HAS_NEW_SYMTAB */ #endif /* CONFIG_HISAX_ELSA */ #ifdef CONFIG_HISAX_AVM_A1 @@ -228,17 +241,8 @@ #define DEFAULT_CARD ISDN_CTYPE_A1_PCMCIA #define DEFAULT_CFG {11,0x170,0,0} int avm_a1_init_pcmcia(void*, int, int*, int); -#ifdef COMPAT_HAS_NEW_SYMTAB EXPORT_SYMBOL(avm_a1_init_pcmcia); EXPORT_SYMBOL(HiSax_closecard); -#else -static struct symbol_table hisax_syms_avm_a1= { -#include - X(avm_a1_init_pcmcia), - X(HiSax_closecard), -#include -}; -#endif /* COMPAT_HAS_NEW_SYMTAB */ #endif /* CONFIG_HISAX_AVM_A1_PCMCIA */ #ifdef CONFIG_HISAX_FRITZPCI @@ -310,15 +314,7 @@ #define DEFAULT_CARD ISDN_CTYPE_SEDLBAUER #define DEFAULT_CFG {11,0x270,0,0} int sedl_init_pcmcia(void*, int, int*, int); -#ifdef COMPAT_HAS_NEW_SYMTAB EXPORT_SYMBOL(sedl_init_pcmcia); -#else -static struct symbol_table hisax_syms_sedl= { -#include - X(sedl_init_pcmcia), -#include -}; -#endif /* COMPAT_HAS_NEW_SYMTAB */ #endif /* CONFIG_HISAX_SEDLBAUER */ #ifdef CONFIG_HISAX_SPORTSTER @@ -406,6 +402,13 @@ #define DEFAULT_CFG {15,0x180,0,0} #endif +#ifdef CONFIG_HISAX_W6692 +#undef DEFAULT_CARD +#undef DEFAULT_CFG +#define DEFAULT_CARD ISDN_CTYPE_W6692 +#define DEFAULT_CFG {0,0,0,0} +#endif + #ifdef CONFIG_HISAX_1TR6 #define DEFAULT_PROTO ISDN_PTYPE_1TR6 #define DEFAULT_PROTO_NAME "1TR6" @@ -483,7 +486,6 @@ {0, 0, 0, 0, 0, 0, 0, 0}; static char *id HISAX_INITDATA = HiSaxID; -#ifdef COMPAT_HAS_NEW_SYMTAB MODULE_AUTHOR("Karsten Keil"); MODULE_PARM(type, "1-8i"); MODULE_PARM(protocol, "1-8i"); @@ -491,11 +493,10 @@ MODULE_PARM(irq, "1-8i"); MODULE_PARM(mem, "1-8i"); MODULE_PARM(id, "s"); -#ifdef CONFIG_HISAX_16_3 /* For Creatix/Teles PnP */ +#ifdef IO0_IO1 MODULE_PARM(io0, "1-8i"); MODULE_PARM(io1, "1-8i"); -#endif /* CONFIG_HISAX_16_3 */ -#endif /* COMPAT_HAS_NEW_SYMTAB */ +#endif /* IO0_IO1 */ #endif /* MODULE */ int nrcards; @@ -528,9 +529,9 @@ printk(KERN_INFO "HiSax: Linux Driver for passive ISDN cards\n"); #ifdef MODULE - printk(KERN_INFO "HiSax: Version 3.3a (module)\n"); + printk(KERN_INFO "HiSax: Version 3.3c (module)\n"); #else - printk(KERN_INFO "HiSax: Version 3.3a (kernel)\n"); + printk(KERN_INFO "HiSax: Version 3.3c (kernel)\n"); #endif strcpy(tmp, l1_revision); printk(KERN_INFO "HiSax: Layer1 Revision %s\n", HiSax_getrev(tmp)); @@ -560,7 +561,6 @@ #ifdef MODULE #define HiSax_init init_module #else -#ifdef COMPAT_HAS_NEW_SETUP #define MAX_ARG (HISAX_MAX_CARDS*5) static int __init HiSax_setup(char *line) @@ -570,12 +570,6 @@ char *str; str = get_options(line, MAX_ARG, ints); -#else -void __init -HiSax_setup(char *str, int *ints) -{ - int i, j, argc; -#endif argc = ints[0]; printk(KERN_DEBUG"HiSax_setup: argc(%d) str(%s)\n", argc, str); i = 0; @@ -615,14 +609,10 @@ strcpy(HiSaxID, "HiSax"); HiSax_id = HiSaxID; } -#ifdef COMPAT_HAS_NEW_SETUP return(1); } __setup("hisax=", HiSax_setup); -#else -} -#endif /* COMPAT_HAS_NEW_SETUP */ #endif /* MODULES */ #if CARD_TELES0 @@ -717,11 +707,11 @@ extern int setup_testemu(struct IsdnCard *card); #endif -#if CARD_BKM_A4T +#if CARD_BKM_A4T extern int setup_bkm_a4t(struct IsdnCard *card); #endif -#if CARD_SCT_QUADRO +#if CARD_SCT_QUADRO extern int setup_sct_quadro(struct IsdnCard *card); #endif @@ -729,6 +719,10 @@ extern int setup_gazel(struct IsdnCard *card); #endif +#if CARD_W6692 +extern int setup_w6692(struct IsdnCard *card); +#endif + /* * Find card with given driverId */ @@ -967,7 +961,7 @@ csta->rcvbuf = NULL; } if (csta->tx_skb) { - idev_kfree_skb(csta->tx_skb, FREE_WRITE); + dev_kfree_skb(csta->tx_skb); csta->tx_skb = NULL; } if (csta->DC_Close != NULL) { @@ -1000,7 +994,7 @@ while (cnt) { cs->cardmsg(cs, CARD_INIT, NULL); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); /* Timeout 10ms */ schedule_timeout((10*HZ)/1000); restore_flags(flags); @@ -1254,6 +1248,11 @@ ret = setup_gazel(card); break; #endif +#if CARD_W6692 + case ISDN_CTYPE_W6692: + ret = setup_w6692(card); + break; +#endif default: printk(KERN_WARNING "HiSax: Support for %s Card not selected\n", @@ -1357,6 +1356,7 @@ kfree((void *) cards[i].cs); cards[i].cs = NULL; HiSax_shiftcards(i); + nrcards--; } } return foundcards; @@ -1387,12 +1387,9 @@ } void -HiSax_reportcard(int cardnr) +HiSax_reportcard(int cardnr, int sel) { struct IsdnCardState *cs = cards[cardnr].cs; - struct PStack *stptr; - struct l3_process *pc; - int j, i = 1; printk(KERN_DEBUG "HiSax: reportcard No %d\n", cardnr + 1); printk(KERN_DEBUG "HiSax: Type %s\n", CardType[cs->typ]); @@ -1400,50 +1397,38 @@ printk(KERN_DEBUG "HiSax: HiSax_reportcard address 0x%lX\n", (ulong) & HiSax_reportcard); printk(KERN_DEBUG "HiSax: cs 0x%lX\n", (ulong) cs); - printk(KERN_DEBUG "HiSax: HW_Flags %x bc0 flg %x bc0 flg %x\n", + printk(KERN_DEBUG "HiSax: HW_Flags %x bc0 flg %x bc1 flg %x\n", cs->HW_Flags, cs->bcs[0].Flag, cs->bcs[1].Flag); printk(KERN_DEBUG "HiSax: bcs 0 mode %d ch%d\n", cs->bcs[0].mode, cs->bcs[0].channel); printk(KERN_DEBUG "HiSax: bcs 1 mode %d ch%d\n", cs->bcs[1].mode, cs->bcs[1].channel); - printk(KERN_DEBUG "HiSax: cs setstack_d 0x%lX\n", (ulong) cs->setstack_d); - printk(KERN_DEBUG "HiSax: cs stl 0x%lX\n", (ulong) & (cs->stlist)); - stptr = cs->stlist; - while (stptr != NULL) { - printk(KERN_DEBUG "HiSax: dst%d 0x%lX\n", i, (ulong) stptr); - printk(KERN_DEBUG "HiSax: dst%d stp 0x%lX\n", i, (ulong) stptr->l1.stlistp); - printk(KERN_DEBUG "HiSax: dst%d l1.l1hw 0x%lX\n", i, (ulong) stptr->l1.l1hw); - printk(KERN_DEBUG "HiSax: tei %d sapi %d\n", - stptr->l2.tei, stptr->l2.sap); - printk(KERN_DEBUG "HiSax: man 0x%lX\n", (ulong) stptr->ma.layer); - pc = stptr->l3.proc; - while (pc) { - printk(KERN_DEBUG "HiSax: l3proc %x 0x%lX\n", pc->callref, - (ulong) pc); - printk(KERN_DEBUG "HiSax: state %d st 0x%lX chan 0x%lX\n", - pc->state, (ulong) pc->st, (ulong) pc->chan); - pc = pc->next; - } - stptr = stptr->next; - i++; - } - for (j = 0; j < 2; j++) { - printk(KERN_DEBUG "HiSax: ch%d 0x%lX\n", j, - (ulong) & cs->channel[j]); - stptr = cs->channel[j].b_st; - i = 1; - while (stptr != NULL) { - printk(KERN_DEBUG "HiSax: b_st%d 0x%lX\n", i, (ulong) stptr); - printk(KERN_DEBUG "HiSax: man 0x%lX\n", (ulong) stptr->ma.layer); - stptr = stptr->next; - i++; - } +#ifdef ERROR_STATISTIC + printk(KERN_DEBUG "HiSax: dc errors(rx,crc,tx) %d,%d,%d\n", + cs->err_rx, cs->err_crc, cs->err_tx); + printk(KERN_DEBUG "HiSax: bc0 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n", + cs->bcs[0].err_inv, cs->bcs[0].err_rdo, cs->bcs[0].err_crc, cs->bcs[0].err_tx); + printk(KERN_DEBUG "HiSax: bc1 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n", + cs->bcs[1].err_inv, cs->bcs[1].err_rdo, cs->bcs[1].err_crc, cs->bcs[1].err_tx); + if (sel == 99) { + cs->err_rx = 0; + cs->err_crc = 0; + cs->err_tx = 0; + cs->bcs[0].err_inv = 0; + cs->bcs[0].err_rdo = 0; + cs->bcs[0].err_crc = 0; + cs->bcs[0].err_tx = 0; + cs->bcs[1].err_inv = 0; + cs->bcs[1].err_rdo = 0; + cs->bcs[1].err_crc = 0; + cs->bcs[1].err_tx = 0; } +#endif } -int __init -HiSax_init(void) +__initfunc(int +HiSax_init(void)) { int i; @@ -1452,27 +1437,18 @@ #ifdef CONFIG_HISAX_ELSA if (type[0] == ISDN_CTYPE_ELSA_PCMCIA) { /* we have exported and return in this case */ -#ifndef COMPAT_HAS_NEW_SYMTAB - register_symtab(&hisax_syms_elsa); -#endif return 0; } #endif #ifdef CONFIG_HISAX_SEDLBAUER if (type[0] == ISDN_CTYPE_SEDLBAUER_PCMCIA) { /* we have to export and return in this case */ -#ifndef COMPAT_HAS_NEW_SYMTAB - register_symtab(&hisax_syms_sedl); -#endif return 0; } #endif #ifdef CONFIG_HISAX_AVM_A1_PCMCIA if (type[0] == ISDN_CTYPE_A1_PCMCIA) { /* we have to export and return in this case */ -#ifndef COMPAT_HAS_NEW_SYMTAB - register_symtab(&hisax_syms_avm_a1); -#endif return 0; } #endif @@ -1515,6 +1491,7 @@ break; #endif case ISDN_CTYPE_ELSA: + case ISDN_CTYPE_HFC_PCI: cards[i].para[0] = io[i]; break; case ISDN_CTYPE_16_3: @@ -1550,6 +1527,7 @@ case ISDN_CTYPE_NETJET: case ISDN_CTYPE_AMD7930: case ISDN_CTYPE_TELESPCI: + case ISDN_CTYPE_W6692: break; case ISDN_CTYPE_BKM_A4T: break; @@ -1582,11 +1560,6 @@ if (HiSax_inithardware(NULL)) { /* Install only, if at least one card found */ #ifdef MODULE -#ifndef COMPAT_HAS_NEW_SYMTAB - /* No symbols to export, hide all symbols */ - register_symtab(NULL); - printk(KERN_INFO "HiSax: module installed\n"); -#endif /* COMPAT_HAS_NEW_SYMTAB */ #endif /* MODULE */ return (0); } else { @@ -1629,9 +1602,7 @@ nrcards = 0; HiSaxVersion(); - if (id) /* If id= string used */ - HiSax_id = id; - /* Initialize all 8 structs, even though we only accept + /* Initialize all structs, even though we only accept two pcmcia cards */ for (i = 0; i < HISAX_MAX_CARDS; i++) { @@ -1680,9 +1651,7 @@ nrcards = 0; HiSaxVersion(); - if (id) /* If id= string used */ - HiSax_id = id; - /* Initialize all 8 structs, even though we only accept + /* Initialize all structs, even though we only accept two pcmcia cards */ for (i = 0; i < HISAX_MAX_CARDS; i++) { @@ -1731,12 +1700,10 @@ nrcards = 0; HiSaxVersion(); - if (id) /* If id= string used */ - HiSax_id = id; - /* Initialize all 16 structs, even though we only accept + /* Initialize all structs, even though we only accept two pcmcia cards */ - for (i = 0; i < 16; i++) { + for (i = 0; i < HISAX_MAX_CARDS; i++) { cards[i].para[0] = irq[i]; cards[i].para[1] = io[i]; cards[i].typ = type[i]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c --- v2.3.26/linux/drivers/isdn/hisax/diva.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/diva.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: diva.c,v 1.16 1999/08/11 21:01:25 keil Exp $ +/* $Id: diva.c,v 1.17 1999/09/04 06:20:06 keil Exp $ * diva.c low level stuff for Eicon.Diehl Diva Family ISDN cards * @@ -12,6 +12,9 @@ * * * $Log: diva.c,v $ + * Revision 1.17 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 1.16 1999/08/11 21:01:25 keil * new PCI codefix * @@ -74,13 +77,10 @@ #include "ipac.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif extern const char *CardType[]; -const char *Diva_revision = "$Revision: 1.16 $"; +const char *Diva_revision = "$Revision: 1.17 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -550,7 +550,6 @@ if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "HSCX: receive out of memory\n"); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } @@ -566,7 +565,6 @@ if (!(skb = dev_alloc_skb(fifo_size))) printk(KERN_WARNING "HiSax: receive out of memory\n"); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); skb_queue_tail(&bcs->rqueue, skb); } @@ -583,7 +581,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->hw.hscx.count = 0; bcs->tx_skb = NULL; } @@ -752,30 +750,30 @@ sti(); if (cs->subtyp == DIVA_IPAC_ISA) { writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0); } else if (cs->subtyp == DIVA_IPAC_PCI) { unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + PITA_MISC_REG); *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); *ireg = PITA_PARA_MPX_MODE; - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0); } else { /* DIVA 2.0 */ cs->hw.diva.ctrl_reg = 0; /* Reset On */ byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); cs->hw.diva.ctrl_reg |= DIVA_RESET; /* Reset Off */ byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); if (cs->subtyp == DIVA_ISA) cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A; @@ -880,16 +878,12 @@ return(0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_diva __initdata = NULL; static struct pci_dev *dev_diva_u __initdata = NULL; static struct pci_dev *dev_diva201 __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif -int __init -setup_diva(struct IsdnCard *card) +__initfunc(int +setup_diva(struct IsdnCard *card)) { int bytecnt; u_char val; @@ -927,7 +921,6 @@ bytecnt = 8; } else { #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Diva: no PCI bus present\n"); return(0); @@ -938,23 +931,23 @@ PCI_DIVA20_ID, dev_diva))) { cs->subtyp = DIVA_PCI; cs->irq = dev_diva->irq; - cs->hw.diva.cfg_reg = get_pcibase(dev_diva, 2) + cs->hw.diva.cfg_reg = dev_diva->resource[ 2].start & PCI_BASE_ADDRESS_IO_MASK; } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_EICON_DIEHL, PCI_DIVA20_U_ID, dev_diva_u))) { cs->subtyp = DIVA_PCI; cs->irq = dev_diva_u->irq; - cs->hw.diva.cfg_reg = get_pcibase(dev_diva_u, 2) + cs->hw.diva.cfg_reg = dev_diva_u->resource[ 2].start & PCI_BASE_ADDRESS_IO_MASK; } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_EICON_DIEHL, PCI_DIVA_201, dev_diva201))) { cs->subtyp = DIVA_IPAC_PCI; cs->irq = dev_diva201->irq; cs->hw.diva.pci_cfg = - (ulong) ioremap((get_pcibase(dev_diva201, 0) + (ulong) ioremap((dev_diva201->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK), 4096); cs->hw.diva.cfg_reg = - (ulong) ioremap((get_pcibase(dev_diva201, 1) + (ulong) ioremap((dev_diva201->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK), 4096); } else { printk(KERN_WARNING "Diva: No PCI card found\n"); @@ -970,66 +963,6 @@ printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); return(0); } -#else - u_char pci_bus, pci_device_fn, pci_irq; - u_int pci_ioaddr; - - cs->subtyp = 0; - for (; pci_index < 0xff; pci_index++) { - if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL, - PCI_DIVA20_ID, pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) - cs->subtyp = DIVA_PCI; - else if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL, - PCI_DIVA20_U_ID, pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) - cs->subtyp = DIVA_PCI; - else if (pcibios_find_device(PCI_VENDOR_EICON_DIEHL, - PCI_DIVA_201, pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) - cs->subtyp = DIVA_IPAC_PCI; - else - break; - /* get IRQ */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - - /* get IO address */ - if (cs->subtyp == DIVA_IPAC_PCI) { - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - cs->hw.diva.pci_cfg = (ulong) ioremap(pci_ioaddr, - 4096); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &pci_ioaddr); - cs->hw.diva.cfg_reg = (ulong) ioremap(pci_ioaddr, - 4096); - } else { - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &pci_ioaddr); - cs->hw.diva.pci_cfg = pci_ioaddr & ~3; - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_2, &pci_ioaddr); - cs->hw.diva.cfg_reg = pci_ioaddr & ~3; - } - if (cs->subtyp) - break; - } - if (!cs->subtyp) { - printk(KERN_WARNING "Diva: No PCI card found\n"); - return(0); - } - pci_index++; - if (!pci_irq) { - printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - return(0); - } - if (!pci_ioaddr) { - printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - return(0); - } - cs->irq = pci_irq; -#endif /* COMPAT_HAS_NEW_PCI */ cs->irq_flags |= SA_SHIRQ; #else printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/elsa.c linux/drivers/isdn/hisax/elsa.c --- v2.3.26/linux/drivers/isdn/hisax/elsa.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/hisax/elsa.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: elsa.c,v 2.18 1999/08/25 16:50:54 keil Exp $ +/* $Id: elsa.c,v 2.19 1999/09/04 06:20:06 keil Exp $ * elsa.c low level stuff for Elsa isdn cards * @@ -14,6 +14,9 @@ * for ELSA PCMCIA support * * $Log: elsa.c,v $ + * Revision 2.19 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 2.18 1999/08/25 16:50:54 keil * Fix bugs which cause 2.3.14 hangs (waitqueue init) * @@ -91,15 +94,12 @@ #include "hscx.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif #include #include extern const char *CardType[]; -const char *Elsa_revision = "$Revision: 2.18 $"; +const char *Elsa_revision = "$Revision: 2.19 $"; const char *Elsa_Types[] = {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro", "PCMCIA", "QS 1000", "QS 3000", "QS 1000 PCI", "QS 3000 PCI", @@ -578,10 +578,10 @@ save_flags(flags); sti(); writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x20); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_POTA2, 0x00); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_MASK, 0xc0); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ restore_flags(flags); @@ -785,7 +785,7 @@ cs->hw.elsa.status |= ELSA_TIMER_AKTIV; byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg); byteout(cs->hw.elsa.timer, 0); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((110*HZ)/1000); restore_flags(flags); cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT; @@ -928,12 +928,8 @@ return (CARD_portlist[i]); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_qs1000 __initdata = NULL; static struct pci_dev *dev_qs3000 __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif int setup_elsa(struct IsdnCard *card) @@ -1051,7 +1047,6 @@ cs->irq); } else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Elsa: no PCI bus present\n"); return(0); @@ -1061,17 +1056,17 @@ dev_qs1000))) { cs->subtyp = ELSA_QS1000PCI; cs->irq = dev_qs1000->irq; - cs->hw.elsa.cfg = get_pcibase(dev_qs1000, 1) & + cs->hw.elsa.cfg = dev_qs1000->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK; - cs->hw.elsa.base = get_pcibase(dev_qs1000, 3) & + cs->hw.elsa.base = dev_qs1000->resource[ 3].start & PCI_BASE_ADDRESS_IO_MASK; } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ELSA, PCI_QS3000_ID, dev_qs3000))) { cs->subtyp = ELSA_QS3000PCI; cs->irq = dev_qs3000->irq; - cs->hw.elsa.cfg = get_pcibase(dev_qs3000, 1) & + cs->hw.elsa.cfg = dev_qs3000->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK; - cs->hw.elsa.base = get_pcibase(dev_qs3000, 3) & + cs->hw.elsa.base = dev_qs3000->resource[ 3].start & PCI_BASE_ADDRESS_IO_MASK; } else { printk(KERN_WARNING "Elsa: No PCI card found\n"); @@ -1096,54 +1091,6 @@ HZDELAY(500); /* wait 500*10 ms */ restore_flags(flags); } -#else - u_char pci_bus, pci_device_fn, pci_irq; - u_int pci_ioaddr; - - cs->subtyp = 0; - for (; pci_index < 0xff; pci_index++) { - if (pcibios_find_device(PCI_VENDOR_ELSA, - PCI_QS1000_ID, pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) - cs->subtyp = ELSA_QS1000PCI; - else if (pcibios_find_device(PCI_VENDOR_ELSA, - PCI_QS3000_ID, pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) - cs->subtyp = ELSA_QS3000PCI; - else - break; - /* get IRQ */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - - /* get IO address */ - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &pci_ioaddr); - pci_ioaddr &= ~3; /* remove io/mem flag */ - cs->hw.elsa.cfg = pci_ioaddr; - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_3, &pci_ioaddr); - if (cs->subtyp) - break; - } - if (!cs->subtyp) { - printk(KERN_WARNING "Elsa: No PCI card found\n"); - return(0); - } - pci_index++; - if (!pci_irq) { - printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n"); - return(0); - } - - if (!pci_ioaddr) { - printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); - return(0); - } - pci_ioaddr &= ~3; /* remove io/mem flag */ - cs->hw.elsa.base = pci_ioaddr; - cs->irq = pci_irq; -#endif /* COMPAT_HAS_NEW_PCI */ cs->hw.elsa.ale = cs->hw.elsa.base; cs->hw.elsa.isac = cs->hw.elsa.base +1; cs->hw.elsa.hscx = cs->hw.elsa.base +1; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/elsa_ser.c linux/drivers/isdn/hisax/elsa_ser.c --- v2.3.26/linux/drivers/isdn/hisax/elsa_ser.c Sun Aug 15 11:49:08 1999 +++ linux/drivers/isdn/hisax/elsa_ser.c Sun Nov 7 16:34:00 1999 @@ -298,7 +298,7 @@ (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; } } @@ -389,74 +389,6 @@ } } -#if 0 -static inline void check_modem_status(struct IsdnCardState *cs) -{ - int status; - struct async_struct *info = cs->hw.elsa.info; - struct async_icount *icount; - - status = serial_inp(info, UART_MSR); - - if (status & UART_MSR_ANY_DELTA) { - icount = &info->state->icount; - /* update input line counters */ - if (status & UART_MSR_TERI) - icount->rng++; - if (status & UART_MSR_DDSR) - icount->dsr++; - if (status & UART_MSR_DDCD) { - icount->dcd++; - } - if (status & UART_MSR_DCTS) - icount->cts++; -// wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) -// wake_up_interruptible(&info->open_wait); -; - else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) && - (info->flags & ASYNC_CALLOUT_NOHUP))) { -#ifdef SERIAL_DEBUG_OPEN - printk("doing serial hangup..."); -#endif - if (info->tty) - tty_hangup(info->tty); - } - } -#if 0 - if (info->flags & ASYNC_CTS_FLOW) { - if (info->tty->hw_stopped) { - if (status & UART_MSR_CTS) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - serial_outp(info, UART_IER, info->IER); -// rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if (!(status & UART_MSR_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - serial_outp(info, UART_IER, info->IER); - } - } - } -#endif 0 -} -#endif static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs) { @@ -510,13 +442,13 @@ bcs->hw.hscx.rcvbuf = NULL; } while ((skb = skb_dequeue(&bcs->rqueue))) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } while ((skb = skb_dequeue(&bcs->squeue))) { - idev_kfree_skb(skb, FREE_WRITE); + dev_kfree_skb(skb); } if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/gazel.c linux/drivers/isdn/hisax/gazel.c --- v2.3.26/linux/drivers/isdn/hisax/gazel.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/gazel.c Sun Nov 7 16:34:00 1999 @@ -37,9 +37,6 @@ #include "isdnl1.h" #include "ipac.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif extern const char *CardType[]; const char *gazel_revision = "$Revision: 2.6 $"; @@ -573,11 +570,7 @@ return (0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_tel __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif static int setup_gazelpci(struct IsdnCardState *cs) @@ -589,42 +582,19 @@ printk(KERN_WARNING "Gazel: PCI card automatic recognition\n"); found = 0; -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_WARNING "Gazel: No PCI bus present\n"); return 1; } -#endif seekcard = GAZEL_R685; for (nbseek = 0; nbseek < 3; nbseek++) { -#ifdef COMPAT_HAS_NEW_PCI if ((dev_tel = pci_find_device(GAZEL_MANUFACTURER, seekcard, dev_tel))) { pci_irq = dev_tel->irq; - pci_ioaddr0 = get_pcibase(dev_tel, 1); - pci_ioaddr1 = get_pcibase(dev_tel, 2); + pci_ioaddr0 = dev_tel->resource[ 1].start; + pci_ioaddr1 = dev_tel->resource[ 2].start; found = 1; } -#else - for (; pci_index < 0xff; pci_index++) { - u_char pci_bus, pci_device_fn; - - if (pcibios_find_device(GAZEL_MANUFACTURER, seekcard, - pci_index, &pci_bus, &pci_device_fn) - != PCIBIOS_SUCCESSFUL) - break; - /* get IRQ */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - /* get IO address */ - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &pci_ioaddr0); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_2, &pci_ioaddr1); - found = 1; - break; - } -#endif /* COMPAT_HAS_NEW_PCI */ if (found) break; else { @@ -636,9 +606,6 @@ seekcard = GAZEL_DJINN_ITOO; break; } -#ifndef COMPAT_HAS_NEW_PCI - pci_index = 0; -#endif } } if (!found) { @@ -690,8 +657,8 @@ return (0); } -int __init - setup_gazel(struct IsdnCard *card) +__initfunc(int + setup_gazel(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hfc_2bds0.c linux/drivers/isdn/hisax/hfc_2bds0.c --- v2.3.26/linux/drivers/isdn/hisax/hfc_2bds0.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/hfc_2bds0.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bds0.c,v 1.9 1999/07/01 08:11:35 keil Exp $ +/* $Id: hfc_2bds0.c,v 1.10 1999/10/14 20:25:28 keil Exp $ * * specific routines for CCD's HFC 2BDS0 * @@ -6,6 +6,9 @@ * * * $Log: hfc_2bds0.c,v $ + * Revision 1.10 1999/10/14 20:25:28 keil + * add a statistic for error monitoring + * * Revision 1.9 1999/07/01 08:11:35 keil * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel * @@ -260,6 +263,9 @@ if (cs->debug & L1_DEB_WARN) debugl1(cs, "hfc_empty_fifo: incoming packet too small"); cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel); +#ifdef ERROR_STATISTIC + bcs->err_inv++; +#endif cli(); while ((idx++ < count) && WaitNoBusy(cs)) ReadReg(cs, HFCD_DATA_NODEB, cip); @@ -267,7 +273,6 @@ } else if (!(skb = dev_alloc_skb(count - 3))) printk(KERN_WARNING "HFC: receive out of memory\n"); else { - SET_SKB_FREE(skb); ptr = skb_put(skb, count - 3); idx = 0; cip = HFCB_FIFO | HFCB_FIFO_OUT | HFCB_REC | HFCB_CHANNEL(bcs->channel); @@ -285,7 +290,7 @@ sti(); debugl1(cs, "RFIFO BUSY error"); printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); skb = NULL; } else { cli(); @@ -301,8 +306,11 @@ bcs->channel, chksum, stat); if (stat) { debugl1(cs, "FIFO CRC error"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); skb = NULL; +#ifdef ERROR_STATISTIC + bcs->err_crc++; +#endif } } } @@ -390,7 +398,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; } WaitForBusy(cs); @@ -592,7 +600,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -634,17 +642,6 @@ */ if (!cs) return; -#if 0 - if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { - if (cs->debug) - debugl1(cs, "D-Channel Busy cleared"); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); - stptr = stptr->next; - } - } -#endif if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { switch (cs->dc.hfcd.ph_state) { case (0): @@ -737,7 +734,6 @@ while ((idx++ < rcnt) && WaitNoBusy(cs)) ReadReg(cs, HFCD_DATA_NODEB, cip); } else if ((skb = dev_alloc_skb(rcnt - 3))) { - SET_SKB_FREE(skb); ptr = skb_put(skb, rcnt - 3); while (idx < (rcnt - 3)) { cli(); @@ -752,8 +748,11 @@ sti(); debugl1(cs, "RFIFO D BUSY error"); printk(KERN_WARNING "HFC DFIFO channel BUSY Error\n"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); skb = NULL; +#ifdef ERROR_STATISTIC + cs->err_rx++; +#endif } else { cli(); WaitNoBusy(cs); @@ -768,8 +767,11 @@ chksum, stat); if (stat) { debugl1(cs, "FIFO CRC error"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); skb = NULL; +#ifdef ERROR_STATISTIC + cs->err_crc++; +#endif } else { skb_queue_tail(&cs->rq, skb); sched_event_D(cs, D_RCVBUFREADY); @@ -865,7 +867,7 @@ cli(); WaitNoBusy(cs); ReadReg(cs, HFCD_DATA, HFCD_FIFO | HFCD_F1_INC | HFCD_SEND); - idev_kfree_skb(cs->tx_skb, FREE_WRITE); + dev_kfree_skb(cs->tx_skb); cs->tx_skb = NULL; sti(); WaitForBusy(cs); @@ -999,7 +1001,7 @@ } goto afterXPR; } else { - idev_kfree_skb(cs->tx_skb, FREE_WRITE); + dev_kfree_skb(cs->tx_skb); cs->tx_cnt = 0; cs->tx_skb = NULL; } @@ -1114,32 +1116,6 @@ cs->hw.hfcD.mst_m |= HFCD_MASTER; cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m); break; -#if 0 - case (HW_TESTLOOP | REQUEST): - u_char val = 0; - if (1 & (int) arg) - val |= 0x0c; - if (2 & (int) arg) - val |= 0x3; - if (test_bit(HW_IOM1, &cs->HW_Flags)) { - /* IOM 1 Mode */ - if (!val) { - cs->writeisac(cs, ISAC_SPCR, 0xa); - cs->writeisac(cs, ISAC_ADF1, 0x2); - } else { - cs->writeisac(cs, ISAC_SPCR, val); - cs->writeisac(cs, ISAC_ADF1, 0xa); - } - } else { - /* IOM 2 Mode */ - cs->writeisac(cs, ISAC_SPCR, val); - if (val) - cs->writeisac(cs, ISAC_ADF1, 0x8); - else - cs->writeisac(cs, ISAC_ADF1, 0x0); - } - break; -#endif default: if (cs->debug & L1_DEB_WARN) debugl1(cs, "hfcd_l1hw unknown pr %4x", pr); @@ -1156,24 +1132,10 @@ static void hfc_dbusy_timer(struct IsdnCardState *cs) { -#if 0 - struct PStack *stptr; - if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - if (cs->debug) - debugl1(cs, "D-Channel Busy"); - test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - stptr = cs->stlist; - - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); - stptr = stptr->next; - } - } -#endif } -unsigned int * __init -init_send_hfcd(int cnt) +__initfunc(unsigned int +*init_send_hfcd(int cnt)) { int i, *send; @@ -1187,8 +1149,8 @@ return(send); } -void __init -init2bds0(struct IsdnCardState *cs) +__initfunc(void +init2bds0(struct IsdnCardState *cs)) { cs->setstack_d = setstack_hfcd; cs->dbusytimer.function = (void *) hfc_dbusy_timer; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hfc_2bs0.c linux/drivers/isdn/hisax/hfc_2bs0.c --- v2.3.26/linux/drivers/isdn/hisax/hfc_2bs0.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/hfc_2bs0.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: hfc_2bs0.c,v 1.9 1999/07/01 08:11:36 keil Exp $ +/* $Id: hfc_2bs0.c,v 1.10 1999/10/14 20:25:28 keil Exp $ * specific routines for CCD's HFC 2BS0 * @@ -6,6 +6,9 @@ * * * $Log: hfc_2bs0.c,v $ + * Revision 1.10 1999/10/14 20:25:28 keil + * add a statistic for error monitoring + * * Revision 1.9 1999/07/01 08:11:36 keil * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel * @@ -217,12 +220,14 @@ stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | HFC_CHANNEL(bcs->channel)); WaitForBusy(cs); +#ifdef ERROR_STATISTIC + bcs->err_inv++; +#endif return (NULL); } if (!(skb = dev_alloc_skb(count - 3))) printk(KERN_WARNING "HFC: receive out of memory\n"); else { - SET_SKB_FREE(skb); ptr = skb_put(skb, count - 3); idx = 0; cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel); @@ -233,7 +238,7 @@ if (idx != count - 3) { debugl1(cs, "RFIFO BUSY error"); printk(KERN_WARNING "HFC FIFO channel %d BUSY Error\n", bcs->channel); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); WaitNoBusy(cs); stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | HFC_CHANNEL(bcs->channel)); @@ -251,8 +256,11 @@ bcs->channel, chksum, stat); if (stat) { debugl1(cs, "FIFO CRC error"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); skb = NULL; +#ifdef ERROR_STATISTIC + bcs->err_crc++; +#endif } WaitNoBusy(cs); stat = cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F2_INC | HFC_REC | @@ -325,7 +333,7 @@ bcs->tx_cnt -= count; if (PACKET_NOACK == bcs->tx_skb->pkt_type) count = -1; - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; WaitForBusy(cs); WaitNoBusy(cs); @@ -523,7 +531,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -559,8 +567,8 @@ return (0); } -void __init -init_send(struct BCState *bcs) +__initfunc(void +init_send(struct BCState *bcs)) { int i; @@ -573,8 +581,8 @@ bcs->hw.hfc.send[i] = 0x1fff; } -void __init -inithfc(struct IsdnCardState *cs) +__initfunc(void +inithfc(struct IsdnCardState *cs)) { init_send(&cs->bcs[0]); init_send(&cs->bcs[1]); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c --- v2.3.26/linux/drivers/isdn/hisax/hfc_pci.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/hfc_pci.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: hfc_pci.c,v 1.18 1999/08/29 17:05:44 werner Exp $ +/* $Id: hfc_pci.c,v 1.23 1999/11/07 17:01:55 keil Exp $ * hfc_pci.c low level driver for CCD´s hfc-pci based cards * @@ -23,6 +23,25 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: hfc_pci.c,v $ + * Revision 1.23 1999/11/07 17:01:55 keil + * fix for 2.3 pci structs + * + * Revision 1.22 1999/10/10 20:14:27 werner + * + * Correct B2-chan usage in conjuntion with echo mode. First implementation of NT-leased line mode. + * + * Revision 1.21 1999/10/02 17:47:49 werner + * + * Changed init order, added correction for page alignment with shared mem + * + * Revision 1.20 1999/09/07 06:18:55 werner + * + * Added io parameter for HFC-PCI based cards. Needed only with multiple cards + * when initialisation/selection order needs to be set. + * + * Revision 1.19 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 1.18 1999/08/29 17:05:44 werner * corrected tx_lo line setup. Datasheet is not correct. * @@ -91,40 +110,40 @@ #include "hfc_pci.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif #include extern const char *CardType[]; -static const char *hfcpci_revision = "$Revision: 1.18 $"; +static const char *hfcpci_revision = "$Revision: 1.23 $"; /* table entry in the PCI devices list */ typedef struct { - int vendor_id; - int device_id; - char *vendor_name; - char *card_name; - } PCI_ENTRY; - -static const PCI_ENTRY id_list[] = { - {0x1397,0x2BD0,"CCD/Billion/Asuscom","2BD0"}, - {0x1397,0xB000,"Billion","B000"}, - {0x1397,0xB006,"Billion","B006"}, - {0x1397,0xB007,"Billion","B007"}, - {0x1397,0xB008,"Billion","B008"}, - {0x1397,0xB009,"Billion","B009"}, - {0x1397,0xB00A,"Billion","B00A"}, - {0x1397,0xB00B,"Billion","B00B"}, - {0x1397,0xB00C,"Billion","B00C"}, - {0x1043,0x0675,"Asuscom/Askey","675"}, - {0x0871,0xFFA2,"German telekom","T-Concept"}, - {0x0871,0xFFA1,"German telekom","A1T"}, - {0x1051,0x0100,"Motorola MC145575","MC145575"}, - {0x1397,0xB100,"Seyeon","B100"}, - {0x15B0,0x2BD0,"Zoltrix","2BD0"}, - {0,0,NULL,NULL}, + int vendor_id; + int device_id; + char *vendor_name; + char *card_name; +} PCI_ENTRY; + +#define NT_T1_COUNT 20 /* number of 3.125ms interrupts for G2 timeout */ + +static const PCI_ENTRY id_list[] = +{ + {0x1397, 0x2BD0, "CCD/Billion/Asuscom", "2BD0"}, + {0x1397, 0xB000, "Billion", "B000"}, + {0x1397, 0xB006, "Billion", "B006"}, + {0x1397, 0xB007, "Billion", "B007"}, + {0x1397, 0xB008, "Billion", "B008"}, + {0x1397, 0xB009, "Billion", "B009"}, + {0x1397, 0xB00A, "Billion", "B00A"}, + {0x1397, 0xB00B, "Billion", "B00B"}, + {0x1397, 0xB00C, "Billion", "B00C"}, + {0x1043, 0x0675, "Asuscom/Askey", "675"}, + {0x0871, 0xFFA2, "German telekom", "T-Concept"}, + {0x0871, 0xFFA1, "German telekom", "A1T"}, + {0x1051, 0x0100, "Motorola MC145575", "MC145575"}, + {0x1397, 0xB100, "Seyeon", "B100"}, + {0x15B0, 0x2BD0, "Zoltrix", "2BD0"}, + {0, 0, NULL, NULL}, }; @@ -151,9 +170,21 @@ void release_io_hfcpci(struct IsdnCardState *cs) { + int flags; + + save_flags(flags); + cli(); + cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */ + Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); + restore_flags(flags); + Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */ + sti(); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */ + Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ #if CONFIG_PCI - pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, 0); /* disabe memory mapped ports + busmaster */ -#endif /* CONFIG_PCI */ + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */ +#endif /* CONFIG_PCI */ releasehfcpci(cs); del_timer(&cs->hw.hfcpci.timer); kfree(cs->hw.hfcpci.share_start); @@ -170,16 +201,20 @@ { long flags; + save_flags(flags); + cli(); pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ + cs->hw.hfcpci.int_m2 = 0; /* interrupt output off ! */ + Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); + printk(KERN_INFO "HFC_PCI: resetting card\n"); pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, PCI_ENA_MEMIO + PCI_ENA_MASTER); /* enable memory ports + busmaster */ Write_hfc(cs, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */ - save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */ Write_hfc(cs, HFCPCI_CIRM, 0); /* Reset Off */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((20 * HZ) / 1000); /* Timeout 20ms */ if (Read_hfc(cs, HFCPCI_STATUS) & 2) printk(KERN_WARNING "HFC-PCI init bit busy\n"); @@ -187,25 +222,23 @@ cs->hw.hfcpci.fifo_en = 0x30; /* only D fifos enabled */ Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); - cs->hw.hfcpci.trm = 0 + HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */ + cs->hw.hfcpci.trm = 0 + HFCPCI_BTRANS_THRESMASK; /* no echo connect , threshold */ Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); Write_hfc(cs, HFCPCI_CLKDEL, 0x0e); /* ST-Bit delay for TE-Mode */ cs->hw.hfcpci.sctrl_e = HFCPCI_AUTO_AWAKE; Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e); /* S/T Auto awake */ - cs->hw.hfcpci.bswapped = 0; /* no exchange */ + cs->hw.hfcpci.bswapped = 0; /* no exchange */ + cs->hw.hfcpci.nt_mode = 0; /* we are in TE mode */ cs->hw.hfcpci.ctmt = HFCPCI_TIM3_125 | HFCPCI_AUTO_TIMER; Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); - cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE; - cs->hw.hfcpci.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC | - HFCPCI_INTS_L1STATE | HFCPCI_CLTIMER; + cs->hw.hfcpci.int_m1 = HFCPCI_INTS_DTRANS | HFCPCI_INTS_DREC | + HFCPCI_INTS_L1STATE | HFCPCI_INTS_TIMER; Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); /* Clear already pending ints */ if (Read_hfc(cs, HFCPCI_INT_S1)); - if (Read_hfc(cs, HFCPCI_INT_S2)); Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 2); /* HFC ST 2 */ udelay(10); @@ -213,24 +246,29 @@ cs->hw.hfcpci.mst_m = HFCPCI_MASTER; /* HFC Master Mode */ Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); - cs->hw.hfcpci.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */ + cs->hw.hfcpci.sctrl = 0x40; /* set tx_lo mode, error in datasheet ! */ Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); cs->hw.hfcpci.sctrl_r = 0; Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); - /* Init GCI/IOM2 in master mode */ + /* Init GCI/IOM2 in master mode */ /* Slots 0 and 1 are set for B-chan 1 and 2 */ /* D- and monitor/CI channel are not enabled */ /* STIO1 is used as output for data, B1+B2 from ST->IOM+HFC */ - /* STIO2 is used as data input, B1+B2 from IOM->ST */ + /* STIO2 is used as data input, B1+B2 from IOM->ST */ /* ST B-channel send disabled -> continous 1s */ /* The IOM slots are always enabled */ - cs->hw.hfcpci.conn = 0x36; /* set data flow directions */ + cs->hw.hfcpci.conn = 0x36; /* set data flow directions */ Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); - Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* B1-Slot 0 STIO1 out enabled */ - Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* B2-Slot 1 STIO1 out enabled */ - Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* B1-Slot 0 STIO2 in enabled */ - Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* B2-Slot 1 STIO2 in enabled */ + Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* B1-Slot 0 STIO1 out enabled */ + Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* B2-Slot 1 STIO1 out enabled */ + Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* B1-Slot 0 STIO2 in enabled */ + Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* B2-Slot 1 STIO2 in enabled */ + + /* Finally enable IRQ output */ + cs->hw.hfcpci.int_m2 = HFCPCI_IRQ_ENABLE; + Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); + if (Read_hfc(cs, HFCPCI_INT_S2)); restore_flags(flags); } @@ -317,12 +355,11 @@ } else if (!(skb = dev_alloc_skb(count - 3))) printk(KERN_WARNING "HFCPCI: receive out of memory\n"); else { - SET_SKB_FREE(skb); total = count; count -= 3; ptr = skb_put(skb, count); - if (zp->z2 + count <= B_FIFO_SIZE + B_SUB_VAL) + if (zp->z2 + count <= B_FIFO_SIZE + B_SUB_VAL) maxlen = count; /* complete transfer */ else maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ @@ -381,7 +418,6 @@ df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ df->za[df->f2 & D_FREG_MASK].z2 = (zp->z2 + rcnt) & (D_FIFO_SIZE - 1); } else if ((skb = dev_alloc_skb(rcnt - 3))) { - SET_SKB_FREE(skb); total = rcnt; rcnt -= 3; ptr = skb_put(skb, rcnt); @@ -415,55 +451,56 @@ /*******************************************************************************/ /* check for transparent receive data and read max one threshold size if avail */ /*******************************************************************************/ -int hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type *bz, u_char *bdata) -{ unsigned short *z1r, *z2r; - int new_z2, fcnt, maxlen; - struct sk_buff *skb; - u_char *ptr, *ptr1; - - z1r = &bz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ - z2r = z1r + 1; - - if (!(fcnt = *z1r - *z2r)) - return(0); /* no data avail */ - - if (fcnt <= 0) - fcnt += B_FIFO_SIZE; /* bytes actually buffered */ - if (fcnt > HFCPCI_BTRANS_THRESHOLD) - fcnt = HFCPCI_BTRANS_THRESHOLD; /* limit size */ - - new_z2 = *z2r + fcnt; /* new position in fifo */ - if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z2 -= B_FIFO_SIZE; /* buffer wrap */ +int +hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata) +{ + unsigned short *z1r, *z2r; + int new_z2, fcnt, maxlen; + struct sk_buff *skb; + u_char *ptr, *ptr1; + + z1r = &bz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ + z2r = z1r + 1; + + if (!(fcnt = *z1r - *z2r)) + return (0); /* no data avail */ + + if (fcnt <= 0) + fcnt += B_FIFO_SIZE; /* bytes actually buffered */ + if (fcnt > HFCPCI_BTRANS_THRESHOLD) + fcnt = HFCPCI_BTRANS_THRESHOLD; /* limit size */ + + new_z2 = *z2r + fcnt; /* new position in fifo */ + if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z2 -= B_FIFO_SIZE; /* buffer wrap */ - if (!(skb = dev_alloc_skb(fcnt))) + if (!(skb = dev_alloc_skb(fcnt))) printk(KERN_WARNING "HFCPCI: receive out of memory\n"); - else { - SET_SKB_FREE(skb); - ptr = skb_put(skb, fcnt); - if (*z2r + fcnt <= B_FIFO_SIZE + B_SUB_VAL) - maxlen = fcnt; /* complete transfer */ - else - maxlen = B_FIFO_SIZE + B_SUB_VAL - *z2r; /* maximum */ - - ptr1 = bdata + (*z2r - B_SUB_VAL); /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - fcnt -= maxlen; - - if (fcnt) { /* rest remaining */ - ptr += maxlen; - ptr1 = bdata; /* start of buffer */ - memcpy(ptr, ptr1, fcnt); /* rest */ - } - cli(); - skb_queue_tail(&bcs->rqueue, skb); - sti(); - hfcpci_sched_event(bcs, B_RCVBUFREADY); - } - - *z2r = new_z2; /* new position */ - return(1); -} /* hfcpci_empty_fifo_trans */ + else { + ptr = skb_put(skb, fcnt); + if (*z2r + fcnt <= B_FIFO_SIZE + B_SUB_VAL) + maxlen = fcnt; /* complete transfer */ + else + maxlen = B_FIFO_SIZE + B_SUB_VAL - *z2r; /* maximum */ + + ptr1 = bdata + (*z2r - B_SUB_VAL); /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + fcnt -= maxlen; + + if (fcnt) { /* rest remaining */ + ptr += maxlen; + ptr1 = bdata; /* start of buffer */ + memcpy(ptr, ptr1, fcnt); /* rest */ + } + cli(); + skb_queue_tail(&bcs->rqueue, skb); + sti(); + hfcpci_sched_event(bcs, B_RCVBUFREADY); + } + + *z2r = new_z2; /* new position */ + return (1); +} /* hfcpci_empty_fifo_trans */ /**********************************/ /* B-channel main receive routine */ @@ -524,11 +561,10 @@ receive = 1; else receive = 0; - } else - if (bcs->mode == L1_MODE_TRANS) - receive = hfcpci_empty_fifo_trans(bcs, bz, bdata); - else - receive = 0; + } else if (bcs->mode == L1_MODE_TRANS) + receive = hfcpci_empty_fifo_trans(bcs, bz, bdata); + else + receive = 0; test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); if (count && receive) goto Begin; @@ -603,7 +639,7 @@ df->f1 = new_f1; /* next frame */ restore_flags(flags); - idev_kfree_skb(cs->tx_skb, FREE_WRITE); + dev_kfree_skb(cs->tx_skb); cs->tx_skb = NULL; return; } @@ -620,7 +656,7 @@ bzfifo_type *bz; u_char *bdata; u_char new_f1, *src, *dst; - unsigned short *z1t, *z2t; + unsigned short *z1t, *z2t; if (!bcs->tx_skb) return; @@ -639,57 +675,53 @@ } if (bcs->mode == L1_MODE_TRANS) { - z1t = &bz->za[MAX_B_FRAMES].z1; - z2t = z1t + 1; - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo_trans %d z1(%x) z2(%x)", - bcs->channel, *z1t, *z2t); - fcnt = *z2t - *z1t; - if (fcnt <= 0) - fcnt += B_FIFO_SIZE; /* fcnt contains available bytes in fifo */ - fcnt = B_FIFO_SIZE - fcnt; /* remaining bytes to send */ - - while ((fcnt < 2 * HFCPCI_BTRANS_THRESHOLD) && (bcs->tx_skb)) { - if (bcs->tx_skb->len < B_FIFO_SIZE - fcnt) { - /* data is suitable for fifo */ - count = bcs->tx_skb->len; - - new_z1 = *z1t + count; /* new buffer Position */ - if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z1 -= B_FIFO_SIZE; /* buffer wrap */ - src = bcs->tx_skb->data; /* source pointer */ - dst = bdata + (*z1t - B_SUB_VAL); - maxlen = (B_FIFO_SIZE + B_SUB_VAL) - *z1t; /* end of fifo */ - if (maxlen > count) - maxlen = count; /* limit size */ - memcpy(dst, src, maxlen); /* first copy */ + z1t = &bz->za[MAX_B_FRAMES].z1; + z2t = z1t + 1; + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci_fill_fifo_trans %d z1(%x) z2(%x)", + bcs->channel, *z1t, *z2t); + fcnt = *z2t - *z1t; + if (fcnt <= 0) + fcnt += B_FIFO_SIZE; /* fcnt contains available bytes in fifo */ + fcnt = B_FIFO_SIZE - fcnt; /* remaining bytes to send */ + + while ((fcnt < 2 * HFCPCI_BTRANS_THRESHOLD) && (bcs->tx_skb)) { + if (bcs->tx_skb->len < B_FIFO_SIZE - fcnt) { + /* data is suitable for fifo */ + count = bcs->tx_skb->len; + + new_z1 = *z1t + count; /* new buffer Position */ + if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) + new_z1 -= B_FIFO_SIZE; /* buffer wrap */ + src = bcs->tx_skb->data; /* source pointer */ + dst = bdata + (*z1t - B_SUB_VAL); + maxlen = (B_FIFO_SIZE + B_SUB_VAL) - *z1t; /* end of fifo */ + if (maxlen > count) + maxlen = count; /* limit size */ + memcpy(dst, src, maxlen); /* first copy */ + + count -= maxlen; /* remaining bytes */ + if (count) { + dst = bdata; /* start of buffer */ + src += maxlen; /* new position */ + memcpy(dst, src, count); + } + bcs->tx_cnt -= bcs->tx_skb->len; + fcnt += bcs->tx_skb->len; + *z1t = new_z1; /* now send data */ + } else if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded", + bcs->channel, bcs->tx_skb->len); - count -= maxlen; /* remaining bytes */ - if (count) { - dst = bdata; /* start of buffer */ - src += maxlen; /* new position */ - memcpy(dst, src, count); - } - bcs->tx_cnt -= bcs->tx_skb->len; - fcnt += bcs->tx_skb->len; - *z1t = new_z1; /* now send data */ - } - else - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded", - bcs->channel, bcs->tx_skb->len); - - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); - cli(); - bcs->tx_skb = skb_dequeue(&bcs->squeue); /* fetch next data */ - sti(); - } - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - restore_flags(flags); - return; + dev_kfree_skb(bcs->tx_skb); + cli(); + bcs->tx_skb = skb_dequeue(&bcs->squeue); /* fetch next data */ + sti(); + } + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + restore_flags(flags); + return; } - - if (cs->debug & L1_DEB_HSCX) debugl1(cs, "hfcpci_fill_fifo_hdlc %d f1(%d) f2(%d) z1(f1)(%x)", bcs->channel, bz->f1, bz->f2, @@ -749,57 +781,113 @@ bz->f1 = new_f1; /* next frame */ restore_flags(flags); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); return; } +/**********************************************/ +/* D-channel l1 state call for leased NT-mode */ +/**********************************************/ +static void +dch_nt_l2l1(struct PStack *st, int pr, void *arg) +{ + struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; + + switch (pr) { + case (PH_DATA | REQUEST): + case (PH_PULL | REQUEST): + case (PH_PULL | INDICATION): + st->l1.l1hw(st, pr, arg); + break; + case (PH_ACTIVATE | REQUEST): + st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL); + break; + case (PH_TESTLOOP | REQUEST): + if (1 & (long) arg) + debugl1(cs, "PH_TEST_LOOP B1"); + if (2 & (long) arg) + debugl1(cs, "PH_TEST_LOOP B2"); + if (!(3 & (long) arg)) + debugl1(cs, "PH_TEST_LOOP DISABLED"); + st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg); + break; + default: + if (cs->debug) + debugl1(cs, "dch_nt_l2l1 msg %04X unhandled", pr); + break; + } +} + + + /***********************/ /* set/reset echo mode */ -/***********************/ +/***********************/ static int -hfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl *ic) +hfcpci_auxcmd(struct IsdnCardState *cs, isdn_ctrl * ic) { - int flags; - int i = *(unsigned int *) ic->parm.num; - - if (cs->chanlimit > 1) - return(-EINVAL); - - save_flags(flags); - cli(); - if (i) { - cs->logecho = 1; - cs->hw.hfcpci.trm |= 0x20; /* enable echo chan */ - cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_B2REC; - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2RX; - } - else { - cs->logecho = 0; - cs->hw.hfcpci.trm &= ~0x20; /* enable echo chan */ - cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_B2REC; - cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2RX; - } - cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; - cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; - cs->hw.hfcpci.conn |= 0x10; /* B2-IOM -> B2-ST */ - cs->hw.hfcpci.ctmt &= ~2; - Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); - Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); - Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); - Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); - Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); - Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); - Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - restore_flags(flags); - return(0); -} /* hfcpci_auxcmd */ + int flags; + int i = *(unsigned int *) ic->parm.num; + + if ((ic->arg == 98) && + (!(cs->hw.hfcpci.int_m1 & (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC + HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC)))) { + save_flags(flags); + cli(); + Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 0); /* HFC ST G0 */ + udelay(10); + cs->hw.hfcpci.sctrl |= SCTRL_MODE_NT; + Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); /* set NT-mode */ + udelay(10); + Write_hfc(cs, HFCPCI_STATES, HFCPCI_LOAD_STATE | 1); /* HFC ST G1 */ + udelay(10); + Write_hfc(cs, HFCPCI_STATES, 1 | HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); + cs->dc.hfcpci.ph_state = 1; + cs->hw.hfcpci.nt_mode = 1; + cs->hw.hfcpci.nt_timer = 0; + cs->stlist->l2.l2l1 = dch_nt_l2l1; + restore_flags(flags); + debugl1(cs, "NT mode activated"); + return (0); + } + if ((cs->chanlimit > 1) || (cs->hw.hfcpci.bswapped) || + (cs->hw.hfcpci.nt_mode) || (ic->arg != 12)) + return (-EINVAL); + + save_flags(flags); + cli(); + if (i) { + cs->logecho = 1; + cs->hw.hfcpci.trm |= 0x20; /* enable echo chan */ + cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_B2REC; + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2RX; + } else { + cs->logecho = 0; + cs->hw.hfcpci.trm &= ~0x20; /* disable echo chan */ + cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_B2REC; + cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2RX; + } + cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; + cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; + cs->hw.hfcpci.conn |= 0x10; /* B2-IOM -> B2-ST */ + cs->hw.hfcpci.ctmt &= ~2; + Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); + Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); + Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); + Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); + Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); + Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + restore_flags(flags); + return (0); +} /* hfcpci_auxcmd */ /*****************************/ /* E-channel receive routine */ /*****************************/ -static void receive_emsg(struct IsdnCardState *cs) +static void +receive_emsg(struct IsdnCardState *cs) { long flags; int rcnt; @@ -836,55 +924,54 @@ if (cs->debug & L1_DEB_ISAC) debugl1(cs, "hfcpci e_rec z1(%x) z2(%x) cnt(%d)", zp->z1, zp->z2, rcnt); - new_z2 = zp->z2 + rcnt; /* new position in fifo */ + new_z2 = zp->z2 + rcnt; /* new position in fifo */ if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) - new_z2 -= B_FIFO_SIZE; /* buffer wrap */ + new_z2 -= B_FIFO_SIZE; /* buffer wrap */ new_f2 = (bz->f2 + 1) & MAX_B_FRAMES; - if ((rcnt > 256 + 3) || (count < 4) || + if ((rcnt > 256 + 3) || (count < 4) || (*(bdata + (zp->z1 - B_SUB_VAL)))) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hfcpci_empty_echan: incoming packet invalid length %d or crc", rcnt); - bz->za[new_f2].z2 = new_z2; - bz->f2 = new_f2; /* next buffer */ + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "hfcpci_empty_echan: incoming packet invalid length %d or crc", rcnt); + bz->za[new_f2].z2 = new_z2; + bz->f2 = new_f2; /* next buffer */ } else { - total = rcnt; - rcnt -= 3; - ptr = e_buffer; - - if (zp->z2 <= B_FIFO_SIZE + B_SUB_VAL) - maxlen = rcnt; /* complete transfer */ - else - maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ + total = rcnt; + rcnt -= 3; + ptr = e_buffer; - ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ - memcpy(ptr, ptr1, maxlen); /* copy data */ - rcnt -= maxlen; + if (zp->z2 <= B_FIFO_SIZE + B_SUB_VAL) + maxlen = rcnt; /* complete transfer */ + else + maxlen = B_FIFO_SIZE + B_SUB_VAL - zp->z2; /* maximum */ - if (rcnt) { /* rest remaining */ - ptr += maxlen; - ptr1 = bdata; /* start of buffer */ - memcpy(ptr, ptr1, rcnt); /* rest */ - } - bz->za[new_f2].z2 = new_z2; - bz->f2 = new_f2; /* next buffer */ - if (cs->debug & DEB_DLOG_HEX) { - ptr = cs->dlog; - if ((total - 3) < MAX_DLOG_SPACE / 3 - 10) { - *ptr++ = 'E'; - *ptr++ = 'C'; - *ptr++ = 'H'; - *ptr++ = 'O'; - *ptr++ = ':'; - ptr += QuickHex(ptr, e_buffer, total - 3); - ptr--; - *ptr++ = '\n'; - *ptr = 0; - HiSax_putstatus(cs, NULL, cs->dlog); - } else - HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); - } + ptr1 = bdata + (zp->z2 - B_SUB_VAL); /* start of data */ + memcpy(ptr, ptr1, maxlen); /* copy data */ + rcnt -= maxlen; - } + if (rcnt) { /* rest remaining */ + ptr += maxlen; + ptr1 = bdata; /* start of buffer */ + memcpy(ptr, ptr1, rcnt); /* rest */ + } + bz->za[new_f2].z2 = new_z2; + bz->f2 = new_f2; /* next buffer */ + if (cs->debug & DEB_DLOG_HEX) { + ptr = cs->dlog; + if ((total - 3) < MAX_DLOG_SPACE / 3 - 10) { + *ptr++ = 'E'; + *ptr++ = 'C'; + *ptr++ = 'H'; + *ptr++ = 'O'; + *ptr++ = ':'; + ptr += QuickHex(ptr, e_buffer, total - 3); + ptr--; + *ptr++ = '\n'; + *ptr = 0; + HiSax_putstatus(cs, NULL, cs->dlog); + } else + HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); + } + } rcnt = bz->f1 - bz->f2; if (rcnt < 0) @@ -900,7 +987,7 @@ goto Begin; restore_flags(flags); return; -} /* receive_emsg */ +} /* receive_emsg */ /*********************/ /* Interrupt handler */ @@ -919,6 +1006,9 @@ printk(KERN_WARNING "HFC-PCI: Spurious interrupt!\n"); return; } + if (!(cs->hw.hfcpci.int_m2 & 0x08)) + return; /* not initialised */ + if (HFCPCI_ANYINT & (stat = Read_hfc(cs, HFCPCI_STATUS))) { val = Read_hfc(cs, HFCPCI_INT_S1); if (cs->debug & L1_DEB_ISAC) @@ -931,7 +1021,7 @@ test_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags) ? "locked" : "unlocked"); val &= cs->hw.hfcpci.int_m1; - if (val & 0x40) { /* TE state machine irq */ + if (val & 0x40) { /* state machine irq */ exval = Read_hfc(cs, HFCPCI_STATES) & 0xf; if (cs->debug & L1_DEB_ISAC) debugl1(cs, "ph_state chg %d->%d", cs->dc.hfcpci.ph_state, @@ -940,6 +1030,14 @@ sched_event_D_pci(cs, D_L1STATECHANGE); val &= ~0x40; } + if (val & 0x80) { /* timer irq */ + if (cs->hw.hfcpci.nt_mode) { + if ((--cs->hw.hfcpci.nt_timer) < 0) + sched_event_D_pci(cs, D_L1STATECHANGE); + } + val &= ~0x80; + Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); + } while (val) { save_flags(flags); cli(); @@ -954,24 +1052,23 @@ cs->hw.hfcpci.int_s1 = exval; } if (val & 0x08) { - if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1:0))) { + if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1 : 0))) { if (cs->debug) debugl1(cs, "hfcpci spurious 0x08 IRQ"); } else main_rec_hfcpci(bcs); } - if (val & 0x10) { - if (cs->logecho) - receive_emsg(cs); - else - if (!(bcs = Sel_BCS(cs, 1))) { + if (val & 0x10) { + if (cs->logecho) + receive_emsg(cs); + else if (!(bcs = Sel_BCS(cs, 1))) { if (cs->debug) debugl1(cs, "hfcpci spurious 0x10 IRQ"); } else main_rec_hfcpci(bcs); } if (val & 0x01) { - if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1:0))) { + if (!(bcs = Sel_BCS(cs, cs->hw.hfcpci.bswapped ? 1 : 0))) { if (cs->debug) debugl1(cs, "hfcpci spurious 0x01 IRQ"); } else { @@ -1036,7 +1133,7 @@ } goto afterXPR; } else { - idev_kfree_skb(cs->tx_skb, FREE_WRITE); + dev_kfree_skb(cs->tx_skb); cs->tx_cnt = 0; cs->tx_skb = NULL; } @@ -1070,20 +1167,6 @@ static void hfcpci_dbusy_timer(struct IsdnCardState *cs) { -#if 0 - struct PStack *stptr; - if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { - if (cs->debug) - debugl1(cs, "D-Channel Busy"); - test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); - stptr = cs->stlist; - - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); - stptr = stptr->next; - } - } -#endif } /*************************************/ @@ -1094,6 +1177,7 @@ { struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; struct sk_buff *skb = arg; + int flags; switch (pr) { case (PH_DATA | REQUEST): @@ -1169,39 +1253,46 @@ Write_hfc(cs, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION); break; case (HW_DEACTIVATE | REQUEST): - cs->hw.hfcpci.mst_m &= ~HFCPCI_MASTER; + cs->hw.hfcpci.mst_m &= ~HFCPCI_MASTER; Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); break; case (HW_INFO3 | REQUEST): cs->hw.hfcpci.mst_m |= HFCPCI_MASTER; Write_hfc(cs, HFCPCI_MST_MODE, cs->hw.hfcpci.mst_m); break; -#if 0 case (HW_TESTLOOP | REQUEST): - u_char val = 0; - if (1 & (int) arg) - val |= 0x0c; - if (2 & (int) arg) - val |= 0x3; - if (test_bit(HW_IOM1, &cs->HW_Flags)) { - /* IOM 1 Mode */ - if (!val) { - cs->writeisac(cs, ISAC_SPCR, 0xa); - cs->writeisac(cs, ISAC_ADF1, 0x2); - } else { - cs->writeisac(cs, ISAC_SPCR, val); - cs->writeisac(cs, ISAC_ADF1, 0xa); - } - } else { - /* IOM 2 Mode */ - cs->writeisac(cs, ISAC_SPCR, val); - if (val) - cs->writeisac(cs, ISAC_ADF1, 0x8); - else - cs->writeisac(cs, ISAC_ADF1, 0x0); + switch ((int) arg) { + case (1): + Write_hfc(cs, HFCPCI_B1_SSL, 0x80); /* tx slot */ + Write_hfc(cs, HFCPCI_B1_RSL, 0x80); /* rx slot */ + save_flags(flags); + cli(); + cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~7) | 1; + Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); + restore_flags(flags); + break; + + case (2): + Write_hfc(cs, HFCPCI_B2_SSL, 0x81); /* tx slot */ + Write_hfc(cs, HFCPCI_B2_RSL, 0x81); /* rx slot */ + save_flags(flags); + cli(); + cs->hw.hfcpci.conn = (cs->hw.hfcpci.conn & ~0x38) | 0x08; + Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); + restore_flags(flags); + break; + + default: + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "hfcpci_l1hw loop invalid %4x", (int) arg); + return; } + save_flags(flags); + cli(); + cs->hw.hfcpci.trm |= 0x80; /* enable IOM-loop */ + Write_hfc(cs, HFCPCI_TRM, cs->hw.hfcpci.trm); + restore_flags(flags); break; -#endif default: if (cs->debug & L1_DEB_WARN) debugl1(cs, "hfcpci_l1hw unknown pr %4x", pr); @@ -1241,113 +1332,127 @@ { struct IsdnCardState *cs = bcs->cs; bzfifo_type *bzr, *bzt; - int flags; + int flags, fifo2; if (cs->debug & L1_DEB_HSCX) debugl1(cs, "HFCPCI bchannel mode %d bchan %d/%d", mode, bc, bcs->channel); bcs->mode = mode; bcs->channel = bc; - if (cs->chanlimit > 1) { - cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcpci.sctrl_e &= ~0x80; - } - else { - if (bc) { - cs->hw.hfcpci.bswapped = 1; /* B1 and B2 exchanged */ - cs->hw.hfcpci.sctrl_e |= 0x80; - bc = 0; /* B1 controller used */ - } - else { - cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ - cs->hw.hfcpci.sctrl_e &= ~0x80; - } - } + fifo2 = bc; save_flags(flags); cli(); + if (cs->chanlimit > 1) { + cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ + cs->hw.hfcpci.sctrl_e &= ~0x80; + } else { + if (bc) { + if (mode != L1_MODE_NULL) { + cs->hw.hfcpci.bswapped = 1; /* B1 and B2 exchanged */ + cs->hw.hfcpci.sctrl_e |= 0x80; + } else { + cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ + cs->hw.hfcpci.sctrl_e &= ~0x80; + } + fifo2 = 0; + } else { + cs->hw.hfcpci.bswapped = 0; /* B1 and B2 normal mode */ + cs->hw.hfcpci.sctrl_e &= ~0x80; + } + } switch (mode) { case (L1_MODE_NULL): if (bc) { cs->hw.hfcpci.sctrl &= ~SCTRL_B2_ENA; cs->hw.hfcpci.sctrl_r &= ~SCTRL_B2_ENA; - cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); } else { cs->hw.hfcpci.sctrl &= ~SCTRL_B1_ENA; cs->hw.hfcpci.sctrl_r &= ~SCTRL_B1_ENA; + } + if (fifo2) { + cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); + } else { cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); } break; case (L1_MODE_TRANS): if (bc) { - cs->hw.hfcpci.ctmt |= 2; - cs->hw.hfcpci.conn &= ~0x18; cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); - bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; - bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2; } else { - cs->hw.hfcpci.ctmt |= 1; - cs->hw.hfcpci.conn &= ~0x03; cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; + } + if (fifo2) { + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); + cs->hw.hfcpci.ctmt |= 2; + cs->hw.hfcpci.conn &= ~0x18; + bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b2; + bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b2; + } else { cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); - bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1; - bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1; + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); + cs->hw.hfcpci.ctmt |= 1; + cs->hw.hfcpci.conn &= ~0x03; + bzr = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.rxbz_b1; + bzt = &((fifo_area *) (cs->hw.hfcpci.fifos))->b_chans.txbz_b1; } bzr->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1; - bzr->za[MAX_B_FRAMES].z2 = bzr->za[MAX_B_FRAMES].z1; + bzr->za[MAX_B_FRAMES].z2 = bzr->za[MAX_B_FRAMES].z1; bzr->f1 = MAX_B_FRAMES; - bzr->f2 = bzr->f1; /* init F pointers to remain constant */ + bzr->f2 = bzr->f1; /* init F pointers to remain constant */ bzt->za[MAX_B_FRAMES].z1 = B_FIFO_SIZE + B_SUB_VAL - 1; - bzt->za[MAX_B_FRAMES].z2 = bzt->za[MAX_B_FRAMES].z1; + bzt->za[MAX_B_FRAMES].z2 = bzt->za[MAX_B_FRAMES].z1; bzt->f1 = MAX_B_FRAMES; - bzt->f2 = bzt->f1; /* init F pointers to remain constant */ + bzt->f2 = bzt->f1; /* init F pointers to remain constant */ break; case (L1_MODE_HDLC): if (bc) { - cs->hw.hfcpci.ctmt &= ~2; - cs->hw.hfcpci.conn &= ~0x18; cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; - cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); } else { - cs->hw.hfcpci.ctmt &= ~1; - cs->hw.hfcpci.conn &= ~0x3; cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; + } + if (fifo2) { + cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B2; + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); + cs->hw.hfcpci.ctmt &= ~2; + cs->hw.hfcpci.conn &= ~0x18; + } else { cs->hw.hfcpci.fifo_en |= HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); + cs->hw.hfcpci.int_m1 |= (HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); + cs->hw.hfcpci.ctmt &= ~1; + cs->hw.hfcpci.conn &= ~0x03; } break; case (L1_MODE_EXTRN): if (bc) { - cs->hw.hfcpci.conn |= 0x10; + cs->hw.hfcpci.conn |= 0x10; cs->hw.hfcpci.sctrl |= SCTRL_B2_ENA; cs->hw.hfcpci.sctrl_r |= SCTRL_B2_ENA; cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B2; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS+HFCPCI_INTS_B2REC); + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B2TRANS + HFCPCI_INTS_B2REC); } else { - cs->hw.hfcpci.conn |= 0x02; + cs->hw.hfcpci.conn |= 0x02; cs->hw.hfcpci.sctrl |= SCTRL_B1_ENA; cs->hw.hfcpci.sctrl_r |= SCTRL_B1_ENA; cs->hw.hfcpci.fifo_en &= ~HFCPCI_FIFOEN_B1; - cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS+HFCPCI_INTS_B1REC); + cs->hw.hfcpci.int_m1 &= ~(HFCPCI_INTS_B1TRANS + HFCPCI_INTS_B1REC); } break; } + Write_hfc(cs, HFCPCI_SCTRL_E, cs->hw.hfcpci.sctrl_e); Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); - restore_flags(flags); Write_hfc(cs, HFCPCI_FIFO_EN, cs->hw.hfcpci.fifo_en); Write_hfc(cs, HFCPCI_SCTRL, cs->hw.hfcpci.sctrl); Write_hfc(cs, HFCPCI_SCTRL_R, cs->hw.hfcpci.sctrl_r); Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt); Write_hfc(cs, HFCPCI_CONNECT, cs->hw.hfcpci.conn); + restore_flags(flags); } /******************************/ @@ -1420,7 +1525,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -1467,40 +1572,72 @@ static void hfcpci_bh(struct IsdnCardState *cs) { + int flags; /* struct PStack *stptr; */ if (!cs) return; -#if 0 - if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { - if (cs->debug) - debugl1(cs, "D-Channel Busy cleared"); - stptr = cs->stlist; - while (stptr != NULL) { - stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); - stptr = stptr->next; - } - } -#endif if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { - switch (cs->dc.hfcpci.ph_state) { - case (0): - l1_msg(cs, HW_RESET | INDICATION, NULL); - break; - case (3): - l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); - break; - case (8): - l1_msg(cs, HW_RSYNC | INDICATION, NULL); - break; - case (6): - l1_msg(cs, HW_INFO2 | INDICATION, NULL); - break; - case (7): - l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); - break; - default: - break; + if (!cs->hw.hfcpci.nt_mode) + switch (cs->dc.hfcpci.ph_state) { + case (0): + l1_msg(cs, HW_RESET | INDICATION, NULL); + break; + case (3): + l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); + break; + case (8): + l1_msg(cs, HW_RSYNC | INDICATION, NULL); + break; + case (6): + l1_msg(cs, HW_INFO2 | INDICATION, NULL); + break; + case (7): + l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); + break; + default: + break; + } else { + switch (cs->dc.hfcpci.ph_state) { + case (2): + save_flags(flags); + cli(); + if (cs->hw.hfcpci.nt_timer < 0) { + cs->hw.hfcpci.nt_timer = 0; + cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + /* Clear already pending ints */ + if (Read_hfc(cs, HFCPCI_INT_S1)); + + Write_hfc(cs, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); + udelay(10); + Write_hfc(cs, HFCPCI_STATES, 4); + cs->dc.hfcpci.ph_state = 4; + } else { + cs->hw.hfcpci.int_m1 |= HFCPCI_INTS_TIMER; + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + cs->hw.hfcpci.ctmt &= ~HFCPCI_AUTO_TIMER; + cs->hw.hfcpci.ctmt |= HFCPCI_TIM3_125; + Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); + Write_hfc(cs, HFCPCI_CTMT, cs->hw.hfcpci.ctmt | HFCPCI_CLTIMER); + cs->hw.hfcpci.nt_timer = NT_T1_COUNT; + Write_hfc(cs, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); /* allow G2 -> G3 transition */ + } + restore_flags(flags); + break; + case (1): + case (3): + case (4): + save_flags(flags); + cli(); + cs->hw.hfcpci.nt_timer = 0; + cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; + Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); + restore_flags(flags); + break; + default: + break; + } } } if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) @@ -1513,8 +1650,8 @@ /*************************************/ /* Alloc memory send data for queues */ /*************************************/ -unsigned int * __init - init_send_hfcpci(int cnt) +__initfunc(unsigned int + *init_send_hfcpci(int cnt)) { int i, *send; @@ -1531,18 +1668,14 @@ /********************************/ /* called for card init message */ /********************************/ -void __init - inithfcpci(struct IsdnCardState *cs) +__initfunc(void + inithfcpci(struct IsdnCardState *cs)) { cs->setstack_d = setstack_hfcpci; cs->dbusytimer.function = (void *) hfcpci_dbusy_timer; cs->dbusytimer.data = (long) cs; init_timer(&cs->dbusytimer); cs->tqueue.routine = (void *) (void *) hfcpci_bh; -#if 0 - if (!cs->hw.hfcpci.send) - cs->hw.hfcpci.send = init_send_hfcpci(16); -#endif if (!cs->bcs[0].hw.hfc.send) cs->bcs[0].hw.hfc.send = init_send_hfcpci(32); if (!cs->bcs[1].hw.hfc.send) @@ -1579,7 +1712,7 @@ inithfcpci(cs); save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((80 * HZ) / 1000); /* Timeout 80ms */ /* now switch timer interrupt off */ cs->hw.hfcpci.int_m1 &= ~HFCPCI_INTS_TIMER; @@ -1596,52 +1729,49 @@ /* this variable is used as card index when more than one cards are present */ -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_hfcpci __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif #endif /* CONFIG_PCI */ -int __init - setup_hfcpci(struct IsdnCard *card) +__initfunc(int + setup_hfcpci(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; + unsigned short cmd; char tmp[64]; int i; -#ifdef COMPAT_HAS_NEW_PCI - struct pci_dev *tmp_hfcpci = NULL; -#endif + struct pci_dev *tmp_hfcpci = NULL; strcpy(tmp, hfcpci_revision); printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); #if CONFIG_PCI cs->hw.hfcpci.int_s1 = 0; -#if 0 - cs->hw.hfcpci.send = NULL; -#endif cs->bcs[0].hw.hfc.send = NULL; cs->bcs[1].hw.hfc.send = NULL; cs->dc.hfcpci.ph_state = 0; cs->hw.hfcpci.fifo = 255; if (cs->typ == ISDN_CTYPE_HFC_PCI) { -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "HFC-PCI: no PCI bus present\n"); return (0); } i = 0; - while (id_list[i].vendor_id) { - tmp_hfcpci = pci_find_device(id_list[i].vendor_id, - id_list[i].device_id, - dev_hfcpci); - if (tmp_hfcpci) break; - i++; - } - + while (id_list[i].vendor_id) { + tmp_hfcpci = pci_find_device(id_list[i].vendor_id, + id_list[i].device_id, + dev_hfcpci); + i++; + if (tmp_hfcpci) { + if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK))) + continue; + else + break; + } + } + if (tmp_hfcpci) { - dev_hfcpci = tmp_hfcpci; /* old device */ + i--; + dev_hfcpci = tmp_hfcpci; /* old device */ cs->hw.hfcpci.pci_bus = dev_hfcpci->bus->number; cs->hw.hfcpci.pci_device_fn = dev_hfcpci->devfn; cs->irq = dev_hfcpci->irq; @@ -1649,43 +1779,45 @@ printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); return (0); } - cs->hw.hfcpci.pci_io = (char *) get_pcibase(dev_hfcpci, 1); - printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n",id_list[i].vendor_name,id_list[i].card_name); + cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start; + printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); } else { printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); return (0); } -#else - for (; pci_index < 255; pci_index++) { - unsigned char irq; - - i = 0; - while (id_list[i].vendor_id) { - if (pcibios_find_device(id_list[i].vendor_id, - id_list[i].device_id, pci_index, - &cs->hw.hfcpci.pci_bus, &cs->hw.hfcpci.pci_device_fn) == 0) - break; - i++; - } - if (!id_list[i].vendor_id) - continue; - - pcibios_read_config_byte(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, - PCI_INTERRUPT_LINE, &irq); - cs->irq = irq; - + if (((int) cs->hw.hfcpci.pci_io & (PAGE_SIZE - 1))) { + printk(KERN_WARNING "HFC-PCI shared mem address will be corrected\n"); + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, + cs->hw.hfcpci.pci_device_fn, + PCI_COMMAND, + 0x0103); /* set SERR */ + pcibios_read_config_word(cs->hw.hfcpci.pci_bus, + cs->hw.hfcpci.pci_device_fn, + PCI_COMMAND, + &cmd); + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, + cs->hw.hfcpci.pci_device_fn, + PCI_COMMAND, + cmd & ~2); + (int) cs->hw.hfcpci.pci_io &= ~(PAGE_SIZE - 1); + pcibios_write_config_dword(cs->hw.hfcpci.pci_bus, + cs->hw.hfcpci.pci_device_fn, + PCI_BASE_ADDRESS_1, + (int) cs->hw.hfcpci.pci_io); + pcibios_write_config_word(cs->hw.hfcpci.pci_bus, + cs->hw.hfcpci.pci_device_fn, + PCI_COMMAND, + cmd); pcibios_read_config_dword(cs->hw.hfcpci.pci_bus, - cs->hw.hfcpci.pci_device_fn, PCI_BASE_ADDRESS_1, - (void *) &cs->hw.hfcpci.pci_io); - printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n",id_list[i].vendor_name,id_list[i].card_name); - break; - } - if (pci_index == 255) { - printk(KERN_WARNING "HFC-PCI: No card found\n"); - return (0); + cs->hw.hfcpci.pci_device_fn, + PCI_BASE_ADDRESS_1, + (void *) &cs->hw.hfcpci.pci_io); + if (((int) cs->hw.hfcpci.pci_io & (PAGE_SIZE - 1))) { + printk(KERN_WARNING "HFC-PCI unable to align address %x\n", (unsigned) cs->hw.hfcpci.pci_io); + return (0); + } + dev_hfcpci->resource[1].start = (int) cs->hw.hfcpci.pci_io; } - pci_index++; -#endif /* COMPAT_HAS_NEW_PCI */ if (!cs->hw.hfcpci.pci_io) { printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); return (0); @@ -1701,16 +1833,16 @@ (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000; pcibios_write_config_dword(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, 0x80, - (u_int) virt_to_bus(cs->hw.hfcpci.fifos)); + (u_int) virt_to_bus(cs->hw.hfcpci.fifos)); cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256); printk(KERN_INFO - "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", + "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", (u_int) cs->hw.hfcpci.pci_io, (u_int) cs->hw.hfcpci.fifos, (u_int) virt_to_bus(cs->hw.hfcpci.fifos), cs->irq, HZ); pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */ - cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ + cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ cs->hw.hfcpci.int_m1 = 0; Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1); Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); @@ -1735,7 +1867,7 @@ reset_hfcpci(cs); cs->cardmsg = &hfcpci_card_msg; - cs->auxcmd = &hfcpci_auxcmd; + cs->auxcmd = &hfcpci_auxcmd; return (1); #else printk(KERN_WARNING "HFC-PCI: NO_PCI_BIOS\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hfc_pci.h linux/drivers/isdn/hisax/hfc_pci.h --- v2.3.26/linux/drivers/isdn/hisax/hfc_pci.h Tue Aug 31 17:29:13 1999 +++ linux/drivers/isdn/hisax/hfc_pci.h Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: hfc_pci.h,v 1.6 1999/08/28 21:04:29 werner Exp $ +/* $Id: hfc_pci.h,v 1.7 1999/10/10 20:13:06 werner Exp $ * specific defines for CCD's HFC 2BDS0 PCI chips * @@ -21,6 +21,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: hfc_pci.h,v $ + * Revision 1.7 1999/10/10 20:13:06 werner + * + * Corrected timer constant + * * Revision 1.6 1999/08/28 21:04:29 werner * Implemented full audio support (transparent mode) * @@ -129,7 +133,7 @@ /* bits in CTMT (Write) */ #define HFCPCI_CLTIMER 0x80 -#define HFCPCI_TIM3_125 0x00 +#define HFCPCI_TIM3_125 0x04 #define HFCPCI_TIM25 0x10 #define HFCPCI_TIM50 0x14 #define HFCPCI_TIM400 0x18 diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hfcscard.c linux/drivers/isdn/hisax/hfcscard.c --- v2.3.26/linux/drivers/isdn/hisax/hfcscard.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/hfcscard.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: hfcscard.c,v 1.4 1999/08/09 18:59:59 keil Exp $ +/* $Id: hfcscard.c,v 1.5 1999/09/04 06:20:06 keil Exp $ * hfcscard.c low level stuff for hfcs based cards (Teles3c, ACER P10) * @@ -6,6 +6,9 @@ * * * $Log: hfcscard.c,v $ + * Revision 1.5 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 1.4 1999/08/09 18:59:59 keil * Fix S0 init - Thanks to Stefan Gybas * @@ -27,7 +30,7 @@ extern const char *CardType[]; -static const char *hfcs_revision = "$Revision: 1.4 $"; +static const char *hfcs_revision = "$Revision: 1.5 $"; static void hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs) @@ -82,13 +85,13 @@ cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); /* Reset On */ save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((30*HZ)/1000); cs->hw.hfcD.cirm = 0; if (cs->typ == ISDN_CTYPE_TELES3C) cs->hw.hfcD.cirm |= HFCD_MEM8K; cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CIRM, cs->hw.hfcD.cirm); /* Reset Off */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); if (cs->typ == ISDN_CTYPE_TELES3C) cs->hw.hfcD.cirm |= HFCD_INTB; @@ -135,7 +138,7 @@ init2bds0(cs); save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((80*HZ)/1000); cs->hw.hfcD.ctmt |= HFCD_TIM800; cs->BC_Write_Reg(cs, HFCD_DATA, HFCD_CTMT, cs->hw.hfcD.ctmt); @@ -148,8 +151,8 @@ return(0); } -int __init -setup_hfcs(struct IsdnCard *card) +__initfunc(int +setup_hfcs(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h --- v2.3.26/linux/drivers/isdn/hisax/hisax.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/hisax.h Sun Nov 7 16:34:00 1999 @@ -1,8 +1,18 @@ -/* $Id: hisax.h,v 2.34 1999/08/25 17:00:04 keil Exp $ +/* $Id: hisax.h,v 2.37 1999/10/14 20:25:28 keil Exp $ * Basic declarations, defines and prototypes * * $Log: hisax.h,v $ + * Revision 2.37 1999/10/14 20:25:28 keil + * add a statistic for error monitoring + * + * Revision 2.36 1999/10/10 20:16:15 werner + * + * Added variable to hfcpci union. + * + * Revision 2.35 1999/09/04 06:35:09 keil + * Winbond W6692 support + * * Revision 2.34 1999/08/25 17:00:04 keil * Make ISAR V32bis modem running * Make LL->HL interface open for additional commands @@ -137,6 +147,8 @@ #include #include +#undef ERROR_STATISTIC + #define REQUEST 0 #define CONFIRM 1 #define INDICATION 2 @@ -447,6 +459,13 @@ u_char tsaxr1; }; +struct w6692B_hw { + int bchan; + int rcvidx; + int count; /* Current skb sent count */ + u_char *rcvbuf; /* B-Channel receive Buffer */ +}; + struct isar_reg { unsigned int Flags; volatile u_char bstat; @@ -571,6 +590,12 @@ int event; int (*BC_SetStack) (struct PStack *, struct BCState *); void (*BC_Close) (struct BCState *); +#ifdef ERROR_STATISTIC + int err_crc; + int err_tx; + int err_rdo; + int err_inv; +#endif union { struct hscx_hw hscx; struct hdlc_hw hdlc; @@ -578,6 +603,7 @@ struct hfcB_hw hfc; struct tiger_hw tiger; struct amd7930_hw amd7930; + struct w6692B_hw w6692; } hw; }; @@ -744,7 +770,8 @@ unsigned char fifo; unsigned char fifo_en; unsigned char bswapped; - /* unsigned int *send; */ + unsigned char nt_mode; + int nt_timer; unsigned char pci_bus; unsigned char pci_device_fn; unsigned char *pci_io; /* start of PCI IO memory */ @@ -813,6 +840,11 @@ unsigned char iom2; }; +struct w6692_hw { + unsigned int iobase; + struct timer_list timer; +}; + #ifdef CONFIG_HISAX_TESTEMU struct te_hw { unsigned char *sfifo; @@ -821,13 +853,8 @@ unsigned char *sfifo_e; int sfifo_cnt; unsigned int stat; -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t rwaitq; wait_queue_head_t swaitq; -#else - struct wait_queue *rwaitq; - struct wait_queue *swaitq; -#endif }; #endif @@ -847,11 +874,7 @@ int mon_rxp; struct arcofi_msg *arcofi_list; struct timer_list arcofitimer; -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t arcofi_wait; -#else - struct wait_queue *arcofi_wait; -#endif u_char arcofi_bc; u_char arcofi_state; u_char mocr; @@ -866,6 +889,10 @@ int ph_state; }; +struct w6692_chip { + int ph_state; +}; + #define HW_IOM1 0 #define HW_IPAC 1 #define HW_ISAR 2 @@ -910,6 +937,7 @@ #endif struct bkm_hw ax; struct gazel_hw gazel; + struct w6692_hw w6692; } hw; int myid; isdn_if iif; @@ -940,6 +968,7 @@ struct isac_chip isac; struct hfcd_chip hfcd; struct hfcpci_chip hfcpci; + struct w6692_chip w6692; } dc; u_char *rcvbuf; int rcvidx; @@ -948,6 +977,11 @@ int event; struct tq_struct tqueue; struct timer_list dbusytimer; +#ifdef ERROR_STATISTIC + int err_crc; + int err_tx; + int err_rx; +#endif }; #define MON0_RX 1 @@ -992,7 +1026,8 @@ #define ISDN_CTYPE_SCT_QUADRO 33 #define ISDN_CTYPE_GAZEL 34 #define ISDN_CTYPE_HFC_PCI 35 -#define ISDN_CTYPE_COUNT 35 +#define ISDN_CTYPE_W6692 36 +#define ISDN_CTYPE_COUNT 36 #ifdef ISDN_CHIP_ISAC @@ -1007,10 +1042,6 @@ #define __initdata #endif -#ifndef __init -#define __init -#endif - #define HISAX_INITFUNC(__arginit) __initfunc(__arginit) #define HISAX_INITDATA __initdata @@ -1243,6 +1274,15 @@ #define CARD_GAZEL 0 #endif +#ifdef CONFIG_HISAX_W6692 +#define CARD_W6692 1 +#ifndef ISDN_CHIP_W6692 +#define ISDN_CHIP_W6692 1 +#endif +#else +#define CARD_W6692 0 +#endif + #define TEI_PER_CARD 0 #ifdef CONFIG_HISAX_1TR6 @@ -1336,7 +1376,7 @@ int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); -void HiSax_reportcard(int cardnr); +void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char * p, int cnt); void LogFrame(struct IsdnCardState *cs, u_char * p, int size); void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hscx.c linux/drivers/isdn/hisax/hscx.c --- v2.3.26/linux/drivers/isdn/hisax/hscx.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/hscx.c Sun Nov 7 16:34:00 1999 @@ -219,7 +219,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/hscx_irq.c linux/drivers/isdn/hisax/hscx_irq.c --- v2.3.26/linux/drivers/isdn/hisax/hscx_irq.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/hscx_irq.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: hscx_irq.c,v 1.12 1999/07/01 08:11:42 keil Exp $ +/* $Id: hscx_irq.c,v 1.13 1999/10/14 20:25:28 keil Exp $ * hscx_irq.c low level b-channel stuff for Siemens HSCX * @@ -7,6 +7,9 @@ * This is an include file for fast inline IRQ stuff * * $Log: hscx_irq.c,v $ + * Revision 1.13 1999/10/14 20:25:28 keil + * add a statistic for error monitoring + * * Revision 1.12 1999/07/01 08:11:42 keil * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel * @@ -181,16 +184,28 @@ if (val & 0x80) { /* RME */ r = READHSCX(cs, hscx, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { - if (!(r & 0x80)) + if (!(r & 0x80)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX invalid frame"); - if ((r & 0x40) && bcs->mode) +#ifdef ERROR_STATISTIC + bcs->err_inv++; +#endif + } + if ((r & 0x40) && bcs->mode) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX RDO mode=%d", bcs->mode); - if (!(r & 0x20)) +#ifdef ERROR_STATISTIC + bcs->err_rdo++; +#endif + } + if (!(r & 0x20)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX CRC error"); +#ifdef ERROR_STATISTIC + bcs->err_crc++; +#endif + } WriteHSCXCMDR(cs, hscx, 0x80); } else { count = READHSCX(cs, hscx, HSCX_RBCL) & ( @@ -204,7 +219,6 @@ if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "HSCX: receive out of memory\n"); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } @@ -220,7 +234,6 @@ if (!(skb = dev_alloc_skb(fifo_size))) printk(KERN_WARNING "HiSax: receive out of memory\n"); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); skb_queue_tail(&bcs->rqueue, skb); } @@ -237,7 +250,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->hw.hscx.count = 0; bcs->tx_skb = NULL; } @@ -267,6 +280,9 @@ if (bcs->mode == 1) hscx_fill_fifo(bcs); else { +#ifdef ERROR_STATISTIC + bcs->err_tx++; +#endif /* Here we lost an TX interrupt, so * restart transmitting the whole frame. */ @@ -297,6 +313,9 @@ /* Here we lost an TX interrupt, so * restart transmitting the whole frame. */ +#ifdef ERROR_STATISTIC + bcs->err_tx++; +#endif if (bcs->tx_skb) { skb_push(bcs->tx_skb, bcs->hw.hscx.count); bcs->tx_cnt += bcs->hw.hscx.count; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/isac.c linux/drivers/isdn/hisax/isac.c --- v2.3.26/linux/drivers/isdn/hisax/isac.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/hisax/isac.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isac.c,v 1.23 1999/08/25 16:50:52 keil Exp $ +/* $Id: isac.c,v 1.24 1999/10/14 20:25:28 keil Exp $ * isac.c ISAC specific routines * @@ -9,6 +9,9 @@ * ../../../Documentation/isdn/HiSax.cert * * $Log: isac.c,v $ + * Revision 1.24 1999/10/14 20:25:28 keil + * add a statistic for error monitoring + * * Revision 1.23 1999/08/25 16:50:52 keil * Fix bugs which cause 2.3.14 hangs (waitqueue init) * @@ -281,12 +284,20 @@ if (val & 0x80) { /* RME */ exval = cs->readisac(cs, ISAC_RSTA); if ((exval & 0x70) != 0x20) { - if (exval & 0x40) + if (exval & 0x40) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC RDO"); - if (!(exval & 0x20)) +#ifdef ERROR_STATISTIC + cs->err_rx++; +#endif + } + if (!(exval & 0x20)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "ISAC CRC error"); +#ifdef ERROR_STATISTIC + cs->err_crc++; +#endif + } cs->writeisac(cs, ISAC_CMDR, 0x80); } else { count = cs->readisac(cs, ISAC_RBCL) & 0x1f; @@ -300,7 +311,6 @@ if (!(skb = alloc_skb(count, GFP_ATOMIC))) printk(KERN_WARNING "HiSax: D receive out of memory\n"); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, count), cs->rcvbuf, count); skb_queue_tail(&cs->rq, skb); } @@ -328,7 +338,7 @@ isac_fill_fifo(cs); goto afterXPR; } else { - idev_kfree_skb(cs->tx_skb, FREE_WRITE); + dev_kfree_skb(cs->tx_skb); cs->tx_cnt = 0; cs->tx_skb = NULL; } @@ -372,6 +382,9 @@ if (exval & 0x40) { /* XDU */ debugl1(cs, "ISAC XDU"); printk(KERN_WARNING "HiSax: ISAC XDU\n"); +#ifdef ERROR_STATISTIC + cs->err_tx++; +#endif if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) del_timer(&cs->dbusytimer); if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) @@ -614,7 +627,7 @@ discard_queue(&cs->rq); discard_queue(&cs->sq); if (cs->tx_skb) { - idev_kfree_skb(cs->tx_skb, FREE_WRITE); + dev_kfree_skb(cs->tx_skb); cs->tx_skb = NULL; } if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) @@ -670,7 +683,7 @@ /* discard frame; reset transceiver */ test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); if (cs->tx_skb) { - idev_kfree_skb(cs->tx_skb, FREE_WRITE); + dev_kfree_skb(cs->tx_skb); cs->tx_cnt = 0; cs->tx_skb = NULL; } else { diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/isar.c linux/drivers/isdn/hisax/isar.c --- v2.3.26/linux/drivers/isdn/hisax/isar.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/hisax/isar.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isar.c,v 1.5 1999/08/25 16:59:55 keil Exp $ +/* $Id: isar.c,v 1.7 1999/10/14 20:25:29 keil Exp $ * isar.c ISAR (Siemens PSB 7110) specific routines * @@ -6,6 +6,12 @@ * * * $Log: isar.c,v $ + * Revision 1.7 1999/10/14 20:25:29 keil + * add a statistic for error monitoring + * + * Revision 1.6 1999/08/31 11:20:20 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.5 1999/08/25 16:59:55 keil * Make ISAR V32bis modem running * Make LL->HL interface open for additional commands @@ -459,7 +465,6 @@ case L1_MODE_TRANS: case L1_MODE_V32: if ((skb = dev_alloc_skb(ireg->clsb))) { - SET_SKB_FREE(skb); rcv_mbox(cs, ireg, (u_char *)skb_put(skb, ireg->clsb)); skb_queue_tail(&bcs->rqueue, skb); isar_sched_event(bcs, B_RCVBUFREADY); @@ -478,6 +483,12 @@ if (cs->debug & L1_DEB_WARN) debugl1(cs, "isar frame error %x len %d", ireg->cmsb, ireg->clsb); +#ifdef ERROR_STATISTIC + if (ireg->cmsb & HDLC_ERR_RER) + bcs->err_inv++; + if (ireg->cmsb & HDLC_ERR_CER) + bcs->err_crc++; +#endif bcs->hw.isar.rcvidx = 0; cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); } else { @@ -493,7 +504,6 @@ } else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx-2))) { printk(KERN_WARNING "ISAR: receive out of memory\n"); } else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, bcs->hw.isar.rcvidx-2), bcs->hw.isar.rcvbuf, bcs->hw.isar.rcvidx-2); skb_queue_tail(&bcs->rqueue, skb); @@ -593,7 +603,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.isar.txcnt); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->hw.isar.txcnt = 0; bcs->tx_skb = NULL; } @@ -789,10 +799,19 @@ check_send(cs, ireg->cmsb); break; case ISAR_IIS_BSTEV: - cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); +#ifdef ERROR_STATISTIC + if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { + if (ireg->cmsb == BSTEV_TBO) + bcs->err_tx++; + if (ireg->cmsb == BSTEV_RBO) + bcs->err_rdo++; + } +#endif if (cs->debug & L1_DEB_WARN) debugl1(cs, "Buffer STEV dpath%d msb(%x)", ireg->iis>>6, ireg->cmsb); + cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0); + break; case ISAR_IIS_PSTEV: if ((bcs = sel_bcs_isar(cs, ireg->iis >> 6))) { rcv_mbox(cs, ireg, (u_char *)ireg->par); @@ -1022,8 +1041,8 @@ &bcs->hw.isar.reg->Flags)) bcs->hw.isar.dpath = 1; else { - printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n"); - debugl1(cs, "isar modeisar analog funktions only with DP1"); + printk(KERN_WARNING"isar modeisar analog works only with DP1\n"); + debugl1(cs, "isar modeisar analog works only with DP1"); return(1); } break; @@ -1159,7 +1178,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); if (bcs->cs->debug & L1_DEB_HSCX) @@ -1223,7 +1242,7 @@ ll_run(cs, features); break; default: - printk(KERN_DEBUG "HiSax: invalid ioclt %d\n", + printk(KERN_DEBUG "HiSax: invalid ioctl %d\n", (int) ic->arg); return(-EINVAL); } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/isar.h linux/drivers/isdn/hisax/isar.h --- v2.3.26/linux/drivers/isdn/hisax/isar.h Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/hisax/isar.h Sun Nov 7 16:34:00 1999 @@ -1,10 +1,13 @@ -/* $Id: isar.h,v 1.5 1999/08/25 16:59:59 keil Exp $ +/* $Id: isar.h,v 1.6 1999/10/14 20:25:29 keil Exp $ * isar.h ISAR (Siemens PSB 7110) specific defines * * Author Karsten Keil (keil@isdn4linux.de) * * * $Log: isar.h,v $ + * Revision 1.6 1999/10/14 20:25:29 keil + * add a statistic for error monitoring + * * Revision 1.5 1999/08/25 16:59:59 keil * Make ISAR V32bis modem running * Make LL->HL interface open for additional commands @@ -178,12 +181,17 @@ #define HDLC_FSD 0x20 #define HDLC_FST 0x20 #define HDLC_ERROR 0x1c +#define HDLC_ERR_FAD 0x10 +#define HDLC_ERR_RER 0x08 +#define HDLC_ERR_CER 0x01 #define SART_NMD 0x01 #define BSTAT_RDM0 0x1 #define BSTAT_RDM1 0x2 #define BSTAT_RDM2 0x4 #define BSTAT_RDM3 0x8 +#define BSTEV_TBO 0x1f +#define BSTEV_RBO 0x2f extern int ISARVersion(struct IsdnCardState *cs, char *s); extern void isar_int_main(struct IsdnCardState *cs); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c --- v2.3.26/linux/drivers/isdn/hisax/isdnl1.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/hisax/isdnl1.c Sun Nov 7 16:34:00 1999 @@ -318,12 +318,12 @@ stptr = cs->stlist; if (skb->len<3) { debugl1(cs, "D-channel frame too short(%d)",skb->len); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } if ((skb->data[0] & 1) || !(skb->data[1] &1)) { debugl1(cs, "D-channel frame wrong EA0/EA1"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } sapi = skb->data[0] >> 2; @@ -350,7 +350,7 @@ stptr = stptr->next; } } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } else if (sapi == CTRL_SAPI) { /* sapi 0 */ found = 0; while (stptr != NULL) @@ -361,7 +361,7 @@ } else stptr = stptr->next; if (!found) - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } } } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/isdnl2.c linux/drivers/isdn/hisax/isdnl2.c --- v2.3.26/linux/drivers/isdn/hisax/isdnl2.c Thu Aug 26 13:05:35 1999 +++ linux/drivers/isdn/hisax/isdnl2.c Sun Nov 7 16:34:00 1999 @@ -201,7 +201,7 @@ for (i = 0; i < MAX_WINDOW; i++) { if (l2->windowar[i]) { cnt++; - idev_kfree_skb(l2->windowar[i], FREE_WRITE); + dev_kfree_skb(l2->windowar[i]); l2->windowar[i] = NULL; } } @@ -480,7 +480,7 @@ len = l2->windowar[l2->sow]->len; if (PACKET_NOACK == l2->windowar[l2->sow]->pkt_type) len = -1; - idev_kfree_skb(l2->windowar[l2->sow], FREE_WRITE); + dev_kfree_skb(l2->windowar[l2->sow]); l2->windowar[l2->sow] = NULL; l2->sow = (l2->sow + 1) % l2->window; if (st->lli.l2writewakeup && (len >=0)) @@ -501,7 +501,6 @@ printk(KERN_WARNING "isdl2 can't alloc sbbuff for send_uframe\n"); return; } - SET_SKB_FREE(skb); memcpy(skb_put(skb, i), tmp, i); enqueue_super(st, skb); } @@ -515,7 +514,7 @@ inline void FreeSkb(struct sk_buff *skb) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } @@ -970,7 +969,6 @@ printk(KERN_WARNING "isdl2 can't alloc sbbuff for enquiry_cr\n"); return; } - SET_SKB_FREE(skb); memcpy(skb_put(skb, i), tmp, i); enqueue_super(st, skb); } @@ -1343,7 +1341,7 @@ if (l2->windowar[p1]) { printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n", p1); - idev_kfree_skb(l2->windowar[p1], FREE_WRITE); + dev_kfree_skb(l2->windowar[p1]); } l2->windowar[p1] = skb_clone(skb, GFP_ATOMIC); @@ -1367,7 +1365,6 @@ "isdl2 pull_iqueue skb header(%d/%d) too short\n", i, p1); oskb = skb; skb = alloc_skb(oskb->len + i, GFP_ATOMIC); - SET_SKB_FREE(skb); memcpy(skb_put(skb, i), header, i); memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len); FreeSkb(oskb); @@ -1788,12 +1785,12 @@ switch (pr) { case (DL_DATA | REQUEST): if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg)) { - idev_kfree_skb((struct sk_buff *) arg, FREE_READ); + dev_kfree_skb((struct sk_buff *) arg); } break; case (DL_UNIT_DATA | REQUEST): if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg)) { - idev_kfree_skb((struct sk_buff *) arg, FREE_READ); + dev_kfree_skb((struct sk_buff *) arg); } break; case (DL_ESTABLISH | REQUEST): diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/isdnl3.c linux/drivers/isdn/hisax/isdnl3.c --- v2.3.26/linux/drivers/isdn/hisax/isdnl3.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/isdnl3.c Sun Nov 7 16:34:00 1999 @@ -260,7 +260,6 @@ printk(KERN_WARNING "HiSax: No skb for D-channel\n"); return (NULL); } - SET_SKB_FREE(skb); skb_reserve(skb, MAX_HEADER_LEN); return (skb); } @@ -272,7 +271,7 @@ HiSax_putstatus(st->l1.hardware, "L3", "no D protocol"); if (skb) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/isurf.c linux/drivers/isdn/hisax/isurf.c --- v2.3.26/linux/drivers/isdn/hisax/isurf.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/isurf.c Sun Nov 7 16:34:00 1999 @@ -1,10 +1,13 @@ -/* $Id: isurf.c,v 1.5 1999/08/25 17:00:02 keil Exp $ +/* $Id: isurf.c,v 1.6 1999/09/04 06:20:06 keil Exp $ * isurf.c low level stuff for Siemens I-Surf/I-Talk cards * * Author Karsten Keil (keil@isdn4linux.de) * * $Log: isurf.c,v $ + * Revision 1.6 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 1.5 1999/08/25 17:00:02 keil * Make ISAR V32bis modem running * Make LL->HL interface open for additional commands @@ -34,7 +37,7 @@ extern const char *CardType[]; -static const char *ISurf_revision = "$Revision: 1.5 $"; +static const char *ISurf_revision = "$Revision: 1.6 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -154,10 +157,10 @@ byteout(cs->hw.isurf.reset, chips); /* Reset On */ save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); byteout(cs->hw.isurf.reset, ISURF_ISAR_EA); /* Reset Off */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); restore_flags(flags); } @@ -206,8 +209,8 @@ return(isar_auxcmd(cs, ic)); } -int __init -setup_isurf(struct IsdnCard *card) +__initfunc(int +setup_isurf(struct IsdnCard *card)) { int ver; struct IsdnCardState *cs = card->cs; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/ix1_micro.c linux/drivers/isdn/hisax/ix1_micro.c --- v2.3.26/linux/drivers/isdn/hisax/ix1_micro.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/ix1_micro.c Sun Nov 7 16:34:00 1999 @@ -282,8 +282,8 @@ } -int __init -setup_ix1micro(struct IsdnCard *card) +__initfunc(int +setup_ix1micro(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/jade.c linux/drivers/isdn/hisax/jade.c --- v2.3.26/linux/drivers/isdn/hisax/jade.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/jade.c Sun Nov 7 16:34:00 1999 @@ -214,7 +214,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/jade_irq.c linux/drivers/isdn/hisax/jade_irq.c --- v2.3.26/linux/drivers/isdn/hisax/jade_irq.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/jade_irq.c Sun Nov 7 16:34:00 1999 @@ -161,7 +161,6 @@ if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "JADE %s receive out of memory\n", (jade ? "B":"A")); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } @@ -177,7 +176,6 @@ if (!(skb = dev_alloc_skb(fifo_size))) printk(KERN_WARNING "HiSax: receive out of memory\n"); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); skb_queue_tail(&bcs->rqueue, skb); } @@ -194,7 +192,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->hw.hscx.count = 0; bcs->tx_skb = NULL; } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/l3_1tr6.c linux/drivers/isdn/hisax/l3_1tr6.c --- v2.3.26/linux/drivers/isdn/hisax/l3_1tr6.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/l3_1tr6.c Sun Nov 7 16:34:00 1999 @@ -94,14 +94,14 @@ { struct sk_buff *skb = arg; - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); l3_1tr6_release_req(pc, 0, NULL); } static void l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); if (pc->st->l3.debug & L3_DEB_WARN) l3_debug(pc->st, msg); l3_1tr6_release_req(pc, 0, NULL); @@ -251,7 +251,7 @@ if ((FAC_SPV == p[3]) || (FAC_Activate == p[3])) pc->para.spv = 1; } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); /* Signal all services, linklevel takes care of Service-Indicator */ if (bcfound) { @@ -290,7 +290,7 @@ l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb); return; } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); L3AddTimer(&pc->timer, T304, CC_T304); pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc); } @@ -321,7 +321,7 @@ l3_1tr6_error(pc, "missing call sent WE0_chanID", skb); return; } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); L3AddTimer(&pc->timer, T310, CC_T310); newl3state(pc, 3); pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc); @@ -332,7 +332,7 @@ { struct sk_buff *skb = arg; - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); L3DelTimer(&pc->timer); /* T304 */ newl3state(pc, 4); pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc); @@ -363,7 +363,7 @@ } } else if (pc->st->l3.debug & L3_DEB_CHARGE) l3_debug(pc->st, "charging info not found"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } @@ -372,7 +372,7 @@ { struct sk_buff *skb = arg; - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } static void @@ -386,7 +386,7 @@ return; } newl3state(pc, 10); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); pc->para.chargeinfo = 0; pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc); } @@ -414,7 +414,7 @@ l3_1tr6_error(pc, "missing REL cause", skb); return; } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); StopAllL3Timer(pc); newl3state(pc, 0); l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1); @@ -427,7 +427,7 @@ { struct sk_buff *skb = arg; - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); StopAllL3Timer(pc); newl3state(pc, 0); pc->para.cause = NO_CAUSE; @@ -484,7 +484,7 @@ l3_1tr6_error(pc, "missing connack date", skb); return; } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); newl3state(pc, 12); pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc); } @@ -499,7 +499,7 @@ l3_1tr6_error(pc, "missing connack date", skb); return; } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); newl3state(pc, 10); pc->para.chargeinfo = 0; L3DelTimer(&pc->timer); @@ -814,7 +814,7 @@ sprintf(tmp, "up1tr6 len only %d", skb->len); l3_debug(st, tmp); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) { @@ -824,7 +824,7 @@ skb->data[0], skb->len); l3_debug(st, tmp); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } if (skb->data[1] != 1) { @@ -832,13 +832,13 @@ sprintf(tmp, "up1tr6 CR len not 1"); l3_debug(st, tmp); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } cr = skb->data[2]; mt = skb->data[3]; if (skb->data[0] == PROTO_DIS_N0) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "up1tr6%s N0 mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt); @@ -853,11 +853,11 @@ sprintf(tmp, "up1tr6 no roc mem"); l3_debug(st, tmp); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } } else { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } } else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) || @@ -865,7 +865,7 @@ (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) || (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) || (mt == MT_N1_INFO)) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } else { if (!(proc = new_l3_process(st, cr))) { @@ -873,7 +873,7 @@ sprintf(tmp, "up1tr6 no roc mem"); l3_debug(st, tmp); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } mt = MT_N1_INVALID; @@ -884,7 +884,7 @@ ((1 << proc->state) & datastln1[i].state)) break; if (i == DATASTLN1_LEN) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { sprintf(tmp, "up1tr6%sstate %d mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/l3dss1.c linux/drivers/isdn/hisax/l3dss1.c --- v2.3.26/linux/drivers/isdn/hisax/l3dss1.c Thu Aug 26 13:05:37 1999 +++ linux/drivers/isdn/hisax/l3dss1.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: l3dss1.c,v 2.19 1999/08/25 16:55:23 keil Exp $ +/* $Id: l3dss1.c,v 2.20 1999/10/11 22:16:27 keil Exp $ * EURO/DSS1 D-channel protocol * @@ -13,6 +13,9 @@ * Fritz Elfert * * $Log: l3dss1.c,v $ + * Revision 2.20 1999/10/11 22:16:27 keil + * Suspend/Resume is possible without explicit ID too + * * Revision 2.19 1999/08/25 16:55:23 keil * Fix for test case TC10011 * @@ -90,7 +93,7 @@ #include extern char *HiSax_getrev(const char *revision); -const char *dss1_revision = "$Revision: 2.19 $"; +const char *dss1_revision = "$Revision: 2.20 $"; #define EXT_BEARER_CAPS 1 @@ -2520,14 +2523,13 @@ u_char *msg = pc->chan->setup.phone; MsgHead(p, pc->callref, MT_SUSPEND); - - *p++ = IE_CALL_ID; l = *msg++; if (l && (l <= 10)) { /* Max length 10 octets */ + *p++ = IE_CALL_ID; *p++ = l; for (i = 0; i < l; i++) *p++ = *msg++; - } else { + } else if (l) { l3_debug(pc->st, "SUS wrong CALL_ID len %d", l); return; } @@ -2596,13 +2598,13 @@ MsgHead(p, pc->callref, MT_RESUME); - *p++ = IE_CALL_ID; l = *msg++; if (l && (l <= 10)) { /* Max length 10 octets */ + *p++ = IE_CALL_ID; *p++ = l; for (i = 0; i < l; i++) *p++ = *msg++; - } else { + } else if (l) { l3_debug(pc->st, "RES wrong CALL_ID len %d", l); return; } @@ -2976,7 +2978,7 @@ } if (skb->len < 3) { l3_debug(st, "dss1up frame too short(%d)", skb->len); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } @@ -2986,13 +2988,13 @@ (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", skb->data[0], skb->len); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } cr = getcallref(skb->data); if (skb->len < ((skb->data[1] & 0x0f) + 3)) { l3_debug(st, "dss1up frame too short(%d)", skb->len); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } mt = skb->data[skb->data[1] + 2]; @@ -3001,26 +3003,26 @@ if (cr == -2) { /* wrong Callref */ if (st->l3.debug & L3_DEB_WARN) l3_debug(st, "dss1up wrong Callref"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } else if (cr == -1) { /* Dummy Callref */ if (mt == MT_FACILITY) if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) { l3dss1_parse_facility(st, NULL, (pr == (DL_DATA | INDICATION)) ? -1 : -2, p); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } if (st->l3.debug & L3_DEB_WARN) l3_debug(st, "dss1up dummy Callref (no facility msg or ie)"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } else if ((((skb->data[1] & 0x0f) == 1) && (0==(cr & 0x7f))) || (((skb->data[1] & 0x0f) == 2) && (0==(cr & 0x7fff)))) { /* Global CallRef */ if (st->l3.debug & L3_DEB_STATE) l3_debug(st, "dss1up Global CallRef"); global_handler(st, mt, skb); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } else if (!(proc = getl3proc(st, cr))) { /* No transaction process exist, that means no call with @@ -3032,7 +3034,7 @@ /* Setup with wrong CREF flag */ if (st->l3.debug & L3_DEB_STATE) l3_debug(st, "dss1up wrong CRef flag"); - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } if (!(proc = dss1_new_l3_process(st, cr))) { @@ -3040,7 +3042,7 @@ * CAUSE 0x2f "Resource unavailable", but this * need a new_l3_process too ... arghh */ - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } } else if (mt == MT_STATUS) { @@ -3074,17 +3076,17 @@ l3dss1_msg_without_setup(proc, 0, NULL); } } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } else if (mt == MT_RELEASE_COMPLETE) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } else { /* ETS 300-104 part 2 * if setup has not been made and a message type * (except MT_SETUP and RELEASE_COMPLETE) is received, * we must send MT_RELEASE_COMPLETE cause 81 */ - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); if ((proc = dss1_new_l3_process(st, cr))) { proc->para.cause = 81; l3dss1_msg_without_setup(proc, 0, NULL); @@ -3093,7 +3095,7 @@ } } if (l3dss1_check_messagetype_validity(proc, mt, skb)) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) @@ -3120,7 +3122,7 @@ } datastatelist[i].rout(proc, pr, skb); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/md5sums.asc linux/drivers/isdn/hisax/md5sums.asc --- v2.3.26/linux/drivers/isdn/hisax/md5sums.asc Thu Aug 26 13:05:37 1999 +++ linux/drivers/isdn/hisax/md5sums.asc Sun Nov 7 16:34:00 1999 @@ -6,26 +6,26 @@ # Eicon Technology Diva 2.01 PCI cards in the moment. # Read ../../../Documentation/isdn/HiSax.cert for more informations. # -0cc164fadd4ec0e2983ec9735e209cbd isac.c -5fe8cb5526c78c91f61b0a94a423ea5d isdnl1.c -3b9522e8bf9e1c3e7848d729fc3dc05d isdnl2.c -f4184a50e35e5b568608e6cb7a693319 isdnl3.c -ef70f4269fdc2ca15100f9b776afaa0d tei.c -65be616dd9d0e06c788d4fdd0fe5fe0a callc.c +3c2b1c96274cba97a8261d1cecc662b8 isac.c +a9a15d069dbacb383cc24c238cb5ebbe isdnl1.c +bb51bd223040b511c18f091da5ab6456 isdnl2.c +b7aa7f97b2374967a4aca7c52991142c isdnl3.c +a23fbf8879c1432b04640b8b04bdf419 tei.c +d7072dbbeeb7c4c45f3810ed13cf5545 callc.c bf9605b36429898f7be6630034e83230 cert.c -97c5e31c2739665b9c2976a30ce0b357 l3dss1.c -b674eee9314a7cc413971c84003cf1d2 l3_1tr6.c -51b2ef1efb221bb09fd08ab28bd2c565 elsa.c -24cda374da44b57f6a1bb215424267b5 diva.c +0e500813968adacaea2ef22c9cdd89eb l3dss1.c +2d748ced0eea375b21fe7ea91ca7917c l3_1tr6.c +d45fde1c90dda636ab134f2a51db435e elsa.c +0b5fb429f5bfe188fd42a5be01abbb14 diva.c # end of md5sums -----BEGIN PGP SIGNATURE----- Version: 2.6.3i Charset: noconv -iQCVAwUBN8RgFjpxHvX/mS9tAQFzFQP/dOgnppDIm5ug1hnlWjQ/0BVurKEEJ64r -DYDHwkcog+0gVE/EB1A7WUDqpFEnj52OZeoVinCfdVuVjP8IkrAJ8dCONsnXjBXz -pzM+FunP1LFxuv2TVM0f642j98JxS8rObGWH8ZwY36P2QfNp47zorO2F9WvdCkuz -sxJUtMUOlQ8= -=8uEP +iQCVAwUBOCYF6jpxHvX/mS9tAQFnxQP/dpHyNjbo5BhFEZ8qIgpPJzoCgV+b2pB+ +h9Z/Q1jg8l23L/lP9dW00ogrKnKziVUUJqg+wWVEAA7BnNVr3aeyQKFTVuOnK5MC +Oy0Z98p530vgOBiZ47elNfpefjhfD3duSSYNA4R9fEHVZB/atKFYvB5GDGmrwjIZ +2f3g3kBP5Os= +=zNnO -----END PGP SIGNATURE----- diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/mic.c linux/drivers/isdn/hisax/mic.c --- v2.3.26/linux/drivers/isdn/hisax/mic.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/mic.c Sun Nov 7 16:34:00 1999 @@ -224,8 +224,8 @@ return(0); } -int __init -setup_mic(struct IsdnCard *card) +__initfunc(int +setup_mic(struct IsdnCard *card)) { int bytecnt; struct IsdnCardState *cs = card->cs; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c --- v2.3.26/linux/drivers/isdn/hisax/netjet.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/netjet.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: netjet.c,v 1.13 1999/08/11 21:01:31 keil Exp $ +/* $Id: netjet.c,v 1.16 1999/10/14 20:25:29 keil Exp $ * netjet.c low level stuff for Traverse Technologie NETJet ISDN cards * @@ -7,6 +7,15 @@ * Thanks to Traverse Technologie Australia for documents and informations * * $Log: netjet.c,v $ + * Revision 1.16 1999/10/14 20:25:29 keil + * add a statistic for error monitoring + * + * Revision 1.15 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * + * Revision 1.14 1999/08/31 11:20:25 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.13 1999/08/11 21:01:31 keil * new PCI codefix * @@ -59,9 +68,6 @@ #include "hscx.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif #include #include @@ -75,7 +81,7 @@ extern const char *CardType[]; -const char *NETjet_revision = "$Revision: 1.13 $"; +const char *NETjet_revision = "$Revision: 1.16 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -406,7 +412,6 @@ if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "TIGER: receive out of memory\n"); else { - SET_SKB_FREE(skb); memcpy(skb_put(skb, count), bcs->hw.tiger.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } @@ -526,19 +531,26 @@ debugl1(bcs->cs, "tiger: frame not byte aligned"); state=HDLC_FLAG_SEARCH; bcs->hw.tiger.r_err++; +#ifdef ERROR_STATISTIC + bcs->err_inv++; +#endif } else { if (bcs->cs->debug & L1_DEB_HSCX) debugl1(bcs->cs,"tiger frame end(%d,%d): fcs(%x) i %x", i,j,bcs->hw.tiger.r_fcs, bcs->cs->hw.njet.irqstat0); if (bcs->hw.tiger.r_fcs == PPP_GOODFCS) { got_frame(bcs, (bitcnt>>3)-3); - } else + } else { if (bcs->cs->debug) { debugl1(bcs->cs, "tiger FCS error"); printframe(bcs->cs, bcs->hw.tiger.rcvbuf, (bitcnt>>3)-1, "rec"); bcs->hw.tiger.r_err++; } +#ifdef ERROR_STATISTIC + bcs->err_crc++; +#endif + } state=HDLC_FLAG_FOUND; } bitcnt=0; @@ -556,10 +568,13 @@ if ((state == HDLC_FRAME_FOUND) && !(bitcnt & 7)) { if ((bitcnt>>3)>=HSCX_BUFMAX) { - debugl1(bcs->cs, "tiger: frame to big"); + debugl1(bcs->cs, "tiger: frame too big"); r_val=0; state=HDLC_FLAG_SEARCH; bcs->hw.tiger.r_err++; +#ifdef ERROR_STATISTIC + bcs->err_inv++; +#endif } else { bcs->hw.tiger.rcvbuf[(bitcnt>>3)-1] = r_val; bcs->hw.tiger.r_fcs = @@ -584,6 +599,12 @@ if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_READ) { debugl1(cs,"tiger warn read double dma %x/%x", cs->hw.njet.irqstat0, cs->hw.njet.last_is0); +#ifdef ERROR_STATISTIC + if (cs->bcs[0].mode) + cs->bcs[0].err_rdo++; + if (cs->bcs[1].mode) + cs->bcs[1].err_rdo++; +#endif return; } else { cs->hw.njet.last_is0 &= ~NETJET_IRQM0_READ; @@ -705,7 +726,7 @@ if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len); - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; } test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); @@ -755,6 +776,12 @@ if ((cs->hw.njet.irqstat0 & cs->hw.njet.last_is0) & NETJET_IRQM0_WRITE) { debugl1(cs,"tiger warn write double dma %x/%x", cs->hw.njet.irqstat0, cs->hw.njet.last_is0); +#ifdef ERROR_STATISTIC + if (cs->bcs[0].mode) + cs->bcs[0].err_tx++; + if (cs->bcs[1].mode) + cs->bcs[1].err_tx++; +#endif return; } else { cs->hw.njet.last_is0 &= ~NETJET_IRQM0_WRITE; @@ -842,7 +869,7 @@ discard_queue(&bcs->rqueue); discard_queue(&bcs->squeue); if (bcs->tx_skb) { - idev_kfree_skb(bcs->tx_skb, FREE_WRITE); + dev_kfree_skb(bcs->tx_skb); bcs->tx_skb = NULL; test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); } @@ -889,8 +916,8 @@ } -void __init -inittiger(struct IsdnCardState *cs) +__initfunc(void +inittiger(struct IsdnCardState *cs)) { if (!(cs->bcs[0].hw.tiger.send = kmalloc(NETJET_DMA_TXSIZE * sizeof(unsigned int), GFP_KERNEL | GFP_DMA))) { @@ -1027,11 +1054,11 @@ sti(); cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ restore_flags(flags); cs->hw.njet.auxd = 0; @@ -1074,23 +1101,15 @@ return(0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_netjet __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif -int __init -setup_netjet(struct IsdnCard *card) +__initfunc(int +setup_netjet(struct IsdnCard *card)) { int bytecnt; struct IsdnCardState *cs = card->cs; char tmp[64]; #if CONFIG_PCI -#ifndef COMPAT_HAS_NEW_PCI - u_char pci_bus, pci_device_fn, pci_irq; - u_int pci_ioaddr, found; -#endif #endif strcpy(tmp, NETjet_revision); printk(KERN_INFO "HiSax: Traverse Tech. NETjet driver Rev. %s\n", HiSax_getrev(tmp)); @@ -1098,7 +1117,6 @@ return(0); test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags); #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Netjet: no PCI bus present\n"); return(0); @@ -1110,7 +1128,7 @@ printk(KERN_WARNING "NETjet: No IRQ for PCI card found\n"); return(0); } - cs->hw.njet.base = get_pcibase(dev_netjet, 0) + cs->hw.njet.base = dev_netjet->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK; if (!cs->hw.njet.base) { printk(KERN_WARNING "NETjet: No IO-Adr for PCI card found\n"); @@ -1120,41 +1138,6 @@ printk(KERN_WARNING "NETjet: No PCI card found\n"); return(0); } -#else - found = 0; - for (; pci_index < 0xff; pci_index++) { - if (pcibios_find_device(PCI_VENDOR_TRAVERSE_TECH, - PCI_NETJET_ID, pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) - found = 1; - else - continue; - /* get IRQ */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - - /* get IO address */ - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - if (found) - break; - } - if (!found) { - printk(KERN_WARNING "NETjet: No PCI card found\n"); - return(0); - } - pci_index++; - if (!pci_irq) { - printk(KERN_WARNING "NETjet: No IRQ for PCI card found\n"); - return(0); - } - if (!pci_ioaddr) { - printk(KERN_WARNING "NETjet: No IO-Adr for PCI card found\n"); - return(0); - } - cs->hw.njet.base = pci_ioaddr & PCI_BASE_ADDRESS_IO_MASK; - cs->irq = pci_irq; -#endif /* COMPAT_HAS_NEW_PCI */ cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; bytecnt = 256; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/niccy.c linux/drivers/isdn/hisax/niccy.c --- v2.3.26/linux/drivers/isdn/hisax/niccy.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/niccy.c Sun Nov 7 16:34:00 1999 @@ -40,9 +40,6 @@ #include "hscx.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif extern const char *CardType[]; const char *niccy_revision = "$Revision: 1.8 $"; @@ -259,14 +256,10 @@ return(0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *niccy_dev __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif -int __init -setup_niccy(struct IsdnCard *card) +__initfunc(int +setup_niccy(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -306,7 +299,6 @@ } else { #if CONFIG_PCI u_int pci_ioaddr; -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Niccy: no PCI bus present\n"); return(0); @@ -320,66 +312,21 @@ return(0); } cs->irq = niccy_dev->irq; - if (!get_pcibase(niccy_dev, 0)) { + if (!niccy_dev->resource[ 0].start) { printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n"); return(0); } - cs->hw.niccy.cfg_reg = get_pcibase(niccy_dev, 0) & PCI_BASE_ADDRESS_IO_MASK; - if (!get_pcibase(niccy_dev, 1)) { + cs->hw.niccy.cfg_reg = niccy_dev->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK; + if (!niccy_dev->resource[ 1].start) { printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n"); return(0); } - pci_ioaddr = get_pcibase(niccy_dev, 1) & PCI_BASE_ADDRESS_IO_MASK; + pci_ioaddr = niccy_dev->resource[ 1].start & PCI_BASE_ADDRESS_IO_MASK; cs->subtyp = NICCY_PCI; } else { printk(KERN_WARNING "Niccy: No PCI card found\n"); return(0); } -#else - u_char pci_bus, pci_device_fn, pci_irq; - - cs->subtyp = 0; - for (; pci_index < 0xff; pci_index++) { - if (pcibios_find_device(PCI_VENDOR_DR_NEUHAUS, - PCI_NICCY_ID, pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) - cs->subtyp = NICCY_PCI; - else - continue; - /* get IRQ */ - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - - /* get IO pci AMCC address */ - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - if (!pci_ioaddr) { - printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n"); - return(0); - } - cs->hw.niccy.cfg_reg = pci_ioaddr & ~3 ; - /* get IO address */ - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_1, &pci_ioaddr); - if (cs->subtyp) - break; - } - if (!cs->subtyp) { - printk(KERN_WARNING "Niccy: No PCI card found\n"); - return(0); - } - pci_index++; - if (!pci_irq) { - printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n"); - return(0); - } - if (!pci_ioaddr) { - printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n"); - return(0); - } - pci_ioaddr &= ~3; /* remove io/mem flag */ - cs->irq = pci_irq; -#endif /* COMPAT_HAS_NEW_PCI */ cs->irq_flags |= SA_SHIRQ; cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/s0box.c linux/drivers/isdn/hisax/s0box.c --- v2.3.26/linux/drivers/isdn/hisax/s0box.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/s0box.c Sun Nov 7 16:34:00 1999 @@ -212,8 +212,8 @@ return(0); } -int __init -setup_s0box(struct IsdnCard *card) +__initfunc(int +setup_s0box(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/saphir.c linux/drivers/isdn/hisax/saphir.c --- v2.3.26/linux/drivers/isdn/hisax/saphir.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/saphir.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: saphir.c,v 1.3 1999/07/12 21:05:26 keil Exp $ +/* $Id: saphir.c,v 1.4 1999/09/04 06:20:06 keil Exp $ * saphir.c low level stuff for HST Saphir 1 * @@ -8,6 +8,9 @@ * * * $Log: saphir.c,v $ + * Revision 1.4 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 1.3 1999/07/12 21:05:26 keil * fix race in IRQ handling * added watchdog for lost IRQs @@ -26,7 +29,7 @@ #include "isdnl1.h" extern const char *CardType[]; -static char *saphir_rev = "$Revision: 1.3 $"; +static char *saphir_rev = "$Revision: 1.4 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -234,10 +237,10 @@ save_flags(flags); sti(); byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((30*HZ)/1000); /* Timeout 30ms */ restore_flags(flags); byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val); @@ -265,8 +268,8 @@ } -int __init -setup_saphir(struct IsdnCard *card) +__initfunc(int +setup_saphir(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/sedlbauer.c linux/drivers/isdn/hisax/sedlbauer.c --- v2.3.26/linux/drivers/isdn/hisax/sedlbauer.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/sedlbauer.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: sedlbauer.c,v 1.16 1999/08/29 18:23:01 niemann Exp $ +/* $Id: sedlbauer.c,v 1.17 1999/09/04 06:20:06 keil Exp $ * sedlbauer.c low level stuff for Sedlbauer cards * includes support for the Sedlbauer speed star (speed star II), @@ -17,6 +17,9 @@ * Edgar Toernig * * $Log: sedlbauer.c,v $ + * Revision 1.17 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 1.16 1999/08/29 18:23:01 niemann * Fixed typo in errormsg * @@ -100,13 +103,10 @@ #include "isar.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif extern const char *CardType[]; -const char *Sedlbauer_revision = "$Revision: 1.16 $"; +const char *Sedlbauer_revision = "$Revision: 1.17 $"; const char *Sedlbauer_Types[] = {"None", "speed card/win", "speed star", "speed fax+", @@ -474,10 +474,10 @@ writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20); save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_CONF, 0x0); writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ACFG, 0xff); @@ -489,10 +489,10 @@ byteout(cs->hw.sedl.reset_on, SEDL_RESET); /* Reset On */ save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); byteout(cs->hw.sedl.reset_off, 0); /* Reset Off */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); restore_flags(flags); } @@ -542,15 +542,11 @@ } #ifdef SEDLBAUER_PCI -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_sedl __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif #endif -int __init -setup_sedlbauer(struct IsdnCard *card) +__initfunc(int +setup_sedlbauer(struct IsdnCard *card)) { int bytecnt, ver, val; struct IsdnCardState *cs = card->cs; @@ -585,7 +581,6 @@ /* Probe for Sedlbauer speed pci */ #if SEDLBAUER_PCI #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "Sedlbauer: no PCI bus present\n"); return(0); @@ -597,41 +592,12 @@ printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); return(0); } - cs->hw.sedl.cfg_reg = get_pcibase(dev_sedl, 0) & + cs->hw.sedl.cfg_reg = dev_sedl->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK; } else { printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); return(0); } -#else - for (; pci_index < 255; pci_index++) { - unsigned char pci_bus, pci_device_fn; - unsigned int ioaddr; - unsigned char irq; - - if (pcibios_find_device (PCI_VENDOR_SEDLBAUER, - PCI_SPEEDPCI_ID, pci_index, - &pci_bus, &pci_device_fn) != 0) { - continue; - } - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &irq); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &ioaddr); - cs->irq = irq; - cs->hw.sedl.cfg_reg = ioaddr & PCI_BASE_ADDRESS_IO_MASK; - if (!cs->hw.sedl.cfg_reg) { - printk(KERN_WARNING "Sedlbauer: No IO-Adr for PCI card found\n"); - return(0); - } - break; - } - if (pci_index == 255) { - printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); - return(0); - } - pci_index++; -#endif /* COMPAT_HAS_NEW_PCI */ cs->irq_flags |= SA_SHIRQ; cs->hw.sedl.bus = SEDL_BUS_PCI; cs->hw.sedl.chip = SEDL_CHIP_IPAC; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/sportster.c linux/drivers/isdn/hisax/sportster.c --- v2.3.26/linux/drivers/isdn/hisax/sportster.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/sportster.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: sportster.c,v 1.9 1999/07/12 21:05:29 keil Exp $ +/* $Id: sportster.c,v 1.10 1999/09/04 06:20:06 keil Exp $ * sportster.c low level stuff for USR Sportster internal TA * @@ -7,6 +7,9 @@ * Thanks to Christian "naddy" Weisgerber (3Com, US Robotics) for documentation * * $Log: sportster.c,v $ + * Revision 1.10 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * * Revision 1.9 1999/07/12 21:05:29 keil * fix race in IRQ handling * added watchdog for lost IRQs @@ -43,7 +46,7 @@ #include "isdnl1.h" extern const char *CardType[]; -const char *sportster_revision = "$Revision: 1.9 $"; +const char *sportster_revision = "$Revision: 1.10 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -177,11 +180,11 @@ byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); cs->hw.spt.res_irq &= ~SPORTSTER_RESET; /* Reset Off */ byteout(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ, cs->hw.spt.res_irq); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); restore_flags(flags); } @@ -208,8 +211,8 @@ return(0); } -int __init -get_io_range(struct IsdnCardState *cs) +__initfunc(int +get_io_range(struct IsdnCardState *cs)) { int i, j, adr; @@ -234,8 +237,8 @@ } } -int __init -setup_sportster(struct IsdnCard *card) +__initfunc(int +setup_sportster(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/tei.c linux/drivers/isdn/hisax/tei.c --- v2.3.26/linux/drivers/isdn/hisax/tei.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/hisax/tei.c Sun Nov 7 16:34:00 1999 @@ -169,7 +169,6 @@ printk(KERN_WARNING "HiSax: No skb for TEI manager\n"); return; } - SET_SKB_FREE(skb); bp = skb_put(skb, 3); bp[0] = (TEI_SAPI << 2); bp[1] = (GROUP_TEI << 1) | 0x1; @@ -371,7 +370,7 @@ int mt; if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) { - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); return; } @@ -417,7 +416,7 @@ st->ma.tei_m.printdebug(&st->ma.tei_m, "tei handler wrong pr %x\n", pr); } - idev_kfree_skb(skb, FREE_READ); + dev_kfree_skb(skb); } static void diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/teleint.c linux/drivers/isdn/hisax/teleint.c --- v2.3.26/linux/drivers/isdn/hisax/teleint.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/teleint.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: teleint.c,v 1.9 1999/07/12 21:05:30 keil Exp $ +/* $Id: teleint.c,v 1.11 1999/09/04 06:20:06 keil Exp $ * teleint.c low level stuff for TeleInt isdn cards * @@ -6,6 +6,12 @@ * * * $Log: teleint.c,v $ + * Revision 1.11 1999/09/04 06:20:06 keil + * Changes from kernel set_current_state() + * + * Revision 1.10 1999/08/31 11:20:27 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.9 1999/07/12 21:05:30 keil * fix race in IRQ handling * added watchdog for lost IRQs @@ -45,7 +51,7 @@ extern const char *CardType[]; -const char *TeleInt_revision = "$Revision: 1.9 $"; +const char *TeleInt_revision = "$Revision: 1.11 $"; #define byteout(addr,val) outb(val,addr) #define bytein(addr) inb(addr) @@ -64,7 +70,7 @@ while (ret && --max_delay) ret = HFC_BUSY & bytein(ale); if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inaktive\n"); + printk(KERN_WARNING "TeleInt Busy not inactive\n"); restore_flags(flags); return (0); } @@ -86,7 +92,7 @@ while (ret && --max_delay) ret = HFC_BUSY & bytein(ale); if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inaktive\n"); + printk(KERN_WARNING "TeleInt Busy not inactive\n"); return; } data[i] = bytein(adr); @@ -108,7 +114,7 @@ while (ret && --max_delay) ret = HFC_BUSY & bytein(ale); if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inaktive\n"); + printk(KERN_WARNING "TeleInt Busy not inactive\n"); restore_flags(flags); return; } @@ -130,7 +136,7 @@ while (ret && --max_delay) ret = HFC_BUSY & bytein(ale); if (!max_delay) { - printk(KERN_WARNING "TeleInt Busy not inaktive\n"); + printk(KERN_WARNING "TeleInt Busy not inactive\n"); return; } byteout(adr, data[i]); @@ -254,11 +260,11 @@ byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); /* Reset On */ save_flags(flags); sti(); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((30*HZ)/1000); cs->hw.hfc.cirm &= ~HFC_RESET; byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); /* Reset Off */ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((10*HZ)/1000); restore_flags(flags); } @@ -289,8 +295,8 @@ return(0); } -int __init -setup_TeleInt(struct IsdnCard *card) +__initfunc(int +setup_TeleInt(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/teles0.c linux/drivers/isdn/hisax/teles0.c --- v2.3.26/linux/drivers/isdn/hisax/teles0.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/teles0.c Sun Nov 7 16:34:00 1999 @@ -295,8 +295,8 @@ return(0); } -int __init -setup_teles0(struct IsdnCard *card) +__initfunc(int +setup_teles0(struct IsdnCard *card)) { u_char val; struct IsdnCardState *cs = card->cs; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/teles3.c linux/drivers/isdn/hisax/teles3.c --- v2.3.26/linux/drivers/isdn/hisax/teles3.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/teles3.c Sun Nov 7 16:34:00 1999 @@ -321,8 +321,8 @@ return(0); } -int __init -setup_teles3(struct IsdnCard *card) +__initfunc(int +setup_teles3(struct IsdnCard *card)) { u_char val; struct IsdnCardState *cs = card->cs; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/telespci.c linux/drivers/isdn/hisax/telespci.c --- v2.3.26/linux/drivers/isdn/hisax/telespci.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/isdn/hisax/telespci.c Sun Nov 7 16:34:00 1999 @@ -42,9 +42,6 @@ #include "hscx.h" #include "isdnl1.h" #include -#ifndef COMPAT_HAS_NEW_PCI -#include -#endif extern const char *CardType[]; const char *telespci_revision = "$Revision: 2.9 $"; @@ -304,29 +301,19 @@ return(0); } -#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_tel __initdata = NULL; -#else -static int pci_index __initdata = 0; -#endif -int __init -setup_telespci(struct IsdnCard *card) +__initfunc(int +setup_telespci(struct IsdnCard *card)) { struct IsdnCardState *cs = card->cs; char tmp[64]; -#ifndef COMPAT_HAS_NEW_PCI - u_char pci_bus, pci_device_fn, pci_irq; - u_int pci_memaddr; - u_char found = 0; -#endif strcpy(tmp, telespci_revision); printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_TELESPCI) return (0); #if CONFIG_PCI -#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "TelesPCI: no PCI bus present\n"); return(0); @@ -337,40 +324,14 @@ printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); return(0); } - cs->hw.teles0.membase = (u_int) ioremap(get_pcibase(dev_tel, 0), + cs->hw.teles0.membase = (u_int) ioremap(dev_tel->resource[ 0].start, PAGE_SIZE); printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", - get_pcibase(dev_tel, 0), dev_tel->irq); + dev_tel->resource[ 0].start, dev_tel->irq); } else { printk(KERN_WARNING "TelesPCI: No PCI card found\n"); return(0); } -#else - for (; pci_index < 0xff; pci_index++) { - if (pcibios_find_device (0x11DE, 0x6120, - pci_index, &pci_bus, &pci_device_fn) - == PCIBIOS_SUCCESSFUL) { - found = 1; - } else { - break; - } - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_memaddr); - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq); - - printk(KERN_INFO "Found: Zoran, base-address: 0x%x," - " irq: 0x%x\n", pci_memaddr, pci_irq); - break; - } - if (!found) { - printk(KERN_WARNING "TelesPCI: No PCI card found\n"); - return(0); - } - pci_index++; - cs->irq = pci_irq; - cs->hw.teles0.membase = (u_int) vremap(pci_memaddr, PAGE_SIZE); -#endif /* COMPAT_HAS_NEW_PCI */ #else printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n"); printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/w6692.c linux/drivers/isdn/hisax/w6692.c --- v2.3.26/linux/drivers/isdn/hisax/w6692.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/w6692.c Sun Nov 7 16:34:00 1999 @@ -0,0 +1,1063 @@ +/* $Id: w6692.c,v 1.1 1999/09/04 06:28:58 keil Exp $ + + * w6692.c Winbond W6692 specific routines + * + * Author Petr Novak + * (based on HiSax driver by Karsten Keil) + * + * This file is (c) under GNU PUBLIC LICENSE + * + * $Log: w6692.c,v $ + * Revision 1.1 1999/09/04 06:28:58 keil + * first revision + * + * + * + */ + +#include +#define __NO_VERSION__ +#include "hisax.h" +#include "w6692.h" +#include "isdnl1.h" +#include +#include + +#define PCI_VEND_ASUSCOM 0x675 +#define PCI_DEV_ASUSCOMPCI1 0x1702 +#ifndef PCI_VENDOR_ID_WINBOND2 +#define PCI_VENDOR_ID_WINBOND2 0x1050 +#endif +#define PCI_DEVICE_W6692 0x6692 + +/* table entry in the PCI devices list */ +typedef struct { + int vendor_id; + int device_id; + char *vendor_name; + char *card_name; +} PCI_ENTRY; + +static const PCI_ENTRY id_list[] = +{ + {PCI_VEND_ASUSCOM, PCI_DEV_ASUSCOMPCI1, "AsusCom", "TA XXX"}, + {PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_W6692, "Winbond", "W6692"}, + {0, 0, NULL, NULL} +}; + +extern const char *CardType[]; + +const char *w6692_revision = "$Revision: 1.1 $"; + +#define DBUSY_TIMER_VALUE 80 + +static char *W6692Ver[] HISAX_INITDATA = +{"W6692 V00", "W6692 V01", "W6692 V10", + "W6692 V11"}; + +static void +W6692Version(struct IsdnCardState *cs, char *s) +{ + int val; + + val = cs->readW6692(cs, W_D_RBCH); + printk(KERN_INFO "%s Winbond W6692 version (%x): %s\n", s, val, W6692Ver[(val >> 6) & 3]); +} + +static void +ph_command(struct IsdnCardState *cs, unsigned int command) +{ + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "ph_command %x", command); + cs->writeisac(cs, W_CIX, command); +} + + +static void +W6692_new_ph(struct IsdnCardState *cs) +{ + switch (cs->dc.w6692.ph_state) { + case (W_L1CMD_RST): + ph_command(cs, W_L1CMD_DRC); + l1_msg(cs, HW_RESET | INDICATION, NULL); + /* fallthru */ + case (W_L1IND_CD): + l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL); + break; + case (W_L1IND_DRD): + l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL); + break; + case (W_L1IND_CE): + l1_msg(cs, HW_POWERUP | CONFIRM, NULL); + break; + case (W_L1IND_LD): + l1_msg(cs, HW_RSYNC | INDICATION, NULL); + break; + case (W_L1IND_ARD): + l1_msg(cs, HW_INFO2 | INDICATION, NULL); + break; + case (W_L1IND_AI8): + l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL); + break; + case (W_L1IND_AI10): + l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL); + break; + default: + break; + } +} + +static void +W6692_bh(struct IsdnCardState *cs) +{ + struct PStack *stptr; + + if (!cs) + return; + if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { + if (cs->debug) + debugl1(cs, "D-Channel Busy cleared"); + stptr = cs->stlist; + while (stptr != NULL) { + stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL); + stptr = stptr->next; + } + } + if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) + W6692_new_ph(cs); + if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) + DChannel_proc_rcv(cs); + if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) + DChannel_proc_xmt(cs); +/* + if (test_and_clear_bit(D_RX_MON1, &cs->event)) + arcofi_fsm(cs, ARCOFI_RX_END, NULL); + if (test_and_clear_bit(D_TX_MON1, &cs->event)) + arcofi_fsm(cs, ARCOFI_TX_END, NULL); + */ +} + +void +W6692_sched_event(struct IsdnCardState *cs, int event) +{ + test_and_set_bit(event, &cs->event); + queue_task(&cs->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +static void +W6692B_sched_event(struct BCState *bcs, int event) +{ + bcs->event |= 1 << event; + queue_task(&bcs->tqueue, &tq_immediate); + mark_bh(IMMEDIATE_BH); +} + +static void +W6692_empty_fifo(struct IsdnCardState *cs, int count) +{ + u_char *ptr; + long flags; + + if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) + debugl1(cs, "W6692_empty_fifo"); + + if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692_empty_fifo overrun %d", + cs->rcvidx + count); + cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK); + cs->rcvidx = 0; + return; + } + ptr = cs->rcvbuf + cs->rcvidx; + cs->rcvidx += count; + save_flags(flags); + cli(); + cs->readW6692fifo(cs, ptr, count); + cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK); + restore_flags(flags); + if (cs->debug & L1_DEB_ISAC_FIFO) { + char *t = cs->dlog; + + t += sprintf(t, "W6692_empty_fifo cnt %d", count); + QuickHex(t, ptr, count); + debugl1(cs, cs->dlog); + } +} + +static void +W6692_fill_fifo(struct IsdnCardState *cs) +{ + int count, more; + u_char *ptr; + long flags; + + if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO)) + debugl1(cs, "W6692_fill_fifo"); + + if (!cs->tx_skb) + return; + + count = cs->tx_skb->len; + if (count <= 0) + return; + + more = 0; + if (count > W_D_FIFO_THRESH) { + more = !0; + count = W_D_FIFO_THRESH; + } + save_flags(flags); + cli(); + ptr = cs->tx_skb->data; + skb_pull(cs->tx_skb, count); + cs->tx_cnt += count; + cs->writeW6692fifo(cs, ptr, count); + cs->writeW6692(cs, W_D_CMDR, more ? W_D_CMDR_XMS : (W_D_CMDR_XMS | W_D_CMDR_XME)); + restore_flags(flags); + if (test_and_set_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { + debugl1(cs, "W6692_fill_fifo dbusytimer running"); + del_timer(&cs->dbusytimer); + } + init_timer(&cs->dbusytimer); + cs->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ) / 1000); + add_timer(&cs->dbusytimer); + if (cs->debug & L1_DEB_ISAC_FIFO) { + char *t = cs->dlog; + + t += sprintf(t, "W6692_fill_fifo cnt %d", count); + QuickHex(t, ptr, count); + debugl1(cs, cs->dlog); + } +} + +static void +W6692B_empty_fifo(struct BCState *bcs, int count) +{ + u_char *ptr; + struct IsdnCardState *cs = bcs->cs; + long flags; + + if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) + debugl1(cs, "W6692B_empty_fifo"); + + if (bcs->hw.w6692.rcvidx + count > HSCX_BUFMAX) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692B_empty_fifo: incoming packet too large"); + cs->BC_Write_Reg(cs, bcs->hw.w6692.bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); + bcs->hw.w6692.rcvidx = 0; + return; + } + ptr = bcs->hw.w6692.rcvbuf + bcs->hw.w6692.rcvidx; + bcs->hw.w6692.rcvidx += count; + save_flags(flags); + cli(); + READW6692BFIFO(cs, bcs->hw.w6692.bchan, ptr, count); + cs->BC_Write_Reg(cs, bcs->hw.w6692.bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT); + restore_flags(flags); + if (cs->debug & L1_DEB_HSCX_FIFO) { + char *t = bcs->blog; + + t += sprintf(t, "W6692B_empty_fifo %c cnt %d", + bcs->hw.w6692.bchan ? 'B' : 'A', count); + QuickHex(t, ptr, count); + debugl1(cs, bcs->blog); + } +} + +static void +W6692B_fill_fifo(struct BCState *bcs) +{ + struct IsdnCardState *cs = bcs->cs; + int more, count; + u_char *ptr; + long flags; + + + if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) + debugl1(cs, "W6692B_fill_fifo"); + + if (!bcs->tx_skb) + return; + if (bcs->tx_skb->len <= 0) + return; + + more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; + if (bcs->tx_skb->len > W_B_FIFO_THRESH) { + more = !0; + count = W_B_FIFO_THRESH; + } else + count = bcs->tx_skb->len; + + save_flags(flags); + cli(); + ptr = bcs->tx_skb->data; + skb_pull(bcs->tx_skb, count); + bcs->tx_cnt -= count; + bcs->hw.w6692.count += count; + WRITEW6692BFIFO(cs, bcs->hw.w6692.bchan, ptr, count); + cs->BC_Write_Reg(cs, bcs->hw.w6692.bchan, W_B_CMDR, W_B_CMDR_RACT | W_B_CMDR_XMS | (more ? 0 : W_B_CMDR_XME)); + restore_flags(flags); + if (cs->debug & L1_DEB_HSCX_FIFO) { + char *t = bcs->blog; + + t += sprintf(t, "W6692B_fill_fifo %c cnt %d", + bcs->hw.w6692.bchan ? 'B' : 'A', count); + QuickHex(t, ptr, count); + debugl1(cs, bcs->blog); + } +} + +static void +W6692B_interrupt(struct IsdnCardState *cs, u_char bchan) +{ + u_char val; + u_char r; + struct BCState *bcs = cs->bcs + bchan; + struct sk_buff *skb; + int count; + + val = cs->BC_Read_Reg(cs, bchan, W_B_EXIR); + debugl1(cs, "W6692B chan %d B_EXIR 0x%02X", bchan, val); + + if (!test_bit(BC_FLG_INIT, &bcs->Flag)) { + debugl1(cs, "W6692B not INIT yet"); + return; + } + if (val & W_B_EXI_RME) { /* RME */ + r = cs->BC_Read_Reg(cs, bchan, W_B_STAR); + if (r & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB | W_B_STAR_XDOW)) { + if ((r & W_B_STAR_RDOV) && bcs->mode) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692 B RDOV mode=%d", + bcs->mode); + if (r & W_B_STAR_CRCE) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692 B CRC error"); + cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RRST | W_B_CMDR_RACT); + } else { + count = cs->BC_Read_Reg(cs, bchan, W_B_RBCL) & (W_B_FIFO_THRESH - 1); + if (count == 0) + count = W_B_FIFO_THRESH; + W6692B_empty_fifo(bcs, count); + if ((count = bcs->hw.w6692.rcvidx) > 0) { + if (cs->debug & L1_DEB_HSCX_FIFO) + debugl1(cs, "W6692 Bchan Frame %d", count); + if (!(skb = dev_alloc_skb(count))) + printk(KERN_WARNING "W6692: Bchan receive out of memory\n"); + else { + memcpy(skb_put(skb, count), bcs->hw.w6692.rcvbuf, count); + skb_queue_tail(&bcs->rqueue, skb); + } + } + } + bcs->hw.w6692.rcvidx = 0; + W6692B_sched_event(bcs, B_RCVBUFREADY); + } + if (val & W_B_EXI_RMR) { /* RMR */ + W6692B_empty_fifo(bcs, W_B_FIFO_THRESH); + if (bcs->mode == L1_MODE_TRANS) { + /* receive audio data */ + if (!(skb = dev_alloc_skb(W_B_FIFO_THRESH))) + printk(KERN_WARNING "HiSax: receive out of memory\n"); + else { + memcpy(skb_put(skb, W_B_FIFO_THRESH), bcs->hw.w6692.rcvbuf, W_B_FIFO_THRESH); + skb_queue_tail(&bcs->rqueue, skb); + } + bcs->hw.w6692.rcvidx = 0; + W6692B_sched_event(bcs, B_RCVBUFREADY); + } + } + if (val & W_B_EXI_XFR) { /* XFR */ + if (bcs->tx_skb) { + if (bcs->tx_skb->len) { + W6692B_fill_fifo(bcs); + return; + } else { + if (bcs->st->lli.l1writewakeup && + (PACKET_NOACK != bcs->tx_skb->pkt_type)) + bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.w6692.count); + dev_kfree_skb(bcs->tx_skb); + bcs->hw.w6692.count = 0; + bcs->tx_skb = NULL; + } + } + if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { + bcs->hw.w6692.count = 0; + test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); + W6692B_fill_fifo(bcs); + } else { + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + W6692B_sched_event(bcs, B_XMTBUFREADY); + } + } + if (val & W_B_EXI_XDUN) { /* XDUN */ + if (bcs->mode == 1) + W6692B_fill_fifo(bcs); + else { + /* Here we lost an TX interrupt, so + * restart transmitting the whole frame. + */ + if (bcs->tx_skb) { + skb_push(bcs->tx_skb, bcs->hw.w6692.count); + bcs->tx_cnt += bcs->hw.w6692.count; + bcs->hw.w6692.count = 0; + } + cs->BC_Write_Reg(cs, bcs->hw.w6692.bchan, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT); + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692 B EXIR %x Lost TX", val); + } + } +} + +static void +W6692_interrupt(int intno, void *dev_id, struct pt_regs *regs) +{ + struct IsdnCardState *cs = dev_id; + u_char val, exval, v1; + struct sk_buff *skb; + unsigned int count; + long flags; + int icnt = 5; + + if (!cs) { + printk(KERN_WARNING "W6692: Spurious interrupt!\n"); + return; + } + val = cs->readW6692(cs, W_ISTA); + + StartW6692: + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "W6692 ISTA %x", val); + + if (val & W_INT_D_RME) { /* RME */ + exval = cs->readW6692(cs, W_D_RSTA); + if (exval & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) { + if (exval & W_D_RSTA_RDOV) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692 RDOV"); + if (exval & W_D_RSTA_CRCE) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692 D-channel CRC error"); + if (exval & W_D_RSTA_RMB) + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692 D-channel ABORT"); + cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST); + } else { + count = cs->readW6692(cs, W_D_RBCL) & (W_D_FIFO_THRESH - 1); + if (count == 0) + count = W_D_FIFO_THRESH; + W6692_empty_fifo(cs, count); + save_flags(flags); + cli(); + if ((count = cs->rcvidx) > 0) { + cs->rcvidx = 0; + if (!(skb = alloc_skb(count, GFP_ATOMIC))) + printk(KERN_WARNING "HiSax: D receive out of memory\n"); + else { + memcpy(skb_put(skb, count), cs->rcvbuf, count); + skb_queue_tail(&cs->rq, skb); + } + } + restore_flags(flags); + } + cs->rcvidx = 0; + W6692_sched_event(cs, D_RCVBUFREADY); + } + if (val & W_INT_D_RMR) { /* RMR */ + W6692_empty_fifo(cs, W_D_FIFO_THRESH); + } + if (val & W_INT_D_XFR) { /* XFR */ + if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) + del_timer(&cs->dbusytimer); + if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) + W6692_sched_event(cs, D_CLEARBUSY); + if (cs->tx_skb) { + if (cs->tx_skb->len) { + W6692_fill_fifo(cs); + goto afterXFR; + } else { + dev_kfree_skb(cs->tx_skb); + cs->tx_cnt = 0; + cs->tx_skb = NULL; + } + } + if ((cs->tx_skb = skb_dequeue(&cs->sq))) { + cs->tx_cnt = 0; + W6692_fill_fifo(cs); + } else + W6692_sched_event(cs, D_XMTBUFREADY); + } + afterXFR: + if (val & (W_INT_XINT0 | W_INT_XINT1)) { /* XINT0/1 - never */ + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "W6692 spurious XINT!"); + } + if (val & W_INT_D_EXI) { /* EXI */ + exval = cs->readW6692(cs, W_D_EXIR); + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692 D_EXIR %02x", exval); + if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) { /* Transmit underrun/collision */ + debugl1(cs, "W6692 D-chan underrun/collision"); + printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL\n"); + if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) + del_timer(&cs->dbusytimer); + if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) + W6692_sched_event(cs, D_CLEARBUSY); + if (cs->tx_skb) { /* Restart frame */ + skb_push(cs->tx_skb, cs->tx_cnt); + cs->tx_cnt = 0; + W6692_fill_fifo(cs); + } else { + printk(KERN_WARNING "HiSax: W6692 XDUN/XCOL no skb\n"); + debugl1(cs, "W6692 XDUN/XCOL no skb"); + cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST); + } + } + if (exval & W_D_EXI_RDOV) { /* RDOV */ + debugl1(cs, "W6692 D-channel RDOV"); + printk(KERN_WARNING "HiSax: W6692 D-RDOV\n"); + cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST); + } + if (exval & W_D_EXI_TIN2) { /* TIN2 - never */ + debugl1(cs, "W6692 spurious TIN2 interrupt"); + } + if (exval & W_D_EXI_MOC) { /* MOC - not supported */ + debugl1(cs, "W6692 spurious MOC interrupt"); + v1 = cs->readW6692(cs, W_MOSR); + debugl1(cs, "W6692 MOSR %02x", v1); + } + if (exval & W_D_EXI_ISC) { /* ISC - Level1 change */ + v1 = cs->readW6692(cs, W_CIR); + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "W6692 ISC CIR=0x%02X", v1); + if (v1 & W_CIR_ICC) { + cs->dc.w6692.ph_state = v1 & W_CIR_COD_MASK; + if (cs->debug & L1_DEB_ISAC) + debugl1(cs, "ph_state_change %x", cs->dc.w6692.ph_state); + W6692_sched_event(cs, D_L1STATECHANGE); + } + if (v1 & W_CIR_SCC) { + v1 = cs->readW6692(cs, W_SQR); + debugl1(cs, "W6692 SCC SQR=0x%02X", v1); + } + } + if (exval & W_D_EXI_WEXP) { + debugl1(cs, "W6692 spurious WEXP interrupt!"); + } + if (exval & W_D_EXI_TEXP) { + debugl1(cs, "W6692 spurious TEXP interrupt!"); + } + } + if (val & W_INT_B1_EXI) { + debugl1(cs, "W6692 B channel 1 interrupt"); + W6692B_interrupt(cs, 0); + } + if (val & W_INT_B2_EXI) { + debugl1(cs, "W6692 B channel 2 interrupt"); + W6692B_interrupt(cs, 1); + } + val = cs->readW6692(cs, W_ISTA); + if (val && icnt) { + icnt--; + goto StartW6692; + } + if (!icnt) { + printk(KERN_WARNING "W6692 IRQ LOOP\n"); + cs->writeW6692(cs, W_IMASK, 0xff); + } +} + +static void +W6692_l1hw(struct PStack *st, int pr, void *arg) +{ + struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware; + struct sk_buff *skb = arg; + int val; + + switch (pr) { + case (PH_DATA | REQUEST): + if (cs->debug & DEB_DLOG_HEX) + LogFrame(cs, skb->data, skb->len); + if (cs->debug & DEB_DLOG_VERBOSE) + dlogframe(cs, skb, 0); + if (cs->tx_skb) { + skb_queue_tail(&cs->sq, skb); +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + Logl2Frame(cs, skb, "PH_DATA Queued", 0); +#endif + } else { + cs->tx_skb = skb; + cs->tx_cnt = 0; +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + Logl2Frame(cs, skb, "PH_DATA", 0); +#endif + W6692_fill_fifo(cs); + } + break; + case (PH_PULL | INDICATION): + if (cs->tx_skb) { + if (cs->debug & L1_DEB_WARN) + debugl1(cs, " l2l1 tx_skb exist this shouldn't happen"); + skb_queue_tail(&cs->sq, skb); + break; + } + if (cs->debug & DEB_DLOG_HEX) + LogFrame(cs, skb->data, skb->len); + if (cs->debug & DEB_DLOG_VERBOSE) + dlogframe(cs, skb, 0); + cs->tx_skb = skb; + cs->tx_cnt = 0; +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + Logl2Frame(cs, skb, "PH_DATA_PULLED", 0); +#endif + W6692_fill_fifo(cs); + break; + case (PH_PULL | REQUEST): +#ifdef L2FRAME_DEBUG /* psa */ + if (cs->debug & L1_DEB_LAPD) + debugl1(cs, "-> PH_REQUEST_PULL"); +#endif + if (!cs->tx_skb) { + test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); + } else + test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + break; + case (HW_RESET | REQUEST): + if ((cs->dc.w6692.ph_state == W_L1IND_DRD)) + ph_command(cs, W_L1CMD_ECK); + else { + ph_command(cs, W_L1CMD_RST); + cs->dc.w6692.ph_state = W_L1CMD_RST; + W6692_new_ph(cs); + } + break; + case (HW_ENABLE | REQUEST): + ph_command(cs, W_L1CMD_ECK); + break; + case (HW_INFO3 | REQUEST): + ph_command(cs, W_L1CMD_AR8); + break; + case (HW_TESTLOOP | REQUEST): + val = 0; + if (1 & (long) arg) + val |= 0x0c; + if (2 & (long) arg) + val |= 0x3; + /* !!! not implemented yet */ + break; + case (HW_DEACTIVATE | RESPONSE): + discard_queue(&cs->rq); + discard_queue(&cs->sq); + if (cs->tx_skb) { + dev_kfree_skb(cs->tx_skb); + cs->tx_skb = NULL; + } + if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) + del_timer(&cs->dbusytimer); + if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags)) + W6692_sched_event(cs, D_CLEARBUSY); + break; + default: + if (cs->debug & L1_DEB_WARN) + debugl1(cs, "W6692_l1hw unknown %04x", pr); + break; + } +} + +static void +setstack_W6692(struct PStack *st, struct IsdnCardState *cs) +{ + st->l1.l1hw = W6692_l1hw; +} + +static void +DC_Close_W6692(struct IsdnCardState *cs) +{ +} + +static void +dbusy_timer_handler(struct IsdnCardState *cs) +{ + struct PStack *stptr; + int rbch, star; + + if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) { + rbch = cs->readW6692(cs, W_D_RBCH); + star = cs->readW6692(cs, W_D_STAR); + if (cs->debug) + debugl1(cs, "D-Channel Busy D_RBCH %02x D_STAR %02x", + rbch, star); + if (star & W_D_STAR_XBZ) { /* D-Channel Busy */ + test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags); + stptr = cs->stlist; + while (stptr != NULL) { + stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL); + stptr = stptr->next; + } + } else { + /* discard frame; reset transceiver */ + test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags); + if (cs->tx_skb) { + dev_kfree_skb(cs->tx_skb); + cs->tx_cnt = 0; + cs->tx_skb = NULL; + } else { + printk(KERN_WARNING "HiSax: W6692 D-Channel Busy no skb\n"); + debugl1(cs, "D-Channel Busy no skb"); + } + cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_XRST); /* Transmitter reset */ + cs->irq_func(cs->irq, cs, NULL); + } + } +} + +static void +W6692Bmode(struct BCState *bcs, int mode, int bc) +{ + struct IsdnCardState *cs = bcs->cs; + int bchan = bcs->hw.w6692.bchan; + + if (cs->debug & L1_DEB_HSCX) + debugl1(cs, "w6692 %c mode %d ichan %d", + '1' + bchan, mode, bc); + bcs->mode = mode; + bcs->channel = bc; + + switch (mode) { + case (L1_MODE_NULL): + cs->BC_Write_Reg(cs, bchan, W_B_MODE, 0); + break; + case (L1_MODE_TRANS): + cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_MMS); + break; + case (L1_MODE_HDLC): + cs->BC_Write_Reg(cs, bchan, W_B_MODE, W_B_MODE_ITF); + cs->BC_Write_Reg(cs, bchan, W_B_ADM1, 0xff); + cs->BC_Write_Reg(cs, bchan, W_B_ADM2, 0xff); + break; + } + if (mode) + cs->BC_Write_Reg(cs, bchan, W_B_CMDR, W_B_CMDR_RRST | + W_B_CMDR_RACT | W_B_CMDR_XRST); + cs->BC_Write_Reg(cs, bchan, W_B_EXIM, 0x00); +} + +static void +W6692_l2l1(struct PStack *st, int pr, void *arg) +{ + struct sk_buff *skb = arg; + long flags; + + switch (pr) { + case (PH_DATA | REQUEST): + save_flags(flags); + cli(); + if (st->l1.bcs->tx_skb) { + skb_queue_tail(&st->l1.bcs->squeue, skb); + restore_flags(flags); + } else { + st->l1.bcs->tx_skb = skb; + test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + st->l1.bcs->hw.w6692.count = 0; + restore_flags(flags); + st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); + } + break; + case (PH_PULL | INDICATION): + if (st->l1.bcs->tx_skb) { + printk(KERN_WARNING "W6692_l2l1: this shouldn't happen\n"); + break; + } + test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + st->l1.bcs->tx_skb = skb; + st->l1.bcs->hw.w6692.count = 0; + st->l1.bcs->cs->BC_Send_Data(st->l1.bcs); + break; + case (PH_PULL | REQUEST): + if (!st->l1.bcs->tx_skb) { + test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + st->l1.l1l2(st, PH_PULL | CONFIRM, NULL); + } else + test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags); + break; + case (PH_ACTIVATE | REQUEST): + test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); + W6692Bmode(st->l1.bcs, st->l1.mode, st->l1.bc); + l1_msg_b(st, pr, arg); + break; + case (PH_DEACTIVATE | REQUEST): + l1_msg_b(st, pr, arg); + break; + case (PH_DEACTIVATE | CONFIRM): + test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag); + test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag); + W6692Bmode(st->l1.bcs, 0, st->l1.bc); + st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL); + break; + } +} + +static void +close_w6692state(struct BCState *bcs) +{ + W6692Bmode(bcs, 0, bcs->channel); + if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { + if (bcs->hw.w6692.rcvbuf) { + kfree(bcs->hw.w6692.rcvbuf); + bcs->hw.w6692.rcvbuf = NULL; + } + if (bcs->blog) { + kfree(bcs->blog); + bcs->blog = NULL; + } + discard_queue(&bcs->rqueue); + discard_queue(&bcs->squeue); + if (bcs->tx_skb) { + dev_kfree_skb(bcs->tx_skb); + bcs->tx_skb = NULL; + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + } + } +} + +static int +open_w6692state(struct IsdnCardState *cs, struct BCState *bcs) +{ + if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) { + if (!(bcs->hw.w6692.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for w6692.rcvbuf\n"); + test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); + return (1); + } + if (!(bcs->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for bcs->blog\n"); + test_and_clear_bit(BC_FLG_INIT, &bcs->Flag); + kfree(bcs->hw.w6692.rcvbuf); + bcs->hw.w6692.rcvbuf = NULL; + return (2); + } + skb_queue_head_init(&bcs->rqueue); + skb_queue_head_init(&bcs->squeue); + } + bcs->tx_skb = NULL; + test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); + bcs->event = 0; + bcs->hw.w6692.rcvidx = 0; + bcs->tx_cnt = 0; + return (0); +} + +static int +setstack_w6692(struct PStack *st, struct BCState *bcs) +{ + bcs->channel = st->l1.bc; + if (open_w6692state(st->l1.hardware, bcs)) + return (-1); + st->l1.bcs = bcs; + st->l2.l2l1 = W6692_l2l1; + setstack_manager(st); + bcs->st = st; + setstack_l1_B(st); + return (0); +} + +HISAX_INITFUNC(void initW6692(struct IsdnCardState *cs, int part)) +{ + if (part & 1) { + cs->tqueue.routine = (void *) (void *) W6692_bh; + cs->setstack_d = setstack_W6692; + cs->DC_Close = DC_Close_W6692; + cs->dbusytimer.function = (void *) dbusy_timer_handler; + cs->dbusytimer.data = (long) cs; + init_timer(&cs->dbusytimer); + + cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST); + cs->writeW6692(cs, W_D_CTL, 0x00); + cs->writeW6692(cs, W_IMASK, 0xff); + cs->writeW6692(cs, W_D_SAM, 0xff); + cs->writeW6692(cs, W_D_TAM, 0xff); + cs->writeW6692(cs, W_D_EXIM, 0x00); + cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT); + cs->writeW6692(cs, W_IMASK, 0x18); + ph_command(cs, W_L1CMD_RST); + cs->dc.w6692.ph_state = W_L1CMD_RST; + W6692_new_ph(cs); + ph_command(cs, W_L1CMD_ECK); + + cs->bcs[0].BC_SetStack = setstack_w6692; + cs->bcs[1].BC_SetStack = setstack_w6692; + cs->bcs[0].BC_Close = close_w6692state; + cs->bcs[1].BC_Close = close_w6692state; + cs->bcs[0].hw.w6692.bchan = 0; + cs->bcs[1].hw.w6692.bchan = 1; + W6692Bmode(cs->bcs, 0, 0); + W6692Bmode(cs->bcs + 1, 0, 0); + } + if (part & 2) { + /* Reenable all IRQ */ + cs->writeW6692(cs, W_IMASK, 0x18); + cs->writeW6692(cs, W_D_EXIM, 0x00); + cs->BC_Write_Reg(cs, 0, W_B_EXIM, 0x00); + cs->BC_Write_Reg(cs, 1, W_B_EXIM, 0x00); + /* Reset D-chan receiver and transmitter */ + cs->writeW6692(cs, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST); + } +} + +/* Interface functions */ + +static u_char +ReadW6692(struct IsdnCardState *cs, u_char offset) +{ + return (inb(cs->hw.w6692.iobase + offset)); +} + +static void +WriteW6692(struct IsdnCardState *cs, u_char offset, u_char value) +{ + outb(value, cs->hw.w6692.iobase + offset); +} + +static void +ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + insb(cs->hw.w6692.iobase + W_D_RFIFO, data, size); +} + +static void +WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size) +{ + outsb(cs->hw.w6692.iobase + W_D_XFIFO, data, size); +} + +static u_char +ReadW6692B(struct IsdnCardState *cs, int bchan, u_char offset) +{ + return (inb(cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset)); +} + +static void +WriteW6692B(struct IsdnCardState *cs, int bchan, u_char offset, u_char value) +{ + outb(value, cs->hw.w6692.iobase + (bchan ? 0x40 : 0) + offset); +} + +static int +w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg) +{ + switch (mt) { + case CARD_RESET: + return (0); + case CARD_RELEASE: + release_region(cs->hw.w6692.iobase, 256); + return (0); + case CARD_INIT: + initW6692(cs, 3); + return (0); + case CARD_TEST: + return (0); + } + return (0); +} + +static int id_idx = 0; + +static struct pci_dev *dev_w6692 __initdata = NULL; + +__initfunc(int setup_w6692(struct IsdnCard *card)) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + u_char found = 0; + u_char pci_irq = 0; + u_int pci_ioaddr = 0; + + strcpy(tmp, w6692_revision); + printk(KERN_INFO "HiSax: W6692 driver Rev. %s\n", HiSax_getrev(tmp)); + if (cs->typ != ISDN_CTYPE_W6692) + return (0); +#if CONFIG_PCI + if (!pci_present()) { + printk(KERN_ERR "W6692: no PCI bus present\n"); + return (0); + } + while (id_list[id_idx].vendor_id) { + dev_w6692 = pci_find_device(id_list[id_idx].vendor_id, + id_list[id_idx].device_id, + dev_w6692); + if (dev_w6692) + break; + id_idx++; + } + if (dev_w6692) { + found = 1; + pci_irq = dev_w6692->irq; + /* I think address 0 is allways the configuration area */ + /* and address 1 is the real IO space KKe 03.09.99 */ + pci_ioaddr = dev_w6692->resource[ 1].start; + } + if (!found) { + printk(KERN_WARNING "W6692: No PCI card found\n"); + return (0); + } + cs->irq = pci_irq; + if (!cs->irq) { + printk(KERN_WARNING "W6692: No IRQ for PCI card found\n"); + return (0); + } + pci_ioaddr &= PCI_BASE_ADDRESS_IO_MASK; + if (!pci_ioaddr) { + printk(KERN_WARNING "W6692: NO I/O Base Address found\n"); + return (0); + } + cs->hw.w6692.iobase = pci_ioaddr; + printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n", + id_list[id_idx].vendor_name, id_list[id_idx].card_name, + pci_ioaddr, dev_w6692->irq); + if (check_region((cs->hw.w6692.iobase), 256)) { + printk(KERN_WARNING + "HiSax: %s I/O ports %x-%x already in use\n", + id_list[id_idx].card_name, + cs->hw.w6692.iobase, + cs->hw.w6692.iobase + 255); + return (0); + } else { + request_region(cs->hw.w6692.iobase, 256, + id_list[id_idx].card_name); + } +#else + printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n"); + printk(KERN_WARNING "HiSax: W6692 unable to config\n"); + return (0); +#endif /* CONFIG_PCI */ + + printk(KERN_INFO + "HiSax: %s config irq:%d I/O:%x\n", + id_list[id_idx].card_name, cs->irq, + cs->hw.w6692.iobase); + + cs->readW6692 = &ReadW6692; + cs->writeW6692 = &WriteW6692; + cs->readisacfifo = &ReadISACfifo; + cs->writeisacfifo = &WriteISACfifo; + cs->BC_Read_Reg = &ReadW6692B; + cs->BC_Write_Reg = &WriteW6692B; + cs->BC_Send_Data = &W6692B_fill_fifo; + cs->cardmsg = &w6692_card_msg; + cs->irq_func = &W6692_interrupt; + W6692Version(cs, "W6692:"); + printk(KERN_INFO "W6692 ISTA=0x%X\n", ReadW6692(cs, W_ISTA)); + printk(KERN_INFO "W6692 IMASK=0x%X\n", ReadW6692(cs, W_IMASK)); + printk(KERN_INFO "W6692 D_EXIR=0x%X\n", ReadW6692(cs, W_D_EXIR)); + printk(KERN_INFO "W6692 D_EXIM=0x%X\n", ReadW6692(cs, W_D_EXIM)); + printk(KERN_INFO "W6692 D_RSTA=0x%X\n", ReadW6692(cs, W_D_RSTA)); + return (1); +} diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/hisax/w6692.h linux/drivers/isdn/hisax/w6692.h --- v2.3.26/linux/drivers/isdn/hisax/w6692.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/isdn/hisax/w6692.h Sun Nov 7 16:34:00 1999 @@ -0,0 +1,190 @@ +/* $Id: w6692.h,v 1.1 1999/09/04 06:28:58 keil Exp $ + + * w6692.h Winbond W6692 specific defines + * + * Author Petr Novak + * + * + * $Log: w6692.h,v $ + * Revision 1.1 1999/09/04 06:28:58 keil + * first revision + * + * + * Revision 1.0 1999/08/28 21:58:00 pnovak + * first version + * + * + */ + +/* map W6692 functions to ISAC functions */ +#define readW6692 readisac +#define writeW6692 writeisac +#define readW6692fifo readisacfifo +#define writeW6692fifo writeisacfifo + +/* B-channel FIFO read/write routines */ + +#define READW6692BFIFO(cs,bchan,ptr,count) \ + insb(cs->hw.w6692.iobase+W_B_RFIFO+(bchan?0x40:0),ptr,count) + +#define WRITEW6692BFIFO(cs,bchan,ptr,count) \ + outsb(cs->hw.w6692.iobase+W_B_XFIFO+(bchan?0x40:0),ptr,count) + +/* Specifications of W6692 registers */ + +#define W_D_RFIFO 0x00 /* R */ +#define W_D_XFIFO 0x04 /* W */ +#define W_D_CMDR 0x08 /* W */ +#define W_D_MODE 0x0c /* R/W */ +#define W_D_TIMR 0x10 /* R/W */ +#define W_ISTA 0x14 /* R_clr */ +#define W_IMASK 0x18 /* R/W */ +#define W_D_EXIR 0x1c /* R_clr */ +#define W_D_EXIM 0x20 /* R/W */ +#define W_D_STAR 0x24 /* R */ +#define W_D_RSTA 0x28 /* R */ +#define W_D_SAM 0x2c /* R/W */ +#define W_D_SAP1 0x30 /* R/W */ +#define W_D_SAP2 0x34 /* R/W */ +#define W_D_TAM 0x38 /* R/W */ +#define W_D_TEI1 0x3c /* R/W */ +#define W_D_TEI2 0x40 /* R/W */ +#define W_D_RBCH 0x44 /* R */ +#define W_D_RBCL 0x48 /* R */ +#define W_TIMR2 0x4c /* W */ +#define W_L1_RC 0x50 /* R/W */ +#define W_D_CTL 0x54 /* R/W */ +#define W_CIR 0x58 /* R */ +#define W_CIX 0x5c /* W */ +#define W_SQR 0x60 /* R */ +#define W_SQX 0x64 /* W */ +#define W_PCTL 0x68 /* R/W */ +#define W_MOR 0x6c /* R */ +#define W_MOX 0x70 /* R/W */ +#define W_MOSR 0x74 /* R_clr */ +#define W_MOCR 0x78 /* R/W */ +#define W_GCR 0x7c /* R/W */ + +#define W_B_RFIFO 0x80 /* R */ +#define W_B_XFIFO 0x84 /* W */ +#define W_B_CMDR 0x88 /* W */ +#define W_B_MODE 0x8c /* R/W */ +#define W_B_EXIR 0x90 /* R_clr */ +#define W_B_EXIM 0x94 /* R/W */ +#define W_B_STAR 0x98 /* R */ +#define W_B_ADM1 0x9c /* R/W */ +#define W_B_ADM2 0xa0 /* R/W */ +#define W_B_ADR1 0xa4 /* R/W */ +#define W_B_ADR2 0xa8 /* R/W */ +#define W_B_RBCL 0xac /* R */ +#define W_B_RBCH 0xb0 /* R */ + +#define W_XADDR 0xf4 /* R/W */ +#define W_XDATA 0xf8 /* R/W */ +#define W_EPCTL 0xfc /* W */ + +/* W6692 register bits */ + +#define W_D_CMDR_XRST 0x01 +#define W_D_CMDR_XME 0x02 +#define W_D_CMDR_XMS 0x08 +#define W_D_CMDR_STT 0x10 +#define W_D_CMDR_RRST 0x40 +#define W_D_CMDR_RACK 0x80 + +#define W_D_MODE_RLP 0x01 +#define W_D_MODE_DLP 0x02 +#define W_D_MODE_MFD 0x04 +#define W_D_MODE_TEE 0x08 +#define W_D_MODE_TMS 0x10 +#define W_D_MODE_RACT 0x40 +#define W_D_MODE_MMS 0x80 + +#define W_INT_B2_EXI 0x01 +#define W_INT_B1_EXI 0x02 +#define W_INT_D_EXI 0x04 +#define W_INT_XINT0 0x08 +#define W_INT_XINT1 0x10 +#define W_INT_D_XFR 0x20 +#define W_INT_D_RME 0x40 +#define W_INT_D_RMR 0x80 + +#define W_D_EXI_WEXP 0x01 +#define W_D_EXI_TEXP 0x02 +#define W_D_EXI_ISC 0x04 +#define W_D_EXI_MOC 0x08 +#define W_D_EXI_TIN2 0x10 +#define W_D_EXI_XCOL 0x20 +#define W_D_EXI_XDUN 0x40 +#define W_D_EXI_RDOV 0x80 + +#define W_D_STAR_DRDY 0x10 +#define W_D_STAR_XBZ 0x20 +#define W_D_STAR_XDOW 0x80 + +#define W_D_RSTA_RMB 0x10 +#define W_D_RSTA_CRCE 0x20 +#define W_D_RSTA_RDOV 0x40 + +#define W_D_CTL_SRST 0x20 + +#define W_CIR_SCC 0x80 +#define W_CIR_ICC 0x40 +#define W_CIR_COD_MASK 0x0f + +#define W_B_CMDR_XRST 0x01 +#define W_B_CMDR_XME 0x02 +#define W_B_CMDR_XMS 0x04 +#define W_B_CMDR_RACT 0x20 +#define W_B_CMDR_RRST 0x40 +#define W_B_CMDR_RACK 0x80 + +#define W_B_MODE_FTS0 0x01 +#define W_B_MODE_FTS1 0x02 +#define W_B_MODE_SW56 0x04 +#define W_B_MODE_BSW0 0x08 +#define W_B_MODE_BSW1 0x10 +#define W_B_MODE_EPCM 0x20 +#define W_B_MODE_ITF 0x40 +#define W_B_MODE_MMS 0x80 + +#define W_B_EXI_XDUN 0x01 +#define W_B_EXI_XFR 0x02 +#define W_B_EXI_RDOV 0x10 +#define W_B_EXI_RME 0x20 +#define W_B_EXI_RMR 0x40 + +#define W_B_STAR_XBZ 0x01 +#define W_B_STAR_XDOW 0x04 +#define W_B_STAR_RMB 0x10 +#define W_B_STAR_CRCE 0x20 +#define W_B_STAR_RDOV 0x40 + +#define W_B_RBCH_LOV 0x20 + +/* W6692 Layer1 commands */ + +#define W_L1CMD_ECK 0x00 +#define W_L1CMD_RST 0x01 +#define W_L1CMD_SCP 0x04 +#define W_L1CMD_SSP 0x02 +#define W_L1CMD_AR8 0x08 +#define W_L1CMD_AR10 0x09 +#define W_L1CMD_EAL 0x0a +#define W_L1CMD_DRC 0x0f + +/* W6692 Layer1 indications */ + +#define W_L1IND_CE 0x07 +#define W_L1IND_DRD 0x00 +#define W_L1IND_LD 0x04 +#define W_L1IND_ARD 0x08 +#define W_L1IND_TI 0x0a +#define W_L1IND_ATI 0x0b +#define W_L1IND_AI8 0x0c +#define W_L1IND_AI10 0x0d +#define W_L1IND_CD 0x0f + +/* FIFO thresholds */ +#define W_D_FIFO_THRESH 64 +#define W_B_FIFO_THRESH 64 diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c --- v2.3.26/linux/drivers/isdn/icn/icn.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/isdn/icn/icn.c Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: icn.c,v 1.59 1999/08/28 22:10:55 keil Exp $ +/* $Id: icn.c,v 1.62 1999/09/06 07:29:35 fritz Exp $ * ISDN low-level module for the ICN active ISDN-Card. * - * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: icn.c,v $ + * Revision 1.62 1999/09/06 07:29:35 fritz + * Changed my mail-address. + * + * Revision 1.61 1999/09/03 14:06:58 fritz + * Fixed a memory leak. + * + * Revision 1.60 1999/08/31 11:20:32 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.59 1999/08/28 22:10:55 keil * __setup function should be static * @@ -238,7 +247,7 @@ #undef MAP_DEBUG static char -*revision = "$Revision: 1.59 $"; +*revision = "$Revision: 1.62 $"; static int icn_addcard(int, char *, char *); @@ -467,7 +476,7 @@ if (!eflag) { if ((cnt = card->rcvidx[channel])) { if (!(skb = dev_alloc_skb(cnt))) { - printk(KERN_WARNING "ïcn: receive out of memory\n"); + printk(KERN_WARNING "icn: receive out of memory\n"); break; } memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt); @@ -545,12 +554,10 @@ if (!skb->len) { save_flags(flags); cli(); - if (card->xskb[channel]) { + if (card->xskb[channel]) card->xskb[channel] = NULL; - restore_flags(flags); - dev_kfree_skb(skb); - } else - restore_flags(flags); + restore_flags(flags); + dev_kfree_skb(skb); if (card->xlen[channel]) { cmd.command = ISDN_STAT_BSENT; cmd.driver = card->myid; @@ -1852,7 +1859,6 @@ #ifdef MODULE #define icn_init init_module #else -#ifdef COMPAT_HAS_NEW_SETUP #include static int __init icn_setup(char *line) @@ -1863,14 +1869,6 @@ static char sid2[20]; str = get_options(line, 2, ints); -#else -void -icn_setup(char *str, int *ints) -{ - char *p; - static char sid[20]; - static char sid2[20]; -#endif if (ints[0]) portbase = ints[1]; if (ints[0] > 1) @@ -1884,13 +1882,9 @@ icn_id2 = sid2; } } -#ifdef COMPAT_HAS_NEW_SETUP return(1); } __setup("icn=", icn_setup); -#else -} -#endif #endif /* MODULES */ int diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/icn/icn.h linux/drivers/isdn/icn/icn.h --- v2.3.26/linux/drivers/isdn/icn/icn.h Sun May 23 10:03:41 1999 +++ linux/drivers/isdn/icn/icn.h Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: icn.h,v 1.28 1997/10/10 15:56:18 fritz Exp $ +/* $Id: icn.h,v 1.29 1999/09/06 07:29:35 fritz Exp $ * ISDN lowlevel-module for the ICN active ISDN-Card. * - * Copyright 1994 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1994 by Fritz Elfert (fritz@isdn4linux.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: icn.h,v $ + * Revision 1.29 1999/09/06 07:29:35 fritz + * Changed my mail-address. + * * Revision 1.28 1997/10/10 15:56:18 fritz * New HL<->LL interface: * New BSENT callback with nr. of bytes included. diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- v2.3.26/linux/drivers/isdn/isdn_common.c Fri Oct 15 15:25:13 1999 +++ linux/drivers/isdn/isdn_common.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_common.c,v 1.86 1999/07/31 12:59:42 armin Exp $ +/* $Id: isdn_common.c,v 1.93 1999/11/04 13:11:36 keil Exp $ * Linux ISDN subsystem, common used functions (linklevel). * @@ -21,6 +21,40 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_common.c,v $ + * Revision 1.93 1999/11/04 13:11:36 keil + * Reinit of v110 structs + * + * Revision 1.92 1999/10/31 15:59:50 he + * more skb headroom checks + * + * Revision 1.91 1999/10/28 22:48:45 armin + * Bugfix: isdn_free_channel() now frees the channel, + * even when the usage of the ttyI has changed. + * + * Revision 1.90 1999/10/27 21:21:17 detabc + * Added support for building logically-bind-group's per interface. + * usefull for outgoing call's with more then one isdn-card. + * + * Switchable support to dont reset the hangup-timeout for + * receive frames. Most part's of the timru-rules for receiving frames + * are now obsolete. If the input- or forwarding-firewall deny + * the frame, the line will be not hold open. + * + * Revision 1.89 1999/10/16 14:46:47 keil + * replace kmalloc with vmalloc for the big dev struct + * + * Revision 1.88 1999/10/02 00:39:26 he + * Fixed a 2.3.x wait queue initialization (was causing panics) + * + * Revision 1.87 1999/09/12 16:19:39 detabc + * added abc features + * low cost routing for net-interfaces (only the HL side). + * need more implementation in the isdnlog-utility + * udp info support (first part). + * different EAZ on outgoing call's. + * more checks on D-Channel callbacks (double use of channels). + * tested and running with kernel 2.3.17 + * * Revision 1.86 1999/07/31 12:59:42 armin * Added tty fax capabilities. * @@ -362,6 +396,7 @@ #include #include #include +#include #include #include "isdn_common.h" #include "isdn_tty.h" @@ -381,7 +416,7 @@ isdn_dev *dev = (isdn_dev *) 0; -static char *isdn_revision = "$Revision: 1.86 $"; +static char *isdn_revision = "$Revision: 1.93 $"; extern char *isdn_net_revision; extern char *isdn_tty_revision; @@ -1039,9 +1074,6 @@ isdn_free_queue(&dev->drv[di]->rpqueue[i]); kfree(dev->drv[di]->rpqueue); kfree(dev->drv[di]->rcv_waitq); -#ifndef COMPAT_HAS_NEW_WAITQ - kfree(dev->drv[di]->snd_waitq); -#endif kfree(dev->drv[di]); dev->drv[di] = NULL; dev->drvid[di][0] = '\0'; @@ -1103,11 +1135,7 @@ * of the mapping (di,ch)<->minor, happen during the sleep? --he */ int -#ifdef COMPAT_HAS_NEW_WAITQ isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep) -#else -isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, struct wait_queue **sleep) -#endif { int left; int count; @@ -1535,6 +1563,9 @@ * are serialized by means of a semaphore. */ switch (cmd) { + case IIOCNETLCR: + printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); + return -ENODEV; #ifdef CONFIG_NETDEVICES case IIOCNETAIF: /* Add a network-interface */ @@ -2092,13 +2123,19 @@ save_flags(flags); cli(); for (i = 0; i < ISDN_MAX_CHANNELS; i++) - if (((dev->usage[i] & ISDN_USAGE_MASK) == usage) && + if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && (dev->drvmap[i] == di) && (dev->chanmap[i] == ch)) { dev->usage[i] &= (ISDN_USAGE_NONE | ISDN_USAGE_EXCLUSIVE); strcpy(dev->num[i], "???"); dev->ibytes[i] = 0; dev->obytes[i] = 0; +// 20.10.99 JIM, try to reinitialize v110 ! + dev->v110emu[i] = 0; + atomic_set(&(dev->v110use[i]), 0); + isdn_v110_close(dev->v110[i]); + dev->v110[i] = NULL; +// 20.10.99 JIM, try to reinitialize v110 ! isdn_info_update(); isdn_free_queue(&dev->drv[di]->rpqueue[ch]); } @@ -2180,8 +2217,33 @@ /* V.110 must always be acknowledged */ ack = 1; ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, nskb); - } else - ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb); + } else { + int hl = dev->drv[drvidx]->interface->hl_hdrlen; + + if( skb_headroom(skb) < hl ){ + /* + * This should only occur when new HL driver with + * increased hl_hdrlen was loaded after netdevice + * was created and connected to the new driver. + * + * The V.110 branch (re-allocates on its own) does + * not need this + */ + struct sk_buff * skb_tmp; + + skb_tmp = skb_realloc_headroom(skb, hl); + printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed"); + if (!skb_tmp) return -ENOMEM; /* 0 better? */ + ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb_tmp); + if( ret > 0 ){ + dev_kfree_skb(skb); + } else { + dev_kfree_skb(skb_tmp); + } + } else { + ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb); + } + } if (ret > 0) { dev->obytes[idx] += ret; if (dev->v110[idx]) { @@ -2202,43 +2264,11 @@ int register_isdn_module(isdn_module *m) { -#if 0 - isdn_module_list **pp = &dev->modules; - isdn_module *new = kmalloc(sizeof(isdn_module_list), GFP_KERNEL); - - if (!new) { - printk(KERN_WARNING "isdn: Out of memory in register_isdn_module\n"); - return -1; - } - while (*pp && (*pp)->orig != m) - pp = &(*pp)->next; - if (*pp != NULL) { - printk(KERN_WARNING "isdn: Module %s already registered\n", m->name); - return -1; - } - while (*pp && ((*pp)->module.priority < m->priority)) - pp = &(*pp)->next; - new->next = *pp; - new->orig = m; - new->module = *m; - - *pp = new; -#endif return 0; } int unregister_isdn_module(isdn_module *m) { -#if 0 - isdn_module_list **pp = &dev->modules; - - while (*pp && *pp != m) - pp = &(*pp)->next; - if (*pp == NULL) { - printk(KERN_WARNING "isdn: Module %s not found\n", m->name); - return -1; - } -#endif return 0; } @@ -2248,9 +2278,7 @@ int j, k, m; ulong flags; -#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&d->st_waitq); -#endif if (d->flags & DRV_FLAG_RUNNING) return -1; if (n < 1) return 0; @@ -2300,14 +2328,9 @@ if ((adding) && (d->rcv_waitq)) kfree(d->rcv_waitq); -#ifdef COMPAT_HAS_NEW_WAITQ d->rcv_waitq = (wait_queue_head_t *) kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_KERNEL); if (!d->rcv_waitq) { -#else - if (!(d->rcv_waitq = (struct wait_queue **) - kmalloc(sizeof(struct wait_queue *) * m, GFP_KERNEL))) { -#endif printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n"); if (!adding) { kfree(d->rpqueue); @@ -2316,30 +2339,11 @@ } return -1; } -#ifdef COMPAT_HAS_NEW_WAITQ d->snd_waitq = d->rcv_waitq + m; for (j = 0; j < m; j++) { init_waitqueue_head(&d->rcv_waitq[j]); init_waitqueue_head(&d->snd_waitq[j]); } -#else - memset((char *) d->rcv_waitq, 0, sizeof(struct wait_queue *) * m); - - if ((adding) && (d->snd_waitq)) - kfree(d->snd_waitq); - if (!(d->snd_waitq = (struct wait_queue **) - kmalloc(sizeof(struct wait_queue *) * m, GFP_KERNEL))) { - printk(KERN_WARNING "register_isdn: Could not alloc snd_waitq\n"); - if (!adding) { - kfree(d->rcv_waitq); - kfree(d->rpqueue); - kfree(d->rcvcount); - kfree(d->rcverr); - } - return -1; - } - memset((char *) d->snd_waitq, 0, sizeof(struct wait_queue *) * m); -#endif dev->channels += n; save_flags(flags); @@ -2513,33 +2517,26 @@ int i; char tmprev[50]; - sti(); - if (!(dev = (isdn_dev *) kmalloc(sizeof(isdn_dev), GFP_KERNEL))) { + if (!(dev = (isdn_dev *) vmalloc(sizeof(isdn_dev)))) { printk(KERN_WARNING "isdn: Could not allocate device-struct.\n"); return -EIO; } memset((char *) dev, 0, sizeof(isdn_dev)); init_timer(&dev->timer); dev->timer.function = isdn_timer_funct; -#ifdef COMPAT_HAS_NEW_WAITQ init_MUTEX(&dev->sem); init_waitqueue_head(&dev->info_waitq); -#else - dev->sem = MUTEX; -#endif for (i = 0; i < ISDN_MAX_CHANNELS; i++) { dev->drvmap[i] = -1; dev->chanmap[i] = -1; dev->m_idx[i] = -1; strcpy(dev->num[i], "???"); -#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&dev->mdm.info[i].open_wait); init_waitqueue_head(&dev->mdm.info[i].close_wait); -#endif } if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) { printk(KERN_WARNING "isdn: Could not register control devices\n"); - kfree(dev); + vfree(dev); return -EIO; } if ((i = isdn_tty_modem_init()) < 0) { @@ -2548,7 +2545,7 @@ tty_unregister_driver(&dev->mdm.cua_modem); if (i <= -2) tty_unregister_driver(&dev->mdm.tty_modem); - kfree(dev); + vfree(dev); unregister_chrdev(ISDN_MAJOR, "isdn"); return -EIO; } @@ -2560,7 +2557,7 @@ for (i = 0; i < ISDN_MAX_CHANNELS; i++) kfree(dev->mdm.info[i].xmit_buf - 4); unregister_chrdev(ISDN_MAJOR, "isdn"); - kfree(dev); + vfree(dev); return -EIO; } #endif /* CONFIG_ISDN_PPP */ @@ -2629,7 +2626,7 @@ printk(KERN_WARNING "isdn: controldevice busy, remove cancelled\n"); } else { del_timer(&dev->timer); - kfree(dev); + vfree(dev); printk(KERN_NOTICE "ISDN-subsystem unloaded\n"); } restore_flags(flags); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_common.h linux/drivers/isdn/isdn_common.h --- v2.3.26/linux/drivers/isdn/isdn_common.h Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/isdn_common.h Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_common.h,v 1.16 1999/07/01 08:29:54 keil Exp $ +/* $Id: isdn_common.h,v 1.17 1999/10/27 21:21:17 detabc Exp $ * header for Linux ISDN subsystem, common used functions and debugging-switches (linklevel). * @@ -21,6 +21,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_common.h,v $ + * Revision 1.17 1999/10/27 21:21:17 detabc + * Added support for building logically-bind-group's per interface. + * usefull for outgoing call's with more then one isdn-card. + * + * Switchable support to dont reset the hangup-timeout for + * receive frames. Most part's of the timru-rules for receiving frames + * are now obsolete. If the input- or forwarding-firewall deny + * the frame, the line will be not hold open. + * * Revision 1.16 1999/07/01 08:29:54 keil * compatibility to 2.3 kernel * @@ -118,11 +127,7 @@ extern void isdn_timer_ctrl(int tf, int onoff); extern void isdn_unexclusive_channel(int di, int ch); extern int isdn_getnum(char **); -#ifdef COMPAT_HAS_NEW_WAITQ extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *); -#else -extern int isdn_readbchan(int, int, u_char *, u_char *, int, struct wait_queue**); -#endif extern int isdn_get_free_channel(int, int, int, int, int); extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *); extern int register_isdn(isdn_if * i); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c --- v2.3.26/linux/drivers/isdn/isdn_net.c Thu Aug 26 13:05:37 1999 +++ linux/drivers/isdn/isdn_net.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_net.c,v 1.89 1999/08/22 20:26:03 calle Exp $ +/* $Id: isdn_net.c,v 1.95 1999/10/27 21:21:17 detabc Exp $ * Linux ISDN subsystem, network interfaces and related functions (linklevel). * @@ -21,6 +21,38 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_net.c,v $ + * Revision 1.95 1999/10/27 21:21:17 detabc + * Added support for building logically-bind-group's per interface. + * usefull for outgoing call's with more then one isdn-card. + * + * Switchable support to dont reset the hangup-timeout for + * receive frames. Most part's of the timru-rules for receiving frames + * are now obsolete. If the input- or forwarding-firewall deny + * the frame, the line will be not hold open. + * + * Revision 1.94 1999/10/02 11:07:02 he + * Changed tbusy logic in indn_net.c + * + * Revision 1.93 1999/09/23 22:22:41 detabc + * added tcp-keepalive-detect with local response (ipv4 only) + * added host-only-interface support + * (source ipaddr == interface ipaddr) (ipv4 only) + * ok with kernel 2.3.18 and 2.2.12 + * + * Revision 1.92 1999/09/13 23:25:17 he + * serialized xmitting frames from isdn_ppp and BSENT statcallb + * + * Revision 1.91 1999/09/12 16:19:39 detabc + * added abc features + * low cost routing for net-interfaces (only the HL side). + * need more implementation in the isdnlog-utility + * udp info support (first part). + * different EAZ on outgoing call's. + * more checks on D-Channel callbacks (double use of channels). + * tested and running with kernel 2.3.17 + * + * Revision 1.90 1999/09/04 22:21:39 detabc + * * Revision 1.89 1999/08/22 20:26:03 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -360,13 +392,58 @@ #include "isdn_concap.h" #endif + +#ifndef ISDN_NEW_TBUSY +#define ISDN_NEW_TBUSY +#endif +#ifdef ISDN_NEW_TBUSY +/* + * Outline of new tbusy handling: + * + * Old method, roughly spoken, consisted of setting tbusy when entering + * isdn_net_start_xmit() and at several other locations and clearing + * it from isdn_net_start_xmit() thread when sending was successful. + * + * With 2.3.x multithreaded network core, to prevent problems, tbusy should + * only be set by the isdn_net_start_xmit() thread and only when a tx-busy + * condition is detected. Other threads (in particular isdn_net_stat_callb()) + * are only allowed to clear tbusy. + * + * -HE + */ + +/* + * Tell upper layers that the network device is ready to xmit more frames. + */ +static void __inline__ isdn_net_dev_xon(struct net_device * dev) +{ + dev->tbusy = 0; + mark_bh(NET_BH); +} + +static void __inline__ isdn_net_lp_xon(isdn_net_local * lp) +{ + lp->netdev->dev.tbusy = 0; + if(lp->master) lp->master->tbusy = 0; + mark_bh(NET_BH); +} + +/* + * Ask upper layers to temporarily cease passing us more xmit frames. + */ +static void __inline__ isdn_net_dev_xoff(struct net_device * dev) +{ + dev->tbusy = 1; +} +#endif + /* Prototypes */ int isdn_net_force_dial_lp(isdn_net_local *); static int isdn_net_start_xmit(struct sk_buff *, struct net_device *); static int isdn_net_xmit(struct net_device *, isdn_net_local *, struct sk_buff *); -char *isdn_net_revision = "$Revision: 1.89 $"; +char *isdn_net_revision = "$Revision: 1.95 $"; /* * Code for raw-networking over ISDN @@ -408,7 +485,11 @@ save_flags(flags); cli(); /* Avoid glitch on writes to CMD regs */ dev->interrupt = 0; +#ifdef ISDN_NEW_TBUSY + isdn_net_dev_xon(dev); +#else dev->tbusy = 0; +#endif #ifdef CONFIG_ISDN_X25 if( cprot && cprot -> pops && dops ) cprot -> pops -> restart ( cprot, dev, dops ); @@ -607,6 +688,13 @@ (!lp->dialstate)) { lp->stats.tx_packets++; lp->stats.tx_bytes += c->parm.length; + /* some HL drivers deliver + ISDN_STAT_BSENT from hw interrupt. + Output routines in isdn_ppp are now + called with irq disabled such that + dequeueing the sav_skb while another + frame is sent will not occur. + */ if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && lp->sav_skb) { struct net_device *mdev; if (lp->master) @@ -615,13 +703,19 @@ mdev = &lp->netdev->dev; if (!isdn_net_send_skb(mdev, lp, lp->sav_skb)) { lp->sav_skb = NULL; +#ifndef ISDN_NEW_TBUSY mark_bh(NET_BH); +#endif } else { return 1; } } +#ifdef ISDN_NEW_TBUSY + isdn_net_lp_xon(lp); +#else if (test_and_clear_bit(0, (void *) &(p->dev.tbusy))) mark_bh(NET_BH); +#endif } return 1; case ISDN_STAT_DCONN: @@ -704,7 +798,6 @@ lp->dialstarted = 0; lp->dialwait_timer = 0; - /* Immediately send first skb to speed up arp */ #ifdef CONFIG_ISDN_PPP if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) isdn_ppp_wakeup_daemon(lp); @@ -715,11 +808,15 @@ if( pops->connect_ind) pops->connect_ind(cprot); #endif /* CONFIG_ISDN_X25 */ + /* Immediately send first skb to speed up arp */ if (lp->first_skb) { if (!(isdn_net_xmit(&p->dev, lp, lp->first_skb))) lp->first_skb = NULL; } +#ifdef ISDN_NEW_TBUSY + if(! lp->first_skb) isdn_net_lp_xon(lp); +#else else { /* * dev.tbusy is usually cleared implicitly by isdn_net_xmit(,,lp->first_skb). @@ -728,6 +825,7 @@ lp->netdev->dev.tbusy = 0; mark_bh(NET_BH); } +#endif /* ISDN_NEW_TBUSY */ return 1; } break; @@ -1162,6 +1260,7 @@ break; } printk(KERN_INFO "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n", + p[12], p[13], p[14], p[15], p[16], p[17], p[18], p[19], addinfo); @@ -1180,8 +1279,12 @@ * standard send-routine, else send directly. * * Return: 0 on success, !0 on failure. + */ +#ifndef ISDN_NEW_TBUSY +/* * Side-effects: ndev->tbusy is cleared on success. */ +#endif int isdn_net_send_skb(struct net_device *ndev, isdn_net_local * lp, struct sk_buff *skb) @@ -1192,13 +1295,17 @@ ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb); if (ret == len) { lp->transcount += len; +#ifndef ISDN_NEW_TBUSY clear_bit(0, (void *) &(ndev->tbusy)); +#endif return 0; } if (ret < 0) { dev_kfree_skb(skb); lp->stats.tx_errors++; +#ifndef ISDN_NEW_TBUSY clear_bit(0, (void *) &(ndev->tbusy)); +#endif return 0; } return 1; @@ -1244,7 +1351,11 @@ if (lp->srobin == ndev) ret = isdn_net_send_skb(ndev, lp, skb); else +#ifdef ISDN_NEW_TBUSY + ret = isdn_net_start_xmit(skb, lp->srobin); +#else ret = ndev->tbusy = isdn_net_start_xmit(skb, lp->srobin); +#endif lp->srobin = (slp->slave) ? slp->slave : ndev; slp = (isdn_net_local *) (lp->srobin->priv); if (!((slp->flags & ISDN_NET_CONNECTED) && (slp->dialstate == 0))) @@ -1298,15 +1409,19 @@ #ifdef CONFIG_ISDN_X25 struct concap_proto * cprot = lp -> netdev -> cprot; #endif - if (ndev->tbusy) { if (jiffies - ndev->trans_start < (2 * HZ)) return 1; if (!lp->dialstate) lp->stats.tx_errors++; ndev->trans_start = jiffies; +#ifdef ISDN_NEW_TBUSY + isdn_net_dev_xon(ndev); +#endif } +#ifndef ISDN_NEW_TBUSY ndev->tbusy = 1; /* left instead of obsolete test_and_set_bit() */ +#endif #ifdef CONFIG_ISDN_X25 /* At this point hard_start_xmit() passes control to the encapsulation protocol (if present). @@ -1320,7 +1435,11 @@ when a dl_establish request is received from the upper layer. */ if( cprot ) { - return cprot -> pops -> encap_and_xmit ( cprot , skb); + int ret = cprot -> pops -> encap_and_xmit ( cprot , skb); +#ifdef ISDN_NEW_TBUSY + if(ret) isdn_net_dev_xoff(ndev); +#endif + return ret; } else #endif /* auto-dialing xmit function */ @@ -1339,7 +1458,9 @@ if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) { isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'"); dev_kfree_skb(skb); +#ifndef ISDN_NEW_TBUSY ndev->tbusy = 0; +#endif return 0; } if (lp->phone[1]) { @@ -1355,7 +1476,9 @@ if(jiffies < lp->dialwait_timer) { isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached"); dev_kfree_skb(skb); +#ifndef ISDN_NEW_TBUSY ndev->tbusy = 0; +#endif restore_flags(flags); return 0; } else @@ -1364,22 +1487,28 @@ /* Grab a free ISDN-Channel */ if (((chi = - isdn_get_free_channel(ISDN_USAGE_NET, - lp->l2_proto, - lp->l3_proto, - lp->pre_device, - lp->pre_channel)) < 0) && + isdn_get_free_channel( + ISDN_USAGE_NET, + lp->l2_proto, + lp->l3_proto, + lp->pre_device, + lp->pre_channel) + ) < 0) && ((chi = - isdn_get_free_channel(ISDN_USAGE_NET, - lp->l2_proto, - lp->l3_proto, - lp->pre_device, - lp->pre_channel^1)) < 0)) { + isdn_get_free_channel( + ISDN_USAGE_NET, + lp->l2_proto, + lp->l3_proto, + lp->pre_device, + lp->pre_channel^1) + ) < 0)) { restore_flags(flags); isdn_net_unreachable(ndev, skb, "No channel"); dev_kfree_skb(skb); +#ifndef ISDN_NEW_TBUSY ndev->tbusy = 0; +#endif return 0; } /* Log packet, which triggered dialing */ @@ -1399,6 +1528,9 @@ } restore_flags(flags); isdn_net_dial(); /* Initiate dialing */ +#ifdef ISDN_NEW_TBUSY + isdn_net_dev_xoff(ndev); +#endif return 1; /* let upper layer requeue skb packet */ } #endif @@ -1412,7 +1544,9 @@ } lp->first_skb = skb; /* Initiate dialing */ +#ifndef ISDN_NEW_TBUSY ndev->tbusy = 0; +#endif restore_flags(flags); isdn_net_dial(); return 0; @@ -1420,21 +1554,37 @@ isdn_net_unreachable(ndev, skb, "No phone number"); dev_kfree_skb(skb); +#ifndef ISDN_NEW_TBUSY ndev->tbusy = 0; +#endif return 0; } } else { - /* Connection is established, try sending */ + /* Device is connected to an ISDN channel */ ndev->trans_start = jiffies; if (!lp->dialstate) { + /* ISDN connection is established, try sending */ + int ret; if (lp->first_skb) { - if (isdn_net_xmit(ndev, lp, lp->first_skb)) + if (isdn_net_xmit(ndev, lp, lp->first_skb)){ +#ifdef ISDN_NEW_TBUSY + isdn_net_dev_xoff(ndev); +#endif return 1; +} lp->first_skb = NULL; } - return (isdn_net_xmit(ndev, lp, skb)); + ret = (isdn_net_xmit(ndev, lp, skb)); +#ifdef ISDN_NEW_TBUSY + if(ret) isdn_net_dev_xoff(ndev); +#endif + return ret; } else +#ifdef ISDN_NEW_TBUSY + isdn_net_dev_xoff(ndev); +#else ndev->tbusy = 1; +#endif } } return 1; @@ -1915,7 +2065,7 @@ } /* - * Interface-setup. (called just after registering a new interface) + * Interface-setup. (just after registering a new interface) */ static int isdn_net_init(struct net_device *ndev) @@ -2046,7 +2196,6 @@ isdn_net_phone *n; ulong flags; char nr[32]; - /* Search name in netdev-chain */ save_flags(flags); cli(); @@ -2258,10 +2407,15 @@ lp->name, nr, eaz); if (lp->phone[1]) { /* Grab a free ISDN-Channel */ - if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto, + if ((chi = + isdn_get_free_channel( + ISDN_USAGE_NET, + lp->l2_proto, lp->l3_proto, - lp->pre_device, - lp->pre_channel)) < 0) { + lp->pre_device, + lp->pre_channel) + ) < 0) { + printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name); restore_flags(flags); return 0; @@ -2368,10 +2522,14 @@ cli(); /* Grab a free ISDN-Channel */ - if ((chi = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto, - lp->l3_proto, - lp->pre_device, - lp->pre_channel)) < 0) { + if ((chi = + isdn_get_free_channel( + ISDN_USAGE_NET, + lp->l2_proto, + lp->l3_proto, + lp->pre_device, + lp->pre_channel) + ) < 0) { printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name); restore_flags(flags); return -EAGAIN; @@ -3076,7 +3234,6 @@ if (dev->netdev == NULL) isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0); restore_flags(flags); - kfree(p->local); kfree(p); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c --- v2.3.26/linux/drivers/isdn/isdn_ppp.c Thu Aug 26 13:05:37 1999 +++ linux/drivers/isdn/isdn_ppp.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_ppp.c,v 1.52 1999/08/22 20:26:07 calle Exp $ +/* $Id: isdn_ppp.c,v 1.60 1999/11/04 20:29:55 he Exp $ * * Linux ISDN subsystem, functions for synchronous PPP (linklevel). * @@ -19,6 +19,34 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_ppp.c,v $ + * Revision 1.60 1999/11/04 20:29:55 he + * applied Andre Beck's reset_free fix + * + * Revision 1.59 1999/10/31 15:59:50 he + * more skb headroom checks + * + * Revision 1.58 1999/10/30 13:13:01 keil + * Henners isdn_ppp_skb_push:under fix + * + * Revision 1.57 1999/10/05 22:47:17 he + * Removed dead ISDN_SYNCPPP_READDRESS code (obsoleted by sysctl_ip_dynaddr + * and network address translation) + * + * Revision 1.56 1999/09/29 16:01:06 he + * replaced dev_alloc_skb() for downstream skbs by equivalent alloc_skb() + * + * Revision 1.55 1999/09/23 22:07:51 detabc + * + * make ipc_head common usable (for use compressor with raw-ip) + * add function before netif_rx(). needed for ipv4-tcp-keepalive-detect. + * ~ + * + * Revision 1.54 1999/09/13 23:25:17 he + * serialized xmitting frames from isdn_ppp and BSENT statcallb + * + * Revision 1.53 1999/08/31 11:18:14 paul + * various spelling corrections (new checksums may be needed, Karsten!) + * * Revision 1.52 1999/08/22 20:26:07 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -212,10 +240,6 @@ /* TODO: right tbusy handling when using MP */ -/* - * experimental for dynamic addressing: readdress IP frames - */ -#undef ISDN_SYNCPPP_READDRESS #define CONFIG_ISDN_CCP 1 #include @@ -258,6 +282,7 @@ unsigned char code, unsigned char id, unsigned char *data, int len); static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is); +static void isdn_ppp_ccp_reset_free(struct ippp_struct *is); static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is, unsigned char id); static void isdn_ppp_ccp_timer_callback(unsigned long closure); @@ -281,9 +306,10 @@ static void isdn_ppp_free_mpqueue(isdn_net_dev *); #endif -char *isdn_ppp_revision = "$Revision: 1.52 $"; +char *isdn_ppp_revision = "$Revision: 1.60 $"; static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS]; + static struct isdn_ppp_compressor *ipc_head = NULL; /* @@ -354,10 +380,6 @@ printk(KERN_DEBUG "isdn_ppp_free %d %lx %lx\n", lp->ppp_slot, (long) lp, (long) is->lp); is->lp = NULL; /* link is down .. set lp to NULL */ -#ifdef ISDN_SYNCPPP_READDRESS - is->old_pa_addr = 0x0; - is->old_pa_dstaddr = 0x0; -#endif lp->ppp_slot = -1; /* is this OK ?? */ restore_flags(flags); @@ -450,9 +472,6 @@ ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK; -#ifndef COMPAT_HAS_NEW_WAITQ - if (ippp_table[lp->ppp_slot]->wq) -#endif wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq); } @@ -470,11 +489,7 @@ return 0; is = ippp_table[slot]; -#ifdef COMPAT_HAS_NEW_WAITQ if (is->state) -#else - if (is->state && is->wq) -#endif wake_up_interruptible(&is->wq); is->state = IPPP_CLOSEWAIT; @@ -515,9 +530,6 @@ } is = file->private_data = ippp_table[slot]; -#if 0 - if (is->debug & 0x1) -#endif printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n", slot, min, is->state); /* compression stuff */ @@ -539,11 +551,7 @@ is->mru = 1524; /* MRU, default 1524 */ is->maxcid = 16; /* VJ: maxcid */ is->tk = current; -#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&is->wq); -#else - is->wq = NULL; /* read() wait queue */ -#endif is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */ is->last = is->rq; is->minor = min; @@ -615,9 +623,9 @@ is->comp_stat = is->link_comp_stat = NULL; is->decomp_stat = is->link_decomp_stat = NULL; + /* Clean up if necessary */ if(is->reset) - kfree(is->reset); - is->reset = NULL; + isdn_ppp_ccp_reset_free(is); /* this slot is ready for new connections */ is->state = 0; @@ -719,10 +727,6 @@ } is->pppcfg = val; break; -#if 0 - case PPPIOCGSTAT: /* read PPP statistic information */ - break; -#endif case PPPIOCGIDLE: /* get idle time information */ if (lp) { struct ppp_idle pidle; @@ -911,9 +915,6 @@ is->last = bl->next; restore_flags(flags); -#ifndef COMPAT_HAS_NEW_WAITQ - if (is->wq) -#endif wake_up_interruptible(&is->wq); return len; @@ -1004,6 +1005,7 @@ lp->dialstate == 0 && (lp->flags & ISDN_NET_CONNECTED)) { unsigned short hl; + unsigned long flags; int cnt; struct sk_buff *skb; /* @@ -1027,6 +1029,8 @@ isdn_ppp_send_ccp(lp->netdev,lp,skb); /* keeps CCP/compression states in sync */ + save_flags(flags); + cli(); if ((cnt = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb)) != count) { if (lp->sav_skb) { dev_kfree_skb(lp->sav_skb); @@ -1035,6 +1039,7 @@ printk(KERN_INFO "isdn_ppp_write: Can't write PPP frame to LL (%d,%d)!\n", cnt, count); lp->sav_skb = skb; } + restore_flags(flags); } } return count; @@ -1115,7 +1120,7 @@ isdn_ppp_frame_log("receive", skb->data, skb->len, 32,is->unit,lp->ppp_slot); } if (net_dev->local->master) { - printk(KERN_WARNING "isdn_ppp_receice: net_dev != master\n"); + printk(KERN_WARNING "isdn_ppp_receive: net_dev != master\n"); net_dev = ((isdn_net_local *) net_dev->local->master->priv)->netdev; } if (skb->data[0] == 0xff && skb->data[1] == 0x03) @@ -1459,6 +1464,7 @@ isdn_net_dev *nd; unsigned int proto = PPP_IP; /* 0x21 */ struct ippp_struct *ipt,*ipts; + unsigned long flags; if (mdev) mlp = (isdn_net_local *) (mdev->priv); @@ -1470,12 +1476,6 @@ ipts = ippp_table[mlp->ppp_slot]; if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */ -#ifdef ISDN_SYNCPPP_READDRESS - if (!ipts->old_pa_addr) - ipts->old_pa_addr = mdev->pa_addr; - if (!ipts->old_pa_dstaddr) - ipts->old_pa_dstaddr = mdev->pa_dstaddr; -#endif if (ipts->debug & 0x1) printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name); return 1; @@ -1484,21 +1484,6 @@ switch (ntohs(skb->protocol)) { case ETH_P_IP: proto = PPP_IP; -#ifdef ISDN_SYNCPPP_READDRESS - if (ipts->old_pa_addr != mdev->pa_addr) { - struct iphdr *ipfr; - ipfr = (struct iphdr *) skb->data; - if(ipts->debug & 0x4) - printk(KERN_DEBUG "IF-address changed from %lx to %lx\n", ipts->old_pa_addr, mdev->pa_addr); - if (ipfr->version == 4) { - if (ipfr->saddr == ipts->old_pa_addr) { - printk(KERN_DEBUG "readdressing %lx to %lx\n", ipfr->saddr, mdev->pa_addr); - ipfr->saddr = mdev->pa_addr; - } - } - } - /* dstaddr change not so important */ -#endif break; case ETH_P_IPX: proto = PPP_IPX; /* untested */ @@ -1529,8 +1514,6 @@ /* Pull off the fake header we stuck on earlier to keep * the fragemntation code happy. - * this will break the ISDN_SYNCPPP_READDRESS hack a few lines - * above. So, enabling this is no longer allowed */ skb_pull(skb,IPPP_MAX_HEADER); @@ -1548,7 +1531,13 @@ * sk_buff. old call to dev_alloc_skb only reserved * 16 bytes, now we are looking what the driver want. */ - hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen; + hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen + IPPP_MAX_HEADER; + /* + * Note: hl might still be insufficient because the method + * above does not account for a possibible MPPP slave channel + * which had larger HL header space requirements than the + * master. + */ new_skb = alloc_skb(hl+skb->len, GFP_ATOMIC); if (new_skb) { u_char *buf; @@ -1654,13 +1643,16 @@ printk(KERN_DEBUG "skb xmit: len: %d\n", (int) skb->len); isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,lp->ppp_slot); } + save_flags(flags); + cli(); if (isdn_net_send_skb(netdev, lp, skb)) { - if (lp->sav_skb) { /* whole sav_skb processing with disabled IRQs ?? */ + if (lp->sav_skb) { /* should never happen as sav_skb are sent with disabled IRQs) */ printk(KERN_ERR "%s: whoops .. there is another stored skb!\n", netdev->name); dev_kfree_skb(skb); } else lp->sav_skb = skb; } + restore_flags(flags); return 0; } @@ -1744,12 +1736,6 @@ ippp_table[nlp->ppp_slot]->mpppcfg |= ippp_table[lp->ppp_slot]->mpppcfg & (SC_MP_PROT | SC_REJ_MP_PROT | SC_OUT_SHORT_SEQ | SC_IN_SHORT_SEQ); -#if 0 - if (ippp_table[nlp->ppp_slot]->mpppcfg != ippp_table[lp->ppp_slot]->mpppcfg) { - printk(KERN_WARNING "isdn_ppp_bundle: different MP options %04x and %04x\n", - ippp_table[nlp->ppp_slot]->mpppcfg, ippp_table[lp->ppp_slot]->mpppcfg); - } -#endif restore_flags(flags); return 0; @@ -2075,9 +2061,6 @@ int len; isdn_net_local *lp = (isdn_net_local *) dev->priv; -#if 0 - printk(KERN_DEBUG "ippp, dev_ioctl: cmd %#08x , %d \n", cmd, lp->ppp_slot); -#endif if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) return -EINVAL; @@ -2241,17 +2224,20 @@ { struct sk_buff *skb; unsigned char *p; - int count; + int count, hl; + unsigned long flags; int cnt = 0; isdn_net_local *lp = is->lp; /* Alloc large enough skb */ - skb = dev_alloc_skb(len + 16); + hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen; + skb = alloc_skb(len + hl + 16,GFP_ATOMIC); if(!skb) { printk(KERN_WARNING "ippp: CCP cannot send reset - out of memory\n"); return; } + skb_reserve(skb, hl); /* We may need to stuff an address and control field first */ if(!(is->pppcfg & SC_COMP_AC)) { @@ -2284,6 +2270,8 @@ especially dunno what the sav_skb stuff is good for. */ count = skb->len; + save_flags(flags); + cli(); if ((cnt = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb)) != count) { if (lp->sav_skb) { @@ -2297,21 +2285,41 @@ cnt, count); lp->sav_skb = skb; } + restore_flags(flags); } /* Allocate the reset state vector */ static struct ippp_ccp_reset *isdn_ppp_ccp_reset_alloc(struct ippp_struct *is) { struct ippp_ccp_reset *r; - printk(KERN_DEBUG "ippp_ccp: allocating reset data structure\n"); r = kmalloc(sizeof(struct ippp_ccp_reset), GFP_KERNEL); - if(!r) + if(!r) { + printk(KERN_ERR "ippp_ccp: failed to allocate reset data" + " structure - no mem\n"); return NULL; + } memset(r, 0, sizeof(struct ippp_ccp_reset)); + printk(KERN_DEBUG "ippp_ccp: allocated reset data structure %p\n", r); is->reset = r; return r; } +/* Destroy the reset state vector. Kill all pending timers first. */ +static void isdn_ppp_ccp_reset_free(struct ippp_struct *is) +{ + unsigned int id; + + printk(KERN_DEBUG "ippp_ccp: freeing reset data structure %p\n", + is->reset); + for(id = 0; id < 256; id++) { + if(is->reset->rs[id]) { + isdn_ppp_ccp_reset_free_state(is, (unsigned char)id); + } + } + kfree(is->reset); + is->reset = NULL; +} + /* Free a given state and clear everything up for later reallocation */ static void isdn_ppp_ccp_reset_free_state(struct ippp_struct *is, unsigned char id) @@ -2653,13 +2661,7 @@ } if(type) { /* type=1 => Link compression */ -#if 0 - compressor = is->link_compressor; - stat = is->link_comp_stat; - new_proto = PPP_LINK_COMP; -#else return skb_in; -#endif } else { if(!master) { @@ -2683,9 +2685,11 @@ } /* Allow for at least 150 % expansion (for now) */ - skb_out = dev_alloc_skb(skb_in->len + skb_in->len/2 + 32); + skb_out = alloc_skb(skb_in->len + skb_in->len/2 + 32 + + skb_headroom(skb_in), GFP_ATOMIC); if(!skb_out) return skb_in; + skb_reserve(skb_out, skb_headroom(skb_in)); ret = (compressor->compress)(stat,skb_in,skb_out,*proto); if(!ret) { @@ -2914,7 +2918,6 @@ } } - int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc) { ipc->next = ipc_head; @@ -2949,6 +2952,16 @@ printk(KERN_DEBUG "[%d] Set %s type %d\n",is->unit, (data->flags&IPPP_COMP_FLAG_XMIT)?"compressor":"decompressor",num); + /* If is has no valid reset state vector, we cannot allocate a + decompressor. The decompressor would cause reset transactions + sooner or later, and they need that vector. */ + + if(!(data->flags & IPPP_COMP_FLAG_XMIT) && !is->reset) { + printk(KERN_ERR "ippp_ccp: no reset data structure - can't" + " allow decompression.\n"); + return -ENOMEM; + } + while(ipc) { if(ipc->num == num) { stat = ipc->alloc(data); @@ -3000,5 +3013,3 @@ } return -EINVAL; } - - diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c --- v2.3.26/linux/drivers/isdn/isdn_tty.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/isdn/isdn_tty.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_tty.c,v 1.73 1999/08/28 21:56:27 keil Exp $ +/* $Id: isdn_tty.c,v 1.80 1999/11/07 13:34:30 armin Exp $ * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel). * @@ -20,6 +20,30 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_tty.c,v $ + * Revision 1.80 1999/11/07 13:34:30 armin + * Fixed AT command line editor + * + * Revision 1.79 1999/10/29 18:35:08 armin + * Check number len in isdn_get_msnstr() to avoid buffer overflow. + * + * Revision 1.78 1999/10/28 23:03:51 armin + * Bugfix: now freeing channel on modem_hup() even when + * usage on ttyI has changed and error-report for + * AT-commands on wrong channel-state. + * + * Revision 1.77 1999/10/26 21:13:14 armin + * using define for checking phone number len in isdn_tty_getdial() + * + * Revision 1.76 1999/10/11 22:16:26 keil + * Suspend/Resume is possible without explicit ID too + * + * Revision 1.75 1999/10/08 18:59:32 armin + * Bugfix of too small MSN buffer and checking phone number + * in isdn_tty_getdial() + * + * Revision 1.74 1999/09/04 06:20:04 keil + * Changes from kernel set_current_state() + * * Revision 1.73 1999/08/28 21:56:27 keil * misplaced #endif caused ttyI crash in 2.3.X * @@ -348,7 +372,7 @@ static int si2bit[8] = {4, 1, 4, 4, 4, 4, 4, 4}; -char *isdn_tty_revision = "$Revision: 1.73 $"; +char *isdn_tty_revision = "$Revision: 1.80 $"; /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb() @@ -1014,7 +1038,6 @@ isdn_tty_modem_hup(modem_info * info, int local) { isdn_ctrl cmd; - int usage; if (!info) return; @@ -1068,10 +1091,7 @@ } isdn_all_eaz(info->isdn_driver, info->isdn_channel); info->emu.mdmreg[REG_RINGCNT] = 0; - usage = isdn_calc_usage(info->emu.mdmreg[REG_SI1I], - info->emu.mdmreg[REG_L2PROT]); - isdn_free_channel(info->isdn_driver, info->isdn_channel, - usage); + isdn_free_channel(info->isdn_driver, info->isdn_channel, 0); } info->isdn_driver = -1; info->isdn_channel = -1; @@ -1108,8 +1128,8 @@ printk(KERN_DEBUG "Msusp ttyI%d\n", info->line); #endif l = strlen(id); - if ((info->isdn_driver >= 0) && l) { - cmd.parm.cmsg.Length = l+17; + if ((info->isdn_driver >= 0)) { + cmd.parm.cmsg.Length = l+18; cmd.parm.cmsg.Command = CAPI_FACILITY; cmd.parm.cmsg.Subcommand = CAPI_REQ; cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1; @@ -1147,10 +1167,6 @@ int l; l = strlen(id); - if (!l) { - isdn_tty_modem_result(4, info); - return; - } for (j = 7; j >= 0; j--) if (m->mdmreg[REG_SI1] & (1 << j)) { si = bit2si[j]; @@ -1204,7 +1220,7 @@ isdn_command(&cmd); cmd.driver = info->isdn_driver; cmd.arg = info->isdn_channel; - cmd.parm.cmsg.Length = l+17; + cmd.parm.cmsg.Length = l+18; cmd.parm.cmsg.Command = CAPI_FACILITY; cmd.parm.cmsg.Subcommand = CAPI_REQ; cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1; @@ -1901,12 +1917,7 @@ static int isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info * info) { -#ifdef COMPAT_HAS_NEW_WAITQ DECLARE_WAITQUEUE(wait, NULL); -#else - struct wait_queue wait = - {current, NULL}; -#endif int do_clocal = 0; unsigned long flags; int retval; @@ -2157,7 +2168,7 @@ */ timeout = jiffies + HZ; while (!(info->lsr & UART_LSR_TEMT)) { - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(20); if (time_after(jiffies,timeout)) break; @@ -2173,7 +2184,7 @@ info->ncarrier = 0; tty->closing = 0; if (info->blocked_open) { - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(50); wake_up_interruptible(&info->open_wait); } @@ -2375,11 +2386,7 @@ return -3; } #endif -#ifdef COMPAT_HAS_NEW_WAITQ init_MUTEX(&info->write_sem); -#else - info->write_sem = MUTEX; -#endif sprintf(info->last_cause, "0000"); sprintf(info->last_num, "none"); info->last_dir = 0; @@ -2396,13 +2403,8 @@ info->blocked_open = 0; info->callout_termios = m->cua_modem.init_termios; info->normal_termios = m->tty_modem.init_termios; -#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); -#else - info->open_wait = 0; - info->close_wait = 0; -#endif info->isdn_driver = -1; info->isdn_channel = -1; info->drv_index = -1; @@ -3101,9 +3103,12 @@ static void isdn_tty_get_msnstr(char *n, char **p) { - while ((*p[0] >= '0' && *p[0] <= '9') || + int limit = ISDN_MSNLEN - 1; + + while (((*p[0] >= '0' && *p[0] <= '9') || /* Why a comma ??? */ - (*p[0] == ',')) + (*p[0] == ',')) && + (limit--)) *n++ = *p[0]++; *n = '\0'; } @@ -3115,16 +3120,18 @@ isdn_tty_getdial(char *p, char *q,int cnt) { int first = 1; - int limit=39; /* MUST match the size in isdn_tty_parse to avoid - buffer overflow */ + int limit = ISDN_MSNLEN - 1; /* MUST match the size of interface var to avoid + buffer overflow */ while (strchr(" 0123456789,#.*WPTS-", *p) && *p && --cnt>0) { if ((*p >= '0' && *p <= '9') || ((*p == 'S') && first) || - (*p == '*') || (*p == '#')) + (*p == '*') || (*p == '#')) { *q++ = *p; - p++; - if(!--limit) + limit--; + } + if(!limit) break; + p++; first = 0; } *q = 0; @@ -3268,6 +3275,8 @@ case 'F': /* &F -Set Factory-Defaults */ p[0]++; + if (info->msr & UART_MSR_DCD) + PARSE_ERROR1; isdn_tty_reset_profile(m); isdn_tty_modem_reset_regs(info, 1); break; @@ -3919,6 +3928,12 @@ break; case 'D': /* D - Dial */ + if (info->msr & UART_MSR_DCD) + PARSE_ERROR; + if (info->msr & UART_MSR_RI) { + isdn_tty_modem_result(3, info); + return; + } isdn_tty_getdial(++p, ds, sizeof ds); p += strlen(p); if (!strlen(m->msn)) @@ -4113,7 +4128,7 @@ c = *p; total++; if (c == m->mdmreg[REG_CR] || c == m->mdmreg[REG_LF]) { - /* Separator (CR oder LF) */ + /* Separator (CR or LF) */ m->mdmcmd[m->mdmcmdl] = 0; if (m->mdmreg[REG_ECHO] & BIT_ECHO) { eb[0] = c; @@ -4126,7 +4141,7 @@ continue; } if (c == m->mdmreg[REG_BS] && m->mdmreg[REG_BS] < 128) { - /* Backspace-Funktion */ + /* Backspace-Function */ if ((m->mdmcmdl > 2) || (!m->mdmcmdl)) { if (m->mdmcmdl) m->mdmcmdl--; @@ -4144,18 +4159,24 @@ if (m->mdmcmdl < 255) { c = my_toupper(c); switch (m->mdmcmdl) { - case 0: - if (c == 'A') - m->mdmcmd[m->mdmcmdl] = c; - break; case 1: - if (c == 'T') + if (c == 'T') { m->mdmcmd[m->mdmcmdl] = c; + m->mdmcmd[++m->mdmcmdl] = 0; + break; + } else + m->mdmcmdl = 0; + /* Fall through, check for 'A' */ + case 0: + if (c == 'A') { + m->mdmcmd[m->mdmcmdl] = c; + m->mdmcmd[++m->mdmcmdl] = 0; + } break; default: m->mdmcmd[m->mdmcmdl] = c; + m->mdmcmd[++m->mdmcmdl] = 0; } - m->mdmcmd[++m->mdmcmdl] = 0; } } } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_tty.h linux/drivers/isdn/isdn_tty.h --- v2.3.26/linux/drivers/isdn/isdn_tty.h Thu Aug 26 13:05:37 1999 +++ linux/drivers/isdn/isdn_tty.h Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_tty.h,v 1.16 1999/08/22 20:26:10 calle Exp $ +/* $Id: isdn_tty.h,v 1.17 1999/09/21 19:00:35 armin Exp $ * header for Linux ISDN subsystem, tty related functions (linklevel). * @@ -20,6 +20,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_tty.h,v $ + * Revision 1.17 1999/09/21 19:00:35 armin + * Extended FCON message with added CPN + * can now be activated with Bit 1 of Reg 23. + * * Revision 1.16 1999/08/22 20:26:10 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -154,6 +158,7 @@ #define REG_CPN 23 #define BIT_CPN 1 +#define BIT_CPNFCON 2 extern void isdn_tty_modem_escape(void); extern void isdn_tty_modem_ring(void); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_ttyfax.c linux/drivers/isdn/isdn_ttyfax.c --- v2.3.26/linux/drivers/isdn/isdn_ttyfax.c Thu Aug 26 13:05:37 1999 +++ linux/drivers/isdn/isdn_ttyfax.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_ttyfax.c,v 1.3 1999/08/22 20:26:12 calle Exp $ +/* $Id: isdn_ttyfax.c,v 1.4 1999/09/21 19:00:35 armin Exp $ * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel). * * Copyright 1999 by Armin Schindler (mac@melware.de) @@ -20,6 +20,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_ttyfax.c,v $ + * Revision 1.4 1999/09/21 19:00:35 armin + * Extended FCON message with added CPN + * can now be activated with Bit 1 of Reg 23. + * * Revision 1.3 1999/08/22 20:26:12 calle * backported changes from kernel 2.3.14: * - several #include "config.h" gone, others come. @@ -46,7 +50,7 @@ #include "isdn_ttyfax.h" -static char *isdn_tty_fax_revision = "$Revision: 1.3 $"; +static char *isdn_tty_fax_revision = "$Revision: 1.4 $"; #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; } @@ -98,7 +102,7 @@ break; case 2: /* +FCON */ /* Append CPN, if enabled */ - if ((m->mdmreg[REG_CPN] & BIT_CPN) && + if ((m->mdmreg[REG_CPN] & BIT_CPNFCON) && (!(dev->usage[info->isdn_channel] & ISDN_USAGE_OUTGOING))) { sprintf(rs, "/%s", m->cpn); isdn_tty_at_cout(rs, info); @@ -907,76 +911,6 @@ return 0; } -#if 0 - /* LO=n - Flow control opts */ - if (!strncmp(p[0], "LO", 2)) { /* TODO */ - p[0] += 2; - switch (*p[0]) { - case '?': - p[0]++; - sprintf(rs, "\r\n%d",f->lo); - isdn_tty_at_cout(rs, info); - break; - case '=': - p[0]++; - if (*p[0] == '?') - { - p[0]++; - sprintf(rs, "\r\n0,1,2"); - isdn_tty_at_cout(rs, info); - } - else - { - par = isdn_getnum(p); - if ((par < 0) || (par > 2)) - PARSE_ERROR1; - f->lo = par; -#ifdef ISDN_TTY_FAX_STAT_DEBUG - printk(KERN_DEBUG "isdn_tty: Fax FLO=%d\n", par); -#endif - } - break; - default: - PARSE_ERROR1; - } - return 0; - } -#endif -#if 0 - /* LPL=n - Doc for polling cmd */ - if (!strncmp(p[0], "LPL", 3)) { /* TODO */ - p[0] += 3; - switch (*p[0]) { - case '?': - p[0]++; - sprintf(rs, "\r\n%d",f->lpl); - isdn_tty_at_cout(rs, info); - break; - case '=': - p[0]++; - if (*p[0] == '?') - { - p[0]++; - sprintf(rs, "\r\n0,1"); - isdn_tty_at_cout(rs, info); - } - else - { - par = isdn_getnum(p); - if ((par < 0) || (par > 1)) - PARSE_ERROR1; - f->lpl = par; -#ifdef ISDN_TTY_FAX_STAT_DEBUG - printk(KERN_DEBUG "isdn_tty: Fax FLPL=%d\n", par); -#endif - } - break; - default: - PARSE_ERROR1; - } - return 0; - } -#endif /* MDL? - DCE Model */ if (!strncmp(p[0], "MDL?", 4)) { @@ -1066,41 +1000,6 @@ return 0; } -#if 0 - /* PTS=n - Page transfer status */ - if (!strncmp(p[0], "PTS", 3)) { /* TODO */ - p[0] += 3; - switch (*p[0]) { - case '?': - p[0]++; - sprintf(rs, "\r\n%d",f->pts); - isdn_tty_at_cout(rs, info); - break; - case '=': - p[0]++; - if (*p[0] == '?') - { - p[0]++; - sprintf(rs, "\r\n0-5"); - isdn_tty_at_cout(rs, info); - } - else - { - par = isdn_getnum(p); - if ((par < 0) || (par > 5)) - PARSE_ERROR1; - f->pts = par; -#ifdef ISDN_TTY_FAX_STAT_DEBUG - printk(KERN_DEBUG "isdn_tty: Fax FPTS=%d\n", par); -#endif - } - break; - default: - PARSE_ERROR1; - } - return 0; - } -#endif /* REL=n - Phase C received EOL alignment */ if (!strncmp(p[0], "REL", 3)) { @@ -1148,41 +1047,6 @@ return 0; } -#if 0 - /* SPL=n - Enable polling */ - if (!strncmp(p[0], "SPL", 3)) { /* TODO */ - p[0] += 3; - switch (*p[0]) { - case '?': - p[0]++; - sprintf(rs, "\r\n%d", f->spl); - isdn_tty_at_cout(rs, info); - break; - case '=': - p[0]++; - if (*p[0] == '?') - { - p[0]++; - sprintf(rs, "\r\n0,1"); - isdn_tty_at_cout(rs, info); - } - else - { - par = isdn_getnum(p); - if ((par < 0) || (par > 1)) - PARSE_ERROR1; - f->spl = par; -#ifdef ISDN_TTY_FAX_STAT_DEBUG - printk(KERN_DEBUG "isdn_tty: Fax FSPL=%d\n", par); -#endif - } - break; - default: - PARSE_ERROR1; - } - return 0; - } -#endif /* Phase C Transmit Data Block Size */ if (!strncmp(p[0], "TBC=", 4)) { /* dummy, not used */ diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_v110.c linux/drivers/isdn/isdn_v110.c --- v2.3.26/linux/drivers/isdn/isdn_v110.c Wed Apr 1 16:21:03 1998 +++ linux/drivers/isdn/isdn_v110.c Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_v110.c,v 1.2 1998/02/22 19:44:25 fritz Exp $ +/* $Id: isdn_v110.c,v 1.3 1999/10/30 09:49:28 keil Exp $ * Linux ISDN subsystem, V.110 related functions (linklevel). * @@ -19,6 +19,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_v110.c,v $ + * Revision 1.3 1999/10/30 09:49:28 keil + * Reinit of v110 structs + * * Revision 1.2 1998/02/22 19:44:25 fritz * Bugfixes and improvements regarding V.110, V.110 now running. * @@ -36,7 +39,7 @@ #undef ISDN_V110_DEBUG -char *isdn_v110_revision = "$Revision: 1.2 $"; +char *isdn_v110_revision = "$Revision: 1.3 $"; #define V110_38400 255 #define V110_19200 15 @@ -148,21 +151,13 @@ } /* isdn_v110_close frees private V.110 data structures */ -static void +void isdn_v110_close(isdn_v110_stream * v) { if (v == NULL) return; #ifdef ISDN_V110_DEBUG printk(KERN_DEBUG "v110 close\n"); -#if 0 - printk(KERN_DEBUG "isdn_v110_close: nbytes=%d\n", v->nbytes); - printk(KERN_DEBUG "isdn_v110_close: nbits=%d\n", v->nbits); - printk(KERN_DEBUG "isdn_v110_close: key=%d\n", v->key); - printk(KERN_DEBUG "isdn_v110_close: SyncInit=%d\n", v->SyncInit); - printk(KERN_DEBUG "isdn_v110:close: decodelen=%d\n", v->decodelen); - printk(KERN_DEBUG "isdn_v110_close: framelen=%d\n", v->framelen); -#endif #endif kfree(v->encodebuf); kfree(v); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdn_v110.h linux/drivers/isdn/isdn_v110.h --- v2.3.26/linux/drivers/isdn/isdn_v110.h Wed Apr 1 16:21:03 1998 +++ linux/drivers/isdn/isdn_v110.h Sun Nov 7 16:34:00 1999 @@ -1,4 +1,4 @@ -/* $Id: isdn_v110.h,v 1.1 1998/02/20 17:32:11 fritz Exp $ +/* $Id: isdn_v110.h,v 1.2 1999/10/30 09:49:28 keil Exp $ * Linux ISDN subsystem, V.110 related functions (linklevel). * @@ -19,6 +19,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn_v110.h,v $ + * Revision 1.2 1999/10/30 09:49:28 keil + * Reinit of v110 structs + * * Revision 1.1 1998/02/20 17:32:11 fritz * First checkin (not yet completely functionable). * @@ -41,5 +44,6 @@ extern struct sk_buff *isdn_v110_decode(isdn_v110_stream *, struct sk_buff *); extern int isdn_v110_stat_callback(int, isdn_ctrl *); +extern void isdn_v110_close(isdn_v110_stream * v); #endif diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdnloop/isdnloop.c linux/drivers/isdn/isdnloop/isdnloop.c --- v2.3.26/linux/drivers/isdn/isdnloop/isdnloop.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdnloop/isdnloop.c Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: isdnloop.c,v 1.8 1998/11/18 18:59:43 armin Exp $ +/* $Id: isdnloop.c,v 1.9 1999/09/06 07:29:36 fritz Exp $ * ISDN low-level module implementing a dummy loop driver. * - * Copyright 1997 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdnloop.c,v $ + * Revision 1.9 1999/09/06 07:29:36 fritz + * Changed my mail-address. + * * Revision 1.8 1998/11/18 18:59:43 armin * changes for 2.1.127 * @@ -56,7 +59,7 @@ #include "isdnloop.h" static char -*revision = "$Revision: 1.8 $"; +*revision = "$Revision: 1.9 $"; static int isdnloop_addcard(char *); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/isdnloop/isdnloop.h linux/drivers/isdn/isdnloop/isdnloop.h --- v2.3.26/linux/drivers/isdn/isdnloop/isdnloop.h Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/isdnloop/isdnloop.h Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: isdnloop.h,v 1.3 1998/04/14 20:59:35 he Exp $ +/* $Id: isdnloop.h,v 1.4 1999/09/06 07:29:36 fritz Exp $ * Loopback lowlevel module for testing of linklevel. * - * Copyright 1997 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,9 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdnloop.h,v $ + * Revision 1.4 1999/09/06 07:29:36 fritz + * Changed my mail-address. + * * Revision 1.3 1998/04/14 20:59:35 he * merged 2.1.94 changes * diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/pcbit/drv.c linux/drivers/isdn/pcbit/drv.c --- v2.3.26/linux/drivers/isdn/pcbit/drv.c Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/pcbit/drv.c Sun Nov 7 16:34:00 1999 @@ -86,9 +86,7 @@ dev_pcbit[board] = dev; memset(dev, 0, sizeof(struct pcbit_dev)); -#ifdef COMPAT_HAS_NEW_WAITQ init_waitqueue_head(&dev->set_running_wq); -#endif if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF ) dev->sh_mem = (unsigned char*) mem_base; @@ -593,20 +591,6 @@ dev->b1->s_refnum, dev->b2->s_refnum); #endif -#if 0 - if (dev->b1->s_refnum == refnum) - chan = dev->b1; - else { - - if (dev->b2->s_refnum == refnum) - chan = dev->b2; - else { - chan = NULL; - printk(KERN_WARNING "Connection Confirm - refnum doesn't match chan\n"); - break; - } - } -#else /* We just try to find a channel in the right state */ if (dev->b1->fsm_state == ST_CALL_INIT) @@ -620,7 +604,6 @@ break; } } -#endif if (capi_decode_conn_conf(chan, skb, &complete)) { printk(KERN_DEBUG "conn_conf indicates error\n"); pcbit_fsm_event(dev, chan, EV_ERROR, NULL); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/pcbit/layer2.c linux/drivers/isdn/pcbit/layer2.c --- v2.3.26/linux/drivers/isdn/pcbit/layer2.c Thu May 21 13:45:01 1998 +++ linux/drivers/isdn/pcbit/layer2.c Sun Nov 7 16:34:00 1999 @@ -375,16 +375,11 @@ if (dev->read_frame) { printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n"); -#if 0 - pcbit_l2_error(dev); - return; -#else /* discard previous queued frame */ if (dev->read_frame->skb) kfree_skb(dev->read_frame->skb); kfree(dev->read_frame); dev->read_frame = NULL; -#endif } frame = kmalloc(sizeof(struct frame_buf), GFP_ATOMIC); @@ -460,14 +455,10 @@ if (!(frame = dev->read_frame)) { printk("Type 1 frame and no frame queued\n"); -#if 1 /* usually after an error: toss frame */ dev->readptr += tt; if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN) dev->readptr -= BANKLEN; -#else - pcbit_l2_error(dev); -#endif return; } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/pcbit/module.c linux/drivers/isdn/pcbit/module.c --- v2.3.26/linux/drivers/isdn/pcbit/module.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/isdn/pcbit/module.c Sun Nov 7 16:34:00 1999 @@ -102,7 +102,6 @@ } #else -#ifdef COMPAT_HAS_NEW_SETUP #define MAX_PARA (MAX_PCBIT_CARDS * 2) #include static int __init pcbit_setup(char *line) @@ -112,11 +111,6 @@ int ints[MAX_PARA+1]; str = get_options(line, MAX_PARA, ints); -#else -void pcbit_setup(char *str, int *ints) -{ - int i, j, argc; -#endif argc = ints[0]; i = 0; j = 1; @@ -135,13 +129,9 @@ i++; } -#ifdef COMPAT_HAS_NEW_SETUP return(1); } __setup("pcbit=", pcbit_setup); -#else -} -#endif #endif diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/pcbit/pcbit.h linux/drivers/isdn/pcbit/pcbit.h --- v2.3.26/linux/drivers/isdn/pcbit/pcbit.h Thu Aug 12 09:42:33 1999 +++ linux/drivers/isdn/pcbit/pcbit.h Sun Nov 7 16:34:00 1999 @@ -68,11 +68,7 @@ struct frame_buf *write_queue; /* Protocol start */ -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t set_running_wq; -#else - struct wait_queue *set_running_wq; -#endif struct timer_list set_running_timer; struct timer_list error_recover_timer; diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/sc/init.c linux/drivers/isdn/sc/init.c --- v2.3.26/linux/drivers/isdn/sc/init.c Thu Nov 5 09:58:44 1998 +++ linux/drivers/isdn/sc/init.c Sun Nov 7 16:34:00 1999 @@ -164,7 +164,7 @@ if(do_reset) { pr_debug("Doing a SAFE probe reset\n"); outb(0xFF, io[b] + RESET_OFFSET); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(milliseconds(10000)); } pr_debug("RAM Base for board %d is 0x%x, %s probe\n", b, ram[b], @@ -512,19 +512,10 @@ * Try to identify a PRI card */ outb(PRI_BASEPG_VAL, pgport); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); sig = readl(rambase + SIG_OFFSET); pr_debug("Looking for a signature, got 0x%x\n", sig); -#if 0 -/* - * For Gary: - * If it's a timing problem, it should be gone with the above schedule() - * Another possible reason may be the missing volatile in the original - * code. readl() does this for us. - */ - printk(""); /* Hack! Doesn't work without this !!!??? */ -#endif if(sig == SIGNATURE) return PRI_BOARD; @@ -532,13 +523,10 @@ * Try to identify a PRI card */ outb(BRI_BASEPG_VAL, pgport); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); sig = readl(rambase + SIG_OFFSET); pr_debug("Looking for a signature, got 0x%x\n", sig); -#if 0 - printk(""); /* Hack! Doesn't work without this !!!??? */ -#endif if(sig == SIGNATURE) return BRI_BOARD; @@ -567,7 +555,7 @@ */ x = 0; while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) { - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); x++; } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/sc/ioctl.c linux/drivers/isdn/sc/ioctl.c --- v2.3.26/linux/drivers/isdn/sc/ioctl.c Thu May 29 21:53:06 1997 +++ linux/drivers/isdn/sc/ioctl.c Sun Nov 7 16:34:00 1999 @@ -15,9 +15,6 @@ extern board *adapter[]; -#if 0 -static char *ChannelStates[] = { "Idle", "Ready", "Connecting", "Connected", "Disconnecting" }; -#endif int GetStatus(int card, boardInfo *); @@ -42,7 +39,7 @@ pr_debug("%s: SCIOLOAD: ioctl received\n", adapter[card]->devicename); if(adapter[card]->EngineUp) { - pr_debug("%s: SCIOCLOAD: Command Failed, LoadProc while engine running.\n", + pr_debug("%s: SCIOCLOAD: command failed, LoadProc while engine running.\n", adapter[card]->devicename); return -1; } @@ -56,12 +53,12 @@ status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc, 0, sizeof(srec), srec, &rcvmsg, SAR_TIMEOUT); if(status) { - pr_debug("%s: SCIOCLOAD: Command Failed, status = %d\n", + pr_debug("%s: SCIOCLOAD: command failed, status = %d\n", adapter[card]->devicename, status); return -1; } else { - pr_debug("%s: SCIOCLOAD: Command Sucessful\n", adapter[card]->devicename); + pr_debug("%s: SCIOCLOAD: command successful\n", adapter[card]->devicename); return 0; } } @@ -70,7 +67,7 @@ { pr_debug("%s: SCIOSTART: ioctl received\n", adapter[card]->devicename); if(adapter[card]->EngineUp) { - pr_debug("%s: SCIOCSTART: Command Failed, Engine already running.\n", + pr_debug("%s: SCIOCSTART: command failed, engine already running.\n", adapter[card]->devicename); return -1; } @@ -94,16 +91,16 @@ if ((err = copy_from_user(&switchtype, (char *) data->dataptr, sizeof(char)))) return err; - pr_debug("%s: SCIOCSETSWITCH: Setting switch type to %d\n", adapter[card]->devicename, + pr_debug("%s: SCIOCSETSWITCH: setting switch type to %d\n", adapter[card]->devicename, switchtype); status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallSetSwitchType, 0, sizeof(char),&switchtype,&rcvmsg, SAR_TIMEOUT); if(!status && !rcvmsg.rsp_status) { - pr_debug("%s: SCIOCSETSWITCH: Command Successful\n", adapter[card]->devicename); + pr_debug("%s: SCIOCSETSWITCH: command successful\n", adapter[card]->devicename); return 0; } else { - pr_debug("%s: SCIOCSETSWITCH: Command Failed (status = %d)\n", + pr_debug("%s: SCIOCSETSWITCH: command failed (status = %d)\n", adapter[card]->devicename, status); return status; } @@ -123,10 +120,10 @@ status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetSwitchType, 0, 0, 0, &rcvmsg, SAR_TIMEOUT); if (!status && !rcvmsg.rsp_status) { - pr_debug("%s: SCIOCGETSWITCH: Command Sucessful\n", adapter[card]->devicename); + pr_debug("%s: SCIOCGETSWITCH: command successful\n", adapter[card]->devicename); } else { - pr_debug("%s: SCIOCGETSWITCH: Command Failed (status = %d)\n", + pr_debug("%s: SCIOCGETSWITCH: command failed (status = %d)\n", adapter[card]->devicename, status); return status; } @@ -156,10 +153,10 @@ status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetSPID, data->channel, 0, 0, &rcvmsg, SAR_TIMEOUT); if (!status) { - pr_debug("%s: SCIOCGETSPID: Command Sucessful\n", adapter[card]->devicename); + pr_debug("%s: SCIOCGETSPID: command successful\n", adapter[card]->devicename); } else { - pr_debug("%s: SCIOCGETSPID: Command Failed (status = %d)\n", + pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n", adapter[card]->devicename, status); return status; } @@ -188,18 +185,18 @@ if ((err = copy_from_user(spid, (char *) data->dataptr, sizeof(spid)))) return err; - pr_debug("%s: SCIOCSETSPID: Setting channel %d spid to %s\n", + pr_debug("%s: SCIOCSETSPID: setting channel %d spid to %s\n", adapter[card]->devicename, data->channel, spid); status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallSetSPID, data->channel, strlen(spid), spid, &rcvmsg, SAR_TIMEOUT); if(!status && !rcvmsg.rsp_status) { - pr_debug("%s: SCIOCSETSPID: Command Successful\n", + pr_debug("%s: SCIOCSETSPID: command successful\n", adapter[card]->devicename); return 0; } else { - pr_debug("%s: SCIOCSETSPID: Command Failed (status = %d)\n", + pr_debug("%s: SCIOCSETSPID: command failed (status = %d)\n", adapter[card]->devicename, status); return status; } @@ -219,10 +216,10 @@ status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetMyNumber, data->channel, 0, 0, &rcvmsg, SAR_TIMEOUT); if (!status) { - pr_debug("%s: SCIOCGETDN: Command Sucessful\n", adapter[card]->devicename); + pr_debug("%s: SCIOCGETDN: command successful\n", adapter[card]->devicename); } else { - pr_debug("%s: SCIOCGETDN: Command Failed (status = %d)\n", + pr_debug("%s: SCIOCGETDN: command failed (status = %d)\n", adapter[card]->devicename, status); return status; } @@ -252,18 +249,18 @@ if ((err = copy_from_user(dn, (char *) data->dataptr, sizeof(dn)))) return err; - pr_debug("%s: SCIOCSETDN: Setting channel %d dn to %s\n", + pr_debug("%s: SCIOCSETDN: setting channel %d dn to %s\n", adapter[card]->devicename, data->channel, dn); status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallSetMyNumber, data->channel, strlen(dn),dn,&rcvmsg, SAR_TIMEOUT); if(!status && !rcvmsg.rsp_status) { - pr_debug("%s: SCIOCSETDN: Command Successful\n", + pr_debug("%s: SCIOCSETDN: command successful\n", adapter[card]->devicename); return 0; } else { - pr_debug("%s: SCIOCSETDN: Command Failed (status = %d)\n", + pr_debug("%s: SCIOCSETDN: command failed (status = %d)\n", adapter[card]->devicename, status); return status; } @@ -273,7 +270,7 @@ pr_debug("%s: SCIOTRACE: ioctl received\n", adapter[card]->devicename); /* adapter[card]->trace = !adapter[card]->trace; - pr_debug("%s: SCIOCTRACE: Tracing turned %s\n", adapter[card]->devicename, + pr_debug("%s: SCIOCTRACE: tracing turned %s\n", adapter[card]->devicename, adapter[card]->trace ? "ON" : "OFF"); */ break; @@ -305,11 +302,11 @@ status = send_and_receive(card, CEPID, ceReqTypeCall, ceReqClass0, ceReqCallGetCallType, data->channel, 0, 0, &rcvmsg, SAR_TIMEOUT); if (!status && !rcvmsg.rsp_status) { - pr_debug("%s: SCIOCGETSPEED: Command Sucessful\n", + pr_debug("%s: SCIOCGETSPEED: command successful\n", adapter[card]->devicename); } else { - pr_debug("%s: SCIOCGETSPEED: Command Failed (status = %d)\n", + pr_debug("%s: SCIOCGETSPEED: command failed (status = %d)\n", adapter[card]->devicename, status); return status; } diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/sc/message.c linux/drivers/isdn/sc/message.c --- v2.3.26/linux/drivers/isdn/sc/message.c Sun May 23 10:03:42 1999 +++ linux/drivers/isdn/sc/message.c Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ /* - * $Id: message.c,v 1.4 1999/01/05 18:29:47 he Exp $ + * $Id: message.c,v 1.5 1999/09/04 06:20:07 keil Exp $ * Copyright (C) 1996 SpellCaster Telecommunications Inc. * * message.c - functions for sending and receiving control messages @@ -266,7 +266,7 @@ tries = 0; /* wait for the response */ while (tries < timeout) { - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); pr_debug("SAR waiting..\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/isdn/sc/packet.c linux/drivers/isdn/sc/packet.c --- v2.3.26/linux/drivers/isdn/sc/packet.c Wed Apr 1 16:21:04 1998 +++ linux/drivers/isdn/sc/packet.c Sun Nov 7 16:34:00 1999 @@ -1,5 +1,5 @@ /* - * $Id: packet.c,v 1.4 1998/02/12 23:08:50 keil Exp $ + * $Id: packet.c,v 1.5 1999/08/31 11:20:41 paul Exp $ * Copyright (C) 1996 SpellCaster Telecommunications Inc. * * This program is free software; you can redistribute it and/or modify @@ -52,11 +52,11 @@ card = get_card_from_id(devId); if(!IS_VALID_CARD(card)) { - pr_debug("Invalid param: %d is not a valid card id\n", card); + pr_debug("invalid param: %d is not a valid card id\n", card); return -ENODEV; } - pr_debug("%s: Send Packet: frst = 0x%x nxt = %d f = %d n = %d\n", + pr_debug("%s: sndpkt: frst = 0x%x nxt = %d f = %d n = %d\n", adapter[card]->devicename, adapter[card]->channel[channel].first_sendbuf, adapter[card]->channel[channel].next_sendbuf, @@ -64,26 +64,26 @@ adapter[card]->channel[channel].num_sendbufs); if(!adapter[card]->channel[channel].free_sendbufs) { - pr_debug("%s: Out out TX buffers\n", adapter[card]->devicename); + pr_debug("%s: out of TX buffers\n", adapter[card]->devicename); return -EINVAL; } if(data->len > BUFFER_SIZE) { - pr_debug("%s: Data overflows buffer size (data > buffer)\n", adapter[card]->devicename); + pr_debug("%s: data overflows buffer size (data > buffer)\n", adapter[card]->devicename); return -EINVAL; } ReqLnkWrite.buff_offset = adapter[card]->channel[channel].next_sendbuf * BUFFER_SIZE + adapter[card]->channel[channel].first_sendbuf; ReqLnkWrite.msg_len = data->len; /* sk_buff size */ - pr_debug("%s: Writing %d bytes to buffer offset 0x%x\n", adapter[card]->devicename, + pr_debug("%s: writing %d bytes to buffer offset 0x%x\n", adapter[card]->devicename, ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset); memcpy_toshmem(card, (char *)ReqLnkWrite.buff_offset, data->data, ReqLnkWrite.msg_len); /* * sendmessage */ - pr_debug("%s: Send Packet size=%d, buf_offset=0x%x buf_indx=%d\n", + pr_debug("%s: sndpkt size=%d, buf_offset=0x%x buf_indx=%d\n", adapter[card]->devicename, ReqLnkWrite.msg_len, ReqLnkWrite.buff_offset, adapter[card]->channel[channel].next_sendbuf); @@ -92,7 +92,7 @@ channel+1, sizeof(LLData), (unsigned int*)&ReqLnkWrite); len = data->len; if(status) { - pr_debug("%s: Failed to send packet, status = %d\n", adapter[card]->devicename, status); + pr_debug("%s: failed to send packet, status = %d\n", adapter[card]->devicename, status); return -1; } else { @@ -101,7 +101,7 @@ ++adapter[card]->channel[channel].next_sendbuf == adapter[card]->channel[channel].num_sendbufs ? 0 : adapter[card]->channel[channel].next_sendbuf; - pr_debug("%s: Packet sent successfully\n", adapter[card]->devicename); + pr_debug("%s: packet sent successfully\n", adapter[card]->devicename); dev_kfree_skb(data); indicate_status(card,ISDN_STAT_BSENT,channel, (char *)&len); } @@ -114,7 +114,7 @@ struct sk_buff *skb; if(!IS_VALID_CARD(card)) { - pr_debug("Invalid param: %d is not a valid card id\n", card); + pr_debug("invalid param: %d is not a valid card id\n", card); return; } @@ -122,7 +122,7 @@ case 0x01: case 0x02: case 0x70: - pr_debug("%s: Error status code: 0x%x\n", adapter[card]->devicename, rcvmsg->rsp_status); + pr_debug("%s: error status code: 0x%x\n", adapter[card]->devicename, rcvmsg->rsp_status); return; case 0x00: if (!(skb = dev_alloc_skb(rcvmsg->msg_data.response.msg_len))) { @@ -144,7 +144,7 @@ /* * Recycle the buffer */ - pr_debug("%s: Buffer size : %d\n", adapter[card]->devicename, BUFFER_SIZE); + pr_debug("%s: buffer size : %d\n", adapter[card]->devicename, BUFFER_SIZE); /* memset_shmem(card, rcvmsg->msg_data.response.buff_offset, 0, BUFFER_SIZE); */ newll.buff_offset = rcvmsg->msg_data.response.buff_offset; newll.msg_len = BUFFER_SIZE; @@ -163,30 +163,30 @@ LLData RcvBuffOffset; if(!IS_VALID_CARD(card)) { - pr_debug("Invalid param: %d is not a valid card id\n", card); + pr_debug("invalid param: %d is not a valid card id\n", card); return -ENODEV; } /* * Calculate the buffer offsets (send/recv/send/recv) */ - pr_debug("%s: Seting up channel buffer space in shared RAM\n", adapter[card]->devicename); + pr_debug("%s: setting up channel buffer space in shared RAM\n", adapter[card]->devicename); buffer_size = BUFFER_SIZE; nBuffers = ((adapter[card]->ramsize - BUFFER_BASE) / buffer_size) / 2; nBuffers = nBuffers > BUFFERS_MAX ? BUFFERS_MAX : nBuffers; - pr_debug("%s: Calculating buffer space: %d buffers, %d big\n", adapter[card]->devicename, + pr_debug("%s: calculating buffer space: %d buffers, %d big\n", adapter[card]->devicename, nBuffers, buffer_size); if(nBuffers < 2) { - pr_debug("%s: Not enough buffer space\n", adapter[card]->devicename); + pr_debug("%s: not enough buffer space\n", adapter[card]->devicename); return -1; } cBase = (nBuffers * buffer_size) * (c - 1); - pr_debug("%s: Channel buffer offset from Shared RAM: 0x%x\n", adapter[card]->devicename, cBase); + pr_debug("%s: channel buffer offset from shared RAM: 0x%x\n", adapter[card]->devicename, cBase); adapter[card]->channel[c-1].first_sendbuf = BUFFER_BASE + cBase; adapter[card]->channel[c-1].num_sendbufs = nBuffers / 2; adapter[card]->channel[c-1].free_sendbufs = nBuffers / 2; adapter[card]->channel[c-1].next_sendbuf = 0; - pr_debug("%s: Send buffer setup complete: first=0x%x n=%d f=%d, nxt=%d\n", + pr_debug("%s: send buffer setup complete: first=0x%x n=%d f=%d, nxt=%d\n", adapter[card]->devicename, adapter[card]->channel[c-1].first_sendbuf, adapter[card]->channel[c-1].num_sendbufs, @@ -196,13 +196,13 @@ /* * Prep the receive buffers */ - pr_debug("%s: Adding %d RecvBuffers:\n", adapter[card]->devicename, nBuffers /2); + pr_debug("%s: adding %d RecvBuffers:\n", adapter[card]->devicename, nBuffers /2); for (i = 0 ; i < nBuffers / 2; i++) { RcvBuffOffset.buff_offset = ((adapter[card]->channel[c-1].first_sendbuf + (nBuffers / 2) * buffer_size) + (buffer_size * i)); RcvBuffOffset.msg_len = buffer_size; - pr_debug("%s: Adding RcvBuffer #%d offset=0x%x sz=%d buffsz:%d\n", + pr_debug("%s: adding RcvBuffer #%d offset=0x%x sz=%d bufsz:%d\n", adapter[card]->devicename, i + 1, RcvBuffOffset.buff_offset, RcvBuffOffset.msg_len,buffer_size); diff -u --recursive --new-file v2.3.26/linux/drivers/misc/Config.in linux/drivers/misc/Config.in --- v2.3.26/linux/drivers/misc/Config.in Sat Oct 9 11:47:50 1999 +++ linux/drivers/misc/Config.in Mon Nov 8 17:59:15 1999 @@ -4,6 +4,6 @@ mainmenu_option next_comment comment 'Misc devices' -tristate 'Generic ACPI support' CONFIG_ACPI +bool 'ACPI support' CONFIG_ACPI endmenu diff -u --recursive --new-file v2.3.26/linux/drivers/misc/Makefile linux/drivers/misc/Makefile --- v2.3.26/linux/drivers/misc/Makefile Sat Oct 9 11:47:50 1999 +++ linux/drivers/misc/Makefile Mon Nov 8 17:59:15 1999 @@ -19,11 +19,7 @@ OX_OBJS := ifeq ($(CONFIG_ACPI),y) - O_OBJS += acpi.o -else - ifeq ($(CONFIG_ACPI),m) - M_OBJS += acpi.o - endif + OX_OBJS += acpi.o endif include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.26/linux/drivers/misc/acpi.c linux/drivers/misc/acpi.c --- v2.3.26/linux/drivers/misc/acpi.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/misc/acpi.c Wed Nov 10 20:01:03 1999 @@ -54,6 +54,7 @@ #define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue * x = NULL #endif +static int acpi_idle_thread(void *context); static int acpi_do_ulong(ctl_table *ctl, int write, struct file *file, @@ -69,6 +70,13 @@ struct file *file, void *buffer, size_t *len); +static int acpi_do_sleep_wake(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len); + +DECLARE_WAIT_QUEUE_HEAD(acpi_idle_wait); static struct ctl_table_header *acpi_sysctl = NULL; @@ -84,6 +92,9 @@ static volatile u32 acpi_gpe_level = 0; static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); +static spinlock_t acpi_devs_lock = SPIN_LOCK_UNLOCKED; +static LIST_HEAD(acpi_devs); + /* 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; @@ -147,6 +158,11 @@ &acpi_slp_typ[5], sizeof(acpi_slp_typ[5]), 0600, NULL, &acpi_do_ulong}, +#if 0 + {123, "sleep", (void*) 1, 0, 0600, NULL, &acpi_do_sleep_wake}, + {124, "wake", NULL, 0, 0600, NULL, &acpi_do_sleep_wake}, +#endif + {0} }; @@ -319,15 +335,23 @@ if (addr) { // map table header to determine size table = (struct acpi_table *) - ioremap_nocache((unsigned long) addr, - sizeof(struct acpi_table)); + ioremap((unsigned long) addr, + sizeof(struct acpi_table)); if (table) { unsigned long table_size = table->length; iounmap(table); // remap entire table table = (struct acpi_table *) - ioremap_nocache((unsigned long) addr, - table_size); + ioremap((unsigned long) addr, table_size); + } + + if (!table) { + /* ioremap is a pain, it returns NULL if the + * table starts within mapped physical memory. + * Hopefully, no table straddles a mapped/unmapped + * physical memory boundary, ugh + */ + table = (struct acpi_table*) phys_to_virt(addr); } } return table; @@ -338,6 +362,7 @@ */ static void acpi_unmap_table(struct acpi_table *table) { + // iounmap ignores addresses within physical memory if (table) iounmap(table); } @@ -380,8 +405,14 @@ // fetch RSDT from RSDP rsdt = acpi_map_table(rsdp->rsdt); - if (!rsdt || rsdt->signature != ACPI_RSDT_SIG) { - printk(KERN_ERR "ACPI: missing RSDT\n"); + if (!rsdt) { + printk(KERN_ERR "ACPI: missing RSDT at 0x%p\n", + (void*) rsdp->rsdt); + return -ENODEV; + } + else if (rsdt->signature != ACPI_RSDT_SIG) { + printk(KERN_ERR "ACPI: bad RSDT at 0x%p (%08x)\n", + (void*) rsdp->rsdt, (unsigned) rsdt->signature); acpi_unmap_table(rsdt); return -ENODEV; } @@ -396,9 +427,15 @@ acpi_facp_addr = *rsdt_entry; acpi_dsdt_addr = acpi_facp->dsdt; + // map FACS if it exists if (acpi_facp->facs) { - acpi_facs = (struct acpi_facs*) - acpi_map_table(acpi_facp->facs); + dt = acpi_map_table(acpi_facp->facs); + if (dt && dt->signature == ACPI_FACS_SIG) { + acpi_facs = (struct acpi_facs*) dt; + } + else { + acpi_unmap_table(dt); + } } } else { @@ -624,6 +661,34 @@ } /* + * Put all devices into specified D-state + */ +static int acpi_enter_dx(acpi_dstate_t state) +{ + int status = 0; + struct list_head *i = acpi_devs.next; + + while (i != &acpi_devs) { + struct acpi_dev *dev = list_entry(i, struct acpi_dev, entry); + if (dev->state != state) { + int dev_status = 0; + if (dev->info.transition) + dev_status = dev->info.transition(dev, state); + if (!dev_status) { + // put hardware into D-state + dev->state = state; + } + if (dev_status) + status = dev_status; + } + + i = i->next; + } + + return status; +} + +/* * Enter system sleep state */ static void acpi_enter_sx(int state) @@ -903,10 +968,41 @@ } /* + * Sleep or wake system + */ +static int acpi_do_sleep_wake(ctl_table *ctl, + int write, + struct file *file, + void *buffer, + size_t *len) +{ + if (!write) { + if (file->f_pos) { + *len = 0; + return 0; + } + } + else + { + // just shutdown some devices for now + if (ctl->data) { + acpi_enter_dx(ACPI_D3); + } + else { + acpi_enter_dx(ACPI_D0); + } + } + file->f_pos += *len; + return 0; +} + +/* * Initialize and enable ACPI */ static int __init acpi_init(void) { + int pid; + if (acpi_find_tables() && acpi_find_piix4()) { // no ACPI tables and not PIIX4 return -ENODEV; @@ -917,7 +1013,7 @@ acpi_irq, SA_INTERRUPT | SA_SHIRQ, "acpi", - NULL)) { + acpi_facp)) { printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", acpi_facp->sci_int); acpi_destroy_tables(); @@ -927,6 +1023,10 @@ acpi_claim_ioports(acpi_facp); acpi_sysctl = register_sysctl_table(acpi_dir_table, 1); + pid = kernel_thread(acpi_idle_thread, + NULL, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + /* * Set up the ACPI idle function. Note that we can't really * do this with multiple CPU's, we'd need a per-CPU ACPI @@ -956,18 +1056,84 @@ acpi_release_ioports(acpi_facp); if (acpi_facp->sci_int) - free_irq(acpi_facp->sci_int, NULL); + free_irq(acpi_facp->sci_int, acpi_facp); acpi_destroy_tables(); } -#ifdef MODULE +/* + * Register a device with the ACPI subsystem + */ +struct acpi_dev* acpi_register(struct acpi_dev_info *info, unsigned long adr) +{ + struct acpi_dev *dev = NULL; + if (info) { + dev = kmalloc(sizeof(struct acpi_dev), GFP_KERNEL); + if (dev) { + unsigned long flags; + + memset(dev, 0, sizeof(*dev)); + memcpy(&dev->info, info, sizeof(dev->info)); + dev->adr = adr; + + spin_lock_irqsave(&acpi_devs_lock, flags); + list_add(&dev->entry, &acpi_devs); + spin_unlock_irqrestore(&acpi_devs_lock, flags); + } + } + return dev; +} -module_init(acpi_init) -module_exit(acpi_exit) +/* + * Unregister a device with ACPI + */ +void acpi_unregister(struct acpi_dev *dev) +{ + if (dev) { + unsigned long flags; -#else + spin_lock_irqsave(&acpi_devs_lock, flags); + list_del(&dev->entry); + spin_unlock_irqrestore(&acpi_devs_lock, flags); + + kfree(dev); + } +} + +/* + * Wake up a device + */ +void acpi_wakeup(struct acpi_dev *dev) +{ + // run _PS0 or tell parent bus to wake device up +} + +/* + * Manage idle devices + */ +static int acpi_idle_thread(void *context) +{ + exit_mm(current); + exit_files(current); + strcpy(current->comm, "acpi"); + + for(;;) { + interruptible_sleep_on(&acpi_idle_wait); + if (signal_pending(current)) + break; + + // find all idle devices and set idle timer based on policy + } + + return 0; +} __initcall(acpi_init); -#endif +/* + * Module visible symbols + */ +EXPORT_SYMBOL(acpi_idle_wait); +EXPORT_SYMBOL(acpi_register); +EXPORT_SYMBOL(acpi_unregister); +EXPORT_SYMBOL(acpi_wakeup); diff -u --recursive --new-file v2.3.26/linux/drivers/net/3c507.c linux/drivers/net/3c507.c --- v2.3.26/linux/drivers/net/3c507.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/net/3c507.c Wed Nov 10 09:52:27 1999 @@ -781,7 +781,7 @@ isa_memcpy_toio(write_ptr+2, buf, length); /* Set the old command link pointing to this send packet. */ - isa_isa_writew(tx_block,dev->mem_start + lp->tx_cmd_link); + isa_writew(tx_block,dev->mem_start + lp->tx_cmd_link); lp->tx_cmd_link = tx_block + 20; /* Set the next free tx region. */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c --- v2.3.26/linux/drivers/net/3c59x.c Fri Sep 10 23:57:29 1999 +++ linux/drivers/net/3c59x.c Tue Nov 9 08:20:12 1999 @@ -229,15 +229,13 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int drv_flags, io_size; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_idx, int fnd_cnt); + struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, HAS_PWR_CTRL=0x10, HAS_MII=0x20, HAS_NWAY=0x40, HAS_CB_FNS=0x80, }; -static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, - int irq, int dev_id, int card_idx); +static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, int dev_id, int card_idx); + static struct pci_id_info pci_tbl[] = { {"3c590 Vortex 10Mbps", 0x10B7, 0x5900, 0xffff, PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1}, @@ -493,7 +491,7 @@ }; #ifndef CARDBUS -static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]); +static int vortex_scan(struct pci_id_info pci_tbl[]); #endif static int vortex_open(struct net_device *dev); static void mdio_sync(long ioaddr, int bits); @@ -563,7 +561,7 @@ "vortex_attach().\n", vendor_id, dev_id); return NULL; } - dev = vortex_probe1(bus, devfn, NULL, io, irq, chip_idx, MAX_UNITS+1); + dev = vortex_probe1(bus, devfn, io, irq, chip_idx, MAX_UNITS+1); if (dev) { dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL); strcpy(node->dev_name, dev->name); @@ -614,25 +612,26 @@ register_driver(&vortex_ops); return 0; #else - return vortex_scan(0, pci_tbl); + return vortex_scan(pci_tbl); #endif } #else -int tc59x_probe(struct net_device *dev) +int tc59x_probe(void) { static int scanned=0; if(scanned++) return -ENODEV; printk(KERN_INFO "%s", version); - return vortex_scan(dev, pci_tbl); + return vortex_scan(pci_tbl); } #endif /* not MODULE */ #ifndef CARDBUS -static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]) +static int vortex_scan(struct pci_id_info pci_tbl[]) { int cards_found = 0; + struct net_device *dev; /* Allow an EISA-only driver. */ #if defined(CONFIG_PCI) || (defined(MODULE) && !defined(NO_PCI)) @@ -712,7 +711,7 @@ PCI_COMMAND, new_command); } - dev = vortex_probe1(pci_bus, pci_device_fn, dev, ioaddr, irq, + dev = vortex_probe1(pci_bus, pci_device_fn, ioaddr, irq, chip_idx, cards_found); if (dev) { @@ -753,9 +752,8 @@ device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83); if ((device_id & 0xFF00) != 0x5900) continue; - vortex_probe1(0, 0, dev, ioaddr, inw(ioaddr + 0xC88) >> 12, + vortex_probe1(0, 0, ioaddr, inw(ioaddr + 0xC88) >> 12, 4, cards_found); - dev = 0; cards_found++; } } @@ -763,7 +761,7 @@ #ifdef MODULE /* Special code to work-around the Compaq PCI BIOS32 problem. */ if (compaq_ioaddr) { - vortex_probe1(0, 0, dev, compaq_ioaddr, compaq_irq, + vortex_probe1(0, 0, compaq_ioaddr, compaq_irq, compaq_device_id, cards_found++); dev = 0; } @@ -774,15 +772,15 @@ #endif /* ! Cardbus */ static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, - int irq, int chip_idx, int card_idx) + long ioaddr, int irq, int chip_idx, int card_idx) { struct vortex_private *vp; int option; unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */ int i; + struct net_device *dev; - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); printk(KERN_INFO "%s: 3Com %s at 0x%lx, ", dev->name, pci_tbl[chip_idx].name, ioaddr); diff -u --recursive --new-file v2.3.26/linux/drivers/net/82596.c linux/drivers/net/82596.c --- v2.3.26/linux/drivers/net/82596.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/net/82596.c Mon Nov 8 11:03:20 1999 @@ -11,10 +11,15 @@ by Richard Hirst Renamed to be 82596.c - *** Untested on Apricot hardware, and may require some hacking - *** to make it work. The old 82596.c reported hasn't worked - *** since 1.3.xx anyway. I have been unable to find any users - *** of Apricot hardware to test this on. + 980825: Changed to receive directly in to sk_buffs which are + allocated at open() time. Eliminates copy on incoming frames + (small ones are still copied). Shared data now held in a + non-cached page, so we can run on 68060 in copyback mode. + + TBD: + * look at deferring rx frames rather than discarding (as per tulip) + * handle tx ring full as per tulip + * performace test to tune rx_copybreak Most of my modifications relate to the braindead big-endian implementation by Intel. When the i596 is operating in @@ -57,12 +62,22 @@ #include #include #include -#include /*?? */ +#include -#ifdef CONFIG_MVME16x_NET +#if defined(CONFIG_MVME16x_NET) || defined(CONFIG_MVME16x_NET_MODULE) +#define ENABLE_MVME16x_NET +#endif +#if defined(CONFIG_BVME6000_NET) || defined(CONFIG_BVME6000_NET_MODULE) +#define ENABLE_BVME6000_NET +#endif +#if defined(CONFIG_APRICOT) || defined(CONFIG_APRICOT_MODULE) +#define ENABLE_APRICOT +#endif + +#ifdef ENABLE_MVME16x_NET #include #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET #include #endif @@ -83,11 +98,12 @@ #define MACH_IS_APRICOT 0 #else #define WSWAPrfd(x) x +#define WSWAPrbd(x) ((struct i596_rbd *)(x)) #define WSWAPiscp(x) ((struct i596_iscp *)(x)) #define WSWAPscb(x) ((struct i596_scb *)(x)) #define WSWAPcmd(x) x #define WSWAPtbd(x) x -#define WSWAPchar(x) x +#define WSWAPchar(x) ((char *)(x)) #define ISCP_BUSY 0x0001 #define MACH_IS_APRICOT 1 #endif @@ -103,19 +119,22 @@ #define PORT_ALTSCP 0x02 /* alternate SCB address */ #define PORT_ALTDUMP 0x03 /* Alternate DUMP address */ -#ifndef HAVE_ALLOC_SKB -#define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority) -#define kfree_skbmem(buff, size) kfree_s(buff,size) -#endif - -#define APRICOT_DEBUG 2 +#define I82596_DEBUG 1 -#ifdef APRICOT_DEBUG -int i596_debug = APRICOT_DEBUG; +#ifdef I82596_DEBUG +int i596_debug = I82596_DEBUG; #else int i596_debug = 1; #endif +/* Copy frames shorter than rx_copybreak, otherwise pass on up in + * a full sized sk_buff. Value of 100 stolen from tulip.c (!alpha). + */ +static int rx_copybreak = 100; + +#define PKT_BUF_SZ 1536 +#define MAX_MC_CNT 64 + #define I596_TOTAL_SIZE 17 #define I596_NULL -1 @@ -179,12 +198,22 @@ unsigned short stat; unsigned short cmd; struct i596_rfd *next; - long rbd; + struct i596_rbd *rbd; unsigned short count; unsigned short size; - char data[1532]; }; +struct i596_rbd { + unsigned short count; + unsigned short zero1; + struct i596_rbd *next; + char *data; + unsigned short size; + unsigned short zero2; + struct sk_buff *skb; +}; + +#define TX_RING_SIZE 16 #define RX_RING_SIZE 16 struct i596_scb { @@ -222,6 +251,9 @@ struct i596_cmd set_conf; char i596_config[16]; struct i596_cmd tdr; + struct i596_cmd mc_cmd; /* Keep these three together!!! */ + short mc_cnt; /* Keep these three together!!! */ + char mc_addrs[MAX_MC_CNT*6]; /* Keep these three together!!! */ unsigned long stat; int last_restart __attribute__((aligned(4))); struct i596_rfd *rx_tail; @@ -230,6 +262,11 @@ int cmd_backlog; unsigned long last_cmd; struct net_device_stats stats; + struct i596_rfd rfds[RX_RING_SIZE]; + struct i596_rbd rbds[RX_RING_SIZE]; + struct tx_cmd tx_cmds[TX_RING_SIZE]; + struct i596_tbd tbds[TX_RING_SIZE]; + int next_tx_cmd; }; char init_setup[] = @@ -262,23 +299,24 @@ static void print_eth(char *); static void set_multicast_list(struct net_device *dev); +static int rx_ring_size = RX_RING_SIZE; static int ticks_limit = 25; static int max_cmd_backlog = 16; static inline void CA(struct net_device *dev) { -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { ((struct i596_reg *) dev->base_addr)->ca = 1; } #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { volatile u32 i = *(volatile u32 *) (dev->base_addr); } #endif -#ifdef CONFIG_APRICOT_i596 +#ifdef ENABLE_APRICOT if (MACH_IS_APRICOT) { outw(0, (short) (dev->base_addr) + 4); } @@ -288,14 +326,14 @@ static inline void MPU_PORT(struct net_device *dev, int c, volatile void *x) { -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { struct i596_reg *p = (struct i596_reg *) (dev->base_addr); p->porthi = ((c) | (u32) (x)) & 0xffff; p->portlo = ((c) | (u32) (x)) >> 16; } #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { u32 v = (u32) (c) | (u32) (x); v = ((u32) (v) << 16) | ((u32) (v) >> 16); @@ -307,7 +345,7 @@ } -#if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) +#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET) static void i596_error(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; @@ -333,77 +371,88 @@ } #endif -static inline int init_rx_bufs(struct net_device *dev, int num) +static inline void init_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = (struct i596_private *)dev->priv; int i; struct i596_rfd *rfd; - - lp->scb.rfd = (struct i596_rfd *) I596_NULL; + struct i596_rbd *rbd; if (i596_debug > 1) - printk("%s: init_rx_bufs %d.\n", dev->name, num); + printk ("%s: init_rx_bufs %d.\n", dev->name, rx_ring_size); - for (i = 0; i < num; i++) { - if (!(rfd = (struct i596_rfd *) kmalloc(sizeof(struct i596_rfd), GFP_KERNEL))) - break; + /* First build the Receive Buffer Descriptor List */ - rfd->stat = 0x0000; - rfd->rbd = I596_NULL; - rfd->count = 0; - rfd->size = 1532; - if (i == 0) { - rfd->cmd = CMD_EOL; - lp->rx_tail = rfd; - } else - rfd->cmd = 0x0000; + for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { + struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); - rfd->next = lp->scb.rfd; - lp->scb.rfd = WSWAPrfd(rfd); + if (skb == NULL) + panic("82596: alloc_skb() failed"); + skb->dev = dev; + rbd->next = WSWAPrbd(rbd+1); + rbd->skb = skb; + rbd->data = WSWAPchar(skb->tail); + rbd->size = PKT_BUF_SZ; +#ifdef __mc68000__ + cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ); +#endif } + lp->rbds[rx_ring_size-1].next = WSWAPrbd(lp->rbds); - if (i != 0) - lp->rx_tail->next = lp->scb.rfd; + /* Now build the Receive Frame Descriptor List */ - return (i); + for (i = 0, rfd = lp->rfds; i < rx_ring_size; i++, rfd++) { + rfd->rbd = (struct i596_rbd *)I596_NULL; + rfd->next = WSWAPrfd(rfd+1); + rfd->cmd = CMD_FLEX; + } + lp->scb.rfd = WSWAPrfd(lp->rfds); + lp->rfds[0].rbd = WSWAPrbd(lp->rbds); + rfd = lp->rfds + rx_ring_size - 1; + lp->rx_tail = rfd; + rfd->next = WSWAPrfd(lp->rfds); + rfd->cmd = CMD_EOL|CMD_FLEX; } static inline void remove_rx_bufs(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; - struct i596_rfd *rfd = WSWAPrfd(lp->scb.rfd); - - lp->rx_tail->next = (struct i596_rfd *) I596_NULL; + struct i596_private *lp = (struct i596_private *)dev->priv; + struct i596_rbd *rbd; + int i; - do { - lp->scb.rfd = rfd->next; - kfree(rfd); - rfd = WSWAPrfd(lp->scb.rfd); + for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) { + if (rbd->skb == NULL) + break; + dev_kfree_skb(rbd->skb); } - while (rfd != lp->rx_tail); } static inline void init_i596_mem(struct net_device *dev) { struct i596_private *lp = (struct i596_private *) dev->priv; -#if !defined(CONFIG_MVME16x_NET) && !defined(CONFIG_BVME6000_NET) +#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) short ioaddr = dev->base_addr; #endif int boguscnt = 100000; unsigned long flags; + int i; -#if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) -#ifdef CONFIG_MVME16x_NET +#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET) +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000; /* Disable all ints for now */ pcc2[0x28] = 1; pcc2[0x2a] = 0x40; - pcc2[0x2b] = 0x40; /* Set snooping bits now! */ + /* Following disables snooping. Snooping is not required + * as we make appropriate use of non-cached pages for + * shared data, and cache_push/cache_clear. + */ + pcc2[0x2b] = 0x00; } #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG; @@ -419,7 +468,7 @@ MPU_PORT(dev, PORT_ALTSCP, &lp->scp); -#else +#elif defined(ENABLE_APRICOT) /* change the scp address */ outw(0, ioaddr); @@ -431,15 +480,15 @@ lp->last_cmd = jiffies; -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) lp->scp.sysbus = 0x00000054; #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) lp->scp.sysbus = 0x0000004c; #endif -#ifdef CONFIG_APRICOT_i596 +#ifdef ENABLE_APRICOT if (MACH_IS_APRICOT) lp->scp.sysbus = 0x00440000; #endif @@ -454,7 +503,7 @@ if (i596_debug > 1) printk("%s: starting i82596.\n", dev->name); -#if !defined(CONFIG_MVME16x_NET) && !defined(CONFIG_BVME6000_NET) +#if defined(ENABLE_APRICOT) (void) inb(ioaddr + 0x10); outb(4, ioaddr + 0xf); #endif @@ -466,9 +515,22 @@ dev->name, lp->scb.status, lp->scb.command); break; } + + /* Ensure rx frame/buffer descriptors are tidy */ + /* Bit naff doing this here as well as in init_rx_bufs() */ + + for (i = 0; i < rx_ring_size; i++) { + lp->rfds[i].rbd = (struct i596_rbd *)I596_NULL; + lp->rfds[i].cmd = CMD_FLEX; + } + lp->rfds[rx_ring_size-1].cmd = CMD_EOL|CMD_FLEX; + lp->scb.rfd = WSWAPrfd(lp->rfds); + lp->rfds[0].rbd = WSWAPrbd(lp->rbds); + lp->rx_tail = lp->rfds + rx_ring_size - 1; + lp->scb.command = 0; -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000; @@ -478,7 +540,7 @@ pcc2[0x2b] = 0x55; } #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG; @@ -525,38 +587,88 @@ static inline int i596_rx(struct net_device *dev) { - struct i596_private *lp = (struct i596_private *) dev->priv; + struct i596_private *lp = (struct i596_private *)dev->priv; struct i596_rfd *rfd; + struct i596_rbd *rbd; int frames = 0; if (i596_debug > 3) - printk("i596_rx()\n"); + printk ("i596_rx()\n"); - rfd = WSWAPrfd(lp->scb.rfd); /* Reference next frame descriptor to check */ + rfd = WSWAPrfd(lp->scb.rfd); /* Ref next frame to check */ - while ((rfd->stat) & STAT_C) { /* Loop while we have complete frames */ - if (i596_debug > 2) - print_eth(rfd->data); + while ((rfd->stat) & STAT_C) { /* Loop while complete frames */ + rbd = WSWAPrbd(rfd->rbd); /* Ref associated buffer desc */ + + if (i596_debug >2) + print_eth(WSWAPchar(rbd->data)); if ((rfd->stat) & STAT_OK) { /* a good frame */ - int pkt_len = rfd->count & 0x3fff; - struct sk_buff *skb = dev_alloc_skb(pkt_len); + int pkt_len = rbd->count & 0x3fff; + struct sk_buff *skb = rbd->skb; + int rx_in_place = 0; frames++; + /* Check if the packet is long enough to just accept + * without copying to a properly sized skbuff. + */ + + if (pkt_len > rx_copybreak) { + struct sk_buff *newskb; + char *temp; + + /* Get fresh skbuff to replace filled one. */ + newskb = dev_alloc_skb(PKT_BUF_SZ); + if (newskb == NULL) { + skb = NULL; /* drop pkt */ + goto memory_squeeze; + } + /* Pass up the skb already on the Rx ring. */ + temp = skb_put(skb, pkt_len); + if (WSWAPchar(rbd->data) != temp) + printk(KERN_ERR "%s: Internal consistency error " + "-- the skbuff addresses do not match" + " in i596_rx: %p vs. %p / %p.\n", dev->name, + WSWAPchar(rbd->data), + skb->head, temp); + rx_in_place = 1; + rbd->skb = newskb; + newskb->dev = dev; + rbd->data = WSWAPchar(newskb->tail); +#ifdef __mc68000__ + cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ); +#endif + } + else + skb = dev_alloc_skb(pkt_len + 2); +memory_squeeze: if (skb == NULL) { - printk("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name); + /* XXX tulip.c can defer packets here!! */ + printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; - } else { + } + else { skb->dev = dev; - memcpy(skb_put(skb, pkt_len), rfd->data, pkt_len); - skb->protocol = eth_type_trans(skb, dev); + if (!rx_in_place) { + /* 16 byte align the data fields */ + skb_reserve(skb, 2); + memcpy(skb_put(skb,pkt_len), + WSWAPchar(rbd->data), pkt_len); + } + skb->protocol=eth_type_trans(skb,dev); + skb->len = pkt_len; +#ifdef __mc68000__ + cache_clear(virt_to_phys(rbd->skb->tail), + pkt_len); +#endif netif_rx(skb); lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; + lp->stats.rx_bytes+=pkt_len; } - } else { + } + else { lp->stats.rx_errors++; if ((rfd->stat) & 0x0001) lp->stats.collisions++; @@ -576,21 +688,40 @@ /* Clear the buffer descriptor count and EOF + F flags */ + if (rbd != (struct i596_rbd *)I596_NULL) + rbd->count=0; + else + printk("%s: Null rbd - oops!\n", dev->name); + + /* Tidy the frame descriptor, marking it as end of list */ + + rfd->rbd = (struct i596_rbd *)I596_NULL; rfd->stat = 0; + rfd->cmd = CMD_EOL|CMD_FLEX; rfd->count = 0; - rfd->cmd = CMD_EOL; - lp->rx_tail->cmd = 0; + + /* Remove end-of-list from old end descriptor */ + + lp->rx_tail->cmd = CMD_FLEX; + + /* Update last frame descriptor to reference the one just + * processed */ + lp->rx_tail = rfd; + + /* Update record of next frame descriptor to process */ + lp->scb.rfd = rfd->next; - rfd = WSWAPrfd(lp->scb.rfd); /* Next frame descriptor to check */ + rfd = WSWAPrfd(lp->scb.rfd); /* Next frame desc. to check */ } if (i596_debug > 3) - printk("frames %d\n", frames); + printk ("frames %d\n", frames); return 0; } + static inline void i596_cleanup_cmd(struct i596_private *lp) { struct i596_cmd *ptr; @@ -617,13 +748,12 @@ lp->stats.tx_aborted_errors++; ptr->next = (struct i596_cmd *) I596_NULL; - kfree(tx_cmd); + tx_cmd->cmd.command = 0; /* Mark as free */ break; } case CmdMulticastList: { ptr->next = (struct i596_cmd *) I596_NULL; - kfree(ptr); break; } default: @@ -743,26 +873,19 @@ static int i596_open(struct net_device *dev) { - int i; - if (i596_debug > 1) printk("%s: i596_open() irq %d.\n", dev->name, dev->irq); - if (request_irq(dev->irq, &i596_interrupt, 0, "apricot", dev)) + if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) return -EAGAIN; -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { - if (request_irq(0x56, &i596_error, 0, "apricot_error", dev)) + if (request_irq(0x56, &i596_error, 0, "i82596_error", dev)) return -EAGAIN; } #endif - if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE) - printk("%s: only able to allocate %d receive buffers\n", dev->name, i); + init_rx_bufs(dev); - if (i < 4) { - free_irq(dev->irq, dev); - return -EAGAIN; - } dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; @@ -779,6 +902,7 @@ struct i596_private *lp = (struct i596_private *) dev->priv; int ioaddr = dev->base_addr; struct tx_cmd *tx_cmd; + struct i596_tbd *tbd; if (i596_debug > 2) printk("%s: 82596 start xmit\n", dev->name); @@ -810,7 +934,8 @@ dev->trans_start = jiffies; } if (i596_debug > 3) - printk("%s: i596_start_xmit() called\n", dev->name); + printk("%s: i596_start_xmit(%x,%x) called\n", dev->name, + skb->len, (unsigned int)skb->data); /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ @@ -820,14 +945,18 @@ short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; dev->trans_start = jiffies; - tx_cmd = (struct tx_cmd *) kmalloc((sizeof(struct tx_cmd) + sizeof(struct i596_tbd)), GFP_ATOMIC); - if (tx_cmd == NULL) { - printk("%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name); + tx_cmd = lp->tx_cmds + lp->next_tx_cmd; + tbd = lp->tbds + lp->next_tx_cmd; + + if (tx_cmd->cmd.command) { + printk ("%s: xmit ring full, dropping packet.\n", + dev->name); lp->stats.tx_dropped++; dev_kfree_skb(skb); } else { - struct i596_tbd *tbd = (struct i596_tbd *) (tx_cmd + 1); + if (++lp->next_tx_cmd == TX_RING_SIZE) + lp->next_tx_cmd = 0; tx_cmd->tbd = WSWAPtbd(tbd); tbd->next = (struct i596_tbd *) I596_NULL; @@ -841,6 +970,9 @@ tbd->data = WSWAPchar(skb->data); +#ifdef __mc68000__ + cache_push(virt_to_phys(skb->data), length); +#endif if (i596_debug > 3) print_eth(skb->data); i596_add_cmd(dev, (struct i596_cmd *) tx_cmd); @@ -854,7 +986,6 @@ return 0; } - static void print_eth(char *add) { @@ -879,14 +1010,15 @@ struct i596_private *lp; char eth_addr[6]; -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { static int probed = 0; - +#ifdef XXX_FIXME if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) { printk("Ethernet probe disabled - chip not present\n"); return ENODEV; } +#endif if (probed) return ENODEV; probed++; @@ -895,7 +1027,7 @@ dev->irq = (unsigned) MVME16x_IRQ_I596; } #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { volatile unsigned char *rtc = (unsigned char *) BVME_RTC_BASE; unsigned char msr = rtc[3]; @@ -909,7 +1041,7 @@ dev->irq = (unsigned) BVME_IRQ_I596; } #endif -#ifdef CONFIG_APRICOT_INTEL +#ifdef ENABLE_APRICOT int checksum = 0; int ioaddr = 0x300; @@ -953,22 +1085,28 @@ if (i596_debug > 0) printk(version); - /* The APRICOT-specific entries in the device structure. */ + /* The 82596-specific entries in the device structure. */ dev->open = &i596_open; dev->stop = &i596_close; dev->hard_start_xmit = &i596_start_xmit; dev->get_stats = &i596_get_stats; dev->set_multicast_list = &set_multicast_list; - dev->mem_start = (int) kmalloc(sizeof(struct i596_private) + 0x0f, GFP_KERNEL); - /* align for scp */ - dev->priv = (void *) ((dev->mem_start + 0xf) & 0xfffffff0); + dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0); + dev->priv = (void *)(dev->mem_start); lp = (struct i596_private *) dev->priv; if (i596_debug) - printk("%s: lp at 0x%08lx, lp->scb at 0x%08lx\n" - ,dev->name, (unsigned long) lp, (unsigned long) &lp->scb); + printk ("%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n", + dev->name, (unsigned long)lp, + sizeof(struct i596_private), (unsigned long)&lp->scb); memset((void *) lp, 0, sizeof(struct i596_private)); + +#ifdef __mc68000__ + cache_push(virt_to_phys((void *)(dev->mem_start)), 4096); + cache_clear(virt_to_phys((void *)(dev->mem_start)), 4096); + kernel_set_cachemode((void *)(dev->mem_start), 4096, IOMAP_NOCACHE_SER); +#endif lp->scb.command = 0; lp->scb.cmd = (struct i596_cmd *) I596_NULL; lp->scb.rfd = (struct i596_rfd *) I596_NULL; @@ -984,7 +1122,7 @@ int boguscnt = 2000; unsigned short status, ack_cmd = 0; -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { if (*(char *) BVME_LOCAL_IRQ_STAT & BVME_ETHERR) { i596_error(BVME_IRQ_I596, NULL, NULL); @@ -1063,13 +1201,12 @@ dev_kfree_skb(skb); ptr->next = (struct i596_cmd *) I596_NULL; - kfree(tx_cmd); + tx_cmd->cmd.command = 0; /* Mark free */ break; } case CmdMulticastList: { ptr->next = (struct i596_cmd *) I596_NULL; - kfree(ptr); break; } case CmdTDR: @@ -1141,7 +1278,7 @@ } lp->scb.command = ack_cmd; -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { /* Ack the interrupt */ @@ -1150,7 +1287,7 @@ pcc2[0x2a] |= 0x08; } #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG; @@ -1158,7 +1295,7 @@ *ethirq = 3; } #endif -#ifdef CONFIG_APRICOT_INTEL +#ifdef ENABLE_APRICOT (void) inb(ioaddr + 0x10); outb(4, ioaddr + 0xf); #endif @@ -1208,7 +1345,7 @@ i596_cleanup_cmd(lp); -#ifdef CONFIG_MVME16x_NET +#ifdef ENABLE_MVME16x_NET if (MACH_IS_MVME16x) { volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000; @@ -1218,7 +1355,7 @@ pcc2[0x2b] = 0x40; /* Set snooping bits now! */ } #endif -#ifdef CONFIG_BVME6000_NET +#ifdef ENABLE_BVME6000_NET if (MACH_IS_BVME6000) { volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG; @@ -1249,7 +1386,7 @@ { struct i596_private *lp = (struct i596_private *) dev->priv; struct i596_cmd *cmd; - int config = 0; + int config = 0, cnt; if (i596_debug > 1) printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n", dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF", dev->flags & IFF_ALLMULTI ? "ON" : "OFF"); @@ -1279,18 +1416,24 @@ i596_add_cmd(dev, &lp->set_conf); } } + + cnt = dev->mc_count; + if (cnt > MAX_MC_CNT) + { + cnt = MAX_MC_CNT; + printk("%s: Only %d multicast addresses supported", + dev->name, cnt); + } + if (dev->mc_count > 0) { struct dev_mc_list *dmi; unsigned char *cp; - cmd = (struct i596_cmd *) kmalloc(sizeof(struct i596_cmd) + 2 + dev->mc_count * 6, GFP_ATOMIC); - if (cmd == NULL) { - printk("%s: set_multicast Memory squeeze.\n", dev->name); - return; - } + + cmd = &lp->mc_cmd; cmd->command = CmdMulticastList; *((unsigned short *) (cmd + 1)) = dev->mc_count * 6; cp = ((unsigned char *) (cmd + 1)) + 2; - for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { + for(dmi=dev->mc_list;cnt && dmi!=NULL;dmi=dmi->next,cnt--) { memcpy(cp, dmi->dmi_addr, 6); if (i596_debug > 1) printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, *(cp + 0), *(cp + 1), *(cp + 2), *(cp + 3), *(cp + 4), *(cp + 5)); @@ -1306,40 +1449,58 @@ static unsigned int i596_portlist[] __initdata = {0x300, 0}; struct netdev_entry i596_drv = -{"apricot", i82596_probe, I596_TOTAL_SIZE, apricot_portlist}; +{"i82596", i82596_probe, I596_TOTAL_SIZE, i596_portlist}; #endif #ifdef MODULE static char devicename[9] = {0,}; -static struct net_device dev_apricot = +static struct net_device dev_82596 = { - devicename, /* device name inserted by /linux/drivers/net/net_init.c */ + devicename, /* device name inserted by drivers/net/net_init.c */ 0, 0, 0, 0, - 0x300, 10, + 0, 0, /* base, irq */ 0, 0, 0, NULL, i82596_probe}; +#ifdef ENABLE_APRICOT static int io = 0x300; static int irq = 10; MODULE_PARM(irq, "i"); +#endif + +MODULE_PARM(debug, "i"); +static int debug = -1; int init_module(void) { - dev_apricot.base_addr = io; - dev_apricot.irq = irq; - if (register_netdev(&dev_apricot) != 0) +#ifdef ENABLE_APRICOT + dev_82596.base_addr = io; + dev_82596.irq = irq; +#endif + if (debug >= 0) + i596_debug = debug; + if (register_netdev(&dev_82596) != 0) return -EIO; return 0; } void cleanup_module(void) { - unregister_netdev(&dev_apricot); - kfree((void *) dev_apricot.mem_start); - dev_apricot.priv = NULL; + unregister_netdev(&dev_82596); +#ifdef __mc68000__ + /* XXX This assumes default cache mode to be IOMAP_FULL_CACHING, + * XXX which may be invalid (CONFIG_060_WRITETHROUGH) + */ + kernel_set_cachemode((u32)(dev_82596.mem_start), 4096, + IOMAP_FULL_CACHING); +#endif + free_page ((u32)(dev_82596.mem_start)); + dev_82596.priv = NULL; +#ifdef ENABLE_APRICOT /* If we don't do this, we can't re-insmod it later. */ - release_region(dev_apricot.base_addr, I596_TOTAL_SIZE); + release_region(dev_82596.base_addr, I596_TOTAL_SIZE); +#endif } #endif /* MODULE */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/8390.c linux/drivers/net/8390.c --- v2.3.26/linux/drivers/net/8390.c Fri Sep 10 23:57:29 1999 +++ linux/drivers/net/8390.c Thu Nov 11 10:07:21 1999 @@ -1089,7 +1089,10 @@ int start_page) { long e8390_base = dev->base_addr; +#if defined(CONFIG_MAC) || defined(CONFIG_AMIGA_PCMCIA) || \ + defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE) struct ei_device *ei_local = (struct ei_device *) dev->priv; +#endif outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); diff -u --recursive --new-file v2.3.26/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.3.26/linux/drivers/net/Makefile Wed Oct 27 16:34:12 1999 +++ linux/drivers/net/Makefile Wed Nov 10 12:54:34 1999 @@ -3,8 +3,20 @@ # Makefile for the Linux network (ethercard) device drivers. # +O_OBJS := +M_OBJS := +MX_OBJS := + +# Object file lists. + +obj-y := +obj-m := +obj-n := +obj- := + SUB_DIRS := -MOD_SUB_DIRS := $(SUB_DIRS) +MOD_SUB_DIRS := +MOD_IN_SUB_DIRS := ALL_SUB_DIRS := $(SUB_DIRS) fc hamradio irda pcmcia tokenring wan L_TARGET := net.a @@ -12,18 +24,11 @@ M_OBJS := MOD_LIST_NAME := NET_MODULES -# Need these to keep track of whether the 7990 (LANCE), 8390, PPP and SLHC -# modules should really go in the kernel or a module. -CONFIG_8390_BUILTIN := -CONFIG_8390_MODULE := -CONFIG_SLHC_BUILTIN := -CONFIG_SLHC_MODULE := -CONFIG_PPPDEF_BUILTIN := -CONFIG_PPPDEF_MODULE := -CONFIG_7990_BUILTIN := -CONFIG_7990_MODULE := -CONFIG_82596_BUILTIN := -CONFIG_82596_MODULE := +# All of the (potential) objects that export symbols. +# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'. + +export-objs := 8390.o arcnet.o arlan.o ppp_async.o \ + ppp_generic.o slhc.o ifeq ($(CONFIG_PCMCIA),y) SUB_DIRS += pcmcia @@ -34,1072 +39,232 @@ endif endif -ifeq ($(CONFIG_ISDN),y) - ifeq ($(CONFIG_ISDN_PPP),y) - CONFIG_SLHC_BUILTIN = y - CONFIG_PPPDEF_BUILTIN = y - endif -else - ifeq ($(CONFIG_ISDN),m) - ifeq ($(CONFIG_ISDN_PPP),y) - CONFIG_SLHC_MODULE = y - CONFIG_PPPDEF_MODULE = y - endif - endif -endif - -ifeq ($(CONFIG_NET),y) -L_OBJS += Space.o net_init.o loopback.o -endif - -ifeq ($(CONFIG_SEEQ8005),y) -L_OBJS += seeq8005.o -endif - -ifeq ($(CONFIG_ETHERTAP),y) -L_OBJS += ethertap.o -else - ifeq ($(CONFIG_ETHERTAP),m) - M_OBJS += ethertap.o - endif -endif - -ifeq ($(CONFIG_NET_SB1000),y) -L_OBJS += sb1000.o -else - ifeq ($(CONFIG_NET_SB1000),m) - M_OBJS += sb1000.o - endif -endif - -ifeq ($(CONFIG_DAYNAPORT), y) -L_OBJS += daynaport.o -CONFIG_8390_BUILTIN = y -endif - -ifeq ($(CONFIG_APNE),y) -L_OBJS += apne.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_APNE),m) - M_OBJS += apne.o - CONFIG_8390_MODULE = y - endif -endif - -ifeq ($(CONFIG_PCMCIA_PCNET),y) -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_PCMCIA_PCNET),m) - CONFIG_8390_MODULE = y - endif -endif - -ifeq ($(CONFIG_SHAPER),y) -L_OBJS += shaper.o -else - ifeq ($(CONFIG_SHAPER),m) - M_OBJS += shaper.o - endif -endif - -ifeq ($(CONFIG_SK_G16),y) -L_OBJS += sk_g16.o -endif - -ifeq ($(CONFIG_HP100),y) -L_OBJS += hp100.o -else - ifeq ($(CONFIG_HP100),m) - M_OBJS += hp100.o - endif -endif - -ifeq ($(CONFIG_SMC9194),y) -L_OBJS += smc9194.o -else - ifeq ($(CONFIG_SMC9194),m) - M_OBJS += smc9194.o - endif -endif - -ifeq ($(CONFIG_ARM_AM79C961A),y) -L_OBJS += am79c961a.o -else - ifeq ($(CONFIG_ARM_AM79C961A),m) - M_OBJS += am79c961a.o - endif -endif - -ifeq ($(CONFIG_ARM_ETHERH),y) -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_ARM_ETHERH),m) - CONFIG_8390_MODULE = y - endif -endif - -ifeq ($(CONFIG_WD80x3),y) -L_OBJS += wd.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_WD80x3),m) - CONFIG_8390_MODULE = y - M_OBJS += wd.o - endif -endif - -ifeq ($(CONFIG_EL2),y) -L_OBJS += 3c503.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_EL2),m) - CONFIG_8390_MODULE = y - M_OBJS += 3c503.o - endif -endif - -ifeq ($(CONFIG_NE2K_PCI),y) -L_OBJS += ne2k-pci.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_NE2K_PCI),m) - CONFIG_8390_MODULE = y - M_OBJS += ne2k-pci.o - endif -endif - -ifeq ($(CONFIG_NE2000),y) -L_OBJS += ne.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_NE2000),m) - CONFIG_8390_MODULE = y - M_OBJS += ne.o - endif -endif - -ifeq ($(CONFIG_NE2_MCA),y) -L_OBJS += ne2.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_NE2_MCA),m) - CONFIG_8390_MODULE = y - M_OBJS += ne2.o - endif -endif - -ifeq ($(CONFIG_HPLAN),y) -L_OBJS += hp.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_HPLAN),m) - CONFIG_8390_MODULE = y - M_OBJS += hp.o - endif -endif - -ifeq ($(CONFIG_HPLAN_PLUS),y) -L_OBJS += hp-plus.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_HPLAN_PLUS),m) - CONFIG_8390_MODULE = y - M_OBJS += hp-plus.o - endif -endif - -ifeq ($(CONFIG_ULTRA),y) -L_OBJS += smc-ultra.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_ULTRA),m) - CONFIG_8390_MODULE = y - M_OBJS += smc-ultra.o - endif -endif - -ifeq ($(CONFIG_ULTRAMCA),y) -L_OBJS += smc-mca.o -CONFIG_8390_BUILTIN = y +ifeq ($(CONFIG_IRDA),y) +SUB_DIRS += irda +MOD_IN_SUB_DIRS += irda else - ifeq ($(CONFIG_ULTRAMCA),m) - CONFIG_8390_MODULE = y - M_OBJS += smc-mca.o + ifeq ($(CONFIG_IRDA),m) + MOD_IN_SUB_DIRS += irda endif endif -ifeq ($(CONFIG_ULTRA32),y) -L_OBJS += smc-ultra32.o -CONFIG_8390_BUILTIN = y +ifeq ($(CONFIG_TR),y) +SUB_DIRS += tokenring +MOD_IN_SUB_DIRS += tokenring else - ifeq ($(CONFIG_ULTRA32),m) - CONFIG_8390_MODULE = y - M_OBJS += smc-ultra32.o + ifeq ($(CONFIG_TR),m) + MOD_IN_SUB_DIRS += tokenring endif endif -ifeq ($(CONFIG_E2100),y) -L_OBJS += e2100.o -CONFIG_8390_BUILTIN = y +ifeq ($(CONFIG_WAN),y) +SUB_DIRS += wan +MOD_IN_SUB_DIRS += wan else - ifeq ($(CONFIG_E2100),m) - CONFIG_8390_MODULE = y - M_OBJS += e2100.o + ifeq ($(CONFIG_WAN),m) + MOD_IN_SUB_DIRS += wan endif endif -ifeq ($(CONFIG_ES3210),y) -L_OBJS += es3210.o -CONFIG_8390_BUILTIN = y +ifeq ($(CONFIG_NET_FC),y) +SUB_DIRS += fc +MOD_IN_SUB_DIRS += fc else - ifeq ($(CONFIG_ES3210),m) - CONFIG_8390_MODULE = y - M_OBJS += es3210.o + ifeq ($(CONFIG_NET_FC),m) + MOD_IN_SUB_DIRS += fc endif endif -ifeq ($(CONFIG_LNE390),y) -L_OBJS += lne390.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_LNE390),m) - CONFIG_8390_MODULE = y - M_OBJS += lne390.o +ifeq ($(CONFIG_ISDN),y) + ifeq ($(CONFIG_ISDN_PPP),y) + obj-y += slhc.o ppp_deflate.o endif -endif - -ifeq ($(CONFIG_NE3210),y) -L_OBJS += ne3210.o -CONFIG_8390_BUILTIN = y else - ifeq ($(CONFIG_NE3210),m) - CONFIG_8390_MODULE = y - M_OBJS += ne3210.o + ifeq ($(CONFIG_ISDN),m) + ifeq ($(CONFIG_ISDN_PPP),y) + obj-m += slhc.o ppp_deflate.o + endif endif endif -ifeq ($(CONFIG_PLIP),y) -L_OBJS += plip.o -else - ifeq ($(CONFIG_PLIP),m) - M_OBJS += plip.o - endif -endif +obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o +obj-$(CONFIG_SEEQ8005) += seeq8005.o +obj-$(CONFIG_ETHERTAP) += ethertap.o +obj-$(CONFIG_NET_SB1000) += sb1000.o +obj-$(CONFIG_DAYNAPORT) += daynaport.o 8390.o +obj-$(CONFIG_APNE) += apne.o 8390.o +obj-$(CONFIG_PCMCIA_PCNET) += 8390.o +obj-$(CONFIG_SHAPER) += shaper.o +obj-$(CONFIG_SK_G16) += sk_g16.o +obj-$(CONFIG_HP100) += hp100.o +obj-$(CONFIG_SMC9194) += smc9194.o +obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o +obj-$(CONFIG_ARM_ETHERH) += 8390.o +obj-$(CONFIG_WD80x3) += wd.o 8390.o +obj-$(CONFIG_EL2) += 3c503.o 8390.o +obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o +obj-$(CONFIG_NE2000) += ne.o 8390.o +obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o +obj-$(CONFIG_HPLAN) += hp.o 8390.o +obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o +obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o +obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o +obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o +obj-$(CONFIG_E2100) += e2100.o 8390.o +obj-$(CONFIG_ES3210) += es3210.o 8390.o +obj-$(CONFIG_LNE390) += lne390.o 8390.o +obj-$(CONFIG_NE3210) += ne3210.o 8390.o +obj-$(CONFIG_PLIP) += plip.o # bsd_comp.o is *always* a module, for some documented reason # (licensing). ifeq ($(CONFIG_PPP),y) -LX_OBJS += ppp_generic.o -CONFIG_SLHC_BUILTIN = y - ifeq ($(CONFIG_PPP_ASYNC),y) - LX_OBJS += ppp_async.o - else - ifeq ($(CONFIG_PPP_ASYNC),m) - 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 - ifeq ($(CONFIG_PPP_DEFLATE),m) - CONFIG_PPPDEF_MODULE = y - endif - endif + obj-y += ppp_generic.o slhc.o + obj-$(CONFIG_PPP_ASYNC) += ppp_async.o + obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o + obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o ifeq ($(CONFIG_PPP_BSDCOMP),m) - M_OBJS += bsd_comp.o + obj-m += bsd_comp.o endif else ifeq ($(CONFIG_PPP),m) - MX_OBJS += ppp_generic.o - CONFIG_SLHC_MODULE = y - 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 + obj-m += ppp_generic.o slhc.o + obj-$(CONFIG_PPP_ASYNC) += ppp_async.o + obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o + obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o ifeq ($(CONFIG_PPP_BSDCOMP),m) - M_OBJS += bsd_comp.o + obj-m += bsd_comp.o endif endif endif +obj-$(CONFIG_SLIP) += slip.o ifeq ($(CONFIG_SLIP),y) -L_OBJS += slip.o - ifeq ($(CONFIG_SLIP_COMPRESSED),y) - CONFIG_SLHC_BUILTIN = y - endif + obj-$(CONFIG_SLIP_COMPRESSED) += slhc.o else ifeq ($(CONFIG_SLIP),m) - ifeq ($(CONFIG_SLIP_COMPRESSED),y) - CONFIG_SLHC_MODULE = y - endif - M_OBJS += slip.o - endif -endif - -ifeq ($(CONFIG_STRIP),y) -L_OBJS += strip.o -else - ifeq ($(CONFIG_STRIP),m) - M_OBJS += strip.o - endif -endif - -ifeq ($(CONFIG_DE650),y) -ETDRV_OBJS := $(L_OBJS) de650.o -CONFIG_8390_BUILTIN = y -endif - -ifeq ($(CONFIG_3C589),y) -L_OBJS += 3c589.o -endif - -ifeq ($(CONFIG_DUMMY),y) -L_OBJS += dummy.o -else - ifeq ($(CONFIG_DUMMY),m) - M_OBJS += dummy.o - endif -endif - -ifeq ($(CONFIG_DE600),y) -L_OBJS += de600.o -else - ifeq ($(CONFIG_DE600),m) - M_OBJS += de600.o - endif -endif - -ifeq ($(CONFIG_DE620),y) -L_OBJS += de620.o -else - ifeq ($(CONFIG_DE620),m) - M_OBJS += de620.o - endif -endif - -ifeq ($(CONFIG_AT1500),y) -L_OBJS += lance.o -endif - -ifeq ($(CONFIG_LANCE),y) -L_OBJS += lance.o -else - ifeq ($(CONFIG_LANCE),m) - M_OBJS += lance.o - endif -endif - -ifeq ($(CONFIG_SUN3LANCE),y) -L_OBJS += sun3lance.o -endif - -ifeq ($(CONFIG_PCNET32),y) -L_OBJS += pcnet32.o -else - ifeq ($(CONFIG_PCNET32),m) - M_OBJS += pcnet32.o - endif -endif - -ifeq ($(CONFIG_DEFXX),y) -L_OBJS += defxx.o -endif - -ifeq ($(CONFIG_SUNLANCE),y) -L_OBJS += sunlance.o -else - ifeq ($(CONFIG_SUNLANCE),m) - M_OBJS += sunlance.o - endif -endif - -ifeq ($(CONFIG_SGISEEQ), y) -L_OBJS += sgiseeq.o -endif - -ifeq ($(CONFIG_HAPPYMEAL),y) -L_OBJS += sunhme.o -else - ifeq ($(CONFIG_HAPPYMEAL),m) - M_OBJS += sunhme.o - endif -endif - -ifeq ($(CONFIG_SUNQE),y) -L_OBJS += sunqe.o -else - ifeq ($(CONFIG_SUNQE),m) - M_OBJS += sunqe.o - endif -endif - -ifeq ($(CONFIG_SUNBMAC),y) -L_OBJS += sunbmac.o -else - ifeq ($(CONFIG_SUNBMAC),m) - M_OBJS += sunbmac.o - endif -endif - -ifeq ($(CONFIG_SUNBMAC),y) -L_OBJS += sunbmac.o -else - ifeq ($(CONFIG_SUNBMAC),m) - M_OBJS += sunbmac.o + obj-$(CONFIG_SLIP_COMPRESSED) += slhc.o endif endif -ifeq ($(CONFIG_MYRI_SBUS),y) -L_OBJS += myri_sbus.o -else - ifeq ($(CONFIG_MYRI_SBUS),m) - M_OBJS += myri_sbus.o - endif -endif +obj-$(CONFIG_STRIP) += strip.o +obj-$(CONFIG_DE650) += de650.o 8390.o +obj-$(CONFIG_3C589) += 3c589.o +obj-$(CONFIG_DUMMY) += dummy.o +obj-$(CONFIG_DE600) += de600.o +obj-$(CONFIG_DE620) += de620.o +obj-$(CONFIG_AT1500) += lance.o +obj-$(CONFIG_LANCE) += lance.o +obj-$(CONFIG_SUN3LANCE) += sun3lance.o +obj-$(CONFIG_PCNET32) += pcnet32.o +obj-$(CONFIG_DEFXX) += defxx.o +obj-$(CONFIG_SUNLANCE) += sunlance.o +obj-$(CONFIG_SGISEEQ) += sgiseeq.o +obj-$(CONFIG_HAPPYMEAL) += sunhme.o +obj-$(CONFIG_SUNQE) += sunqe.o +obj-$(CONFIG_SUNBMAC) += sunbmac.o +obj-$(CONFIG_SUNBMAC) += sunbmac.o +obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o +obj-$(CONFIG_AT1700) += at1700.o +obj-$(CONFIG_FMV18X) += fmv18x.o +obj-$(CONFIG_EL1) += 3c501.o +obj-$(CONFIG_EL16) += 3c507.o +obj-$(CONFIG_ELMC) += 3c523.o +obj-$(CONFIG_SKMC) += sk_mca.o +obj-$(CONFIG_ELMC_II) += 3c527.o +obj-$(CONFIG_EL3) += 3c509.o +obj-$(CONFIG_3C515) += 3c515.o +obj-$(CONFIG_VORTEX) += 3c59x.o +obj-$(CONFIG_EEXPRESS) += eexpress.o +obj-$(CONFIG_EEXPRESS_PRO) += eepro.o +obj-$(CONFIG_EEXPRESS_PRO100) += eepro100.o +obj-$(CONFIG_RTL8139) += rtl8139.o +obj-$(CONFIG_SIS900) += sis900.o +obj-$(CONFIG_DM9102) += dmfe.o +obj-$(CONFIG_YELLOWFIN) += yellowfin.o +obj-$(CONFIG_ACENIC) += acenic.o +obj-$(CONFIG_WAVELAN) += wavelan.o +obj-$(CONFIG_ARLAN) += arlan.o arlan-proc.o +obj-$(CONFIG_TLAN) += tlan.o +obj-$(CONFIG_VIA_RHINE) += via-rhine.o +obj-$(CONFIG_ZNET) += znet.o +obj-$(CONFIG_DEPCA) += depca.o +obj-$(CONFIG_EWRK3) += ewrk3.o +obj-$(CONFIG_ATP) += atp.o +obj-$(CONFIG_DE4X5) += de4x5.o +obj-$(CONFIG_NI5010) += ni5010.o +obj-$(CONFIG_NI52) += ni52.o +obj-$(CONFIG_NI65) += ni65.o +obj-$(CONFIG_ELPLUS) += 3c505.o +obj-$(CONFIG_AC3200) += ac3200.o 8390.o +obj-$(CONFIG_APRICOT) += 82596.o +obj-$(CONFIG_MVME16x_NET) += 82596.o +obj-$(CONFIG_BVME6000_NET) += 82596.o +obj-$(CONFIG_DEC_ELCP) += tulip.o +obj-$(CONFIG_ARCNET) += arcnet.o +obj-$(CONFIG_ARCNET_COM90xx) += com90xx.o +obj-$(CONFIG_ARCNET_COM90xxIO) += com90io.o +obj-$(CONFIG_ARCNET_RIM_I) += arc-rimi.o +obj-$(CONFIG_ARCNET_COM20020) += com20020.o +obj-$(CONFIG_ETH16I) += eth16i.o +obj-$(CONFIG_EPIC100) += epic100.o +obj-$(CONFIG_ARIADNE2) += ariadne2.o 8390.o +obj-$(CONFIG_HPLANCE) += hplance.o 7990.o +obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o +obj-$(CONFIG_EQUALIZER) += eql.o +obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o +obj-$(CONFIG_BAGETLANCE) += bagetlance.o +obj-$(CONFIG_DECLANCE) += declance.o +obj-$(CONFIG_ATARILANCE) += atarilance.o +obj-$(CONFIG_ATARI_BIONET) += atari_bionet.o +obj-$(CONFIG_ATARI_PAMSNET) += atari_pamsnet.o +obj-$(CONFIG_A2065) += a2065.o +obj-$(CONFIG_HYDRA) += hydra.o +obj-$(CONFIG_ARIADNE) += ariadne.o +obj-$(CONFIG_DGRS) += dgrs.o +obj-$(CONFIG_CS89x0) += cs89x0.o +obj-$(CONFIG_LTPC) += ltpc.o +obj-$(CONFIG_COPS) += cops.o +obj-$(CONFIG_IPDDP) += ipddp.o +obj-$(CONFIG_RCPCI) += rcpci.o +obj-$(CONFIG_MACE) += mace.o +obj-$(CONFIG_MACSONIC) += macsonic.o +obj-$(CONFIG_BMAC) += bmac.o +obj-$(CONFIG_NCR885E) += ncr885e.o +obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o -ifeq ($(CONFIG_AT1700),y) -L_OBJS += at1700.o -else - ifeq ($(CONFIG_AT1700),m) - M_OBJS += at1700.o - endif -endif - -ifeq ($(CONFIG_FMV18X),y) -L_OBJS += fmv18x.o -else - ifeq ($(CONFIG_FMV18X),m) - M_OBJS += fmv18x.o - endif -endif - -ifeq ($(CONFIG_EL1),y) -L_OBJS += 3c501.o -else - ifeq ($(CONFIG_EL1),m) - M_OBJS += 3c501.o - endif -endif - -ifeq ($(CONFIG_EL16),y) -L_OBJS += 3c507.o -else - ifeq ($(CONFIG_EL16),m) - M_OBJS += 3c507.o - endif -endif - -ifeq ($(CONFIG_ELMC),y) -L_OBJS += 3c523.o -else - ifeq ($(CONFIG_ELMC),m) - M_OBJS += 3c523.o - endif -endif - -ifeq ($(CONFIG_SKMC),y) -L_OBJS += sk_mca.o -else - ifeq ($(CONFIG_SKMC),m) - M_OBJS += sk_mca.o - endif -endif - -ifeq ($(CONFIG_ELMC_II),y) -L_OBJS += 3c527.o -else - ifeq ($(CONFIG_ELMC_II),m) - M_OBJS += 3c527.o - endif -endif - -ifeq ($(CONFIG_EL3),y) -L_OBJS += 3c509.o -else - ifeq ($(CONFIG_EL3),m) - M_OBJS += 3c509.o - endif -endif - -ifeq ($(CONFIG_3C515),y) -L_OBJS += 3c515.o -else - ifeq ($(CONFIG_3C515),m) - M_OBJS += 3c515.o - endif -endif - -ifeq ($(CONFIG_VORTEX),y) -L_OBJS += 3c59x.o -else - ifeq ($(CONFIG_VORTEX),m) - M_OBJS += 3c59x.o - endif -endif - -ifeq ($(CONFIG_EEXPRESS),y) -L_OBJS += eexpress.o -else - ifeq ($(CONFIG_EEXPRESS),m) - M_OBJS += eexpress.o - endif -endif - -ifeq ($(CONFIG_EEXPRESS_PRO),y) -L_OBJS += eepro.o -else - ifeq ($(CONFIG_EEXPRESS_PRO),m) - M_OBJS += eepro.o - endif -endif - -ifeq ($(CONFIG_EEXPRESS_PRO100),y) -L_OBJS += eepro100.o -else - ifeq ($(CONFIG_EEXPRESS_PRO100),m) - M_OBJS += eepro100.o - endif -endif - -ifeq ($(CONFIG_RTL8139),y) -L_OBJS += rtl8139.o -else - ifeq ($(CONFIG_RTL8139),m) - M_OBJS += rtl8139.o - endif -endif - -ifeq ($(CONFIG_SIS900),y) -L_OBJS += sis900.o -else - ifeq ($(CONFIG_SIS900),m) - M_OBJS += sis900.o - endif -endif - -ifeq ($(CONFIG_DM9102),y) -L_OBJS += dmfe.o -else - ifeq ($(CONFIG_DM9102),m) - M_OBJS += dmfe.o - endif -endif - - -ifeq ($(CONFIG_YELLOWFIN),y) -L_OBJS += yellowfin.o -else - ifeq ($(CONFIG_YELLOWFIN),m) - M_OBJS += yellowfin.o - endif -endif - -ifeq ($(CONFIG_ACENIC),y) -L_OBJS += acenic.o -else - ifeq ($(CONFIG_ACENIC),m) - M_OBJS += acenic.o - endif -endif - -ifeq ($(CONFIG_WAVELAN),y) -L_OBJS += wavelan.o -else - ifeq ($(CONFIG_WAVELAN),m) - M_OBJS += wavelan.o - endif -endif - -ifeq ($(CONFIG_ARLAN),y) -LX_OBJS += arlan.o arlan-proc.o -else - ifeq ($(CONFIG_ARLAN),m) - MX_OBJS += arlan.o arlan-proc.o - endif -endif - -ifeq ($(CONFIG_TLAN),y) -L_OBJS += tlan.o -else - ifeq ($(CONFIG_TLAN),m) - M_OBJS += tlan.o - endif -endif - -ifeq ($(CONFIG_VIA_RHINE),y) -L_OBJS += via-rhine.o -else - ifeq ($(CONFIG_VIA_RHINE),m) - M_OBJS += via-rhine.o - endif -endif - -ifeq ($(CONFIG_ZNET),y) -L_OBJS += znet.o -endif - -ifeq ($(CONFIG_DEPCA),y) -L_OBJS += depca.o -else - ifeq ($(CONFIG_DEPCA),m) - M_OBJS += depca.o - endif -endif - -ifeq ($(CONFIG_EWRK3),y) -L_OBJS += ewrk3.o -else - ifeq ($(CONFIG_EWRK3),m) - M_OBJS += ewrk3.o - endif -endif - -ifeq ($(CONFIG_ATP),y) -L_OBJS += atp.o -endif - -ifeq ($(CONFIG_DE4X5),y) -L_OBJS += de4x5.o -else - ifeq ($(CONFIG_DE4X5),m) - M_OBJS += de4x5.o - endif -endif - -ifeq ($(CONFIG_NI5010),y) -L_OBJS += ni5010.o -else - ifeq ($(CONFIG_NI5010),m) - M_OBJS += ni5010.o - endif -endif - -ifeq ($(CONFIG_NI52),y) -L_OBJS += ni52.o -else - ifeq ($(CONFIG_NI52),m) - M_OBJS += ni52.o - endif -endif - -ifeq ($(CONFIG_NI65),y) -L_OBJS += ni65.o -else - ifeq ($(CONFIG_NI65),m) - M_OBJS += ni65.o - endif -endif - -ifeq ($(CONFIG_ELPLUS),y) -L_OBJS += 3c505.o -else - ifeq ($(CONFIG_ELPLUS),m) - M_OBJS += 3c505.o - endif -endif - -ifeq ($(CONFIG_AC3200),y) -L_OBJS += ac3200.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_AC3200),m) - CONFIG_8390_MODULE = y - M_OBJS += ac3200.o - endif -endif - -ifeq ($(CONFIG_APRICOT),y) -CONFIG_82596_BUILTIN = y -else - ifeq ($(CONFIG_APRICOT),m) - CONFIG_82596_MODULE = y - endif -endif - -ifeq ($(CONFIG_MVME16x_NET),y) -CONFIG_82596_BUILTIN = y -else - ifeq ($(CONFIG_MVME16x_NET),m) - CONFIG_82596_MODULE = y - endif -endif - -ifeq ($(CONFIG_BVME6000_NET),y) -CONFIG_82596_BUILTIN = y -else - ifeq ($(CONFIG_BVME6000_NET),m) - CONFIG_82596_MODULE = y - endif -endif - -ifeq ($(CONFIG_DEC_ELCP),y) -L_OBJS += tulip.o -else - ifeq ($(CONFIG_DEC_ELCP),m) - M_OBJS += tulip.o - endif -endif - -ifeq ($(CONFIG_ARCNET),y) -LX_OBJS += arcnet.o -else - ifeq ($(CONFIG_ARCNET),m) - MX_OBJS += arcnet.o - endif -endif - -ifeq ($(CONFIG_ARCNET_COM90xx),y) -L_OBJS += com90xx.o -else - ifeq ($(CONFIG_ARCNET_COM90xx),m) - M_OBJS += com90xx.o - endif -endif - -ifeq ($(CONFIG_ARCNET_COM90xxIO),y) -L_OBJS += com90io.o -else - ifeq ($(CONFIG_ARCNET_COM90xxIO),m) - M_OBJS += com90io.o - endif -endif - -ifeq ($(CONFIG_ARCNET_RIM_I),y) -L_OBJS += arc-rimi.o -else - ifeq ($(CONFIG_ARCNET_RIM_I),m) - M_OBJS += arc-rimi.o - endif -endif - -ifeq ($(CONFIG_ARCNET_COM20020),y) -L_OBJS += com20020.o -else - ifeq ($(CONFIG_ARCNET_COM20020),m) - M_OBJS += com20020.o - endif -endif - -ifeq ($(CONFIG_ETH16I),y) -L_OBJS += eth16i.o -else - ifeq ($(CONFIG_ETH16I),m) - M_OBJS += eth16i.o - endif -endif - -ifeq ($(CONFIG_EPIC100),y) -L_OBJS += epic100.o -else - ifeq ($(CONFIG_EPIC100),m) - M_OBJS += epic100.o - endif -endif - -# If anything built-in uses slhc, then build it into the kernel also. -# If not, but a module uses it, build as a module. -ifdef CONFIG_SLHC_BUILTIN -LX_OBJS += slhc.o -else - ifdef CONFIG_SLHC_MODULE - MX_OBJS += slhc.o - endif -endif - -# if anything built-in uses ppp_deflate, then build it into the kernel also. -# If not, but a module uses it, build as a module. -ifdef CONFIG_PPPDEF_BUILTIN -L_OBJS += ppp_deflate.o -else - ifdef CONFIG_PPPDEF_MODULE - M_OBJS += ppp_deflate.o - endif -endif - -ifeq ($(CONFIG_ARIADNE2),y) -L_OBJS += ariadne2.o -CONFIG_8390_BUILTIN = y -else - ifeq ($(CONFIG_ARIADNE2),m) - M_OBJS += ariadne2.o - CONFIG_8390_MODULE = y - endif -endif - -# If anything built-in uses the 8390, then build it into the kernel also. -# If not, but a module uses it, build as a module. -ifdef CONFIG_8390_BUILTIN -L_OBJS += 8390.o -else - ifdef CONFIG_8390_MODULE - MX_OBJS += 8390.o - endif -endif - -ifeq ($(CONFIG_HPLANCE),y) -L_OBJS += hplance.o -CONFIG_7990_BUILTIN = y -else - ifeq ($(CONFIG_HPLANCE),m) - CONFIG_7990_MODULE = y - M_OBJS += hplance.o - endif -endif - -ifeq ($(CONFIG_MVME147_NET),y) -L_OBJS += mvme147.o -CONFIG_7990_BUILTIN = y -else - ifeq ($(CONFIG_MVME147_NET),m) - CONFIG_7990_MODULE = y - M_OBJS += mvme147.o - endif -endif - -# If we need generic LANCE support, either in the kernel or as a module, -# build it in the appropriate way. -ifdef CONFIG_7990_BUILTIN -L_OBJS += 7990.o -else - ifdef CONFIG_7990_MODULE - M_OBJS += 7990.o - endif -endif - -# If anything built-in uses the 82596, then build it into the kernel also. -# If not, but a module uses it, build as a module. -ifdef CONFIG_82596_BUILTIN -L_OBJS += 82596.o -else - ifdef CONFIG_82596_MODULE - M_OBJS += 82596.o - endif -endif - -ifeq ($(CONFIG_EQUALIZER),y) -L_OBJS += eql.o -else - ifeq ($(CONFIG_EQUALIZER),m) - M_OBJS += eql.o - endif -endif - -ifeq ($(CONFIG_MIPS_JAZZ_SONIC),y) -L_OBJS += jazzsonic.o -else - ifeq ($(CONFIG_MIPS_JAZZ_SONIC),m) - M_OBJS += jazzsonic.o - endif -endif - -ifeq ($(CONFIG_BAGETLANCE),y) -L_OBJS += bagetlance.o -else - ifeq ($(CONFIG_BAGETLANCE),m) - M_OBJS += bagetlance.o - endif -endif - -ifeq ($(CONFIG_DECLANCE),y) -L_OBJS += declance.o -else - ifeq ($(CONFIG_DECLANCE),m) - M_OBJS += declance.o - endif -endif - -ifeq ($(CONFIG_ATARILANCE),y) -L_OBJS += atarilance.o -else - ifeq ($(CONFIG_ATARILANCE),m) - M_OBJS += atarilance.o - endif -endif - -ifeq ($(CONFIG_ATARI_BIONET),y) -L_OBJS += atari_bionet.o -else - ifeq ($(CONFIG_ATARI_BIONET),m) - M_OBJS += atari_bionet.o - endif -endif - -ifeq ($(CONFIG_ATARI_PAMSNET),y) -L_OBJS += atari_pamsnet.o -else - ifeq ($(CONFIG_ATARI_PAMSNET),m) - M_OBJS += atari_pamsnet.o - endif -endif - -ifeq ($(CONFIG_A2065),y) -L_OBJS += a2065.o -else - ifeq ($(CONFIG_A2065),m) - M_OBJS += a2065.o - endif -endif - -ifeq ($(CONFIG_HYDRA),y) -L_OBJS += hydra.o -else - ifeq ($(CONFIG_HYDRA),m) - M_OBJS += hydra.o - endif -endif - -ifeq ($(CONFIG_ARIADNE),y) -L_OBJS += ariadne.o -else - ifeq ($(CONFIG_ARIADNE),m) - M_OBJS += ariadne.o - endif -endif - -ifeq ($(CONFIG_DGRS),y) -L_OBJS += dgrs.o -else - ifeq ($(CONFIG_DGRS),m) - M_OBJS += dgrs.o - endif -endif - -ifeq ($(CONFIG_CS89x0),y) -L_OBJS += cs89x0.o -else - ifeq ($(CONFIG_CS89x0),m) - M_OBJS += cs89x0.o - endif -endif - -ifeq ($(CONFIG_LTPC),y) -L_OBJS += ltpc.o -else - ifeq ($(CONFIG_LTPC),m) - M_OBJS += ltpc.o - endif -endif - -ifeq ($(CONFIG_COPS),y) -L_OBJS += cops.o -else - ifeq ($(CONFIG_COPS),m) - M_OBJS += cops.o - endif -endif - -ifeq ($(CONFIG_IPDDP),y) -L_OBJS += ipddp.o -else - ifeq ($(CONFIG_IPDDP),m) - M_OBJS += ipddp.o - endif -endif +# +# HIPPI adapters +# -ifeq ($(CONFIG_RCPCI),y) -L_OBJS += rcpci.o -else - ifeq ($(CONFIG_RCPCI),m) - M_OBJS += rcpci.o - endif -endif +obj-$(CONFIG_ROADRUNNER) += rrunner.o -ifeq ($(CONFIG_MACE),y) -L_OBJS += mace.o -else - ifeq ($(CONFIG_MACE),m) - M_OBJS += mace.o - endif -endif +# Extract lists of the multi-part drivers. +# The 'int-*' lists are the intermediate files used to build the multi's. -ifeq ($(CONFIG_MACSONIC),y) -L_OBJS += macsonic.o -endif +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) -ifeq ($(CONFIG_BMAC),y) -L_OBJS += bmac.o -else - ifeq ($(CONFIG_BMAC),m) - M_OBJS += bmac.o - endif -endif +# Files that are both resident and modular: remove from modular. -ifeq ($(CONFIG_NCR885E),y) -L_OBJS += ncr885e.o -else - ifeq ($(CONFIG_NCR885E),m) - M_OBJS += ncr885e.o - endif -endif +obj-m := $(filter-out $(obj-y), $(obj-m)) +int-m := $(filter-out $(int-y), $(int-m)) -ifeq ($(CONFIG_ADAPTEC_STARFIRE),y) -L_OBJS += starfire.o -else - ifeq ($(CONFIG_ADAPTEC_STARFIRE),m) - M_OBJS += starfire.o - endif -endif +# Take multi-part drivers out of obj-y and put components in. -# -# HIPPI adapters -# +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) -ifeq ($(CONFIG_ROADRUNNER),y) -L_OBJS += rrunner.o -else - ifeq ($(CONFIG_ROADRUNNER),m) - M_OBJS += rrunner.o - endif -endif +# Translate to Rules.make lists. -ifeq ($(CONFIG_IRDA),y) -SUB_DIRS += irda -MOD_IN_SUB_DIRS += irda -else - ifeq ($(CONFIG_IRDA),m) - MOD_IN_SUB_DIRS += irda - endif -endif +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) -ifeq ($(CONFIG_TR),y) -SUB_DIRS += tokenring -MOD_IN_SUB_DIRS += tokenring -else - ifeq ($(CONFIG_TR),m) - MOD_IN_SUB_DIRS += tokenring - endif -endif - -ifeq ($(CONFIG_WAN),y) -SUB_DIRS += wan -MOD_IN_SUB_DIRS += wan -else - ifeq ($(CONFIG_WAN),m) - MOD_IN_SUB_DIRS += wan - endif -endif - -ifeq ($(CONFIG_NET_FC),y) -SUB_DIRS += fc -MOD_IN_SUB_DIRS += fc -else - ifeq ($(CONFIG_NET_FC),m) - MOD_IN_SUB_DIRS += fc - endif -endif +L_OBJS += $(O_OBJS) +L_OBJS += $(OX_OBJS) include $(TOPDIR)/Rules.make @@ -1108,3 +273,4 @@ rcpci.o: rcpci45.o rclanmtl.o $(LD) -r -o rcpci.o rcpci45.o rclanmtl.o + diff -u --recursive --new-file v2.3.26/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.3.26/linux/drivers/net/Space.c Mon Oct 11 15:38:14 1999 +++ linux/drivers/net/Space.c Tue Nov 9 08:20:12 1999 @@ -42,24 +42,20 @@ */ extern int ne2_probe(struct net_device *dev); -extern int tulip_probe(struct net_device *dev); extern int hp100_probe(struct net_device *dev); extern int ultra_probe(struct net_device *dev); extern int ultra32_probe(struct net_device *dev); extern int ultramca_probe(struct net_device *dev); extern int wd_probe(struct net_device *dev); extern int el2_probe(struct net_device *dev); -extern int ne2k_pci_probe(struct net_device *dev); extern int ne_probe(struct net_device *dev); extern int hp_probe(struct net_device *dev); extern int hp_plus_probe(struct net_device *dev); extern int znet_probe(struct net_device *); extern int express_probe(struct net_device *); extern int eepro_probe(struct net_device *); -extern int eepro100_probe(struct net_device *); extern int el3_probe(struct net_device *); extern int at1500_probe(struct net_device *); -extern int pcnet32_probe(struct net_device *); extern int at1700_probe(struct net_device *); extern int fmv18x_probe(struct net_device *); extern int eth16i_probe(struct net_device *); @@ -85,14 +81,7 @@ extern int sonic_probe(struct net_device *); extern int SK_init(struct net_device *); extern int seeq8005_probe(struct net_device *); -extern int tc59x_probe(struct net_device *); -extern int dgrs_probe(struct net_device *); extern int smc_init( struct net_device * ); -extern int sparc_lance_probe(struct net_device *); -extern int happy_meal_probe(struct net_device *); -extern int qec_probe(struct net_device *); -extern int bigmac_probe(struct net_device *); -extern int myri_sbus_probe(struct net_device *); extern int sgiseeq_probe(struct net_device *); extern int atarilance_probe(struct net_device *); extern int sun3lance_probe(struct net_device *); @@ -104,33 +93,19 @@ extern int bionet_probe(struct net_device *); extern int pamsnet_probe(struct net_device *); extern int tlan_probe(struct net_device *); -extern int mace_probe(struct net_device *); -extern int bmac_probe(struct net_device *); -extern int ncr885e_probe(struct net_device *); extern int cs89x0_probe(struct net_device *dev); extern int ethertap_probe(struct net_device *dev); extern int ether1_probe (struct net_device *dev); extern int ether3_probe (struct net_device *dev); extern int etherh_probe (struct net_device *dev); extern int am79c961_probe(struct net_device *dev); -extern int epic100_probe(struct net_device *dev); -extern int rtl8139_probe(struct net_device *dev); -extern int sis900_probe(struct net_device *dev); extern int hplance_probe(struct net_device *dev); extern int bagetlance_probe(struct net_device *); extern int dec_lance_probe(struct net_device *); extern int mvme147lance_probe(struct net_device *dev); -extern int via_rhine_probe(struct net_device *dev); extern int tc515_probe(struct net_device *dev); extern int lance_probe(struct net_device *dev); -extern int starfire_probe(struct net_device *dev); -extern int rcpci_probe(struct net_device *); extern int mac_onboard_sonic_probe(struct net_device *dev); -extern int dmfe_reg_board(struct net_device *); - -/* Gigabit Ethernet adapters */ -extern int yellowfin_probe(struct net_device *dev); -extern int acenic_probe(struct net_device *dev); /* Detachable devices ("pocket adaptors") */ extern int atp_init(struct net_device *); @@ -141,9 +116,6 @@ extern int dfx_probe(struct net_device *dev); extern int apfddi_init(struct net_device *dev); -/* HIPPI boards */ -extern int rr_hippi_probe(struct net_device *); - /* Fibre Channel adapters */ extern int iph5526_probe(struct net_device *dev); @@ -182,74 +154,15 @@ } /* - * If your probe touches ISA ports (<0x400) in addition to - * looking for PCI cards, then put it in the isa_probes - * list instead. - */ -struct devprobe pci_probes[] __initdata = { -#ifdef CONFIG_DGRS - {dgrs_probe, 0}, -#endif -#ifdef CONFIG_RCPCI - {rcpci_probe, 0}, -#endif -#ifdef CONFIG_VORTEX - {tc59x_probe, 0}, -#endif -#ifdef CONFIG_NE2K_PCI - {ne2k_pci_probe, 0}, -#endif -#ifdef CONFIG_PCNET32 - {pcnet32_probe, 0}, -#endif -#ifdef CONFIG_EEXPRESS_PRO100 /* Intel EtherExpress Pro/100 */ - {eepro100_probe, 0}, -#endif -#ifdef CONFIG_DEC_ELCP - {tulip_probe, 0}, -#endif -#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */ - {de4x5_probe, 0}, -#endif -#ifdef CONFIG_TLAN - {tlan_probe, 0}, -#endif -#ifdef CONFIG_EPIC100 - {epic100_probe, 0}, -#endif -#ifdef CONFIG_RTL8139 - {rtl8139_probe, 0}, -#endif -#ifdef CONFIG_SIS900 - {sis900_probe, 0}, -#endif - -#ifdef CONFIG_DM9102 - {dmfe_reg_board, 0}, -#endif - -#ifdef CONFIG_YELLOWFIN - {yellowfin_probe, 0}, -#endif -#ifdef CONFIG_ACENIC - {acenic_probe, 0}, -#endif -#ifdef CONFIG_VIA_RHINE - {via_rhine_probe, 0}, -#endif -#ifdef CONFIG_ADAPTEC_STARFIRE - {starfire_probe, 0}, -#endif - {NULL, 0}, -}; - -/* * This is a bit of an artificial separation as there are PCI drivers * that also probe for EISA cards (in the PCI group) and there are ISA * drivers that probe for EISA cards (in the ISA group). These are the - * EISA only driver probes. + * EISA only driver probes, and also the legacy PCI probes */ struct devprobe eisa_probes[] __initdata = { +#ifdef CONFIG_TLAN + {tlan_probe, 0}, +#endif #ifdef CONFIG_ULTRA32 {ultra32_probe, 0}, #endif @@ -268,24 +181,6 @@ {NULL, 0}, }; -struct devprobe sparc_probes[] __initdata = { -#ifdef CONFIG_HAPPYMEAL - {happy_meal_probe, 0}, -#endif -#ifdef CONFIG_SUNLANCE - {sparc_lance_probe, 0}, -#endif -#ifdef CONFIG_SUNQE - {qec_probe, 0}, -#endif -#ifdef CONFIG_SUNBMAC - {bigmac_probe, 0}, -#endif -#ifdef CONFIG_MYRI_SBUS - {myri_sbus_probe, 0}, -#endif - {NULL, 0}, -}; struct devprobe mca_probes[] __initdata = { #ifdef CONFIG_ULTRAMCA @@ -463,18 +358,6 @@ {NULL, 0}, }; -struct devprobe ppc_probes[] __initdata = { -#ifdef CONFIG_MACE - {mace_probe, 0}, -#endif -#ifdef CONFIG_BMAC - {bmac_probe, 0}, -#endif -#ifdef CONFIG_NCR885E - {ncr885e_probe, 0}, -#endif - {NULL, 0}, -}; struct devprobe sgi_probes[] __initdata = { #ifdef CONFIG_SGISEEQ @@ -514,8 +397,9 @@ /* * Unified ethernet device probe, segmented per architecture and - * per bus interface. + * per bus interface. This drives the legacy devices only for now. */ + static int __init ethif_probe(struct net_device *dev) { unsigned long base_addr = dev->base_addr; @@ -537,14 +421,8 @@ return 0; if (probe_list(dev, mips_probes) == 0) return 0; - if (probe_list(dev, ppc_probes) == 0) - return 0; if (probe_list(dev, sgi_probes) == 0) return 0; - if (probe_list(dev, sparc_probes) == 0) - return 0; - if (probe_list(dev, pci_probes) == 0) - return 0; if (probe_list(dev, eisa_probes) == 0) return 0; if (probe_list(dev, mca_probes) == 0) @@ -585,28 +463,6 @@ } #endif -#ifdef CONFIG_HIPPI -static int hippi_probe(struct net_device *dev) -{ - /* - * Damn this is ugly. - * - * Why the heck would we want to determine this from the base - * address? Stupid PC'ism .... grrrrr. - */ - if (dev->base_addr == -1) - return 1; - - if (1 -#ifdef CONFIG_ROADRUNNER - && rr_hippi_probe(dev) -#endif - && 1 ) { - return 1; /* -ENODEV or -EAGAIN would be more accurate. */ - } - return 0; -} -#endif /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is tring of 9 zeros. */ #define __PAD6 "\0\0\0\0\0\0\0\0\0" @@ -668,16 +524,6 @@ # define NEXT_DEV (&cops0_dev) #endif /* COPS */ -#if defined(CONFIG_IPDDP) - extern int ipddp_init(struct net_device *dev); - static struct net_device dev_ipddp = { - "ipddp0" __PAD6, - 0, 0, 0, 0, - 0x0, 0, - 0, 0, 0, NEXT_DEV, ipddp_init }; -# undef NEXT_DEV -# define NEXT_DEV (&dev_ipddp) -#endif /* CONFIG_IPDDP */ /* The first device defaults to I/O base '0', which means autoprobe. */ #ifndef ETH0_ADDR @@ -694,109 +540,33 @@ #define ETH_NOPROBE_ADDR 0xffe0 static struct net_device eth7_dev = { - "eth7" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe }; + "eth%d" __PAD5, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe }; static struct net_device eth6_dev = { - "eth6" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð7_dev, ethif_probe }; + "eth%d" __PAD5, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð7_dev, ethif_probe }; static struct net_device eth5_dev = { - "eth5" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð6_dev, ethif_probe }; + "eth%d" __PAD5, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð6_dev, ethif_probe }; static struct net_device eth4_dev = { - "eth4" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð5_dev, ethif_probe }; + "eth%d" __PAD5, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð5_dev, ethif_probe }; static struct net_device eth3_dev = { - "eth3" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð4_dev, ethif_probe }; + "eth%d" __PAD5, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð4_dev, ethif_probe }; static struct net_device eth2_dev = { - "eth2" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð3_dev, ethif_probe }; + "eth%d" __PAD5, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð3_dev, ethif_probe }; static struct net_device eth1_dev = { - "eth1" __PAD4, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð2_dev, ethif_probe }; + "eth%d" __PAD5, 0,0,0,0,ETH_NOPROBE_ADDR /* I/O base*/, 0,0,0,0, ð2_dev, ethif_probe }; static struct net_device eth0_dev = { - "eth0" __PAD4, 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, ð1_dev, ethif_probe }; + "eth%d" __PAD5, 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, ð1_dev, ethif_probe }; # undef NEXT_DEV # define NEXT_DEV (ð0_dev) -#if defined(SLIP) || defined(CONFIG_SLIP) - /* To be exact, this node just hooks the initialization - routines to the device structures. */ -extern int slip_init_ctrl_dev(struct net_device *); -static struct net_device slip_bootstrap = { - "slip_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, slip_init_ctrl_dev, }; -#undef NEXT_DEV -#define NEXT_DEV (&slip_bootstrap) -#endif /* SLIP */ - -#if defined(X25_ASY) || defined(CONFIG_X25_ASY) - /* To be exact, this node just hooks the initialization - routines to the device structures. */ -extern int x25_asy_init_ctrl_dev(struct net_device *); -static struct net_device x25_asy_bootstrap = { - "x25_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, x25_asy_init_ctrl_dev, }; -#undef NEXT_DEV -#define NEXT_DEV (&x25_asy_bootstrap) -#endif /* X25_ASY */ - -#if defined(CONFIG_MKISS) - /* To be exact, this node just hooks the initialization - routines to the device structures. */ -extern int mkiss_init_ctrl_dev(struct net_device *); -static struct net_device mkiss_bootstrap = { - "mkiss_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, mkiss_init_ctrl_dev, }; -#undef NEXT_DEV -#define NEXT_DEV (&mkiss_bootstrap) -#endif /* MKISS */ - -#if defined(CONFIG_YAM) -extern int yam_init(struct net_device *); -static struct net_device yam_bootstrap = { - "yam", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, yam_init, }; -#undef NEXT_DEV -#define NEXT_DEV (&yam_bootstrap) -#endif /* CONFIG_YAM */ - -#if defined(CONFIG_STRIP) -extern int strip_init_ctrl_dev(struct net_device *); -static struct net_device strip_bootstrap = { - "strip_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, strip_init_ctrl_dev, }; -#undef NEXT_DEV -#define NEXT_DEV (&strip_bootstrap) -#endif /* STRIP */ - -#if defined(CONFIG_PPP) -extern int ppp_init(struct net_device *); -static struct net_device ppp_bootstrap = { - "ppp_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, ppp_init, }; -#undef NEXT_DEV -#define NEXT_DEV (&ppp_bootstrap) -#endif /* PPP */ - -#ifdef CONFIG_DUMMY - extern int dummy_init(struct net_device *dev); - static struct net_device dummy_dev = { - "dummy" __PAD5, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, dummy_init, }; -# undef NEXT_DEV -# define NEXT_DEV (&dummy_dev) -#endif - -#ifdef CONFIG_EQUALIZER -extern int eql_init(struct net_device *dev); -struct net_device eql_dev = { - "eql" __PAD3, /* Master device for IP traffic load - balancing */ - 0x0, 0x0, 0x0, 0x0, /* recv end/start; mem end/start */ - 0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NEXT_DEV, /* next device */ - eql_init /* set up the rest */ -}; -# undef NEXT_DEV -# define NEXT_DEV (&eql_dev) -#endif + #ifdef CONFIG_TR /* Token-ring device probe */ extern int ibmtr_probe(struct net_device *); extern int olympic_probe(struct net_device *); -extern int sktr_probe(struct net_device *); +extern int tms380tr_probe(struct net_device *); static int trif_probe(struct net_device *dev) @@ -809,7 +579,7 @@ && olympic_probe(dev) #endif #ifdef CONFIG_SKTR - && sktr_probe(dev) + && tms380tr_probe(dev) #endif #ifdef CONFIG_SMCTR && smctr_probe(dev) @@ -820,21 +590,21 @@ return 0; } static struct net_device tr7_dev = { - "tr7" __PAD3,0,0,0,0,0,0,0,0,0, NEXT_DEV, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, NEXT_DEV, trif_probe }; static struct net_device tr6_dev = { - "tr6" __PAD3,0,0,0,0,0,0,0,0,0, &tr7_dev, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, &tr7_dev, trif_probe }; static struct net_device tr5_dev = { - "tr5" __PAD3,0,0,0,0,0,0,0,0,0, &tr6_dev, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, &tr6_dev, trif_probe }; static struct net_device tr4_dev = { - "tr4" __PAD3,0,0,0,0,0,0,0,0,0, &tr5_dev, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, &tr5_dev, trif_probe }; static struct net_device tr3_dev = { - "tr3" __PAD3,0,0,0,0,0,0,0,0,0, &tr4_dev, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, &tr4_dev, trif_probe }; static struct net_device tr2_dev = { - "tr2" __PAD3,0,0,0,0,0,0,0,0,0, &tr3_dev, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, &tr3_dev, trif_probe }; static struct net_device tr1_dev = { - "tr1" __PAD3,0,0,0,0,0,0,0,0,0, &tr2_dev, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, &tr2_dev, trif_probe }; static struct net_device tr0_dev = { - "tr0" __PAD3,0,0,0,0,0,0,0,0,0, &tr1_dev, trif_probe }; + "tr%d" __PAD3,0,0,0,0,0,0,0,0,0, &tr1_dev, trif_probe }; # undef NEXT_DEV # define NEXT_DEV (&tr0_dev) @@ -861,28 +631,6 @@ #define NEXT_DEV (&fddi0_dev) #endif -#ifdef CONFIG_HIPPI - static struct net_device hip3_dev = - {"hip3" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, hippi_probe}; - static struct net_device hip2_dev = - {"hip2" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip3_dev, hippi_probe}; - static struct net_device hip1_dev = - {"hip1" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip2_dev, hippi_probe}; - static struct net_device hip0_dev = - {"hip0" __PAD4, 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip1_dev, hippi_probe}; - -#undef NEXT_DEV -#define NEXT_DEV (&hip0_dev) -#endif - -#ifdef CONFIG_APBIF - extern int bif_init(struct net_device *dev); - static struct net_device bif_dev = { - "bif" __PAD3, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, bif_init }; -# undef NEXT_DEV -# define NEXT_DEV (&bif_dev) -#endif - #ifdef CONFIG_NET_FC static struct net_device fc1_dev = { @@ -917,27 +665,7 @@ #endif -#ifdef CONFIG_NET_SB1000 - extern int sb1000_probe(struct net_device *dev); - static struct net_device sb1000_dev = { - "cm0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, sb1000_probe }; -# undef NEXT_DEV -# define NEXT_DEV (&sb1000_dev) -#endif -extern int loopback_init(struct net_device *dev); -struct net_device loopback_dev = { - "lo" __PAD2, /* Software Loopback interface */ - 0x0, /* recv memory end */ - 0x0, /* recv memory start */ - 0x0, /* memory end */ - 0x0, /* memory start */ - 0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NEXT_DEV, /* next device */ - loopback_init /* loopback_init should set up the rest */ -}; - -struct net_device *dev_base = &loopback_dev; +struct net_device *dev_base = NEXT_DEV; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; + diff -u --recursive --new-file v2.3.26/linux/drivers/net/acenic.c linux/drivers/net/acenic.c --- v2.3.26/linux/drivers/net/acenic.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/net/acenic.c Tue Nov 9 08:20:12 1999 @@ -295,12 +295,13 @@ static int probed __initdata = 0; -int __init acenic_probe (struct net_device *dev) +int __init acenic_probe(void) { int boards_found = 0; int version_disp; struct ace_private *ap; struct pci_dev *pdev = NULL; + struct net_device *dev; if (probed) return -ENODEV; @@ -312,7 +313,6 @@ version_disp = 0; while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET<<8, pdev))){ - dev = NULL; if (!((pdev->vendor == PCI_VENDOR_ID_ALTEON) && (pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC)) && @@ -330,10 +330,10 @@ (pdev->device == PCI_DEVICE_ID_SGI_ACENIC))) continue; - dev = init_etherdev(dev, sizeof(struct ace_private)); + dev = init_etherdev(NULL, sizeof(struct ace_private)); if (dev == NULL){ - printk(KERN_ERR "Unable to allocate etherdev " + printk(KERN_ERR "acenic: Unable to allocate net_device " "structure!\n"); break; } @@ -341,8 +341,10 @@ if (!dev->priv) dev->priv = kmalloc(sizeof(*ap), GFP_KERNEL); if (!dev->priv) + { + printk(KERN_ERR "acenic: Unable to allocate memory.\n"); return -ENOMEM; - + } ap = dev->priv; ap->pdev = pdev; @@ -487,7 +489,7 @@ root_dev = NULL; - cards = acenic_probe(NULL); + cards = acenic_probe(); return cards ? 0 : -ENODEV; } diff -u --recursive --new-file v2.3.26/linux/drivers/net/bmac.c linux/drivers/net/bmac.c --- v2.3.26/linux/drivers/net/bmac.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/net/bmac.c Tue Nov 9 08:20:12 1999 @@ -1256,14 +1256,14 @@ return 1; } -int -bmac_probe(struct net_device *dev) +int bmac_probe(void) { int j, rev; struct bmac_data *bp; struct device_node *bmacs; unsigned char *addr; static struct device_node *all_bmacs = NULL, *next_bmac; + struct net_device *dev = NULL; if (all_bmacs == NULL) { all_bmacs = find_devices("bmac"); @@ -1292,14 +1292,8 @@ return -EINVAL; } - if (dev == NULL) { - dev = init_etherdev(NULL, PRIV_BYTES); - bmac_devs = dev; /*KLUDGE!!*/ - } else { - /* XXX this doesn't look right (but it's never used :-) */ - dev->priv = kmalloc(PRIV_BYTES, GFP_KERNEL); - if (dev->priv == 0) return -ENOMEM; - } + dev = init_etherdev(NULL, PRIV_BYTES); + bmac_devs = dev; /*KLUDGE!!*/ #ifdef MODULE bmac_devs = dev; @@ -1610,7 +1604,7 @@ if(bmac_devs != NULL) return -EBUSY; - res = bmac_probe(NULL); + res = bmac_probe(); return res; } diff -u --recursive --new-file v2.3.26/linux/drivers/net/dgrs.c linux/drivers/net/dgrs.c --- v2.3.26/linux/drivers/net/dgrs.c Wed Aug 18 11:36:41 1999 +++ linux/drivers/net/dgrs.c Tue Nov 9 08:20:12 1999 @@ -1241,7 +1241,6 @@ static int __init dgrs_found_device( - struct net_device *dev, int io, ulong mem, int irq, @@ -1250,108 +1249,74 @@ ) { DGRS_PRIV *priv; + struct net_device *dev; - #ifdef MODULE - { - /* Allocate and fill new device structure. */ - int dev_size = sizeof(struct net_device) + sizeof(DGRS_PRIV); - int i; - - dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); - memset(dev, 0, dev_size); - dev->priv = ((void *)dev) + sizeof(struct net_device); - priv = (DGRS_PRIV *)dev->priv; - - dev->name = priv->devname; /* An empty string. */ - dev->base_addr = io; - dev->mem_start = mem; - dev->mem_end = mem + 2048 * 1024 - 1; - dev->irq = irq; - priv->plxreg = plxreg; - priv->plxdma = plxdma; - priv->vplxdma = NULL; - - priv->chan = 1; - priv->devtbl[0] = dev; - - dev->init = dgrs_probe1; - - ether_setup(dev); - priv->next_dev = dgrs_root_dev; - dgrs_root_dev = dev; - if (register_netdev(dev) != 0) - return -EIO; + /* Allocate and fill new device structure. */ + int dev_size = sizeof(struct net_device) + sizeof(DGRS_PRIV); + int i; + + dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); + memset(dev, 0, dev_size); + dev->priv = ((void *)dev) + sizeof(struct net_device); + priv = (DGRS_PRIV *)dev->priv; + + dev->name = priv->devname; /* An empty string. */ + dev->base_addr = io; + dev->mem_start = mem; + dev->mem_end = mem + 2048 * 1024 - 1; + dev->irq = irq; + priv->plxreg = plxreg; + priv->plxdma = plxdma; + priv->vplxdma = NULL; + + priv->chan = 1; + priv->devtbl[0] = dev; + + dev->init = dgrs_probe1; + ether_setup(dev); + priv->next_dev = dgrs_root_dev; + dgrs_root_dev = dev; + if (register_netdev(dev) != 0) + return -EIO; - if ( !dgrs_nicmode ) - return (0); /* Switch mode, we are done */ + if ( !dgrs_nicmode ) + return (0); /* Switch mode, we are done */ - /* - * Operating card as N separate NICs - */ - priv->nports = priv->bcomm->bc_nports; - for (i = 1; i < priv->nports; ++i) - { - struct net_device *devN; - DGRS_PRIV *privN; + /* + * Operating card as N separate NICs + */ - /* Allocate new dev and priv structures */ - devN = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); + priv->nports = priv->bcomm->bc_nports; + for (i = 1; i < priv->nports; ++i) + { + struct net_device *devN; + DGRS_PRIV *privN; + /* Allocate new dev and priv structures */ + devN = (struct net_device *) kmalloc(dev_size, GFP_KERNEL); /* Make it an exact copy of dev[0]... */ - memcpy(devN, dev, dev_size); - devN->priv = ((void *)devN) + sizeof(struct net_device); - privN = (DGRS_PRIV *)devN->priv; - + memcpy(devN, dev, dev_size); + devN->priv = ((void *)devN) + sizeof(struct net_device); + privN = (DGRS_PRIV *)devN->priv; /* ... but seset devname to a NULL string */ - privN->devname[0] = 0; - devN->name = privN->devname; - + privN->devname[0] = 0; + devN->name = privN->devname; /* ... and zero out VM areas */ - privN->vmem = 0; - privN->vplxdma = 0; - + privN->vmem = 0; + privN->vplxdma = 0; /* ... and zero out IRQ */ - devN->irq = 0; - + devN->irq = 0; /* ... and base MAC address off address of 1st port */ - devN->dev_addr[5] += i; - privN->chan = i+1; - - priv->devtbl[i] = devN; - - devN->init = dgrs_initclone; - ether_setup(devN); - privN->next_dev = dgrs_root_dev; - dgrs_root_dev = devN; - if (register_netdev(devN) != 0) - return -EIO; - } - } - #else - { - if (dev) - { - dev->priv = kmalloc(sizeof (DGRS_PRIV), GFP_KERNEL); - memset(dev->priv, 0, sizeof (DGRS_PRIV)); - } - dev = init_etherdev(dev, sizeof(DGRS_PRIV)); - priv = (DGRS_PRIV *)dev->priv; - - dev->base_addr = io; - dev->mem_start = mem; - dev->mem_end = mem + 2048 * 1024; - dev->irq = irq; - priv->plxreg = plxreg; - priv->plxdma = plxdma; - priv->vplxdma = NULL; - - priv->chan = 1; - priv->devtbl[0] = dev; - - dgrs_probe1(dev); + devN->dev_addr[5] += i; + privN->chan = i+1; + priv->devtbl[i] = devN; + devN->init = dgrs_initclone; + ether_setup(devN); + privN->next_dev = dgrs_root_dev; + dgrs_root_dev = devN; + if (register_netdev(devN) != 0) + return -EIO; } - #endif - return (0); } @@ -1360,8 +1325,7 @@ */ static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 }; -static int __init -dgrs_scan(struct net_device *dev) +static int __init dgrs_scan(void) { int cards_found = 0; uint io; @@ -1452,9 +1416,8 @@ PCI_LATENCY_TIMER, 255); } - dgrs_found_device(dev, io, mem, irq, plxreg, plxdma); + dgrs_found_device(io, mem, irq, plxreg, plxdma); - dev = 0; cards_found++; } } @@ -1479,9 +1442,8 @@ irq = is2iv[ inb(io+ES4H_IS) & ES4H_IS_INTMASK ]; - dgrs_found_device(dev, io, mem, irq, 0L, 0L); + dgrs_found_device(io, mem, irq, 0L, 0L); - dev = 0; ++cards_found; } } @@ -1564,7 +1526,7 @@ * Find and configure all the cards */ dgrs_root_dev = NULL; - cards_found = dgrs_scan(0); + cards_found = dgrs_scan(); return cards_found ? 0 : -ENODEV; } @@ -1605,7 +1567,7 @@ { int cards_found; - cards_found = dgrs_scan(dev); + cards_found = dgrs_scan(); if (dgrs_debug && cards_found) printk("dgrs: SW=%s FW=Build %d %s\n", version, dgrs_firmnum, dgrs_firmdate); diff -u --recursive --new-file v2.3.26/linux/drivers/net/dmfe.c linux/drivers/net/dmfe.c --- v2.3.26/linux/drivers/net/dmfe.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/net/dmfe.c Wed Nov 10 09:52:30 1999 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -275,7 +276,7 @@ }; /* function declaration ------------------------------------- */ -int dmfe_reg_board(struct net_device *); +int dmfe_reg_board(void); static int dmfe_open(struct net_device *); static int dmfe_start_xmit(struct sk_buff *, struct net_device *); static int dmfe_stop(struct net_device *); @@ -309,7 +310,7 @@ * Search DM910X board, allocate space and register it */ -int dmfe_reg_board(struct net_device *dev) +int __init dmfe_reg_board(void) { u32 pci_iobase; u16 dm9102_count = 0; @@ -318,6 +319,7 @@ struct dmfe_board_info *db; /* Point a board information structure */ int i; struct pci_dev *net_dev = NULL; + struct net_device *dev; DMFE_DBUG(0, "dmfe_reg_board()", 0); @@ -365,7 +367,7 @@ dm9102_count++; /* Found a DM9102 card */ /* Init network device */ - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); /* Allocated board information structure */ db = (void *) (kmalloc(sizeof(*db), GFP_KERNEL | GFP_DMA)); @@ -402,7 +404,6 @@ for (i = 0; i < 6; i++) dev->dev_addr[i] = db->srom[20 + i]; - dev = 0; /* NULL device */ } #ifdef MODULE @@ -1488,7 +1489,7 @@ break; } - return dmfe_reg_board(0); /* search board and register */ + return dmfe_reg_board(); /* search board and register */ } /* diff -u --recursive --new-file v2.3.26/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c --- v2.3.26/linux/drivers/net/eepro100.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/eepro100.c Tue Nov 9 08:20:12 1999 @@ -284,9 +284,7 @@ */ /* This table drives the PCI probe routines. */ -static struct net_device * -speedo_found1(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_idx, int fnd_cnt); +static struct net_device *speedo_found1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); #ifdef USE_IO #define SPEEDO_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR1 @@ -312,8 +310,7 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_idx, int fnd_cnt); + struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); } static pci_tbl[] = { { "Intel PCI EtherExpress Pro100", 0x8086, 0x1229, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 32, speedo_found1 }, @@ -534,7 +531,7 @@ static struct net_device *root_speedo_dev = NULL; #if ! defined(HAS_PCI_NETIF) -int eepro100_init(struct net_device *dev) +int eepro100_init(void) { int cards_found = 0; static int pci_index = 0; @@ -616,19 +613,18 @@ } else if (speedo_debug > 1) printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency); - speedo_found1(pci_bus, pci_device_fn, dev, ioaddr, irq, 0,cards_found); - dev = NULL; - cards_found++; + if(speedo_found1(pci_bus, pci_device_fn, ioaddr, irq, 0,cards_found)) + cards_found++; } return cards_found; } #endif -static struct net_device * -speedo_found1(int pci_bus, int pci_devfn, struct net_device *dev, +static struct net_device *speedo_found1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int card_idx) { + struct net_device *dev; struct speedo_private *sp; const char *product; int i, option; @@ -640,7 +636,7 @@ printk(version); #endif - dev = init_etherdev(dev, sizeof(struct speedo_private)); + dev = init_etherdev(NULL, sizeof(struct speedo_private)); if (dev->mem_start > 0) option = dev->mem_start; @@ -1837,12 +1833,12 @@ printk(KERN_INFO "%s", version); #if defined(HAS_PCI_NETIF) - cards_found = netif_pci_probe(pci_tbl, NULL); + cards_found = netif_pci_probe(pci_tbl); if (cards_found < 0) printk(KERN_INFO "eepro100: No cards found, driver not installed.\n"); return cards_found; #else - cards_found = eepro100_init(NULL); + cards_found = eepro100_init(); if (cards_found <= 0) { printk(KERN_INFO "eepro100: No cards found, driver not installed.\n"); return -ENODEV; @@ -1877,11 +1873,11 @@ #else /* not MODULE */ -int eepro100_probe(struct net_device *dev) +int eepro100_probe(void) { int cards_found = 0; - cards_found = eepro100_init(dev); + cards_found = eepro100_init(); /* Only emit the version if the driver is being used. */ if (speedo_debug > 0 && cards_found) diff -u --recursive --new-file v2.3.26/linux/drivers/net/epic100.c linux/drivers/net/epic100.c --- v2.3.26/linux/drivers/net/epic100.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/epic100.c Tue Nov 9 08:20:12 1999 @@ -151,9 +151,8 @@ /* The rest of these values should never change. */ -static struct net_device *epic_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, int irq, - int chip_id, int card_idx); +static struct net_device *epic_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, + int chip_id, int card_idx); enum pci_flags_bit { PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, @@ -164,7 +163,7 @@ const char *name; u16 vendor_id, device_id, device_id_mask, pci_flags; int io_size, min_latency; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, + struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); } chip_tbl[] = { {"SMSC EPIC/100 83c170", 0x10B8, 0x0005, 0x7fff, @@ -274,12 +273,13 @@ static struct net_device *root_epic_dev = NULL; #ifndef CARDBUS -int epic100_probe(struct net_device *dev) +int epic100_probe(void) { int cards_found = 0; int chip_idx, irq; u16 pci_command, new_command; unsigned char pci_bus, pci_device_fn; + struct net_device *dev; #ifdef PCI_SUPPORT_VER2 struct pci_dev *pcidev = NULL; @@ -356,7 +356,7 @@ PCI_COMMAND, new_command); } - dev = chip_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, pci_ioaddr, + dev = chip_tbl[chip_idx].probe1(pci_bus, pci_device_fn, pci_ioaddr, irq, chip_idx, cards_found); /* Check the latency timer. */ @@ -381,24 +381,26 @@ } #endif /* not CARDBUS */ -static struct net_device *epic_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, int irq, +static struct net_device *epic_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int card_idx) { struct epic_private *ep; int i, option = 0, duplex = 0; + struct net_device *dev; - if (dev && dev->mem_start) { - option = dev->mem_start; - duplex = (dev->mem_start & 16) ? 1 : 0; - } else if (card_idx >= 0 && card_idx < MAX_UNITS) { +// FIXME if (dev && dev->mem_start) { +// option = dev->mem_start; +// duplex = (dev->mem_start & 16) ? 1 : 0; +// } +// else + if (card_idx >= 0 && card_idx < MAX_UNITS) { if (options[card_idx] >= 0) option = options[card_idx]; if (full_duplex[card_idx] >= 0) duplex = full_duplex[card_idx]; } - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); dev->base_addr = ioaddr; dev->irq = irq; @@ -1343,7 +1345,7 @@ io == 0 ? "I/O address" : "IRQ"); return NULL; } - dev = epic_probe1(bus, devfn, NULL, io, irq, 2, -1); + dev = epic_probe1(bus, devfn, io, irq, 2, -1); if (dev) { dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL); strcpy(node->dev_name, dev->name); @@ -1417,7 +1419,7 @@ register_driver(&epic_ops); return 0; #else - return epic100_probe(0); + return epic100_probe(); #endif } diff -u --recursive --new-file v2.3.26/linux/drivers/net/es3210.c linux/drivers/net/es3210.c --- v2.3.26/linux/drivers/net/es3210.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/net/es3210.c Wed Nov 10 09:53:37 1999 @@ -344,7 +344,7 @@ isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count); } else { /* Packet is in one chunk. */ - isa_eth_io_copy_and_csum(skb, xfer_start, count, 0); + isa_eth_io_copy_and_sum(skb, xfer_start, count, 0); } } diff -u --recursive --new-file v2.3.26/linux/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c --- v2.3.26/linux/drivers/net/fc/iph5526.c Fri Sep 10 23:57:30 1999 +++ linux/drivers/net/fc/iph5526.c Thu Nov 11 16:57:30 1999 @@ -3752,11 +3752,6 @@ /* SCSI stuff starts here */ -static struct proc_dir_entry proc_scsi_iph5526 = { - PROC_SCSI_IPH5526_FC, 7, "iph5526", S_IFDIR, S_IRUGO | S_IXUGO, 2 -}; - - int iph5526_detect(Scsi_Host_Template *tmpt) { struct Scsi_Host *host = NULL; @@ -3766,7 +3761,7 @@ u_int pci_maddr = 0; struct pci_dev *pdev = NULL; - tmpt->proc_dir = &proc_scsi_iph5526; + tmpt->proc_name = "iph5526"; if (pci_present() == 0) { printk("iph5526: PCI not present\n"); return 0; diff -u --recursive --new-file v2.3.26/linux/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c --- v2.3.26/linux/drivers/net/hamradio/mkiss.c Wed Aug 18 11:38:50 1999 +++ linux/drivers/net/hamradio/mkiss.c Tue Nov 9 08:20:12 1999 @@ -972,15 +972,7 @@ mkiss_init(); -#ifdef MODULE return status; -#else - /* - * Return "not found", so that dev_init() will unlink - * the placeholder device entry for us. - */ - return ENODEV; -#endif } diff -u --recursive --new-file v2.3.26/linux/drivers/net/hamradio/yam.c linux/drivers/net/hamradio/yam.c --- v2.3.26/linux/drivers/net/hamradio/yam.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/net/hamradio/yam.c Tue Nov 9 08:20:12 1999 @@ -70,68 +70,13 @@ #include #include -#include -#include "yam9600.h" -#include "yam1200.h" - -/* --------------------------------------------------------------------- */ - -/* - * currently this module is supposed to support both module styles, i.e. - * the old one present up to about 2.1.9, and the new one functioning - * starting with 2.1.21. The reason is I have a kit allowing to compile - * this module also under 2.0.x which was requested by several people. - * This will go in 2.2 - */ #include - -#if LINUX_VERSION_CODE >= 0x20100 #include -#else -#include -#include - -#undef put_user -#undef get_user - -#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; }) -#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; }) - -extern inline int copy_from_user(void *to, const void *from, unsigned long n) -{ - int i = verify_area(VERIFY_READ, from, n); - if (i) - return i; - memcpy_fromfs(to, from, n); - return 0; -} - -extern inline int copy_to_user(void *to, const void *from, unsigned long n) -{ - int i = verify_area(VERIFY_WRITE, to, n); - if (i) - return i; - memcpy_tofs(to, from, n); - return 0; -} -#endif - -#if LINUX_VERSION_CODE < 0x20115 -extern __inline__ void dev_init_buffers(struct net_device *dev) -{ - int i; - for (i = 0; i < DEV_NUMBUFFS; i++) { - skb_queue_head_init(&dev->buffs[i]); - } -} -#endif - -#if LINUX_VERSION_CODE >= 0x20123 #include -#else -#define __init -#define __initdata -#endif + +#include +#include "yam9600.h" +#include "yam1200.h" /* --------------------------------------------------------------------- */ @@ -177,11 +122,8 @@ /* Stats section */ -#if LINUX_VERSION_CODE < 0x20119 - struct enet_statistics stats; -#else struct net_device_stats stats; -#endif + int nb_rxint; int nb_mdint; @@ -907,13 +849,7 @@ /* --------------------------------------------------------------------- */ -#if LINUX_VERSION_CODE >= 0x20119 -static struct net_device_stats * - yam_get_stats(struct net_device *dev) -#else -static struct enet_statistics * - yam_get_stats(struct net_device *dev) -#endif +static struct net_device_stats *yam_get_stats(struct net_device *dev) { struct yam_port *yp; @@ -1195,8 +1131,9 @@ /* --------------------------------------------------------------------- */ -int __init yam_init(struct net_device *dev) +int __init yam_init(void) { + struct net_device *dev; int i; printk(yam_drvinfo); @@ -1241,8 +1178,6 @@ add_timer(&yam_timer); yam_net_procfs_init(); - - /* do not keep this device */ return 1; } @@ -1254,16 +1189,13 @@ * command line settable parameters */ -#if LINUX_VERSION_CODE >= 0x20115 MODULE_AUTHOR("Frederic Rible F1OAT frible@teaser.fr"); MODULE_DESCRIPTION("Yam amateur radio modem driver"); -#endif - int init_module(void) { - int ret = yam_init(NULL); + int ret = yam_init(); return (ret == 1) ? 0 : ret; } diff -u --recursive --new-file v2.3.26/linux/drivers/net/mace.c linux/drivers/net/mace.c --- v2.3.26/linux/drivers/net/mace.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/mace.c Wed Nov 10 19:55:03 1999 @@ -101,10 +101,10 @@ return d; } -int -mace_probe(struct net_device *dev) +int mace_probe(void) { int j, rev; + struct net_device *dev; struct mace_data *mp; struct device_node *mace; unsigned char *addr; @@ -126,13 +126,7 @@ return -ENODEV; } - if (dev == NULL) - dev = init_etherdev(0, PRIV_BYTES); - else { - dev->priv = kmalloc(PRIV_BYTES, GFP_KERNEL); - if (dev->priv == 0) - return -ENOMEM; - } + dev = init_etherdev(0, PRIV_BYTES); memset(dev->priv, 0, PRIV_BYTES); mp = (struct mace_data *) dev->priv; @@ -913,7 +907,7 @@ if(mace_devs != NULL) return -EBUSY; - res = mace_probe(NULL); + res = mace_probe(); return res; } diff -u --recursive --new-file v2.3.26/linux/drivers/net/myri_sbus.c linux/drivers/net/myri_sbus.c --- v2.3.26/linux/drivers/net/myri_sbus.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/myri_sbus.c Tue Nov 9 08:20:12 1999 @@ -1074,8 +1074,9 @@ return 0; } -int __init myri_sbus_probe(struct net_device *dev) +int __init myri_sbus_probe(void) { + struct net_device *dev = NULL; struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; static int called = 0; @@ -1108,7 +1109,7 @@ init_module(void) { root_myri_dev = NULL; - return myri_sbus_probe(NULL); + return myri_sbus_probe(); } void diff -u --recursive --new-file v2.3.26/linux/drivers/net/ncr885e.c linux/drivers/net/ncr885e.c --- v2.3.26/linux/drivers/net/ncr885e.c Mon Oct 11 15:38:14 1999 +++ linux/drivers/net/ncr885e.c Wed Nov 10 10:00:48 1999 @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -134,8 +133,7 @@ static int ncr885e_close( struct net_device *dev ); static void ncr885e_rx( struct net_device *dev ); static void ncr885e_tx( struct net_device *dev ); -static int ncr885e_probe1( struct net_device *dev, unsigned long ioaddr, - unsigned char irq ); +static int ncr885e_probe1( unsigned long ioaddr, unsigned char irq ); static int ncr885e_xmit_start( struct sk_buff *skb, struct net_device *dev ); static struct net_device_stats *ncr885e_stats( struct net_device *dev ); static void ncr885e_set_multicast( struct net_device *dev ); @@ -1162,15 +1160,16 @@ */ static int -ncr885e_probe1( struct net_device *dev, unsigned long ioaddr, unsigned char irq ) +ncr885e_probe1(unsigned long ioaddr, unsigned char irq ) { + struct net_device *dev; struct ncr885e_private *sp; unsigned short station_addr[3], val; unsigned char *p; int i; - dev = init_etherdev( dev, 0 ); + dev = init_etherdev(NULL, 0 ); /* construct private data for the 885 ethernet */ dev->priv = kmalloc( sizeof( struct ncr885e_private ), GFP_KERNEL ); @@ -1227,7 +1226,7 @@ * worry about the rest. */ -int __init ncr885e_probe( struct net_device *dev ) +int __init ncr885e_probe(void) { struct pci_dev *pdev = NULL; unsigned int ioaddr, chips = 0; @@ -1257,7 +1256,7 @@ continue; /* finish off the probe */ - if ( !(ncr885e_probe1( dev, ioaddr, irq ))) { + if ( !(ncr885e_probe1(ioaddr, irq ))) { chips++; @@ -1432,7 +1431,7 @@ if ( debug >= 0) ncr885e_debug = debug; - return ncr885e_probe( NULL ); + return ncr885e_probe(); } void diff -u --recursive --new-file v2.3.26/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c --- v2.3.26/linux/drivers/net/ne2k-pci.c Fri Sep 10 23:57:30 1999 +++ linux/drivers/net/ne2k-pci.c Tue Nov 9 08:20:12 1999 @@ -104,9 +104,8 @@ #define NESM_START_PG 0x40 /* First page of TX buffer */ #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ -int ne2k_pci_probe(struct net_device *dev); -static struct net_device *ne2k_pci_probe1(struct net_device *dev, long ioaddr, int irq, - int chip_idx); +int ne2k_pci_probe(void); +static struct net_device *ne2k_pci_probe1(long ioaddr, int irq, int chip_idx); static int ne2k_pci_open(struct net_device *dev); static int ne2k_pci_close(struct net_device *dev); @@ -139,7 +138,7 @@ if (debug) printk(KERN_INFO "%s", version); - if (ne2k_pci_probe(0)) { + if (ne2k_pci_probe()) { printk(KERN_NOTICE "ne2k-pci.c: No useable cards found, driver NOT installed.\n"); return -ENODEV; } @@ -186,11 +185,12 @@ {"ne2k_pci", ne2k_pci_probe1, NE_IO_EXTENT, 0}; #endif -int __init ne2k_pci_probe(struct net_device *dev) +int __init ne2k_pci_probe(void) { struct pci_dev *pdev = NULL; int cards_found = 0; int i; + struct net_device *dev; if ( ! pci_present()) return -ENODEV; @@ -241,7 +241,7 @@ #endif printk("ne2k-pci.c: PCI NE2000 clone '%s' at I/O %#lx, IRQ %d.\n", pci_clone_list[i].name, pci_ioaddr, pci_irq_line); - dev = ne2k_pci_probe1(dev, pci_ioaddr, pci_irq_line, i); + dev = ne2k_pci_probe1(pci_ioaddr, pci_irq_line, i); if (dev == 0) { /* Should not happen. */ printk(KERN_ERR "ne2k-pci: Probe of PCI card at %#lx failed.\n", @@ -255,7 +255,6 @@ ne2k_card->dev = dev; ne2k_card->pci_dev = pdev; } - dev = 0; cards_found++; } @@ -263,8 +262,9 @@ return cards_found ? 0 : -ENODEV; } -static struct net_device __init *ne2k_pci_probe1(struct net_device *dev, long ioaddr, int irq, int chip_idx) +static struct net_device __init *ne2k_pci_probe1(long ioaddr, int irq, int chip_idx) { + struct net_device *dev; int i; unsigned char SA_prom[32]; int start_page, stop_page; @@ -288,7 +288,7 @@ } } - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); /* Reset card. Who knows what dain-bramaged state it was left in. */ { diff -u --recursive --new-file v2.3.26/linux/drivers/net/net_init.c linux/drivers/net/net_init.c --- v2.3.26/linux/drivers/net/net_init.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/net/net_init.c Tue Nov 9 08:23:04 1999 @@ -23,6 +23,10 @@ 14/06/96 - Paul Gortmaker: Add generic eth_change_mtu() function. 24/09/96 - Paul Norton: Add token-ring variants of the netdev functions. + + 08/11/99 - Alan Cox: Got fed up of the mess in this file and cleaned it + up. We now share common code and have regularised name + allocation setups. Abolished the 16 card limits. */ #include @@ -61,79 +65,66 @@ and a space waste] */ -/* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */ -#define MAX_ETH_CARDS 16 -static struct net_device *ethdev_index[MAX_ETH_CARDS]; - -/* Fill in the fields of the device structure with ethernet-generic values. - - If no device structure is passed, a new one is constructed, complete with - a SIZEOF_PRIVATE private data area. +static struct net_device *init_alloc_dev(int sizeof_priv) +{ + struct net_device *dev; + int alloc_size = sizeof(struct net_device) + IFNAMSIZ + + sizeof_priv + 3; + alloc_size &= ~3; /* Round to dword boundary. */ + dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + if(dev==NULL) + { + printk(KERN_ERR "alloc_dev: Unable to allocate device memory.\n"); + return NULL; + } + memset(dev, 0, alloc_size); + if (sizeof_priv) + dev->priv = (void *) (dev + 1); + dev->name = sizeof_priv + (char *)(dev + 1); + return dev; +} - If an empty string area is passed as dev->name, or a new structure is made, - a new name string is constructed. The passed string area should be 8 bytes - long. +/* + * Create and name a device from a prototype, then perform any needed + * setup. */ -struct net_device * -init_etherdev(struct net_device *dev, int sizeof_priv) +static struct net_device *init_netdev(struct net_device *dev, int sizeof_priv, char *mask, void (*setup)(struct net_device *)) { int new_device = 0; - int i; - /* Use an existing correctly named device in Space.c:dev_base. */ + /* + * Allocate a device if one is not provided. + */ + if (dev == NULL) { - int alloc_size = sizeof(struct net_device) + IFNAMSIZ - + sizeof_priv + 3; - struct net_device *cur_dev; - char pname[8]; /* Putative name for the device. */ - - for (i = 0; i < MAX_ETH_CARDS; ++i) - if (ethdev_index[i] == NULL) { - sprintf(pname, "eth%d", i); - read_lock_bh(&dev_base_lock); - for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next) { - if (strcmp(pname, cur_dev->name) == 0) { - dev = cur_dev; - read_unlock_bh(&dev_base_lock); - dev->init = NULL; - sizeof_priv = (sizeof_priv + 3) & ~3; - dev->priv = sizeof_priv - ? kmalloc(sizeof_priv, GFP_KERNEL) - : NULL; - if (dev->priv) memset(dev->priv, 0, sizeof_priv); - goto found; - } - } - read_unlock_bh(&dev_base_lock); - } - - alloc_size &= ~3; /* Round to dword boundary. */ - - dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); + dev=init_alloc_dev(sizeof_priv); if(dev==NULL) return NULL; - memset(dev, 0, alloc_size); - if (sizeof_priv) - dev->priv = (void *) (dev + 1); - dev->name = sizeof_priv + (char *)(dev + 1); new_device = 1; } -found: /* From the double loop above. */ - - if (dev->name && - ((dev->name[0] == '\0') || (dev->name[0] == ' '))) { - for (i = 0; i < MAX_ETH_CARDS; ++i) - if (ethdev_index[i] == NULL) { - sprintf(dev->name, "eth%d", i); - ethdev_index[i] = dev; - break; - } + /* + * Allocate a name + */ + + if (dev->name && (dev->name[0] == '\0' || dev->name[0] == ' ')) + { + if(dev_alloc_name(dev, mask)<0) + { + if(new_device) + kfree(dev); + return NULL; + } } - - ether_setup(dev); /* Hmmm, should this be called here? */ + + /* + * Configure via the caller provided setup function then + * register if needed. + */ + + setup(dev); if (new_device) { rtnl_lock(); @@ -143,6 +134,21 @@ return dev; } +/* Fill in the fields of the device structure with ethernet-generic values. + + If no device structure is passed, a new one is constructed, complete with + a SIZEOF_PRIVATE private data area. + + If an empty string area is passed as dev->name, or a new structure is made, + a new name string is constructed. The passed string area should be 8 bytes + long. + */ + +struct net_device *init_etherdev(struct net_device *dev, int sizeof_priv) +{ + return init_netdev(dev, sizeof_priv, "eth%d", ether_setup); +} + static int eth_mac_addr(struct net_device *dev, void *p) { @@ -174,8 +180,6 @@ #endif #ifdef CONFIG_HIPPI -#define MAX_HIP_CARDS 4 -static struct net_device *hipdev_index[MAX_HIP_CARDS]; static int hippi_change_mtu(struct net_device *dev, int new_mtu) { @@ -205,82 +209,14 @@ struct net_device *init_hippi_dev(struct net_device *dev, int sizeof_priv) { - int new_device = 0; - int i; - - /* Use an existing correctly named device in Space.c:dev_base. */ - if (dev == NULL) { - int alloc_size = sizeof(struct net_device) + IFNAMSIZ - + sizeof_priv + 3; - struct net_device *cur_dev; - char pname[8]; - - for (i = 0; i < MAX_HIP_CARDS; ++i) - if (hipdev_index[i] == NULL) { - sprintf(pname, "hip%d", i); - read_lock_bh(&dev_base_lock); - for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next) { - if (strcmp(pname, cur_dev->name) == 0) { - dev = cur_dev; - read_unlock_bh(&dev_base_lock); - dev->init = NULL; - sizeof_priv = (sizeof_priv + 3) & ~3; - dev->priv = sizeof_priv - ? kmalloc(sizeof_priv, GFP_KERNEL) - : NULL; - if (dev->priv) memset(dev->priv, 0, sizeof_priv); - goto hipfound; - } - } - read_unlock_bh(&dev_base_lock); - } - - alloc_size &= ~3; /* Round to dword boundary. */ - - dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); - if(dev==NULL) - return NULL; - memset(dev, 0, alloc_size); - if (sizeof_priv) - dev->priv = (void *) (dev + 1); - dev->name = sizeof_priv + (char *)(dev + 1); - new_device = 1; - } - -hipfound: /* From the double loop above. */ - - if (dev->name && - ((dev->name[0] == '\0') || (dev->name[0] == ' '))) { - for (i = 0; i < MAX_HIP_CARDS; ++i) - if (hipdev_index[i] == NULL) { - sprintf(dev->name, "hip%d", i); - hipdev_index[i] = dev; - break; - } - } - - hippi_setup(dev); - - if (new_device) { - rtnl_lock(); - register_netdevice(dev); - rtnl_unlock(); - } - return dev; + return init_netdev(dev, sizeof_priv, "hip%d", hippi_setup); } void unregister_hipdev(struct net_device *dev) { - int i; rtnl_lock(); unregister_netdevice(dev); - for (i = 0; i < MAX_HIP_CARDS; ++i) { - if (hipdev_index[i] == dev) { - hipdev_index[i] = NULL; - break; - } - } rtnl_unlock(); } @@ -303,23 +239,9 @@ void ether_setup(struct net_device *dev) { - int i; /* Fill in the fields of the device structure with ethernet-generic values. This should be in a common file instead of per-driver. */ - /* register boot-defined "eth" devices */ - if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) { - i = simple_strtoul(dev->name + 3, NULL, 0); - if (ethdev_index[i] == NULL) { - ethdev_index[i] = dev; - } - else if (dev != ethdev_index[i]) { - /* Really shouldn't happen! */ - printk("ether_setup: Ouch! Someone else took %s\n", - dev->name); - } - } - dev->change_mtu = eth_change_mtu; dev->hard_header = eth_header; dev->rebuild_header = eth_rebuild_header; @@ -376,19 +298,6 @@ #ifdef CONFIG_HIPPI void hippi_setup(struct net_device *dev) { - int i; - - if (dev->name && (strncmp(dev->name, "hip", 3) == 0)) { - i = simple_strtoul(dev->name + 3, NULL, 0); - if (hipdev_index[i] == NULL) { - hipdev_index[i] = dev; - } - else if (dev != hipdev_index[i]) { - printk("hippi_setup: Ouch! Someone else took %s\n", - dev->name); - } - } - dev->set_multicast_list = NULL; dev->change_mtu = hippi_change_mtu; dev->hard_header = hippi_header; @@ -478,45 +387,33 @@ return 0; } -static int etherdev_get_index(struct net_device *dev) -{ - int i=MAX_ETH_CARDS; - - for (i = 0; i < MAX_ETH_CARDS; ++i) { - if (ethdev_index[i] == NULL) { - sprintf(dev->name, "eth%d", i); -/* printk("loading device '%s'...\n", dev->name);*/ - ethdev_index[i] = dev; - return i; - } - } - return -1; -} - -static void etherdev_put_index(struct net_device *dev) -{ - int i; - for (i = 0; i < MAX_ETH_CARDS; ++i) { - if (ethdev_index[i] == dev) { - ethdev_index[i] = NULL; - break; - } - } -} - int register_netdev(struct net_device *dev) { - int i=-1; - rtnl_lock(); - if (dev->name && - (dev->name[0] == '\0' || dev->name[0] == ' ')) - i = etherdev_get_index(dev); - + /* + * If the name is a format string the caller wants us to + * do a name allocation + */ + + if (dev->name && strchr(dev->name, '%')) + { + if(dev_alloc_name(dev, dev->name)<0) + return -EBUSY; + } + + /* + * Back compatibility hook. Kill this one in 2.5 + */ + + if (dev->name && (dev->name[0]==0 || dev->name[0]==' ')) + { + if(dev_alloc_name(dev, "eth%d")<0) + return -EBUSY; + } + + if (register_netdevice(dev)) { - if (i >= 0) - etherdev_put_index(dev); rtnl_unlock(); return -EIO; } @@ -528,120 +425,40 @@ { rtnl_lock(); unregister_netdevice(dev); - etherdev_put_index(dev); rtnl_unlock(); } #ifdef CONFIG_TR -/* The list of used and available "tr" slots */ -#define MAX_TR_CARDS 16 -static struct net_device *trdev_index[MAX_TR_CARDS]; -struct net_device *init_trdev(struct net_device *dev, int sizeof_priv) +static void tr_configure(struct net_device *dev) { - int new_device = 0; - int i; - - /* Use an existing correctly named device in Space.c:dev_base. */ - if (dev == NULL) { - int alloc_size = sizeof(struct net_device) + IFNAMSIZ - + sizeof_priv + 3; - struct net_device *cur_dev; - char pname[8]; /* Putative name for the device. */ - - for (i = 0; i < MAX_TR_CARDS; ++i) - if (trdev_index[i] == NULL) { - sprintf(pname, "tr%d", i); - read_lock_bh(&dev_base_lock); - for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next) { - if (strcmp(pname, cur_dev->name) == 0) { - dev = cur_dev; - read_unlock_bh(&dev_base_lock); - dev->init = NULL; - sizeof_priv = (sizeof_priv + 3) & ~3; - dev->priv = sizeof_priv - ? kmalloc(sizeof_priv, GFP_KERNEL) - : NULL; - if (dev->priv) memset(dev->priv, 0, sizeof_priv); - goto trfound; - } - } - read_unlock_bh(&dev_base_lock); - } - - alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); - if(dev==NULL) - return NULL; - memset(dev, 0, alloc_size); - if (sizeof_priv) - dev->priv = (void *) (dev + 1); - dev->name = sizeof_priv + (char *)(dev + 1); - new_device = 1; - } - -trfound: /* From the double loop above. */ - - for (i = 0; i < MAX_TR_CARDS; ++i) - if (trdev_index[i] == NULL) { - sprintf(dev->name, "tr%d", i); - trdev_index[i] = dev; - break; - } - - - dev->hard_header = tr_header; - dev->rebuild_header = tr_rebuild_header; + /* + * Configure and register + */ + + dev->hard_header = tr_header; + dev->rebuild_header = tr_rebuild_header; - dev->type = ARPHRD_IEEE802; - dev->hard_header_len = TR_HLEN; - dev->mtu = 2000; /* bug in fragmenter...*/ - dev->addr_len = TR_ALEN; - dev->tx_queue_len = 100; /* Long queues on tr */ + dev->type = ARPHRD_IEEE802_TR; + dev->hard_header_len = TR_HLEN; + dev->mtu = 2000; + dev->addr_len = TR_ALEN; + dev->tx_queue_len = 100; /* Long queues on tr */ memset(dev->broadcast,0xFF, TR_ALEN); /* New-style flags. */ - dev->flags = IFF_BROADCAST; - - if (new_device) { - rtnl_lock(); - register_netdevice(dev); - rtnl_unlock(); - } - return dev; + dev->flags = IFF_BROADCAST | IFF_MULTICAST ; } -void tr_setup(struct net_device *dev) +struct net_device *init_trdev(struct net_device *dev, int sizeof_priv) { - int i; - - /* register boot-defined "tr" devices */ - if (dev->name && (strncmp(dev->name, "tr", 2) == 0)) { - i = simple_strtoul(dev->name + 2, NULL, 0); - if (trdev_index[i] == NULL) { - trdev_index[i] = dev; - } - else if (dev != trdev_index[i]) { - /* Really shouldn't happen! */ - printk("tr_setup: Ouch! Someone else took %s\n", - dev->name); - } - } + return init_netdev(dev, sizeof_priv, "tr%d", tr_configure); } -void tr_freedev(struct net_device *dev) +void tr_setup(struct net_device *dev) { - int i; - for (i = 0; i < MAX_TR_CARDS; ++i) - { - if (trdev_index[i] == dev) - { - trdev_index[i] = NULL; - break; - } - } } int register_trdev(struct net_device *dev) @@ -660,33 +477,14 @@ rtnl_lock(); unregister_netdevice(dev); rtnl_unlock(); - tr_freedev(dev); } #endif #ifdef CONFIG_NET_FC -#define MAX_FC_CARDS 2 -static struct net_device *fcdev_index[MAX_FC_CARDS]; - void fc_setup(struct net_device *dev) { -int i; - - /* register boot-defined "fc" devices */ - if (dev->name && (strncmp(dev->name, "fc", 2) == 0)) { - i = simple_strtoul(dev->name + 2, NULL, 0); - if (fcdev_index[i] == NULL) { - fcdev_index[i] = dev; - } - else if (dev != fcdev_index[i]) { - /* Really shouldn't happen! */ - printk("fc_setup: Ouch! Someone else took %s\n", - dev->name); - } - } - dev->hard_header = fc_header; dev->rebuild_header = fc_rebuild_header; @@ -700,76 +498,16 @@ /* New-style flags. */ dev->flags = IFF_BROADCAST; - dev_init_buffers(dev); + dev_init_buffers(dev); return; } struct net_device *init_fcdev(struct net_device *dev, int sizeof_priv) { -int new_device = 0; -int i; - /* Use an existing correctly named device in Space.c:dev_base. */ - if (dev == NULL) { - int alloc_size = sizeof(struct net_device) + sizeof("fc%d ") + sizeof_priv + 3; - struct net_device *cur_dev; - char pname[8]; /* Putative name for the device. */ - - for (i = 0; i < MAX_FC_CARDS; ++i) - if (fcdev_index[i] == NULL) { - sprintf(pname, "fc%d", i); - for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next) - if (strcmp(pname, cur_dev->name) == 0) { - dev = cur_dev; - dev->init = NULL; - sizeof_priv = (sizeof_priv + 3) &~3; - dev->priv = sizeof_priv - ? kmalloc(sizeof_priv, GFP_KERNEL) - : NULL; - if (dev->priv) memset(dev->priv, 0, sizeof_priv); - goto fcfound; - } - } - - alloc_size &= ~3; /* Round to dword boundary. */ - dev = (struct net_device *)kmalloc(alloc_size, GFP_KERNEL); - memset(dev, 0, alloc_size); - if (sizeof_priv) - dev->priv = (void *) (dev + 1); - dev->name = sizeof_priv + (char *)(dev + 1); - new_device = 1; - } - -fcfound: /* From the double loop */ - - for (i = 0; i < MAX_FC_CARDS; ++i) - if (fcdev_index[i] == NULL) { - sprintf(dev->name, "fc%d", i); - fcdev_index[i] = dev; - break; - } - - fc_setup(dev); - if (new_device) { - rtnl_lock(); - register_netdevice(dev); - rtnl_unlock(); - } - return dev; + return init_netdev(dev, sizeof_priv, "fc%d", fc_setup); } -void fc_freedev(struct net_device *dev) -{ -int i; - for (i = 0; i < MAX_FC_CARDS; ++i) { - if (fcdev_index[i] == dev) { - fcdev_index[i] = NULL; - break; - } - } -} - - int register_fcdev(struct net_device *dev) { dev_init_buffers(dev); @@ -785,7 +523,6 @@ rtnl_lock(); unregister_netdevice(dev); rtnl_unlock(); - fc_freedev(dev); } #endif /* CONFIG_NET_FC */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/3c574_cs.c linux/drivers/net/pcmcia/3c574_cs.c --- v2.3.26/linux/drivers/net/pcmcia/3c574_cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/3c574_cs.c Thu Nov 11 16:03:36 1999 @@ -2,7 +2,7 @@ Written 1993-1998 by Donald Becker, becker@cesdis.gsfc.nasa.gov, (driver core) and - David Hinds, dhinds@allegro.stanford.edu (derived from his PC card code). + David Hinds, dhinds@pcmcia.sourceforge.org (from his PC card code). This software may be used and distributed according to the terms of the GNU Public License, incorporated herein by reference. @@ -322,7 +322,6 @@ link->release.data = (u_long)link; link->io.NumPorts1 = 32; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - link->io.IOAddrLines = 5; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; if (irq_list[0] == -1) @@ -483,6 +482,7 @@ /* Configure card */ link->state |= DEV_CONFIG; + link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; i = CardServices(RequestIO, link->handle, &link->io); diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/3c575_cb.c linux/drivers/net/pcmcia/3c575_cb.c --- v2.3.26/linux/drivers/net/pcmcia/3c575_cb.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/pcmcia/3c575_cb.c Thu Nov 11 16:03:36 1999 @@ -0,0 +1,2215 @@ +/* EtherLinkXL.c: A 3Com EtherLink PCI III/XL ethernet driver for linux. */ +/* + Written 1996-1999 by Donald Becker. + + This software may be used and distributed according to the terms + of the GNU Public License, incorporated herein by reference. + + This driver is for the 3Com "Vortex" and "Boomerang" series ethercards. + Members of the series include Fast EtherLink 3c590/3c592/3c595/3c597 + and the EtherLink XL 3c900 and 3c905 cards. + + The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O + Center of Excellence in Space Data and Information Sciences + Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 +*/ + +static char *version = +"3c59x.c:v0.99L 5/28/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n"; + +/* "Knobs" that adjust features and parameters. */ +/* Set the copy breakpoint for the copy-only-tiny-frames scheme. + Setting to > 1512 effectively disables this feature. */ +static const int rx_copybreak = 200; +/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */ +static const int mtu = 1500; +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static int max_interrupt_work = 20; + +/* Put out somewhat more debugging messages. (0: no msg, 1 minimal .. 6). */ +#define vortex_debug debug +#ifdef VORTEX_DEBUG +static int vortex_debug = VORTEX_DEBUG; +#else +static int vortex_debug = 1; +#endif + +/* Some values here only for performance evaluation and path-coverage + debugging. */ +static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits; + +/* A few values that may be tweaked. */ +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (2*HZ) + +/* Keep the ring sizes a power of two for efficiency. */ +#define TX_RING_SIZE 16 +#define RX_RING_SIZE 32 +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ + +#ifndef __OPTIMIZE__ +#warning You must compile this file with the correct options! +#warning See the last lines of the source file. +#error You must compile this driver with "-O". +#endif + +#include +#include +#ifdef MODULE +#ifdef MODVERSIONS +#include +#endif +#include +#else +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* For NR_IRQS only. */ +#include +#include + +/* Kernel compatibility defines, some common to David Hinds' PCMCIA package. + This is only in the support-all-kernels source code. */ + +#define RUN_AT(x) (jiffies + (x)) + +#include + +#define PCI_SUPPORT_VER2 +#define DEV_FREE_SKB(skb) dev_kfree_skb(skb); +#if ! defined(CAP_NET_ADMIN) +#define capable(CAP_XXX) (suser()) +#endif + +#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115 +MODULE_AUTHOR("Donald Becker "); +MODULE_DESCRIPTION("3Com 3c590/3c900 series Vortex/Boomerang driver"); +MODULE_PARM(debug, "i"); +MODULE_PARM(options, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i"); +MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(max_interrupt_work, "i"); +MODULE_PARM(compaq_ioaddr, "i"); +MODULE_PARM(compaq_irq, "i"); +MODULE_PARM(compaq_device_id, "i"); +#endif + +/* Operational parameter that usually are not changed. */ + +/* The Vortex size is twice that of the original EtherLinkIII series: the + runtime register window, window 1, is now always mapped in. + The Boomerang size is twice as large as the Vortex -- it has additional + bus master control registers. */ +#define VORTEX_TOTAL_SIZE 0x20 +#define BOOMERANG_TOTAL_SIZE 0x40 + +/* Set iff a MII transceiver on any interface requires mdio preamble. + This only set with the original DP83840 on older 3c905 boards, so the extra + code size of a per-interface flag is not worthwhile. */ +static char mii_preamble_required = 0; + +/* + Theory of Operation + +I. Board Compatibility + +This device driver is designed for the 3Com FastEtherLink and FastEtherLink +XL, 3Com's PCI to 10/100baseT adapters. It also works with the 10Mbs +versions of the FastEtherLink cards. The supported product IDs are + 3c590, 3c592, 3c595, 3c597, 3c900, 3c905 + +The related ISA 3c515 is supported with a separate driver, 3c515.c, included +with the kernel source or available from + cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html + +II. Board-specific settings + +PCI bus devices are configured by the system at boot time, so no jumpers +need to be set on the board. The system BIOS should be set to assign the +PCI INTA signal to an otherwise unused system IRQ line. + +The EEPROM settings for media type and forced-full-duplex are observed. +The EEPROM media type should be left at the default "autoselect" unless using +10base2 or AUI connections which cannot be reliably detected. + +III. Driver operation + +The 3c59x series use an interface that's very similar to the previous 3c5x9 +series. The primary interface is two programmed-I/O FIFOs, with an +alternate single-contiguous-region bus-master transfer (see next). + +The 3c900 "Boomerang" series uses a full-bus-master interface with separate +lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet, +DEC Tulip and Intel Speedo3. The first chip version retains a compatible +programmed-I/O interface that has been removed in 'B' and subsequent board +revisions. + +One extension that is advertised in a very large font is that the adapters +are capable of being bus masters. On the Vortex chip this capability was +only for a single contiguous region making it far less useful than the full +bus master capability. There is a significant performance impact of taking +an extra interrupt or polling for the completion of each transfer, as well +as difficulty sharing the single transfer engine between the transmit and +receive threads. Using DMA transfers is a win only with large blocks or +with the flawed versions of the Intel Orion motherboard PCI controller. + +The Boomerang chip's full-bus-master interface is useful, and has the +currently-unused advantages over other similar chips that queued transmit +packets may be reordered and receive buffer groups are associated with a +single frame. + +With full-bus-master support, this driver uses a "RX_COPYBREAK" scheme. +Rather than a fixed intermediate receive buffer, this scheme allocates +full-sized skbuffs as receive buffers. The value RX_COPYBREAK is used as +the copying breakpoint: it is chosen to trade-off the memory wasted by +passing the full-sized skbuff to the queue layer for all frames vs. the +copying cost of copying a frame to a correctly-sized skbuff. + +IIIC. Synchronization +The driver runs as two independent, single-threaded flows of control. One +is the send-packet routine, which enforces single-threaded use by the +dev->tbusy flag. The other thread is the interrupt handler, which is single +threaded by the hardware and other software. + +IV. Notes + +Thanks to Cameron Spitzer and Terry Murphy of 3Com for providing development +3c590, 3c595, and 3c900 boards. +The name "Vortex" is the internal 3Com project name for the PCI ASIC, and +the EISA version is called "Demon". According to Terry these names come +from rides at the local amusement park. + +The new chips support both ethernet (1.5K) and FDDI (4.5K) packet sizes! +This driver only supports ethernet packets because of the skbuff allocation +limit of 4K. +*/ + +/* This table drives the PCI probe routines. It's mostly boilerplate in all + of the drivers, and will likely be provided by some future kernel. +*/ +enum pci_flags_bit { + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, +}; +struct pci_id_info { + const char *name; + u16 vendor_id, device_id, device_id_mask, flags; + int drv_flags, io_size; + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_idx, int fnd_cnt); +}; + +enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, + HAS_PWR_CTRL=0x10, HAS_MII=0x20, HAS_NWAY=0x40, HAS_CB_FNS=0x80, }; +static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, + int irq, int dev_id, int card_idx); +static struct pci_id_info pci_tbl[] = { + {"3c590 Vortex 10Mbps", 0x10B7, 0x5900, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1}, + {"3c595 Vortex 100baseTx", 0x10B7, 0x5950, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1}, + {"3c595 Vortex 100baseT4", 0x10B7, 0x5951, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1}, + {"3c595 Vortex 100base-MII", 0x10B7, 0x5952, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, vortex_probe1}, + {"3Com Vortex", 0x10B7, 0x5900, 0xff00, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1}, + {"3c900 Boomerang 10baseT", 0x10B7, 0x9000, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1}, + {"3c900 Boomerang 10Mbps Combo", 0x10B7, 0x9001, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1}, + {"3c900 Cyclone 10Mbps Combo", 0x10B7, 0x9005, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c900B-FL Cyclone 10base-FL", 0x10B7, 0x900A, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c905 Boomerang 100baseTx", 0x10B7, 0x9050, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1}, + {"3c905 Boomerang 100baseT4", 0x10B7, 0x9051, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1}, + {"3c905B Cyclone 100baseTx", 0x10B7, 0x9055, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY, 128, vortex_probe1}, + {"3c905B Cyclone 10/100/BNC", 0x10B7, 0x9058, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY, 128, vortex_probe1}, + {"3c905B-FX Cyclone 100baseFx", 0x10B7, 0x905A, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c905C Tornado", 0x10B7, 0x9200, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c980 Cyclone", 0x10B7, 0x9800, 0xfff0, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3cSOHO100-TX Hurricane", 0x10B7, 0x7646, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c555 Laptop Hurricane", 0x10B7, 0x5055, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1}, + {"3c575 Boomerang CardBus", 0x10B7, 0x5057, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1}, + {"3CCFE575 Cyclone CardBus", 0x10B7, 0x5157, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS, + 128, vortex_probe1}, + {"3CCFE575CT Cyclone CardBus", 0x10B7, 0x5257, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS, + 128, vortex_probe1}, + {"3CCFE656 Cyclone CardBus", 0x10B7, 0x6560, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS, + 128, vortex_probe1}, + {"3CCFEM656 Cyclone CardBus", 0x10B7, 0x6562, 0xffff, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS, + 128, vortex_probe1}, + {"3c575 series CardBus (unknown version)", 0x10B7, 0x5057, 0xf0ff, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1}, + {"3Com Boomerang (unknown version)", 0x10B7, 0x9000, 0xff00, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, vortex_probe1}, + {0,}, /* 0 terminated list. */ +}; + +/* Operational definitions. + These are not used by other compilation units and thus are not + exported in a ".h" file. + + First the windows. There are eight register windows, with the command + and status registers available in each. + */ +#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) +#define EL3_CMD 0x0e +#define EL3_STATUS 0x0e + +/* The top five bits written to EL3_CMD are a command, the lower + 11 bits are the parameter, if applicable. + Note that 11 parameters bits was fine for ethernet, but the new chip + can handle FDDI length frames (~4500 octets) and now parameters count + 32-bit 'Dwords' rather than octets. */ + +enum vortex_cmd { + TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11, + RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, + UpStall = 6<<11, UpUnstall = (6<<11)+1, + DownStall = (6<<11)+2, DownUnstall = (6<<11)+3, + RxDiscard = 8<<11, TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11, + FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, + SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, + SetTxThreshold = 18<<11, SetTxStart = 19<<11, + StartDMAUp = 20<<11, StartDMADown = (20<<11)+1, StatsEnable = 21<<11, + StatsDisable = 22<<11, StopCoax = 23<<11, SetFilterBit = 25<<11,}; + +/* The SetRxFilter command accepts the following classes: */ +enum RxFilter { + RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 }; + +/* Bits in the general status register. */ +enum vortex_status { + IntLatch = 0x0001, HostError = 0x0002, TxComplete = 0x0004, + TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020, + IntReq = 0x0040, StatsFull = 0x0080, + DMADone = 1<<8, DownComplete = 1<<9, UpComplete = 1<<10, + DMAInProgress = 1<<11, /* DMA controller is still busy.*/ + CmdInProgress = 1<<12, /* EL3_CMD is still busy.*/ +}; + +/* Register window 1 offsets, the window used in normal operation. + On the Vortex this window is always mapped at offsets 0x10-0x1f. */ +enum Window1 { + TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14, + RxStatus = 0x18, Timer=0x1A, TxStatus = 0x1B, + TxFree = 0x1C, /* Remaining free bytes in Tx buffer. */ +}; +enum Window0 { + Wn0EepromCmd = 10, /* Window 0: EEPROM command register. */ + Wn0EepromData = 12, /* Window 0: EEPROM results register. */ + IntrStatus=0x0E, /* Valid in all windows. */ +}; +enum Win0_EEPROM_bits { + EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0, + EEPROM_EWENB = 0x30, /* Enable erasing/writing for 10 msec. */ + EEPROM_EWDIS = 0x00, /* Disable EWENB before 10 msec timeout. */ +}; +/* EEPROM locations. */ +enum eeprom_offset { + PhysAddr01=0, PhysAddr23=1, PhysAddr45=2, ModelID=3, + EtherLink3ID=7, IFXcvrIO=8, IRQLine=9, + NodeAddr01=10, NodeAddr23=11, NodeAddr45=12, + DriverTune=13, Checksum=15}; + +enum Window2 { /* Window 2. */ + Wn2_ResetOptions=12, +}; +enum Window3 { /* Window 3: MAC/config bits. */ + Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8, +}; +union wn3_config { + int i; + struct w3_config_fields { + unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2; + int pad8:8; + unsigned int ram_split:2, pad18:2, xcvr:4, autoselect:1; + int pad24:7; + } u; +}; + +enum Window4 { /* Window 4: Xcvr/media bits. */ + Wn4_FIFODiag = 4, Wn4_NetDiag = 6, Wn4_PhysicalMgmt=8, Wn4_Media = 10, +}; +enum Win4_Media_bits { + Media_SQE = 0x0008, /* Enable SQE error counting for AUI. */ + Media_10TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */ + Media_Lnk = 0x0080, /* Enable just link beat for 100TX/100FX. */ + Media_LnkBeat = 0x0800, +}; +enum Window7 { /* Window 7: Bus Master control. */ + Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12, +}; +/* Boomerang bus master control registers. */ +enum MasterCtrl { + PktStatus = 0x20, DownListPtr = 0x24, FragAddr = 0x28, FragLen = 0x2c, + TxFreeThreshold = 0x2f, UpPktStatus = 0x30, UpListPtr = 0x38, +}; + +/* The Rx and Tx descriptor lists. + Caution Alpha hackers: these types are 32 bits! Note also the 8 byte + alignment contraint on tx_ring[] and rx_ring[]. */ +#define LAST_FRAG 0x80000000 /* Last Addr/Len pair in descriptor. */ +struct boom_rx_desc { + u32 next; /* Last entry points to 0. */ + s32 status; + u32 addr; /* Up to 63 addr/len pairs possible. */ + s32 length; /* Set LAST_FRAG to indicate last pair. */ +}; +/* Values for the Rx status entry. */ +enum rx_desc_status { + RxDComplete=0x00008000, RxDError=0x4000, + /* See boomerang_rx() for actual error bits */ + IPChksumErr=1<<25, TCPChksumErr=1<<26, UDPChksumErr=1<<27, + IPChksumValid=1<<29, TCPChksumValid=1<<30, UDPChksumValid=1<<31, +}; + +struct boom_tx_desc { + u32 next; /* Last entry points to 0. */ + s32 status; /* bits 0:12 length, others see below. */ + u32 addr; + s32 length; +}; + +/* Values for the Tx status entry. */ +enum tx_desc_status { + CRCDisable=0x2000, TxDComplete=0x8000, + AddIPChksum=0x02000000, AddTCPChksum=0x04000000, AddUDPChksum=0x08000000, + TxIntrUploaded=0x80000000, /* IRQ when in FIFO, but maybe not sent. */ +}; + +/* Chip features we care about in vp->capabilities, read from the EEPROM. */ +enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 }; + +struct vortex_private { + /* The Rx and Tx rings should be quad-word-aligned. */ + struct boom_rx_desc rx_ring[RX_RING_SIZE]; + struct boom_tx_desc tx_ring[TX_RING_SIZE]; + /* The addresses of transmit- and receive-in-place skbuffs. */ + struct sk_buff* rx_skbuff[RX_RING_SIZE]; + struct sk_buff* tx_skbuff[TX_RING_SIZE]; + struct net_device *next_module; + void *priv_addr; + unsigned int cur_rx, cur_tx; /* The next free ring entry */ + unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ + struct net_device_stats stats; + struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ + + /* PCI configuration space information. */ + u8 pci_bus, pci_devfn; /* PCI bus location, for power management. */ + char *cb_fn_base; /* CardBus function status addr space. */ + int chip_id; + + /* The remainder are related to chip state, mostly media selection. */ + unsigned long in_interrupt; + struct timer_list timer; /* Media selection timer. */ + int options; /* User-settable misc. driver options. */ + unsigned int media_override:4, /* Passed-in media type. */ + default_media:4, /* Read from the EEPROM/Wn3_Config. */ + full_duplex:1, force_fd:1, autoselect:1, + bus_master:1, /* Vortex can only do a fragment bus-m. */ + full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ + hw_csums:1, /* Has hardware checksums. */ + tx_full:1, + open:1; + u16 status_enable; + u16 intr_enable; + u16 available_media; /* From Wn3_Options. */ + u16 capabilities, info1, info2; /* Various, from EEPROM. */ + u16 advertising; /* NWay media advertisement */ + unsigned char phys[2]; /* MII device addresses. */ +}; + +/* The action to take with a media selection timer tick. + Note that we deviate from the 3Com order by checking 10base2 before AUI. + */ +enum xcvr_types { + XCVR_10baseT=0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx, + XCVR_100baseFx, XCVR_MII=6, XCVR_NWAY=8, XCVR_ExtMII=9, XCVR_Default=10, +}; + +static struct media_table { + char *name; + unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */ + mask:8, /* The transceiver-present bit in Wn3_Config.*/ + next:8; /* The media type to try next. */ + int wait; /* Time before we check media status. */ +} media_tbl[] = { + { "10baseT", Media_10TP,0x08, XCVR_10base2, (14*HZ)/10}, + { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1*HZ)/10}, + { "undefined", 0, 0x80, XCVR_10baseT, 10000}, + { "10base2", 0, 0x10, XCVR_AUI, (1*HZ)/10}, + { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14*HZ)/10}, + { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14*HZ)/10}, + { "MII", 0, 0x41, XCVR_10baseT, 3*HZ }, + { "undefined", 0, 0x01, XCVR_10baseT, 10000}, + { "Autonegotiate", 0, 0x41, XCVR_10baseT, 3*HZ}, + { "MII-External", 0, 0x41, XCVR_10baseT, 3*HZ }, + { "Default", 0, 0xFF, XCVR_10baseT, 10000}, +}; + +#ifndef CARDBUS +static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]); +#endif +static void vortex_up(struct net_device *dev); +static void vortex_down(struct net_device *dev); +static int vortex_open(struct net_device *dev); +static void mdio_sync(long ioaddr, int bits); +static int mdio_read(long ioaddr, int phy_id, int location); +static void mdio_write(long ioaddr, int phy_id, int location, int value); +static void vortex_timer(unsigned long arg); +static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int vortex_rx(struct net_device *dev); +static int boomerang_rx(struct net_device *dev); +static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static int vortex_close(struct net_device *dev); +static void update_stats(long ioaddr, struct net_device *dev); +static struct net_device_stats *vortex_get_stats(struct net_device *dev); +static void set_rx_mode(struct net_device *dev); +static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static void acpi_wake(int pci_bus, int pci_devfn); +static void acpi_set_WOL(struct net_device *dev); + +/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ +/* Option count limit only -- unlimited interfaces are supported. */ +#define MAX_UNITS 8 +static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,}; +static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; +/* A list of all installed Vortex devices, for removing the driver module. */ +static struct net_device *root_vortex_dev = NULL; + +#ifdef MODULE +#ifndef CARDBUS +/* Variables to work-around the Compaq PCI BIOS32 problem. */ +static int compaq_ioaddr = 0, compaq_irq = 0, compaq_device_id = 0x5900; +#endif + +#ifdef CARDBUS + +#include + +static dev_node_t *vortex_attach(dev_locator_t *loc) +{ + u16 dev_id, vendor_id; + u32 io; + u8 bus, devfn, irq; + struct net_device *dev; + int chip_idx; + + if (loc->bus != LOC_PCI) return NULL; + bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; + pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io); + pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq); + pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID, &vendor_id); + pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id); + printk(KERN_INFO "vortex_attach(bus %d, function %d, device %4.4x)\n", + bus, devfn, dev_id); + io &= ~3; + if (io == 0 || irq == 0) { + printk(KERN_ERR "The 3Com CardBus Ethernet interface was not " + "assigned an %s.\n" KERN_ERR " It will not be activated.\n", + io == 0 ? "I/O address" : "IRQ"); + return NULL; + } + for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++) + if (vendor_id == pci_tbl[chip_idx].vendor_id + && (dev_id & pci_tbl[chip_idx].device_id_mask) == + pci_tbl[chip_idx].device_id) + break; + if (pci_tbl[chip_idx].vendor_id == 0) { /* Compiled out! */ + printk(KERN_INFO "Unable to match chip type %4.4x %4.4x in " + "vortex_attach().\n", vendor_id, dev_id); + return NULL; + } + dev = vortex_probe1(bus, devfn, NULL, io, irq, chip_idx, MAX_UNITS+1); + if (dev) { + dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL); + strcpy(node->dev_name, dev->name); + node->major = node->minor = 0; + node->next = NULL; + MOD_INC_USE_COUNT; + return node; + } + return NULL; +} + +static void vortex_detach(dev_node_t *node) +{ + struct net_device **devp, **next; + printk(KERN_INFO "vortex_detach(%s)\n", node->dev_name); + for (devp = &root_vortex_dev; *devp; devp = next) { + next = &((struct vortex_private *)(*devp)->priv)->next_module; + if (strcmp((*devp)->name, node->dev_name) == 0) break; + } + if (*devp) { + struct net_device *dev = *devp; + struct vortex_private *vp = dev->priv; + if (dev->flags & IFF_UP) + vortex_close(dev); + dev->flags &= ~(IFF_UP|IFF_RUNNING); + unregister_netdev(dev); + if (vp->cb_fn_base) iounmap(vp->cb_fn_base); + kfree(dev); + *devp = *next; + kfree(vp->priv_addr); + kfree(node); + MOD_DEC_USE_COUNT; + } +} + +static void vortex_suspend(dev_node_t *node) +{ + struct net_device *dev, *next; + printk(KERN_INFO "vortex_suspend(%s)\n", node->dev_name); + for (dev = root_vortex_dev; dev; dev = next) { + next = ((struct vortex_private *)dev->priv)->next_module; + if (strcmp(dev->name, node->dev_name) == 0) break; + } + if (dev && dev->priv) { + struct vortex_private *vp = (struct vortex_private *)dev->priv; + if (vp->open) vortex_down(dev); + } +} + +static void vortex_resume(dev_node_t *node) +{ + struct net_device *dev, *next; + printk(KERN_INFO "vortex_resume(%s)\n", node->dev_name); + for (dev = root_vortex_dev; dev; dev = next) { + next = ((struct vortex_private *)dev->priv)->next_module; + if (strcmp(dev->name, node->dev_name) == 0) break; + } + if (dev && dev->priv) { + struct vortex_private *vp = (struct vortex_private *)dev->priv; + if (vp->open) vortex_up(dev); + } +} + +struct driver_operations vortex_ops = { + "3c575_cb", vortex_attach, vortex_suspend, vortex_resume, vortex_detach +}; + +#endif /* Cardbus support */ + +int init_module(void) +{ + if (vortex_debug) + printk(KERN_INFO "%s", version); +#ifdef CARDBUS + register_driver(&vortex_ops); + return 0; +#else + return vortex_scan(0, pci_tbl); +#endif +} + +#else +int tc59x_probe(struct net_device *dev) +{ + static int did_version = -1; + if (++did_version <= 0) + printk(KERN_INFO "%s", version); + return vortex_scan(dev, pci_tbl); +} +#endif /* not MODULE */ + +#ifndef CARDBUS +static int vortex_scan(struct net_device *dev, struct pci_id_info pci_tbl[]) +{ + int cards_found = 0; + + /* Allow an EISA-only driver. */ +#if defined(CONFIG_PCI) || (defined(MODULE) && !defined(NO_PCI)) + /* Ideally we would detect all cards in slot order. That would + be best done a central PCI probe dispatch, which wouldn't work + well with the current structure. So instead we detect 3Com cards + in slot order. */ + if (pcibios_present()) { + static int pci_index = 0; + unsigned char pci_bus, pci_device_fn; + + for (;pci_index < 0xff; pci_index++) { + u16 vendor, device, pci_command, new_command; + int chip_idx, irq; + long ioaddr; + + if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_index, + &pci_bus, &pci_device_fn) + != PCIBIOS_SUCCESSFUL) + break; + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_VENDOR_ID, &vendor); + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_DEVICE_ID, &device); + for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++) + if (vendor == pci_tbl[chip_idx].vendor_id + && (device & pci_tbl[chip_idx].device_id_mask) == + pci_tbl[chip_idx].device_id) + break; + if (pci_tbl[chip_idx].vendor_id == 0) /* Compiled out! */ + continue; + + /* The Cyclone requires config space re-write if powered down. */ + acpi_wake(pci_bus, pci_device_fn); + + { + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); + ioaddr = pdev->resource[0].start; + irq = pdev->irq; +#elif LINUX_VERSION_CODE >= 0x20155 + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); + ioaddr = pdev->base_address[0] & ~3; + irq = pdev->irq; + } + + if (ioaddr == 0) { + printk(KERN_WARNING " A 3Com network adapter has been found, " + "however it has not been assigned an I/O address.\n" + " You may need to power-cycle the machine for this " + "device to work!\n"); + continue; + } + + /* Activate the card. */ + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, &pci_command); + new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO; + if (pci_command != new_command) { + printk(KERN_INFO " The PCI BIOS has not enabled the device " + "at %d/%d. Updating PCI command %4.4x->%4.4x.\n", + pci_bus, pci_device_fn, pci_command, new_command); + pcibios_write_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, new_command); + } + + dev = vortex_probe1(pci_bus, pci_device_fn, dev, ioaddr, irq, + chip_idx, cards_found); + + if (dev) { + /* Get and check the latency values. On the 3c590 series + the latency timer must be set to the maximum value to avoid + data corruption that occurs when the timer expires during + a transfer -- a bug in the Vortex chip only. */ + u8 pci_latency; + u8 new_latency = (device & 0xff00) == 0x5900 ? 248 : 32; + + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, &pci_latency); + if (pci_latency < new_latency) { + printk(KERN_INFO "%s: Overriding PCI latency" + " timer (CFLT) setting of %d, new value is %d.\n", + dev->name, pci_latency, new_latency); + pcibios_write_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, new_latency); + } + dev = 0; + cards_found++; + } + } + } +#endif /* NO_PCI */ + + /* Now check all slots of the EISA bus. */ + if (EISA_bus) { + static long ioaddr = 0x1000; + for ( ; ioaddr < 0x9000; ioaddr += 0x1000) { + int device_id; + if (check_region(ioaddr, VORTEX_TOTAL_SIZE)) + continue; + /* Check the standard EISA ID register for an encoded '3Com'. */ + if (inw(ioaddr + 0xC80) != 0x6d50) + continue; + /* Check for a product that we support, 3c59{2,7} any rev. */ + device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83); + if ((device_id & 0xFF00) != 0x5900) + continue; + vortex_probe1(0, 0, dev, ioaddr, inw(ioaddr + 0xC88) >> 12, + 4, cards_found); + dev = 0; + cards_found++; + } + } + +#ifdef MODULE + /* Special code to work-around the Compaq PCI BIOS32 problem. */ + if (compaq_ioaddr) { + vortex_probe1(0, 0, dev, compaq_ioaddr, compaq_irq, + compaq_device_id, cards_found++); + dev = 0; + } +#endif + + return cards_found ? 0 : -ENODEV; +} +#endif /* ! Cardbus */ + +static struct net_device *vortex_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, + int irq, int chip_idx, int card_idx) +{ + struct vortex_private *vp; + int option; + unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */ + int i; + + dev = init_etherdev(dev, 0); + + printk(KERN_INFO "%s: 3Com %s at 0x%lx, ", + dev->name, pci_tbl[chip_idx].name, ioaddr); + + dev->base_addr = ioaddr; + dev->irq = irq; + dev->mtu = mtu; + + /* Make certain the descriptor lists are aligned. */ + { + void *mem = kmalloc(sizeof(*vp) + 15, GFP_KERNEL); + vp = (void *)(((long)mem + 15) & ~15); + vp->priv_addr = mem; + } + memset(vp, 0, sizeof(*vp)); + dev->priv = vp; + + vp->next_module = root_vortex_dev; + root_vortex_dev = dev; + + vp->chip_id = chip_idx; + vp->pci_bus = pci_bus; + vp->pci_devfn = pci_devfn; + + /* The lower four bits are the media type. */ + if (dev->mem_start) + option = dev->mem_start; + else if (card_idx < MAX_UNITS) + option = options[card_idx]; + else + option = -1; + + if (option >= 0) { + vp->media_override = ((option & 7) == 2) ? 0 : option & 15; + vp->full_duplex = (option & 0x200) ? 1 : 0; + vp->bus_master = (option & 16) ? 1 : 0; + } else { + vp->media_override = 7; + vp->full_duplex = 0; + vp->bus_master = 0; + } + if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0) + vp->full_duplex = 1; + + vp->force_fd = vp->full_duplex; + vp->options = option; + + /* Read the station address from the EEPROM. */ + EL3WINDOW(0); + for (i = 0; i < 0x40; i++) { + int timer; +#ifdef CARDBUS + outw(0x230 + i, ioaddr + Wn0EepromCmd); +#else + outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd); +#endif + /* Pause for at least 162 us. for the read to take place. */ + for (timer = 10; timer >= 0; timer--) { + udelay(162); + if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0) + break; + } + eeprom[i] = inw(ioaddr + Wn0EepromData); + } + for (i = 0; i < 0x18; i++) + checksum ^= eeprom[i]; + checksum = (checksum ^ (checksum >> 8)) & 0xff; + if (checksum != 0x00) { /* Grrr, needless incompatible change 3Com. */ + while (i < 0x21) + checksum ^= eeprom[i++]; + checksum = (checksum ^ (checksum >> 8)) & 0xff; + } + if (checksum != 0x00) + printk(" ***INVALID CHECKSUM %4.4x*** ", checksum); + + for (i = 0; i < 3; i++) + ((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]); + for (i = 0; i < 6; i++) + printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); + EL3WINDOW(2); + for (i = 0; i < 6; i++) + outb(dev->dev_addr[i], ioaddr + i); + +#ifdef __sparc__ + printk(", IRQ %s\n", __irq_itoa(dev->irq)); +#else + printk(", IRQ %d\n", dev->irq); + /* Tell them about an invalid IRQ. */ + if (vortex_debug && (dev->irq <= 0 || dev->irq >= NR_IRQS)) + printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n", + dev->irq); +#endif + + if (pci_tbl[vp->chip_id].drv_flags & HAS_CB_FNS) { + u32 fn_st_addr; /* Cardbus function status space */ + pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_2, + &fn_st_addr); + if (fn_st_addr) + vp->cb_fn_base = ioremap(fn_st_addr & ~3, 128); + printk(KERN_INFO "%s: CardBus functions mapped %8.8x->%p\n", + dev->name, fn_st_addr, vp->cb_fn_base); + } + + /* Extract our information from the EEPROM data. */ + vp->info1 = eeprom[13]; + vp->info2 = eeprom[15]; + vp->capabilities = eeprom[16]; + + if (vp->info1 & 0x8000) + vp->full_duplex = 1; + + { + char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; + union wn3_config config; + EL3WINDOW(3); + vp->available_media = inw(ioaddr + Wn3_Options); + if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */ + vp->available_media = 0x40; + config.i = inl(ioaddr + Wn3_Config); + if (vortex_debug > 1) + printk(KERN_DEBUG " Internal config register is %4.4x, " + "transceivers %#x.\n", config.i, inw(ioaddr + Wn3_Options)); + printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n", + 8 << config.u.ram_size, + config.u.ram_width ? "word" : "byte", + ram_split[config.u.ram_split], + config.u.autoselect ? "autoselect/" : "", + config.u.xcvr > XCVR_ExtMII ? "" : + media_tbl[config.u.xcvr].name); + vp->default_media = config.u.xcvr; + vp->autoselect = config.u.autoselect; + } + + if (vp->media_override != 7) { + printk(KERN_INFO " Media override to transceiver type %d (%s).\n", + vp->media_override, media_tbl[vp->media_override].name); + dev->if_port = vp->media_override; + } else + dev->if_port = vp->default_media; + + if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { + int phy, phy_idx = 0; + EL3WINDOW(4); + mii_preamble_required++; + mii_preamble_required++; + mdio_read(ioaddr, 24, 1); + for (phy = 1; phy <= 32 && phy_idx < sizeof(vp->phys); phy++) { + int mii_status, phyx = phy & 0x1f; + mii_status = mdio_read(ioaddr, phyx, 1); + if (mii_status && mii_status != 0xffff) { + vp->phys[phy_idx++] = phyx; + printk(KERN_INFO " MII transceiver found at address %d," + " status %4x.\n", phyx, mii_status); + if ((mii_status & 0x0040) == 0) + mii_preamble_required++; + } + } + mii_preamble_required--; + if (phy_idx == 0) { + printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n"); + vp->phys[0] = 24; + } else { + vp->advertising = mdio_read(ioaddr, vp->phys[0], 4); + if (vp->full_duplex) { + /* Only advertise the FD media types. */ + vp->advertising &= ~0x02A0; + mdio_write(ioaddr, vp->phys[0], 4, vp->advertising); + } + } + } + + if (vp->capabilities & CapPwrMgmt) + acpi_set_WOL(dev); + + if (vp->capabilities & CapBusMaster) { + vp->full_bus_master_tx = 1; + printk(KERN_INFO" Enabling bus-master transmits and %s receives.\n", + (vp->info2 & 1) ? "early" : "whole-frame" ); + vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2; + } + + /* We do a request_region() to register /proc/ioports info. */ + request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name); + + /* The 3c59x-specific entries in the device structure. */ + dev->open = &vortex_open; + dev->hard_start_xmit = &vortex_start_xmit; + dev->stop = &vortex_close; + dev->get_stats = &vortex_get_stats; + dev->do_ioctl = &vortex_ioctl; + dev->set_multicast_list = &set_rx_mode; + + return dev; +} + +static void wait_for_completion(struct net_device *dev, int cmd) +{ + int i = 2000; + outw(cmd, dev->base_addr + EL3_CMD); + while (--i > 0) + if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress)) + break; + if (i == 0) + printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", + dev->name, cmd); +} + +static void +vortex_up(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct vortex_private *vp = (struct vortex_private *)dev->priv; + union wn3_config config; + int i; + + /* Should be if(HAS_ACPI) */ + acpi_wake(vp->pci_bus, vp->pci_devfn); + + /* Before initializing select the active media port. */ + EL3WINDOW(3); + config.i = inl(ioaddr + Wn3_Config); + + if (vp->media_override != 7) { + if (vortex_debug > 1) + printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n", + dev->name, vp->media_override, + media_tbl[vp->media_override].name); + dev->if_port = vp->media_override; + } else if (vp->autoselect) { + if (pci_tbl[vp->chip_id].drv_flags & HAS_NWAY) + dev->if_port = XCVR_NWAY; + else { + /* Find first available media type, starting with 100baseTx. */ + dev->if_port = XCVR_100baseTx; + while (! (vp->available_media & media_tbl[dev->if_port].mask)) + dev->if_port = media_tbl[dev->if_port].next; + } + } else + dev->if_port = vp->default_media; + + init_timer(&vp->timer); + vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait); + vp->timer.data = (unsigned long)dev; + vp->timer.function = &vortex_timer; /* timer handler */ + add_timer(&vp->timer); + + if (vortex_debug > 1) + printk(KERN_DEBUG "%s: Initial media type %s.\n", + dev->name, media_tbl[dev->if_port].name); + + vp->full_duplex = vp->force_fd; + config.u.xcvr = dev->if_port; + if ( ! (pci_tbl[vp->chip_id].drv_flags & HAS_NWAY)) + outl(config.i, ioaddr + Wn3_Config); + + if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { + int mii_reg1, mii_reg5; + EL3WINDOW(4); + /* Read BMSR (reg1) only to clear old status. */ + mii_reg1 = mdio_read(ioaddr, vp->phys[0], 1); + mii_reg5 = mdio_read(ioaddr, vp->phys[0], 5); + if (mii_reg5 == 0xffff || mii_reg5 == 0x0000) + ; /* No MII device or no link partner report */ + else if ((mii_reg5 & 0x0100) != 0 /* 100baseTx-FD */ + || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */ + vp->full_duplex = 1; + if (vortex_debug > 1) + printk(KERN_INFO "%s: MII #%d status %4.4x, link partner capability %4.4x," + " setting %s-duplex.\n", dev->name, vp->phys[0], + mii_reg1, mii_reg5, vp->full_duplex ? "full" : "half"); + EL3WINDOW(3); + } + + /* Set the full-duplex bit. */ + outb(((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | + (dev->mtu > 1500 ? 0x40 : 0), ioaddr + Wn3_MAC_Ctrl); + + if (vortex_debug > 1) { + printk(KERN_DEBUG "%s: vortex_open() InternalConfig %8.8x.\n", + dev->name, config.i); + } + + wait_for_completion(dev, TxReset); + wait_for_completion(dev, RxReset); + + outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD); + + if (vortex_debug > 1) { + EL3WINDOW(4); + printk(KERN_DEBUG "%s: vortex_open() irq %d media status %4.4x.\n", + dev->name, dev->irq, inw(ioaddr + Wn4_Media)); + } + + /* Set the station address and mask in window 2 each time opened. */ + EL3WINDOW(2); + for (i = 0; i < 6; i++) + outb(dev->dev_addr[i], ioaddr + i); + for (; i < 12; i+=2) + outw(0, ioaddr + i); + if (vp->cb_fn_base) { + u_short n = inw(ioaddr + Wn2_ResetOptions); + /* Inverted LED polarity */ + if (pci_tbl[vp->chip_id].device_id != 0x5257) + n |= 0x0010; + /* Inverted polarity of MII power bit */ + if ((pci_tbl[vp->chip_id].device_id == 0x6560) || + (pci_tbl[vp->chip_id].device_id == 0x6562) || + (pci_tbl[vp->chip_id].device_id == 0x5257)) + n |= 0x4000; + outw(n, ioaddr + Wn2_ResetOptions); + } + + if (dev->if_port == XCVR_10base2) + /* Start the thinnet transceiver. We should really wait 50ms...*/ + outw(StartCoax, ioaddr + EL3_CMD); + if (dev->if_port != XCVR_NWAY) { + EL3WINDOW(4); + outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) | + media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); + } + + /* Switch to the stats window, and clear all stats by reading. */ + outw(StatsDisable, ioaddr + EL3_CMD); + EL3WINDOW(6); + for (i = 0; i < 10; i++) + inb(ioaddr + i); + inw(ioaddr + 10); + inw(ioaddr + 12); + /* New: On the Vortex we must also clear the BadSSD counter. */ + EL3WINDOW(4); + inb(ioaddr + 12); + /* ..and on the Boomerang we enable the extra statistics bits. */ + outw(0x0040, ioaddr + Wn4_NetDiag); + + /* Switch to register set 7 for normal use. */ + EL3WINDOW(7); + + if (vp->full_bus_master_rx) { /* Boomerang bus master. */ + vp->cur_rx = vp->dirty_rx = 0; + /* Initialize the RxEarly register as recommended. */ + outw(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD); + outl(0x0020, ioaddr + PktStatus); + outl(virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr); + } + if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */ + dev->hard_start_xmit = &boomerang_start_xmit; + vp->cur_tx = vp->dirty_tx = 0; + outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */ + /* Clear the Tx ring. */ + for (i = 0; i < TX_RING_SIZE; i++) + vp->tx_skbuff[i] = 0; + outl(0, ioaddr + DownListPtr); + } + /* Set receiver mode: presumably accept b-case and phys addr only. */ + set_rx_mode(dev); + outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ + + vp->in_interrupt = 0; + dev->tbusy = 0; + dev->interrupt = 0; + dev->start = 1; + + outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ + outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ + /* Allow status bits to be seen. */ + vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete| + (vp->full_bus_master_tx ? DownComplete : TxAvailable) | + (vp->full_bus_master_rx ? UpComplete : RxComplete) | + (vp->bus_master ? DMADone : 0); + vp->intr_enable = SetIntrEnb | IntLatch | TxAvailable | RxComplete | + StatsFull | HostError | TxComplete | IntReq + | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete; + outw(vp->status_enable, ioaddr + EL3_CMD); + /* Ack all pending events, and set active indicator mask. */ + outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, + ioaddr + EL3_CMD); + outw(vp->intr_enable, ioaddr + EL3_CMD); + if (vp->cb_fn_base) /* The PCMCIA people are idiots. */ + writel(0x8000, vp->cb_fn_base + 4); +} + +static int +vortex_open(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + int i; + + /* Use the now-standard shared IRQ implementation. */ + if (request_irq(dev->irq, &vortex_interrupt, SA_SHIRQ, dev->name, dev)) { + return -EAGAIN; + } + + if (vp->full_bus_master_rx) { /* Boomerang bus master. */ + if (vortex_debug > 2) + printk(KERN_DEBUG "%s: Filling in the Rx ring.\n", dev->name); + for (i = 0; i < RX_RING_SIZE; i++) { + struct sk_buff *skb; + vp->rx_ring[i].next = cpu_to_le32(virt_to_bus(&vp->rx_ring[i+1])); + vp->rx_ring[i].status = 0; /* Clear complete bit. */ + vp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG); + skb = dev_alloc_skb(PKT_BUF_SZ); + vp->rx_skbuff[i] = skb; + if (skb == NULL) + break; /* Bad news! */ + skb->dev = dev; /* Mark as being used by this device. */ + skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ + vp->rx_ring[i].addr = cpu_to_le32(virt_to_bus(skb->tail)); + } + /* Wrap the ring. */ + vp->rx_ring[i-1].next = cpu_to_le32(virt_to_bus(&vp->rx_ring[0])); + } + if (vp->full_bus_master_tx) + dev->hard_start_xmit = &boomerang_start_xmit; + + vortex_up(dev); + vp->open = 1; + MOD_INC_USE_COUNT; + + return 0; +} + +static void vortex_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + int next_tick = 60*HZ; + int ok = 0; + int media_status, mii_status, old_window; + + if (vortex_debug > 1) + printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n", + dev->name, media_tbl[dev->if_port].name); + + disable_irq(dev->irq); + old_window = inw(ioaddr + EL3_CMD) >> 13; + EL3WINDOW(4); + media_status = inw(ioaddr + Wn4_Media); + switch (dev->if_port) { + case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx: + if (media_status & Media_LnkBeat) { + ok = 1; + if (vortex_debug > 1) + printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n", + dev->name, media_tbl[dev->if_port].name, media_status); + } else if (vortex_debug > 1) + printk(KERN_DEBUG "%s: Media %s is has no link beat, %x.\n", + dev->name, media_tbl[dev->if_port].name, media_status); + break; + case XCVR_MII: case XCVR_NWAY: + mii_status = mdio_read(ioaddr, vp->phys[0], 1); + ok = 1; + if (debug > 1) + printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n", + dev->name, mii_status); + if (mii_status & 0x0004) { + int mii_reg5 = mdio_read(ioaddr, vp->phys[0], 5); + if (! vp->force_fd && mii_reg5 != 0xffff) { + int duplex = (mii_reg5&0x0100) || + (mii_reg5 & 0x01C0) == 0x0040; + if (vp->full_duplex != duplex) { + vp->full_duplex = duplex; + printk(KERN_INFO "%s: Setting %s-duplex based on MII " + "#%d link partner capability of %4.4x.\n", + dev->name, vp->full_duplex ? "full" : "half", + vp->phys[0], mii_reg5); + /* Set the full-duplex bit. */ + EL3WINDOW(3); + outb((vp->full_duplex ? 0x20 : 0) | + (dev->mtu > 1500 ? 0x40 : 0), + ioaddr + Wn3_MAC_Ctrl); + } + next_tick = 60*HZ; + } + } + break; + default: /* Other media types handled by Tx timeouts. */ + if (vortex_debug > 1) + printk(KERN_DEBUG "%s: Media %s is has no indication, %x.\n", + dev->name, media_tbl[dev->if_port].name, media_status); + ok = 1; + } + if ( ! ok) { + union wn3_config config; + + do { + dev->if_port = media_tbl[dev->if_port].next; + } while ( ! (vp->available_media & media_tbl[dev->if_port].mask)); + if (dev->if_port == XCVR_Default) { /* Go back to default. */ + dev->if_port = vp->default_media; + if (vortex_debug > 1) + printk(KERN_DEBUG "%s: Media selection failing, using default " + "%s port.\n", + dev->name, media_tbl[dev->if_port].name); + } else { + if (vortex_debug > 1) + printk(KERN_DEBUG "%s: Media selection failed, now trying " + "%s port.\n", + dev->name, media_tbl[dev->if_port].name); + next_tick = media_tbl[dev->if_port].wait; + } + outw((media_status & ~(Media_10TP|Media_SQE)) | + media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); + + EL3WINDOW(3); + config.i = inl(ioaddr + Wn3_Config); + config.u.xcvr = dev->if_port; + outl(config.i, ioaddr + Wn3_Config); + + outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax, + ioaddr + EL3_CMD); + } + EL3WINDOW(old_window); + enable_irq(dev->irq); + + if (vortex_debug > 2) + printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n", + dev->name, media_tbl[dev->if_port].name); + + vp->timer.expires = RUN_AT(next_tick); + add_timer(&vp->timer); + return; +} + +static void vortex_tx_timeout(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + + printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n", + dev->name, inb(ioaddr + TxStatus), + inw(ioaddr + EL3_STATUS)); + /* Slight code bloat to be user friendly. */ + if ((inb(ioaddr + TxStatus) & 0x88) == 0x88) + printk(KERN_ERR "%s: Transmitter encountered 16 collisions --" + " network cable problem?\n", dev->name); + if (inw(ioaddr + EL3_STATUS) & IntLatch) { + printk(KERN_ERR "%s: Interrupt posted but not delivered --" + " IRQ blocked by another device?\n", dev->name); + /* Bad idea here.. but we might as well handle a few events. */ + vortex_interrupt(dev->irq, dev, 0); + } + +#if ! defined(final_version) && LINUX_VERSION_CODE >= 0x10300 + if (vp->full_bus_master_tx) { + int i; + printk(KERN_DEBUG " Flags; bus-master %d, full %d; dirty %d " + "current %d.\n", + vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx, vp->cur_tx); + printk(KERN_DEBUG " Transmit list %8.8x vs. %p.\n", + inl(ioaddr + DownListPtr), + &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]); + for (i = 0; i < TX_RING_SIZE; i++) { + printk(KERN_DEBUG " %d: @%p length %8.8x status %8.8x\n", i, + &vp->tx_ring[i], + le32_to_cpu(vp->tx_ring[i].length), + le32_to_cpu(vp->tx_ring[i].status)); + } + } +#endif + wait_for_completion(dev, TxReset); + + vp->stats.tx_errors++; + if (vp->full_bus_master_tx) { + if (vortex_debug > 0) + printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", + dev->name); + if (vp->cur_tx - vp->dirty_tx > 0 && inl(ioaddr + DownListPtr) == 0) + outl(virt_to_bus(&vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]), + ioaddr + DownListPtr); + if (vp->tx_full && (vp->cur_tx - vp->dirty_tx <= TX_RING_SIZE - 1)) { + vp->tx_full = 0; + clear_bit(0, (void*)&dev->tbusy); + } + outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); + outw(DownUnstall, ioaddr + EL3_CMD); + } else + vp->stats.tx_dropped++; + + /* Issue Tx Enable */ + outw(TxEnable, ioaddr + EL3_CMD); + dev->trans_start = jiffies; + + /* Switch to register set 7 for normal use. */ + EL3WINDOW(7); +} + +/* + * Handle uncommon interrupt sources. This is a separate routine to minimize + * the cache impact. + */ +static void +vortex_error(struct net_device *dev, int status) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + int do_tx_reset = 0; + + if (status & TxComplete) { /* Really "TxError" for us. */ + unsigned char tx_status = inb(ioaddr + TxStatus); + /* Presumably a tx-timeout. We must merely re-enable. */ + if (vortex_debug > 2 + || (tx_status != 0x88 && vortex_debug > 0)) + printk(KERN_DEBUG"%s: Transmit error, Tx status register %2.2x.\n", + dev->name, tx_status); + if (tx_status & 0x14) vp->stats.tx_fifo_errors++; + if (tx_status & 0x38) vp->stats.tx_aborted_errors++; + outb(0, ioaddr + TxStatus); + if (tx_status & 0x30) + do_tx_reset = 1; + else /* Merely re-enable the transmitter. */ + outw(TxEnable, ioaddr + EL3_CMD); + } + if (status & RxEarly) { /* Rx early is unused. */ + vortex_rx(dev); + outw(AckIntr | RxEarly, ioaddr + EL3_CMD); + } + if (status & StatsFull) { /* Empty statistics. */ + static int DoneDidThat = 0; + if (vortex_debug > 4) + printk(KERN_DEBUG "%s: Updating stats.\n", dev->name); + update_stats(ioaddr, dev); + /* HACK: Disable statistics as an interrupt source. */ + /* This occurs when we have the wrong media type! */ + if (DoneDidThat == 0 && + inw(ioaddr + EL3_STATUS) & StatsFull) { + printk(KERN_WARNING "%s: Updating statistics failed, disabling " + "stats as an interrupt source.\n", dev->name); + EL3WINDOW(5); + outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD); + EL3WINDOW(7); + DoneDidThat++; + } + } + if (status & IntReq) { /* Restore all interrupt sources. */ + outw(vp->status_enable, ioaddr + EL3_CMD); + outw(vp->intr_enable, ioaddr + EL3_CMD); + } + if (status & HostError) { + u16 fifo_diag; + EL3WINDOW(4); + fifo_diag = inw(ioaddr + Wn4_FIFODiag); + printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n", + dev->name, fifo_diag); + /* Adapter failure requires Tx/Rx reset and reinit. */ + if (vp->full_bus_master_tx) { + wait_for_completion(dev, TotalReset | 0xff); + /* Re-enable the receiver. */ + outw(RxEnable, ioaddr + EL3_CMD); + outw(TxEnable, ioaddr + EL3_CMD); + } else if (fifo_diag & 0x0400) + do_tx_reset = 1; + if (fifo_diag & 0x3000) { + wait_for_completion(dev, RxReset); + /* Set the Rx filter to the current state. */ + set_rx_mode(dev); + outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */ + outw(AckIntr | HostError, ioaddr + EL3_CMD); + } + } + if (do_tx_reset) { + wait_for_completion(dev, TxReset); + outw(TxEnable, ioaddr + EL3_CMD); + } + +} + +static int +vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { + if (jiffies - dev->trans_start >= TX_TIMEOUT) + vortex_tx_timeout(dev); + return 1; + } + + /* Put out the doubleword header... */ + outl(skb->len, ioaddr + TX_FIFO); + if (vp->bus_master) { + /* Set the bus-master controller to transfer the packet. */ + outl(virt_to_bus(skb->data), ioaddr + Wn7_MasterAddr); + outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen); + vp->tx_skb = skb; + outw(StartDMADown, ioaddr + EL3_CMD); + /* dev->tbusy will be cleared at the DMADone interrupt. */ + } else { + /* ... and the packet rounded to a doubleword. */ + outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); + DEV_FREE_SKB(skb); + if (inw(ioaddr + TxFree) > 1536) { + clear_bit(0, (void*)&dev->tbusy); + } else + /* Interrupt us when the FIFO has room for max-sized packet. */ + outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD); + } + + dev->trans_start = jiffies; + + /* Clear the Tx status stack. */ + { + int tx_status; + int i = 32; + + while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) { + if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */ + if (vortex_debug > 2) + printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n", + dev->name, tx_status); + if (tx_status & 0x04) vp->stats.tx_fifo_errors++; + if (tx_status & 0x38) vp->stats.tx_aborted_errors++; + if (tx_status & 0x30) { + wait_for_completion(dev, TxReset); + } + outw(TxEnable, ioaddr + EL3_CMD); + } + outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */ + } + } + return 0; +} + +static int +boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { + if (jiffies - dev->trans_start >= TX_TIMEOUT) + vortex_tx_timeout(dev); + return 1; + } else { + /* Calculate the next Tx descriptor entry. */ + int entry = vp->cur_tx % TX_RING_SIZE; + struct boom_tx_desc *prev_entry = + &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE]; + unsigned long flags; + + if (vortex_debug > 3) + printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n", + dev->name, vp->cur_tx); + if (vp->tx_full) { + if (vortex_debug >0) + printk(KERN_WARNING "%s: Tx Ring full, refusing to send buffer.\n", + dev->name); + return 1; + } + vp->tx_skbuff[entry] = skb; + vp->tx_ring[entry].next = 0; + vp->tx_ring[entry].addr = cpu_to_le32(virt_to_bus(skb->data)); + vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG); + vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded); + + save_flags(flags); + cli(); + /* Wait for the stall to complete. */ + wait_for_completion(dev, DownStall); + prev_entry->next = cpu_to_le32(virt_to_bus(&vp->tx_ring[entry])); + if (inl(ioaddr + DownListPtr) == 0) { + outl(virt_to_bus(&vp->tx_ring[entry]), ioaddr + DownListPtr); + queued_packet++; + } + outw(DownUnstall, ioaddr + EL3_CMD); + restore_flags(flags); + + vp->cur_tx++; + if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1) + vp->tx_full = 1; + else { /* Clear previous interrupt enable. */ +#if defined(tx_interrupt_mitigation) + prev_entry->status &= cpu_to_le32(~TxIntrUploaded); +#endif + clear_bit(0, (void*)&dev->tbusy); + } + dev->trans_start = jiffies; + return 0; + } +} + +/* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ +static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr; + int latency, status; + int work_done = max_interrupt_work; + +#if defined(__i386__) + /* A lock to prevent simultaneous entry bug on Intel SMP machines. */ + if (test_and_set_bit(0, (void*)&dev->interrupt)) { + printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n", + dev->name); + dev->interrupt = 0; /* Avoid halting machine. */ + return; + } +#else + if (dev->interrupt) { + printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name); + return; + } + dev->interrupt = 1; +#endif + + dev->interrupt = 1; + ioaddr = dev->base_addr; + latency = inb(ioaddr + Timer); + status = inw(ioaddr + EL3_STATUS); + + if (status == 0xffff) + goto handler_exit; + if (vortex_debug > 4) + printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n", + dev->name, status, latency); + do { + if (vortex_debug > 5) + printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n", + dev->name, status); + if (status & RxComplete) + vortex_rx(dev); + if (status & UpComplete) { + outw(AckIntr | UpComplete, ioaddr + EL3_CMD); + boomerang_rx(dev); + } + + if (status & TxAvailable) { + if (vortex_debug > 5) + printk(KERN_DEBUG " TX room bit was handled.\n"); + /* There's room in the FIFO for a full-sized packet. */ + outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); + clear_bit(0, (void*)&dev->tbusy); + mark_bh(NET_BH); + } + + if (status & DownComplete) { + unsigned int dirty_tx = vp->dirty_tx; + + outw(AckIntr | DownComplete, ioaddr + EL3_CMD); + while (vp->cur_tx - dirty_tx > 0) { + int entry = dirty_tx % TX_RING_SIZE; + if (inl(ioaddr + DownListPtr) == + virt_to_bus(&vp->tx_ring[entry])) + break; /* It still hasn't been processed. */ + if (vp->tx_skbuff[entry]) { + DEV_FREE_SKB(vp->tx_skbuff[entry]); + vp->tx_skbuff[entry] = 0; + } + /* vp->stats.tx_packets++; Counted below. */ + dirty_tx++; + } + vp->dirty_tx = dirty_tx; + if (vp->tx_full && (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) { + vp->tx_full = 0; + clear_bit(0, (void*)&dev->tbusy); + mark_bh(NET_BH); + } + } + if (status & DMADone) { + if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) { + outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */ + DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */ + if (inw(ioaddr + TxFree) > 1536) { + clear_bit(0, (void*)&dev->tbusy); + mark_bh(NET_BH); + } else /* Interrupt when FIFO has room for max-sized packet. */ + outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD); + } + } + /* Check for all uncommon interrupts at once. */ + if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) { + if (status == 0xffff) + break; + vortex_error(dev, status); + } + + if (--work_done < 0) { + if ((status & (0x7fe - (UpComplete | DownComplete))) == 0) { + /* Just ack these and return. */ + outw(AckIntr | UpComplete | DownComplete, ioaddr + EL3_CMD); + } else { + printk(KERN_WARNING "%s: Too much work in interrupt, status " + "%4.4x. Temporarily disabling functions (%4.4x).\n", + dev->name, status, SetStatusEnb | ((~status) & 0x7FE)); + /* Disable all pending interrupts. */ + outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD); + outw(AckIntr | 0x7FF, ioaddr + EL3_CMD); + /* The timer will reenable interrupts. */ + break; + } + } + /* Acknowledge the IRQ. */ + outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); + if (vp->cb_fn_base) /* The PCMCIA people are idiots. */ + writel(0x8000, vp->cb_fn_base + 4); + + } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete)); + + if (vortex_debug > 4) + printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", + dev->name, status); +handler_exit: +#if defined(__i386__) + clear_bit(0, (void*)&dev->interrupt); +#else + dev->interrupt = 0; +#endif + return; +} + +static int vortex_rx(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + int i; + short rx_status; + + if (vortex_debug > 5) + printk(KERN_DEBUG" In rx_packet(), status %4.4x, rx_status %4.4x.\n", + inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus)); + while ((rx_status = inw(ioaddr + RxStatus)) > 0) { + if (rx_status & 0x4000) { /* Error, update stats. */ + unsigned char rx_error = inb(ioaddr + RxErrors); + if (vortex_debug > 2) + printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); + vp->stats.rx_errors++; + if (rx_error & 0x01) vp->stats.rx_over_errors++; + if (rx_error & 0x02) vp->stats.rx_length_errors++; + if (rx_error & 0x04) vp->stats.rx_frame_errors++; + if (rx_error & 0x08) vp->stats.rx_crc_errors++; + if (rx_error & 0x10) vp->stats.rx_length_errors++; + } else { + /* The packet length: up to 4.5K!. */ + int pkt_len = rx_status & 0x1fff; + struct sk_buff *skb; + + skb = dev_alloc_skb(pkt_len + 5); + if (vortex_debug > 4) + printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n", + pkt_len, rx_status); + if (skb != NULL) { + skb->dev = dev; + skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ + /* 'skb_put()' points to the start of sk_buff data area. */ + if (vp->bus_master && + ! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) { + outl(virt_to_bus(skb_put(skb, pkt_len)), + ioaddr + Wn7_MasterAddr); + outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen); + outw(StartDMAUp, ioaddr + EL3_CMD); + while (inw(ioaddr + Wn7_MasterStatus) & 0x8000) + ; + } else { + insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len), + (pkt_len + 3) >> 2); + } + outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */ + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; + vp->stats.rx_packets++; + /* Wait a limited time to go to next packet. */ + for (i = 200; i >= 0; i--) + if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) + break; + continue; + } else if (vortex_debug) + printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of " + "size %d.\n", dev->name, pkt_len); + } + outw(RxDiscard, ioaddr + EL3_CMD); + vp->stats.rx_dropped++; + /* Wait a limited time to skip this packet. */ + for (i = 200; i >= 0; i--) + if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) + break; + } + + return 0; +} + +static int +boomerang_rx(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + int entry = vp->cur_rx % RX_RING_SIZE; + long ioaddr = dev->base_addr; + int rx_status; + int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx; + + if (vortex_debug > 5) + printk(KERN_DEBUG " In boomerang_rx(), status %4.4x, rx_status " + "%4.4x.\n", + inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus)); + while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){ + if (--rx_work_limit < 0) + break; + if (rx_status & RxDError) { /* Error, update stats. */ + unsigned char rx_error = rx_status >> 16; + if (vortex_debug > 2) + printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); + vp->stats.rx_errors++; + if (rx_error & 0x01) vp->stats.rx_over_errors++; + if (rx_error & 0x02) vp->stats.rx_length_errors++; + if (rx_error & 0x04) vp->stats.rx_frame_errors++; + if (rx_error & 0x08) vp->stats.rx_crc_errors++; + if (rx_error & 0x10) vp->stats.rx_length_errors++; + } else { + /* The packet length: up to 4.5K!. */ + int pkt_len = rx_status & 0x1fff; + struct sk_buff *skb; + + if (vortex_debug > 4) + printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n", + pkt_len, rx_status); + + /* Check if the packet is long enough to just accept without + copying to a properly sized skbuff. */ + if (pkt_len < rx_copybreak + && (skb = dev_alloc_skb(pkt_len + 2)) != 0) { + skb->dev = dev; + skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ + /* 'skb_put()' points to the start of sk_buff data area. */ + memcpy(skb_put(skb, pkt_len), + bus_to_virt(le32_to_cpu(vp->rx_ring[entry].addr)), + pkt_len); + rx_copy++; + } else { + void *temp; + /* Pass up the skbuff already on the Rx ring. */ + skb = vp->rx_skbuff[entry]; + vp->rx_skbuff[entry] = NULL; + temp = skb_put(skb, pkt_len); + /* Remove this checking code for final release. */ + if (bus_to_virt(le32_to_cpu(vp->rx_ring[entry].addr)) != temp) + printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match" + " in boomerang_rx: %p vs. %p.\n", dev->name, + bus_to_virt(le32_to_cpu(vp->rx_ring[entry].addr)), + temp); + rx_nocopy++; + } + skb->protocol = eth_type_trans(skb, dev); + { /* Use hardware checksum info. */ + int csum_bits = rx_status & 0xee000000; + if (csum_bits && + (csum_bits == (IPChksumValid | TCPChksumValid) || + csum_bits == (IPChksumValid | UDPChksumValid))) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + rx_csumhits++; + } + } + netif_rx(skb); + dev->last_rx = jiffies; + vp->stats.rx_packets++; + } + entry = (++vp->cur_rx) % RX_RING_SIZE; + } + /* Refill the Rx ring buffers. */ + for (; vp->dirty_rx < vp->cur_rx; vp->dirty_rx++) { + struct sk_buff *skb; + entry = vp->dirty_rx % RX_RING_SIZE; + if (vp->rx_skbuff[entry] == NULL) { + skb = dev_alloc_skb(PKT_BUF_SZ); + if (skb == NULL) + break; /* Bad news! */ + skb->dev = dev; /* Mark as being used by this device. */ + skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ + vp->rx_ring[entry].addr = cpu_to_le32(virt_to_bus(skb->tail)); + vp->rx_skbuff[entry] = skb; + } + vp->rx_ring[entry].status = 0; /* Clear complete bit. */ + outw(UpUnstall, ioaddr + EL3_CMD); + } + return 0; +} + +static void +vortex_down(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + + dev->start = 0; + dev->tbusy = 1; + + del_timer(&vp->timer); + + /* Turn off statistics ASAP. We update vp->stats below. */ + outw(StatsDisable, ioaddr + EL3_CMD); + + /* Disable the receiver and transmitter. */ + outw(RxDisable, ioaddr + EL3_CMD); + outw(TxDisable, ioaddr + EL3_CMD); + + if (dev->if_port == XCVR_10base2) + /* Turn off thinnet power. Green! */ + outw(StopCoax, ioaddr + EL3_CMD); + + outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD); + + update_stats(ioaddr, dev); + if (vp->full_bus_master_rx) + outl(0, ioaddr + UpListPtr); + if (vp->full_bus_master_tx) + outl(0, ioaddr + DownListPtr); + + if (vp->capabilities & CapPwrMgmt) + acpi_set_WOL(dev); +} + +static int +vortex_close(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + int i; + + if (dev->start) + vortex_down(dev); + + if (vortex_debug > 1) { + printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n", + dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus)); + printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d" + " tx_queued %d Rx pre-checksummed %d.\n", + dev->name, rx_nocopy, rx_copy, queued_packet, rx_csumhits); + } + + free_irq(dev->irq, dev); + + if (vp->full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */ + for (i = 0; i < RX_RING_SIZE; i++) + if (vp->rx_skbuff[i]) { + DEV_FREE_SKB(vp->rx_skbuff[i]); + vp->rx_skbuff[i] = 0; + } + } + if (vp->full_bus_master_tx) { /* Free Boomerang bus master Tx buffers. */ + for (i = 0; i < TX_RING_SIZE; i++) + if (vp->tx_skbuff[i]) { + DEV_FREE_SKB(vp->tx_skbuff[i]); + vp->tx_skbuff[i] = 0; + } + } + + MOD_DEC_USE_COUNT; + vp->open = 0; + return 0; +} + +static struct net_device_stats *vortex_get_stats(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + unsigned long flags; + + if (dev->start) { + save_flags(flags); + cli(); + update_stats(dev->base_addr, dev); + restore_flags(flags); + } + return &vp->stats; +} + +/* Update statistics. + Unlike with the EL3 we need not worry about interrupts changing + the window setting from underneath us, but we must still guard + against a race condition with a StatsUpdate interrupt updating the + table. This is done by checking that the ASM (!) code generated uses + atomic updates with '+='. + */ +static void update_stats(long ioaddr, struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + int old_window = inw(ioaddr + EL3_CMD); + + if (old_window == 0xffff) /* Chip suspended or ejected. */ + return; + /* Unlike the 3c5x9 we need not turn off stats updates while reading. */ + /* Switch to the stats window, and read everything. */ + EL3WINDOW(6); + vp->stats.tx_carrier_errors += inb(ioaddr + 0); + vp->stats.tx_heartbeat_errors += inb(ioaddr + 1); + /* Multiple collisions. */ inb(ioaddr + 2); + vp->stats.collisions += inb(ioaddr + 3); + vp->stats.tx_window_errors += inb(ioaddr + 4); + vp->stats.rx_fifo_errors += inb(ioaddr + 5); + vp->stats.tx_packets += inb(ioaddr + 6); + vp->stats.tx_packets += (inb(ioaddr + 9)&0x30) << 4; + /* Rx packets */ inb(ioaddr + 7); /* Must read to clear */ + /* Tx deferrals */ inb(ioaddr + 8); + /* Don't bother with register 9, an extension of registers 6&7. + If we do use the 6&7 values the atomic update assumption above + is invalid. */ + vp->stats.rx_bytes += inw(ioaddr + 10); + vp->stats.tx_bytes += inw(ioaddr + 12); + /* New: On the Vortex we must also clear the BadSSD counter. */ + EL3WINDOW(4); + inb(ioaddr + 12); + + { + u8 up = inb(ioaddr + 13); + vp->stats.rx_bytes += (up & 0x0f) << 16; + vp->stats.tx_bytes += (up & 0xf0) << 12; + } + + /* We change back to window 7 (not 1) with the Vortex. */ + EL3WINDOW(old_window >> 13); + return; +} + +static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + u16 *data = (u16 *)&rq->ifr_data; + int phy = vp->phys[0] & 0x1f; + + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + data[0] = phy; + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + EL3WINDOW(4); + data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f); + return 0; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + EL3WINDOW(4); + mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]); + return 0; + default: + return -EOPNOTSUPP; + } +} + +/* Pre-Cyclone chips have no documented multicast filter, so the only + multicast setting is to receive all multicast frames. At least + the chip has a very clean way to set the mode, unlike many others. */ +static void set_rx_mode(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + int new_mode; + + if (dev->flags & IFF_PROMISC) { + if (vortex_debug > 0) + printk(KERN_NOTICE "%s: Setting promiscuous mode.\n", dev->name); + new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm; + } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) { + new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast; + } else + new_mode = SetRxFilter | RxStation | RxBroadcast; + + outw(new_mode, ioaddr + EL3_CMD); +} + +/* MII transceiver control section. + Read and write the MII registers using software-generated serial + MDIO protocol. See the MII specifications or DP83840A data sheet + for details. */ + +/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually + met by back-to-back PCI I/O cycles, but we insert a delay to avoid + "overclocking" issues. */ +#define mdio_delay() inl(mdio_addr) + +#define MDIO_SHIFT_CLK 0x01 +#define MDIO_DIR_WRITE 0x04 +#define MDIO_DATA_WRITE0 (0x00 | MDIO_DIR_WRITE) +#define MDIO_DATA_WRITE1 (0x02 | MDIO_DIR_WRITE) +#define MDIO_DATA_READ 0x02 +#define MDIO_ENB_IN 0x00 + +/* Generate the preamble required for initial synchronization and + a few older transceivers. */ +static void mdio_sync(long ioaddr, int bits) +{ + long mdio_addr = ioaddr + Wn4_PhysicalMgmt; + + /* Establish sync by sending at least 32 logic ones. */ + while (-- bits >= 0) { + outw(MDIO_DATA_WRITE1, mdio_addr); + mdio_delay(); + outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } +} + +static int mdio_read(long ioaddr, int phy_id, int location) +{ + int i; + int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; + unsigned int retval = 0; + long mdio_addr = ioaddr + Wn4_PhysicalMgmt; + + if (mii_preamble_required) + mdio_sync(ioaddr, 32); + + /* Shift the read command bits out. */ + for (i = 14; i >= 0; i--) { + int dataval = (read_cmd&(1< 0; i--) { + outw(MDIO_ENB_IN, mdio_addr); + mdio_delay(); + retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); + outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff; +} + +static void mdio_write(long ioaddr, int phy_id, int location, int value) +{ + int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value; + long mdio_addr = ioaddr + Wn4_PhysicalMgmt; + int i; + + if (mii_preamble_required) + mdio_sync(ioaddr, 32); + + /* Shift the command bits out. */ + for (i = 31; i >= 0; i--) { + int dataval = (write_cmd&(1<= 0; i--) { + outw(MDIO_ENB_IN, mdio_addr); + mdio_delay(); + outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + + return; +} + +/* ACPI: Advanced Configuration and Power Interface. */ +/* Set Wake-On-LAN mode and put the board into D3 (power-down) state. */ +static void acpi_set_WOL(struct net_device *dev) +{ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + long ioaddr = dev->base_addr; + + /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */ + EL3WINDOW(7); + outw(2, ioaddr + 0x0c); + /* The RxFilter must accept the WOL frames. */ + outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); + outw(RxEnable, ioaddr + EL3_CMD); + /* Change the power state to D3; RxEnable doesn't take effect. */ + pcibios_write_config_word(vp->pci_bus, vp->pci_devfn, 0xe0, 0x8103); +} +/* Change from D3 (sleep) to D0 (active). + Problem: The Cyclone forgets all PCI config info during the transition! */ +static void acpi_wake(int bus, int devfn) +{ + u32 base0, base1, romaddr; + u16 pci_command, pwr_command; + u8 pci_latency, pci_cacheline, irq; + + pcibios_read_config_word(bus, devfn, 0xe0, &pwr_command); + if ((pwr_command & 3) == 0) + return; + pcibios_read_config_word( bus, devfn, PCI_COMMAND, &pci_command); + pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &base0); + pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_1, &base1); + pcibios_read_config_dword(bus, devfn, PCI_ROM_ADDRESS, &romaddr); + pcibios_read_config_byte( bus, devfn, PCI_LATENCY_TIMER, &pci_latency); + pcibios_read_config_byte( bus, devfn, PCI_CACHE_LINE_SIZE, &pci_cacheline); + pcibios_read_config_byte( bus, devfn, PCI_INTERRUPT_LINE, &irq); + + pcibios_write_config_word( bus, devfn, 0xe0, 0x0000); + pcibios_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, base0); + pcibios_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_1, base1); + pcibios_write_config_dword(bus, devfn, PCI_ROM_ADDRESS, romaddr); + pcibios_write_config_byte( bus, devfn, PCI_INTERRUPT_LINE, irq); + pcibios_write_config_byte( bus, devfn, PCI_LATENCY_TIMER, pci_latency); + pcibios_write_config_byte( bus, devfn, PCI_CACHE_LINE_SIZE, pci_cacheline); + pcibios_write_config_word( bus, devfn, PCI_COMMAND, pci_command | 5); +} + +#ifdef MODULE +void cleanup_module(void) +{ + struct net_device *next_dev; + +#ifdef CARDBUS + unregister_driver(&vortex_ops); +#endif + + /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ + while (root_vortex_dev) { + struct vortex_private *vp=(void *)(root_vortex_dev->priv); + next_dev = vp->next_module; + unregister_netdev(root_vortex_dev); + outw(TotalReset, root_vortex_dev->base_addr + EL3_CMD); + release_region(root_vortex_dev->base_addr, + pci_tbl[vp->chip_id].io_size); + kfree(root_vortex_dev); + kfree(vp->priv_addr); + root_vortex_dev = next_dev; + } +} + +#endif /* MODULE */ + +/* + * Local variables: + * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c59x.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c59x.c" + * cardbus-compile-command: "gcc -DCARDBUS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c59x.c -o 3c575_cb.o -I/usr/src/linux/pcmcia-cs-3.0.9/include/" + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/3c589_cs.c linux/drivers/net/pcmcia/3c589_cs.c --- v2.3.26/linux/drivers/net/pcmcia/3c589_cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/3c589_cs.c Thu Nov 11 16:03:36 1999 @@ -2,9 +2,9 @@ A PCMCIA ethernet driver for the 3com 3c589 card. - Copyright (C) 1999 David A. Hinds -- dhinds@hyper.stanford.edu + Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org - 3c589_cs.c 1.135 1999/10/07 20:14:54 + 3c589_cs.c 1.137 1999/11/08 20:46:17 The network driver code is based on Donald Becker's 3c589 code: @@ -115,7 +115,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"3c589_cs.c 1.135 1999/10/07 20:14:54 (David Hinds)"; +"3c589_cs.c 1.137 1999/11/08 20:46:17 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -226,7 +226,6 @@ link->release.data = (u_long)link; link->io.NumPorts1 = 16; link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; - link->io.IOAddrLines = 4; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; if (irq_list[0] == -1) @@ -392,6 +391,7 @@ link->state |= DEV_CONFIG; /* For the 3c562, the base address must be xx00-xx7f */ + link->io.IOAddrLines = 16; for (i = j = 0; j < 0x400; j += 0x10) { if (multi && (j & 0x80)) continue; link->io.BasePort1 = j ^ 0x300; diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/Config.in linux/drivers/net/pcmcia/Config.in --- v2.3.26/linux/drivers/net/pcmcia/Config.in Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/Config.in Thu Nov 11 16:03:36 1999 @@ -15,11 +15,11 @@ dep_tristate ' SMC 91Cxx PCMCIA support' CONFIG_PCMCIA_SMC91C92 $CONFIG_PCMCIA dep_tristate ' Xircom 16-bit PCMCIA support' CONFIG_PCMCIA_XIRC2PS $CONFIG_PCMCIA - # if [ "$CONFIG_CARDBUS" = "y" ]; then - # dep_tristate ' 3Com 3c575 CardBus support' CONFIG_PCMCIA_3C575 $CONFIG_PCMCIA - # dep_tristate ' DEC Tulip CardBus support' CONFIG_PCMCIA_TULIP $CONFIG_PCMCIA - # dep_tristate ' SMC EPIC CardBus support' CONFIG_PCMCIA_EPIC100 $CONFIG_PCMCIA - # fi + if [ "$CONFIG_CARDBUS" = "y" ]; then + dep_tristate ' 3Com 3c575 CardBus support' CONFIG_PCMCIA_3C575 m + dep_tristate ' DEC Tulip CardBus support' CONFIG_PCMCIA_TULIP m + dep_tristate ' SMC EPIC CardBus support' CONFIG_PCMCIA_EPIC100 m + fi dep_tristate ' Aviator/Raytheon 2.4MHz wireless support' CONFIG_PCMCIA_RAYCS $CONFIG_PCMCIA dep_tristate ' Xircom Netwave AirSurfer wireless support' CONFIG_PCMCIA_NETWAVE $CONFIG_PCMCIA diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/Makefile linux/drivers/net/pcmcia/Makefile --- v2.3.26/linux/drivers/net/pcmcia/Makefile Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/Makefile Thu Nov 11 16:03:36 1999 @@ -9,110 +9,44 @@ ALL_SUB_DIRS := $(SUB_DIRS) O_TARGET := pcmcia_net.o -O_OBJS := -M_OBJS := -MOD_LIST_NAME := PCMCIA_MODULES - -#CFLAGS_3c575_cb.o = -DCARDBUS -#CFLAGS_tulip_cb.o = -DCARDBUS - -ifeq ($(CONFIG_PCMCIA_3C589),y) - O_OBJS += 3c589_cs.o -else - ifeq ($(CONFIG_PCMCIA_3C589),m) - M_OBJS += 3c589_cs.o - endif -endif - -ifeq ($(CONFIG_PCMCIA_3C574),y) - O_OBJS += 3c574_cs.o -else - ifeq ($(CONFIG_PCMCIA_3C574),m) - M_OBJS += 3c574_cs.o - endif -endif - -ifeq ($(CONFIG_PCMCIA_FMVJ18X),y) - O_OBJS += fmvj18x_cs.o -else - ifeq ($(CONFIG_PCMCIA_FMVJ18X),m) - M_OBJS += fmvj18x_cs.o - endif -endif - -ifeq ($(CONFIG_PCMCIA_NMCLAN),y) - O_OBJS += nmclan_cs.o -else - ifeq ($(CONFIG_PCMCIA_NMCLAN),m) - M_OBJS += nmclan_cs.o - endif -endif - -ifeq ($(CONFIG_PCMCIA_PCNET),y) - O_OBJS += pcnet_cs.o -else - ifeq ($(CONFIG_PCMCIA_PCNET),m) - M_OBJS += pcnet_cs.o - endif -endif - -ifeq ($(CONFIG_PCMCIA_SMC91C92),y) - O_OBJS += smc91c92_cs.o -else - ifeq ($(CONFIG_PCMCIA_SMC91C92),m) - M_OBJS += smc91c92_cs.o - endif -endif - -#ifeq ($(CONFIG_PCMCIA_3C575),y) -# O_OBJS += 3c575_cb.o -#else -# ifeq ($(CONFIG_PCMCIA_3C575),m) -# M_OBJS += 3c575_cb.o -# endif -#endif - -#ifeq ($(CONFIG_PCMCIA_TULIP),y) -# O_OBJS += tulip_cb.o -#else -# ifeq ($(CONFIG_PCMCIA_TULIP),m) -# M_OBJS += tulip_cb.o -# endif -#endif - -#ifeq ($(CONFIG_PCMCIA_EPIC100),y) -# O_OBJS += epic100_cb.o -#else -# ifeq ($(CONFIG_PCMCIA_EPIC100),m) -# M_OBJS += epic100_cb.o -# endif -#endif - -ifeq ($(CONFIG_PCMCIA_RAYCS),y) - OX_OBJS += ray_cs.o -else - ifeq ($(CONFIG_PCMCIA_RAYCS),m) - MX_OBJS += ray_cs.o - endif -endif - -ifeq ($(CONFIG_PCMCIA_NETWAVE),y) - OX_OBJS += netwave_cs.o -else - ifeq ($(CONFIG_PCMCIA_NETWAVE),m) - M_OBJS += netwave_cs.o - endif -endif - -ifeq ($(CONFIG_PCMCIA_WAVELAN),y) - OX_OBJS += wavelan_cs.o -else - ifeq ($(CONFIG_PCMCIA_WAVELAN),m) - M_OBJS += wavelan_cs.o - endif -endif +MOD_LIST_NAME := PCMCIA_NET_MODULES + +obj-y := +obj-m := +obj-n := +obj- := + +# Things that need to export symbols +export-objs := ray_cs.o + +CFLAGS_3c575_cb.o = -DCARDBUS -DMODULE +CFLAGS_tulip_cb.o = -DCARDBUS -DMODULE + +# 16-bit client drivers +obj-$(CONFIG_PCMCIA_3C589) += 3c589_cs.o +obj-$(CONFIG_PCMCIA_3C574) += 3c574_cs.o +obj-$(CONFIG_PCMCIA_FMVJ18X) += fmvj18x_cs.o +obj-$(CONFIG_PCMCIA_NMCLAN) += nmclan_cs.o +obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o +obj-$(CONFIG_PCMCIA_SMC91C92) += smc91c92_cs.o +obj-$(CONFIG_PCMCIA_XIRC2PS) += xirc2ps_cs.o + +# 16-bit wireless client drivers +obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o +obj-$(CONFIG_PCMCIA_NETWAVE) += netwave_cs.o +obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan_cs.o + +# Cardbus client drivers +obj-$(CONFIG_PCMCIA_3C575) += 3c575_cb.o +obj-$(CONFIG_PCMCIA_TULIP) += tulip_cb.o +obj-$(CONFIG_PCMCIA_EPIC100) += epic100_cb.o + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(filter-out $(export-objs), $(obj-m)) +MX_OBJS := $(filter $(export-objs), $(obj-m)) include $(TOPDIR)/Rules.make -#epic100_cb.o: ../epic100.c -# $(CC) $(CFLAGS) -DCARDBUS -c -o $@ ../epic100.c +epic100_cb.o: ../epic100.c + $(CC) $(CFLAGS) -DMODULE -DCARDBUS -c -o $@ ../epic100.c diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/netwave_cs.c linux/drivers/net/pcmcia/netwave_cs.c --- v2.3.26/linux/drivers/net/pcmcia/netwave_cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/netwave_cs.c Thu Nov 11 16:03:37 1999 @@ -6,7 +6,7 @@ * Status: Experimental. * Authors: John Markus Bjørndalen * Dag Brattli - * David Hinds + * David Hinds * Created at: A long time ago! * Modified at: Mon Nov 10 11:54:37 1997 * Modified by: Dag Brattli diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/nmclan_cs.c linux/drivers/net/pcmcia/nmclan_cs.c --- v2.3.26/linux/drivers/net/pcmcia/nmclan_cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/nmclan_cs.c Thu Nov 11 16:03:37 1999 @@ -28,7 +28,7 @@ Dean Siasoyco, New Media Corporation Ken Lesniak, Silicon Graphics, Inc. Donald Becker - David Hinds + David Hinds The Linux client driver is based on the 3c589_cs.c client driver by David Hinds. diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/pcnet_cs.c linux/drivers/net/pcmcia/pcnet_cs.c --- v2.3.26/linux/drivers/net/pcmcia/pcnet_cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/pcnet_cs.c Thu Nov 11 16:03:37 1999 @@ -9,9 +9,9 @@ Conrad ethernet card, and the Kingston KNE-PCM/x in shared-memory mode. It will also handle the Socket EA card in either mode. - Copyright (C) 1999 David A. Hinds -- dhinds@hyper.stanford.edu + Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org - pcnet_cs.c 1.101 1999/10/21 00:56:19 + pcnet_cs.c 1.106 1999/11/09 21:53:13 The network driver code is based on Donald Becker's NE2000 code: @@ -72,7 +72,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"pcnet_cs.c 1.101 1999/10/21 00:56:19 (David Hinds)"; +"pcnet_cs.c 1.106 1999/11/09 21:53:13 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -187,6 +187,8 @@ HAS_MISC_REG | HAS_IBM_MISC }, { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, HAS_MISC_REG | HAS_IBM_MISC }, + { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17, + HAS_MISC_REG | HAS_IBM_MISC }, { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, HAS_MISC_REG | HAS_IBM_MISC }, { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, @@ -229,7 +231,7 @@ u_long flags; caddr_t base; struct timer_list watchdog; - int stale; + int stale, link; u_short fast_poll; } pcnet_dev_t; @@ -578,6 +580,7 @@ link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; } if (link->io.BasePort1 == 0) { + link->io.IOAddrLines = 16; for (j = 0; j < 0x400; j += 0x20) { link->io.BasePort1 = j ^ 0x300; link->io.BasePort2 = (j ^ 0x300) + 0x10; @@ -656,6 +659,7 @@ (cfg->mem.win[0].len >= 0x4000)); link->io.BasePort1 = io->win[i].base; link->io.NumPorts1 = io->win[i].len; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { last_ret = try_io_port(link); if (last_ret == CS_SUCCESS) break; @@ -681,10 +685,14 @@ CS_CHECK(RequestConfiguration, handle, &link->conf); dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; - if ((if_port == 1) || (if_port == 2)) - dev->if_port = if_port; - else - printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n"); + if (info->flags & HAS_MISC_REG) { + if ((if_port == 1) || (if_port == 2)) + dev->if_port = if_port; + else + printk(KERN_NOTICE "pcnet_cs: invalid if_port requested\n"); + } else { + dev->if_port = 0; + } dev->tbusy = 0; if (register_netdev(dev) != 0) { printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); @@ -885,19 +893,11 @@ link->open++; MOD_INC_USE_COUNT; - /* For D-Link EtherFast, wait for something(?) to happen */ - if (info->flags & IS_DL10019A) { - int i; - for (i = 0; i < 20; i++) { - if ((inb(dev->base_addr+0x1c) & 0x01) == 0) break; - __set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/10); - } - } - set_misc_reg(dev); request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); + /* Start by assuming the link is bad */ + info->link = 1; info->watchdog.function = &ei_watchdog; info->watchdog.data = (u_long)info; info->watchdog.expires = jiffies + HZ; @@ -969,17 +969,14 @@ { pcnet_dev_t *info = (pcnet_dev_t *)dev; if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { - if ((map->port != 0) && !(info->flags & HAS_MISC_REG)) { - printk(KERN_NOTICE "%s: transceiver selection not " - "implemented\n", dev->name); - return -EINVAL; - } - if ((map->port == 1) || (map->port == 2)) { - dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", - dev->name, if_names[dev->if_port]); - } else + if (!(info->flags & HAS_MISC_REG)) + return -EOPNOTSUPP; + else if ((map->port < 1) || (map->port > 2)) return -EINVAL; + dev->if_port = map->port; + printk(KERN_INFO "%s: switched to %s port\n", + dev->name, if_names[dev->if_port]); + NS8390_init(dev, 1); } return 0; } @@ -1015,6 +1012,17 @@ info->watchdog.expires = jiffies + 1; add_timer(&info->watchdog); return; + } + + if (info->flags & IS_DL10019A) { + int state = inb(dev->base_addr+0x1c) & 0x01; + if (state != info->link) { + printk(KERN_INFO "%s: %s link beat\n", dev->name, + (state) ? "lost" : "found"); + if (!state) + NS8390_init(dev, 1); + info->link = state; + } } reschedule: diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c --- v2.3.26/linux/drivers/net/pcmcia/ray_cs.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/net/pcmcia/ray_cs.c Wed Nov 10 08:40:04 1999 @@ -147,7 +147,6 @@ static void start_net(u_long local); /* void start_net(ray_dev_t *local); */ -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); @@ -308,18 +307,6 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey "; -#ifdef CONFIG_PROC_FS -struct proc_dir_entry ray_cs_proc_entry = { - 0, /* Dynamic inode # */ - 6,"ray_cs", /* name length and name */ - S_IFREG | S_IRUGO, /* mode */ - 1, 0, 0, /* nlinks, owner, group */ - 0, /* size (unused) */ - NULL, /* operations (default) */ - &ray_cs_proc_read, /* function to read data */ - /* The end ?? */ -}; -#endif /*===========================================================================*/ static void cs_error(client_handle_t handle, int func, int ret) { @@ -2695,7 +2682,8 @@ rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach); DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc); #ifdef CONFIG_PROC_FS - proc_register(&proc_root, &ray_cs_proc_entry); + /* [proc-namespace][fixme] It shouldn't be under root, damnit! */ + create_proc_info_entry("ray_cs", 0, &proc_root, ray_cs_proc_read); #endif if (translate != 0) translate = 1; return 0; @@ -2726,7 +2714,7 @@ ray_detach(dev_list); } #ifdef CONFIG_PROC_FS - proc_unregister(&proc_root, ray_cs_proc_entry.low_ino); + remove_proc_entry("ray_cs", &proc_root); #endif } /* exit_ray_cs */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/smc91c92_cs.c linux/drivers/net/pcmcia/smc91c92_cs.c --- v2.3.26/linux/drivers/net/pcmcia/smc91c92_cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/smc91c92_cs.c Thu Nov 11 16:03:37 1999 @@ -6,13 +6,13 @@ Megahertz, Motorola, Ositech, and Psion Dacom ethernet/modem multifunction cards. - Copyright (C) 1999 David A. Hinds -- dhinds@hyper.stanford.edu + Copyright (C) 1999 David A. Hinds -- dhinds@pcmcia.sourceforge.org - smc91c92_cs.c 1.79 1999/10/19 00:38:29 + smc91c92_cs.c 1.82 1999/11/08 20:46:17 This driver contains code written by Donald Becker (becker@cesdis.gsfc.nasa.gov), Rowan Hughes (x-csrdh@jcu.edu.au), - David Hinds (dhinds@hyper.stanford.edu), and Erik Stahlman + David Hinds (dhinds@pcmcia.sourceforge.org), and Erik Stahlman (erik@vt.edu). Donald wrote the SMC 91c92 code using parts of Erik's SMC 91c94 driver. Rowan wrote a similar driver, and I've incorporated some parts of his driver here. I (Dave) wrote most @@ -717,6 +717,7 @@ if (i == CS_SUCCESS) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; + link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } @@ -784,6 +785,7 @@ link->io.NumPorts1 = 64; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; + link->io.IOAddrLines = 16; /* Enable Hard Decode, LAN, Modem */ link->conf.ConfigIndex = 0x23; @@ -1799,15 +1801,17 @@ static int s9k_config(struct net_device *dev, struct ifmap *map) { + struct smc_private *lp = dev->priv; if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { - if (map->port <= 2) { - dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", - dev->name, if_names[dev->if_port]); - } else + if (lp->cfg & CFG_MII_SELECT) + return -EOPNOTSUPP; + else if (map->port > 2) return -EINVAL; + dev->if_port = map->port; + printk(KERN_INFO "%s: switched to %s port\n", + dev->name, if_names[dev->if_port]); + smc_reset(dev); } - smc_reset(dev); return 0; } diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/tulip_cb.c linux/drivers/net/pcmcia/tulip_cb.c --- v2.3.26/linux/drivers/net/pcmcia/tulip_cb.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/pcmcia/tulip_cb.c Thu Nov 11 16:03:37 1999 @@ -0,0 +1,3383 @@ +/* tulip.c: A DEC 21040-family ethernet driver for Linux. */ +/* + Written/copyright 1994-1999 by Donald Becker. + + This software may be used and distributed according to the terms + of the GNU Public License, incorporated herein by reference. + + This driver is for the Digital "Tulip" Ethernet adapter interface. + It should work with most DEC 21*4*-based chips/ethercards, as well as + with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and ASIX. + + The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O + Center of Excellence in Space Data and Information Sciences + Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 + + Support and updates available at + http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html +*/ + +#define SMP_CHECK +static const char version[] = "tulip.c:v0.91 4/14/99 becker@cesdis.gsfc.nasa.gov (modified by danilo@cs.uni-magdeburg.de for XIRCOM CBE, fixed by Doug Ledford)\n"; + +/* A few user-configurable values. */ + +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static int max_interrupt_work = 25; + +#define MAX_UNITS 8 +/* Used to pass the full-duplex flag, etc. */ +static int full_duplex[MAX_UNITS] = {0, }; +static int options[MAX_UNITS] = {0, }; +static int mtu[MAX_UNITS] = {0, }; /* Jumbo MTU for interfaces. */ + +/* The possible media types that can be set in options[] are: */ +static const char * const medianame[] = { + "10baseT", "10base2", "AUI", "100baseTx", + "10baseT-FD", "100baseTx-FD", "100baseT4", "100baseFx", + "100baseFx-FD", "MII 10baseT", "MII 10baseT-FD", "MII", + "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FD", "MII 100baseT4", +}; + +/* Set if the PCI BIOS detects the chips on a multiport board backwards. */ +#ifdef REVERSE_PROBE_ORDER +static int reverse_probe = 1; +#else +static int reverse_probe = 0; +#endif + +/* Keep the ring sizes a power of two for efficiency. + Making the Tx ring too large decreases the effectiveness of channel + bonding and packet priority. + There are no ill effects from too-large receive rings. */ +#define TX_RING_SIZE 16 +#define RX_RING_SIZE 32 + +/* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ +#ifdef __alpha__ +static int rx_copybreak = 1518; +#else +static int rx_copybreak = 100; +#endif + +/* + Set the bus performance register. + Typical: Set 16 longword cache alignment, no burst limit. + Cache alignment bits 15:14 Burst length 13:8 + 0000 No alignment 0x00000000 unlimited 0800 8 longwords + 4000 8 longwords 0100 1 longword 1000 16 longwords + 8000 16 longwords 0200 2 longwords 2000 32 longwords + C000 32 longwords 0400 4 longwords + Warning: many older 486 systems are broken and require setting 0x00A04800 + 8 longword cache alignment, 8 longword burst. + ToDo: Non-Intel setting could be better. +*/ + +#if defined(__alpha__) +static int csr0 = 0x01A00000 | 0xE000; +#elif defined(__powerpc__) +static int csr0 = 0x01B00000 | 0x8000; +#elif defined(__sparc__) +static int csr0 = 0x01B00080 | 0x8000; +#elif defined(__i386__) +static int csr0 = 0x01A00000 | 0x8000; +#else +#warning Processor architecture undefined! +static int csr0 = 0x00A00000 | 0x4800; +#endif + +/* Operational parameters that usually are not changed. */ +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (4*HZ) +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ +/* This is a mysterious value that can be written to CSR11 in the 21040 (only) + to support a pre-NWay full-duplex signaling mechanism using short frames. + No one knows what it should be, but if left at its default value some + 10base2(!) packets trigger a full-duplex-request interrupt. */ +#define FULL_DUPLEX_MAGIC 0x6969 + +#if !defined(__OPTIMIZE__) || !defined(__KERNEL__) +#warning You must compile this file with the correct options! +#warning See the last lines of the source file. +#error You must compile this driver with "-O". +#endif + +#include +#include +#ifdef MODULE +#ifdef MODVERSIONS +#include +#endif +#include +#else +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Processor type for cache alignment. */ +#include +#include +#include + +/* Kernel compatibility defines, some common to David Hinds' PCMCIA package. + This is only in the support-all-kernels source code. */ + +#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115 +MODULE_AUTHOR("Donald Becker "); +MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver"); +MODULE_PARM(debug, "i"); +MODULE_PARM(max_interrupt_work, "i"); +MODULE_PARM(reverse_probe, "i"); +MODULE_PARM(rx_copybreak, "i"); +MODULE_PARM(csr0, "i"); +MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); +#endif + +#define RUN_AT(x) (jiffies + (x)) + +#define NETSTATS_VER2 +#define PCI_SUPPORT_VER3 +#define dev_free_skb(skb) dev_kfree_skb(skb); + +#define tulip_debug debug +#ifdef TULIP_DEBUG +static int tulip_debug = TULIP_DEBUG; +#else +static int tulip_debug = 1; +#endif + +/* + Theory of Operation + +I. Board Compatibility + +This device driver is designed for the DECchip "Tulip", Digital's +single-chip ethernet controllers for PCI. Supported members of the family +are the 21040, 21041, 21140, 21140A, 21142, and 21143. Similar work-alike +chips from Lite-On, Macronics, ASIX, Compex and other listed below are also +supported. + +These chips are used on at least 140 unique PCI board designs. The great +number of chips and board designs supported is the reason for the +driver size and complexity. Almost of the increasing complexity is in the +board configuration and media selection code. There is very little +increasing in the operational critical path length. + +II. Board-specific settings + +PCI bus devices are configured by the system at boot time, so no jumpers +need to be set on the board. The system BIOS preferably should assign the +PCI INTA signal to an otherwise unused system IRQ line. + +Some boards have EEPROMs tables with default media entry. The factory default +is usually "autoselect". This should only be overridden when using +transceiver connections without link beat e.g. 10base2 or AUI, or (rarely!) +for forcing full-duplex when used with old link partners that do not do +autonegotiation. + +III. Driver operation + +IIIa. Ring buffers + +The Tulip can use either ring buffers or lists of Tx and Rx descriptors. +This driver uses statically allocated rings of Rx and Tx descriptors, set at +compile time by RX/TX_RING_SIZE. This version of the driver allocates skbuffs +for the Rx ring buffers at open() time and passes the skb->data field to the +Tulip as receive data buffers. When an incoming frame is less than +RX_COPYBREAK bytes long, a fresh skbuff is allocated and the frame is +copied to the new skbuff. When the incoming frame is larger, the skbuff is +passed directly up the protocol stack and replaced by a newly allocated +skbuff. + +The RX_COPYBREAK value is chosen to trade-off the memory wasted by +using a full-sized skbuff for small frames vs. the copying costs of larger +frames. For small frames the copying cost is negligible (esp. considering +that we are pre-loading the cache with immediately useful header +information). For large frames the copying cost is non-trivial, and the +larger copy might flush the cache of useful data. A subtle aspect of this +choice is that the Tulip only receives into longword aligned buffers, thus +the IP header at offset 14 isn't longword aligned for further processing. +Copied frames are put into the new skbuff at an offset of "+2", thus copying +has the beneficial effect of aligning the IP header and preloading the +cache. + +IIIC. Synchronization +The driver runs as two independent, single-threaded flows of control. One +is the send-packet routine, which enforces single-threaded use by the +dev->tbusy flag. The other thread is the interrupt handler, which is single +threaded by the hardware and other software. + +The send packet thread has partial control over the Tx ring and 'dev->tbusy' +flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next +queue slot is empty, it clears the tbusy flag when finished otherwise it sets +the 'tp->tx_full' flag. + +The interrupt handler has exclusive control over the Rx ring and records stats +from the Tx ring. (The Tx-done interrupt can't be selectively turned off, so +we can't avoid the interrupt overhead by having the Tx routine reap the Tx +stats.) After reaping the stats, it marks the queue entry as empty by setting +the 'base' to zero. Iff the 'tp->tx_full' flag is set, it clears both the +tx_full and tbusy flags. + +IV. Notes + +Thanks to Duke Kamstra of SMC for long ago providing an EtherPower board. +Greg LaPolla at Linksys provided PNIC and other Linksys boards. +Znyx provided a four-port card for testing. + +IVb. References + +http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html +http://www.digital.com (search for current 21*4* datasheets and "21X4 SROM") +http://www.national.com/pf/DP/DP83840A.html +http://www.asix.com.tw/pmac.htm +http://www.admtek.com.tw/ + +IVc. Errata + +The old DEC databooks were light on details. +The 21040 databook claims that CSR13, CSR14, and CSR15 should each be the last +register of the set CSR12-15 written. Hmmm, now how is that possible? + +The DEC SROM format is very badly designed not precisely defined, leading to +part of the media selection junkheap below. Some boards do not have EEPROM +media tables and need to be patched up. Worse, other boards use the DEC +design kit media table when it isn't correct for their board. + +We cannot use MII interrupts because there is no defined GPIO pin to attach +them. The MII transceiver status is polled using an kernel timer. + +*/ + +static struct net_device * +tulip_probe1(int pci_bus, int pci_devfn, struct net_device *dev, long ioaddr, + int irq, int chip_idx, int board_idx); + +/* This table drives the PCI probe routines. It's mostly boilerplate in all + of the drivers, and will likely be provided by some future kernel. + Note the matching code -- the first table entry matchs all 56** cards but + second only the 1234 card. +*/ +enum pci_flags_bit { + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, +}; +#define PCI_ADDR0_IO (PCI_USES_IO|PCI_ADDR0) + +struct pci_id_info { + const char *name; + u16 vendor_id, device_id, device_id_mask, flags; + int io_size, min_latency; + struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, + long ioaddr, int irq, int chip_idx, int fnd_cnt); +}; +#ifndef CARDBUS +static struct pci_id_info pci_tbl[] = { + { "Digital DC21040 Tulip", + 0x1011, 0x0002, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, + { "Digital DC21041 Tulip", + 0x1011, 0x0014, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, + { "Digital DS21140 Tulip", + 0x1011, 0x0009, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, + { "Digital DS21143 Tulip", + 0x1011, 0x0019, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, + { "Lite-On 82c168 PNIC", + 0x11AD, 0x0002, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, + { "Macronix 98713 PMAC", + 0x10d9, 0x0512, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, + { "Macronix 98715 PMAC", + 0x10d9, 0x0531, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, + { "Macronix 98725 PMAC", + 0x10d9, 0x0531, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, + { "ASIX AX88140", + 0x125B, 0x1400, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, + { "Lite-On LC82C115 PNIC-II", + 0x11AD, 0xc115, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, + { "ADMtek AN981 Comet", + 0x1317, 0x0981, 0xffff, PCI_ADDR0_IO, 256, 32, tulip_probe1 }, + { "Compex RL100-TX", + 0x11F6, 0x9881, 0xffff, PCI_ADDR0_IO, 128, 32, tulip_probe1 }, + {0}, +}; +#endif /* !CARD_BUS */ + +/* This table use during operation for capabilities and media timer. */ + +static void tulip_timer(unsigned long data); +static void t21142_timer(unsigned long data); +static void mxic_timer(unsigned long data); +static void pnic_timer(unsigned long data); +static void comet_timer(unsigned long data); + +enum tbl_flag { + HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8, + HAS_ACPI=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */ + HAS_NWAY143=0x40, /* Uses 21143-like internal NWay. */ +}; +static struct tulip_chip_table { + char *chip_name; + int io_size; + int valid_intrs; /* CSR7 interrupt enable settings */ + int flags; + void (*media_timer)(unsigned long data); +} tulip_tbl[] = { + { "Digital DC21040 Tulip", 128, 0x0001ebef, 0, tulip_timer }, + { "Digital DC21041 Tulip", 128, 0x0001ebef, HAS_MEDIA_TABLE, tulip_timer }, + { "Digital DS21140 Tulip", 128, 0x0001ebef, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, tulip_timer }, + { "Digital DS21143 Tulip", 128, 0x0801fbff, + HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY143, t21142_timer }, + { "Lite-On 82c168 PNIC", 256, 0x0001ebef, + HAS_MII, pnic_timer }, + { "Macronix 98713 PMAC", 128, 0x0001ebef, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, + { "Macronix 98715 PMAC", 256, 0x0001ebef, + HAS_MEDIA_TABLE, mxic_timer }, + { "Macronix 98725 PMAC", 256, 0x0001ebef, + HAS_MEDIA_TABLE, mxic_timer }, + { "ASIX AX88140", 128, 0x0001fbff, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY, tulip_timer }, + { "Lite-On PNIC-II", 256, 0x0001ebef, + HAS_MII | HAS_NWAY143, pnic_timer }, + { "ADMtek Comet", 256, 0x0001abef, + MC_HASH_ONLY, comet_timer }, + { "Compex 9881 PMAC", 128, 0x0001ebef, + HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, + { "Xircom Cardbus Adapter (DEC 21143 compatible mode)", 128, 0x0801fbff, + HAS_MII | HAS_ACPI, tulip_timer }, + {0}, +}; +/* This matches the table above. Note 21142 == 21143. */ +enum chips { + DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3, + LC82C168, MX98713, MX98715, MX98725, AX88140, PNIC2, COMET, COMPEX9881, + X3201_3, +}; + +/* A full-duplex map for media types. */ +enum MediaIs { + MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8, + MediaIs100=16}; +static const char media_cap[] = +{0,0,0,16, 3,19,16,24, 27,4,7,5, 0,20,23,20 }; +static u8 t21040_csr13[] = {2,0x0C,8,4, 4,0,0,0, 0,0,0,0, 4,0,0,0}; +/* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD*/ +static u16 t21041_csr13[] = { 0xEF05, 0xEF09, 0xEF09, 0xEF01, 0xEF09, }; +static u16 t21041_csr14[] = { 0x7F3F, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, }; +static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; + +static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, }; +static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, }; +static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; + +/* Offsets to the Command and Status Registers, "CSRs". All accesses + must be longword instructions and quadword aligned. */ +enum tulip_offsets { + CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28, + CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58, + CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 }; + +/* The bits in the CSR5 status registers, mostly interrupt sources. */ +enum status_bits { + TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10, + NormalIntr=0x10000, AbnormalIntr=0x8000, + RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40, + TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01, +}; + +/* The Tulip Rx and Tx buffer descriptors. */ +struct tulip_rx_desc { + s32 status; + s32 length; + u32 buffer1, buffer2; +}; + +struct tulip_tx_desc { + s32 status; + s32 length; + u32 buffer1, buffer2; /* We use only buffer 1. */ +}; + +enum desc_status_bits { + DescOwned=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300, +}; + +/* Ring-wrap flag in length field, use for last ring entry. + 0x01000000 means chain on buffer2 address, + 0x02000000 means use the ring start address in CSR2/3. + Note: Some work-alike chips do not function correctly in chained mode. + The ASIX chip works only in chained mode. + Thus we indicates ring mode, but always write the 'next' field for + chained mode as well. +*/ +#define DESC_RING_WRAP 0x02000000 + +#ifdef CARDBUS +#define EEPROM_ADDRLEN (chip_rev == 65 ? 8 : 6) +#else +#define EEPROM_ADDRLEN 6 +#endif +#define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */ + +struct medialeaf { + u8 type; + u8 media; + unsigned char *leafdata; +}; + +struct mediatable { + u16 defaultmedia; + u8 leafcount, csr12dir; /* General purpose pin directions. */ + unsigned has_mii:1, has_nonmii:1, has_reset:6; + u32 csr15dir, csr15val; /* 21143 NWay setting. */ + struct medialeaf mleaf[0]; +}; + +struct mediainfo { + struct mediainfo *next; + int info_type; + int index; + unsigned char *info; +}; + +struct tulip_private { + char devname[8]; /* Used only for kernel debugging. */ + const char *product_name; + struct net_device *next_module; + struct tulip_rx_desc rx_ring[RX_RING_SIZE]; + struct tulip_tx_desc tx_ring[TX_RING_SIZE]; + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + struct sk_buff* tx_skbuff[TX_RING_SIZE]; +#ifdef CARDBUS + /* The X3201-3 requires double word aligned tx bufs */ + struct sk_buff* tx_aligned_skbuff[TX_RING_SIZE]; +#endif + /* The addresses of receive-in-place skbuffs. */ + struct sk_buff* rx_skbuff[RX_RING_SIZE]; + char *rx_buffs; /* Address of temporary Rx buffers. */ + u8 setup_buf[96*sizeof(u16) + 7]; + u16 *setup_frame; /* Pseudo-Tx frame to init address table. */ + int chip_id; + int revision; + struct net_device_stats stats; + struct timer_list timer; /* Media selection timer. */ + int interrupt; /* In-interrupt flag. */ + unsigned int cur_rx, cur_tx; /* The next free ring entry */ + unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ + unsigned int tx_full:1; /* The Tx queue is full. */ + unsigned int full_duplex:1; /* Full-duplex operation requested. */ + unsigned int full_duplex_lock:1; + unsigned int fake_addr:1; /* Multiport board faked address. */ + unsigned int default_port:4; /* Last dev->if_port value. */ + unsigned int media2:4; /* Secondary monitored media port. */ + unsigned int medialock:1; /* Don't sense media type. */ + unsigned int mediasense:1; /* Media sensing in progress. */ + unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */ + unsigned int open:1; + unsigned int csr0; /* CSR0 setting. */ + unsigned int csr6; /* Current CSR6 control settings. */ + unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ + u16 to_advertise; /* NWay capabilities advertised. */ + u16 lpar; /* 21143 Link partner ability. */ + u16 advertising[4]; + signed char phys[4], mii_cnt; /* MII device addresses. */ + struct mediatable *mtable; + int cur_index; /* Current media index. */ + int saved_if_port; + unsigned char pci_bus, pci_devfn; + int pad0, pad1; /* Used for 8-byte alignment */ +}; + +static void parse_eeprom(struct net_device *dev); +static int read_eeprom(long ioaddr, int location, int addr_len); +static int mdio_read(struct net_device *dev, int phy_id, int location); +static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static void select_media(struct net_device *dev, int startup); +static void tulip_up(struct net_device *dev); +static void tulip_down(struct net_device *dev); +static int tulip_open(struct net_device *dev); +static void tulip_timer(unsigned long data); +static void t21142_start_nway(struct net_device *dev); +static void tulip_tx_timeout(struct net_device *dev); +static void tulip_init_ring(struct net_device *dev); +static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev); +static int tulip_rx(struct net_device *dev); +static void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +static int tulip_close(struct net_device *dev); +static struct net_device_stats *tulip_get_stats(struct net_device *dev); +#ifdef HAVE_PRIVATE_IOCTL +static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +#endif +static void set_rx_mode(struct net_device *dev); + +/* The Xircom cards are picky about when certain bits in CSR6 can be + manipulated. Keith Owens . */ + +static void outl_CSR6 (u32 newcsr6, long ioaddr, int chip_idx) +{ + const int strict_bits = 0x0060e202; + int csr5, csr5_22_20, csr5_19_17, currcsr6, attempts = 200; + long flags; + save_flags(flags); + cli(); + if (chip_idx != X3201_3) { + outl(newcsr6, ioaddr + CSR6); + restore_flags(flags); + return; + } + newcsr6 &= 0x726cfeca; /* mask out the reserved CSR6 bits that always */ + /* read 0 on the Xircom cards */ + newcsr6 |= 0x320c0000; /* or in the reserved bits that always read 1 */ + currcsr6 = inl(ioaddr + CSR6); + if (((newcsr6 & strict_bits) == (currcsr6 & strict_bits)) || + ((currcsr6 & ~0x2002) == 0)) { + outl(newcsr6, ioaddr + CSR6); /* safe */ + restore_flags(flags); + return; + } + /* make sure the transmitter and receiver are stopped first */ + currcsr6 &= ~0x2002; + while (1) { + csr5 = inl(ioaddr + CSR5); + if (csr5 == 0xffffffff) + break; /* cannot read csr5, card removed? */ + csr5_22_20 = csr5 & 0x700000; + csr5_19_17 = csr5 & 0x0e0000; + if ((csr5_22_20 == 0 || csr5_22_20 == 0x600000) && + (csr5_19_17 == 0 || csr5_19_17 == 0x80000 || csr5_19_17 == 0xc0000)) + break; /* both are stopped or suspended */ + if (!--attempts) { + printk(KERN_INFO "tulip.c: outl_CSR6 too many attempts," + "csr5=0x%08x\n", csr5); + outl(newcsr6, ioaddr + CSR6); /* unsafe but do it anyway */ + restore_flags(flags); + return; + } + outl(currcsr6, ioaddr + CSR6); + udelay(1); + } + /* now it is safe to change csr6 */ + outl(newcsr6, ioaddr + CSR6); + restore_flags(flags); +} + +/* A list of all installed Tulip devices. */ +static struct net_device *root_tulip_dev = NULL; + +#ifndef CARDBUS +int tulip_probe(struct net_device *dev) +{ + int cards_found = 0; + int pci_index = 0; + unsigned char pci_bus, pci_device_fn; + + if ( ! pcibios_present()) + return -ENODEV; + + for (;pci_index < 0xff; pci_index++) { + u16 vendor, device, pci_command, new_command; + int chip_idx; + int irq; + long ioaddr; + + if (pcibios_find_class + (PCI_CLASS_NETWORK_ETHERNET << 8, + reverse_probe ? 0xfe - pci_index : pci_index, + &pci_bus, &pci_device_fn) != PCIBIOS_SUCCESSFUL) { + if (reverse_probe) + continue; + else + break; + } + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_VENDOR_ID, &vendor); + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_DEVICE_ID, &device); + + for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++) + if (vendor == pci_tbl[chip_idx].vendor_id + && (device & pci_tbl[chip_idx].device_id_mask) == + pci_tbl[chip_idx].device_id) + break; + if (pci_tbl[chip_idx].vendor_id == 0) + continue; + + { +#if defined(PCI_SUPPORT_VER2) + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); + ioaddr = pdev->base_address[0] & ~3; + irq = pdev->irq; +#elif defined(PCI_SUPPORT_VER3) + struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn); + ioaddr = pdev->resource[0].start; + irq = pdev->irq; +#else + u32 pci_ioaddr; + u8 pci_irq_line; + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_ioaddr); + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq_line); + ioaddr = pci_ioaddr & ~3; + irq = pci_irq_line; +#endif + } + + if (debug > 2) + printk(KERN_INFO "Found %s at PCI I/O address %#lx.\n", + pci_tbl[chip_idx].name, ioaddr); + + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, &pci_command); + new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO; + if (pci_command != new_command) { + printk(KERN_INFO " The PCI BIOS has not enabled the" + " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n", + pci_bus, pci_device_fn, pci_command, new_command); + pcibios_write_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, new_command); + } + + dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr, + irq, chip_idx, cards_found); + + /* Get and check the bus-master and latency values. */ + if (dev) { + u8 pci_latency; + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, &pci_latency); + if (pci_latency < 10) { + printk(KERN_INFO " PCI latency timer (CFLT) is " + "unreasonably low at %d. Setting to 64 clocks.\n", + pci_latency); + pcibios_write_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, 64); + } + } + dev = 0; + cards_found++; + } + + return cards_found ? 0 : -ENODEV; +} +#endif /* not CARDBUS */ + +static struct net_device *tulip_probe1(int pci_bus, int pci_devfn, + struct net_device *dev, long ioaddr, int irq, + int chip_idx, int board_idx) +{ + static int did_version = 0; /* Already printed version info. */ + struct tulip_private *tp; + /* See note below on the multiport cards. */ + static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'}; + static int last_irq = 0; + static int multiport_cnt = 0; /* For four-port boards w/one EEPROM */ + u8 chip_rev; + int i; + unsigned short sum; + + if (tulip_debug > 0 && did_version++ == 0) + printk(KERN_INFO "%s", version); + + dev = init_etherdev(dev, 0); + + pcibios_read_config_byte(pci_bus, pci_devfn, PCI_REVISION_ID, &chip_rev); + /* Bring the 21143 out of sleep mode. + Caution: Snooze mode does not work with some boards! */ + if (tulip_tbl[chip_idx].flags & HAS_ACPI) + pcibios_write_config_dword(pci_bus, pci_devfn, 0x40, 0x00000000); + + printk(KERN_INFO "%s: %s rev %d at %#3lx,", + dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr); + + /* Stop the chip's Tx and Rx processes. */ + outl_CSR6(inl(ioaddr + CSR6) & ~0x2002, ioaddr, chip_idx); + /* Clear the missed-packet counter. */ + (volatile int)inl(ioaddr + CSR8); + + if (chip_idx == DC21041) { + if (inl(ioaddr + CSR9) & 0x8000) { + printk(" 21040 compatible mode,"); + chip_idx = DC21040; + } else { + printk(" 21041 mode,"); + } + } + + /* The station address ROM is read byte serially. The register must + be polled, waiting for the value to be read bit serially from the + EEPROM. + */ + sum = 0; + if (chip_idx == DC21040) { + outl(0, ioaddr + CSR9); /* Reset the pointer with a dummy write. */ + for (i = 0; i < 6; i++) { + int value, boguscnt = 100000; + do + value = inl(ioaddr + CSR9); + while (value < 0 && --boguscnt > 0); + dev->dev_addr[i] = value; + sum += value & 0xff; + } + } else if (chip_idx == LC82C168) { + for (i = 0; i < 3; i++) { + int value, boguscnt = 100000; + outl(0x600 | i, ioaddr + 0x98); + do + value = inl(ioaddr + CSR9); + while (value < 0 && --boguscnt > 0); + put_unaligned(le16_to_cpu(value), ((u16*)dev->dev_addr) + i); + sum += value & 0xffff; + } + } else if (chip_idx == COMET) { + /* No need to read the EEPROM. */ + put_unaligned(inl(ioaddr + 0xA4), (u32 *)dev->dev_addr); + put_unaligned(inl(ioaddr + 0xA8), (u16 *)(dev->dev_addr + 4)); + for (i = 0; i < 6; i ++) + sum += dev->dev_addr[i]; + } else if (chip_idx == X3201_3) { + /* Xircom has its address stored in the CIS + * we access it through the boot rom interface for now + * this might not work, as the CIS is not parsed but I + * (danilo) use the offset I found on my card's CIS !!! + * + * Doug Ledford: I changed this routine around so that it + * walks the CIS memory space, parsing the config items, and + * finds the proper lan_node_id tuple and uses the data + * stored there. + */ + unsigned char j, tuple, link, data_id, data_count; + outl(1<<12, ioaddr + CSR9); /* enable boot rom access */ + for (i = 0x100; i < 0x1f7; i += link+2) { + outl(i, ioaddr + CSR10); + tuple = inl(ioaddr + CSR9) & 0xff; + outl(i + 1, ioaddr + CSR10); + link = inl(ioaddr + CSR9) & 0xff; + outl(i + 2, ioaddr + CSR10); + data_id = inl(ioaddr + CSR9) & 0xff; + outl(i + 3, ioaddr + CSR10); + data_count = inl(ioaddr + CSR9) & 0xff; + if ( (tuple == 0x22) && + (data_id == 0x04) && (data_count == 0x06) ) { + /* + * This is it. We have the data we want. + */ + for (j = 0; j < 6; j++) { + outl(i + j + 4, ioaddr + CSR10); + dev->dev_addr[j] = inl(ioaddr + CSR9) & 0xff; + } + break; + } else if (link == 0) { + break; + } + } + sum = 1; // to make check below fail! + } else { /* Must be a new chip, with a serial EEPROM interface. */ + /* We read the whole EEPROM, and sort it out later. DEC has a + specification _Digital Semiconductor 21X4 Serial ROM Format_ + but early vendor boards just put the address in the first six + EEPROM locations. */ + unsigned char ee_data[EEPROM_SIZE]; + int sa_offset = 0; + + for (i = 0; i < sizeof(ee_data)/2; i++) + ((u16 *)ee_data)[i] = + le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN)); + + /* Detect the simple EEPROM format by the duplicated station addr. */ + for (i = 0; i < 8; i ++) + if (ee_data[i] != ee_data[16+i]) + sa_offset = 20; + if (ee_data[0] == 0xff && ee_data[1] == 0xff && ee_data[2] == 0) { + sa_offset = 2; /* Grrr, damn Matrox boards. */ + multiport_cnt = 4; + } + for (i = 0; i < 6; i ++) { + dev->dev_addr[i] = ee_data[i + sa_offset]; + sum += ee_data[i + sa_offset]; + } + } + /* Lite-On boards have the address byte-swapped. */ + if ((dev->dev_addr[0] == 0xA0 || dev->dev_addr[0] == 0xC0) + && dev->dev_addr[1] == 0x00) + for (i = 0; i < 6; i+=2) { + char tmp = dev->dev_addr[i]; + dev->dev_addr[i] = dev->dev_addr[i+1]; + dev->dev_addr[i+1] = tmp; + } + /* On the Zynx 315 Etherarray and other multiport boards only the + first Tulip has an EEPROM. + The addresses of the subsequent ports are derived from the first. + Many PCI BIOSes also incorrectly report the IRQ line, so we correct + that here as well. */ + if (sum == 0 || sum == 6*0xff) { + printk(" EEPROM not present,"); + for (i = 0; i < 5; i++) + dev->dev_addr[i] = last_phys_addr[i]; + dev->dev_addr[i] = last_phys_addr[i] + 1; +#if defined(__i386__) /* Patch up x86 BIOS bug. */ + if (last_irq) + irq = last_irq; +#endif + } + + for (i = 0; i < 6; i++) + printk("%c%2.2X", i ? ':' : ' ', last_phys_addr[i] = dev->dev_addr[i]); + printk(", IRQ %d.\n", irq); + last_irq = irq; + + /* We do a request_region() only to register /proc/ioports info. */ + /* Note that proper size is tulip_tbl[chip_idx].chip_name, but... */ + request_region(ioaddr, tulip_tbl[chip_idx].io_size, dev->name); + + dev->base_addr = ioaddr; + dev->irq = irq; + + /* Make certain the data structures are quadword aligned. */ + tp = (void *)(((long)kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA) + 7) & ~7); + memset(tp, 0, sizeof(*tp)); + dev->priv = tp; + + tp->next_module = root_tulip_dev; + root_tulip_dev = dev; + + tp->pci_bus = pci_bus; + tp->pci_devfn = pci_devfn; + tp->chip_id = chip_idx; + tp->revision = chip_rev; + tp->csr0 = csr0; + tp->setup_frame = (u16 *)(((unsigned long)tp->setup_buf + 7) & ~7); + + /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles. + And the ASIX must have a burst limit or horrible things happen. */ + if ( (chip_idx == DC21143 && chip_rev == 65) || + (chip_idx == X3201_3) ) + tp->csr0 &= ~0x01000000; + else if (chip_idx == AX88140) + tp->csr0 |= 0x2000; + +#ifdef TULIP_FULL_DUPLEX + tp->full_duplex = 1; + tp->full_duplex_lock = 1; +#endif +#ifdef TULIP_DEFAULT_MEDIA + tp->default_port = TULIP_DEFAULT_MEDIA; +#endif +#ifdef TULIP_NO_MEDIA_SWITCH + tp->medialock = 1; +#endif + + /* The lower four bits are the media type. */ + if (board_idx >= 0 && board_idx < MAX_UNITS) { + tp->default_port = options[board_idx] & 15; + if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0) + tp->full_duplex = 1; + if (mtu[board_idx] > 0) + dev->mtu = mtu[board_idx]; + } + if (dev->mem_start) + tp->default_port = dev->mem_start; + if (tp->default_port) { + tp->medialock = 1; + if (media_cap[tp->default_port] & MediaAlwaysFD) + tp->full_duplex = 1; + } + if (tp->full_duplex) + tp->full_duplex_lock = 1; + + /* This is logically part of probe1(), but too complex to write inline. */ + if (tulip_tbl[chip_idx].flags & HAS_MEDIA_TABLE) + parse_eeprom(dev); + + if (media_cap[tp->default_port] & MediaIsMII) { + u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 }; + tp->to_advertise = media2advert[tp->default_port - 9]; + } else + tp->to_advertise = 0x03e1; + + if ((tulip_tbl[chip_idx].flags & ALWAYS_CHECK_MII) || + (tp->mtable && tp->mtable->has_mii) || + ( ! tp->mtable && (tulip_tbl[chip_idx].flags & HAS_MII))) { + int phy, phy_idx; + if (tp->mtable && tp->mtable->has_mii) { + for (i = 0; i < tp->mtable->leafcount; i++) + if (tp->mtable->mleaf[i].media == 11) { + tp->cur_index = i; + tp->saved_if_port = dev->if_port; + select_media(dev, 1); + dev->if_port = tp->saved_if_port; + break; + } + } + /* Find the connected MII xcvrs. + Doing this in open() would allow detecting external xcvrs later, + but takes much time. */ + for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys); + phy++) { + int mii_status = mdio_read(dev, phy, 1); + if ((mii_status & 0x8301) == 0x8001 || + ((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) { + int mii_reg0 = mdio_read(dev, phy, 0); + int mii_advert = mdio_read(dev, phy, 4); + int reg4 = ((mii_status>>6) & tp->to_advertise) | 1; + tp->phys[phy_idx] = phy; + tp->advertising[phy_idx++] = reg4; + printk(KERN_INFO "%s: MII transceiver #%d " + "config %4.4x status %4.4x advertising %4.4x.\n", + dev->name, phy, mii_reg0, mii_status, mii_advert); + /* Fixup for DLink with miswired PHY. */ + if (mii_advert != reg4) { + printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d," + " previously advertising %4.4x.\n", + dev->name, reg4, phy, mii_advert); + mdio_write(dev, phy, 4, reg4); + } + /* Enable autonegotiation: some boards default to off. */ + mdio_write(dev, phy, 0, mii_reg0 | + (tp->full_duplex ? 0x1100 : 0x1000) | + (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0)); + } + } + tp->mii_cnt = phy_idx; + if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { + printk(KERN_INFO "%s: ***WARNING***: No MII transceiver found!\n", + dev->name); + tp->phys[0] = 1; + } + } + + /* The Tulip-specific entries in the device structure. */ + dev->open = &tulip_open; + dev->hard_start_xmit = &tulip_start_xmit; + dev->stop = &tulip_close; + dev->get_stats = &tulip_get_stats; +#ifdef HAVE_PRIVATE_IOCTL + dev->do_ioctl = &private_ioctl; +#endif +#ifdef HAVE_MULTICAST + dev->set_multicast_list = &set_rx_mode; +#endif + + /* Reset the xcvr interface and turn on heartbeat. */ + switch (chip_idx) { + case DC21041: + outl(0x00000000, ioaddr + CSR13); + outl(0xFFFFFFFF, ioaddr + CSR14); + outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ + outl_CSR6(inl(ioaddr + CSR6) | 0x0200, ioaddr, chip_idx); + outl(0x0000EF05, ioaddr + CSR13); + break; + case DC21040: + outl(0x00000000, ioaddr + CSR13); + outl(0x00000004, ioaddr + CSR13); + break; + case DC21140: default: + if (tp->mtable) + outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); + break; + case DC21142: + case PNIC2: + if (tp->mii_cnt || media_cap[dev->if_port] & MediaIsMII) { + outl_CSR6(0x82020000, ioaddr, chip_idx); + outl(0x0000, ioaddr + CSR13); + outl(0x0000, ioaddr + CSR14); + outl_CSR6(0x820E0000, ioaddr, chip_idx); + } else { + outl_CSR6(0x82420200, ioaddr, chip_idx); + outl(0x0001, ioaddr + CSR13); + outl(0x0003FFFF, ioaddr + CSR14); + outl(0x0008, ioaddr + CSR15); + outl(0x0001, ioaddr + CSR13); + outl(0x1301, ioaddr + CSR12); /* Start NWay. */ + } + break; + case X3201_3: + outl(0x0008, ioaddr + CSR15); + udelay(5); /* The delays are Xircom recommended to give the + * chipset time to reset the actual hardware + * on the PCMCIA card + */ + outl(0xa8050000, ioaddr + CSR15); + udelay(5); + outl(0xa00f0000, ioaddr + CSR15); + udelay(5); + outl_CSR6(0x32000200, ioaddr, chip_idx); + break; + case LC82C168: + if ( ! tp->mii_cnt) { + outl_CSR6(0x00420000, ioaddr, chip_idx); + outl(0x30, ioaddr + CSR12); + outl(0x0001F078, ioaddr + 0xB8); + outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */ + } + break; + case MX98713: case COMPEX9881: + outl_CSR6(0x00000000, ioaddr, chip_idx); + outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */ + outl(0x00000001, ioaddr + CSR13); + break; + case MX98715: case MX98725: + outl_CSR6(0x01a80000, ioaddr, chip_idx); + outl(0xFFFFFFFF, ioaddr + CSR14); + outl(0x00001000, ioaddr + CSR12); + break; + case COMET: + /* No initialization necessary. */ + break; + } + + return dev; +} + +/* Serial EEPROM section. */ +/* The main routine to parse the very complicated SROM structure. + Search www.digital.com for "21X4 SROM" to get details. + This code is very complex, and will require changes to support + additional cards, so I'll be verbose about what is going on. + */ + +/* Known cards that have old-style EEPROMs. */ +static struct fixups { + char *name; + unsigned char addr0, addr1, addr2; + u16 newtable[32]; /* Max length below. */ +} eeprom_fixups[] = { + {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c, + 0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }}, + {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x021f, + 0x0000, 0x009E, /* 10baseT */ + 0x0903, 0x006D, /* 100baseTx */ }}, + {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x033f, + 0x0107, 0x8021, /* 100baseFx */ + 0x0108, 0x8021, /* 100baseFx-FD */ + 0x0103, 0x006D, /* 100baseTx */ }}, + {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0313, + 0x1001, 0x009E, /* 10base2, CSR12 0x10*/ + 0x0000, 0x009E, /* 10baseT */ + 0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */ }}, + {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x031F, + 0x1B01, 0x0000, /* 10base2, CSR12 0x1B */ + 0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */ + 0x0B00, 0x009E, /* 10baseT, CSR12 0x0B */ + }}, + {0, 0, 0, 0, {}}}; + +static const char * block_name[] = {"21140 non-MII", "21140 MII PHY", + "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"}; + +#if defined(__i386__) /* AKA get_unaligned() */ +#define get_u16(ptr) (*(u16 *)(ptr)) +#else +#define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8)) +#endif + +static void parse_eeprom(struct net_device *dev) +{ + /* The last media info list parsed, for multiport boards. */ + static struct mediatable *last_mediatable = NULL; + static unsigned char *last_ee_data = NULL; + static int controller_index = 0; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + unsigned char *ee_data = tp->eeprom; + int i; +#ifdef CARDBUS + int chip_rev = tp->revision; +#endif + + tp->mtable = 0; + for (i = 0; i < EEPROM_SIZE/2; i++) + ((u16 *)ee_data)[i] = + le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN)); + + /* Detect an old-style (SA only) EEPROM layout: + memcmp(eedata, eedata+16, 8). */ + for (i = 0; i < 8; i ++) + if (ee_data[i] != ee_data[16+i]) + break; + if (i >= 8) { + if (ee_data[0] == 0xff) { + if (last_mediatable) { + controller_index++; + printk(KERN_INFO "%s: Controller %d of multiport board.\n", + dev->name, controller_index); + tp->mtable = last_mediatable; + ee_data = last_ee_data; + goto subsequent_board; + } else + printk(KERN_INFO "%s: Missing EEPROM, this interface may " + "not work correctly!\n", + dev->name); + return; + } + /* Do a fix-up based on the vendor half of the station address prefix. */ + for (i = 0; eeprom_fixups[i].name; i++) { + if (dev->dev_addr[0] == eeprom_fixups[i].addr0 + && dev->dev_addr[1] == eeprom_fixups[i].addr1 + && dev->dev_addr[2] == eeprom_fixups[i].addr2) { + if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55) + i++; /* An Accton EN1207, not an outlaw Maxtech. */ + memcpy(ee_data + 26, eeprom_fixups[i].newtable, + sizeof(eeprom_fixups[i].newtable)); + printk(KERN_INFO "%s: Old format EEPROM on '%s' board. Using" + " substitute media control info.\n", + dev->name, eeprom_fixups[i].name); + break; + } + } + if (eeprom_fixups[i].name == NULL) { /* No fixup found. */ + printk(KERN_INFO "%s: Old style EEPROM with no media selection " + "information.\n", + dev->name); + return; + } + } + + controller_index = 0; + if (ee_data[19] > 1) { /* Multiport board. */ + last_ee_data = ee_data; + } +subsequent_board: + + if (ee_data[27] == 0) { /* No valid media table. */ + } else if (tp->chip_id == DC21041) { + unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3]; + short media; + int count; + + media = get_u16(p); + p += 2; + count = *p++; + + printk(KERN_INFO "%s:21041 Media information at %d, default media " + "%4.4x (%s).\n", dev->name, ee_data[27], media, + media & 0x0800 ? "Autosense" : medianame[media & 15]); + for (i = 0; i < count; i++) { + unsigned char media_code = *p++; + u16 csrvals[3]; + int idx; + for (idx = 0; idx < 3; idx++) { + csrvals[idx] = get_u16(p); + p += 2; + } + if (media_code & 0x40) { + printk(KERN_INFO "%s: 21041 media %2.2x (%s)," + " csr13 %4.4x csr14 %4.4x csr15 %4.4x.\n", + dev->name, media_code & 15, medianame[media_code & 15], + csrvals[0], csrvals[1], csrvals[2]); + } else + printk(KERN_INFO "%s: 21041 media #%d, %s.\n", + dev->name, media_code & 15, medianame[media_code & 15]); + } + } else { + unsigned char *p = (void *)ee_data + ee_data[27]; + unsigned char csr12dir = 0; + int count; + struct mediatable *mtable; + u16 media = get_u16(p); + + p += 2; + if (tulip_tbl[tp->chip_id].flags & CSR12_IN_SROM) + csr12dir = *p++; + count = *p++; + mtable = (struct mediatable *) + kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf), + GFP_KERNEL); + if (mtable == NULL) + return; /* Horrible, impossible failure. */ + last_mediatable = tp->mtable = mtable; + mtable->defaultmedia = media; + mtable->leafcount = count; + mtable->csr12dir = csr12dir; + mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0; + mtable->csr15dir = mtable->csr15val = 0; + + printk(KERN_INFO "%s: EEPROM default media type %s.\n", dev->name, + media & 0x0800 ? "Autosense" : medianame[media & 15]); + for (i = 0; i < count; i++) { + struct medialeaf *leaf = &mtable->mleaf[i]; + + if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */ + leaf->type = 0; + leaf->media = p[0] & 0x3f; + leaf->leafdata = p; + if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */ + mtable->has_mii = 1; + p += 4; + } else { + leaf->type = p[1]; + if (p[1] == 0x05) { + mtable->has_reset = i; + leaf->media = p[2] & 0x0f; + } else if (p[1] & 1) { + mtable->has_mii = 1; + leaf->media = 11; + } else { + mtable->has_nonmii = 1; + leaf->media = p[2] & 0x0f; + if (p[1] == 2) { + if (leaf->media == 0) { + mtable->csr15dir = get_unaligned((u16*)&p[3])<<16; + mtable->csr15val = get_unaligned((u16*)&p[5])<<16; + } else if (leaf->media == 0x40) { + u32 base15 = get_unaligned((u16*)&p[7]); + mtable->csr15dir = + (get_unaligned((u16*)&p[9])<<16) + base15; + mtable->csr15val = + (get_unaligned((u16*)&p[11])<<16) + base15; + } + } + } + leaf->leafdata = p + 2; + p += (p[0] & 0x3f) + 1; + } + if (tulip_debug > 1 && leaf->media == 11) { + unsigned char *bp = leaf->leafdata; + printk(KERN_INFO "%s: MII interface PHY %d, setup/reset " + "sequences %d/%d long, capabilities %2.2x %2.2x.\n", + dev->name, bp[0], bp[1], bp[1 + bp[1]*2], + bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]); + } + printk(KERN_INFO "%s: Index #%d - Media %s (#%d) described " + "by a %s (%d) block.\n", + dev->name, i, medianame[leaf->media], leaf->media, + block_name[leaf->type], leaf->type); + } + } +} +/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/ + +/* EEPROM_Ctrl bits. */ +#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */ +#define EE_CS 0x01 /* EEPROM chip select. */ +#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ +#define EE_WRITE_0 0x01 +#define EE_WRITE_1 0x05 +#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ +#define EE_ENB (0x4800 | EE_CS) + +/* Delay between EEPROM clock transitions. + Even at 33Mhz current PCI implementations don't overrun the EEPROM clock. + We add a bus turn-around to insure that this remains true. */ +#define eeprom_delay() inl(ee_addr) + +/* The EEPROM commands include the alway-set leading bit. */ +#define EE_WRITE_CMD (5 << addr_len) +#define EE_READ_CMD (6 << addr_len) +#define EE_ERASE_CMD (7 << addr_len) + +static int read_eeprom(long ioaddr, int location, int addr_len) +{ + int i; + unsigned short retval = 0; + long ee_addr = ioaddr + CSR9; + int read_cmd = location | EE_READ_CMD; + + outl(EE_ENB & ~EE_CS, ee_addr); + outl(EE_ENB, ee_addr); + + /* Shift the read command bits out. */ + for (i = 4 + addr_len; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + outl(EE_ENB | dataval, ee_addr); + eeprom_delay(); + outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(); + } + outl(EE_ENB, ee_addr); + + for (i = 16; i > 0; i--) { + outl(EE_ENB | EE_SHIFT_CLK, ee_addr); + eeprom_delay(); + retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); + outl(EE_ENB, ee_addr); + eeprom_delay(); + } + + /* Terminate the EEPROM access. */ + outl(EE_ENB & ~EE_CS, ee_addr); + return retval; +} + +/* MII transceiver control section. + Read and write the MII registers using software-generated serial + MDIO protocol. See the MII specifications or DP83840A data sheet + for details. */ + +/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually + met by back-to-back PCI I/O cycles, but we insert a delay to avoid + "overclocking" issues or future 66Mhz PCI. */ +#define mdio_delay() inl(mdio_addr) + +/* Read and write the MII registers using software-generated serial + MDIO protocol. It is just different enough from the EEPROM protocol + to not share code. The maxium data clock rate is 2.5 Mhz. */ +#define MDIO_SHIFT_CLK 0x10000 +#define MDIO_DATA_WRITE0 0x00000 +#define MDIO_DATA_WRITE1 0x20000 +#define MDIO_ENB 0x00000 /* Ignore the 0x02000 databook setting. */ +#define MDIO_ENB_IN 0x40000 +#define MDIO_DATA_READ 0x80000 + +static int mdio_read(struct net_device *dev, int phy_id, int location) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int i; + int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; + int retval = 0; + long ioaddr = dev->base_addr; + long mdio_addr = ioaddr + CSR9; + + if (tp->chip_id == LC82C168) { + int i = 1000; + outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0); + inl(ioaddr + 0xA0); + inl(ioaddr + 0xA0); + while (--i > 0) + if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000)) + return retval & 0xffff; + return 0xffff; + } + + if (tp->chip_id == COMET) { + if (phy_id == 1) { + if (location < 7) + return inl(ioaddr + 0xB4 + (location<<2)); + else if (location == 17) + return inl(ioaddr + 0xD0); + else if (location >= 29 && location <= 31) + return inl(ioaddr + 0xD4 + ((location-29)<<2)); + } + return 0xffff; + } + + /* Establish sync by sending at least 32 logic ones. */ + for (i = 32; i >= 0; i--) { + outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); + mdio_delay(); + outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + /* Shift the read command bits out. */ + for (i = 15; i >= 0; i--) { + int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; + + outl(MDIO_ENB | dataval, mdio_addr); + mdio_delay(); + outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + /* Read the two transition, 16 data, and wire-idle bits. */ + for (i = 19; i > 0; i--) { + outl(MDIO_ENB_IN, mdio_addr); + mdio_delay(); + retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); + outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + return (retval>>1) & 0xffff; +} + +static void mdio_write(struct net_device *dev, int phy_id, int location, int value) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int i; + int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value; + long ioaddr = dev->base_addr; + long mdio_addr = ioaddr + CSR9; + + if (tp->chip_id == LC82C168) { + int i = 1000; + outl(cmd, ioaddr + 0xA0); + do + if ( ! (inl(ioaddr + 0xA0) & 0x80000000)) + break; + while (--i > 0); + return; + } + + if (tp->chip_id == COMET) { + if (phy_id != 1) + return; + if (location < 7) + outl(value, ioaddr + 0xB4 + (location<<2)); + else if (location == 17) + outl(value, ioaddr + 0xD0); + else if (location >= 29 && location <= 31) + outl(value, ioaddr + 0xD4 + ((location-29)<<2)); + return; + } + + /* Establish sync by sending 32 logic ones. */ + for (i = 32; i >= 0; i--) { + outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); + mdio_delay(); + outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + /* Shift the command bits out. */ + for (i = 31; i >= 0; i--) { + int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; + outl(MDIO_ENB | dataval, mdio_addr); + mdio_delay(); + outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + /* Clear out extra bits. */ + for (i = 2; i > 0; i--) { + outl(MDIO_ENB_IN, mdio_addr); + mdio_delay(); + outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); + mdio_delay(); + } + return; +} + +static void +tulip_up(struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int i; + + /* On some chip revs we must set the MII/SYM port before the reset!? */ + if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) + outl_CSR6(0x00040000, ioaddr, tp->chip_id); + + /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */ + outl(0x00000001, ioaddr + CSR0); + + /* Deassert reset. */ + outl(tp->csr0, ioaddr + CSR0); + udelay(2); + + /* Clear the tx ring */ + for (i = 0; i < TX_RING_SIZE; i++) { + tp->tx_skbuff[i] = 0; + tp->tx_ring[i].status = 0x00000000; + } + + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: tulip_open() irq %d.\n", dev->name, dev->irq); + + if (tulip_tbl[tp->chip_id].flags & MC_HASH_ONLY) { + u32 addr_low = cpu_to_le32(get_unaligned((u32 *)dev->dev_addr)); + u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(dev->dev_addr+4))); + if (tp->chip_id == AX88140) { + outl(0, ioaddr + CSR13); + outl(addr_low, ioaddr + CSR14); + outl(1, ioaddr + CSR13); + outl(addr_high, ioaddr + CSR14); + } else if (tp->chip_id == COMET) { + outl(addr_low, ioaddr + 0xA4); + outl(addr_high, ioaddr + 0xA8); + outl(0, ioaddr + 0xAC); + outl(0, ioaddr + 0xB0); + } + } else if (tp->chip_id != X3201_3) { + /* This is set_rx_mode(), but without starting the transmitter. */ + u16 *eaddrs = (u16 *)dev->dev_addr; + u16 *setup_frm = &tp->setup_frame[15*6]; + + /* 21140 bug: you must add the broadcast address. */ + memset(tp->setup_frame, 0xff, 96*sizeof(u16)); + /* Fill the final entry of the table with our physical address. */ + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; + /* Put the setup frame on the Tx list. */ + tp->tx_ring[0].length = 0x08000000 | 192; + tp->tx_ring[0].buffer1 = virt_to_bus(tp->setup_frame); + tp->tx_ring[0].status = DescOwned; + + tp->cur_tx++; + } else { /* X3201_3 */ + u16 *eaddrs = (u16 *)dev->dev_addr; + u16 *setup_frm = &tp->setup_frame[0*6]; + + /* fill the table with the broadcast address */ + memset(tp->setup_frame, 0xff, 96*sizeof(u16)); + /* re-fill the first 14 table entries with our address */ + for(i=0; i<14; i++) { + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; + } + + /* Put the setup frame on the Tx list. */ + tp->tx_ring[0].length = 0x08000000 | 192; + /* Lie about the address of our setup frame to make the */ + /* chip happy */ + tp->tx_ring[0].buffer1 = (virt_to_bus(tp->setup_frame) + 4); + tp->tx_ring[0].status = DescOwned; + + tp->cur_tx++; + } + outl(virt_to_bus(tp->rx_ring), ioaddr + CSR3); + outl(virt_to_bus(tp->tx_ring), ioaddr + CSR4); + + tp->saved_if_port = dev->if_port; + if (dev->if_port == 0) + dev->if_port = tp->default_port; + if (tp->chip_id == DC21041 && dev->if_port > 4) + /* Invalid: Select initial TP, autosense, autonegotiate. */ + dev->if_port = 4; + + /* Allow selecting a default media. */ + i = 0; + if (tp->mtable == NULL) + goto media_picked; + if (dev->if_port) { + int looking_for = media_cap[dev->if_port] & MediaIsMII ? 11 : + (dev->if_port == 12 ? 0 : dev->if_port); + for (i = 0; i < tp->mtable->leafcount; i++) + if (tp->mtable->mleaf[i].media == looking_for) { + printk(KERN_INFO "%s: Using user-specified media %s.\n", + dev->name, medianame[dev->if_port]); + goto media_picked; + } + } + if ((tp->mtable->defaultmedia & 0x0800) == 0) { + int looking_for = tp->mtable->defaultmedia & 15; + for (i = 0; i < tp->mtable->leafcount; i++) + if (tp->mtable->mleaf[i].media == looking_for) { + printk(KERN_INFO "%s: Using EEPROM-set media %s.\n", + dev->name, medianame[looking_for]); + goto media_picked; + } + } + /* Start sensing first non-full-duplex media. */ + for (i = tp->mtable->leafcount - 1; + (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) + ; +media_picked: + + tp->csr6 = 0; + tp->cur_index = i; + if (dev->if_port == 0 && tp->chip_id == DC21142) { + if (tp->mii_cnt) { + select_media(dev, 1); + if (tulip_debug > 1) + printk(KERN_INFO "%s: Using MII transceiver %d, status " + "%4.4x.\n", + dev->name, tp->phys[0], mdio_read(dev, tp->phys[0], 1)); + outl_CSR6(0x82020000, ioaddr, tp->chip_id); + tp->csr6 = 0x820E0000; + dev->if_port = 11; + outl(0x0000, ioaddr + CSR13); + outl(0x0000, ioaddr + CSR14); + } else + t21142_start_nway(dev); + } else if ((tp->chip_id == LC82C168 || tp->chip_id == PNIC2) + && tp->mii_cnt && ! tp->medialock) { + dev->if_port = 11; + tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0); + outl(0x0001, ioaddr + CSR15); + } else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) + && ! tp->medialock) { + dev->if_port = 0; + tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0); + outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); + } else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) { + /* Provided by BOLO, Macronix - 12/10/1998. */ + dev->if_port = 0; + tp->csr6 = 0x01880200; + outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); + outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); + } else if (tp->chip_id == DC21143 && + media_cap[dev->if_port] & MediaIsMII) { + /* We must reset the media CSRs when we force-select MII mode. */ + outl(0x0000, ioaddr + CSR13); + outl(0x0000, ioaddr + CSR14); + outl(0x0008, ioaddr + CSR15); + } else if (tp->chip_id == X3201_3) { + outl(0x0008, ioaddr + CSR15); + udelay(5); + outl(0xa8050000, ioaddr + CSR15); + udelay(5); + outl(0xa00f0000, ioaddr + CSR15); + udelay(5); + tp->csr6 = 0x32400000; + } else if (tp->chip_id == COMET) { + dev->if_port = 0; + tp->csr6 = 0x00040000; + } else + select_media(dev, 1); + + /* Start the chip's Tx to process setup frame. */ + outl_CSR6(tp->csr6, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2000, ioaddr, tp->chip_id); + + dev->tbusy = 0; + tp->interrupt = 0; + dev->start = 1; + + /* Enable interrupts by setting the interrupt mask. */ + outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5); + outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + outl(0, ioaddr + CSR2); /* Rx poll demand */ + + if (tulip_debug > 2) { + printk(KERN_DEBUG "%s: Done tulip_open(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n", + dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5), + inl(ioaddr + CSR6)); + } + /* Set the timer to switch to check for link beat and perhaps switch + to an alternate media type. */ + init_timer(&tp->timer); + tp->timer.expires = RUN_AT(5*HZ); + tp->timer.data = (unsigned long)dev; + tp->timer.function = tulip_tbl[tp->chip_id].media_timer; + add_timer(&tp->timer); +} + +static int +tulip_open(struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + + if (request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev)) + return -EAGAIN; + + tulip_init_ring(dev); + + tulip_up(dev); + tp->open = 1; + MOD_INC_USE_COUNT; + + return 0; +} + +/* Set up the transceiver control registers for the selected media type. */ +static void select_media(struct net_device *dev, int startup) +{ + long ioaddr = dev->base_addr; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + struct mediatable *mtable = tp->mtable; + u32 new_csr6; + int i; + + if (mtable) { + struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index]; + unsigned char *p = mleaf->leafdata; + switch (mleaf->type) { + case 0: /* 21140 non-MII xcvr. */ + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver" + " with control setting %2.2x.\n", + dev->name, p[1]); + dev->if_port = p[0]; + if (startup) + outl(mtable->csr12dir | 0x100, ioaddr + CSR12); + outl(p[1], ioaddr + CSR12); + new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18); + break; + case 2: case 4: { + u16 setup[5]; + u32 csr13val, csr14val, csr15dir, csr15val; + for (i = 0; i < 5; i++) + setup[i] = get_u16(&p[i*2 + 1]); + + dev->if_port = p[0] & 15; + if (media_cap[dev->if_port] & MediaAlwaysFD) + tp->full_duplex = 1; + + if (startup && mtable->has_reset) { + struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; + unsigned char *rst = rleaf->leafdata; + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Resetting the transceiver.\n", + dev->name); + for (i = 0; i < rst[0]; i++) + outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15); + } + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control " + "%4.4x/%4.4x.\n", + dev->name, medianame[dev->if_port], setup[0], setup[1]); + if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */ + csr13val = setup[0]; + csr14val = setup[1]; + csr15dir = (setup[3]<<16) | setup[2]; + csr15val = (setup[4]<<16) | setup[2]; + outl(0, ioaddr + CSR13); + outl(csr14val, ioaddr + CSR14); + outl(csr15dir, ioaddr + CSR15); /* Direction */ + outl(csr15val, ioaddr + CSR15); /* Data */ + outl(csr13val, ioaddr + CSR13); + } else { + csr13val = 1; + csr14val = 0x0003FF7F; + csr15dir = (setup[0]<<16) | 0x0008; + csr15val = (setup[1]<<16) | 0x0008; + if (dev->if_port <= 4) + csr14val = t21142_csr14[dev->if_port]; + if (startup) { + outl(0, ioaddr + CSR13); + outl(csr14val, ioaddr + CSR14); + } + outl(csr15dir, ioaddr + CSR15); /* Direction */ + outl(csr15val, ioaddr + CSR15); /* Data */ + if (startup) outl(csr13val, ioaddr + CSR13); + } + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Setting CSR15 to %8.8x/%8.8x.\n", + dev->name, csr15dir, csr15val); + if (mleaf->type == 4) + new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18); + else + new_csr6 = 0x82420000; + break; + } + case 1: case 3: { + int phy_num = p[0]; + int init_length = p[1]; + u16 *misc_info; + u16 to_advertise; + + dev->if_port = 11; + new_csr6 = 0x020E0000; + if (mleaf->type == 3) { /* 21142 */ + u16 *init_sequence = (u16*)(p+2); + u16 *reset_sequence = &((u16*)(p+3))[init_length]; + int reset_length = p[2 + init_length*2]; + misc_info = reset_sequence + reset_length; + if (startup) + for (i = 0; i < reset_length; i++) + outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); + for (i = 0; i < init_length; i++) + outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); + } else { + u8 *init_sequence = p + 2; + u8 *reset_sequence = p + 3 + init_length; + int reset_length = p[2 + init_length]; + misc_info = (u16*)(reset_sequence + reset_length); + if (startup) { + outl(mtable->csr12dir | 0x100, ioaddr + CSR12); + for (i = 0; i < reset_length; i++) + outl(reset_sequence[i], ioaddr + CSR12); + } + for (i = 0; i < init_length; i++) + outl(init_sequence[i], ioaddr + CSR12); + } + to_advertise = (get_u16(&misc_info[1]) & tp->to_advertise) | 1; + tp->advertising[phy_num] = to_advertise; + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d (%d).\n", + dev->name, to_advertise, phy_num, tp->phys[phy_num]); + /* Bogus: put in by a committee? */ + mdio_write(dev, tp->phys[phy_num], 4, to_advertise); + break; + } + default: + printk(KERN_DEBUG "%s: Invalid media table selection %d.\n", + dev->name, mleaf->type); + new_csr6 = 0x020E0000; + } + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n", + dev->name, medianame[dev->if_port], + inl(ioaddr + CSR12) & 0xff); + } else if (tp->chip_id == DC21041) { + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: 21041 using media %s, CSR12 is %4.4x.\n", + dev->name, medianame[dev->if_port & 15], + inl(ioaddr + CSR12) & 0xffff); + outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ + outl(t21041_csr14[dev->if_port], ioaddr + CSR14); + outl(t21041_csr15[dev->if_port], ioaddr + CSR15); + outl(t21041_csr13[dev->if_port], ioaddr + CSR13); + new_csr6 = 0x80020000; + } else if (tp->chip_id == LC82C168 || tp->chip_id == PNIC2) { + if (startup && ! tp->medialock) + dev->if_port = tp->mii_cnt ? 11 : 0; + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, CSR12 %4.4x," + " media %s.\n", + dev->name, inl(ioaddr + 0xB8), inl(ioaddr + CSR12), + medianame[dev->if_port]); + if (tp->mii_cnt) { + new_csr6 = 0x810C0000; + outl(0x0001, ioaddr + CSR15); + outl(0x0201B07A, ioaddr + 0xB8); + } else if (startup) { + /* Start with 10mbps to do autonegotiation. */ + outl(0x32, ioaddr + CSR12); + new_csr6 = 0x00420000; + outl(0x0001B078, ioaddr + 0xB8); + outl(0x0201B078, ioaddr + 0xB8); + } else if (dev->if_port == 3 || dev->if_port == 5) { + outl(0x33, ioaddr + CSR12); + new_csr6 = 0x01860000; + if (startup) + outl(0x0201F868, ioaddr + 0xB8); /* Trigger autonegotiation. */ + else + outl(0x1F868, ioaddr + 0xB8); + } else { + outl(0x32, ioaddr + CSR12); + new_csr6 = 0x00420000; + outl(0x1F078, ioaddr + 0xB8); + } + } else if (tp->chip_id == DC21040) { /* 21040 */ + /* Turn on the xcvr interface. */ + int csr12 = inl(ioaddr + CSR12); + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: 21040 media type is %s, CSR12 is %2.2x.\n", + dev->name, medianame[dev->if_port], csr12); + if (media_cap[dev->if_port] & MediaAlwaysFD) + tp->full_duplex = 1; + new_csr6 = 0x20000; + /* Set the full duplux match frame. */ + outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11); + outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */ + if (t21040_csr13[dev->if_port] & 8) { + outl(0x0705, ioaddr + CSR14); + outl(0x0006, ioaddr + CSR15); + } else { + outl(0xffff, ioaddr + CSR14); + outl(0x0000, ioaddr + CSR15); + } + outl(0x8f01 | t21040_csr13[dev->if_port], ioaddr + CSR13); + } else if (tp->chip_id == X3201_3) { /* Xircom */ + if (tp->default_port == 0) + dev->if_port = tp->mii_cnt ? 11 : 3; +/* Someone is on crack, the Xircom only does MII, no Fx */ +/* if (media_cap[dev->if_port] & MediaIsMII) { + new_csr6 = 0x020E0000; + } else if (media_cap[dev->if_port] & MediaIsFx) { + new_csr6 = 0x028600000; + } else + new_csr6 = 0x038600000;*/ + new_csr6 = 0x324c0000; + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Xircom CardBus Adapter: " + "%s transceiver, CSR12 %2.2x.\n", + dev->name, medianame[dev->if_port], + inl(ioaddr + CSR12)); + } else { /* Unknown chip type with no media table. */ + if (tp->default_port == 0) + dev->if_port = tp->mii_cnt ? 11 : 3; + if (media_cap[dev->if_port] & MediaIsMII) { + new_csr6 = 0x020E0000; + } else if (media_cap[dev->if_port] & MediaIsFx) { + new_csr6 = 0x028600000; + } else + new_csr6 = 0x038600000; + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: No media description table, assuming " + "%s transceiver, CSR12 %2.2x.\n", + dev->name, medianame[dev->if_port], + inl(ioaddr + CSR12)); + } + + tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0); + return; +} + +/* + Check the MII negotiated duplex, and change the CSR6 setting if + required. + Return 0 if everything is OK. + Return < 0 if the transceiver is missing or has no link beat. + */ +static int check_duplex(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int mii_reg1, mii_reg5, negotiated, duplex; + + if (tp->full_duplex_lock) + return 0; + mii_reg1 = mdio_read(dev, tp->phys[0], 1); + mii_reg5 = mdio_read(dev, tp->phys[0], 5); + if (tulip_debug > 1) + printk(KERN_INFO "%s: MII status %4.4x, Link partner report " + "%4.4x.\n", dev->name, mii_reg1, mii_reg5); + if (mii_reg1 == 0xffff) + return -2; + if ((mii_reg1 & 0x0004) == 0) { + int new_reg1 = mdio_read(dev, tp->phys[0], 1); + if ((new_reg1 & 0x0004) == 0) { + if (tulip_debug > 1) + printk(KERN_INFO "%s: No link beat on the MII interface," + " status %4.4x.\n", dev->name, new_reg1); + return -1; + } + } + negotiated = mii_reg5 & tp->advertising[0]; + duplex = ((negotiated & 0x0300) == 0x0100 + || (negotiated & 0x00C0) == 0x0040); + /* 100baseTx-FD or 10T-FD, but not 100-HD */ + if (tp->full_duplex != duplex) { + tp->full_duplex = duplex; + if (tp->full_duplex) tp->csr6 |= 0x0200; + else tp->csr6 &= ~0x0200; + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + if (tulip_debug > 0) + printk(KERN_INFO "%s: Setting %s-duplex based on MII" + "#%d link partner capability of %4.4x.\n", + dev->name, tp->full_duplex ? "full" : "half", + tp->phys[0], mii_reg5); + } + return 0; +} + +static void tulip_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + u32 csr12 = inl(ioaddr + CSR12); + int next_tick = 2*HZ; + + if (tulip_debug > 2) { + printk(KERN_DEBUG "%s: Media selection tick, status %8.8x mode %8.8x " + "SIA %8.8x %8.8x %8.8x %8.8x.\n", + dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR6), + csr12, inl(ioaddr + CSR13), + inl(ioaddr + CSR14), inl(ioaddr + CSR15)); + } + switch (tp->chip_id) { + case DC21040: + if (!tp->medialock && csr12 & 0x0002) { /* Network error */ + printk(KERN_INFO "%s: No link beat found.\n", + dev->name); + dev->if_port = (dev->if_port == 2 ? 0 : 2); + select_media(dev, 0); + dev->trans_start = jiffies; + } + break; + case DC21041: + if (tulip_debug > 2) + printk(KERN_DEBUG "%s: 21041 media tick CSR12 %8.8x.\n", + dev->name, csr12); + switch (dev->if_port) { + case 0: case 3: case 4: + if (csr12 & 0x0004) { /*LnkFail */ + /* 10baseT is dead. Check for activity on alternate port. */ + tp->mediasense = 1; + if (csr12 & 0x0200) + dev->if_port = 2; + else + dev->if_port = 1; + printk(KERN_INFO "%s: No 21041 10baseT link beat, Media switched to %s.\n", + dev->name, medianame[dev->if_port]); + outl(0, ioaddr + CSR13); /* Reset */ + outl(t21041_csr14[dev->if_port], ioaddr + CSR14); + outl(t21041_csr15[dev->if_port], ioaddr + CSR15); + outl(t21041_csr13[dev->if_port], ioaddr + CSR13); + next_tick = 10*HZ; /* 2.4 sec. */ + } else + next_tick = 30*HZ; + break; + case 1: /* 10base2 */ + case 2: /* AUI */ + if (csr12 & 0x0100) { + next_tick = (30*HZ); /* 30 sec. */ + tp->mediasense = 0; + } else if ((csr12 & 0x0004) == 0) { + printk(KERN_INFO "%s: 21041 media switched to 10baseT.\n", + dev->name); + dev->if_port = 0; + select_media(dev, 0); + next_tick = (24*HZ)/10; /* 2.4 sec. */ + } else if (tp->mediasense || (csr12 & 0x0002)) { + dev->if_port = 3 - dev->if_port; /* Swap ports. */ + select_media(dev, 0); + next_tick = 20*HZ; + } else { + next_tick = 20*HZ; + } + break; + } + break; + case DC21140: case DC21142: case MX98713: case COMPEX9881: default: { + struct medialeaf *mleaf; + unsigned char *p; + if (tp->mtable == NULL) { /* No EEPROM info, use generic code. */ + /* Not much that can be done. + Assume this a generic MII or SYM transceiver. */ + next_tick = 60*HZ; + if (tulip_debug > 2) + printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x " + "CSR12 0x%2.2x.\n", + dev->name, inl(ioaddr + CSR6), csr12 & 0xff); + break; + } + mleaf = &tp->mtable->mleaf[tp->cur_index]; + p = mleaf->leafdata; + switch (mleaf->type) { + case 0: case 4: { + /* Type 0 serial or 4 SYM transceiver. Check the link beat bit. */ + int offset = mleaf->type == 4 ? 5 : 2; + s8 bitnum = p[offset]; + if (p[offset+1] & 0x80) { + if (tulip_debug > 1) + printk(KERN_DEBUG"%s: Transceiver monitor tick " + "CSR12=%#2.2x, no media sense.\n", + dev->name, csr12); + if (mleaf->type == 4) { + if (mleaf->media == 3 && (csr12 & 0x02)) + goto select_next_media; + } + break; + } + if (tulip_debug > 2) + printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x" + " bit %d is %d, expecting %d.\n", + dev->name, csr12, (bitnum >> 1) & 7, + (csr12 & (1 << ((bitnum >> 1) & 7))) != 0, + (bitnum >= 0)); + /* Check that the specified bit has the proper value. */ + if ((bitnum < 0) != + ((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) { + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name, + medianame[mleaf->media]); + if ((p[2] & 0x61) == 0x01) /* Bogus Znyx board. */ + goto actually_mii; + break; + } + if (tp->medialock) + break; + select_next_media: + if (--tp->cur_index < 0) { + /* We start again, but should instead look for default. */ + tp->cur_index = tp->mtable->leafcount - 1; + } + dev->if_port = tp->mtable->mleaf[tp->cur_index].media; + if (media_cap[dev->if_port] & MediaIsFD) + goto select_next_media; /* Skip FD entries. */ + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: No link beat on media %s," + " trying transceiver type %s.\n", + dev->name, medianame[mleaf->media & 15], + medianame[tp->mtable->mleaf[tp->cur_index].media]); + select_media(dev, 0); + /* Restart the transmit process. */ + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + next_tick = (24*HZ)/10; + break; + } + case 1: case 3: /* 21140, 21142 MII */ + actually_mii: + check_duplex(dev); + next_tick = 60*HZ; + break; + case 2: /* 21142 serial block has no link beat. */ + default: + break; + } + } + break; + } + tp->timer.expires = RUN_AT(next_tick); + add_timer(&tp->timer); +} + +/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list + of available transceivers. */ +static void t21142_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int csr12 = inl(ioaddr + CSR12); + int next_tick = 60*HZ; + int new_csr6 = 0; + + if ((tulip_debug > 2) && !(media_cap[dev->if_port] & MediaIsMII)) + printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n", + dev->name, csr12, medianame[dev->if_port]); + if (media_cap[dev->if_port] & MediaIsMII) { + check_duplex(dev); + next_tick = 60*HZ; + } else if (tp->nwayset) { + /* Don't screw up a negotiated session! */ + if (tulip_debug > 1) + printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n", + dev->name, medianame[dev->if_port], csr12); + } else if (tp->medialock) { + ; + } else if (dev->if_port == 3) { + if (csr12 & 2) { /* No 100mbps link beat, revert to 10mbps. */ + if (tulip_debug > 1) + printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, " + "trying NWay.\n", dev->name, csr12); + t21142_start_nway(dev); + next_tick = 3*HZ; + } + } else if (((csr12 & 0x7000) != 0x5000) + && tp->chip_id != X3201_3) { + /* Negotiation failed. Search media types. */ + if (tulip_debug > 1) + printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n", + dev->name, csr12); + if (!(csr12 & 4)) { /* 10mbps link beat good. */ + new_csr6 = 0x82420000; + dev->if_port = 0; + outl(0, ioaddr + CSR13); + outl(0x0003FFFF, ioaddr + CSR14); + outw(t21142_csr15[dev->if_port], ioaddr + CSR15); + outl(t21142_csr13[dev->if_port], ioaddr + CSR13); + } else { + /* Select 100mbps port to check for link beat. */ + new_csr6 = 0x83860000; + dev->if_port = 3; + outl(0, ioaddr + CSR13); + outl(0x0003FF7F, ioaddr + CSR14); + outw(8, ioaddr + CSR15); + outl(1, ioaddr + CSR13); + } + if (tulip_debug > 1) + printk(KERN_INFO"%s: Testing new 21143 media %s.\n", + dev->name, medianame[dev->if_port]); + if (new_csr6 != (tp->csr6 & ~0x00D5)) { + tp->csr6 &= 0x00D5; + tp->csr6 |= new_csr6; + outl(0x0301, ioaddr + CSR12); + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + } + next_tick = 3*HZ; + } + if (tp->cur_tx - tp->dirty_tx > 0 && + jiffies - dev->trans_start > TX_TIMEOUT) { + printk(KERN_WARNING "%s: Tx hung, %d vs. %d.\n", + dev->name, tp->cur_tx, tp->dirty_tx); + tulip_tx_timeout(dev); + } + + tp->timer.expires = RUN_AT(next_tick); + add_timer(&tp->timer); +} + +static void t21142_start_nway(struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int csr14 = ((tp->to_advertise & 0x0180) << 9) | + ((tp->to_advertise&0x0020)<<1) | 0xffbf; + + dev->if_port = 0; + tp->nway = tp->mediasense = 1; + tp->nwayset = tp->lpar = 0; + if (debug > 1) + printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, %8.8x.\n", + dev->name, csr14); + outl(0x0001, ioaddr + CSR13); + outl(csr14, ioaddr + CSR14); + tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); + outl_CSR6(tp->csr6, ioaddr, tp->chip_id); + if (tp->mtable && tp->mtable->csr15dir) { + outl(tp->mtable->csr15dir, ioaddr + CSR15); + outl(tp->mtable->csr15val, ioaddr + CSR15); + } else + outw(0x0008, ioaddr + CSR15); + outl(0x1301, ioaddr + CSR12); /* Trigger NWAY. */ +} + +static void t21142_lnk_change(struct net_device *dev, int csr5) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int csr12 = inl(ioaddr + CSR12); + + if (tulip_debug > 1) + printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, " + "%8.8x.\n", dev->name, csr12, csr5, inl(ioaddr + CSR14)); + + /* If NWay finished and we have a negotiated partner capability. */ + if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { + int setup_done = 0; + tp->lpar = csr12 >> 16; + tp->nwayset = 1; + if (csr12 & 0x01000000) dev->if_port = 5; + else if (csr12 & 0x00800000) dev->if_port = 3; + else if (csr12 & 0x00400000) dev->if_port = 4; + else if (csr12 & 0x00200000) dev->if_port = 0; + else { + tp->nwayset = 0; + if ( ! (csr12 & 2)) dev->if_port = 3; + else if ( ! (csr12 & 4)) dev->if_port = 0; + } + tp->full_duplex = (media_cap[tp->default_port] & MediaAlwaysFD) ? 1:0; + + if (tulip_debug > 1) { + if (tp->nwayset) + printk(KERN_INFO "%s: Switching to %s based on link partner " + "advertisement %4.4x.\n", + dev->name, medianame[dev->if_port], tp->lpar); + else + printk(KERN_INFO "%s: Switching to %s based on link beat " + "status of %4.4x.\n", + dev->name, medianame[dev->if_port], csr12); + } + + if (tp->mtable) { + int i; + for (i = 0; i < tp->mtable->leafcount; i++) + if (tp->mtable->mleaf[i].media == dev->if_port) { + tp->cur_index = i; + select_media(dev, 0); + setup_done = 1; + break; + } + } + if ( ! setup_done) { + tp->csr6 = dev->if_port & 1 ? 0x83860000 : 0x82420000; + if (tp->full_duplex) + tp->csr6 |= 0x0200; + outw(0x0000, ioaddr + CSR13); + outw(0x0000, ioaddr + CSR14); + } + outl_CSR6(tp->csr6 | 0x0000, ioaddr, tp->chip_id); + if (debug > 2) + printk(KERN_DEBUG "%s: Restarting Tx and Rx, CSR5 is %8.8x.\n", + dev->name, inl(ioaddr + CSR5)); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + } else if ((tp->nwayset && (csr5 & 0x08000000) + && (dev->if_port == 3 || dev->if_port == 5) + && (csr12 & 2) == 2) || + (tp->nway && (csr5 & (TPLnkFail)))) { + /* Link blew? Maybe restart NWay. */ + del_timer(&tp->timer); + t21142_start_nway(dev); + tp->timer.expires = RUN_AT(3*HZ); + add_timer(&tp->timer); + } else if (dev->if_port == 3 || dev->if_port == 5) { + if (tulip_debug > 1) + printk(KERN_INFO"%s: 21143 %s link beat %s.\n", + dev->name, medianame[dev->if_port], + (csr12 & 2) ? "failed" : "good"); + if ((csr12 & 2) && ! tp->medialock) { + del_timer(&tp->timer); + t21142_start_nway(dev); + tp->timer.expires = RUN_AT(3*HZ); + add_timer(&tp->timer); + } + } else if (dev->if_port == 0 || dev->if_port == 4) { + if ((csr12 & 4) == 0) + printk(KERN_INFO"%s: 21143 10baseT link beat good.\n", + dev->name); + } else if (!(csr12 & 4)) { /* 10mbps link beat good. */ + if (tulip_debug) + printk(KERN_INFO"%s: 21143 10mbps sensed media.\n", + dev->name); + dev->if_port = 0; + } else if (tp->nwayset) { + if (tulip_debug) + printk(KERN_INFO"%s: 21143 using NWay-set %s, csr6 %8.8x.\n", + dev->name, medianame[dev->if_port], tp->csr6); + } else { /* 100mbps link beat good. */ + if (tulip_debug) + printk(KERN_INFO"%s: 21143 100baseTx sensed media.\n", + dev->name); + dev->if_port = 3; + tp->csr6 = 0x83860000; + outl(0x0003FF7F, ioaddr + CSR14); + outl(0x0301, ioaddr + CSR12); + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + } +} + +static void mxic_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int next_tick = 60*HZ; + + if (tulip_debug > 3) { + printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name, + inl(ioaddr + CSR12)); + } + if (next_tick) { + tp->timer.expires = RUN_AT(next_tick); + add_timer(&tp->timer); + } +} + +static void pnic_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int csr12 = inl(ioaddr + CSR12); + int next_tick = 60*HZ; + int new_csr6 = tp->csr6 & ~0x40C40200; + + if (media_cap[dev->if_port] & MediaIsMII) { + int negotiated = mdio_read(dev, tp->phys[0], 5) & tp->advertising[0]; + + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: PNIC negotiated capability %8.8x, " + "CSR5 %8.8x.\n", + dev->name, negotiated, inl(ioaddr + CSR5)); + + if (negotiated & 0x0380) /* 10 vs 100mbps */ + new_csr6 |= 0x810E0000; + else + new_csr6 |= 0x814E0000; + if (((negotiated & 0x0300) == 0x0100) /* Duplex */ + || (negotiated & 0x00C0) == 0x0040 + || tp->full_duplex_lock) { + tp->full_duplex = 1; + new_csr6 |= 0x0200; + } + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: PNIC MII PHY status %4.4x, Link " + "partner report %4.4x, csr6 %8.8x/%8.8x.\n", + dev->name, mdio_read(dev, tp->phys[0], 1), negotiated, + tp->csr6, inl(ioaddr + CSR6)); + } else { + int phy_reg = inl(ioaddr + 0xB8); + int csr5 = inl(ioaddr + CSR5); + + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: PNIC PHY status %8.8x, CSR5 %8.8x.\n", + dev->name, phy_reg, csr5); + + if (phy_reg & 0x04000000) { /* Remote link fault */ + /*outl(0x0201F078, ioaddr + 0xB8);*/ + next_tick = 3*HZ; + } + if (inl(ioaddr + CSR5) & TPLnkFail) { /* 100baseTx link beat */ + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, " + "CSR5 %8.8x, PHY %3.3x.\n", + dev->name, medianame[dev->if_port], csr12, + inl(ioaddr + CSR5), inl(ioaddr + 0xB8)); + if (tp->medialock) { + } else if (dev->if_port == 0) { + dev->if_port = 3; + outl(0x33, ioaddr + CSR12); + new_csr6 = 0x01860000; + outl(0x1F868, ioaddr + 0xB8); + } else { + dev->if_port = 0; + outl(0x32, ioaddr + CSR12); + new_csr6 = 0x00420000; + outl(0x1F078, ioaddr + 0xB8); + } + new_csr6 |= (tp->csr6 & 0xfdff); + next_tick = 3*HZ; + } else + new_csr6 = tp->csr6; + if (tp->full_duplex_lock || (phy_reg & 0x30000000) != 0) { + tp->full_duplex = 1; + new_csr6 |= 0x00000200; + } + } + if (tp->csr6 != new_csr6) { + tp->csr6 = new_csr6; + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); /* Restart Tx */ + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + dev->trans_start = jiffies; + if (tulip_debug > 1) + printk(KERN_INFO "%s: Changing PNIC configuration to %s-duplex, " + "CSR6 %8.8x.\n", + dev->name, tp->full_duplex ? "full" : "half", new_csr6); + } + tp->timer.expires = RUN_AT(next_tick); + add_timer(&tp->timer); +} + +static void comet_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int next_tick = 60*HZ; + + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability " + "%4.4x.\n", + dev->name, inl(ioaddr + 0xB8), inl(ioaddr + 0xC8)); + tp->timer.expires = RUN_AT(next_tick); + add_timer(&tp->timer); +} + +static void tulip_tx_timeout(struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + + if (media_cap[dev->if_port] & MediaIsMII) { + /* Do nothing -- the media monitor should handle this. */ + if (tulip_debug > 1) + printk(KERN_WARNING "%s: Transmit timeout using MII device.\n", + dev->name); + } else if (tp->chip_id == DC21040) { + if ( !tp->medialock && inl(ioaddr + CSR12) & 0x0002) { + dev->if_port = (dev->if_port == 2 ? 0 : 2); + printk(KERN_INFO "%s: transmit timed out, switching to " + "%s.\n", + dev->name, medianame[dev->if_port]); + select_media(dev, 0); + } + dev->trans_start = jiffies; + return; + } else if (tp->chip_id == DC21041) { + int csr12 = inl(ioaddr + CSR12); + + printk(KERN_WARNING "%s: 21041 transmit timed out, status %8.8x, " + "CSR12 %8.8x, CSR13 %8.8x, CSR14 %8.8x, resetting...\n", + dev->name, inl(ioaddr + CSR5), csr12, + inl(ioaddr + CSR13), inl(ioaddr + CSR14)); + tp->mediasense = 1; + if ( ! tp->medialock) { + if (dev->if_port == 1 || dev->if_port == 2) + if (csr12 & 0x0004) { + dev->if_port = 2 - dev->if_port; + } else + dev->if_port = 0; + else + dev->if_port = 1; + select_media(dev, 0); + } + } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 + || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) { + printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, " + "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", + dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12), + inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(ioaddr + CSR15)); + if ( ! tp->medialock && tp->mtable) { + do + --tp->cur_index; + while (tp->cur_index >= 0 + && (media_cap[tp->mtable->mleaf[tp->cur_index].media] + & MediaIsFD)); + if (--tp->cur_index < 0) { + /* We start again, but should instead look for default. */ + tp->cur_index = tp->mtable->leafcount - 1; + } + select_media(dev, 0); + printk(KERN_WARNING "%s: transmit timed out, switching to %s " + "media.\n", dev->name, medianame[dev->if_port]); + } + } else { + printk(KERN_WARNING "%s: Transmit timed out, status %8.8x, CSR12 " + "%8.8x, resetting...\n", + dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12)); + dev->if_port = 0; + } + +#if defined(way_too_many_messages) + if (tulip_debug > 3) { + int i; + for (i = 0; i < RX_RING_SIZE; i++) { + u8 *buf = (u8 *)(tp->rx_ring[i].buffer1); + int j; + printk(KERN_DEBUG "%2d: %8.8x %8.8x %8.8x %8.8x " + "%2.2x %2.2x %2.2x.\n", + i, (unsigned int)tp->rx_ring[i].status, + (unsigned int)tp->rx_ring[i].length, + (unsigned int)tp->rx_ring[i].buffer1, + (unsigned int)tp->rx_ring[i].buffer2, + buf[0], buf[1], buf[2]); + for (j = 0; buf[j] != 0xee && j < 1600; j++) + if (j < 100) printk(" %2.2x", buf[j]); + printk(" j=%d.\n", j); + } + printk(KERN_DEBUG " Rx ring %8.8x: ", (int)tp->rx_ring); + for (i = 0; i < RX_RING_SIZE; i++) + printk(" %8.8x", (unsigned int)tp->rx_ring[i].status); + printk("\n" KERN_DEBUG " Tx ring %8.8x: ", (int)tp->tx_ring); + for (i = 0; i < TX_RING_SIZE; i++) + printk(" %8.8x", (unsigned int)tp->tx_ring[i].status); + printk("\n"); + } +#endif + + /* Stop and restart the chip's Tx processes . */ + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + /* Trigger an immediate transmit demand. */ + outl(0, ioaddr + CSR1); + + dev->trans_start = jiffies; + tp->stats.tx_errors++; + return; +} + +/* Initialize the Rx and Tx rings, along with various 'dev' bits. */ +static void tulip_init_ring(struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int i; + + tp->tx_full = 0; + tp->cur_rx = tp->cur_tx = 0; + tp->dirty_rx = tp->dirty_tx = 0; + + for (i = 0; i < RX_RING_SIZE; i++) { + tp->rx_ring[i].status = 0x00000000; + tp->rx_ring[i].length = PKT_BUF_SZ; + tp->rx_ring[i].buffer2 = virt_to_bus(&tp->rx_ring[i+1]); + tp->rx_skbuff[i] = NULL; + } + /* Mark the last entry as wrapping the ring. */ + tp->rx_ring[i-1].length = PKT_BUF_SZ | DESC_RING_WRAP; + tp->rx_ring[i-1].buffer2 = virt_to_bus(&tp->rx_ring[0]); + + for (i = 0; i < RX_RING_SIZE; i++) { + /* Note the receive buffer must be longword aligned. + dev_alloc_skb() provides 16 byte alignment. But do *not* + use skb_reserve() to align the IP header! */ + struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ); + tp->rx_skbuff[i] = skb; + if (skb == NULL) + break; + skb->dev = dev; /* Mark as being used by this device. */ + tp->rx_ring[i].status = DescOwned; /* Owned by Tulip chip */ + tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail); + } + tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); + + /* The Tx buffer descriptor is filled in as needed, but we + do need to clear the ownership bit. */ + for (i = 0; i < TX_RING_SIZE; i++) { + tp->tx_skbuff[i] = 0; + tp->tx_ring[i].status = 0x00000000; + tp->tx_ring[i].buffer2 = virt_to_bus(&tp->tx_ring[i+1]); +#ifdef CARDBUS + if (tp->chip_id == X3201_3) + tp->tx_aligned_skbuff[i] = dev_alloc_skb(PKT_BUF_SZ); +#endif CARDBUS + } + tp->tx_ring[i-1].buffer2 = virt_to_bus(&tp->tx_ring[0]); +} + +static int +tulip_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int entry; + u32 flag; + + /* 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, (void*)&dev->tbusy) != 0) { + if (jiffies - dev->trans_start < TX_TIMEOUT) + return 1; + tulip_tx_timeout(dev); + return 1; + } + + /* Caution: the write order is important here, set the base address + with the "ownership" bits last. */ + + /* Calculate the next Tx descriptor entry. */ + entry = tp->cur_tx % TX_RING_SIZE; + + tp->tx_skbuff[entry] = skb; +#ifdef CARDBUS + if (tp->chip_id == X3201_3) { + memcpy(tp->tx_aligned_skbuff[entry]->data,skb->data,skb->len); + tp->tx_ring[entry].buffer1 = virt_to_bus(tp->tx_aligned_skbuff[entry]->data); + } else +#endif + tp->tx_ring[entry].buffer1 = virt_to_bus(skb->data); + + if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE/2) {/* Typical path */ + flag = 0x60000000; /* No interrupt */ + } else if (tp->cur_tx - tp->dirty_tx == TX_RING_SIZE/2) { + flag = 0xe0000000; /* Tx-done intr. */ + } else if (tp->cur_tx - tp->dirty_tx < TX_RING_SIZE - 2) { + flag = 0x60000000; /* No Tx-done intr. */ + } else { + /* Leave room for set_rx_mode() to fill entries. */ + flag = 0xe0000000; /* Tx-done intr. */ + tp->tx_full = 1; + } + if (entry == TX_RING_SIZE-1) + flag |= 0xe0000000 | DESC_RING_WRAP; + + tp->tx_ring[entry].length = skb->len | flag; + tp->tx_ring[entry].status = DescOwned; /* Pass ownership to the chip. */ + tp->cur_tx++; + if ( ! tp->tx_full) + clear_bit(0, (void*)&dev->tbusy); + + /* Trigger an immediate transmit demand. */ + outl(0, dev->base_addr + CSR1); + + dev->trans_start = jiffies; + + return 0; +} + +/* The interrupt handler does all of the Rx thread work and cleans up + after the Tx thread. */ +static void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *)dev_instance; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + int csr5, work_budget = max_interrupt_work; + +#if defined(__i386__) && defined(SMP_CHECK) + if (test_and_set_bit(0, (void*)&dev->interrupt)) { + printk(KERN_ERR "%s: Duplicate entry of the interrupt handler by " + "processor %d.\n", + dev->name, hard_smp_processor_id()); + dev->interrupt = 0; + return; + } +#else + if (dev->interrupt) { + printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name); + return; + } + dev->interrupt = 1; +#endif + + do { + csr5 = inl(ioaddr + CSR5); + /* Acknowledge all of the current interrupt sources ASAP. */ + outl(csr5 & 0x0001ffff, ioaddr + CSR5); + + if (tulip_debug > 4) + printk(KERN_DEBUG "%s: interrupt csr5=%#8.8x new csr5=%#8.8x.\n", + dev->name, csr5, inl(dev->base_addr + CSR5)); + + if (csr5 == 0xffffffff) + break; /* all bits set, assume PCMCIA card removed */ + + if ((csr5 & (NormalIntr|AbnormalIntr)) == 0) + break; + + if (csr5 & (RxIntr | RxNoBuf)) + work_budget -= tulip_rx(dev); + + if (csr5 & (TxNoBuf | TxDied | TxIntr)) { + unsigned int dirty_tx; + + for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0; + dirty_tx++) { + int entry = dirty_tx % TX_RING_SIZE; + int status = tp->tx_ring[entry].status; + + if (status < 0) + break; /* It still hasn't been Txed */ + /* Check for Rx filter setup frames. */ + if (tp->tx_skbuff[entry] == NULL) + continue; + + if (status & 0x8000) { + /* There was an major error, log it. */ +#ifndef final_version + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n", + dev->name, status); +#endif + tp->stats.tx_errors++; + if (status & 0x4104) tp->stats.tx_aborted_errors++; + if (status & 0x0C00) tp->stats.tx_carrier_errors++; + if (status & 0x0200) tp->stats.tx_window_errors++; + if (status & 0x0002) tp->stats.tx_fifo_errors++; + if ((status & 0x0080) && tp->full_duplex == 0) + tp->stats.tx_heartbeat_errors++; +#ifdef ETHER_STATS + if (status & 0x0100) tp->stats.collisions16++; +#endif + } else { +#ifdef ETHER_STATS + if (status & 0x0001) tp->stats.tx_deferred++; +#endif + tp->stats.tx_bytes += tp->tx_ring[entry].length & 0x7ff; + tp->stats.collisions += (status >> 3) & 15; + tp->stats.tx_packets++; + } + + /* Free the original skb. */ + dev_free_skb(tp->tx_skbuff[entry]); + tp->tx_skbuff[entry] = 0; + } + +#ifndef final_version + if (tp->cur_tx - dirty_tx > TX_RING_SIZE) { + printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n", + dev->name, dirty_tx, tp->cur_tx, tp->tx_full); + dirty_tx += TX_RING_SIZE; + } +#endif + + if (tp->tx_full && dev->tbusy + && tp->cur_tx - dirty_tx < TX_RING_SIZE - 2) { + /* The ring is no longer full, clear tbusy. */ + tp->tx_full = 0; + dev->tbusy = 0; + mark_bh(NET_BH); + } + + tp->dirty_tx = dirty_tx; + if (csr5 & TxDied) { + if (tulip_debug > 2) + printk(KERN_WARNING "%s: The transmitter stopped." + " CSR5 is %x, CSR6 %x, new CSR6 %x.\n", + dev->name, csr5, inl(ioaddr + CSR6), tp->csr6); + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + } + } + + /* Log errors. */ + if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */ + if (csr5 == 0xffffffff) + break; + if (csr5 & TxJabber) tp->stats.tx_errors++; + if (csr5 & TxFIFOUnderflow) { + if ((tp->csr6 & 0xC000) != 0xC000) + tp->csr6 += 0x4000; /* Bump up the Tx threshold */ + else + tp->csr6 |= 0x00200000; /* Store-n-forward. */ + /* Restart the transmit process. */ + outl_CSR6(tp->csr6 | 0x0002, ioaddr, tp->chip_id); + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + } + if (csr5 & RxDied) { /* Missed a Rx frame. */ + tp->stats.rx_errors++; + tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff; + outl_CSR6(tp->csr6 | 0x2002, ioaddr, tp->chip_id); + } + if (csr5 & TimerInt) { + if (tulip_debug > 2) + printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n", + dev->name, csr5); + outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7); + } + if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) { + if ( tp->chip_id == DC21142) + t21142_lnk_change(dev, csr5); + } + /* Clear all error sources, included undocumented ones! */ + outl(0x0800f7ba, ioaddr + CSR5); + } + if (--work_budget < 0) { + if (tulip_debug > 1) + printk(KERN_WARNING "%s: Too much work during an interrupt, " + "csr5=0x%8.8x.\n", dev->name, csr5); + /* Acknowledge all interrupt sources. */ + outl(0x8001ffff, ioaddr + CSR5); +#ifdef notdef + /* Clear all but standard interrupt sources. */ + outl((~csr5) & 0x0001ebef, ioaddr + CSR7); +#endif + break; + } + } while (1); + + if (tulip_debug > 3) + printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n", + dev->name, inl(ioaddr + CSR5)); + +#if defined(__i386__) + clear_bit(0, (void*)&dev->interrupt); +#else + dev->interrupt = 0; +#endif + return; +} + +static int +tulip_rx(struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int entry = tp->cur_rx % RX_RING_SIZE; + int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx; + int work_done = 0; + + if (tulip_debug > 4) + printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry, + tp->rx_ring[entry].status); + /* If we own the next entry, it's a new packet. Send it up. */ + while (tp->rx_ring[entry].status >= 0) { + s32 status = tp->rx_ring[entry].status; + + if (tulip_debug > 5) + printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry, + tp->rx_ring[entry].status); + if (--rx_work_limit < 0) + break; + if ((status & 0x38008300) != 0x0300) { + if ((status & 0x38000300) != 0x0300) { + /* Ingore earlier buffers. */ + if ((status & 0xffff) != 0x7fff) { + if (tulip_debug > 1) + printk(KERN_WARNING "%s: Oversized Ethernet frame " + "spanned multiple buffers, status %8.8x!\n", + dev->name, status); + tp->stats.rx_length_errors++; + } + } else if (status & RxDescFatalErr) { + /* There was a fatal error. */ + if (tulip_debug > 2) + printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n", + dev->name, status); + tp->stats.rx_errors++; /* end of a packet.*/ + if (status & 0x0890) tp->stats.rx_length_errors++; + if (status & 0x0004) tp->stats.rx_frame_errors++; + if (status & 0x0002) tp->stats.rx_crc_errors++; + if (status & 0x0001) tp->stats.rx_fifo_errors++; + } + } else { + /* Omit the four octet CRC from the length. */ + short pkt_len = ((status >> 16) & 0x7ff) - 4; + struct sk_buff *skb; + +#ifndef final_version + if (pkt_len > 1518) { + printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n", + dev->name, pkt_len, pkt_len); + pkt_len = 1518; + tp->stats.rx_length_errors++; + } +#endif + /* Check if the packet is long enough to accept without copying + to a minimally-sized skbuff. */ + if (pkt_len < rx_copybreak + && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { + skb->dev = dev; + skb_reserve(skb, 2); /* 16 byte align the IP header */ +#if ! defined(__alpha__) + eth_copy_and_sum(skb, bus_to_virt(tp->rx_ring[entry].buffer1), + pkt_len, 0); + skb_put(skb, pkt_len); +#else + memcpy(skb_put(skb, pkt_len), + bus_to_virt(tp->rx_ring[entry].buffer1), pkt_len); +#endif + work_done++; + } else { /* Pass up the skb already on the Rx ring. */ + char *temp = skb_put(skb = tp->rx_skbuff[entry], pkt_len); + tp->rx_skbuff[entry] = NULL; +#ifndef final_version + if (bus_to_virt(tp->rx_ring[entry].buffer1) != temp) + printk(KERN_ERR "%s: Internal fault: The skbuff addresses " + "do not match in tulip_rx: %p vs. %p / %p.\n", + dev->name, bus_to_virt(tp->rx_ring[entry].buffer1), + skb->head, temp); +#endif + } + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; + tp->stats.rx_packets++; + tp->stats.rx_bytes += pkt_len; + } + entry = (++tp->cur_rx) % RX_RING_SIZE; + } + + /* Refill the Rx ring buffers. */ + for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) { + entry = tp->dirty_rx % RX_RING_SIZE; + if (tp->rx_skbuff[entry] == NULL) { + struct sk_buff *skb; + skb = tp->rx_skbuff[entry] = dev_alloc_skb(PKT_BUF_SZ); + if (skb == NULL) + break; + skb->dev = dev; /* Mark as being used by this device. */ + tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail); + work_done++; + } + tp->rx_ring[entry].status = DescOwned; + } + + return work_done; +} + +static void +tulip_down(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + + dev->start = 0; + dev->tbusy = 1; + + /* Disable interrupts by clearing the interrupt mask. */ + outl(0x00000000, ioaddr + CSR7); + /* Stop the chip's Tx and Rx processes. */ + outl_CSR6(inl(ioaddr + CSR6) & ~0x2002, ioaddr, tp->chip_id); + /* 21040 -- Leave the card in 10baseT state. */ + if (tp->chip_id == DC21040) + outl(0x00000004, ioaddr + CSR13); + + if (inl(ioaddr + CSR6) != 0xffffffff) + tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff; + + del_timer(&tp->timer); + + dev->if_port = tp->saved_if_port; +} + +static int +tulip_close(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + int i; + + if (tulip_debug > 1) + printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", + dev->name, inl(ioaddr + CSR5)); + + if (dev->start) + tulip_down(dev); + + free_irq(dev->irq, dev); + + /* Free all the skbuffs in the Rx queue. */ + for (i = 0; i < RX_RING_SIZE; i++) { + struct sk_buff *skb = tp->rx_skbuff[i]; + tp->rx_skbuff[i] = 0; + tp->rx_ring[i].status = 0; /* Not owned by Tulip chip. */ + tp->rx_ring[i].length = 0; + tp->rx_ring[i].buffer1 = 0xBADF00D0; /* An invalid address. */ + if (skb) { + dev_free_skb(skb); + } + } + for (i = 0; i < TX_RING_SIZE; i++) { + if (tp->tx_skbuff[i]) + dev_free_skb(tp->tx_skbuff[i]); + tp->tx_skbuff[i] = 0; + } + + MOD_DEC_USE_COUNT; + tp->open = 0; + return 0; +} + +static struct net_device_stats *tulip_get_stats(struct net_device *dev) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + + if (dev->start) + tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff; + + return &tp->stats; +} + +#ifdef HAVE_PRIVATE_IOCTL +/* Provide ioctl() calls to examine the MII xcvr state. */ +static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct tulip_private *tp = (struct tulip_private *)dev->priv; + long ioaddr = dev->base_addr; + u16 *data = (u16 *)&rq->ifr_data; + int phy = tp->phys[0] & 0x1f; + long flags; + + switch(cmd) { + case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ + if (tp->mii_cnt) + data[0] = phy; + else if (tp->chip_id == DC21142) /* 21142 pseudo-MII */ + data[0] = 32; + else if (tp->chip_id == PNIC2) + data[0] = 32; + else if (tp->chip_id == COMET) + data[0] = 1; + else + return -ENODEV; + return 0; + case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ + if (data[0] == 32 && + (tp->chip_id == DC21142 || tp->chip_id == PNIC2)) { + int csr12 = inl(ioaddr + CSR12); + int csr14 = inl(ioaddr + CSR14); + switch (data[1]) { + case 0: { + data[3] = (csr14<<5) & 0x1000; + break; } + case 1: + data[3] = 0x7848 + ((csr12&0x7000) == 0x5000 ? 0x20 : 0) + + (csr12&0x06 ? 0x04 : 0); + break; + case 4: { + data[3] = ((csr14>>9)&0x0380) + + ((inl(ioaddr + CSR6)>>3)&0x0040) +((csr14>>1)&0x20) + 1; + break; + } + case 5: data[3] = csr12 >> 16; break; + default: data[3] = 0; break; + } + } else { + save_flags(flags); + cli(); + data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f); + restore_flags(flags); + } + return 0; + case SIOCDEVPRIVATE+2: /* Write the specified MII register */ +#if defined(CAP_NET_ADMIN) + if (!capable(CAP_NET_ADMIN)) + return -EPERM; +#else + if (!suser()) + return -EPERM; +#endif + if (data[0] == 32 && tp->chip_id == DC21142) { + if (data[1] == 5) + tp->to_advertise = data[2]; + } else { + save_flags(flags); + cli(); + mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]); + restore_flags(flags); + } + return 0; + default: + return -EOPNOTSUPP; + } + + return -EOPNOTSUPP; +} +#endif /* HAVE_PRIVATE_IOCTL */ + +/* Set or clear the multicast filter for this adaptor. + Note that we only use exclusion around actually queueing the + new frame, not around filling tp->setup_frame. This is non-deterministic + when re-entered but still correct. */ + +/* The little-endian AUTODIN32 ethernet CRC calculation. + N.B. Do not use for bulk data, use a table-based routine instead. + This is common code and should be moved to net/core/crc.c */ +static unsigned const ethernet_polynomial_le = 0xedb88320U; +static inline u32 ether_crc_le(int length, unsigned char *data) +{ + u32 crc = 0xffffffff; /* Initial value. */ + while(--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 8; --bit >= 0; current_octet >>= 1) { + if ((crc ^ current_octet) & 1) { + crc >>= 1; + crc ^= ethernet_polynomial_le; + } else + crc >>= 1; + } + } + return crc; +} +static unsigned const ethernet_polynomial = 0x04c11db7U; +static inline u32 ether_crc(int length, unsigned char *data) +{ + int crc = -1; + + while(--length >= 0) { + unsigned char current_octet = *data++; + int bit; + for (bit = 0; bit < 8; bit++, current_octet >>= 1) + crc = (crc << 1) ^ + ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0); + } + return crc; +} + +static void set_rx_mode(struct net_device *dev) +{ + long ioaddr = dev->base_addr; + int csr6 = inl(ioaddr + CSR6) & ~0x00D5; + struct tulip_private *tp = (struct tulip_private *)dev->priv; + + tp->csr6 &= ~0x00D5; + if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ + tp->csr6 |= 0x00C0; + csr6 |= 0x00C0; + /* Unconditionally log net taps. */ + printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name); + } else if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) { + /* Too many to filter well -- accept all multicasts. */ + tp->csr6 |= 0x0080; + csr6 |= 0x0080; + } else if (tulip_tbl[tp->chip_id].flags & MC_HASH_ONLY) { + /* Some work-alikes have only a 64-entry hash filter table. */ + /* Should verify correctness on big-endian/__powerpc__ */ + struct dev_mc_list *mclist; + int i; + u32 mc_filter[2]; /* Multicast hash filter */ + if (dev->mc_count > 64) { /* Arbitrary non-effective limit. */ + tp->csr6 |= 0x0080; + csr6 |= 0x0080; + } else { + mc_filter[1] = mc_filter[0] = 0; + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) + set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter); + if (tp->chip_id == AX88140) { + outl(2, ioaddr + CSR13); + outl(mc_filter[0], ioaddr + CSR14); + outl(3, ioaddr + CSR13); + outl(mc_filter[1], ioaddr + CSR14); + } else if (tp->chip_id == COMET) { /* Has a simple hash filter. */ + outl(mc_filter[0], ioaddr + 0xAC); + outl(mc_filter[1], ioaddr + 0xB0); + } + } + } else { + u16 *eaddrs, *setup_frm = tp->setup_frame; + struct dev_mc_list *mclist; + u32 tx_flags = 0x08000000 | 192; + int i; + + /* Note that only the low-address shortword of setup_frame is valid! + The values are doubled for big-endian architectures. */ + if ((dev->mc_count > 14) || ((dev->mc_count > 6) && (tp->chip_id == X3201_3))) { /* Must use a multicast hash table. */ + u16 hash_table[32]; + tx_flags = 0x08400000 | 192; /* Use hash filter. */ + memset(hash_table, 0, sizeof(hash_table)); + set_bit(255, hash_table); /* Broadcast entry */ + /* This should work on big-endian machines as well. */ + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) + set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x1ff, + hash_table); + for (i = 0; i < 32; i++) { + *setup_frm++ = hash_table[i]; + *setup_frm++ = hash_table[i]; + } + setup_frm = &tp->setup_frame[13*6]; + } else if(tp->chip_id != X3201_3) { + /* We have <= 14 addresses so we can use the wonderful + 16 address perfect filtering of the Tulip. */ + for (i = 0, mclist = dev->mc_list; i < dev->mc_count; + i++, mclist = mclist->next) { + eaddrs = (u16 *)mclist->dmi_addr; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; + } + /* Fill the unused entries with the broadcast address. */ + memset(setup_frm, 0xff, (15-i)*12); + setup_frm = &tp->setup_frame[15*6]; + } else { + /* fill the first two table entries with our address */ + eaddrs = (u16 *)dev->dev_addr; + for(i=0; i<2; i++) { + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; + } + /* Double fill each entry to accomodate chips that */ + /* don't like to parse these correctly */ + for (i=0, mclist=dev->mc_list; imc_count; + i++, mclist=mclist->next) { + eaddrs = (u16 *)mclist->dmi_addr; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; + } + i=((i+1)*2); + /* Fill the unused entries with the broadcast address. */ + memset(setup_frm, 0xff, (15-i)*12); + setup_frm = &tp->setup_frame[15*6]; + } + + /* Fill the final entry with our physical address. */ + eaddrs = (u16 *)dev->dev_addr; + *setup_frm++ = eaddrs[0]; *setup_frm++ = eaddrs[0]; + *setup_frm++ = eaddrs[1]; *setup_frm++ = eaddrs[1]; + *setup_frm++ = eaddrs[2]; *setup_frm++ = eaddrs[2]; + /* Now add this frame to the Tx list. */ + if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) { + /* Same setup recently queued, we need not add it. */ + } else { + unsigned long flags; + unsigned int entry, dummy = -1; + + save_flags(flags); cli(); + entry = tp->cur_tx++ % TX_RING_SIZE; + + if (entry != 0) { + /* Avoid a chip errata by prefixing a dummy entry. */ + tp->tx_skbuff[entry] = 0; + tp->tx_ring[entry].length = + (entry == TX_RING_SIZE-1) ? DESC_RING_WRAP : 0; + tp->tx_ring[entry].buffer1 = 0; + /* race with chip, set DescOwned later */ + dummy = entry; + entry = tp->cur_tx++ % TX_RING_SIZE; + } + + tp->tx_skbuff[entry] = 0; + /* Put the setup frame on the Tx list. */ + if (entry == TX_RING_SIZE-1) + tx_flags |= DESC_RING_WRAP; /* Wrap ring. */ + tp->tx_ring[entry].length = tx_flags; + if(tp->chip_id == X3201_3) + tp->tx_ring[entry].buffer1 = (virt_to_bus(tp->setup_frame) + 4); + else + tp->tx_ring[entry].buffer1 = virt_to_bus(tp->setup_frame); + tp->tx_ring[entry].status = DescOwned; + if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) { + set_bit(0, (void*)&dev->tbusy); + tp->tx_full = 1; + } + if (dummy >= 0) + tp->tx_ring[dummy].status = DescOwned; + restore_flags(flags); + /* Trigger an immediate transmit demand. */ + outl(0, ioaddr + CSR1); + } + } + outl_CSR6(csr6 | 0x0000, ioaddr, tp->chip_id); +} + +#ifdef CARDBUS + +#include + +static dev_node_t *tulip_attach(dev_locator_t *loc) +{ + struct net_device *dev; + u16 dev_id; + u16 vendor_id; + u32 io; + u8 bus, devfn, irq; + + if (loc->bus != LOC_PCI) return NULL; + bus = loc->b.pci.bus; devfn = loc->b.pci.devfn; + printk(KERN_INFO "tulip_attach(bus %d, function %d)\n", bus, devfn); + pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io); + pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id); + pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq); + pcibios_read_config_word(bus, devfn, PCI_VENDOR_ID, &vendor_id); + if (dev_id == 0x0003 && vendor_id == 0x115d) + dev = tulip_probe1(bus, devfn, NULL, io & ~3, irq, X3201_3, 0); + else + dev = tulip_probe1(bus, devfn, NULL, io & ~3, irq, DC21142, 0); + if (dev) { + dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL); + strcpy(node->dev_name, dev->name); + node->major = node->minor = 0; + node->next = NULL; + MOD_INC_USE_COUNT; + return node; + } + return NULL; +} + +static void tulip_suspend(dev_node_t *node) +{ + struct net_device *dev, *next; + printk(KERN_INFO "tulip_suspend(%s)\n", node->dev_name); + for (dev = root_tulip_dev; dev; dev = next) { + next = ((struct tulip_private *)dev->priv)->next_module; + if (strcmp(dev->name, node->dev_name) == 0) break; + } + if (dev) { + struct tulip_private *tp = (struct tulip_private *)dev->priv; + if (tp->open) tulip_down(dev); + } +} + +static void tulip_resume(dev_node_t *node) +{ + struct net_device *dev, *next; + printk(KERN_INFO "tulip_resume(%s)\n", node->dev_name); + for (dev = root_tulip_dev; dev; dev = next) { + next = ((struct tulip_private *)dev->priv)->next_module; + if (strcmp(dev->name, node->dev_name) == 0) break; + } + if (dev) { + struct tulip_private *tp = (struct tulip_private *)dev->priv; + if (tp->open) tulip_up(dev); + } +} + +static void tulip_detach(dev_node_t *node) +{ + struct net_device **devp, **next; + printk(KERN_INFO "tulip_detach(%s)\n", node->dev_name); + for (devp = &root_tulip_dev; *devp; devp = next) { + next = &((struct tulip_private *)(*devp)->priv)->next_module; + if (strcmp((*devp)->name, node->dev_name) == 0) break; + } + if (*devp) { + struct net_device *dev = *devp; + struct tulip_private *tp = dev->priv; + unregister_netdev(dev); + kfree(dev); + kfree(tp); + *devp = *next; + kfree(node); + MOD_DEC_USE_COUNT; + } +} + +struct driver_operations tulip_ops = { + "tulip_cb", tulip_attach, tulip_suspend, tulip_resume, tulip_detach +}; + +#endif /* Cardbus support */ + +#ifdef MODULE +int init_module(void) +{ +#ifdef CARDBUS + reverse_probe = 0; /* Not used. */ + register_driver(&tulip_ops); + return 0; +#else + return tulip_probe(NULL); +#endif +} + +void cleanup_module(void) +{ + struct net_device *next_dev; + +#ifdef CARDBUS + unregister_driver(&tulip_ops); +#endif + + /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ + while (root_tulip_dev) { + struct tulip_private *tp = (struct tulip_private *)root_tulip_dev->priv; + next_dev = tp->next_module; + unregister_netdev(root_tulip_dev); + release_region(root_tulip_dev->base_addr, + tulip_tbl[tp->chip_id].io_size); + kfree(root_tulip_dev); + root_tulip_dev = next_dev; + } +} + +#endif /* MODULE */ + +/* + * Local variables: + * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c tulip.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c tulip.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" + * cardbus-compile-command: "gcc -DCARDBUS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c tulip.c -o tulip_cb.o -I/usr/src/pcmcia-cs-3.0.9/include/" + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/wavelan_cs.h linux/drivers/net/pcmcia/wavelan_cs.h --- v2.3.26/linux/drivers/net/pcmcia/wavelan_cs.h Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/wavelan_cs.h Thu Nov 11 16:03:37 1999 @@ -122,7 +122,7 @@ * Yunzhou Li finished is work. * Joe Finney patched the driver to start * correctly 2.00 cards (2.4 GHz with frequency selection). - * David Hinds integrated the whole in his + * David Hinds integrated the whole in his * Pcmcia package (+ bug corrections). * * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some @@ -174,7 +174,7 @@ * Matthew Geier (matthew@cs.su.oz.au), * Remo di Giovanni (remo@cs.su.oz.au), * Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM), - * David Hinds , + * David Hinds , * Jan Hoogendoorn (c/o marteijn@lucent.com), * Bruce Janson , * Anthony D. Joseph , diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcmcia/xirc2ps_cs.c linux/drivers/net/pcmcia/xirc2ps_cs.c --- v2.3.26/linux/drivers/net/pcmcia/xirc2ps_cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/pcmcia/xirc2ps_cs.c Thu Nov 11 16:03:37 1999 @@ -83,10 +83,6 @@ /* Enable the bug fix for CEM56 to use modem and ethernet simultaneously */ #define CEM56_FIX -#if !defined(PCMCIA_DEBUG) && 0 - #define PCMCIA_DEBUG 4 -#endif - #include #include #include @@ -250,6 +246,9 @@ #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); +#define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args) +#else +#define DEBUG(n, args...) #endif static char *version = "xirc2ps_cs.c 1.31 1998/12/09 19:32:55 (dd9jn+kvh)"; @@ -313,11 +312,11 @@ /* MII management prototypes */ static void mii_idle(ioaddr_t ioaddr); static void mii_putbit(ioaddr_t ioaddr, unsigned data); -static int mii_getbit( ioaddr_t ioaddr ); +static int mii_getbit(ioaddr_t ioaddr); static void mii_wbits(ioaddr_t ioaddr, unsigned data, int len); static unsigned mii_rd(ioaddr_t ioaddr, u_char phyaddr, u_char phyreg); static void mii_wr(ioaddr_t ioaddr, u_char phyaddr, u_char phyreg, - unsigned data, int len); + unsigned data, int len); /* * The event() function is this driver's Card Services event handler. @@ -396,6 +395,7 @@ int silicon; /* silicon revision. 0=old CE2, 1=Scipper, 4=Mohawk */ int mohawk; /* a CE3 type card */ int dingo; /* a CEM56 type card */ + int new_mii; /* has full 10baseT/100baseT MII */ int modem; /* is a multi function card (i.e with a modem) */ caddr_t dingo_ccr; /* only used for CEM56 cards */ int suspended; @@ -411,7 +411,7 @@ static void set_addresses(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static int do_init(struct net_device *dev); -static int set_card_type( dev_link_t *link, const void *s ); +static int set_card_type(dev_link_t *link, const void *s); static int do_config(struct net_device *dev, struct ifmap *map); static int do_open(struct net_device *dev); static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -441,11 +441,11 @@ } static int -get_tuple_data(int fn, client_handle_t handle, tuple_t *tuple ) +get_tuple_data(int fn, client_handle_t handle, tuple_t *tuple) { int err; - if( (err=CardServices(fn, handle, tuple)) ) + if ((err=CardServices(fn, handle, tuple))) return err; return CardServices(GetTupleData, handle, tuple); } @@ -455,7 +455,7 @@ { int err; - if( (err=get_tuple_data(fn, handle, tuple)) ) + if ((err=get_tuple_data(fn, handle, tuple))) return err; return CardServices(ParseTuple, handle, tuple, parse); } @@ -477,7 +477,7 @@ save_flags(flags); sti(); - while(timeout >= jiffies) + while (timeout >= jiffies) ; restore_flags(flags); } @@ -489,27 +489,27 @@ { ioaddr_t ioaddr = dev->base_addr; - if(pc_debug > 1) { + if (pc_debug > 1) { int i, page; printk(KDBG_XIRC "Register common: "); - for(i = 0; i < 8; i++ ) - printk(" %2.2x", GetByte(i) ); + for (i = 0; i < 8; i++) + printk(" %2.2x", GetByte(i)); printk("\n"); - for(page = 0; page <= 8; page++) { + for (page = 0; page <= 8; page++) { printk(KDBG_XIRC "Register page %2x: ", page); SelectPage(page); - for(i = 8; i < 16; i++) + for (i = 8; i < 16; i++) printk(" %2.2x", GetByte(i)); printk("\n"); } - for(page=0x40 ; page <= 0x5f; page++) { - if( page == 0x43 || (page >= 0x46 && page <= 0x4f) - || (page >= 0x51 && page <=0x5e) ) + for (page=0x40 ; page <= 0x5f; page++) { + if (page == 0x43 || (page >= 0x46 && page <= 0x4f) + || (page >= 0x51 && page <=0x5e)) continue; printk(KDBG_XIRC "Register page %2x: ", page); SelectPage(page); - for(i = 8; i < 16; i++) + for (i = 8; i < 16; i++) printk(" %2.2x", GetByte(i)); printk("\n"); } @@ -525,9 +525,9 @@ static void mii_idle(ioaddr_t ioaddr) { - PutByte(XIRCREG2_GPR2, 0x04|0 ); /* drive MDCK low */ + PutByte(XIRCREG2_GPR2, 0x04|0); /* drive MDCK low */ udelay(1); - PutByte(XIRCREG2_GPR2, 0x04|1 ); /* and drive MDCK high */ + PutByte(XIRCREG2_GPR2, 0x04|1); /* and drive MDCK high */ udelay(1); } @@ -538,29 +538,27 @@ mii_putbit(ioaddr_t ioaddr, unsigned data) { #if 1 - if( data ) { - PutByte(XIRCREG2_GPR2, 0x0c|2|0 ); /* set MDIO */ + if (data) { + PutByte(XIRCREG2_GPR2, 0x0c|2|0); /* set MDIO */ udelay(1); - PutByte(XIRCREG2_GPR2, 0x0c|2|1 ); /* and drive MDCK high */ + PutByte(XIRCREG2_GPR2, 0x0c|2|1); /* and drive MDCK high */ udelay(1); - } - else { - PutByte(XIRCREG2_GPR2, 0x0c|0|0 ); /* clear MDIO */ + } else { + PutByte(XIRCREG2_GPR2, 0x0c|0|0); /* clear MDIO */ udelay(1); - PutByte(XIRCREG2_GPR2, 0x0c|0|1 ); /* and drive MDCK high */ + PutByte(XIRCREG2_GPR2, 0x0c|0|1); /* and drive MDCK high */ udelay(1); } #else - if( data ) { - PutWord(XIRCREG2_GPR2-1, 0x0e0e ); + if (data) { + PutWord(XIRCREG2_GPR2-1, 0x0e0e); udelay(1); - PutWord(XIRCREG2_GPR2-1, 0x0f0f ); + PutWord(XIRCREG2_GPR2-1, 0x0f0f); udelay(1); - } - else { - PutWord(XIRCREG2_GPR2-1, 0x0c0c ); + } else { + PutWord(XIRCREG2_GPR2-1, 0x0c0c); udelay(1); - PutWord(XIRCREG2_GPR2-1, 0x0d0d ); + PutWord(XIRCREG2_GPR2-1, 0x0d0d); udelay(1); } #endif @@ -570,14 +568,14 @@ * Get a bit from MDI/O */ static int -mii_getbit( ioaddr_t ioaddr ) +mii_getbit(ioaddr_t ioaddr) { unsigned d; - PutByte(XIRCREG2_GPR2, 4|0 ); /* drive MDCK low */ + PutByte(XIRCREG2_GPR2, 4|0); /* drive MDCK low */ udelay(1); d = GetByte(XIRCREG2_GPR2); /* read MDIO */ - PutByte(XIRCREG2_GPR2, 4|1 ); /* drive MDCK high again */ + PutByte(XIRCREG2_GPR2, 4|1); /* drive MDCK high again */ udelay(1); return d & 0x20; /* read MDIO */ } @@ -586,8 +584,8 @@ mii_wbits(ioaddr_t ioaddr, unsigned data, int len) { unsigned m = 1 << (len-1); - for( ; m; m >>= 1) - mii_putbit( ioaddr, data & m ); + for (; m; m >>= 1) + mii_putbit(ioaddr, data & m); } static unsigned @@ -597,16 +595,16 @@ unsigned data=0, m; SelectPage(2); - for( i=0; i < 32; i++ ) /* 32 bit preamble */ + for (i=0; i < 32; i++) /* 32 bit preamble */ mii_putbit(ioaddr, 1); mii_wbits(ioaddr, 0x06, 4); /* Start and opcode for read */ mii_wbits(ioaddr, phyaddr, 5); /* PHY address to be accessed */ mii_wbits(ioaddr, phyreg, 5); /* PHY register to read */ mii_idle(ioaddr); /* turn around */ - mii_getbit( ioaddr); + mii_getbit(ioaddr); - for( m = 1<<15; m; m >>= 1 ) - if( mii_getbit( ioaddr ) ) + for (m = 1<<15; m; m >>= 1) + if (mii_getbit(ioaddr)) data |= m; mii_idle(ioaddr); return data; @@ -618,7 +616,7 @@ int i; SelectPage(2); - for( i=0; i < 32; i++ ) /* 32 bit preamble */ + for (i=0; i < 32; i++) /* 32 bit preamble */ mii_putbit(ioaddr, 1); mii_wbits(ioaddr, 0x05, 4); /* Start and opcode for write */ mii_wbits(ioaddr, phyaddr, 5); /* PHY address to be accessed */ @@ -640,13 +638,13 @@ * not be read according to the DP83840A specs. */ printk(KERN_DEBUG "%s: MII register dump:\n", dev->name); - for(i=0; i < 32; i++ ) { - if( !(i % 8) ) { - if( i ) + for (i=0; i < 32; i++) { + if (!(i % 8)) { + if (i) printk("\n"); - printk(KERN_DEBUG "%s:", dev->name ); + printk(KERN_DEBUG "%s:", dev->name); } - printk(" %04x", mii_rd(ioaddr, 0, i) ); + printk(" %04x", mii_rd(ioaddr, 0, i)); } printk("\n"); } @@ -673,10 +671,7 @@ local_info_t *local; int err; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "attach()\n"); - #endif + DEBUG(0, "attach()\n"); flush_stale_links(); /* Initialize the dev_link_t structure */ @@ -725,7 +720,7 @@ client_reg.event_handler = &xirc2ps_event; client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link; - if( (err = CardServices(RegisterClient, &link->handle, &client_reg)) ) { + if ((err = CardServices(RegisterClient, &link->handle, &client_reg))) { cs_error(link->handle, RegisterClient, err); xirc2ps_detach(link); return NULL; @@ -747,25 +742,20 @@ dev_link_t **linkp; long flags; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "detach(0x%p)\n", link); - #endif + DEBUG(0, "detach(0x%p)\n", link); /* Locate device structure */ - for( linkp = &dev_list; *linkp; linkp = &(*linkp)->next ) - if( *linkp == link) + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; - if( !*linkp ) { - #ifdef PCMCIA_DEBUG - printk(KDBG_XIRC "detach(0x%p): dev_link lost\n", link ); - #endif + if (!*linkp) { + DEBUG(0, "detach(0x%p): dev_link lost\n", link); return; } save_flags(flags); cli(); - if( link->state & DEV_RELEASE_PENDING ) { + if (link->state & DEV_RELEASE_PENDING) { del_timer(&link->release); link->state &= ~DEV_RELEASE_PENDING; } @@ -777,26 +767,24 @@ * the release() function is called, that will trigger a proper * detach(). */ - if(link->state & DEV_CONFIG) { - #ifdef PCMCIA_DEBUG - printk(KDBG_XIRC "detach postponed, '%s' " - "still locked\n", link->dev->dev_name); - #endif + if (link->state & DEV_CONFIG) { + DEBUG(0, "detach postponed, '%s' still locked\n", + link->dev->dev_name); link->state |= DEV_STALE_LINK; return; } /* Break the link with Card Services */ - if(link->handle) + if (link->handle) CardServices(DeregisterClient, link->handle); /* Unlink device structure, free pieces */ *linkp = link->next; - if(link->priv) { + if (link->priv) { struct net_device *dev = link->priv; if (link->dev != NULL) unregister_netdev(dev); - if( dev->priv ) + if (dev->priv) kfree(dev->priv); kfree(link->priv); } @@ -823,7 +811,7 @@ * */ static int -set_card_type( dev_link_t *link, const void *s ) +set_card_type(dev_link_t *link, const void *s) { struct net_device *dev = link->priv; local_info_t *local = dev->priv; @@ -833,27 +821,24 @@ unsigned mediaid= ((const unsigned char *)s)[3]; unsigned prodid = ((const unsigned char *)s)[4]; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "cisrev=%02x mediaid=%02x prodid=%02x\n", - cisrev, mediaid, prodid ); - #endif + DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n", + cisrev, mediaid, prodid); local->mohawk = 0; local->dingo = 0; local->modem = 0; local->card_type = XIR_UNKNOWN; - if( !(prodid & 0x40) ) { + if (!(prodid & 0x40)) { printk(KNOT_XIRC "Ooops: Not a creditcard\n"); return 0; } - if( !(mediaid & 0x01) ) { + if (!(mediaid & 0x01)) { printk(KNOT_XIRC "Not an Ethernet card\n"); return 0; } - if( mediaid & 0x10 ) { + if (mediaid & 0x10) { local->modem = 1; - switch( prodid & 15 ) { + switch(prodid & 15) { case 1: local->card_type = XIR_CEM ; break; case 2: local->card_type = XIR_CEM2 ; break; case 3: local->card_type = XIR_CEM3 ; break; @@ -868,9 +853,8 @@ local->dingo = 1; break; } - } - else { - switch( prodid & 15 ) { + } else { + switch(prodid & 15) { case 1: local->card_type = has_ce2_string(link)? XIR_CE2 : XIR_CE ; break; case 2: local->card_type = XIR_CE2; break; @@ -879,13 +863,13 @@ break; } } - if( local->card_type == XIR_CE || local->card_type == XIR_CEM ) { + if (local->card_type == XIR_CE || local->card_type == XIR_CEM) { printk(KNOT_XIRC "Sorry, this is an old CE card\n"); return 0; } - if( local->card_type == XIR_UNKNOWN ) - printk(KNOT_XIRC "Warning: Unknown card (mediaid=%02x prodid=%02x)\n", - mediaid, prodid ); + if (local->card_type == XIR_UNKNOWN) + printk(KNOT_XIRC "unknown card (mediaid=%02x prodid=%02x)\n", + mediaid, prodid); return 1; } @@ -908,8 +892,8 @@ tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; - if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 2 ) { - if( strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2") ) + if (!first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 2) { + if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2")) return 1; } return 0; @@ -939,10 +923,7 @@ local = dev->priv; local->dingo_ccr = 0; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "config(0x%p)\n", link); - #endif + DEBUG(0, "config(0x%p)\n", link); /* * This reads the card's CONFIG tuple to find its configuration @@ -955,101 +936,89 @@ /* Is this a valid card */ tuple.DesiredTuple = CISTPL_MANFID; - if( (err=first_tuple(handle, &tuple, &parse))) { + if ((err=first_tuple(handle, &tuple, &parse))) { printk(KNOT_XIRC "manfid not found in CIS\n"); goto failure; } - switch( parse.manfid.manf ) { + switch(parse.manfid.manf) { case MANFID_XIRCOM: local->manf_str = "Xircom"; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "found xircom card\n"); - #endif + DEBUG(0, "found xircom card\n"); break; case MANFID_ACCTON: local->manf_str = "Accton"; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "found Accton card\n"); - #endif + DEBUG(0, "found Accton card\n"); break; case MANFID_COMPAQ: case MANFID_COMPAQ2: local->manf_str = "Compaq"; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "found Compaq card\n"); - #endif + DEBUG(0, "found Compaq card\n"); break; case MANFID_INTEL: local->manf_str = "Intel"; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "found Intel card\n"); - #endif + DEBUG(0, "found Intel card\n"); break; default: printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n", - (unsigned)parse.manfid.manf); + (unsigned)parse.manfid.manf); goto failure; } - if( !set_card_type(link, buf ) ) { + if (!set_card_type(link, buf)) { printk(KNOT_XIRC "this card is not supported\n"); goto failure; } /* get configuration stuff */ tuple.DesiredTuple = CISTPL_CONFIG; - if( (err=first_tuple(handle, &tuple, &parse))) + if ((err=first_tuple(handle, &tuple, &parse))) goto cis_error; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* get the ethernet address from the CIS */ tuple.DesiredTuple = CISTPL_FUNCE; - for( err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse) ) { + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)) { /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries: * the first one with a length of zero the second correct - * so I skip all entries with length 0 */ - if( parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID - && ((cistpl_lan_node_id_t *)parse.funce.data)->nb ) + if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID + && ((cistpl_lan_node_id_t *)parse.funce.data)->nb) break; } - if( err ) { /* not found: try to get the node-id from tuple 0x89 */ + if (err) { /* not found: try to get the node-id from tuple 0x89 */ tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */ - if( !(err = get_tuple_data(GetFirstTuple, handle, &tuple )) ) { - if( tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID ) - memcpy( &parse, buf, 8 ); + if (!(err = get_tuple_data(GetFirstTuple, handle, &tuple))) { + if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID) + memcpy(&parse, buf, 8); else err = -1; } } - if( err ) { /* another try (James Lehmer's CE2 version 4.1)*/ + if (err) { /* another try (James Lehmer's CE2 version 4.1)*/ tuple.DesiredTuple = CISTPL_FUNCE; - for( err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse) ) { - if( parse.funce.type == 0x02 && parse.funce.data[0] == 1 - && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13 ) { + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)) { + if (parse.funce.type == 0x02 && parse.funce.data[0] == 1 + && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) { buf[1] = 4; - memcpy( &parse, buf+1, 8 ); + memcpy(&parse, buf+1, 8); break; } } } - if( err ) { + if (err) { printk(KNOT_XIRC "node-id not found in CIS\n"); goto failure; } node_id = (cistpl_lan_node_id_t *)parse.funce.data; - if( node_id->nb != 6 ) { + if (node_id->nb != 6) { printk(KNOT_XIRC "malformed node-id in CIS\n"); goto failure; } - for( i=0; i < 6; i++ ) + for (i=0; i < 6; i++) dev->dev_addr[i] = node_id->id[i]; /* Configure card */ @@ -1059,61 +1028,60 @@ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; link->irq.Attributes = IRQ_HANDLE_PRESENT; link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID; - if( irq_list[0] == -1 ) + if (irq_list[0] == -1) link->irq.IRQInfo2 = irq_mask; else { - for( i = 0; i < 4; i++) + for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; } link->irq.Handler = xirc2ps_interrupt; link->irq.Instance = dev; - if( local->modem ) { + if (local->modem) { int pass; - if( do_sound ) { + if (do_sound) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status |= CCSR_AUDIO_ENA; } link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED ; link->io.NumPorts2 = 8; link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; - if( local->dingo ) { + if (local->dingo) { /* Take the Modem IO port from the CIS and scan for a free * Ethernet port */ link->io.NumPorts1 = 16; /* no Mako stuff anymore */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for( err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse) ) { - if( cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8 ) { - for(ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)) { + if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { + for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = ioaddr; - if( !(err=CardServices(RequestIO, link->handle, - &link->io)) ) + if (!(err=CardServices(RequestIO, link->handle, + &link->io))) goto port_found; } } } - } - else { + } else { link->io.NumPorts1 = 18; /* We do 2 passes here: The first one uses the regular mapping and * the second tries again, thereby considering that the 32 ports are * mirrored every 32 bytes. Actually we use a mirrored port for * the Mako if (on the first pass) the COR bit 5 is set. */ - for( pass=0; pass < 2; pass++ ) { + for (pass=0; pass < 2; pass++) { tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; - for( err = first_tuple(handle, &tuple, &parse); !err; - err = next_tuple(handle, &tuple, &parse) ){ - if( cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8 ){ + for (err = first_tuple(handle, &tuple, &parse); !err; + err = next_tuple(handle, &tuple, &parse)){ + if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){ link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = link->io.BasePort2 - + (pass ? ( cf->index & 0x20 ? -24:8 ) - : ( cf->index & 0x20 ? 8:-24) ); - if( !(err=CardServices(RequestIO, link->handle, + + (pass ? (cf->index & 0x20 ? -24:8) + : (cf->index & 0x20 ? 8:-24)); + if (!(err=CardServices(RequestIO, link->handle, &link->io))) goto port_found; } @@ -1124,30 +1092,29 @@ * .... */ } printk(KNOT_XIRC "no ports available\n"); - } - else { + } else { link->irq.Attributes |= IRQ_TYPE_EXCLUSIVE; link->io.NumPorts1 = 16; - for(ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { + for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->io.BasePort1 = ioaddr; - if( !(err=CardServices(RequestIO, link->handle, &link->io)) ) + if (!(err=CardServices(RequestIO, link->handle, &link->io))) goto port_found; } link->io.BasePort1 = 0; /* let CS decide */ - if( (err=CardServices(RequestIO, link->handle, &link->io)) ) { + if ((err=CardServices(RequestIO, link->handle, &link->io))) { cs_error(link->handle, RequestIO, err); goto config_error; } } port_found: - if( err ) + if (err) goto config_error; /**************** * Now allocate an interrupt line. Note that this does not * actually assign a handler to the interrupt. */ - if( (err=CardServices(RequestIRQ, link->handle, &link->irq))) { + if ((err=CardServices(RequestIRQ, link->handle, &link->irq))) { cs_error(link->handle, RequestIRQ, err); goto config_error; } @@ -1156,13 +1123,13 @@ * This actually configures the PCMCIA socket -- setting up * the I/O windows and the interrupt mapping. */ - if( (err=CardServices(RequestConfiguration, - link->handle, &link->conf)) ) { + if ((err=CardServices(RequestConfiguration, + link->handle, &link->conf))) { cs_error(link->handle, RequestConfiguration, err); goto config_error; } - if( local->dingo ) { + if (local->dingo) { #ifdef CEM56_FIX conf_reg_t reg; #endif @@ -1178,16 +1145,16 @@ reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_0; reg.Value = link->io.BasePort2 & 0xff; - if( (err = CardServices(AccessConfigurationRegister, link->handle, - ® )) ) { + if ((err = CardServices(AccessConfigurationRegister, link->handle, + ®))) { cs_error(link->handle, AccessConfigurationRegister, err); goto config_error; } reg.Action = CS_WRITE; reg.Offset = CISREG_IOBASE_1; reg.Value = (link->io.BasePort2 >> 8) & 0xff; - if( (err = CardServices(AccessConfigurationRegister, link->handle, - ® )) ) { + if ((err = CardServices(AccessConfigurationRegister, link->handle, + ®))) { cs_error(link->handle, AccessConfigurationRegister, err); goto config_error; } @@ -1202,14 +1169,14 @@ req.Size = 0x1000; /* 4k window */ req.AccessSpeed = 0; link->win = (window_handle_t)link->handle; - if( (err = CardServices(RequestWindow, &link->win, &req )) ) { + if ((err = CardServices(RequestWindow, &link->win, &req))) { cs_error(link->handle, RequestWindow, err); goto config_error; } local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800; mem.CardOffset = 0x0; mem.Page = 0; - if( (err = CardServices(MapMemPage, link->win, &mem) ) ) { + if ((err = CardServices(MapMemPage, link->win, &mem))) { cs_error(link->handle, MapMemPage, err); goto config_error; } @@ -1217,72 +1184,72 @@ /* Setup the CCRs; there are no infos in the CIS about the Ethernet * part. */ - writeb(0x47, local->dingo_ccr + CISREG_COR ); + writeb(0x47, local->dingo_ccr + CISREG_COR); ioaddr = link->io.BasePort1; - writeb( ioaddr & 0xff , local->dingo_ccr + CISREG_IOBASE_0 ); - writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1 ); + writeb(ioaddr & 0xff , local->dingo_ccr + CISREG_IOBASE_0); + writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1); #if 0 { u_char tmp; - printk(KERN_INFO "ECOR:" ); - for(i=0; i < 7; i++ ) { - tmp = readb(local->dingo_ccr + i*2 ); - printk(" %02x", tmp ); + printk(KERN_INFO "ECOR:"); + for (i=0; i < 7; i++) { + tmp = readb(local->dingo_ccr + i*2); + printk(" %02x", tmp); } - printk("\n" ); - printk(KERN_INFO "DCOR:" ); - for(i=0; i < 4; i++ ) { - tmp = readb(local->dingo_ccr + 0x20 + i*2 ); - printk(" %02x", tmp ); + printk("\n"); + printk(KERN_INFO "DCOR:"); + for (i=0; i < 4; i++) { + tmp = readb(local->dingo_ccr + 0x20 + i*2); + printk(" %02x", tmp); } - printk("\n" ); - printk(KERN_INFO "SCOR:" ); - for(i=0; i < 10; i++ ) { - tmp = readb(local->dingo_ccr + 0x40 + i*2 ); - printk(" %02x", tmp ); + printk("\n"); + printk(KERN_INFO "SCOR:"); + for (i=0; i < 10; i++) { + tmp = readb(local->dingo_ccr + 0x40 + i*2); + printk(" %02x", tmp); } - printk("\n" ); + printk("\n"); } #endif - writeb( 0x01 , local->dingo_ccr + 0x20 ); - writeb( 0x0c , local->dingo_ccr + 0x22 ); - writeb( 0x00 , local->dingo_ccr + 0x24 ); - writeb( 0x00 , local->dingo_ccr + 0x26 ); - writeb( 0x00 , local->dingo_ccr + 0x28 ); + writeb(0x01 , local->dingo_ccr + 0x20); + writeb(0x0c , local->dingo_ccr + 0x22); + writeb(0x00 , local->dingo_ccr + 0x24); + writeb(0x00 , local->dingo_ccr + 0x26); + writeb(0x00 , local->dingo_ccr + 0x28); } /* The if_port symbol can be set when the module is loaded */ local->probe_port=0; - if( !if_port ) { + if (!if_port) { local->probe_port=1; dev->if_port = 1; } - else if( (if_port >= 1 && if_port <= 2) || (local->mohawk && if_port==4) ) + else if ((if_port >= 1 && if_port <= 2) || (local->mohawk && if_port==4)) dev->if_port = if_port; else - printk(KERN_NOTICE "xirc2ps_cs: invalid if_port requested\n"); + printk(KNOT_XIRC "invalid if_port requested\n"); /* we can now register the device with the net subsystem */ dev->irq = link->irq.AssignedIRQ; dev->base_addr = link->io.BasePort1; dev->tbusy = 0; - if( (err=register_netdev(dev)) ) { - printk(KERN_NOTICE "xirc2ps_cs: register_netdev() failed\n"); + if ((err=register_netdev(dev))) { + printk(KNOT_XIRC "register_netdev() failed\n"); goto config_error; } link->state &= ~DEV_CONFIG_PENDING; link->dev = &local->node; - if( local->dingo ) + if (local->dingo) do_reset(dev, 1); /* a kludge to make the cem56 work */ /* give some infos about the hardware */ printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr", - dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq ); - for(i = 0; i < 6; i++) + dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq); + for (i = 0; i < 6; i++) printk("%c%02X", i?':':' ', dev->dev_addr[i]); printk("\n"); @@ -1294,7 +1261,7 @@ return; cis_error: - printk(KERN_NOTICE "xirc2ps_cs: unable to parse CIS\n"); + printk(KNOT_XIRC "unable to parse CIS\n"); failure: link->state &= ~DEV_CONFIG_PENDING; } /* xirc2ps_config */ @@ -1305,35 +1272,29 @@ * still open, this will be postponed until it is closed. */ static void -xirc2ps_release( u_long arg) +xirc2ps_release(u_long arg) { dev_link_t *link = (dev_link_t *) arg; struct net_device *dev = link->priv; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "release(0x%p)\n", link); - #endif + DEBUG(0, "release(0x%p)\n", link); /* * If the device is currently in use, we won't release until it * is actually closed. */ - if(link->open) { - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "release postponed, '%s' " - "still open\n", link->dev->dev_name); - #endif + if (link->open) { + DEBUG(0, "release postponed, '%s' " + "still open\n", link->dev->dev_name); link->state |= DEV_STALE_CONFIG; return; } - if( link->win ) { + if (link->win) { local_info_t *local = dev->priv; - if( local->dingo ) - iounmap( local->dingo_ccr - 0x0800 ); - CardServices(ReleaseWindow, link->win ); + if (local->dingo) + iounmap(local->dingo_ccr - 0x0800); + CardServices(ReleaseWindow, link->win); } CardServices(ReleaseConfiguration, link->handle); CardServices(ReleaseIO, link->handle, &link->io); @@ -1364,21 +1325,15 @@ struct net_device *dev = link->priv; local_info_t *lp = dev? dev->priv : NULL; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "event(%d)\n", (int)event ); - #endif + DEBUG(0, "event(%d)\n", (int)event); switch (event) { case CS_EVENT_REGISTRATION_COMPLETE: - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "registration complete\n"); - #endif + DEBUG(0, "registration complete\n"); break; case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; - if(link->state & DEV_CONFIG) { + if (link->state & DEV_CONFIG) { dev->tbusy = 1; dev->start = 0; link->release.expires = jiffies + HZ / 20; add_timer(&link->release); @@ -1392,8 +1347,8 @@ link->state |= DEV_SUSPEND; /* Fall through... */ case CS_EVENT_RESET_PHYSICAL: - if(link->state & DEV_CONFIG) { - if(link->open) { + if (link->state & DEV_CONFIG) { + if (link->open) { dev->tbusy = 1; dev->start = 0; lp->suspended=1; do_powerdown(dev); @@ -1405,9 +1360,9 @@ link->state &= ~DEV_SUSPEND; /* Fall through... */ case CS_EVENT_CARD_RESET: - if(link->state & DEV_CONFIG) { + if (link->state & DEV_CONFIG) { CardServices(RequestConfiguration, link->handle, &link->conf); - if( link->open) { + if (link->open) { do_reset(dev,1); lp->suspended=0; dev->tbusy = 0; dev->start = 1; @@ -1438,24 +1393,21 @@ * -- on a laptop? */ - if( !dev->start ) + if (!dev->start) return; - if( dev->interrupt ) { + if (dev->interrupt) { printk(KERR_XIRC "re-entering isr on irq %d (dev=%p)\n", irq, dev); return; } dev->interrupt = 1; lp = dev->priv; ioaddr = dev->base_addr; - if( lp->mohawk ) { /* must disable the interrupt */ - PutByte(XIRCREG_CR, 0 ); + if (lp->mohawk) { /* must disable the interrupt */ + PutByte(XIRCREG_CR, 0); } - #ifdef PCMCIA_DEBUG - if(pc_debug > 6 ) - printk(KERN_DEBUG "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr); - #endif + DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr); saved_page = GetByte(XIRCREG_PR); /* Read the ISR to see whats the cause for the interrupt. @@ -1464,91 +1416,74 @@ int_status = GetByte(XIRCREG_ISR); bytes_rcvd = 0; loop_entry: - if( int_status == 0xff ) { /* card may be ejected */ - #ifdef PCMCIA_DEBUG - if( pc_debug > 3 ) - printk(KERN_DEBUG "%s: interrupt %d for dead card\n", dev->name, irq ); - #endif + if (int_status == 0xff) { /* card may be ejected */ + DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq); goto leave; } eth_status = GetByte(XIRCREG_ESR); SelectPage(0x40); rx_status = GetByte(XIRCREG40_RXST0); - PutByte(XIRCREG40_RXST0, (~rx_status & 0xff) ); + PutByte(XIRCREG40_RXST0, (~rx_status & 0xff)); tx_status = GetByte(XIRCREG40_TXST0); tx_status |= GetByte(XIRCREG40_TXST1) << 8; - PutByte(XIRCREG40_TXST0, 0 ); - PutByte(XIRCREG40_TXST1, 0 ); + PutByte(XIRCREG40_TXST0, 0); + PutByte(XIRCREG40_TXST1, 0); - #ifdef PCMCIA_DEBUG - if( pc_debug > 3 ) - printk(KERN_DEBUG "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n", - dev->name, int_status, eth_status, rx_status, tx_status ); - #endif + DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n", + dev->name, int_status, eth_status, rx_status, tx_status); /***** receive section ******/ SelectPage(0); - while( eth_status & FullPktRcvd ) { + while (eth_status & FullPktRcvd) { rsr = GetByte(XIRCREG0_RSR); - if( bytes_rcvd > maxrx_bytes && (rsr & PktRxOk) ) { + if (bytes_rcvd > maxrx_bytes && (rsr & PktRxOk)) { /* too many bytes received during this int, drop the rest of the * packets */ lp->stats.rx_dropped++; - #ifdef PCMCIA_DEBUG - if( pc_debug > 3 ) - printk(KNOT_XIRC "%s: RX drop, too much done\n", dev->name); - #endif - PutWord(XIRCREG0_DO, 0x8000 ); /* issue cmd: skip_rx_packet */ - } - else if( rsr & PktRxOk ) { + printk(KINF_XIRC "%s: RX drop, too much done\n", dev->name); + PutWord(XIRCREG0_DO, 0x8000); /* issue cmd: skip_rx_packet */ + } else if (rsr & PktRxOk) { struct sk_buff *skb; pktlen = GetWord(XIRCREG0_RBC); bytes_rcvd += pktlen; - #ifdef PCMCIA_DEBUG - if( pc_debug > 5 ) - printk(KDBG_XIRC "rsr=%#02x packet_length=%u\n", rsr, pktlen ); - #endif + DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen); skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */ - if( !skb ) { - #ifdef PCMCIA_DEBUG - if( pc_debug ) - printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n", - pktlen ); - #endif + if (!skb) { + printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n", + pktlen); lp->stats.rx_dropped++; - } - else { /* okay get the packet */ + } else { /* okay get the packet */ skb_reserve(skb, 2); - if( lp->silicon == 0 ) { /* work around a hardware bug */ + if (lp->silicon == 0 ) { /* work around a hardware bug */ unsigned rhsa; /* receive start address */ SelectPage(5); rhsa = GetWord(XIRCREG5_RHSA0); SelectPage(0); rhsa += 3; /* skip control infos */ - if( rhsa >= 0x8000 ) + if (rhsa >= 0x8000) rhsa = 0; - if( rhsa + pktlen > 0x8000 ) { + if (rhsa + pktlen > 0x8000) { unsigned i; u_char *buf = skb_put(skb, pktlen); - for(i=0; i < pktlen ; i++, rhsa++ ) { + for (i=0; i < pktlen ; i++, rhsa++) { buf[i] = GetByte(XIRCREG_EDP); - if( rhsa == 0x8000 ) { + if (rhsa == 0x8000) { rhsa = 0; i--; } } } else { insw(ioaddr+XIRCREG_EDP, - skb_put(skb, pktlen), (pktlen+1)>>1 ); + skb_put(skb, pktlen), (pktlen+1)>>1); } } #if 0 - else if( lp->mohawk ) { + else if (lp->mohawk) { /* To use this 32 bit access we should use * a manual optimized loop * Also the words are swapped, we can get more @@ -1561,7 +1496,7 @@ u_long *p = skb_put(skb, pktlen); register u_long a; ioaddr_t edpreg = ioaddr+XIRCREG_EDP-2; - for(i=0; i < len ; i += 4, p++ ) { + for (i=0; i < len ; i += 4, p++) { a = inl(edpreg); __asm__("rorl $16,%0\n\t" :"=q" (a) @@ -1572,129 +1507,100 @@ #endif else { insw(ioaddr+XIRCREG_EDP, skb_put(skb, pktlen), - (pktlen+1)>>1 ); + (pktlen+1)>>1); } skb->protocol = eth_type_trans(skb, dev); skb->dev = dev; netif_rx(skb); lp->stats.rx_packets++; lp->stats.rx_bytes += pktlen; - if( !(rsr & PhyPkt) ) + if (!(rsr & PhyPkt)) lp->stats.multicast++; } - PutWord(XIRCREG0_DO, 0x8000 ); /* issue cmd: skip_rx_packet */ - } - else { - #ifdef PCMCIA_DEBUG - if( pc_debug > 5 ) - printk("rsr=%#02x\n", rsr ); - #endif + PutWord(XIRCREG0_DO, 0x8000); /* issue cmd: skip_rx_packet */ + } else { + DEBUG(5, "rsr=%#02x\n", rsr); } - if( rsr & PktTooLong ) { + if (rsr & PktTooLong) { lp->stats.rx_frame_errors++; - #ifdef PCMCIA_DEBUG - if( pc_debug > 3 ) - printk(KNOT_XIRC "%s: Packet too long\n", dev->name); - #endif + DEBUG(3, "%s: Packet too long\n", dev->name); } - if( rsr & CRCErr ) { + if (rsr & CRCErr) { lp->stats.rx_crc_errors++; - #ifdef PCMCIA_DEBUG - if( pc_debug > 3 ) - printk(KNOT_XIRC "%s: CRC error\n", dev->name); - #endif + DEBUG(3, "%s: CRC error\n", dev->name); } - if( rsr & AlignErr ) { + if (rsr & AlignErr) { lp->stats.rx_fifo_errors++; /* okay ? */ - #ifdef PCMCIA_DEBUG - if( pc_debug > 3 ) - printk(KNOT_XIRC "%s: Alignment error\n", dev->name); - #endif + DEBUG(3, "%s: Alignment error\n", dev->name); } /* get the new ethernet status */ eth_status = GetByte(XIRCREG_ESR); } - if( rx_status & 0x10 ) { /* Receive overrun */ + if (rx_status & 0x10) { /* Receive overrun */ lp->stats.rx_over_errors++; PutByte(XIRCREG_CR, ClearRxOvrun); - #ifdef PCMCIA_DEBUG - if( pc_debug > 3 ) - printk(KDBG_XIRC "receive overrun cleared\n" ); - #endif + DEBUG(3, "receive overrun cleared\n"); } /***** transmit section ******/ - if( int_status & PktTxed ) { + if (int_status & PktTxed) { unsigned n, nn; n = lp->last_ptr_value; nn = GetByte(XIRCREG0_PTR); lp->last_ptr_value = nn; - if( nn < n ) /* rollover */ + if (nn < n) /* rollover */ lp->stats.tx_packets += 256 - n; - else if( n == nn ) { /* happens sometimes - don't know why */ - #ifdef PCMCIA_DEBUG - if( pc_debug ) - printk(KDBG_XIRC "PTR not changed?\n" ); - #endif - } - else + else if (n == nn) { /* happens sometimes - don't know why */ + DEBUG(0, "PTR not changed?\n"); + } else lp->stats.tx_packets += lp->last_ptr_value - n; dev->tbusy = 0; mark_bh(NET_BH); /* Inform upper layers. */ } - if( tx_status & 0x0002 ) { /* Execessive collissions */ - #ifdef PCMCIA_DEBUG - if( pc_debug ) - printk(KDBG_XIRC "tx restarted due to execssive collissions\n" ); - #endif - PutByte(XIRCREG_CR, RestartTx ); /* restart transmitter process */ + if (tx_status & 0x0002) { /* Execessive collissions */ + DEBUG(0, "tx restarted due to execssive collissions\n"); + PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */ } - if( tx_status & 0x0040 ) + if (tx_status & 0x0040) lp->stats.tx_aborted_errors++; /* recalculate our work chunk so that we limit the duration of this * ISR to about 1/10 of a second. * Calculate only if we received a reasonable amount of bytes. */ - if( bytes_rcvd > 1000 ) { + if (bytes_rcvd > 1000) { u_long duration = jiffies - start_ticks; - if( duration >= HZ/10 ) { /* if more than about 1/10 second */ + if (duration >= HZ/10) { /* if more than about 1/10 second */ maxrx_bytes = (bytes_rcvd * (HZ/10)) / duration; - if( maxrx_bytes < 2000 ) + if (maxrx_bytes < 2000) maxrx_bytes = 2000; - else if( maxrx_bytes > 22000 ) + else if (maxrx_bytes > 22000) maxrx_bytes = 22000; - #ifdef PCMCIA_DEBUG - if( pc_debug > 1) - printk(KDBG_XIRC "set maxrx=%u (rcvd=%u ticks=%lu)\n", - maxrx_bytes, bytes_rcvd, duration ); - #endif - } - else if( !duration && maxrx_bytes < 22000 ) { /* now much faster*/ + DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n", + maxrx_bytes, bytes_rcvd, duration); + } else if (!duration && maxrx_bytes < 22000) { + /* now much faster */ maxrx_bytes += 2000; - if( maxrx_bytes > 22000 ) + if (maxrx_bytes > 22000) maxrx_bytes = 22000; - #ifdef PCMCIA_DEBUG - if( pc_debug > 1 ) - printk(KDBG_XIRC "set maxrx=%u\n", maxrx_bytes ); - #endif + DEBUG(1, "set maxrx=%u\n", maxrx_bytes); } } leave: - if( lockup_hack ) { - if( int_status != 0xff && (int_status = GetByte(XIRCREG_ISR)) != 0 ) + if (lockup_hack) { + if (int_status != 0xff && (int_status = GetByte(XIRCREG_ISR)) != 0) goto loop_entry; } SelectPage(saved_page); dev->interrupt = 0; - PutByte(XIRCREG_CR, EnableIntr ); /* re-enable interrupts */ + PutByte(XIRCREG_CR, EnableIntr); /* re-enable interrupts */ /* Instead of dropping packets during a receive, we could * force an interrupt with this command: - * PutByte(XIRCREG_CR, EnableIntr|ForceIntr ); + * PutByte(XIRCREG_CR, EnableIntr|ForceIntr); */ } /* xirc2ps_interrupt */ @@ -1709,26 +1615,23 @@ unsigned freespace; unsigned pktlen = skb? skb->len : 0; - #ifdef PCMCIA_DEBUG - if(pc_debug>1 ) - printk(KDBG_XIRC "do_start_xmit(skb=%p, dev=%p) len=%u\n", - skb, dev, pktlen ); - #endif + DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n", + skb, dev, pktlen); /* Transmitter timeout, serious problems */ - if( dev->tbusy ) { + if (dev->tbusy) { int tickssofar = jiffies - dev->trans_start; - if( lp->suspended ) { + if (lp->suspended) { dev_kfree_skb (skb); dev->trans_start = jiffies; lp->stats.tx_dropped++; return 0; } - if( tickssofar < TX_TIMEOUT ) + if (tickssofar < TX_TIMEOUT) return 1; - printk(KERN_NOTICE "%s: transmit timed out\n", dev->name ); + printk(KERN_NOTICE "%s: transmit timed out\n", dev->name); lp->stats.tx_errors++; /* reset the card */ do_reset(dev,1); @@ -1736,7 +1639,7 @@ dev->tbusy = 0; } - if( test_and_set_bit(0, (void*)&dev->tbusy ) ) { + if (test_and_set_bit(0, (void*)&dev->tbusy)) { printk(KWRN_XIRC "transmitter access conflict\n"); dev_kfree_skb (skb); return 0; @@ -1749,33 +1652,30 @@ * a larger packetlen than we actually have; the chip will * pad this in his buffer with random bytes */ - if( pktlen < ETH_ZLEN ) + if (pktlen < ETH_ZLEN) pktlen = ETH_ZLEN; SelectPage(0); - PutWord(XIRCREG0_TRS, (u_short)pktlen+2 ); + PutWord(XIRCREG0_TRS, (u_short)pktlen+2); freespace = GetWord(XIRCREG0_TSO); okay = freespace & 0x8000; freespace &= 0x7fff; /* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */ okay = pktlen +2 < freespace; - #ifdef PCMCIA_DEBUG - if(pc_debug > 2 + ( okay ? 2 : 0) ) - printk(KERN_DEBUG "%s: avail. tx space=%u%s\n", dev->name, freespace, - okay? " (okay)":" (not enough)" ); - #endif - if( !okay ) { /* not enough space */ + DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n", + dev->name, freespace, okay ? " (okay)":" (not enough)"); + if (!okay) { /* not enough space */ dev->tbusy = 1; return 1; /* upper layer may decide to requeue this packet */ } /* send the packet */ - PutWord(XIRCREG_EDP, (u_short)pktlen ); - outsw(ioaddr+XIRCREG_EDP, skb->data, pktlen>>1 ); - if( pktlen & 1 ) - PutByte(XIRCREG_EDP, skb->data[pktlen-1] ); + PutWord(XIRCREG_EDP, (u_short)pktlen); + outsw(ioaddr+XIRCREG_EDP, skb->data, pktlen>>1); + if (pktlen & 1) + PutByte(XIRCREG_EDP, skb->data[pktlen-1]); - if( lp->mohawk ) - PutByte(XIRCREG_CR, TransmitPacket|EnableIntr ); + if (lp->mohawk) + PutByte(XIRCREG_CR, TransmitPacket|EnableIntr); dev_kfree_skb (skb); dev->trans_start = jiffies; @@ -1808,29 +1708,28 @@ int i,j,k,n; SelectPage(k=0x50); - for(i=0,j=8,n=0; ; i++, j++) { - if( i > 5 ) { - if( ++n > 9 ) + for (i=0,j=8,n=0; ; i++, j++) { + if (i > 5) { + if (++n > 9) break; i = 0; } - if( j > 15 ) { + if (j > 15) { j = 8; k++; SelectPage(k); } - if( n && n <= dev->mc_count && dmi ) { + if (n && n <= dev->mc_count && dmi) { addr = dmi->dmi_addr; dmi = dmi->next; - } - else + } else addr = dev->dev_addr; - if( lp->mohawk ) - PutByte( j, addr[5-i] ); + if (lp->mohawk) + PutByte(j, addr[5-i]); else - PutByte( j, addr[i] ); + PutByte(j, addr[i]); } SelectPage(0); } @@ -1847,21 +1746,19 @@ ioaddr_t ioaddr = dev->base_addr; SelectPage(0x42); - if( dev->flags & IFF_PROMISC ) { /* snoop */ + if (dev->flags & IFF_PROMISC) { /* snoop */ PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */ - } - else if( dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI) ) { + } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) { PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */ - } - else if( dev->mc_count ) { /* the chip can filter 9 addresses perfectly */ + } else if (dev->mc_count) { + /* the chip can filter 9 addresses perfectly */ PutByte(XIRCREG42_SWC1, 0x00); SelectPage(0x40); - PutByte(XIRCREG40_CMD0, Offline ); + PutByte(XIRCREG40_CMD0, Offline); set_addresses(dev); SelectPage(0x40); - PutByte(XIRCREG40_CMD0, EnableRecv | Online ); - } - else { /* standard usage */ + PutByte(XIRCREG40_CMD0, EnableRecv | Online); + } else { /* standard usage */ PutByte(XIRCREG42_SWC1, 0x00); } SelectPage(0); @@ -1874,10 +1771,7 @@ static int do_init(struct net_device *dev) { - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "do_init(%p)\n", dev ); - #endif + DEBUG(0, "do_init(%p)\n", dev); return 0; } @@ -1886,30 +1780,25 @@ { local_info_t *local = dev->priv; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "do_config(%p)\n", dev ); - #endif - - if( map->port != 255 && map->port != dev->if_port ) { - if( map->port <= 4 ) { - if( !map->port ) { - local->probe_port = 1; - dev->if_port = 1; - } - else { - local->probe_port = 0; - dev->if_port = map->port; - } - printk(KERN_INFO "%s: switching to %s port\n", - dev->name, if_names[dev->if_port]); - do_reset(dev,1); /* not the fine way :-) */ - } - else + DEBUG(0, "do_config(%p)\n", dev); + if (map->port != 255 && map->port != dev->if_port) { + if (local->new_mii) + return -EOPNOTSUPP; + if (map->port > 4) return -EINVAL; + if (!map->port) { + local->probe_port = 1; + dev->if_port = 1; + } else { + local->probe_port = 0; + dev->if_port = map->port; + } + printk(KERN_INFO "%s: switching to %s port\n", + dev->name, if_names[dev->if_port]); + do_reset(dev,1); /* not the fine way :-) */ } #ifdef PCMCIA_DEBUG - else if( map->port == dev->if_port && local->mohawk ) { + else if (local->mohawk) { /* kludge to print the mii regsiters */ mii_dump(dev); } @@ -1926,17 +1815,14 @@ local_info_t *lp = dev->priv; dev_link_t *link; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "do_open(%p)\n", dev ); - #endif + DEBUG(0, "do_open(%p)\n", dev); /* Check that the PCMCIA card is still here. */ - for( link = dev_list; link; link = link->next ) - if( link->priv == dev ) + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; /* Physical device present signature. */ - if( !DEV_OK(link) ) + if (!DEV_OK(link)) return -ENODEV; /* okay */ @@ -1957,25 +1843,22 @@ ioaddr_t ioaddr = dev->base_addr; u16 *data = (u16 *)&rq->ifr_data; - #ifdef PCMCIA_DEBUG - if(pc_debug > 1) - printk(KERN_DEBUG "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n", - dev->name, rq->ifr_ifrn.ifrn_name, cmd, - data[0], data[1], data[2], data[3] ); - #endif + DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n", + dev->name, rq->ifr_ifrn.ifrn_name, cmd, + data[0], data[1], data[2], data[3]); - if( !local->mohawk ) + if (!local->mohawk) return -EOPNOTSUPP; - switch( cmd ) { + switch(cmd) { case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ data[0] = 0; /* we have only this address */ /* fall trough */ case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ - data[3] = mii_rd( ioaddr, data[0] & 0x1f, data[1] & 0x1f); + data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f); break; case SIOCDEVPRIVATE+2: /* Write the specified MII register */ - if( !suser() ) + if (!suser()) return -EPERM; mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16); break; @@ -1995,7 +1878,7 @@ udelay(1); PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */ busy_loop(HZ/25); /* wait 40 msec */ - if( local->mohawk ) + if (local->mohawk) PutByte(XIRCREG4_GPR1, 1); /* set bit 0: power up */ else PutByte(XIRCREG4_GPR1, 1 | 4); /* set bit 0: power up, bit 2: AIC */ @@ -2009,18 +1892,14 @@ ioaddr_t ioaddr = dev->base_addr; unsigned value; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KERN_DEBUG "%s: do_reset(%p,%d)\n", - dev? dev->name:"eth?", dev, full ); - #endif + DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full); hardreset(dev); - PutByte(XIRCREG_CR, SoftReset ); /* set */ + PutByte(XIRCREG_CR, SoftReset); /* set */ busy_loop(HZ/50); /* wait 20 msec */ - PutByte(XIRCREG_CR, 0 ); /* clear */ + PutByte(XIRCREG_CR, 0); /* clear */ busy_loop(HZ/25); /* wait 40 msec */ - if( local->mohawk ) { + if (local->mohawk) { SelectPage(4); /* set pin GP1 and GP2 to output (0x0c) * set GP1 to low to power up the ML6692 (0x00) @@ -2036,25 +1915,23 @@ local->silicon = local->mohawk ? (GetByte(XIRCREG4_BOV) & 0x70) >> 4 : (GetByte(XIRCREG4_BOV) & 0x30) >> 4; - if( local->probe_port ) { - if( !local->mohawk ) { + if (local->probe_port) { + if (!local->mohawk) { SelectPage(4); PutByte(XIRCREG4_GPR0, 4); local->probe_port = 0; } - } - else if( dev->if_port == 2 ) { /* enable 10Base2 */ + } else if (dev->if_port == 2) { /* enable 10Base2 */ SelectPage(0x42); PutByte(XIRCREG42_SWC1, 0xC0); - } - else { /* enable 10BaseT */ + } else { /* enable 10BaseT */ SelectPage(0x42); PutByte(XIRCREG42_SWC1, 0x80); } busy_loop(HZ/25); /* wait 40 msec to let it complete */ #ifdef PCMCIA_DEBUG - if(pc_debug) { + if (pc_debug) { SelectPage(0); value = GetByte(XIRCREG_ESR); /* read the ESR */ printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value); @@ -2063,33 +1940,30 @@ /* setup the ECR */ SelectPage(1); - PutByte(XIRCREG1_IMR0, 0xff ); /* allow all ints */ + PutByte(XIRCREG1_IMR0, 0xff); /* allow all ints */ PutByte(XIRCREG1_IMR1, 1 ); /* and Set TxUnderrunDetect */ value = GetByte(XIRCREG1_ECR); #if 0 - if( local->mohawk ) + if (local->mohawk) value |= DisableLinkPulse; PutByte(XIRCREG1_ECR, value); #endif - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KERN_DEBUG "%s: ECR is: %#02x\n", dev->name, value); - #endif + DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value); SelectPage(0x42); PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */ - if( local->silicon != 1 ) { + if (local->silicon != 1) { /* set the local memory dividing line. * The comments in the sample code say that this is only * settable with the scipper version 2 which is revision 0. * Always for CE3 cards */ SelectPage(2); - PutWord(XIRCREG2_RBS, 0x2000 ); + PutWord(XIRCREG2_RBS, 0x2000); } - if( full ) + if (full) set_addresses(dev); /* Hardware workaround: @@ -2097,7 +1971,7 @@ * to move the offset pointer back to 0. */ SelectPage(0); - PutWord(XIRCREG0_DO, 0x2000 ); /* change offset command, off=0 */ + PutWord(XIRCREG0_DO, 0x2000); /* change offset command, off=0 */ /* setup MAC IMRs and clear status registers */ SelectPage(0x40); /* Bit 7 ... bit 0 */ @@ -2108,36 +1982,23 @@ PutByte(XIRCREG40_TXST0, 0x00); /* TOK, TAB, SQE, LL, TU, JAB, EXC, CRS */ PutByte(XIRCREG40_TXST1, 0x00); /* TEN, rsv, PTD, EXT, retry_counter:4 */ - if( full && local->mohawk && init_mii(dev) ) { - if( dev->if_port == 4 || local->dingo ) { /* and use it */ - SelectPage(2); - value = GetByte(XIRCREG2_MSR); - value |= 0x08; /* Select MII */ - PutByte(XIRCREG2_MSR, value); - busy_loop(HZ/50); /* wait 20 msec */ - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KERN_DEBUG "%s: MII selected\n", dev->name); - #endif - } - else { + if (full && local->mohawk && init_mii(dev)) { + if (dev->if_port == 4 || local->dingo || local->new_mii) { + printk(KERN_INFO "%s: MII selected\n", dev->name); SelectPage(2); PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08); busy_loop(HZ/50); - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KERN_DEBUG "%s: MII detected; using 10mbs\n", - dev->name); - #endif + } else { + printk(KERN_INFO "%s: MII detected; using 10mbs\n", + dev->name); SelectPage(0x42); - if( dev->if_port == 2 ) /* enable 10Base2 */ + if (dev->if_port == 2) /* enable 10Base2 */ PutByte(XIRCREG42_SWC1, 0xC0); else /* enable 10BaseT */ PutByte(XIRCREG42_SWC1, 0x80); busy_loop(HZ/25); /* wait 40 msec to let it complete */ } - } - else { /* No MII */ + } else { /* No MII */ SelectPage(0); value = GetByte(XIRCREG_ESR); /* read the ESR */ dev->if_port = (value & MediaSelect) ? 1 : 2; @@ -2145,34 +2006,34 @@ /* configure the LEDs */ SelectPage(2); - if( dev->if_port == 1 || dev->if_port == 4 ) /* TP: Link and Activity */ - PutByte(XIRCREG2_LED, 0x3b ); + if (dev->if_port == 1 || dev->if_port == 4) /* TP: Link and Activity */ + PutByte(XIRCREG2_LED, 0x3b); else /* Coax: Not-Collision and Activity */ - PutByte(XIRCREG2_LED, 0x3a ); + PutByte(XIRCREG2_LED, 0x3a); if (local->dingo) - PutByte( 0x0b, 0x04 ); /* 100 Mbit LED */ + PutByte(0x0b, 0x04); /* 100 Mbit LED */ /* enable receiver and put the mac online */ - if( full ) { + if (full) { SelectPage(0x40); - PutByte(XIRCREG40_CMD0, EnableRecv | Online ); + PutByte(XIRCREG40_CMD0, EnableRecv | Online); } /* setup Ethernet IMR and enable interrupts */ SelectPage(1); - PutByte(XIRCREG1_IMR0, 0xff ); + PutByte(XIRCREG1_IMR0, 0xff); udelay(1); SelectPage(0); - PutByte(XIRCREG_CR, EnableIntr ); - if( local->modem && !local->dingo ) { /* do some magic */ - if( !(GetByte( 0x10 ) & 0x01 ) ) - PutByte( 0x10, 0x11 ); /* unmask master-int bit */ + PutByte(XIRCREG_CR, EnableIntr); + if (local->modem && !local->dingo) { /* do some magic */ + if (!(GetByte(0x10) & 0x01)) + PutByte(0x10, 0x11); /* unmask master-int bit */ } - if( full ) - printk(KERN_INFO "%s: media %s, silicon revision %d\n", dev->name, - if_names[dev->if_port], local->silicon); + if (full) + printk(KERN_INFO "%s: media %s, silicon revision %d\n", + dev->name, if_names[dev->if_port], local->silicon); /* We should switch back to page 0 to avoid a bug in revision 0 * where regs with offset below 8 can't be read after an access * to the MAC registers */ @@ -2192,68 +2053,70 @@ int i; #ifdef PCMCIA_DEBUG - if(pc_debug>1) { + if (pc_debug>1) { mii_dump(dev); } #endif - status = mii_rd(ioaddr, 0, 1 ); - if( (status & 0xff00) != 0x7800 ) + status = mii_rd(ioaddr, 0, 1); + if ((status & 0xff00) != 0x7800) return 0; /* No MII */ - if( local->probe_port ) + local->new_mii = (mii_rd(ioaddr, 0, 2) != 0xffff); + + if (local->new_mii || local->probe_port) control = 0x1000; /* auto neg */ - else if( dev->if_port == 4 ) + else if (dev->if_port == 4) control = 0x2000; /* no auto neg, 100mbs mode */ else control = 0x0000; /* no auto neg, 10mbs mode */ - mii_wr(ioaddr, 0, 0, control, 16 ); + mii_wr(ioaddr, 0, 0, control, 16); udelay(100); - control = mii_rd(ioaddr, 0, 0 ); + control = mii_rd(ioaddr, 0, 0); - if( control & 0x0400 ) { + if (control & 0x0400) { printk(KERN_NOTICE "%s can't take PHY out of isolation mode\n", - dev->name); + dev->name); local->probe_port = 0; return 0; } - if( local->probe_port ) { + if (local->new_mii || local->probe_port) { /* according to the DP83840A specs the auto negotation process * may take up to 3.5 sec, so we use this also for our ML6692 * Fixme: Better to use a timer here! */ - for(i=0; i < 35; i++ ) { + for (i=0; i < 35; i++) { busy_loop(HZ/10); /* wait 100 msec */ - status = mii_rd(ioaddr, 0, 1 ); - if( (status & 0x0020) && (status & 0x0004) ) + status = mii_rd(ioaddr, 0, 1); + if ((status & 0x0020) && (status & 0x0004)) break; } - if( !(status & 0x0020) ) { - printk(KERN_NOTICE "%s: auto negotation failed;" - " using 10mbs\n", dev->name ); - control = 0x0000; - mii_wr(ioaddr, 0, 0, control, 16 ); - udelay(100); - SelectPage(0); - dev->if_port = (GetByte(XIRCREG_ESR) & MediaSelect) ? 1 : 2; - } - else { - linkpartner = mii_rd(ioaddr, 0, 5 ); - printk(KERN_INFO "%s: MII link partner: %04x\n", dev->name, - linkpartner ); - if( linkpartner & 0x0080 ) { /* 100BaseTx capability */ - dev->if_port = 4; + if (!(status & 0x0020)) { + printk(KERN_INFO "%s: auto negotation failed;" + " using 10mbs\n", dev->name); + if (!local->new_mii) { + control = 0x0000; + mii_wr(ioaddr, 0, 0, control, 16); + udelay(100); + SelectPage(0); + dev->if_port = (GetByte(XIRCREG_ESR) & MediaSelect) ? 1 : 2; } - else + } else { + linkpartner = mii_rd(ioaddr, 0, 5); + printk(KERN_INFO "%s: MII link partner: %04x\n", + dev->name, linkpartner); + if (linkpartner & 0x0080) { + dev->if_port = 4; + } else dev->if_port = 1; } local->probe_port = 0; } #ifdef PCMCIA_DEBUG - if( pc_debug ) + if (pc_debug) mii_dump(dev); #endif @@ -2266,10 +2129,7 @@ ioaddr_t ioaddr = dev->base_addr; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "do_powerdown(%p)\n", dev ); - #endif + DEBUG(0, "do_powerdown(%p)\n", dev); SelectPage(4); PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */ @@ -2277,33 +2137,26 @@ } static int -do_stop( struct net_device *dev) +do_stop(struct net_device *dev) { ioaddr_t ioaddr = dev->base_addr; dev_link_t *link; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "do_stop(%p)\n", dev ); - #endif + DEBUG(0, "do_stop(%p)\n", dev); - for(link = dev_list; link; link = link->next) - if(link->priv == dev) + for (link = dev_list; link; link = link->next) + if (link->priv == dev) break; - if( !link ) + if (!link) return -ENODEV; - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "shutting down\n"); - #endif dev->tbusy = 1; dev->start = 0; SelectPage(0); - PutByte(XIRCREG_CR, 0 ); /* disable interrupts */ + PutByte(XIRCREG_CR, 0); /* disable interrupts */ SelectPage(0x01); - PutByte(XIRCREG1_IMR0, 0x00 ); /* forbid all ints */ + PutByte(XIRCREG1_IMR0, 0x00); /* forbid all ints */ SelectPage(4); PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */ SelectPage(0); @@ -2326,19 +2179,16 @@ servinfo_t serv; printk(KERN_INFO "%s\n", version); - if( card_type ) + if (card_type) printk(KINF_XIRC "option card_type is obsolete\n"); - if( lockup_hack ) + if (lockup_hack) printk(KINF_XIRC "lockup hack is enabled\n"); CardServices(GetCardServicesInfo, &serv); - if( serv.Revision != CS_RELEASE_CODE ) { + if (serv.Revision != CS_RELEASE_CODE) { printk(KNOT_XIRC "Card Services release does not match!\n"); return -1; } - #ifdef PCMCIA_DEBUG - if( pc_debug ) - printk(KDBG_XIRC "pc_debug=%d\n", pc_debug); - #endif + DEBUG(0, "pc_debug=%d\n", pc_debug); register_pccard_driver(&dev_info, &xirc2ps_attach, &xirc2ps_detach); return 0; } @@ -2346,16 +2196,13 @@ static void __exit exit_xirc2ps_cs(void) { - #ifdef PCMCIA_DEBUG - if(pc_debug) - printk(KDBG_XIRC "unloading\n"); - #endif + DEBUG(0, "unloading\n"); unregister_pccard_driver(&dev_info); - while( dev_list ) { - if( dev_list->state & DEV_CONFIG ) - xirc2ps_release( (u_long)dev_list ); - if( dev_list ) /* xirc2ps_release() might already have detached... */ - xirc2ps_detach( dev_list ); + while (dev_list) { + if (dev_list->state & DEV_CONFIG) + xirc2ps_release((u_long)dev_list); + if (dev_list) /* xirc2ps_release() might already have detached... */ + xirc2ps_detach(dev_list); } } diff -u --recursive --new-file v2.3.26/linux/drivers/net/pcnet32.c linux/drivers/net/pcnet32.c --- v2.3.26/linux/drivers/net/pcnet32.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/net/pcnet32.c Tue Nov 9 08:20:12 1999 @@ -268,8 +268,8 @@ #endif }; -int pcnet32_probe(struct net_device *); -static int pcnet32_probe1(struct net_device *, unsigned long, unsigned char, int, int); +int pcnet32_probe(void); +static int pcnet32_probe1(unsigned long, unsigned char, int, int); static int pcnet32_open(struct net_device *); static int pcnet32_init_ring(struct net_device *); static int pcnet32_start_xmit(struct sk_buff *, struct net_device *); @@ -291,7 +291,7 @@ const char *name; u16 vendor_id, device_id, svid, sdid, flags; int io_size; - int (*probe1) (struct net_device *, unsigned long, unsigned char, int, int); + int (*probe1) (unsigned long, unsigned char, int, int); }; static struct pcnet32_pci_id_info pcnet32_tbl[] = { @@ -419,10 +419,10 @@ -int __init pcnet32_probe (struct net_device *dev) +int __init pcnet32_probe(void) { - unsigned long ioaddr = dev ? dev->base_addr: 0; - unsigned int irq_line = dev ? dev->irq : 0; + unsigned long ioaddr = 0; // FIXME dev ? dev->base_addr: 0; + unsigned int irq_line = 0; // FIXME dev ? dev->irq : 0; int *port; int cards_found = 0; @@ -430,7 +430,7 @@ #ifndef __powerpc__ if (ioaddr > 0x1ff) { if (check_region(ioaddr, PCNET32_TOTAL_SIZE) == 0) - return pcnet32_probe1(dev, ioaddr, irq_line, 0, 0); + return pcnet32_probe1(ioaddr, irq_line, 0, 0); else return ENODEV; } else @@ -481,9 +481,8 @@ } printk("Found PCnet/PCI at %#lx, irq %d.\n", ioaddr, irq_line); - if (pcnet32_tbl[chip_idx].probe1(dev, ioaddr, irq_line, 1, cards_found) == 0) { + if (pcnet32_tbl[chip_idx].probe1(ioaddr, irq_line, 1, cards_found) == 0) { cards_found++; - dev = NULL; } } } else @@ -497,7 +496,7 @@ /* check if there is really a pcnet chip on that ioaddr */ if ((inb(ioaddr + 14) == 0x57) && (inb(ioaddr + 15) == 0x57) && - (pcnet32_probe1(dev, ioaddr, 0, 0, 0) == 0)) + (pcnet32_probe1(ioaddr, 0, 0, 0) == 0)) cards_found++; } } @@ -507,13 +506,14 @@ /* pcnet32_probe1 */ static int __init -pcnet32_probe1(struct net_device *dev, unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx) +pcnet32_probe1(unsigned long ioaddr, unsigned char irq_line, int shared, int card_idx) { struct pcnet32_private *lp; int i,media,fdx = 0, mii = 0, fset = 0; int chip_version; char *chipname; char *priv; + struct net_device *dev; struct pcnet32_access *a; /* reset the chip */ @@ -602,7 +602,9 @@ a->write_csr(ioaddr, 80, a->read_csr(ioaddr, 80) | 0x0c00); } - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); + if(dev==NULL) + return ENOMEM; printk(KERN_INFO "%s: %s at %#3lx,", dev->name, chipname, ioaddr); @@ -1399,7 +1401,7 @@ pcnet32_debug = debug; pcnet32_dev = NULL; - return pcnet32_probe(NULL); + return pcnet32_probe(); } void diff -u --recursive --new-file v2.3.26/linux/drivers/net/ppp_async.c linux/drivers/net/ppp_async.c --- v2.3.26/linux/drivers/net/ppp_async.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/net/ppp_async.c Wed Nov 10 19:55:03 1999 @@ -64,6 +64,7 @@ struct ppp_channel chan; /* interface to generic ppp layer */ int connected; + int index; unsigned char obuf[OBUFSIZE]; }; @@ -387,6 +388,7 @@ if (err != 0) break; ap->connected = 1; + ap->index = val; break; case PPPIOCDETACH: err = -ENXIO; @@ -394,6 +396,14 @@ break; ppp_unregister_channel(&ap->chan); ap->connected = 0; + err = 0; + break; + case PPPIOCGUNIT: + err = -ENXIO; + if (!ap->connected) + break; + if (put_user(ap->index, (int *) arg)) + break; err = 0; break; diff -u --recursive --new-file v2.3.26/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c --- v2.3.26/linux/drivers/net/ppp_generic.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/net/ppp_generic.c Tue Nov 9 11:50:49 1999 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -554,8 +555,7 @@ /* Called at boot time if ppp is compiled into the kernel, or at module load time (from init_module) if compiled as a module. */ -int -ppp_init(struct net_device *dev) +int __init ppp_init(void) { int err; #ifndef MODULE @@ -1614,7 +1614,7 @@ int init_module(void) { - ppp_init(0); + ppp_init(); return 0; } diff -u --recursive --new-file v2.3.26/linux/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c --- v2.3.26/linux/drivers/net/rcpci45.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/rcpci45.c Tue Nov 9 08:20:12 1999 @@ -158,8 +158,8 @@ static int RCinit(struct net_device *dev); -static int RCscan(struct net_device *dev); -static int RCfound_device(struct net_device *, int, int, int, int, int, int); +static int RCscan(void); +static int RCfound_device(int, int, int, int, int, int); static int RCopen(struct net_device *); static int RC_xmit_packet(struct sk_buff *, struct net_device *); @@ -181,22 +181,18 @@ #ifdef MODULE int init_module(void) #else -int rcpci_probe(struct net_device *dev) +int rcpci_probe(void) #endif { int cards_found; -#ifdef MODULE - cards_found = RCscan(NULL); -#else - cards_found = RCscan(dev); -#endif + cards_found = RCscan(); if (cards_found) printk(version); return cards_found ? 0 : -ENODEV; } -static int RCscan(struct net_device *dev) +static int RCscan(void) { int cards_found = 0; static int pci_index = 0; @@ -237,13 +233,10 @@ pci_set_master(pdev); - if (!RCfound_device(dev, pci_ioaddr, pci_irq_line, + if (!RCfound_device(pci_ioaddr, pci_irq_line, pci_bus, pci_device_fn, board_index++, cards_found)) - { - dev = 0; cards_found++; - } } #ifdef RCDEBUG printk("rc: found %d cards \n", cards_found); @@ -263,7 +256,7 @@ } static int -RCfound_device(struct net_device *dev, int memaddr, int irq, +RCfound_device(int memaddr, int irq, int bus, int function, int product_index, int card_idx) { int dev_size = 32768; @@ -271,6 +264,8 @@ PDPA pDpa; int init_status; + struct net_device *dev; + /* * Allocate and fill new device structure. * We need enough for struct net_device plus DPA plus the LAN API private @@ -280,7 +275,6 @@ * the LAN API layer. */ -#ifdef MODULE dev = (struct net_device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); if (!dev) { @@ -292,16 +286,6 @@ * dev->priv will point to the start of DPA. */ dev->priv = (void *)(((long)dev + sizeof(struct net_device) + 15) & ~15); -#else - dev->priv = 0; - dev->priv = (struct net_device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC); - if (!dev->priv) - { - printk("rc: unable to kmalloc private area\n"); - return 1; - } - memset(dev->priv, 0, dev_size); -#endif #ifdef RCDEBUG printk("rc: dev = 0x%x, dev->priv = 0x%x\n", (uint)dev, (uint)dev->priv); @@ -386,7 +370,6 @@ pDpa->next = root_RCdev; root_RCdev = dev; -#ifdef MODULE if (register_netdev(dev) != 0) /* linux kernel interface */ { printk("rc: unable to register device \n"); @@ -395,9 +378,6 @@ kfree(dev); return 1; } -#else - RCinit(dev); -#endif printk("%s: RedCreek Communications IPSEC VPN adapter\n", dev->name); diff -u --recursive --new-file v2.3.26/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c --- v2.3.26/linux/drivers/net/rrunner.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/rrunner.c Tue Nov 9 08:20:12 1999 @@ -72,10 +72,11 @@ static int probed __initdata = 0; -int __init rr_hippi_probe (struct net_device *dev) +int __init rr_hippi_probe (void) { int boards_found = 0; int version_disp; /* was version info already displayed? */ + struct net_device *dev; struct pci_dev *pdev = NULL; struct pci_dev *opdev = NULL; u8 pci_latency; @@ -101,7 +102,7 @@ * So we found our HIPPI ... time to tell the system. */ - dev = init_hippi_dev(dev, sizeof(struct rr_private)); + dev = init_hippi_dev(NULL, sizeof(struct rr_private)); if (!dev) break; @@ -192,14 +193,7 @@ * 1 or more boards. Otherwise, return failure (-ENODEV). */ -#ifdef MODULE return boards_found; -#else - if (boards_found > 0) - return 0; - else - return -ENODEV; -#endif } static struct net_device *root_dev = NULL; @@ -213,12 +207,7 @@ int init_module(void) { - int cards; - - root_dev = NULL; - - cards = rr_hippi_probe(NULL); - return cards ? 0 : -ENODEV; + return rr_hippi_probe()? 0 : -ENODEV; } void cleanup_module(void) diff -u --recursive --new-file v2.3.26/linux/drivers/net/rtl8139.c linux/drivers/net/rtl8139.c --- v2.3.26/linux/drivers/net/rtl8139.c Fri Sep 10 23:57:30 1999 +++ linux/drivers/net/rtl8139.c Tue Nov 9 08:20:12 1999 @@ -165,12 +165,10 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_idx, int fnd_cnt); + struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; -static struct net_device * rtl8129_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, +static struct net_device * rtl8129_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chp_idx, int fnd_cnt); static struct pci_id_info pci_tbl[] = @@ -319,11 +317,12 @@ well when dynamically adding drivers. So instead we detect just the Rtl81*9 cards in slot order. */ -int rtl8139_probe(struct net_device *dev) +int rtl8139_probe(void) { int cards_found = 0; int pci_index = 0; unsigned char pci_bus, pci_device_fn; + struct net_device *dev; if ( ! pcibios_present()) return -ENODEV; @@ -383,8 +382,7 @@ PCI_COMMAND, new_command); } - dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr, - irq, chip_idx, cards_found); + dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, ioaddr, irq, chip_idx, cards_found); if (dev && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) { u8 pci_latency; @@ -405,18 +403,18 @@ return cards_found ? 0 : -ENODEV; } -static struct net_device *rtl8129_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, +static struct net_device *rtl8129_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int found_cnt) { static int did_version = 0; /* Already printed version info. */ struct rtl8129_private *tp; int i, option = found_cnt < MAX_UNITS ? options[found_cnt] : 0; + struct net_device *dev; if (rtl8129_debug > 0 && did_version++ == 0) printk(KERN_INFO "%s", version); - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", dev->name, pci_tbl[chip_idx].name, ioaddr, irq); @@ -1429,7 +1427,7 @@ #ifdef MODULE int init_module(void) { - return rtl8139_probe(0); + return rtl8139_probe(); } void diff -u --recursive --new-file v2.3.26/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c --- v2.3.26/linux/drivers/net/seeq8005.c Wed Aug 18 11:36:42 1999 +++ linux/drivers/net/seeq8005.c Wed Nov 10 20:02:27 1999 @@ -30,6 +30,7 @@ 0.48 Receive working */ +#include #include #include #include @@ -780,7 +781,7 @@ /* * If we don't do this, we can't re-insmod it later. */ - release_region(dev_seeq.base_addr, EL1_IO_EXTENT); + release_region(dev_seeq.base_addr, SEEQ8005_IO_EXTENT); } #endif /* MODULE */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/setup.c linux/drivers/net/setup.c --- v2.3.26/linux/drivers/net/setup.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/setup.c Wed Nov 10 19:55:55 1999 @@ -0,0 +1,371 @@ +/* + * New style setup code for the network devices + */ + +#include +#include +#include +#include +#include + +extern int mkiss_init_ctrl_dev(void); +extern int ppp_init(void); +extern int slip_init_ctrl_dev(void); +extern int strip_init_ctrl_dev(void); +extern int x25_asy_init_ctrl_dev(void); + +extern int bpq_init(void); +extern int dmascc_init(void); +extern int scc_init(void); +extern int yam_init(void); + +extern int acenic_probe(void); +extern int arcnet_init(void); +extern int bigmac_probe(void); +extern int bmac_probe(void); +extern int cpm_enet_init(void); +extern int dlci_setup(void); +extern int dgrs_probe(void); +extern int dmfe_reg_board(void); +extern int eepro100_probe(void); +extern int epic100_probe(void); +extern int happy_meal_probe(void); +extern int lapbeth_init(void); +extern int mace_probe(void); +extern int myri_sbus_probe(void); +extern int ncr885e_probe(void); +extern int ne2k_pci_probe(void); +extern int pcnet32_probe(void); +extern int qec_probe(void); +extern int rcpci_probe(void); +extern int rr_hippi_probe(void); +extern int rtl8139_probe(void); +extern int sdla_setup(void); +extern int sis900_probe(void); +extern int sparc_lance_probe(void); +extern int starfire_probe(void); +extern int tc59x_probe(void); +extern int tulip_probe(void); +extern int via_rhine_probe(void); +extern int yellowfin_probe(void); + +/* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is tring of 9 zeros. */ +#define __PAD6 "\0\0\0\0\0\0\0\0\0" +#define __PAD5 __PAD6 "\0" +#define __PAD4 __PAD5 "\0" +#define __PAD3 __PAD4 "\0" +#define __PAD2 __PAD3 "\0" + + +/* + * Devices in this list must do new style probing. That is they must + * allocate their own device objects and do their own bus scans. + */ + +struct net_probe +{ + int (*probe)(void); + int status; /* non-zero if autoprobe has failed */ +}; + +struct net_probe pci_probes[] __initdata = { + /* + * Early setup devices + */ + +#if defined(CONFIG_SCC) + {scc_init, 0}, +#endif +#if defined(CONFIG_DMASCC) + {dmascc_init, 0}, +#endif +#if defined(CONFIG_BPQETHER) + {bpq_init, 0}, +#endif +#if defined(CONFIG_DLCI) + {dlci_setup, 0}, +#endif +#if defined(CONFIG_SDLA) + {sdla_setup, 0}, +#endif +#if defined(CONFIG_LAPBETHER) + {lapbeth_init, 0}, +#endif +#if defined(CONFIG_PLIP) + {plip_init, 0}, +#endif +#if defined(CONFIG_ARCNET) + {arcnet_init, 0}, +#endif +#if defined(CONFIG_8xx) + {cpm_enet_init, 0}, +#endif + /* + * SLHC if present needs attaching so other people see it + * even if not opened. + */ + +#ifdef CONFIG_INET +#if (defined(CONFIG_SLIP) && defined(CONFIG_SLIP_COMPRESSED)) \ + || defined(CONFIG_PPP) \ + || (defined(CONFIG_ISDN) && defined(CONFIG_ISDN_PPP)) + {slhc_install, 0}, +#endif +#endif +/* + * HIPPI + */ +#ifdef CONFIG_ROADRUNNER + {rr_hippi_probe, 0}, +#endif + +/* + * ETHERNET + */ + +/* + * SBUS Ethernet + */ + +#ifdef CONFIG_HAPPYMEAL + {happy_meal_probe, 0}, +#endif +#ifdef CONFIG_SUNLANCE + {sparc_lance_probe, 0}, +#endif +#ifdef CONFIG_SUNQE + {qec_probe, 0}, +#endif +#ifdef CONFIG_SUNBMAC + {bigmac_probe, 0}, +#endif +#ifdef CONFIG_MYRI_SBUS + {myri_sbus_probe, 0}, +#endif + +/* + * PowerPC Mainboard + */ + +#ifdef CONFIG_MACE + {mace_probe, 0}, +#endif +#ifdef CONFIG_BMAC + {bmac_probe, 0}, +#endif +#ifdef CONFIG_NCR885E + {ncr885e_probe, 0}, +#endif + +/* + * PCI Ethernet + */ +#ifdef CONFIG_DGRS + {dgrs_probe, 0}, +#endif +#ifdef CONFIG_RCPCI + {rcpci_probe, 0}, +#endif +#ifdef CONFIG_VORTEX + {tc59x_probe, 0}, +#endif +#ifdef CONFIG_NE2K_PCI + {ne2k_pci_probe, 0}, +#endif +#ifdef CONFIG_PCNET32 + {pcnet32_probe, 0}, +#endif +#ifdef CONFIG_EEXPRESS_PRO100 /* Intel EtherExpress Pro/100 */ + {eepro100_probe, 0}, +#endif +#ifdef CONFIG_DEC_ELCP + {tulip_probe, 0}, +#endif +#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */ + {de4x5_probe, 0}, +#endif +#ifdef CONFIG_EPIC100 + {epic100_probe, 0}, +#endif +#ifdef CONFIG_RTL8139 + {rtl8139_probe, 0}, +#endif +#ifdef CONFIG_SIS900 + {sis900_probe, 0}, +#endif + +#ifdef CONFIG_DM9102 + {dmfe_reg_board, 0}, +#endif + +#ifdef CONFIG_YELLOWFIN + {yellowfin_probe, 0}, +#endif +#ifdef CONFIG_ACENIC + {acenic_probe, 0}, +#endif +#ifdef CONFIG_VIA_RHINE + {via_rhine_probe, 0}, +#endif +#ifdef CONFIG_ADAPTEC_STARFIRE + {starfire_probe, 0}, +#endif + +/* + * Amateur Radio Drivers + */ + +#ifdef CONFIG_YAM + {yam_init, 0}, +#endif /* CONFIG_YAM */ + + + {NULL, 0}, +}; + + +/* + * Run the updated device probes. These do not need a device passed + * into them. + */ + +static void __init network_probe(void) +{ + struct net_probe *p = pci_probes; + + while (p->probe != NULL) + { + p->status = p->probe(); + p++; + } +} + + +/* + * Initialise the line discipline drivers + */ + +static void __init network_ldisc_init(void) +{ +#if defined(CONFIG_SLIP) + slip_init_ctrl_dev(); +#endif +#if defined(CONFIG_X25_ASY) + x25_asy_init_ctrl_dev(); +#endif +#if defined(CONFIG_MKISS) + mkiss_init_ctrl_dev(); +#endif +#if defined(CONFIG_STRIP) + strip_init_ctrl_dev(); +#endif +#if defined(CONFIG_PPP) + ppp_init(); +#endif +} + + +static void __init appletalk_device_init(void) +{ +#if defined(CONFIG_IPDDP) + extern int ipddp_init(struct net_device *dev); + static struct net_device dev_ipddp = { + "ipddp0" __PAD6, + 0, 0, 0, 0, + 0x0, 0, + 0, 0, 0, NULL, ipddp_init + }; + + dev_ipddp.init(&dev_ipddp); +#endif /* CONFIG_IPDDP */ +} + + +/* + * The loopback device is global so it can be directly referenced + * by the network code. + */ + +extern int loopback_init(struct net_device *dev); +struct net_device loopback_dev = +{ + "lo" __PAD2, /* Software Loopback interface */ + 0x0, /* recv memory end */ + 0x0, /* recv memory start */ + 0x0, /* memory end */ + 0x0, /* memory start */ + 0, /* base I/O address */ + 0, /* IRQ */ + 0, 0, 0, /* flags */ + NULL, /* next device */ + loopback_init /* loopback_init should set up the rest */ +}; + +static void special_device_init(void) +{ +#ifdef CONFIG_DUMMY + { + extern int dummy_init(struct net_device *dev); + static struct net_device dummy_dev = { + "dummy" __PAD5, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, dummy_init, + }; + register_netdev(&sb1000_dev); + } +#endif +#ifdef CONFIG_EQUALIZER + { + extern int eql_init(struct net_device *dev); + static struct net_device eql_dev = + { + "eql" __PAD3, /* Master device for IP traffic load balancing */ + 0x0, 0x0, 0x0, 0x0, /* recv end/start; mem end/start */ + 0, /* base I/O address */ + 0, /* IRQ */ + 0, 0, 0, /* flags */ + NULL, /* next device */ + eql_init /* set up the rest */ + }; + register_netdev(&sb1000_dev); + } +#endif +#ifdef CONFIG_APBIF + { + extern int bif_init(struct net_device *dev); + static struct net_device bif_dev = + { + "bif" __PAD3, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, bif_init + }; + register_netdev(&sb1000_dev); + } +#endif +#ifdef CONFIG_NET_SB1000 + { + extern int sb1000_probe(struct net_device *dev); + static struct net_device sb1000_dev = + { + "cm0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, sb1000_probe + }; + register_netdev(&sb1000_dev); + } +#endif + register_netdev(&loopback_dev); +} + +/* + * Initialise network devices + */ + +void __init net_device_init(void) +{ + /* Devices supporting the new probing API */ + network_probe(); + /* Line disciplines */ + network_ldisc_init(); + /* Appletalk */ + appletalk_device_init(); + /* Special devices */ + special_device_init(); + /* That kicks off the legacy init functions */ +} + + diff -u --recursive --new-file v2.3.26/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c --- v2.3.26/linux/drivers/net/sk_mca.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/net/sk_mca.c Wed Nov 10 10:00:48 1999 @@ -71,7 +71,6 @@ #include #include -#include #include #include #include diff -u --recursive --new-file v2.3.26/linux/drivers/net/slhc.c linux/drivers/net/slhc.c --- v2.3.26/linux/drivers/net/slhc.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/slhc.c Tue Nov 9 08:20:12 1999 @@ -759,6 +759,7 @@ #endif /* MODULE */ #else /* CONFIG_INET */ + int slhc_toss(struct slcompress *comp) { diff -u --recursive --new-file v2.3.26/linux/drivers/net/slip.c linux/drivers/net/slip.c --- v2.3.26/linux/drivers/net/slip.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/net/slip.c Tue Nov 9 08:20:12 1999 @@ -1318,11 +1318,8 @@ /* VSV changes end */ /* Initialize SLIP control device -- register SLIP line discipline */ -#ifdef MODULE -static int slip_init_ctrl_dev(void) -#else /* !MODULE */ -int __init slip_init_ctrl_dev(struct net_device *dummy) -#endif /* !MODULE */ + +int __init slip_init_ctrl_dev(void) { int status; @@ -1371,15 +1368,8 @@ } -#ifdef MODULE return status; -#else - /* Return "not found", so that dev_init() will unlink - * the placeholder device entry for us. - */ - return ENODEV; -#endif - } +} diff -u --recursive --new-file v2.3.26/linux/drivers/net/starfire.c linux/drivers/net/starfire.c --- v2.3.26/linux/drivers/net/starfire.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/starfire.c Tue Nov 9 08:20:12 1999 @@ -213,12 +213,10 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_idx, int fnd_cnt); + struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; -static struct net_device *starfire_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, +static struct net_device *starfire_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chp_idx, int fnd_cnt); #if 0 @@ -392,11 +390,12 @@ well when dynamically adding drivers. So instead we detect just the cards we know about in slot order. */ -static int pci_etherdev_probe(struct net_device *dev, struct pci_id_info pci_tbl[]) +static int pci_etherdev_probe(struct pci_id_info pci_tbl[]) { int cards_found = 0; int pci_index = 0; unsigned char pci_bus, pci_device_fn; + struct net_device *dev; if ( ! pcibios_present()) return -ENODEV; @@ -459,7 +458,7 @@ PCI_COMMAND, new_command); } - dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr, + dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, ioaddr, irq, chip_idx, cards_found); if (dev && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) { @@ -474,16 +473,15 @@ PCI_LATENCY_TIMER, min_pci_latency); } } - dev = 0; cards_found++; } return cards_found ? 0 : -ENODEV; } -int starfire_probe(struct net_device *dev) +int starfire_probe(void) { - if (pci_etherdev_probe(dev, pci_tbl) < 0) + if (pci_etherdev_probe(pci_tbl) < 0) return -ENODEV; printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); return 0; @@ -491,13 +489,11 @@ static struct net_device * -starfire_probe1(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_id, int card_idx) +starfire_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_id, int card_idx) { struct netdev_private *np; int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0; - - dev = init_etherdev(dev, sizeof(struct netdev_private)); + struct net_device *dev = init_etherdev(NULL, sizeof(struct netdev_private)); printk(KERN_INFO "%s: %s at 0x%lx, ", dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr); @@ -1388,7 +1384,7 @@ register_driver(ðerdev_ops); return 0; #else - if (pci_etherdev_probe(NULL, pci_tbl)) { + if (pci_etherdev_probe(pci_tbl)) { printk(KERN_INFO " No Starfire adapters detected, driver not loaded.\n"); return -ENODEV; } diff -u --recursive --new-file v2.3.26/linux/drivers/net/strip.c linux/drivers/net/strip.c --- v2.3.26/linux/drivers/net/strip.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/net/strip.c Tue Nov 9 08:20:12 1999 @@ -2831,9 +2831,6 @@ * STRIP driver */ -#ifdef MODULE -static -#endif int strip_init_ctrl_dev(struct net_device *dummy) { static struct tty_ldisc strip_ldisc; diff -u --recursive --new-file v2.3.26/linux/drivers/net/sunbmac.c linux/drivers/net/sunbmac.c --- v2.3.26/linux/drivers/net/sunbmac.c Wed Aug 18 11:36:43 1999 +++ linux/drivers/net/sunbmac.c Tue Nov 9 08:20:12 1999 @@ -1492,8 +1492,9 @@ return res; /* Return error code. */ } -int __init bigmac_probe(struct net_device *dev) +int __init bigmac_probe(void) { + struct net_device *dev = NULL; struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; static int called = 0; @@ -1529,7 +1530,7 @@ init_module(void) { root_bigmac_dev = NULL; - return bigmac_probe(NULL); + return bigmac_probe(); } void diff -u --recursive --new-file v2.3.26/linux/drivers/net/sunhme.c linux/drivers/net/sunhme.c --- v2.3.26/linux/drivers/net/sunhme.c Fri Sep 10 23:57:30 1999 +++ linux/drivers/net/sunhme.c Tue Nov 9 08:20:12 1999 @@ -3459,8 +3459,9 @@ } #endif -int __init happy_meal_probe(struct net_device *dev) +int __init happy_meal_probe(void) { + struct net_device *dev = NULL; struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; static int called = 0; diff -u --recursive --new-file v2.3.26/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c --- v2.3.26/linux/drivers/net/sunlance.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/net/sunlance.c Tue Nov 9 08:20:12 1999 @@ -1157,7 +1157,7 @@ #include /* Find all the lance cards on the system and initialize them */ -int __init sparc_lance_probe (struct net_device *dev) +int __init sparc_lance_probe(void) { static struct linux_sbus_device sdev; static int called = 0; @@ -1171,7 +1171,7 @@ memset (&sdev, 0, sizeof(sdev)); sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; sdev.irqs[0] = 6; - return sparc_lance_init(dev, &sdev, 0, 0); + return sparc_lance_init(NULL, &sdev, 0, 0); } return ENODEV; } @@ -1179,10 +1179,11 @@ #else /* !CONFIG_SUN4 */ /* Find all the lance cards on the system and initialize them */ -int __init sparc_lance_probe (struct net_device *dev) +int __init sparc_lance_probe (void) { struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; + struct net_device *dev = NULL; struct Linux_SBus_DMA *ledma = 0; static int called = 0; int cards = 0, v; @@ -1229,7 +1230,7 @@ init_module(void) { root_lance_dev = NULL; - return sparc_lance_probe(NULL); + return sparc_lance_probe(); } void diff -u --recursive --new-file v2.3.26/linux/drivers/net/sunqe.c linux/drivers/net/sunqe.c --- v2.3.26/linux/drivers/net/sunqe.c Fri Sep 10 23:57:30 1999 +++ linux/drivers/net/sunqe.c Tue Nov 9 08:20:12 1999 @@ -926,8 +926,9 @@ return res; } -int __init qec_probe(struct net_device *dev) +int __init qec_probe(void) { + struct net_device *dev = NULL; struct linux_sbus *bus; struct linux_sbus_device *sdev = 0; static int called = 0; @@ -969,7 +970,7 @@ init_module(void) { root_qec_dev = NULL; - return qec_probe(NULL); + return qec_probe(); } void diff -u --recursive --new-file v2.3.26/linux/drivers/net/tulip.c linux/drivers/net/tulip.c --- v2.3.26/linux/drivers/net/tulip.c Wed Aug 18 11:36:43 1999 +++ linux/drivers/net/tulip.c Tue Nov 9 08:20:12 1999 @@ -410,7 +410,6 @@ }; static struct net_device *tulip_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, int chip_id, int options); static void parse_eeprom(struct net_device *dev); static int read_eeprom(long ioaddr, int location); @@ -446,7 +445,7 @@ This allows the probe routine to use the old driver initialization interface. */ -int tulip_probe(struct net_device *dev) +int tulip_probe(void) { int cards_found = 0; static int pci_index = 0; /* Static, for multiple probe calls. */ @@ -523,10 +522,9 @@ PCI_COMMAND, new_command); } - dev = tulip_probe1(pci_bus, pci_device_fn, dev, chip_idx, cards_found); - - /* Get and check the bus-master and latency values. */ - if (dev) { + if(tulip_probe1(pci_bus, pci_device_fn, chip_idx, cards_found)) + { + /* Get and check the bus-master and latency values. */ unsigned char pci_latency; pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER, &pci_latency); @@ -544,7 +542,6 @@ if (device == PCI_DEVICE_ID_DEC_TULIP_21142) pcibios_write_config_dword(pci_bus, pci_device_fn, 0x40, 0x40000000); - dev = 0; cards_found++; } } @@ -553,9 +550,9 @@ } static struct net_device *tulip_probe1(int pci_bus, int pci_device_fn, - struct net_device *dev, int chip_id, int board_idx) { + struct net_device *dev; static int did_version = 0; /* Already printed version info. */ struct tulip_private *tp; long ioaddr; @@ -570,7 +567,7 @@ if (tulip_debug > 0 && did_version++ == 0) printk(KERN_INFO "%s", version); - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); irq = pci_find_slot(pci_bus, pci_device_fn)->irq; ioaddr = pci_find_slot(pci_bus, pci_device_fn)->resource[0].start; @@ -2745,7 +2742,7 @@ pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io); pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id); io &= ~3; - dev = tulip_probe1(bus, devfn, NULL, DC21142, -1); + dev = tulip_probe1(bus, devfn, DC21142, -1); if (dev) { dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL); strcpy(node->dev_name, dev->name); @@ -2806,7 +2803,7 @@ register_driver(&tulip_ops); return 0; #else - return tulip_probe(NULL); + return tulip_probe(); #endif } diff -u --recursive --new-file v2.3.26/linux/drivers/net/via-rhine.c linux/drivers/net/via-rhine.c --- v2.3.26/linux/drivers/net/via-rhine.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/net/via-rhine.c Tue Nov 9 08:20:12 1999 @@ -248,12 +248,10 @@ const char *name; u16 vendor_id, device_id, device_id_mask, flags; int io_size; - struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev, - long ioaddr, int irq, int chip_idx, int fnd_cnt); + struct net_device *(*probe1)(int pci_bus, int pci_devfn, long ioaddr, int irq, int chip_idx, int fnd_cnt); }; -static struct net_device *via_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, int irq, +static struct net_device *via_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq, int chp_idx, int fnd_cnt); static struct pci_id_info pci_tbl[] = { @@ -393,11 +391,12 @@ well when dynamically adding drivers. So instead we detect just the cards we know about in slot order. */ -static int pci_etherdev_probe(struct net_device *dev, struct pci_id_info pci_tbl[]) +static int pci_etherdev_probe(struct pci_id_info pci_tbl[]) { int cards_found = 0; int pci_index = 0; unsigned char pci_bus, pci_device_fn; + struct net_device *dev; if ( ! pcibios_present()) return -ENODEV; @@ -478,7 +477,7 @@ PCI_COMMAND, new_command); } - dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr, + dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, ioaddr, irq, chip_idx, cards_found); if (dev && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) { @@ -501,21 +500,24 @@ } #ifndef MODULE -int via_rhine_probe(struct net_device *dev) +int via_rhine_probe(void) { printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB); - return pci_etherdev_probe(dev, pci_tbl); + return pci_etherdev_probe(pci_tbl); } #endif static struct net_device *via_probe1(int pci_bus, int pci_devfn, - struct net_device *dev, long ioaddr, int irq, + long ioaddr, int irq, int chip_id, int card_idx) { + struct net_device *dev; struct netdev_private *np; int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0; - dev = init_etherdev(dev, 0); + dev = init_etherdev(NULL, 0); + if(dev==NULL) + return NULL; printk(KERN_INFO "%s: %s at 0x%lx, ", dev->name, pci_tbl[chip_id].name, ioaddr); @@ -539,6 +541,7 @@ /* Make certain the descriptor lists are cache-aligned. */ np = (void *)(((long)kmalloc(sizeof(*np), GFP_KERNEL) + 31) & ~31); + /* FIXME! check return !!! */ memset(np, 0, sizeof(*np)); dev->priv = np; @@ -1264,7 +1267,7 @@ register_driver(ðerdev_ops); return 0; #else - return pci_etherdev_probe(NULL, pci_tbl); + return pci_etherdev_probe(pci_tbl); #endif } diff -u --recursive --new-file v2.3.26/linux/drivers/net/wan/sdla.c linux/drivers/net/wan/sdla.c --- v2.3.26/linux/drivers/net/wan/sdla.c Mon Oct 11 15:38:15 1999 +++ linux/drivers/net/wan/sdla.c Tue Nov 9 08:20:12 1999 @@ -1666,10 +1666,11 @@ return(0); } -void __init sdla_setup(void) +int __init sdla_setup(void) { printk("%s.\n", version); register_frad(devname); + return 0; } #ifdef MODULE diff -u --recursive --new-file v2.3.26/linux/drivers/net/wan/x25_asy.c linux/drivers/net/wan/x25_asy.c --- v2.3.26/linux/drivers/net/wan/x25_asy.c Mon Oct 11 15:38:15 1999 +++ linux/drivers/net/wan/x25_asy.c Tue Nov 9 08:20:12 1999 @@ -813,11 +813,8 @@ } /* Initialize X.25 control device -- register X.25 line discipline */ -#ifdef MODULE -static int x25_asy_init_ctrl_dev(void) -#else /* !MODULE */ -int __init x25_asy_init_ctrl_dev(struct net_device *dummy) -#endif /* !MODULE */ + +int __init x25_asy_init_ctrl_dev(void) { int status; @@ -854,15 +851,8 @@ printk("X.25 async: can't register line discipline (err = %d)\n", status); } -#ifdef MODULE return status; -#else - /* Return "not found", so that dev_init() will unlink - * the placeholder device entry for us. - */ - return ENODEV; -#endif - } +} /* Initialise the X.25 driver. Called by the device init code */ diff -u --recursive --new-file v2.3.26/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c --- v2.3.26/linux/drivers/net/yellowfin.c Wed Aug 18 11:36:43 1999 +++ linux/drivers/net/yellowfin.c Tue Nov 9 08:20:12 1999 @@ -316,8 +316,7 @@ #endif -static struct net_device *yellowfin_probe1(struct net_device *dev, long ioaddr, - int irq, int chip_id, int options); +static struct net_device *yellowfin_probe1(long ioaddr, int irq, int chip_id, int options); static int read_eeprom(long ioaddr, int location); static int mdio_read(long ioaddr, int phy_id, int location); static void mdio_write(long ioaddr, int phy_id, int location, int value); @@ -341,7 +340,7 @@ /* A list of all installed Yellowfin devices, for removing the driver module. */ static struct net_device *root_yellowfin_dev = NULL; -int yellowfin_probe(struct net_device *dev) +int yellowfin_probe(void) { int cards_found = 0; int pci_index = 0; @@ -400,9 +399,8 @@ PCI_COMMAND, new_command); } - dev = yellowfin_probe1(dev, ioaddr, irq, chip_idx, cards_found); - - if (dev) { + if(yellowfin_probe1(ioaddr, irq, chip_idx, cards_found)) + { /* Get and check the bus-master and latency values. */ pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER, &pci_latency); @@ -415,7 +413,6 @@ } else if (yellowfin_debug > 1) printk(KERN_INFO " PCI latency timer (CFLT) is %#x.\n", pci_latency); - dev = 0; cards_found++; } } @@ -423,17 +420,17 @@ return cards_found ? 0 : -ENODEV; } -static struct net_device *yellowfin_probe1(struct net_device *dev, long ioaddr, - int irq, int chip_id, int card_idx) +static struct net_device *yellowfin_probe1(long ioaddr, int irq, int chip_id, int card_idx) { static int did_version = 0; /* Already printed version info. */ struct yellowfin_private *yp; int option, i; + struct net_device *dev; if (yellowfin_debug > 0 && did_version++ == 0) printk(version); - dev = init_etherdev(dev, sizeof(struct yellowfin_private)); + dev = init_etherdev(NULL, sizeof(struct yellowfin_private)); printk(KERN_INFO "%s: %s type %8x at 0x%lx, ", dev->name, chip_tbl[chip_id].name, inl(ioaddr + ChipRev), ioaddr); @@ -1372,7 +1369,7 @@ if (debug >= 0) yellowfin_debug = debug; - return yellowfin_probe(0); + return yellowfin_probe(); } void cleanup_module(void) diff -u --recursive --new-file v2.3.26/linux/drivers/parport/ieee1284.c linux/drivers/parport/ieee1284.c --- v2.3.26/linux/drivers/parport/ieee1284.c Fri Oct 15 15:25:13 1999 +++ linux/drivers/parport/ieee1284.c Mon Nov 8 10:40:40 1999 @@ -80,19 +80,42 @@ * are able to eat the time up to 40ms. */ +int parport_poll_peripheral(struct parport *port, + unsigned char mask, + unsigned char result, + int usec) +{ + /* Zero return code is success, >0 is timeout. */ + int counter = usec / 5; + unsigned char status; + for (; counter > 0; counter--) { + status = parport_read_status (port); + if ((status & mask) == result) + return 0; + if (signal_pending (current)) + return -EINTR; + if (current->need_resched) + break; + udelay (5); + } + + return 1; +} + int parport_wait_peripheral(struct parport *port, unsigned char mask, unsigned char result) { - int counter; + int ret; + int usec; long deadline; unsigned char status; - counter = port->physport->spintime; /* usecs of fast polling */ + usec = port->physport->spintime; /* usecs of fast polling */ if (!port->physport->cad->timeout) /* A zero timeout is "special": busy wait for the entire 35ms. */ - counter = 35000; + usec = 35000; /* Fast polling. * @@ -100,16 +123,9 @@ * How about making a note (in the device structure) of how long * it takes, so we know for next time? */ - for (counter /= 5; counter > 0; counter--) { - status = parport_read_status (port); - if ((status & mask) == result) - return 0; - if (signal_pending (current)) - return -EINTR; - if (current->need_resched) - break; - udelay(5); - } + ret = parport_poll_peripheral (port, mask, result, usec); + if (ret != 1) + return ret; if (!port->physport->cad->timeout) /* We may be in an interrupt handler, so we can't poll @@ -137,7 +153,7 @@ /* parport_wait_event didn't time out, but the * peripheral wasn't actually ready either. * Wait for another 10ms. */ - current->state = TASK_INTERRUPTIBLE; + __set_current_state (TASK_INTERRUPTIBLE); schedule_timeout ((HZ+ 99) / 100); } } @@ -369,8 +385,17 @@ PARPORT_CONTROL_STROBE, PARPORT_CONTROL_STROBE); + /* Event 52: nAck goes low */ + if (parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0)) { + /* This peripheral is _very_ slow. */ + DPRINTK (KERN_DEBUG + "%s: Event 52 didn't happen\n", + port->name); + parport_ieee1284_terminate (port); + return 1; + } + /* Event 53: Set nStrobe high */ - udelay (5); parport_frob_control (port, PARPORT_CONTROL_STROBE, 0); diff -u --recursive --new-file v2.3.26/linux/drivers/parport/ieee1284_ops.c linux/drivers/parport/ieee1284_ops.c --- v2.3.26/linux/drivers/parport/ieee1284_ops.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/parport/ieee1284_ops.c Mon Nov 8 10:18:45 1999 @@ -95,7 +95,7 @@ our interrupt handler called. */ if (count && no_irq) { parport_release (dev); - current->state = TASK_INTERRUPTIBLE; + set_current_state (TASK_INTERRUPTIBLE); schedule_timeout (wait); parport_claim_or_block (dev); } @@ -525,7 +525,7 @@ /* Yield the port for a while. */ if (count && dev->port->irq != PARPORT_IRQ_NONE) { parport_release (dev); - current->state = TASK_INTERRUPTIBLE; + set_current_state (TASK_INTERRUPTIBLE); schedule_timeout ((HZ + 24) / 25); parport_claim_or_block (dev); } diff -u --recursive --new-file v2.3.26/linux/drivers/parport/init.c linux/drivers/parport/init.c --- v2.3.26/linux/drivers/parport/init.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/parport/init.c Mon Nov 8 10:40:40 1999 @@ -181,6 +181,7 @@ EXPORT_SYMBOL(parport_read); EXPORT_SYMBOL(parport_ieee1284_wakeup); EXPORT_SYMBOL(parport_wait_peripheral); +EXPORT_SYMBOL(parport_poll_peripheral); EXPORT_SYMBOL(parport_wait_event); EXPORT_SYMBOL(parport_set_timeout); EXPORT_SYMBOL(parport_ieee1284_interrupt); diff -u --recursive --new-file v2.3.26/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c --- v2.3.26/linux/drivers/parport/parport_pc.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/parport/parport_pc.c Mon Nov 8 10:18:45 1999 @@ -122,7 +122,7 @@ if (time_after_eq (jiffies, expire)) /* The FIFO is stuck. */ return -EBUSY; - current->state = TASK_INTERRUPTIBLE; + __set_current_state (TASK_INTERRUPTIBLE); schedule_timeout ((HZ + 99) / 100); if (signal_pending (current)) break; diff -u --recursive --new-file v2.3.26/linux/drivers/pci/Makefile linux/drivers/pci/Makefile --- v2.3.26/linux/drivers/pci/Makefile Sat Oct 9 11:47:50 1999 +++ linux/drivers/pci/Makefile Mon Nov 8 11:14:41 1999 @@ -32,3 +32,11 @@ endif include $(TOPDIR)/Rules.make + +names.o: names.c devlist.h + +devlist.h: pci.ids gen-devlist + ./gen-devlist devlist.h + +gen-devlist: gen-devlist.c + $(HOSTCC) $(HOSTCFLAGS) -o gen-devlist gen-devlist.c diff -u --recursive --new-file v2.3.26/linux/drivers/pci/devlist.h linux/drivers/pci/devlist.h --- v2.3.26/linux/drivers/pci/devlist.h Mon Nov 1 13:56:26 1999 +++ linux/drivers/pci/devlist.h Wed Dec 31 16:00:00 1969 @@ -1,1016 +0,0 @@ -VENDOR( COMPAQ, "Compaq" ) - DEVICE( COMPAQ, COMPAQ_TOKENRING, "Token Ring 4/16") - DEVICE( COMPAQ, COMPAQ_1280, "QVision 1280/p") - DEVICE( COMPAQ, COMPAQ_SMART2P, "Smart-2/P RAID Controller") - DEVICE( COMPAQ, COMPAQ_NETEL100,"Netelligent 10/100") - DEVICE( COMPAQ, COMPAQ_NETEL10, "Netelligent 10") - DEVICE( COMPAQ, COMPAQ_NETFLEX3I,"NetFlex 3") - DEVICE( COMPAQ, COMPAQ_NETEL100D,"Netelligent 10/100 Dual") - DEVICE( COMPAQ, COMPAQ_NETEL100PI,"Netelligent 10/100 ProLiant") - DEVICE( COMPAQ, COMPAQ_NETEL100I,"Netelligent 10/100 Integrated") - DEVICE( COMPAQ, COMPAQ_THUNDER, "ThunderLAN") - DEVICE( COMPAQ, COMPAQ_NETFLEX3B,"NetFlex 3 BNC") -ENDVENDOR() - -VENDOR( NCR, "NCR" ) - DEVICE( NCR, NCR_53C810, "53c810") - DEVICE( NCR, NCR_53C820, "53c820") - DEVICE( NCR, NCR_53C825, "53c825") - DEVICE( NCR, NCR_53C815, "53c815") - DEVICE( NCR, NCR_53C860, "53c860") - DEVICE( NCR, NCR_53C896, "53c896") - DEVICE( NCR, NCR_53C895, "53c895") - DEVICE( NCR, NCR_53C885, "53c885") - DEVICE( NCR, NCR_53C875, "53c875") - DEVICE( NCR, NCR_53C875J, "53c875J") -ENDVENDOR() - -VENDOR( ATI, "ATI" ) - DEVICE( ATI, ATI_68800, "68800AX") - DEVICE( ATI, ATI_215CT222, "215CT222") - DEVICE( ATI, ATI_210888CX, "210888CX") - DEVICE( ATI, ATI_215GB, "Mach64 GB") - DEVICE( ATI, ATI_215GD, "Mach64 GD (Rage Pro)") - DEVICE( ATI, ATI_215GI, "Mach64 GI (Rage Pro)") - DEVICE( ATI, ATI_215GP, "Mach64 GP (Rage Pro)") - DEVICE( ATI, ATI_215GQ, "Mach64 GQ (Rage Pro)") - DEVICE( ATI, ATI_215GT, "Mach64 GT (Rage II)") - DEVICE( ATI, ATI_215GTB, "Mach64 GTB (Rage II)") - DEVICE( ATI, ATI_210888GX, "210888GX") - DEVICE( ATI, ATI_215LG, "Mach64 LG (Rage Pro)") - DEVICE( ATI, ATI_264LT, "Mach64 LT") - DEVICE( ATI, ATI_264VT, "Mach64 VT") -ENDVENDOR() - -VENDOR( VLSI, "VLSI" ) - DEVICE( VLSI, VLSI_82C592, "82C592-FC1") - DEVICE( VLSI, VLSI_82C593, "82C593-FC1") - DEVICE( VLSI, VLSI_82C594, "82C594-AFC2") - DEVICE( VLSI, VLSI_82C597, "82C597-AFC2") - DEVICE( VLSI, VLSI_82C541, "82C541 Lynx") - DEVICE( VLSI, VLSI_82C543, "82C543 Lynx ISA") - DEVICE( VLSI, VLSI_82C532, "82C532") - DEVICE( VLSI, VLSI_82C534, "82C534") - DEVICE( VLSI, VLSI_82C535, "82C535") - DEVICE( VLSI, VLSI_82C147, "82C147") - DEVICE( VLSI, VLSI_VAS96011, "VAS96011 (Golden Gate II)") -ENDVENDOR() - -VENDOR( ADL, "Avance Logic" ) - DEVICE( ADL, ADL_2301, "2301") -ENDVENDOR() - -VENDOR( NS, "NS" ) - DEVICE( NS, NS_87415, "87415") - DEVICE( NS, NS_87410, "87410") -ENDVENDOR() - -VENDOR( TSENG, "Tseng'Lab" ) - DEVICE( TSENG, TSENG_W32P_2, "ET4000W32P") - DEVICE( TSENG, TSENG_W32P_b, "ET4000W32P rev B") - DEVICE( TSENG, TSENG_W32P_c, "ET4000W32P rev C") - DEVICE( TSENG, TSENG_W32P_d, "ET4000W32P rev D") - DEVICE( TSENG, TSENG_ET6000, "ET6000") -ENDVENDOR() - -VENDOR( WEITEK, "Weitek" ) - DEVICE( WEITEK, WEITEK_P9000, "P9000") - DEVICE( WEITEK, WEITEK_P9100, "P9100") -ENDVENDOR() - -VENDOR( DEC, "DEC" ) - DEVICE( DEC, DEC_BRD, "DC21050") - DEVICE( DEC, DEC_TULIP, "DC21040") - DEVICE( DEC, DEC_TGA, "TGA") - DEVICE( DEC, DEC_TULIP_FAST, "DC21140") - DEVICE( DEC, DEC_TGA2, "TGA2") - DEVICE( DEC, DEC_FDDI, "DEFPA") - DEVICE( DEC, DEC_TULIP_PLUS, "DC21041") - DEVICE( DEC, DEC_21142, "DC21142") - DEVICE( DEC, DEC_21052, "DC21052") - DEVICE( DEC, DEC_21150, "DC21150") - DEVICE( DEC, DEC_21152, "DC21152") - DEVICE( DEC, DEC_21153, "DC21153") - DEVICE( DEC, DEC_21154, "DC21154") -ENDVENDOR() - -VENDOR( CIRRUS, "Cirrus Logic" ) - DEVICE( CIRRUS, CIRRUS_7548, "GD 7548") - DEVICE( CIRRUS, CIRRUS_5430, "GD 5430") - DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434") - DEVICE( CIRRUS, CIRRUS_5434_8, "GD 5434") - DEVICE( CIRRUS, CIRRUS_5436, "GD 5436") - DEVICE( CIRRUS, CIRRUS_5446, "GD 5446") - DEVICE( CIRRUS, CIRRUS_5480, "GD 5480") - DEVICE( CIRRUS, CIRRUS_5462, "Laguna") - DEVICE( CIRRUS, CIRRUS_5464, "Laguna 3D") - DEVICE( CIRRUS, CIRRUS_5465, "Laguna 3DA") - DEVICE( CIRRUS, CIRRUS_6729, "CL 6729") - DEVICE( CIRRUS, CIRRUS_6832, "PD 6832") - DEVICE( CIRRUS, CIRRUS_7542, "CL 7542") - DEVICE( CIRRUS, CIRRUS_7543, "CL 7543") - DEVICE( CIRRUS, CIRRUS_7541, "CL 7541") -ENDVENDOR() - -VENDOR( IBM, "IBM" ) - DEVICE( IBM, IBM_FIRE_CORAL, "Fire Coral") - DEVICE( IBM, IBM_TR, "Token Ring") - DEVICE( IBM, IBM_82G2675, "82G2675") - DEVICE( IBM, IBM_MCA, "MicroChannel") - DEVICE( IBM, IBM_82351, "82351") - DEVICE( IBM, IBM_PYTHON, "Python") - DEVICE( IBM, IBM_SERVERAID, "ServeRAID") - DEVICE( IBM, IBM_TR_WAKE, "Wake On LAN Token Ring") - DEVICE( IBM, IBM_MPIC, "MPIC-2 Interrupt Controller") - DEVICE( IBM, IBM_3780IDSP, "MWave DSP") - DEVICE( IBM, IBM_MPIC_2, "MPIC-2 ASIC Interrupt Controller") -ENDVENDOR() - -VENDOR( WD, "Western Digital" ) - DEVICE( WD, WD_7197, "WD 7197") -ENDVENDOR() - -VENDOR( AMD, "AMD" ) - DEVICE( AMD, AMD_LANCE, "79C970") - DEVICE( AMD, AMD_SCSI, "53C974") -ENDVENDOR() - -VENDOR( TRIDENT, "Trident" ) - DEVICE( TRIDENT, TRIDENT_9320, "Cyber9320") - DEVICE( TRIDENT, TRIDENT_9388, "Cyber9388") - DEVICE( TRIDENT, TRIDENT_9397, "Cyber9397") - DEVICE( TRIDENT, TRIDENT_939A, "Cyber939a") - DEVICE( TRIDENT, TRIDENT_9520, "Cyber9520") - DEVICE( TRIDENT, TRIDENT_9525, "Cyber9525") - DEVICE( TRIDENT, TRIDENT_9420, "TGUI 9420") - DEVICE( TRIDENT, TRIDENT_9440, "TGUI 9440") - DEVICE( TRIDENT, TRIDENT_9660, "TGUI 9660 / Cyber9385") - DEVICE( TRIDENT, TRIDENT_9750, "3DImage 975") - DEVICE( TRIDENT, TRIDENT_9850, "3DImage 985") - DEVICE( TRIDENT, TRIDENT_9880, "Blade 3D") - DEVICE( TRIDENT, TRIDENT_8400, "CyberBlade/i7") - DEVICE( TRIDENT, TRIDENT_8420, "CyberBlade/i7d") - DEVICE( TRIDENT, TRIDENT_8500, "CyberBlade/i1") -ENDVENDOR() - -VENDOR( AI, "Acer Incorporated" ) - DEVICE( AI, AI_M1435, "M1435") -ENDVENDOR() - -VENDOR( MATROX, "Matrox" ) - DEVICE( MATROX, MATROX_MGA_2, "Atlas PX2085") - DEVICE( MATROX, MATROX_MIL, "Millennium") - DEVICE( MATROX, MATROX_MYS, "Mystique") - DEVICE( MATROX, MATROX_MIL_2, "Millennium II") - DEVICE( MATROX, MATROX_MIL_2_AGP,"Millennium II AGP") - DEVICE( MATROX, MATROX_MGA_IMP, "MGA Impression") - DEVICE( MATROX, MATROX_G100_MM, "G100 multi monitor") - DEVICE( MATROX, MATROX_G100_AGP,"G100 AGP") - DEVICE( MATROX, MATROX_G200_PCI,"G200 PCI") - DEVICE( MATROX, MATROX_G200_AGP,"G200 AGP") - DEVICE( MATROX, MATROX_G400, "G400") - DEVICE( MATROX, MATROX_VIA, "Corona / Meteor-II") -ENDVENDOR() - -VENDOR( CT, "Chips & Technologies" ) - DEVICE( CT, CT_65545, "65545") - DEVICE( CT, CT_65548, "65548") - DEVICE( CT, CT_65550, "65550") - DEVICE( CT, CT_65554, "65554") - DEVICE( CT, CT_65555, "65555") -ENDVENDOR() - -VENDOR( MIRO, "Miro" ) - DEVICE( MIRO, MIRO_36050, "ZR36050") -ENDVENDOR() - -VENDOR( NEC, "NEC" ) - DEVICE( NEC, NEC_PCX2, "PowerVR PCX2") -ENDVENDOR() - -VENDOR( FD, "Future Domain" ) - DEVICE( FD, FD_36C70, "TMC-18C30") -ENDVENDOR() - -VENDOR( SI, "Silicon Integrated Systems" ) - DEVICE( SI, SI_5591_AGP, "5591/5592 AGP") - DEVICE( SI, SI_6202, "6202") - DEVICE( SI, SI_503, "85C503") - DEVICE( SI, SI_ACPI, "ACPI") - DEVICE( SI, SI_5597_VGA, "5597/5598 VGA") - DEVICE( SI, SI_6205, "6205") - DEVICE( SI, SI_496, "85C496") - DEVICE( SI, SI_501, "85C501") - DEVICE( SI, SI_530, "530 Host") - DEVICE( SI, SI_601, "85C601") - DEVICE( SI, SI_620, "620 Host") - DEVICE( SI, SI_5107, "5107") - DEVICE( SI, SI_5511, "85C5511") - DEVICE( SI, SI_5513, "85C5513 IDE") - DEVICE( SI, SI_5571, "5571") - DEVICE( SI, SI_5591, "5591/5592 Host") - DEVICE( SI, SI_5597, "5597/5598 Host") - DEVICE( SI, SI_5600, "5600 Host") - DEVICE( SI, SI_6306, "3D-AGP 6306 VGA") - DEVICE( SI, SI_6326, "3D-AGP 6326 VGA") - DEVICE( SI, SI_7001, "7001 USB") -ENDVENDOR() - -VENDOR( HP, "Hewlett Packard" ) - DEVICE( HP, HP_J2585A, "J2585A") - DEVICE( HP, HP_J2585B, "J2585B (Lassen)") -ENDVENDOR() - -VENDOR( PCTECH, "PCTECH" ) - DEVICE( PCTECH, PCTECH_RZ1000, "RZ1000 (buggy)") - DEVICE( PCTECH, PCTECH_RZ1001, "RZ1001 (buggy?)") - DEVICE( PCTECH, PCTECH_SAMURAI_0,"Samurai 0") - DEVICE( PCTECH, PCTECH_SAMURAI_1,"Samurai 1") - DEVICE( PCTECH, PCTECH_SAMURAI_IDE,"Samurai IDE") -ENDVENDOR() - -VENDOR( DPT, "DPT" ) - DEVICE( DPT, DPT, "SmartCache/Raid") -ENDVENDOR() - -VENDOR( OPTI, "OPTi" ) - DEVICE( OPTI, OPTI_92C178, "92C178") - DEVICE( OPTI, OPTI_82C557, "82C557 Viper-M") - DEVICE( OPTI, OPTI_82C558, "82C558 Viper-M ISA+IDE") - DEVICE( OPTI, OPTI_82C621, "82C621") - DEVICE( OPTI, OPTI_82C700, "82C700") - DEVICE( OPTI, OPTI_82C701, "82C701 FireStar Plus") - DEVICE( OPTI, OPTI_82C814, "82C814 Firebridge 1") - DEVICE( OPTI, OPTI_82C822, "82C822") - DEVICE( OPTI, OPTI_82C825, "82C825 Firebridge 2") -ENDVENDOR() - -VENDOR( SGS, "SGS Thomson" ) - DEVICE( SGS, SGS_2000, "STG 2000X") - DEVICE( SGS, SGS_1764, "STG 1764X") -ENDVENDOR() - -VENDOR( BUSLOGIC, "BusLogic" ) - DEVICE( BUSLOGIC, BUSLOGIC_MULTIMASTER_NC, "MultiMaster NC") - DEVICE( BUSLOGIC, BUSLOGIC_MULTIMASTER, "MultiMaster") - DEVICE( BUSLOGIC, BUSLOGIC_FLASHPOINT, "FlashPoint") -ENDVENDOR() - -VENDOR( TI, "Texas Instruments" ) - DEVICE( TI, TI_TVP4010, "TVP4010 Permedia") - DEVICE( TI, TI_TVP4020, "TVP4020 Permedia 2") - DEVICE( TI, TI_PCI1130, "PCI1130") - DEVICE( TI, TI_PCI1131, "PCI1131") - DEVICE( TI, TI_PCI1250, "PCI1250") -ENDVENDOR() - -VENDOR( OAK, "OAK" ) - DEVICE( OAK, OAK_OTI107, "OTI107") -ENDVENDOR() - -VENDOR( WINBOND2, "Winbond" ) - DEVICE( WINBOND2, WINBOND2_89C940,"NE2000-PCI") - DEVICE( WINBOND2, WINBOND2_89C940F, "W89C940F") -ENDVENDOR() - -VENDOR( MOTOROLA, "Motorola" ) - DEVICE( MOTOROLA, MOTOROLA_MPC105,"MPC105 Eagle") - DEVICE( MOTOROLA, MOTOROLA_MPC106,"MPC106 Grackle") - DEVICE( MOTOROLA, MOTOROLA_RAVEN, "Raven") - DEVICE( MOTOROLA, MOTOROLA_FALCON,"Falcon") - DEVICE( MOTOROLA, MOTOROLA_CPX8216,"CPX8216") -ENDVENDOR() - -VENDOR( PROMISE, "Promise Technology" ) - DEVICE( PROMISE, PROMISE_20246, "IDE UltraDMA/33") - DEVICE( PROMISE, PROMISE_20262, "IDE UltraDMA/66") - DEVICE( PROMISE, PROMISE_5300, "DC5030") -ENDVENDOR() - -VENDOR( N9, "Number Nine" ) - DEVICE( N9, N9_I128, "Imagine 128") - DEVICE( N9, N9_I128_2, "Imagine 128v2") - DEVICE( N9, N9_I128_T2R, "Revolution 3D") -ENDVENDOR() - -VENDOR( UMC, "UMC" ) - DEVICE( UMC, UMC_UM8673F, "UM8673F") - DEVICE( UMC, UMC_UM8891A, "UM8891A") - DEVICE( UMC, UMC_UM8886BF, "UM8886BF") - DEVICE( UMC, UMC_UM8886A, "UM8886A") - DEVICE( UMC, UMC_UM8881F, "UM8881F") - DEVICE( UMC, UMC_UM8886F, "UM8886F") - DEVICE( UMC, UMC_UM9017F, "UM9017F") - DEVICE( UMC, UMC_UM8886N, "UM8886N") - DEVICE( UMC, UMC_UM8891N, "UM8891N") -ENDVENDOR() - -VENDOR( X, "X Technology" ) - DEVICE( X, X_AGX016, "ITT AGX016") -ENDVENDOR() - -VENDOR( PICOP, "PicoPower" ) - DEVICE( PICOP, PICOP_PT86C52X, "PT86C52x Vesuvius") - DEVICE( PICOP, PICOP_PT80C524, "PT80C524 Nile") -ENDVENDOR() - -VENDOR( APPLE, "Apple" ) - DEVICE( APPLE, APPLE_BANDIT, "Bandit") - DEVICE( APPLE, APPLE_GC, "Grand Central") - DEVICE( APPLE, APPLE_HYDRA, "Hydra") -ENDVENDOR() - -VENDOR( NEXGEN, "Nexgen" ) - DEVICE( NEXGEN, NEXGEN_82C501, "82C501") -ENDVENDOR() - -VENDOR( QLOGIC, "Q Logic" ) - DEVICE( QLOGIC, QLOGIC_ISP1020, "ISP1020") - DEVICE( QLOGIC, QLOGIC_ISP1022, "ISP1022") -ENDVENDOR() - -VENDOR( CYRIX, "Cyrix" ) - DEVICE( CYRIX, CYRIX_5510, "5510") - DEVICE( CYRIX, CYRIX_PCI_MASTER,"PCI Master") - DEVICE( CYRIX, CYRIX_5520, "5520") - DEVICE( CYRIX, CYRIX_5530_LEGACY,"5530 Kahlua Legacy") - DEVICE( CYRIX, CYRIX_5530_SMI, "5530 Kahlua SMI") - DEVICE( CYRIX, CYRIX_5530_IDE, "5530 Kahlua IDE") - DEVICE( CYRIX, CYRIX_5530_AUDIO,"5530 Kahlua Audio") - DEVICE( CYRIX, CYRIX_5530_VIDEO,"5530 Kahlua Video") -ENDVENDOR() - -VENDOR( LEADTEK, "Leadtek Research" ) - DEVICE( LEADTEK, LEADTEK_805, "S3 805") -ENDVENDOR() - -VENDOR( CONTAQ, "Contaq" ) - DEVICE( CONTAQ, CONTAQ_82C599, "82C599") - DEVICE( CONTAQ, CONTAQ_82C693, "82C693") -ENDVENDOR() - -VENDOR( FOREX, "Forex" ) -ENDVENDOR() - -VENDOR( OLICOM, "Olicom" ) - DEVICE( OLICOM, OLICOM_OC3136, "OC-3136/3137") - DEVICE( OLICOM, OLICOM_OC2315, "OC-2315") - DEVICE( OLICOM, OLICOM_OC2325, "OC-2325") - DEVICE( OLICOM, OLICOM_OC2183, "OC-2183/2185") - DEVICE( OLICOM, OLICOM_OC2326, "OC-2326") - DEVICE( OLICOM, OLICOM_OC6151, "OC-6151/6152") -ENDVENDOR() - -VENDOR( SUN, "Sun Microsystems" ) - DEVICE( SUN, SUN_EBUS, "PCI-EBus Bridge") - DEVICE( SUN, SUN_HAPPYMEAL, "Happy Meal Ethernet") - DEVICE( SUN, SUN_SIMBA, "Advanced PCI Bridge") - DEVICE( SUN, SUN_PBM, "PCI Bus Module") - DEVICE( SUN, SUN_SABRE, "Ultra IIi PCI") -ENDVENDOR() - -VENDOR( CMD, "CMD" ) - DEVICE( CMD, CMD_640, "640 (buggy)") - DEVICE( CMD, CMD_643, "643") - DEVICE( CMD, CMD_646, "646") - DEVICE( CMD, CMD_670, "670") -ENDVENDOR() - -VENDOR( VISION, "Vision" ) - DEVICE( VISION, VISION_QD8500, "QD-8500") - DEVICE( VISION, VISION_QD8580, "QD-8580") -ENDVENDOR() - -VENDOR( BROOKTREE, "Brooktree" ) - DEVICE( BROOKTREE, BROOKTREE_848, "Bt848") - DEVICE( BROOKTREE, BROOKTREE_849A, "Bt849") - DEVICE( BROOKTREE, BROOKTREE_878_1,"Bt878 2nd Contr. (?)") - DEVICE( BROOKTREE, BROOKTREE_878, "Bt878") - DEVICE( BROOKTREE, BROOKTREE_8474, "Bt8474") -ENDVENDOR() - -VENDOR( SIERRA, "Sierra" ) - DEVICE( SIERRA, SIERRA_STB, "STB Horizon 64") -ENDVENDOR() - -VENDOR( SGI, "Silicon Graphics Inc" ) - DEVICE( SGI, SGI_IOC3, "IOC3") -ENDVENDOR() - -VENDOR( ACC, "ACC MICROELECTRONICS" ) - DEVICE( ACC, ACC_2056, "2056") -ENDVENDOR() - -VENDOR( WINBOND, "Winbond" ) - DEVICE( WINBOND, WINBOND_83769, "W83769F") - DEVICE( WINBOND, WINBOND_82C105, "SL82C105") - DEVICE( WINBOND, WINBOND_83C553, "W83C553") -ENDVENDOR() - -VENDOR( DATABOOK, "Databook" ) - DEVICE( DATABOOK, DATABOOK_87144, "DB87144") -ENDVENDOR() - -VENDOR( PLX, "PLX" ) - DEVICE( PLX, PLX_9050, "PCI9050 I2O") - DEVICE( PLX, PLX_9080, "PCI9080 I2O") -ENDVENDOR() - -VENDOR( MADGE, "Madge Networks" ) - DEVICE( MADGE, MADGE_MK2, "Smart 16/4 BM Mk2 Ringnode") - DEVICE( MADGE, MADGE_C155S, "Collage 155 Server") -ENDVENDOR() - -VENDOR( 3COM, "3Com" ) - DEVICE( 3COM, 3COM_3C339, "3C339 TokenRing") - DEVICE( 3COM, 3COM_3C590, "3C590 10bT") - DEVICE( 3COM, 3COM_3C595TX, "3C595 100bTX") - DEVICE( 3COM, 3COM_3C595T4, "3C595 100bT4") - DEVICE( 3COM, 3COM_3C595MII, "3C595 100b-MII") - DEVICE( 3COM, 3COM_3C900TPO, "3C900 10bTPO") - DEVICE( 3COM, 3COM_3C900COMBO,"3C900 10b Combo") - DEVICE( 3COM, 3COM_3C905TX, "3C905 100bTX") - DEVICE( 3COM, 3COM_3C905T4, "3C905 100bT4") - DEVICE( 3COM, 3COM_3C905B_TX, "3C905B 100bTX") -ENDVENDOR() - -VENDOR( SMC, "SMC" ) - DEVICE( SMC, SMC_EPIC100, "9432 TX") -ENDVENDOR() - -VENDOR( AL, "Acer Labs" ) - DEVICE( AL, AL_M1445, "M1445") - DEVICE( AL, AL_M1449, "M1449") - DEVICE( AL, AL_M1451, "M1451") - DEVICE( AL, AL_M1461, "M1461") - DEVICE( AL, AL_M1489, "M1489") - DEVICE( AL, AL_M1511, "M1511") - DEVICE( AL, AL_M1513, "M1513") - DEVICE( AL, AL_M1521, "M1521") - DEVICE( AL, AL_M1523, "M1523") - DEVICE( AL, AL_M1531, "M1531 Aladdin IV") - DEVICE( AL, AL_M1533, "M1533 Aladdin IV") - DEVICE( AL, AL_M1541, "M1541 Aladdin V") - DEVICE( AL, AL_M1543, "M1543 Aladdin V") - DEVICE( AL, AL_M3307, "M3307 MPEG-1 decoder") - DEVICE( AL, AL_M4803, "M4803") - DEVICE( AL, AL_M5219, "M5219") - DEVICE( AL, AL_M5229, "M5229 TXpro") - DEVICE( AL, AL_M5237, "M5237 USB") - DEVICE( AL, AL_M5243, "M5243 AGP") - DEVICE( AL, AL_M7101, "M7101 PMU") -ENDVENDOR() - -VENDOR( MITSUBISHI, "Mitsubishi" ) -ENDVENDOR() - -VENDOR( SURECOM, "Surecom" ) - DEVICE( SURECOM, SURECOM_NE34, "NE-34PCI LAN") -ENDVENDOR() - -VENDOR( NEOMAGIC, "Neomagic" ) - DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_NM2070, "Magicgraph NM2070") - DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_128V, "MagicGraph 128V") - DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_128ZV, "MagicGraph 128ZV") - DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_NM2160, "MagicGraph NM2160") - DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_128ZVPLUS, "MagicGraph 128ZV+") -ENDVENDOR() - -VENDOR( ASP, "Advanced System Products" ) - DEVICE( ASP, ASP_ABP940, "ABP940") - DEVICE( ASP, ASP_ABP940U, "ABP940U") - DEVICE( ASP, ASP_ABP940UW, "ABP940UW") -ENDVENDOR() - -VENDOR( MACRONIX, "Macronix" ) - DEVICE( MACRONIX, MACRONIX_MX98713,"MX98713") - DEVICE( MACRONIX, MACRONIX_MX987x5,"MX98715 / MX98725") -ENDVENDOR() - -VENDOR( TCONRAD, "Thomas-Conrad" ) - DEVICE( TCONRAD, TCONRAD_TOKENRING, "Token Ring 4/16") -ENDVENDOR() - -VENDOR( CERN, "CERN" ) - DEVICE( CERN, CERN_SPSB_PMC, "STAR/RD24 SCI-PCI (PMC)") - DEVICE( CERN, CERN_SPSB_PCI, "STAR/RD24 SCI-PCI (PMC)") - DEVICE( CERN, CERN_HIPPI_DST, "HIPPI destination") - DEVICE( CERN, CERN_HIPPI_SRC, "HIPPI source") -ENDVENDOR() - -VENDOR( NVIDIA, "NVidia" ) - DEVICE( NVIDIA, NVIDIA_TNT, "Riva TNT") - DEVICE( NVIDIA, NVIDIA_TNT2, "Riva TNT2") - DEVICE( NVIDIA, NVIDIA_UTNT2, "Riva TNT2 (Ultra)") - DEVICE( NVIDIA, NVIDIA_VTNT2, "Riva TNT2 (Vanta)") - DEVICE( NVIDIA, NVIDIA_UVTNT2, "Riva TNT2 (Ultra Vanta)") - DEVICE( NVIDIA, NVIDIA_ITNT2, "Riva TNT2 (Integrated)") -ENDVENDOR() - -VENDOR( IMS, "IMS" ) - DEVICE( IMS, IMS_8849, "8849") -ENDVENDOR() - -VENDOR( TEKRAM2, "Tekram" ) - DEVICE( TEKRAM2, TEKRAM2_690c, "DC690c") -ENDVENDOR() - -VENDOR( TUNDRA, "Tundra" ) - DEVICE( TUNDRA, TUNDRA_CA91C042,"CA91C042 Universe") -ENDVENDOR() - -VENDOR( AMCC, "AMCC" ) - DEVICE( AMCC, AMCC_MYRINET, "Myrinet PCI (M2-PCI-32)") - DEVICE( AMCC, AMCC_PARASTATION,"ParaStation Interface") - DEVICE( AMCC, AMCC_S5933, "S5933 PCI44") - DEVICE( AMCC, AMCC_S5933_HEPC3,"S5933 Traquair HEPC3") -ENDVENDOR() - -VENDOR( INTERG, "Intergraphics" ) - DEVICE( INTERG, INTERG_1680, "IGA-1680") - DEVICE( INTERG, INTERG_1682, "IGA-1682") - DEVICE( INTERG, INTERG_2000, "CyberPro 2000") -ENDVENDOR() - -VENDOR( REALTEK, "Realtek" ) - DEVICE( REALTEK, REALTEK_8029, "8029") - DEVICE( REALTEK, REALTEK_8129, "8129") - DEVICE( REALTEK, REALTEK_8139, "8139") -ENDVENDOR() - -VENDOR( TRUEVISION, "Truevision" ) - DEVICE( TRUEVISION, TRUEVISION_T1000,"TARGA 1000") -ENDVENDOR() - -VENDOR( INIT, "Initio Corp" ) - DEVICE( INIT, INIT_320P, "320 P") - DEVICE( INIT, INIT_360P, "360 P") -ENDVENDOR() - -VENDOR( TTI, "Triones Technologies, Inc." ) - DEVICE( TTI, TTI_HPT343, "HPT343 IDE UltraDMA/33") - DEVICE( TTI, TTI_HPT366, "HPT366 IDE UltraDMA/66") -ENDVENDOR() - -VENDOR( VIA, "VIA Technologies" ) - DEVICE( VIA, VIA_8501_0, "VT 8501") - DEVICE( VIA, VIA_82C505, "VT 82C505") - DEVICE( VIA, VIA_82C561, "VT 82C561") - DEVICE( VIA, VIA_82C586_1, "VT 82C586 Apollo IDE") - DEVICE( VIA, VIA_82C576, "VT 82C576 3V") - DEVICE( VIA, VIA_82C585, "VT 82C585 Apollo VP1/VPX") - DEVICE( VIA, VIA_82C586_0, "VT 82C586 Apollo ISA") - DEVICE( VIA, VIA_82C595, "VT 82C595 Apollo VP2") - DEVICE( VIA, VIA_82C596, "VT 82C596 Apollo Mobile") - DEVICE( VIA, VIA_82C597_0, "VT 82C597 Apollo VP3") - DEVICE( VIA, VIA_82C598_0, "VT 82C598 Apollo MVP3") - DEVICE( VIA, VIA_82C680, "VT 82C680 Apollo P6") - DEVICE( VIA, VIA_82C686, "VT 82C686 Apollo Super") - DEVICE( VIA, VIA_82C691, "VT 82C691 Apollo Pro") - DEVICE( VIA, VIA_82C693, "VT 82C693 Apollo Pro Plus") - DEVICE( VIA, VIA_82C926, "VT 82C926 Amazon") - DEVICE( VIA, VIA_82C416, "VT 82C416MV") - DEVICE( VIA, VIA_82C595_97, "VT 82C595 Apollo VP2/97") - DEVICE( VIA, VIA_82C586_2, "VT 82C586 Apollo USB") - DEVICE( VIA, VIA_82C586_3, "VT 82C586B Apollo ACPI") - DEVICE( VIA, VIA_82C686_4, "VT 82C686 Apollo Super ACPI") - DEVICE( VIA, VIA_82C686_5, "VT 82C686 Apollo Super AC97/Audio") - DEVICE( VIA, VIA_82C686_6, "VT 82C686 Apollo Super AC97/Modem") - DEVICE( VIA, VIA_86C100A, "VT 86C100A") - DEVICE( VIA, VIA_8501_1, "VT 8501 PCI Bridge") - DEVICE( VIA, VIA_82C597_1, "VT 82C597 Apollo VP3 AGP") - DEVICE( VIA, VIA_82C598_1, "VT 82C598 Apollo MVP3 AGP") -ENDVENDOR() - -VENDOR( SMC2, "SMC" ) - DEVICE( SMC2, SMC2_1211TX, "1211 TX") -ENDVENDOR() - -VENDOR( VORTEX, "VORTEX" ) - DEVICE( VORTEX, VORTEX_GDT60x0, "GDT 60x0") - DEVICE( VORTEX, VORTEX_GDT6000B,"GDT 6000b") - DEVICE( VORTEX, VORTEX_GDT6x10, "GDT 6110/6510") - DEVICE( VORTEX, VORTEX_GDT6x20, "GDT 6120/6520") - DEVICE( VORTEX, VORTEX_GDT6530, "GDT 6530") - DEVICE( VORTEX, VORTEX_GDT6550, "GDT 6550") - DEVICE( VORTEX, VORTEX_GDT6x17, "GDT 6117/6517") - DEVICE( VORTEX, VORTEX_GDT6x27, "GDT 6127/6527") - DEVICE( VORTEX, VORTEX_GDT6537, "GDT 6537") - DEVICE( VORTEX, VORTEX_GDT6557, "GDT 6557") - DEVICE( VORTEX, VORTEX_GDT6x15, "GDT 6115/6515") - DEVICE( VORTEX, VORTEX_GDT6x25, "GDT 6125/6525") - DEVICE( VORTEX, VORTEX_GDT6535, "GDT 6535") - DEVICE( VORTEX, VORTEX_GDT6555, "GDT 6555") - DEVICE( VORTEX, VORTEX_GDT6x17RP,"GDT 6117RP/6517RP") - DEVICE( VORTEX, VORTEX_GDT6x27RP,"GDT 6127RP/6527RP") - DEVICE( VORTEX, VORTEX_GDT6537RP,"GDT 6537RP") - DEVICE( VORTEX, VORTEX_GDT6557RP,"GDT 6557RP") - DEVICE( VORTEX, VORTEX_GDT6x11RP,"GDT 6111RP/6511RP") - DEVICE( VORTEX, VORTEX_GDT6x21RP,"GDT 6121RP/6521RP") - DEVICE( VORTEX, VORTEX_GDT6x17RP1,"GDT 6117RP1/6517RP1") - DEVICE( VORTEX, VORTEX_GDT6x27RP1,"GDT 6127RP1/6527RP1") - DEVICE( VORTEX, VORTEX_GDT6537RP1,"GDT 6537RP1") - DEVICE( VORTEX, VORTEX_GDT6557RP1,"GDT 6557RP1") - DEVICE( VORTEX, VORTEX_GDT6x11RP1,"GDT 6111RP1/6511RP1") - DEVICE( VORTEX, VORTEX_GDT6x21RP1,"GDT 6121RP1/6521RP1") - DEVICE( VORTEX, VORTEX_GDT6x17RP2,"GDT 6117RP2/6517RP2") - DEVICE( VORTEX, VORTEX_GDT6x27RP2,"GDT 6127RP2/6527RP2") - DEVICE( VORTEX, VORTEX_GDT6537RP2,"GDT 6537RP2") - DEVICE( VORTEX, VORTEX_GDT6557RP2,"GDT 6557RP2") - DEVICE( VORTEX, VORTEX_GDT6x11RP2,"GDT 6111RP2/6511RP2") - DEVICE( VORTEX, VORTEX_GDT6x21RP2,"GDT 6121RP2/6521RP2") -ENDVENDOR() - -VENDOR( EF, "Efficient Networks" ) - DEVICE( EF, EF_ATM_FPGA, "155P-MF1 (FPGA)") - DEVICE( EF, EF_ATM_ASIC, "155P-MF1 (ASIC)") -ENDVENDOR() - -VENDOR( FORE, "Fore Systems" ) - DEVICE( FORE, FORE_PCA200PC, "PCA-200PC") - DEVICE( FORE, FORE_PCA200E, "PCA-200E") -ENDVENDOR() - -VENDOR( IMAGINGTECH, "Imaging Technology" ) - DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI") -ENDVENDOR() - -VENDOR( PHILIPS, "Philips" ) - DEVICE( PHILIPS, PHILIPS_SAA7145,"SAA7145") - DEVICE( PHILIPS, PHILIPS_SAA7146,"SAA7146") -ENDVENDOR() - -VENDOR( CYCLONE, "Cyclone" ) - DEVICE( CYCLONE, CYCLONE_SDK, "SDK") -ENDVENDOR() - -VENDOR( ALLIANCE, "Alliance" ) - DEVICE( ALLIANCE, ALLIANCE_PROMOTIO, "Promotion-6410") - DEVICE( ALLIANCE, ALLIANCE_PROVIDEO, "Provideo") - DEVICE( ALLIANCE, ALLIANCE_AT24, "AT24") - DEVICE( ALLIANCE, ALLIANCE_AT3D, "AT3D") -ENDVENDOR() - -VENDOR( VMIC, "VMIC" ) - DEVICE( VMIC, VMIC_VME, "VMIVME-7587") -ENDVENDOR() - -VENDOR( DIGI, "Digi Intl." ) - DEVICE( DIGI, DIGI_EPC, "AccelPort EPC") - DEVICE( DIGI, DIGI_RIGHTSWITCH, "RightSwitch SE-6") - DEVICE( DIGI, DIGI_XEM, "AccelPort Xem") - DEVICE( DIGI, DIGI_XR, "AccelPort Xr") - DEVICE( DIGI, DIGI_CX, "AccelPort C/X") - DEVICE( DIGI, DIGI_XRJ, "AccelPort Xr/J") - DEVICE( DIGI, DIGI_EPCJ, "AccelPort EPC/J") - DEVICE( DIGI, DIGI_XR_920, "AccelPort Xr 920") -ENDVENDOR() - -VENDOR( MUTECH, "Mutech" ) - DEVICE( MUTECH, MUTECH_MV1000, "MV-1000") -ENDVENDOR() - -VENDOR( RENDITION, "Rendition" ) - DEVICE( RENDITION, RENDITION_VERITE,"Verite 1000") - DEVICE( RENDITION, RENDITION_VERITE2100,"Verite 2100") -ENDVENDOR() - -VENDOR( TOSHIBA, "Toshiba" ) - DEVICE( TOSHIBA, TOSHIBA_601, "Laptop") - DEVICE( TOSHIBA, TOSHIBA_TOPIC95,"ToPIC95") - DEVICE( TOSHIBA, TOSHIBA_TOPIC97,"ToPIC97") -ENDVENDOR() - -VENDOR( RICOH, "Ricoh" ) - DEVICE( RICOH, RICOH_RL5C466, "RL5C466") -ENDVENDOR() - -VENDOR( ARTOP, "Artop Electronics" ) - DEVICE( ARTOP, ARTOP_ATP8400, "ATP8400") - DEVICE( ARTOP, ARTOP_ATP850UF, "ATP850UF") -ENDVENDOR() - -VENDOR( ZEITNET, "ZeitNet" ) - DEVICE( ZEITNET, ZEITNET_1221, "1221") - DEVICE( ZEITNET, ZEITNET_1225, "1225") -ENDVENDOR() - -VENDOR( OMEGA, "Omega Micro" ) - DEVICE( OMEGA, OMEGA_82C092G, "82C092G") -ENDVENDOR() - -VENDOR( LITEON, "LiteOn" ) - DEVICE( LITEON, LITEON_LNE100TX,"LNE100TX") -ENDVENDOR() - -VENDOR( NP, "Network Peripherals" ) - DEVICE( NP, NP_PCI_FDDI, "NP-PCI") -ENDVENDOR() - -VENDOR( ATT, "Lucent Microelectronics" ) - DEVICE( ATT, ATT_L56XMF, "L56xMF") -ENDVENDOR() - -VENDOR( SPECIALIX, "Specialix" ) - DEVICE( SPECIALIX, SPECIALIX_IO8, "IO8+/PCI") - DEVICE( SPECIALIX, SPECIALIX_XIO, "XIO/SIO host") - DEVICE( SPECIALIX, SPECIALIX_RIO, "RIO host") -ENDVENDOR() - -VENDOR( AURAVISION, "Auravision" ) - DEVICE( AURAVISION, AURAVISION_VXP524,"VXP524") -ENDVENDOR() - -VENDOR( IKON, "Ikon" ) - DEVICE( IKON, IKON_10115, "10115 Greensheet") - DEVICE( IKON, IKON_10117, "10117 Greensheet") -ENDVENDOR() - -VENDOR( ZORAN, "Zoran" ) - DEVICE( ZORAN, ZORAN_36057, "ZR36057") - DEVICE( ZORAN, ZORAN_36120, "ZR36120") -ENDVENDOR() - -VENDOR( KINETIC, "Kinetic" ) - DEVICE( KINETIC, KINETIC_2915, "2915 CAMAC") -ENDVENDOR() - -VENDOR( COMPEX, "Compex" ) - DEVICE( COMPEX, COMPEX_ENET100VG4, "Readylink ENET100-VG4") - DEVICE( COMPEX, COMPEX_RL2000, "ReadyLink 2000") -ENDVENDOR() - -VENDOR( RP, "Comtrol" ) - DEVICE( RP, RP32INTF, "RocketPort 32 Intf") - DEVICE( RP, RP8INTF, "RocketPort 8 Intf") - DEVICE( RP, RP16INTF, "RocketPort 16 Intf") - DEVICE( RP, RP4QUAD, "Rocketport 4 Quad") - DEVICE( RP, RP8OCTA, "RocketPort 8 Oct") - DEVICE( RP, RP8J, "RocketPort 8 J") - DEVICE( RP, RPP4, "RocketPort Plus 4 Quad") - DEVICE( RP, RPP8, "RocketPort Plus 8 Oct") - DEVICE( RP, RP8M, "RocketModem 8 J") -ENDVENDOR() - -VENDOR( CYCLADES, "Cyclades" ) - DEVICE( CYCLADES, CYCLOM_Y_Lo, "Cyclom-Y below 1Mbyte") - DEVICE( CYCLADES, CYCLOM_Y_Hi, "Cyclom-Y above 1Mbyte") - DEVICE( CYCLADES, CYCLOM_4Y_Lo, "Cyclom-4Y below 1Mbyte") - DEVICE( CYCLADES, CYCLOM_4Y_Hi, "Cyclom-4Y above 1Mbyte") - DEVICE( CYCLADES, CYCLOM_8Y_Lo, "Cyclom-8Y below 1Mbyte") - DEVICE( CYCLADES, CYCLOM_8Y_Hi, "Cyclom-8Y above 1Mbyte") - DEVICE( CYCLADES, CYCLOM_Z_Lo, "Cyclades-Z below 1Mbyte") - DEVICE( CYCLADES, CYCLOM_Z_Hi, "Cyclades-Z above 1Mbyte") -ENDVENDOR() - -VENDOR( ESSENTIAL, "Essential Communications" ) - DEVICE( ESSENTIAL, ESSENTIAL_ROADRUNNER,"Roadrunner serial HIPPI") -ENDVENDOR() - -VENDOR( O2, "O2 Micro" ) - DEVICE( O2, O2_6832, "6832") -ENDVENDOR() - -VENDOR( 3DFX, "3Dfx" ) - DEVICE( 3DFX, 3DFX_VOODOO, "Voodoo") - DEVICE( 3DFX, 3DFX_VOODOO2, "Voodoo2") - DEVICE( 3DFX, 3DFX_BANSHEE, "Banshee") - DEVICE( 3DFX, 3DFX_VOODOO3, "Voodoo3") -ENDVENDOR() - -VENDOR( SIGMADES, "Sigma Designs" ) - DEVICE( SIGMADES, SIGMADES_6425, "REALmagic64/GX") -ENDVENDOR() - -VENDOR( AVM, "AVM" ) - DEVICE( AVM, AVM_A1, "A1 (Fritz)") -ENDVENDOR() - -VENDOR( CCUBE, "C-Cube" ) -ENDVENDOR() - -VENDOR( DIPIX, "Dipix" ) -ENDVENDOR() - -VENDOR( STALLION, "Stallion" ) - DEVICE( STALLION, STALLION_ECHPCI832,"EasyConnection 8/32") - DEVICE( STALLION, STALLION_ECHPCI864,"EasyConnection 8/64") - DEVICE( STALLION, STALLION_EIOPCI,"EasyIO") -ENDVENDOR() - -VENDOR( OPTIBASE, "Optibase" ) - DEVICE( OPTIBASE, OPTIBASE_FORGE, "MPEG Forge") - DEVICE( OPTIBASE, OPTIBASE_FUSION,"MPEG Fusion") - DEVICE( OPTIBASE, OPTIBASE_VPLEX, "VideoPlex") - DEVICE( OPTIBASE, OPTIBASE_VPLEXCC,"VideoPlex CC") - DEVICE( OPTIBASE, OPTIBASE_VQUEST,"VideoQuest") -ENDVENDOR() - -VENDOR( ESS, "ESS Technologies" ) - DEVICE( ESS, ESS_AUDIOPCI, "3D Audio 1969") -ENDVENDOR() - -VENDOR( SATSAGEM, "SatSagem" ) - DEVICE( SATSAGEM, SATSAGEM_PCR2101,"PCR2101 DVB receiver") - DEVICE( SATSAGEM, SATSAGEM_TELSATTURBO,"Telsat Turbo DVB") -ENDVENDOR() - -VENDOR( HUGHES, "Hughes" ) - DEVICE( HUGHES, HUGHES_DIRECPC, "DirecPC") -ENDVENDOR() - -VENDOR( ENSONIQ, "Ensoniq" ) - DEVICE( ENSONIQ, ENSONIQ_ES1371, "ES1371") - DEVICE( ENSONIQ, ENSONIQ_AUDIOPCI,"AudioPCI") -ENDVENDOR() - -VENDOR( ALTEON, "Alteon" ) - DEVICE( ALTEON, ALTEON_ACENIC, "AceNIC") -ENDVENDOR() - -VENDOR( PICTUREL, "Picture Elements" ) - DEVICE( PICTUREL, PICTUREL_PCIVST,"PCIVST") -ENDVENDOR() - -VENDOR( NVIDIA_SGS, "NVidia/SGS Thomson" ) - DEVICE( NVIDIA_SGS, NVIDIA_SGS_RIVA128, "Riva 128") -ENDVENDOR() - -VENDOR( CBOARDS, "ComputerBoards" ) - DEVICE( CBOARDS, CBOARDS_DAS1602_16,"DAS1602/16") -ENDVENDOR() - -VENDOR( MOTOROLA_OOPS, "Motorola" ) - DEVICE( MOTOROLA_OOPS, MOTOROLA_FALCON,"Falcon") -ENDVENDOR() - -VENDOR( LAVA, "Lava Computer MFG" ) - DEVICE( LAVA, LAVA_PARALLEL, "Lava Parallel") - DEVICE( LAVA, LAVA_DUAL_PAR_A,"Lava Dual Parallel (A)") - DEVICE( LAVA, LAVA_DUAL_PAR_B,"Lava Dual Parallel (B)") - DEVICE( LAVA, LAVA_BOCA_IOPPAR,"BOCA Research IOPPAR") -ENDVENDOR() - -VENDOR( SYMPHONY, "Symphony" ) - DEVICE( SYMPHONY, SYMPHONY_101, "82C101") -ENDVENDOR() - -VENDOR( TEKRAM, "Tekram" ) - DEVICE( TEKRAM, TEKRAM_DC290, "DC-290") -ENDVENDOR() - -VENDOR( 3DLABS, "3Dlabs" ) - DEVICE( 3DLABS, 3DLABS_300SX, "GLINT 300SX") - DEVICE( 3DLABS, 3DLABS_500TX, "GLINT 500TX") - DEVICE( 3DLABS, 3DLABS_DELTA, "GLINT Delta") - DEVICE( 3DLABS, 3DLABS_PERMEDIA,"PERMEDIA") - DEVICE( 3DLABS, 3DLABS_MX, "GLINT MX") -ENDVENDOR() - -VENDOR( AVANCE, "Avance" ) - DEVICE( AVANCE, AVANCE_ALG2064, "ALG2064i") - DEVICE( AVANCE, AVANCE_2302, "ALG-2302") -ENDVENDOR() - -VENDOR( NETVIN, "NetVin" ) - DEVICE( NETVIN, NETVIN_NV5000SC,"NV5000") -ENDVENDOR() - -VENDOR( S3, "S3 Inc." ) - DEVICE( S3, S3_PLATO_PXS, "PLATO/PX (system)") - DEVICE( S3, S3_ViRGE, "ViRGE") - DEVICE( S3, S3_TRIO, "Trio32/Trio64") - DEVICE( S3, S3_AURORA64VP, "Aurora64V+") - DEVICE( S3, S3_TRIO64UVP, "Trio64UV+") - DEVICE( S3, S3_ViRGE_VX, "ViRGE/VX") - DEVICE( S3, S3_868, "Vision 868") - DEVICE( S3, S3_928, "Vision 928-P") - DEVICE( S3, S3_864_1, "Vision 864-P") - DEVICE( S3, S3_864_2, "Vision 864-P") - DEVICE( S3, S3_964_1, "Vision 964-P") - DEVICE( S3, S3_964_2, "Vision 964-P") - DEVICE( S3, S3_968, "Vision 968") - DEVICE( S3, S3_TRIO64V2, "Trio64V2/DX or /GX") - DEVICE( S3, S3_PLATO_PXG, "PLATO/PX (graphics)") - DEVICE( S3, S3_ViRGE_DXGX, "ViRGE/DX or /GX") - DEVICE( S3, S3_ViRGE_GX2, "ViRGE/GX2") - DEVICE( S3, S3_ViRGE_MX, "ViRGE/MX") - DEVICE( S3, S3_ViRGE_MXP, "ViRGE/MX+") - DEVICE( S3, S3_ViRGE_MXPMV, "ViRGE/MX+MV") - DEVICE( S3, S3_SONICVIBES, "SonicVibes") -ENDVENDOR() - -VENDOR( DCI, "Decision Computer Int." ) - DEVICE( DCI, DCI_PCCOM4, "PC COM PCI Bus 4 port serial Adapter") -ENDVENDOR() - -VENDOR( GENROCO, "Genroco" ) - DEVICE( GENROCO, GENROCO_HFP832, "TURBOstor HFP832") -ENDVENDOR() - -VENDOR( INTEL, "Intel" ) - DEVICE( INTEL, INTEL_82375, "82375EB") - DEVICE( INTEL, INTEL_82424, "82424ZX Saturn") - DEVICE( INTEL, INTEL_82378, "82378IB") - DEVICE( INTEL, INTEL_82430, "82430ZX Aries") - DEVICE( INTEL, INTEL_82434, "82434LX Mercury/Neptune") - DEVICE( INTEL, INTEL_82092AA_0,"82092AA PCMCIA bridge") - DEVICE( INTEL, INTEL_82092AA_1,"82092AA EIDE") - DEVICE( INTEL, INTEL_7116, "SAA7116") - DEVICE( INTEL, INTEL_82596, "82596") - DEVICE( INTEL, INTEL_82865, "82865") - DEVICE( INTEL, INTEL_82557, "EtherExpress Pro100") - DEVICE( INTEL, INTEL_82559ER, "82559ER") - DEVICE( INTEL, INTEL_82437, "82437") - DEVICE( INTEL, INTEL_82371FB_0,"82371FB PIIX ISA") - DEVICE( INTEL, INTEL_82371FB_1,"82371FB PIIX IDE") - DEVICE( INTEL, INTEL_82371MX, "430MX - 82371MX MPIIX") - DEVICE( INTEL, INTEL_82437MX, "430MX - 82437MX MTSC") - DEVICE( INTEL, INTEL_82441, "82441FX Natoma") - DEVICE( INTEL, INTEL_82380FB, "82380FB Mobile") - DEVICE( INTEL, INTEL_82439, "82439HX Triton II") - DEVICE( INTEL, INTEL_82371SB_0,"82371SB PIIX3 ISA") - DEVICE( INTEL, INTEL_82371SB_1,"82371SB PIIX3 IDE") - DEVICE( INTEL, INTEL_82371SB_2,"82371SB PIIX3 USB") - DEVICE( INTEL, INTEL_82437VX, "82437VX Triton II") - DEVICE( INTEL, INTEL_82439TX, "82439TX") - DEVICE( INTEL, INTEL_82371AB_0,"82371AB PIIX4 ISA") - DEVICE( INTEL, INTEL_82371AB, "82371AB PIIX4 IDE") - DEVICE( INTEL, INTEL_82371AB_2,"82371AB PIIX4 USB") - DEVICE( INTEL, INTEL_82371AB_3,"82371AB PIIX4 ACPI") - DEVICE( INTEL, INTEL_82443LX_0,"440LX - 82443LX PAC Host") - DEVICE( INTEL, INTEL_82443LX_1,"440LX - 82443LX PAC AGP") - DEVICE( INTEL, INTEL_82443BX_0,"440BX - 82443BX Host") - DEVICE( INTEL, INTEL_82443BX_1,"440BX - 82443BX AGP") - DEVICE( INTEL, INTEL_82443BX_2,"440BX - 82443BX Host (no AGP)") - DEVICE( INTEL, INTEL_P6, "Orion P6") - DEVICE( INTEL, INTEL_82450GX, "82450GX Orion P6") -ENDVENDOR() - -VENDOR( KTI, "KTI" ) - DEVICE( KTI, KTI_ET32P2, "ET32P2") -ENDVENDOR() - -VENDOR( ADAPTEC, "Adaptec" ) - DEVICE( ADAPTEC, ADAPTEC_7810, "AIC-7810 RAID") - DEVICE( ADAPTEC, ADAPTEC_7821, "AIC-7860") - DEVICE( ADAPTEC, ADAPTEC_38602, "AIC-7860") - DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850") - DEVICE( ADAPTEC, ADAPTEC_7855, "AIC-7855") - DEVICE( ADAPTEC, ADAPTEC_5800, "AIC-5800") - DEVICE( ADAPTEC, ADAPTEC_3860, "AIC-7860") - DEVICE( ADAPTEC, ADAPTEC_7860, "AIC-7860") - DEVICE( ADAPTEC, ADAPTEC_7861, "AIC-7861") - DEVICE( ADAPTEC, ADAPTEC_7870, "AIC-7870") - DEVICE( ADAPTEC, ADAPTEC_7871, "AIC-7871") - DEVICE( ADAPTEC, ADAPTEC_7872, "AIC-7872") - DEVICE( ADAPTEC, ADAPTEC_7873, "AIC-7873") - DEVICE( ADAPTEC, ADAPTEC_7874, "AIC-7874") - DEVICE( ADAPTEC, ADAPTEC_7895, "AIC-7895U") - DEVICE( ADAPTEC, ADAPTEC_7880, "AIC-7880U") - DEVICE( ADAPTEC, ADAPTEC_7881, "AIC-7881U") - DEVICE( ADAPTEC, ADAPTEC_7882, "AIC-7882U") - DEVICE( ADAPTEC, ADAPTEC_7883, "AIC-7883U") - DEVICE( ADAPTEC, ADAPTEC_7884, "AIC-7884U") - DEVICE( ADAPTEC, ADAPTEC_7885, "AIC-7885U") - DEVICE( ADAPTEC, ADAPTEC_7886, "AIC-7886U") - DEVICE( ADAPTEC, ADAPTEC_7887, "AIC-7887U") - DEVICE( ADAPTEC, ADAPTEC_7888, "AIC-7888U") - DEVICE( ADAPTEC, ADAPTEC_1030, "ABA-1030 DVB receiver") -ENDVENDOR() - -VENDOR( ADAPTEC2, "Adaptec" ) - DEVICE( ADAPTEC2, ADAPTEC2_2940U2,"AHA-2940U2") - DEVICE( ADAPTEC2, ADAPTEC2_2930U2,"AHA-2930U2") - DEVICE( ADAPTEC2, ADAPTEC2_7890B, "AIC-7890/1") - DEVICE( ADAPTEC2, ADAPTEC2_7890, "AIC-7890/1") - DEVICE( ADAPTEC2, ADAPTEC2_3940U2,"AHA-3940U2") - DEVICE( ADAPTEC2, ADAPTEC2_3950U2D,"AHA-3950U2D") - DEVICE( ADAPTEC2, ADAPTEC2_7896, "AIC-7896/7") - DEVICE( ADAPTEC2, ADAPTEC2_7892A, "AIC-7892") - DEVICE( ADAPTEC2, ADAPTEC2_7892B, "AIC-7892") - DEVICE( ADAPTEC2, ADAPTEC2_7892D, "AIC-7892") - DEVICE( ADAPTEC2, ADAPTEC2_7892P, "AIC-7892") - DEVICE( ADAPTEC2, ADAPTEC2_7899A, "AIC-7899") - DEVICE( ADAPTEC2, ADAPTEC2_7899B, "AIC-7899") - DEVICE( ADAPTEC2, ADAPTEC2_7899D, "AIC-7899") - DEVICE( ADAPTEC2, ADAPTEC2_7899P, "AIC-7899") -ENDVENDOR() - -VENDOR( ATRONICS, "Atronics" ) - DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL") -ENDVENDOR() - -VENDOR( TIGERJET, "TigerJet" ) - DEVICE( TIGERJET, TIGERJET_300, "Tiger300 ISDN") -ENDVENDOR() - -VENDOR( ARK, "ARK" ) - DEVICE( ARK, ARK_STING, "Stingray") - DEVICE( ARK, ARK_STINGARK, "Stingray ARK 2000PV") - DEVICE( ARK, ARK_2000MT, "2000MT") -ENDVENDOR() - -#undef VENDOR -#undef ENDVENDOR -#undef DEVICE diff -u --recursive --new-file v2.3.26/linux/drivers/pci/gen-devlist.c linux/drivers/pci/gen-devlist.c --- v2.3.26/linux/drivers/pci/gen-devlist.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/pci/gen-devlist.c Mon Nov 8 11:20:49 1999 @@ -0,0 +1,66 @@ +/* + * Generate devlist.h from the PCI ID file. + * + * (c) 1999 Martin Mares + */ + +#include +#include + +static void +pq(char *c) +{ + while (*c) { + if (*c == '"') + printf("\\\""); + else + putchar(*c); + c++; + } +} + +int +main(void) +{ + char line[1024], *c, vend[8]; + int vendors = 0; + + while (fgets(line, sizeof(line)-1, stdin)) { + if ((c = strchr(line, '\n'))) + *c = 0; + if (!line[0] || line[0] == '#') + continue; + if (line[1] == ' ') { + vend[0] = 0; + continue; + } + if (line[0] == '\t') { + if (vend[0] && strlen(line) > 5 && line[5] == ' ') { + c = line + 5; + while (*c == ' ') + *c++ = 0; + printf("\tDEVICE(%s,%s,\"", vend, line+1); + pq(c); + puts("\")"); + } + } else if (strlen(line) > 4 && line[4] == ' ') { + c = line + 4; + while (*c == ' ') + *c++ = 0; + if (vendors) + puts("ENDVENDOR()\n"); + vendors++; + strcpy(vend, line); + printf("VENDOR(%s,\"", vend); + pq(c); + puts("\")"); + } + } + puts("ENDVENDOR()\n\ +\n\ +#undef VENDOR\n\ +#undef DEVICE\n\ +#undef ENDVENDOR"); + + return 0; +} diff -u --recursive --new-file v2.3.26/linux/drivers/pci/names.c linux/drivers/pci/names.c --- v2.3.26/linux/drivers/pci/names.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/pci/names.c Mon Nov 8 11:19:53 1999 @@ -39,11 +39,11 @@ #define VENDOR( vendor, name ) static struct pci_device_info __devices_##vendor[] __initdata = { #define ENDVENDOR() }; -#define DEVICE( vendor, device, name ) { PCI_DEVICE_ID_##device, 0, __devicestr_##vendor##device }, +#define DEVICE( vendor, device, name ) { 0x##device, 0, __devicestr_##vendor##device }, #include "devlist.h" static const struct pci_vendor_info __initdata pci_vendor_list[] = { -#define VENDOR( vendor, name ) { PCI_VENDOR_ID_##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor }, +#define VENDOR( vendor, name ) { 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor }, #define ENDVENDOR() #define DEVICE( vendor, device, name ) #include "devlist.h" diff -u --recursive --new-file v2.3.26/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids --- v2.3.26/linux/drivers/pci/pci.ids Wed Dec 31 16:00:00 1969 +++ linux/drivers/pci/pci.ids Mon Nov 8 17:04:22 1999 @@ -0,0 +1,3640 @@ +# +# List of PCI ID's +# +# Maintained by Martin Mares +# If you have any new entries, send them to the maintainer. +# +# $Id: pci.ids,v 1.41 1999/10/30 09:25:10 mj Exp $ +# + +# Vendors, devices and subsystems. Please keep sorted. + +# Syntax: +# vendor vendor_name +# device device_name <-- single tab +# subvendor subdevice subsystem_name <-- two tabs + +0000 Gammagraphx, Inc. +001a Ascend Communications, Inc. +0033 Paradyne corp. +003d Lockheed Martin-Marietta Corp +0070 Hauppage computer works Inc. +0675 Dynalink + 1700 IS64PH ISDN Adapter + 1702 IS64PH ISDN Adapter +0a89 BREA Technologies Inc +0e11 Compaq Computer Corporation + 0001 PCI to EISA Bridge + 0002 PCI to ISA Bridge + 0508 Netelligent 4/16 Token Ring + 1000 Triflex/Pentium Bridge, Model 1000 + 2000 Triflex/Pentium Bridge, Model 2000 + 3032 QVision 1280/p + 3033 QVision 1280/p + 3034 QVision 1280/p + 4000 4000 [Triflex] + 6010 HotPlug PCI Bridge 6010 + a0f3 Triflex PCI to ISA Bridge + ae10 Smart-2/P RAID Controller + 0e11 4030 Smart-2/P Array Controller + 0e11 4031 Smart-2SL Array Controller + 0e11 4032 Smart Array Controller + 0e11 4033 Smart 3100ES Array Controller + ae29 MIS-L + ae2a MPC + ae2b MIS-E + ae32 Netelligent 10/100 + ae34 Netelligent 10 + ae35 Integrated NetFlex-3/P + ae40 Netelligent 10/100 Dual + ae43 ProLiant Integrated Netelligent 10/100 + ae69 CETUS-L + ae6c Northstar + b011 Integrated Netelligent 10/100 + b012 Netelligent 10 T/2 + b030 Netelligent WS 5100 + b04a 10/100TX WOL UTP Controller + b0c6 10/100TX Embedded WOL UTP Controller + b0d7 NC3121 (Rev A & B) + f130 NetFlex-3/P ThunderLAN 1.0 + f150 NetFlex-3/P ThunderLAN 2.3 +1000 Symbios Logic Inc. (formerly NCR) + 0001 53c810 + 1000 1000 8100S + 0002 53c820 + 0003 53c825 + 0004 53c815 + 0005 53c810AP + 0006 53c860 + 000b 53c896 + 000c 53c895 + 000d 53c885 + 000f 53c875 + 0e11 7004 Embedded Ultra Wide SCSI Controller + 1092 8760 FirePort 40 Dual SCSI Controller + 1de1 3904 DC390F Ultra Wide SCSI Controller + 0012 53c895a + 008f 53c875J + 1092 8000 FirePort 40 SCSI Controller + 1092 8760 FirePort 40 Dual SCSI Host Adapter + 0701 83C885 + 0702 Yellowfin G-NIC gigabit ethernet + 1318 0000 PEI100X + 0901 61C102 + 1000 63C815 +1001 Initio + 9100 INI-9100/9100W SCSI Host +1002 ATI Technologies Inc + 4158 68800AX [Mach32] + 4354 215CT [Mach64 CT] + 4358 210888CX [Mach64 CX] + 4554 210888ET [Mach64 ET] + 4742 3D Rage Pro AGP 1X/2X + 4744 3D Rage Pro AGP 1X + 4747 3D Rage Pro + 4749 3D Rage Pro + 474c Rage XC + 474d Rage XL AGP + 474e Rage XC AGP + 474f Rage XL + 4750 3D Rage Pro 215GP + 4751 3D Rage Pro 215GQ + 4753 Rage XC + 4754 3D Rage I/II 215GT [Mach64 GT] + 4755 3D Rage II+ 215GTB [Mach64 GTB] + 4756 3D Rage IIC 215IIC [Mach64 GT IIC] + 4757 3D Rage IIC AGP + 4758 210888GX [Mach64 GX] + 4759 3D Rage IIC + 475a 3D Rage IIC AGP + 4c42 3D Rage LT Pro AGP-133 + 0e11 b10e 3D Rage LT Pro (Compaq Armada 1750) + 4c44 3D Rage LT Pro AGP-66 + 4c47 3D Rage LT-G 215LG + 4c49 3D Rage LT Pro + 4c4d 3D Rage P/M Mobility AGP 2x + 4c4e 3D Rage L Mobility AGP 2x + 4c50 3D Rage LT Pro + 4c51 3D Rage LT Pro + 4c52 3D Rage P/M Mobility + 4c53 3D Rage L Mobility + 4c54 264LT [Mach64 LT] + 5041 Rage 128 PA + 5042 Rage 128 PB + 5043 Rage 128 PC + 5044 Rage 128 PD + 5045 Rage 128 PE + 5046 Rage 128 PF + 5047 Rage 128 PG + 5048 Rage 128 PH + 5049 Rage 128 PI + 504A Rage 128 PJ + 504B Rage 128 PK + 504C Rage 128 PL + 504D Rage 128 PM + 504E Rage 128 PN + 504F Rage 128 PO + 5050 Rage 128 PP + 5051 Rage 128 PQ + 5052 Rage 128 PR + 5053 Rage 128 PS + 5054 Rage 128 PT + 5055 Rage 128 PU + 5056 Rage 128 PV + 5057 Rage 128 PW + 5058 Rage 128 PX + 5245 Rage 128 RE + 5246 Rage 128 RF + 524b Rage 128 RK + 524c Rage 128 RL + 5345 Rage 128 SE + 5346 Rage 128 SF + 5347 Rage 128 SG + 534B Rage 128 SK + 534C Rage 128 SL + 534D Rage 128 SM + 5354 Mach 64 VT + 1002 5654 Mach 64 reference + 5654 264VT [Mach64 VT] + 5655 264VT3 [Mach64 VT3] + 5656 264VT4 [Mach64 VT4] +1003 ULSI Systems + 0201 US201 +1004 VLSI Technology Inc + 0005 82C592-FC1 + 0006 82C593-FC1 + 0007 82C594-AFC2 + 0008 82C596/7 [Wildcat] + 0009 82C597-AFC2 + 000c 82C541 [Lynx] + 000d 82C543 [Lynx] + 0101 82C532 + 0102 82C534 + 0103 82C538 + 0104 82C535 + 0105 82C147 + 0200 82C975 + 0280 82C925 + 0702 VAS96011 [Golden Gate II] +1005 Avance Logic Inc. [ALI] + 2064 ALG2032/2064 + 2128 ALG2364A + 2301 ALG2301 + 2302 ALG2302 + 2364 ALG2364 + 2464 ALG2364A + 2501 ALG2564A/25128A +1006 Reply Group +1007 NetFrame Systems Inc +1008 Epson +100a Phoenix Technologies +100b National Semiconductor Corporation + 0001 DP83810 + 0002 87415 + d001 87410 +100c Tseng Labs Inc + 3202 ET4000/W32p rev A + 3205 ET4000/W32p rev B + 3206 ET4000/W32p rev C + 3207 ET4000/W32p rev D + 3208 ET6000 + 4702 ET6300 +100d AST Research Inc +100e Weitek + 9000 P9000 + 9001 P9000 + 9100 P9100 +1010 Video Logic, Ltd. +1011 Digital Equipment Corporation + 0001 DECchip 21050 + 0002 DECchip 21040 [Tulip] + 0004 DECchip 21030 [TGA] + 0007 NVRAM [Zephyr NVRAM] + 0008 KZPSA [KZPSA] + 0009 DECchip 21140 [FasterNet] + 10b8 2001 SMC9332BDT EtherPower 10/100 + 10b8 2002 SMC9332BVT EtherPower T4 10/100 + 10b8 2003 SMC9334BDT EtherPower 10/100 (1-port) + 1112 2300 RNS2300 Fast Ethernet + 1112 2320 RNS2320 Fast Ethernet + 1112 2340 RNS2340 Fast Ethernet + 1113 1207 EN-1207-TX Fast Ethernet + 1109 2400 ANA-6944A/TX Fast Ethernet + 1186 1100 DFE-500TX Fast Ethernet + 1282 9100 AEF-380TXD Fast Ethernet + 2646 0001 KNE100TX Fast Ethernet + 000a 21230 Video Codec + 000d PBXGB [TGA2] + 000f DEFPA + 0014 DECchip 21041 [Tulip Pass 3] + 1186 0100 DE-530+ + 0016 DGLPB [OPPO] + 0019 DECchip 21142/43 + 1011 500b DE500 Fast Ethernet + 1014 0001 10/100 EtherJet Cardbus + 1025 0315 ALN315 Fast Ethernet + 108d 0016 Rapidfire 2327 10/100 Ethernet + 10b8 2005 SMC8032DT Extreme Ethernet 10/100 + 10ef 8169 Cardbus Fast Ethernet + 1109 2a00 ANA-6911A/TX Fast Ethernet + 1109 2b00 ANA-6911A/TXC Fast Ethernet + 1109 3000 ANA-6922/TX Fast Ethernet + 1113 1207 Cheetah Fast Ethernet + 1113 2220 Cardbus Fast Ethernet + 115d 0002 Cardbus Ethernet 10/100 + 1179 0203 Fast Ethernet + 1179 0204 Cardbus Fast Ethernet + 1186 1101 DFE-500TX Fast Ethernet + 1186 1102 DFE-500TX Fast Ethernet + 1266 0004 Eagle Fast EtherMAX + 12af 0019 NetFlyer Cardbus Fast Ethernet + 1395 0001 10/100 Ethernet CardBus PC Card + 8086 0001 EtherExpress PRO/100 Mobile CardBus 32 + 0021 DECchip 21052 + 0022 DECchip 21150 + 0024 DECchip 21152 + 0025 DECchip 21153 + 0026 DECchip 21154 + 0045 DECchip 21553 + 0046 DECchip 21554 +1012 Micronics Computers Inc +1013 Cirrus Logic + 0038 GD 7548 + 0040 GD 7555 Flat Panel GUI Accelerator + 004c GD 7556 Video/Graphics LCD/CRT Ctrlr + 00a0 GD 5430/40 [Alpine] + 00a2 GD 5432 [Alpine] + 00a4 GD 5434-4 [Alpine] + 00a8 GD 5434-8 [Alpine] + 00ac GD 5436 [Alpine] + 00b0 GD 5440 + 00b8 GD 5446 + 00bc GD 5480 + 00d0 GD 5462 + 00d2 GD 5462 [Laguna I] + 00d4 GD 5464 [Laguna] + 00d6 GD 5465 [Laguna] + 00e8 GD 5436U + 1100 CL 6729 + 1110 PD 6832 + 1112 PD 6834 PCMCIA/CardBus Ctrlr + 1113 PD 6833 PCMCIA/CardBus Ctrlr + 1200 GD 7542 [Nordic] + 1202 GD 7543 [Viking] + 1204 GD 7541 [Nordic Light] + 4400 CD 4400 + 6001 CS 4610/11 [CrystalClear SoundFusion Audio Accelerator] + 6003 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator] +1014 IBM + 0002 PCI to MCA Bridge + 0005 Alta Lite + 0007 Alta MP + 000a Fire Coral + 0018 TR Auto LANstreamer + 001b GXT-150P + 001d 82G2675 + 0020 MCA + 0022 IBM27-82351 + 002d Python + 002e ServeRAID controller + 0036 Miami + 003e 16/4 Token ring UTP/STP controller + 1014 003E Token-Ring Adapter + 1014 00CD Token-Ring Adapter + Wake-On-LAN + 1014 00CE 16/4 Token-Ring Adapter 2 + 1014 00CF 16/4 Token-Ring Adapter Special + 1014 00E4 High-Speed 100/16/4 Token-Ring Adapter + 1014 00E5 16/4 Token-Ring Adapter 2 + Wake-On-LAN + 0046 MPIC interrupt controller + 0053 25 MBit ATM Controller + 0057 MPEG PCI Bridge + 005C i82557B 10/100 + 007d 3780IDSP [MWave] + 0095 20H2999 PCI Docking Bridge + 00b7 256-bit Graphics Rasterizer [Fire GL1] + ffff MPIC-2 interrupt controller +1015 LSI Logic Corp of Canada +1016 ICL Personal Systems +1017 SPEA Software AG + 5343 SPEA 3D Accelerator +1018 Unisys Systems +1019 Elitegroup Computer Systems +101a AT&T GIS (NCR) + 0005 100VG ethernet +101b Vitesse Semiconductor +101c Western Digital + 0193 33C193A + 0196 33C196A + 0197 33C197A + 0296 33C296A + 3193 7193 + 3197 7197 + 3296 33C296A + 4296 34C296 + 9710 Pipeline 9710 + 9712 Pipeline 9712 + c24a 90C +101e American Megatrends Inc. + 9010 MegaRAID + 9060 MegaRAID +101f PictureTel +1020 Hitachi Computer Products +1021 OKI Electric Industry Co. Ltd. +1022 Advanced Micro Devices [AMD] + 2000 79c970 [PCnet LANCE] + 103c 104c Ethernet with LAN remote power Adapter + 103c 1064 Ethernet with LAN remote power Adapter + 103c 1065 Ethernet with LAN remote power Adapter + 103c 106c Ethernet with LAN remote power Adapter + 103c 106e Ethernet with LAN remote power Adapter + 103c 10ea Ethernet with LAN remote power Adapter + 1113 1220 EN1220 10/100 Fast Ethernet + 1259 2450 AT-2450 10/100 Fast Ethernet + 1259 2700 AT-2700TX 10/100 Fast Ethernet + 1259 2701 AT-2700FX 100Mb Ethernet + 2001 79c978 [HomePNA] + 2020 53c974 [PCscsi] + 2040 79c974 +1023 Trident Microsystems + 0194 82C194 + 2000 4DWave DX + 2001 4DWave NX + 8400 CyberBlade/i7 + 8420 CyberBlade/i7d + 8500 CyberBlade/i1 + 9320 TGUI 9320 + 9382 Cyber 9382 [Reference design] + 9383 Cyber 9383 [Reference design] + 9385 Cyber 9385 [Reference design] + 9386 Cyber 9386 + 9388 Cyber 9388 + 9397 Cyber 9397 + 939a Cyber 9397DVD + 9420 TGUI 9420 + 9430 TGUI 9430 + 9440 TGUI 9440 + 9460 TGUI 9460 + 9470 TGUI 9470 + 9520 Cyber 9520 + 9525 Cyber 9525 + 9660 TGUI 9660/968x/968x + 9680 TGUI 9680 + 9682 TGUI 9682 + 9683 TGUI 9683 + 9685 ProVIDIA 9685 + 9750 3DIm`age 975 + 9753 TGUI 9753 + 9754 TGUI 9754 + 9759 TGUI 975 + 9783 TGUI 9783 + 9785 TGUI 9785 + 9850 3DImage 9850 + 9880 Blade 3D PCI/AGP +1024 Zenith Data Systems +1025 Acer Incorporated [ALI] + 1435 M1435 + 1445 M1445 + 1449 M1449 + 1451 M1451 + 1461 M1461 + 1489 M1489 + 1511 M1511 + 1513 M1513 + 1531 M1531 + 1533 M1533 + 3141 M3141 + 3143 M3143 + 3145 M3145 + 3147 M3147 + 3149 M3149 + 3151 M3151 + 5217 M5217H + 5219 M5219 + 5225 M5225 + 5229 M5229 + 5235 M5235 +1028 Dell Computer Corporation +1029 Siemens Nixdorf IS +102a LSI Logic + 0000 HYDRA + 0010 ASPEN +102b Matrox Graphics, Inc. +#DJ: I've a suspicion that 0010 is a duplicate of 0d10. + 0010 MGA-I [Impression?] + 0518 MGA-II [Athena] + 0519 MGA 2064W [Millennium] + 051a MGA 1064SG [Mystique] + 1100 102b MGA-1084SG Mystique + 051b MGA 2164W [Millennium II] + 051e MGA 1064SG [Mystique] AGP + 051f MGA 2164W [Millennium II] AGP + 0520 MGA G200 + 102b dbc2 G200 Multi-Monitor + 102b dbc8 G200 Multi-Monitor + 102b dbe2 G200 Multi-Monitor + 102b dbe8 G200 Multi-Monitor + 102b ff03 Millennium G200 SD + 102b ff04 Marvel G200 + 0521 MGA G200 AGP + 1014 ff03 Millennium G200 AGP + 102b 48e9 Mystique G200 AGP + 102b 48f8 Millennium G200 SD AGP + 102b 4a60 Millennium G200 LE AGP + 102b 4a64 Millennium G200 AGP + 102b c93c Millennium G200 AGP + 102b c9b0 Millennium G200 AGP + 102b c9bc Millennium G200 AGP + 102b ca60 Millennium G250 LE AGP + 102b ca6c Millennium G250 AGP + 102b dbbc Millennium G200 AGP + 102b f806 Mystique G200 Video AGP + 102b ff02 Mystique G200 AGP + 102b ff03 Millennium G200 AGP + 102b ff04 Marvel G200 AGP + 0525 MGA G400 AGP + 0e11 b16f Matrox MGA-G400 AGP + 102b 0328 Millennium G400 16Mb SDRAM + 102b 0338 Millennium G400 16Mb SDRAM + 102b 19d8 Millennium G400 16Mb SGRAM + 102b 19f8 Millennium G400 32Mb SGRAM + 102b 2159 Millennium G400 Dual Head 16Mb + 102b 2179 Millennium G400 MAX/Dual Head 32Mb + 102b 217d Millennium G400 Dual Head Max + 102b 2f58 Millennium G400 + 102b 2f78 Millennium G400 + 102b 3693 Marvel G400 AGP + b16f 0e11 Matrox MGA-G400 AGP + 0d10 MGA Ultima/Impression + 1000 MGA G100 [Productiva] + 102b ff01 Productiva G100 + 102b ff05 Productiva G100 Multi-Monitor + 1001 MGA G100 [Productiva] AGP + 102b ff05 MGA-G100 Productiva AGP Multi-Monitor + 2007 MGA Mistral + 4536 VIA Framegrabber +102c Chips and Technologies + 00b8 F64310 + 00c0 F69000 HiQVideo + 00d0 F65545 + 00d8 F65545 + 00dc F65548 + 00e0 F65550 + 00e4 F65554 + 00e5 F65555 HiQVPro + 0e11 b049 Armada 1700 Laptop Display Controller + 00f0 F68554 + 00f4 F68554 HiQVision + 00f5 F68555 +102d Wyse Technology Inc. + 50dc 3328 Audio +102e Olivetti Advanced Technology +102f Toshiba America + 0009 r4x00 + 0020 ATM Meteor 155 +1030 TMC Research +1031 Miro Computer Products AG + 5601 DC20 ASIC + 5607 Video I/O & motion JPEG compressor + 5631 Media 3D + 6057 MiroVideo DC10/DC30+ +1032 Compaq +1033 NEC Corporation + 0001 PCI to 486-like bus Bridge + 0002 PCI to VL98 Bridge + 0003 ATM Controller + 0004 R4000 PCI Bridge + 0005 PCI to 486-like bus Bridge + 0007 PCI to UX-Bus Bridge + 001a [Nile II] + 0021 Vrc4373 [Nile I] + 0029 PowerVR PCX1 + 002a PowerVR 3D + 0035 USB + 0046 PowerVR PCX2 [midas] + 005a Vrc5074 [Nile 4] + 0063 Firewarden + 0067 PowerVR Neon 250 Chipset + 1010 0020 PowerVR Neon 250 AGP 32Mb + 1010 0080 PowerVR Neon 250 AGP 16Mb + 1010 0088 PowerVR Neon 250 16Mb + 1010 0090 PowerVR Neon 250 AGP 16Mb + 1010 0098 PowerVR Neon 250 16Mb + 1010 00a0 PowerVR Neon 250 AGP 32Mb + 1010 00a8 PowerVR Neon 250 32Mb + 1010 0120 PowerVR Neon 250 AGP 32Mb + 0074 56k Voice Modem + 1033 8014 RCV56ACF 56k Voice Modem + 009b Vrc5476 +1034 Framatome Connectors USA Inc. +1035 Comp. & Comm. Research Lab +1036 Future Domain Corp. + 0000 TMC-18C30 [36C70] +1037 Hitachi Micro Systems +1038 AMP, Inc +1039 Silicon Integrated Systems [SiS] + 0001 5591/5592 AGP + 0002 SG86C202 + 0006 85C501/2/3 + 0008 85C503/5513 + 0009 ACPI + 0200 5597/5598 VGA + 0204 82C204 + 0205 SG86C205 + 0406 85C501/2 + 0496 85C496 + 0530 530 Host + 0597 5513C + 0601 85C601 + 0620 620 Host + 0900 SiS900 10/100 Ethernet + 3602 83C602 + 5107 5107 + 5511 5511/5512 + 5513 5513 + 5517 5517 + 5571 5571 + 5591 5591/5592 Host + 5597 5597 [SiS5582] + 5600 5600 Host + 6204 Video decoder & MPEG interface + 6236 6236 3D-AGP + 6306 6306 3D-AGP + 6326 86C326 + 1092 0a50 SpeedStar A50 + 1092 0a70 SpeedStar A70 + 1092 4910 SpeedStar A70 + 1092 4920 SpeedStar A70 + 7001 7001 + 7007 OHCI Compliant FireWire Controller +103a Seiko Epson Corporation +103b Tatung Co. of America +103c Hewlett-Packard Company + 1030 J2585A + 1031 J2585B + 1040 J2973A DeskDirect 10BaseT NIC + 1041 J2585B DeskDirect 10/100 NIC + 1042 J2970A DeskDirect 10BaseT/2 NIC + 1064 79C970 PCnet Ethernet Controller + 2910 E2910A + 2925 E2925A +103e Solliday Engineering +103f Synopsys/Logic Modeling Group +1040 Accelgraphics Inc. +1041 Computrend +1042 Micron + 1000 FDC 37C665 + 1001 37C922 + 3000 Samurai_0 + 3010 Samurai_1 + 3020 Samurai_IDE +1043 Asustek Computer, Inc. +1044 Distributed Processing Technology + 1012 Domino RAID Engine + a400 SmartCache/Raid I-IV Controller + a500 PCI Bridge + a501 SmartRAID V Controller +1045 OPTi Inc. + a0f8 82C750 [Vendetta] USB Controller + c101 92C264 + c178 92C178 + c556 82X556 [Viper] + c557 82C557 [Viper-M] + c558 82C558 [Viper-M ISA+IDE] + c567 82C750 [Vendetta], device 0 + c568 82C750 [Vendetta], device 1 + c569 82C579 [Viper XPress+ Chipset] + c621 82C621 + c700 82C700 + c701 82C701 [FireStar Plus] + c814 82C814 [Firebridge 1] + c822 82C822 + c824 82C824 + c825 82C825 [Firebridge 2] + c861 82C861 + c895 82C895 + d568 82C825 [Firebridge 2] +1046 IPC Corporation, Ltd. +1047 Genoa Systems Corp +1048 Elsa AG + 1000 QuickStep 1000 + 3000 QuickStep 3000 +1049 Fountain Technologies, Inc. +104a SGS Thomson Microelectronics + 0008 STG 2000X + 0009 STG 1764X + 1746 STG 1764X + 3520 MPEG-II decoder card +104b BusLogic + 0140 BT-946C (old) [multimaster 01] + 1040 BT-946C (BA80C30) [MultiMaster 10] + 8130 Flashpoint LT +104c Texas Instruments + 0500 100 MBit LAN Controller + 0508 TMS380C2X Compressor Interface + 1000 Eagle i/f AS + 3d04 TVP4010 [Permedia] + 3d07 TVP4020 [Permedia 2] + 1092 0127 FIRE GL 1000 PRO + 1092 0136 FIRE GL 1000 PRO + 1092 0141 FIRE GL 1000 PRO + 1092 0146 FIRE GL 1000 PRO + 1092 0148 FIRE GL 1000 PRO + 1092 0149 FIRE GL 1000 PRO + 1092 0152 FIRE GL 1000 PRO + 1092 0154 FIRE GL 1000 PRO + 1092 0155 FIRE GL 1000 PRO + 1092 0156 FIRE GL 1000 PRO + 1092 0157 FIRE GL 1000 PRO + 1097 3d01 Jeronimo Pro + 3d3d 0100 Reference Permedia 2 3D + 8000 LYNX FireWire Host Controller + 8009 OHCI Compliant FireWire Controller + 8019 TSB12LV23 OHCI Compliant IEEE-1394 Controller + a001 TDC1570 + a100 TDC1561 + ac10 PCI1050 + ac11 PCI1053 + ac12 PCI1130 + ac13 PCI1031 + ac15 PCI1131 + ac16 PCI1250 + ac17 PCI1220 + ac18 PCI1260 + ac19 PCI1221 + ac1a PCI1210 + ac1b PCI1221 + ac1c PCI1225 + ac1d PCI1251 + ac20 TI 2030 + fe00 FireWire Host Controller + fe03 12C01A FireWire Host Controller +104d Sony Corporation +104e Oak Technology, Inc + 0017 OTI-64017 + 0107 OTI-107 [Spitfire] + 0111 OTI-64111 [Spitfire] + 0217 OTI-64217 + 0317 OTI-64317 +104f Co-time Computer Ltd +1050 Winbond Electronics Corp + 0000 NE2000 + 0001 W83769F + 0105 W82C105 + 0840 W89C840 + 0940 W89C940 + 5a5a W89C940F + 9970 W9970CF +1051 Anigma, Inc. +1053 Young Micro Systems +1054 Hitachi, Ltd +1055 EFAR Microsystems +1056 ICL +# Motorola made a mistake and used this value, please duplicate Moto +# entries here -- Cort +1507 Motorola Computer Group + 0001 MPC105 [Eagle] + 0002 MPC106 [Grackle] + 0100 MC145575 [HFC-PCI] + 0431 KTI829c 100VG + 4801 Raven + 4802 Falcon + 4803 Hawk + 4806 CPX8216 +1057 Motorola Computer Group + 0001 MPC105 [Eagle] + 0002 MPC106 [Grackle] + 0100 MC145575 [HFC-PCI] + 0431 KTI829c 100VG + 4801 Raven + 4802 Falcon + 4803 Hawk + 4806 CPX8216 +1058 Electronics & Telecommunications RSH +1059 Teknor Industrial Computers Inc +105a Promise Technology, Inc. + 4d33 20246 + 4d38 20262 + 5300 DC5300 +105b Foxconn International, Inc. +105c Wipro Infotech Limited +105d Number 9 Computer Company + 2309 Imagine 128 + 2339 Imagine 128-II + 105d 0000 Imagine 128 series 2 4Mb VRAM + 105d 0001 Imagine 128 series 2 4Mb VRAM + 105d 0002 Imagine 128 series 2 4Mb VRAM + 105d 0003 Imagine 128 series 2 4Mb VRAM + 105d 0004 Imagine 128 series 2 4Mb VRAM + 105d 0005 Imagine 128 series 2 4Mb VRAM + 105d 0006 Imagine 128 series 2 4Mb VRAM + 105d 0007 Imagine 128 series 2 4Mb VRAM + 105d 0008 Imagine 128 series 2e 4Mb DRAM + 105d 0009 Imagine 128 series 2e 4Mb DRAM + 105d 000a Imagine 128 series 2 8Mb VRAM + 105d 000b Imagine 128 series 2 8Mb H-VRAM + 493d Imagine 128 T2R [Ticket to Ride] + 5348 Revolution 4 +105e Vtech Computers Ltd +105f Infotronic America Inc +1060 United Microelectronics [UMC] + 0001 UM82C881 + 0002 UM82C886 + 0101 UM8673F + 0881 UM8881 + 0886 UM8886F + 0891 UM8891A + 1001 UM886A + 673a UM8886BF + 8710 UM8710 + 886a UM8886A + 8881 UM8881F + 8886 UM8886F + 888a UM8886A + 8891 UM8891A + 9017 UM9017F + 9018 UM9018 + 9026 UM9026 + e881 UM8881N + e886 UM8886N + e891 UM8891N +1061 I.I.T. + 0001 AGX016 + 0002 IIT3204/3501 +1062 Maspar Computer Corp +1063 Ocean Office Automation +1064 Alcatel +1065 Texas Microsystems +1066 PicoPower Technology + 0000 PT80C826 + 0001 PT86C52x [Vesuvius] + 0002 PT80C524 [Nile] + 0005 National PC87550 System Controller + 8002 PT80C524 [Nile] +1067 Mitsubishi Electronics +1068 Diversified Technology +1069 Mylex Corporation + 0001 DAC960P + 0002 DAC960PD + 0010 DAC960PX + ba55 eXtremeRAID support Device +106a Aten Research Inc +106b Apple Computer Inc. + 0001 Bandit PowerPC host bridge + 0002 Grand Central I/O + 0003 Control Video + 0004 PlanB Video-In + 0007 O'Hare I/O + 000e Hydra Mac I/O + 0010 Heathrow Mac I/O + 0017 Paddington Mac I/O +106c Hyundai Electronics America + 8803 Dual Window Graphics Accelerator + 8804 LAN Controller + 8805 100-BaseT LAN +106d Sequent Computer Systems +106e DFI, Inc +106f City Gate Development Ltd +1070 Daewoo Telecom Ltd +1071 Mitac +1072 GIT Co Ltd +1073 Yamaha Corporation + 0002 YGV615 [RPA3 3D-Graphics Controller] + 0003 YMF-740 + 0004 YMF-724 + 000C YMF-740C [DS-1L Audio Controller] + 000D YMF-724F [DS-1 Audio Controller] + 0010 YMF-744B [DS-1S Audio Controller] + 0012 YMF-754 [DS-1E Audio Controller] +1074 NexGen Microsystems + 4e78 82c500/1 +1075 Advanced Integrations Research +1076 Chaintech Computer Co. Ltd +1077 Q Logic + 1020 ISP1020 + 1022 ISP1022 + 1080 ISP1080 + 1240 ISP1240 + 2020 ISP2020A + 2100 ISP2100 +1078 Cyrix Corporation + 0000 5510 [Grappa] + 0001 PCI Master + 0002 5520 [Cognac] + 0100 5530 Legacy [Kahlua] + 0101 5530 SMI [Kahlua] + 0102 5530 IDE [Kahlua] + 0103 5530 Audio [Kahlua] + 0104 5530 Video [Kahlua] +1079 I-Bus +107a NetWorth +107b Gateway 2000 +107c LG Electronics [Lucky Goldstar Co. Ltd] +107d LeadTek Research Inc. + 0000 P86C850 +107e Interphase Corporation + 0001 ATM Interface Card + 0002 100 VG AnyLan Controller + 0008 155 Mbit ATM Controller +107f Data Technology Corporation + 0802 SL82C105 +1080 Contaq Microsystems + 0600 82C599 + c691 Cypress CY82C691 + c693 82c693 +1081 Supermac Technology + 0d47 Radius PCI to NuBUS Bridge +1082 EFA Corporation of America +1083 Forex Computer Corporation + 0001 FR710 +1084 Parador +1085 Tulip Computers Int.B.V. +1086 J. Bond Computer Systems +1087 Cache Computer +1088 Microcomputer Systems (M) Son +1089 Data General Corporation +108a Bit3 Computer Corp. + 0001 VME Bridge Model 617 + 0010 VME Bridge Model 618 + 3000 VME Bridge Model 2706 +108c Oakleigh Systems Inc. +108d Olicom + 0001 OC-3136/3137 + 0002 16/4 Token Ring + 0004 OC-3139/3140 RapidFire Token-Ring 16/4 + 0005 OC-3250 GoCard Token-Ring 16/4 + 0006 OC-3530 RapidFire Token-Ring 100 + 0007 OC-3141 RapidFire Token-Ring 16/4 + 0011 OC-2315 + 0012 OC-2325 + 0013 OC-2183/2185 + 0014 OC-2326 + 0021 OC-6151/6152 [RapidFire ATM 155] + 0022 ATM Adapter +108e Sun Microsystems Computer Corp. + 0001 EBUS + 1000 EBUS + 1001 Happy Meal + 5000 Simba Advanced PCI Bridge + 8000 PCI Bus Module + a000 Ultra IIi +108f Systemsoft +1090 Encore Computer Corporation +1091 Intergraph Corporation + 0020 3D graphics processor + 0021 3D graphics processor w/Texturing + 0040 3D graphics frame buffer + 0041 3D graphics frame buffer + 0060 Proprietary bus bridge + 00E4 Powerstorm 4D50T + 0720 Motion JPEG codec +1092 Diamond Multimedia Systems + 00a0 Speedstar Pro SE + 00a8 Speedstar 64 + 08d4 Supra 2260 Modem + 1092 Viper V330 + 6120 Maximum DVD + 8810 Stealth SE + 8811 Stealth 64/SE + 8880 Stealth + 8881 Stealth + 88b0 Stealth 64 + 88b1 Stealth 64 + 88c0 Stealth 64 + 88c1 Stealth 64 + 88d0 Stealth 64 + 88d1 Stealth 64 + 88f0 Stealth 64 + 88f1 Stealth 64 + 9999 DMD-I0928-1 "Monster sound" sound chip +1093 National Instruments + 0160 PCI-DIO-96 + 0162 PCI-MIO-16XE-50 + 1170 PCI-MIO-16XE-10 + 1180 PCI-MIO-16E-1 + 1190 PCI-MIO-16E-4 + 1330 PCI-6031E + 1350 PCI-6071E + 2a60 PCI-6023E + c801 PCI-GPIB +1094 First International Computers [FIC] +1095 CMD Technology Inc + 0640 PCI0640 + 0643 PCI0643 + 0646 PCI0646 + 0650 PBC0650A + 0647 PCI0647 + 0670 USB0670 + 0673 USB0673 +1096 Alacron +1097 Appian Technology +1098 Quantum Designs (H.K.) Ltd + 0001 QD-8500 + 0002 QD-8580 +1099 Samsung Electronics Co., Ltd +109a Packard Bell +109b Gemlight Computer Ltd. +109c Megachips Corporation +109d Zida Technologies Ltd. +109e Brooktree Corporation + 0350 Bt848 TV with DMA push + 0351 Bt849A Video capture + 036e Bt878 + 1851 1850 FlyVideo'98 - Video + 1851 1851 FlyVideo II + 1852 1852 FlyVideo'98 - Video (with FM Tuner) + 036f Bt879 + 1851 1850 FlyVideo'98 - Video + 1851 1851 FlyVideo II + 1852 1852 FlyVideo'98 - Video (with FM Tuner) + 0878 Bt878 + 2115 BtV 2115 Mediastream controller + 2125 BtV 2125 Mediastream controller + 2164 BtV 2164 + 2165 BtV 2165 + 8230 Bt8230 ATM Segment/Reassembly Ctrlr (SRC) + 8472 Bt8472 + 8474 Bt8474 +109f Trigem Computer Inc. +10a0 Meidensha Corporation +10a1 Juko Electronics Ind. Co. Ltd +10a2 Quantum Corporation +10a3 Everex Systems Inc +10a4 Globe Manufacturing Sales +10a5 Racal Interlan +10a6 Informtech Industrial Ltd. +10a7 Benchmarq Microelectronics +10a8 Sierra Semiconductor + 0000 STB Horizon 64 +10a9 Silicon Graphics + 0003 IOC3 + 0005 RAD Audio + 0009 Alteon Gigabit Ethernet +10aa ACC Microelectronics + 0000 ACCM 2188 +10ab Digicom +10ac Honeywell IAC +10ad Symphony Labs + 0001 W83769F + 0003 SL82C103 + 0005 SL82C105 + 0103 SL82c103 + 0105 SL82c105 + 0565 W83C553 +10ae Cornerstone Technology +10af Micro Computer Systems Inc +10b0 CardExpert Technology +10b1 Cabletron Systems Inc +10b2 Raytheon Company +10b3 Databook Inc + 3106 DB87144 + b106 DB87144 +10b4 STB Systems Inc + 1b1d Velocity 128 3D + 10b4 237e Velocity 4400 +10b5 PLX Technology, Inc. + 0001 i960 PCI bus interface + 1076 VScom 800 8 port serial adaptor + 1077 VScom 400 4 port serial adaptor + 9036 9036 + 9050 PCI <-> IOBus Bridge + 9060 9060 + 906d 9060SD + 125c 0640 Aries 16000P + 906e 9060ES + 9080 9080 + 10b5 9080 9080 [real subsystem ID not set] +10b6 Madge Networks + 0001 Smart 16/4 Ringnode + 0002 Smart 16/4 BM Mk2 Ringnode + 0003 Smart 16/4 Ringnode + 0e11 b0fd NC4621 4/16 Token-Ring Adapter + WOL + 10b6 0003 Smart 16/4 Ringnode Mk3 + 10b6 0007 Presto Mk2 + 0004 Smart 16/4 Ringnode (BM) + 0006 16/4 Cardbus Adapter + 0007 Presto + 1000 Collage 25 ATM adaptor + 1001 Collage 155 Server +10b7 3Com Corporation + 0001 3c985 1000BaseSX + 3390 Token Link Velocity + 3590 3c359 TokenLink Velocity XL + 5057 3c575 [Megahertz] 10/100 LAN CardBus + 5157 3c575 [Megahertz] 10/100 LAN CardBus + 5900 3c590 10BaseT [Vortex] + 5950 3c595 100BaseTX [Vortex] + 5951 3c595 100BaseT4 [Vortex] + 5952 3c595 100Base-MII [Vortex] + 8811 Token ring + 9000 3c900 10BaseT [Boomerang] + 9001 3c900 Combo [Boomerang] + 9004 3c900B-TPO [Etherlink XL TPO] + 9005 3c900B-Combo [Etherlink XL Combo] + 9006 3c900B-TPC [Etherlink XL TPC] + 900A 3c900B-FL [Etherlink XL FL] + 9050 3c905 100BaseTX [Boomerang] + 9051 3c905 100BaseT4 + 9055 3c905B 100BaseTX [Cyclone] + 9058 3c905B-Combo [Deluxe Etherlink XL 10/100] + 905A 3c905B-FX [Fast Etherlink XL FX 10/100] + 9200 3c905C-TX [Fast Etherlink] + 9800 3c980-TX [Fast Etherlink XL Server Adapter] +10b8 Standard Microsystems Corp [SMC] + 0005 83C170QF + 1055 e000 LANEPIC + 1055 e002 LANEPIC + 10b8 a011 EtherPower II 10/100 + 10b8 a014 EtherPower II 10/100 + 10b8 a015 EtherPower II 10/100 + 10b8 a016 EtherPower II 10/100 + 10b8 a017 EtherPower II 10/100 + 0006 LANEPIC + 1000 FDC 37c665 + 1001 FDC 37C922 + a011 83C170QF + b106 SMC34C90 +10b9 Acer Laboratories Inc. [ALi] + 1435 M1435 + 1445 M1445 + 1449 M1449 + 1451 M1451 + 1461 M1461 + 1489 M1489 + 1511 M1511 [Aladdin] + 1512 M1512 [Aladdin] + 1513 M1513 [Aladdin] + 1521 M1521 [Aladdin III] + 1523 M1523 + 1531 M1531 [Aladdin IV] + 1533 M1533 PCI to ISA Bridge [Aladdin IV] + 1541 M1541 + 1543 M1543 + 1621 M1621 + 3141 M3141 + 3143 M3143 + 3145 M3145 + 3147 M3147 + 3149 M3149 + 3151 M3151 + 3307 M3307 + 3309 M3309 + 5212 M4803 + 5215 MS4803 + 5217 M5217H + 5219 M5219 + 5225 M5225 + 5229 M5229 IDE + 5235 M5225 + 5237 M5237 USB + 5243 M5243 + 5247 M5247 + 7101 M7101 PMU +10ba Mitsubishi Electric Corp. + 0301 AccelGraphics AccelECLIPSE +10bb Dapha Electronics Corporation +10bc Advanced Logic Research +10bd Surecom Technology + 0e34 NE-34 +10be Tseng Labs International Co. +10bf Most Inc +10c0 Boca Research Inc. +10c1 ICM Co., Ltd. +10c2 Auspex Systems Inc. +10c3 Samsung Semiconductors, Inc. + 1100 Smartether100 SC1100 LAN Adapter (i82557B) +10c4 Award Software International Inc. +10c5 Xerox Corporation +10c6 Rambus Inc. +10c7 Media Vision +10c8 Neomagic Corporation + 0001 NM2070 [MagicGraph NM2070] + 0002 NM2090 [MagicGraph 128V] + 0003 NM2093 [MagicGraph 128ZV] + 0004 NM2160 [MagicGraph 128XD] + 0005 [MagicGraph 256AV] + 0006 [MagicGraph 256ZX] + 0083 [MagicGraph 128ZV Plus] + 8005 [MagicMedia 256AV] +10c9 Dataexpert Corporation +10ca Fujitsu Microelectr., Inc. +10cb Omron Corporation +10cc Mentor ARC Inc +10cd Advanced System Products, Inc + 1100 ASC1100 + 1200 ASC1200 [(abp940) Fast SCSI-II] + 1300 ABP940-U / ABP960-U + 2300 ABP940-UW +10ce Radius +10cf Citicorp TTI + 2001 mb86605 +10d0 Fujitsu Limited +10d1 FuturePlus Systems Corp. +10d2 Molex Incorporated +10d3 Jabil Circuit Inc +10d4 Hualon Microelectronics +10d5 Autologic Inc. +10d6 Cetia +10d7 BCM Advanced Research +10d8 Advanced Peripherals Labs +10d9 Macronix, Inc. [MXIC] + 0512 MX98713 + 0531 MX987x5 + 8625 MX86250 + 8888 MX86200 +10da Compaq IPG-Austin + 0508 TC4048 Token Ring 4/16 + 3390 Tl3c3x9 +10db Rohm LSI Systems, Inc. +10dc CERN/ECP/EDU + 0001 STAR/RD24 SCI-PCI (PMC) + 0002 TAR/RD24 SCI-PCI (PMC) [ATT 2C15-3 (FPGA) SCI bridge on PCI 5 Volt card] + 0021 HIPPI destination + 0022 HIPPI source + 10dc ATT2C15-3 FPGA +10dd Evans & Sutherland +10de nVidia Corporation + 0008 NV1 EDGE 3D + 0009 NV1 EDGE 3D + 0020 Riva TNT 128 + 1043 0200 V3400 TNT + 1092 0550 Viper V550 + 1092 0552 Viper V550 + 1102 1015 Graphics Blaster CT6710 + 1092 4804 Viper V550 + 1092 4808 Viper V550 + 1092 4810 Viper V550 + 1092 4812 Viper V550 + 1092 4815 Viper V550 + 1092 4820 Viper V550 with TV out + 1092 4822 Viper V550 + 1092 4904 Viper V550 + 1092 4914 Viper V550 + 1092 8225 Viper V550 + 0028 Riva TNT2 + 1043 0200 AGP-V3800 SGRAM + 1092 4804 Viper V770 + 1092 4a00 Viper V770 + 1092 4a02 Viper V770 Ultra + 1092 6a02 Viper V770 Ultra + 1092 7a02 Viper V770 Ultra + 1102 1020 3D Blaster RIVA TNT2 + 14af 5810 Maxi Gamer Xentor + 0029 Riva TNT2 Ultra + 1043 0200 AGP-V3800 Deluxe + 1102 1021 3D Blaster RIVA TNT2 Ultra + 14af 5820 Maxi Gamer Xentor 32 + 002c Vanta + 1043 0200 AGP-V3800 Combat SDRAM + 1092 6820 Viper V730 + 14af 5008 Maxi Gamer Phoenix 2 + 002d Riva TNT2 Model 64 + 1043 0200 AGP-V3800M + 00a0 Riva TNT2 + 14af 5810 Maxi Gamer Xentor +10df Emulex Corporation + 10df Light Pulse Fibre Channel Adapter + 1ae5 LP6000 Fibre Channel Host Adapter + f700 LP7000 Fibre Channel Host Adapter +10e0 Integrated Micro Solutions Inc. + 5026 IMS5026/27/28 + 5027 IMS5027 + 5028 IMS5028 + 8849 IMS8849 + 8853 IMS8853 + 9128 IMS9129 [Twin turbo 128] +10e1 Tekram Technology Co.,Ltd. + 0391 TRM-S1040 + 690c DC-690c + dc29 DC-290 +10e2 Aptix Corporation +10e3 Tundra Semiconductor Corp. + 0000 CA91C042 [Universe] + 0860 CA91C860 [QSpan] +10e4 Tandem Computers +10e5 Micro Industries Corporation +10e6 Gainbery Computer Products Inc. +10e7 Vadem +10e8 Applied Micro Circuits Corporation + 2011 Q-Motion Video Capture/Edit board + 4750 S5930 [Matchmaker] + 5920 S5920 + 8043 LANai4.x [Myrinet LANai interface chip] + 8062 S5933_PARASTATION + 807d S5933 [Matchmaker] + 8088 Kingsberg Spacetec Format Synchronizer + 8089 Kingsberg Spacetec Serial Output Board + 809c S5933_HEPC3 + 811a PCI-IEEE1355-DS-DE Interface + 8170 S5933 "Matchmaker" PCI Chipset Development Tool +10e9 Alps Electric Co., Ltd. +10ea Intergraphics Systems + 1680 IGA-1680 + 1682 IGA-1682 + 1683 IGA-1683 + 2000 CyberPro 2000 + 2010 CyberPro 2000A +10eb Artists Graphics + 0101 3GA + 8111 Twist3 Frame Grabber +10ec Realtek Semiconductor Co., Ltd. + 8029 RT8029(AS) + 10b8 2011 EZ-Card + 10ec 8029 RT8029(AS) + 1113 1208 EN1208 + 1186 0300 DE-528 + 1259 2400 AT-2400 + 8129 RT8129 + 8139 RT8139 + 1025 8920 ALN-325 + 1025 8921 ALN-325 + 10bd 0320 EP-320X-R + 10ec 8139 RT8139 + 1186 1320 SN5200 + 1259 2500 AT-2500TX + 1429 d010 ND010 + 1432 9130 EN-9130TX + 1436 8139 RT8139 + 146c 1439 FE-1439TX + 1489 6001 GF100TXRII + 1489 6002 GF100TXRA + 149c 139a LFE-8139ATX + 149c 8139 LFE-8139TX + 2646 0001 EtheRx + 8e2e 7000 KF-230TX + 8e2e 7100 KF-230TX/2 +10ed Ascii Corporation + 7310 V7310 +10ee Xilinx, Inc. +10ef Racore Computer Products, Inc. + 8154 M815x Token Ring Adapter +10f0 Peritek Corporation +10f1 Tyan Computer +10f2 Achme Computer, Inc. +10f3 Alaris, Inc. +10f4 S-MOS Systems, Inc. +10f5 NKK Corporation + a001 NDR4000 [NR4600 Bridge] +10f6 Creative Electronic Systems SA +10f7 Matsushita Electric Industrial Co., Ltd. +10f8 Altos India Ltd +10f9 PC Direct +10fa Truevision + 000c TARGA 1000 +10fb Thesys Gesellschaft für Mikroelektronik mbH +10fc I-O Data Device, Inc. +10fd Soyo Computer, Inc +10fe Fast Multimedia AG +10ff NCube +1100 Jazz Multimedia +1101 Initio Corporation + 9100 INI-9100/9100W + 9400 INI-940 + 9401 INI-950 + 9500 360P +1102 Creative Labs + 0002 SB Live! EMU10000 + 1102 0020 CT4850 SBLive! Value + 1102 0021 CT4620 SBLive! + 1102 002f SBLive! mainboard implementation + 1102 8022 CT4780 SBLive! Value + 1102 8024 CT4760 SBLive! + 1102 8026 CT4830 SBLive! Value + 1102 8027 CT4832 SBLive! Value + 1102 8031 CT4831 SBLive! Value + 1102 8040 CT4760 SBLive! + 7002 SB Live! + 1102 0020 Gameport Joystick +1103 Triones Technologies, Inc. + 0003 HPT343 + 0004 HPT366 +1104 RasterOps Corp. +1105 Sigma Designs, Inc. + 8300 REALmagic Hollywood Plus DVD Decoder +1106 VIA Technologies, Inc. + 0501 VT8501 + 0505 VT82C505 + 0561 VT82C561 + 0571 VT82C586 IDE [Apollo] + 0576 VT82C576 3V [Apollo Master] + 0585 VT82C585VP [Apollo VP1/VPX] + 0586 VT82C586/A/B PCI-to-ISA [Apollo VP] + 1106 0000 MVP3 ISA Bridge + 0595 VT82C595 [Apollo VP2] + 0596 VT82C596 ISA [Apollo PRO] + 0597 VT82C597 [Apollo VP3] + 0598 VT82C598 [Apollo MVP3] + 0680 VT82C680 [Apollo P6] + 0686 VT82C686 [Apollo Super] + 0691 VT82C691 [Apollo PRO] + 0693 VT82C693 [Apollo Pro Plus] + 0926 VT82C926 [Amazon] + 1000 VT82C570MV + 1106 VT82C570MV + 1571 VT82C416MV + 1595 VT82C595/97 [Apollo VP2/97] + 3038 VT82C586B USB + 1234 0925 MVP3 USB Controller + 3040 VT82C586B ACPI + 3043 VT86C100A [Rhine 10/100] + 1106 0100 VT86C100A + 1186 1400 DFE-530TX + 3057 VT82C686 [Apollo Super ACPI] + 3058 VT82C686 [Apollo Super AC97/Audio] + 3068 VT82C686 [Apollo Super AC97/Modem] + 5030 VT82C596 ACPI [Apollo PRO] + 6100 VT85C100A [Rhine II] + 8501 VT8501 + 8596 VT82C596 [Apollo PRO AGP] + 8597 VT82C597 [Apollo VP3 AGP] + 8598 VT82C598 [Apollo MVP3 AGP] + 8691 VT82C691 [Apollo Pro] +1107 Stratus Computers + 0576 VIA VT82C570MV [Apollo] (Wrong vendor ID!) +1108 Proteon, Inc. + 0100 p1690plus_AA + 0101 p1690plus_AB + 0105 P1690Plus + 0108 P1690Plus + 0138 P1690Plus + 0139 P1690Plus + 013C P1690Plus + 013D P1690Plus +1109 Cogent Data Technologies, Inc. + 1400 EM110TX [EX110TX] +110a Siemens Nixdorf AG + 0002 Pirahna 2-port + 0005 Tulip controller, power management, switch extender + 4942 FPGA I-Bus Tracer for MBD + 6120 SZB6120 +110b Chromatic Research Inc. + 0001 Mpact Media Processor +110c Mini-Max Technology, Inc. +110d Znyx Advanced Systems +110e CPU Technology +110f Ross Technology +1110 Powerhouse Systems + 6037 Firepower Powerized SMP I/O ASIC + 6073 Firepower Powerized SMP I/O ASIC +1111 Santa Cruz Operation +# DJ- Some people say that 0x1112 is Rockwell International ? +1112 RNS - Div. of Meret Communications Inc + 2200 FDDI Adapter + 2340 4 Port Fast Ethernet Adapter + 2400 ATM Adapter +1113 Accton Technology Corporation + 1211 SMC2-1211TX + 1217 EN-1217 Ethernet Adapter + 5105 10Mbps Network card + 9211 EN-1207D Fast Ethernet Adapter +1114 Atmel Corporation +1115 3D Labs +1116 Data Translation + 0022 DT3001 + 0023 DT3002 + 0024 DT3003 + 0028 DT3003-PGL + 0025 DT3004 + 0026 DT3005 + 0027 DT3001-PGL +1117 Datacube, Inc + 9500 Max-1C SVGA card + 9501 Max-1C image processing +1118 Berg Electronics +1119 ICP Vortex Computersysteme GmbH + 0000 GDT 6000/6020/6050 + 0001 GDT 6000b/6010 + 0002 GDT 6110/6510 + 0003 GDT 6120/6520 + 0004 GDT 6530 + 0005 GDT 6550 + 0006 GDT 6x17 + 0007 GDT 6x27 + 0008 GDT 6537 + 0009 GDT 5557 + 000a GDT 6x15 + 000b GDT 6x25 + 000c GDT 6535 + 000d GDT 6555 + 0100 GDT 6117RP/6517RP + 0101 GDT 6127RP/6527RP + 0102 GDT 6537RP + 0103 GDT 6557RP + 0104 GDT 6111RP/6511RP + 0105 GDT 6121RP/6521RP + 0110 GDT 6117RP1/6517RP1 + 0111 GDT 6127RP1/6527RP1 + 0112 GDT 6537RP1 + 0113 GDT 6557RP1 + 0114 GDT 6111RP1/6511RP1 + 0115 GDT 6121RP1/6521RP1 + 0118 GDT 6x18RD + 0119 GDT 6x28RD + 011A GDT 6x38RD + 011B GDT 6x58RD + 0120 GDT 6117RP2/6517RP2 + 0121 GDT 6127RP2/6527RP2 + 0122 GDT 6537RP2 + 0123 GDT 6557RP2 + 0124 GDT 6111RP2/6511RP2 + 0125 GDT 6121RP2/6521RP2 + 0168 GDT 7x18RN + 0169 GDT 7x28RN + 016A GDT 7x38RN + 016B GDT 7x58RN + 0210 GDT 6x19RD + 0211 GDT 6x29RD + 0260 GDT 7x19RN + 0261 GDT 7x29RN +111a Efficient Networks, Inc + 0000 155P-MF1 (FPGA) + 0002 155P-MF1 (ASIC) + 0003 ENI-25P ATM Adapter + 0005 ENI-25P ATM Adapter +111b Teledyne Electronic Systems +111c Tricord Systems Inc. + 0001 Powerbis Bridge +111d Integrated Device Tech + 0001 IDT77211 ATM Adapter +111e Eldec +111f Precision Digital Images + 4a47 Precision MX Video engine interface + 5243 Frame capture bus interface +1120 EMC Corporation +1121 Zilog +1122 Multi-tech Systems, Inc. +1123 Excellent Design, Inc. +1124 Leutron Vision AG +1125 Eurocore +1127 FORE Systems Inc + 0200 ForeRunner PCA-200 ATM + 0210 PCA-200PC + 0250 ATM + 0300 PCA-200E + 0310 ATM + 0400 ForeRunnerHE ATM Adapter +1129 Firmworks +112a Hermes Electronics Company, Ltd. +112b Linotype - Hell AG +112c Zenith Data Systems +112d Ravicad +112e Infomedia Microelectronics Inc. +112f Imaging Technology Inc + 0000 MVC IC-PCI + 0001 Video frame grabber/processor +1130 Computervision +1131 Philips Semiconductors + 7145 SAA7145 + 7146 SAA7146 +1132 Mitel Corp. +1133 Eicon Technology Corporation + 7901 EiconCard S90 + 7902 EiconCard S90 + 7911 EiconCard S91 + 7912 EiconCard S91 + 7941 EiconCard S94 + 7942 EiconCard S94 + b921 EiconCard P92 + b922 EiconCard P92 + e001 DIVA 20PRO + e002 DIVA 20 + e003 DIVA 20PRO_U + e004 DIVA 20_U + e010 DIVA Server BRI-2M + e014 DIVA Server PRO-30M +1134 Mercury Computer Systems + 0001 Raceway Bridge +1135 Fuji Xerox Co Ltd + 0001 Printer controller +1136 Momentum Data Systems +1137 Cisco Systems Inc +1138 Ziatech Corporation + 8905 8905 [STD 32 Bridge] +1139 Dynamic Pictures, Inc +113a FWB Inc +113b Network Computing Devices +113c Cyclone Microsystems, Inc. + 0000 PCI-9060 i960 Bridge + 0001 PCI-SDK [PCI i960 Evaluation Platform] + 0911 PCI-911 [PCI-based i960Jx Intelligent I/O Controller] + 0912 PCI-912 [i960CF-based Intelligent I/O Controller] + 0913 PCI-913 + 0914 PCI-914 [I/O Controller w/ secondary PCI bus] +113d Leading Edge Products Inc +113e Sanyo Electric Co - Computer Engineering Dept +113f Equinox Systems, Inc. + 0808 SST-64P Adapter + 1010 SST-128P Adapter + 80C0 SST-16P Adapter + 80C4 SST-16P Adapter + 80C8 SST-16P Adapter + 8888 SST-4P Adapter + 9090 SST-8P Adapter +1140 Intervoice Inc +1141 Crest Microsystem Inc +1142 Alliance Semiconductor Corporation + 3210 AP6410 + 6422 ProVideo 6422 + 6424 ProVideo 6424 + 6425 ProMotion AT25 + 643d ProMotion AT3D +1143 NetPower, Inc +1144 Cincinnati Milacron + 0001 Noservo controller +1145 Workbit Corporation +1146 Force Computers +1147 Interface Corp +1148 Syskonnect (Schneider & Koch) + 4000 FDDI Adapter + 0e11 b03b Netelligent 100 FDDI DAS Fibre SC + 0e11 b03c Netelligent 100 FDDI SAS Fibre SC + 0e11 b03d Netelligent 100 FDDI DAS UTP + 0e11 b03e Netelligent 100 FDDI SAS UTP + 0e11 b03f Netelligent 100 FDDI SAS Fibre MIC + 1148 5521 FDDI SK-5521 (SK-NET FDDI-UP) + 1148 5522 FDDI SK-5522 (SK-NET FDDI-UP DAS) + 1148 5541 FDDI SK-5541 (SK-NET FDDI-FP) + 1148 5543 FDDI SK-5543 (SK-NET FDDI-LP) + 1148 5544 FDDI SK-5544 (SK-NET FDDI-LP DAS) + 1148 5821 FDDI SK-5821 (SK-NET FDDI-UP64) + 1148 5822 FDDI SK-5822 (SK-NET FDDI-UP64 DAS) + 1148 5841 FDDI SK-5841 (SK-NET FDDI-FP64) + 1148 5843 FDDI SK-5843 (SK-NET FDDI-LP64) + 1148 5844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS) + 4200 Token ring adaptor + 4300 GE +1149 Win System Corporation +114a VMIC + 7587 VMIVME-7587 +114b Canopus Co., Ltd +114c Annabooks +114d IC Corporation +114e Nikon Systems Inc +114f Digi International + 0002 AccelePort EPC + 0003 RightSwitch SE-6 + 0004 AccelePort Xem + 0005 AccelePort Xr + 0006 AccelePort Xr,C/X + 0009 AccelePort Xr/J + 000a AccelePort EPC/J + 000C DataFirePRIme T1 (1-port) + 000D SyncPort 2-Port (x.25/FR) + 0011 AccelePort 8r EIA-232 (IBM) + 0012 AccelePort 8r EIA-422 + 0013 AccelePort Xr + 0014 AccelePort 8r EIA-422 + 0015 AccelePort Xem + 0016 AccelePort EPC/X + 0017 AccelePort C/X + 001A DataFirePRIme E1 (1-port) + 001B AccelePort C/X (IBM) + 001D DataFire RAS T1/E1/PRI + 0023 AccelePort RAS + 0024 DataFire RAS B4 ST/U + 0026 AccelePort 4r 920 + 0027 AccelePort Xr 920 + 0034 AccelePort 2r 920 + 0035 DataFire DSP T1/E1/PRI cPCI + 6001 Avanstar +1150 Thinking Machines Corp +1151 JAE Electronics Inc. +1152 Megatek +1153 Land Win Electronic Corp +1154 Melco Inc +1155 Pine Technology Ltd +1156 Periscope Engineering +1157 Avsys Corporation +1158 Voarx R & D Inc + 3011 Tokenet/vg 1001/10m anylan + 9050 Lanfleet/Truevalue + 9051 Lanfleet/Truevalue +1159 Mutech Corp + 0001 MV-1000 +115a Harlequin Ltd +115b Parallax Graphics +115c Photron Ltd. +115d Xircom + 0003 Cardbus Ethernet 10/100 + 1014 0181 10/100 EtherJet Cardbus Adapter + 1014 1181 10/100 EtherJet Cardbus Adapter + 115d 0181 Cardbus Ethernet 10/100 + 115d 1181 Cardbus Ethernet 10/100 + 8086 8181 EtherExpress PRO/100 Mobile CardBus 32 Adapter + 8086 9181 EtherExpress PRO/100 Mobile CardBus 32 Adapter + 0005 Cardbus Ethernet 10/100 + 1014 0182 10/100 EtherJet Cardbus Adapter + 1014 1182 10/100 EtherJet Cardbus Adapter + 115d 0182 Cardbus Ethernet 10/100 + 115d 1182 Cardbus Ethernet 10/100 + 0007 Cardbus Ethernet 10/100 + 1014 0182 10/100 EtherJet Cardbus Adapter + 1014 1182 10/100 EtherJet Cardbus Adapter + 115d 0182 Cardbus Ethernet 10/100 + 115d 1182 Cardbus Ethernet 10/100 + 000b Cardbus Ethernet 10/100 + 1014 0183 10/100 EtherJet Cardbus Adapter + 115d 0183 Cardbus Ethernet 10/100 + 000f Cardbus Ethernet 10/100 + 1014 0183 10/100 EtherJet Cardbus Adapter + 115d 0183 Cardbus Ethernet 10/100 + 0101 Cardbus 56k modem + 0103 Cardbus Ethernet + 56k Modem + 115d 1181 CBEM56G-100 Ethernet + 56k Modem + 8086 9181 PRO/100 LAN + Modem56 CardBus +115e Peer Protocols Inc +115f Maxtor Corporation +1160 Megasoft Inc +1161 PFU Limited +1162 OA Laboratory Co Ltd +1163 Rendition + 0001 Verite 1000 + 2000 Verite V2000/V2100/V2200 +1164 Advanced Peripherals Technologies +1165 Imagraph Corporation + 0001 Motion TPEG Recorder/Player with audio +1166 Relience Computer + 0008 CNB20HE + 0009 CNB20HE +1167 Mutoh Industries Inc +1168 Thine Electronics Inc +1169 Centre for Development of Advanced Computing +116a Polaris Communications + 6100 Bus/Tag Channel + 6800 Escon Channel + 7100 Bus/Tag Channel + 7800 Escon Channel +116b Connectware Inc +116c Intelligent Resources Integrated Systems +116d Martin-Marietta +116e Electronics for Imaging +116f Workstation Technology +1170 Inventec Corporation +1171 Loughborough Sound Images Plc +1172 Altera Corporation +1173 Adobe Systems, Inc +1174 Bridgeport Machines +1175 Mitron Computer Inc. +1176 SBE Incorporated +1177 Silicon Engineering +1178 Alfa, Inc. +1179 Toshiba America Info Systems + 0404 DVD Decoder card + 0406 Tecra Video Capture device + 0407 DVD Decoder card (Version 2) + 0601 601 + 0603 ToPIC95 PCI to CardBus Bridge for Notebooks + 060a ToPIC95 + 060f ToPIC97 + 0701 FIR Port +# This is apparently incorrect. Does anyone know the correct ID? +# 0701 Lucent DSP1645 [Mars] +117b L G Electronics, Inc. +117c Atto Technology +117d Becton & Dickinson +117e T/R Systems +117f Integrated Circuit Systems +1180 Ricoh Co Ltd + 0465 RL5c465 + 0466 RL5c466 + 0475 RL5c475 + 0476 RL5c476 II + 0477 RL5c477 + 0478 RL5c478 +1181 Telmatics International +1183 Fujikura Ltd +1184 Forks Inc +1185 Dataworld International Ltd +1186 D-Link System Inc + 0100 DC21041 +1187 Advanced Technology Laboratories, Inc. +1188 Shima Seiki Manufacturing Ltd. +1189 Matsushita Electronics Co Ltd +118a Hilevel Technology +118b Hypertec Pty Limited +118c Corollary, Inc + 0014 PCIB [C-bus II to PCI bus host bridge chip] +118d BitFlow Inc + 0001 Raptor-PCI framegrabber + 0012 Model 12 Road Runner Frame Grabber + 0014 Model 14 Road Runner Frame Grabber + 0024 Model 24 Road Runner Frame Grabber + 0044 Model 44 Road Runner Frame Grabber + 0112 Model 12 Road Runner Frame Grabber + 0114 Model 14 Road Runner Frame Grabber + 0124 Model 24 Road Runner Frame Grabber + 0144 Model 44 Road Runner Frame Grabber + 0212 Model 12 Road Runner Frame Grabber + 0214 Model 14 Road Runner Frame Grabber + 0224 Model 24 Road Runner Frame Grabber + 0244 Model 44 Road Runner Frame Grabber + 0312 Model 12 Road Runner Frame Grabber + 0314 Model 14 Road Runner Frame Grabber + 0324 Model 24 Road Runner Frame Grabber + 0344 Model 44 Road Runner Frame Grabber +118e Hermstedt GmbH +118f Green Logic +1190 Tripace +1191 Artop Electronic Corp + 0004 ATP8400 + 0005 ATP850UF + 8002 AEC6710 SCSI-2 Host Adapter + 8010 AEC6712UW SCSI + 8020 AEC6712U SCSI + 8030 AEC6712S SCSI + 8040 AEC6712D SCSI + 8050 AEC6712SUW SCSI +1192 Densan Company Ltd +1193 Zeitnet Inc. + 0001 1221 + 0002 1225 +1194 Toucan Technology +1195 Ratoc System Inc +1196 Hytec Electronics Ltd +1197 Gage Applied Sciences, Inc. +1198 Lambda Systems Inc +1199 Attachmate Corporation +119a Mind Share, Inc. +119b Omega Micro Inc. + 1221 82C092G +119c Information Technology Inst. +119d Bug, Inc. Sapporo Japan +119e Fujitsu Microelectronics Ltd. +119f Bull HN Information Systems +11a0 Convex Computer Corporation +11a1 Hamamatsu Photonics K.K. +11a2 Sierra Research and Technology +11a3 Deuretzbacher GmbH & Co. Eng. KG +11a4 Barco Graphics NV +11a5 Microunity Systems Eng. Inc +11a6 Pure Data Ltd. +11a7 Power Computing Corp. +11a8 Systech Corp. +11a9 InnoSys Inc. + 4240 AMCC S933Q Intelligent Serial Card +11aa Actel +11ab Galileo Technology Ltd. + 0146 GT-64010 + 4801 GT-48001 + f003 GT-64010 Primary Image Piranha Image Generator +11ac Canon Information Systems Research Aust. +11ad Lite-On Communications Inc + 0002 LNE100TX + 11ad 0002 LNE100TX + 11ad 0003 LNE100TX + 11ad f003 LNE100TX + 11ad ffff LNE100TX + 1385 f004 FA310TX +11ae Aztech System Ltd +11af Avid Technology Inc. +11b0 V3 Semiconductor Inc. + 0292 V292PBC [Am29030/40 Bridge] + 0960 V96xPBC + c960 V96DPC +11b1 Apricot Computers +11b2 Eastman Kodak +11b3 Barr Systems Inc. +11b4 Leitch Technology International +11b5 Radstone Technology Plc +11b6 United Video Corp +11b8 XPoint Technologies, Inc + 0001 Quad PeerMaster +11b9 Pathlight Technology Inc. + c0ed SSA Controller +11ba Videotron Corp +11bb Pyramid Technology +11bc Network Peripherals Inc + 0001 NP-PCI +11bd Pinnacle Systems Inc. +11be International Microcircuits Inc +11bf Astrodesign, Inc. +11c0 Hewlett Packard +11c1 Lucent Microelectronics + 0440 56k WinModem + 0001 0440 LT WinModem 56k Data+Fax+Voice+Dsvd + 1033 8015 LT WinModem 56k Data+Fax+Voice+Dsvd + 1033 804f LT WinModem 56k Data+Fax+Voice+Dsvd + 10cf 102c LB LT Modem V.90 56k + 10cf 104a BIBLO LT Modem 56k + 10cf 105f LB2 LT Modem V.90 56k + 1179 0001 Internal V.90 Modem + 11c1 0440 LT WinModem 56k Data+Fax+Voice+Dsvd + 122d 4101 MDP7800-U Modem + 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd + 13e0 0440 LT WinModem 56k Data+Fax+Voice+Dsvd + 13e0 0441 LT WinModem 56k Data+Fax+Voice+Dsvd + 13e0 f100 LT WinModem 56k Data+Fax+Voice+Dsvd + 13e0 f101 LT WinModem 56k Data+Fax+Voice+Dsvd + 144d 2101 LT56PV Modem + 149f 0440 LT WinModem 56k Data+Fax+Voice+Dsvd + 0441 56k WinModem + 1033 804d LT WinModem 56k Data+Fax + 1092 0440 Supra 56i + 1179 0001 Internal V.90 Modem + 11c1 0440 LT WinModem 56k Data+Fax + 11c1 0441 LT WinModem 56k Data+Fax + 122d 4100 MDP7800-U Modem + 13e0 0040 LT WinModem 56k Data+Fax + 13e0 0100 LT WinModem 56k Data+Fax + 13e0 0410 LT WinModem 56k Data+Fax + 13e0 0420 TelePath Internet 56k WinModem + 13e0 0443 LT WinModem 56k Data+Fax + 1416 9804 CommWave 56k Modem + 141d 0440 LT WinModem 56k Data+Fax + 144f 0441 Lucent 56k V.90 DF Modem + 1468 0441 Presario 56k V.90 DF Modem + 0442 56k WinModem + 0001 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 11c1 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 11c1 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 13e0 0412 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 13e0 0442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 13fc 2471 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 144d 2104 LT56PT Modem + 149f 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 1668 0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 0448 WinModem 56k + 13e0 0040 LT WinModem 56k Data+Fax+Voice+Dsvd + 0449 WinModem 56k + 0e11 b14d 56k V.90 Modem + 13e0 0020 LT WinModem 56k Data+Fax + 13e0 0041 TelePath Internet 56k WinModem + 144f 0449 Lucent 56k V.90 DFi Modem + 1468 0449 Presario 56k V.90 DFi Modem + 044A F-1156IV WinModem (V90, 56KFlex) + 13e0 0012 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 13e0 0042 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 144f 1005 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd + 0480 Venus WinModem (V90, 56KFlex) +11c2 Sand Microelectronics +11c4 Document Technologies, Inc +11c5 Shiva Corporation +11c6 Dainippon Screen Mfg. Co. Ltd +11c7 D.C.M. Data Systems +11c8 Dolphin Interconnect Solutions AS + 0658 PSB32 SCI-Adapter D31x + d665 PSB64 SCI-Adapter D32x + d667 PSB66 SCI-Adapter D33x +11c9 Magma + 0010 16-line serial port w/- DMA + 0011 4-line serial port w/- DMA +11ca LSI Systems, Inc +11cb Specialix Research Ltd. + 2000 PCI_9050 + 11cb 0200 SX + 11cb b008 I/O8+ + 4000 SUPI_1 + 8000 T225 +11cc Michels & Kleberhoff Computer GmbH +11cd HAL Computer Systems, Inc. +11ce Netaccess +11cf Pioneer Electronic Corporation +11d0 Lockheed Martin Federal Systems-Manassas +11d1 Auravision + 01f7 VxP524 +11d2 Intercom Inc. +11d3 Trancell Systems Inc +11d4 Analog Devices +11d5 Ikon Corporation + 0115 10115 + 0117 10117 +11d6 Tekelec Telecom +11d7 Trenton Technology, Inc. +11d8 Image Technologies Development +11d9 TEC Corporation +11da Novell +11db Sega Enterprises Ltd +11dc Questra Corporation +11dd Crosfield Electronics Limited +11de Zoran Corporation + 6057 ZR36057PQC Video cutting chipset + 1031 7efe DC10 Plus + 1031 fc00 MiroVIDEO DC50, Motion JPEG Capture/CODEC Board + 13ca 4231 JPEG/TV Card + 6120 ZR36120 + 1328 f001 Cinemaster C DVD Decoder +11df New Wave PDG +11e0 Cray Communications A/S +11e1 GEC Plessey Semi Inc. +11e2 Samsung Information Systems America +11e3 Quicklogic Corporation +11e4 Second Wave Inc +11e5 IIX Consulting +11e6 Mitsui-Zosen System Research +11e7 Toshiba America, Elec. Company +11e8 Digital Processing Systems Inc. +11e9 Highwater Designs Ltd. +11ea Elsag Bailey +11eb Formation Inc. +11ec Coreco Inc +11ed Mediamatics +11ee Dome Imaging Systems Inc +11ef Nicolet Technologies B.V. +11f0 Compu-Shack + 4231 FDDI + 4232 FASTline UTP Quattro + 4233 FASTline FO + 4234 FASTline UTP + 4235 FASTline-II UTP + 4236 FASTline-II FO + 4731 GIGAline +11f1 Symbios Logic Inc +11f2 Picture Tel Japan K.K. +11f3 Keithley Metrabyte +11f4 Kinetic Systems Corporation + 2915 CAMAC controller +11f5 Computing Devices International +11f6 Compex + 0112 ENet100VG4 + 1401 ReadyLink 2000 + 2011 RL100-ATX 10/100 + 2201 ReadyLink 100TX (Winbond W89C840) + 9881 RL100TX +11f7 Scientific Atlanta +11f8 PMC-Sierra Inc. + 7375 PM7375 [LASAR-155 ATM SAR] +11f9 I-Cube Inc +11fa Kasan Electronics Company, Ltd. +11fb Datel Inc +11fc Silicon Magic +11fd High Street Consultants +11fe Comtrol Corporation + 0001 RocketPort 8 Oct + 0002 RocketPort 8 Intf + 0003 RocketPort 16 Intf + 0004 RocketPort 32 Intf + 0005 RocketPort Octacable + 0006 RocketPort 8J + 0008 RocketPort 8-port + 0009 RocketPort 16-port + 000A RocketPort Plus Quadcable + 000B RocketPort Plus Octacable + 000C RocketPort 8-port Modem +11ff Scion Corporation +1200 CSS Corporation +1201 Vista Controls Corp +1202 Network General Corp. +1203 Bayer Corporation, Agfa Division +1204 Lattice Semiconductor Corporation +1205 Array Corporation +1206 Amdahl Corporation +1208 Parsytec GmbH + 4853 HS-Link Device +1209 SCI Systems Inc +120a Synaptel +120b Adaptive Solutions +120c Technical Corp. +120d Compression Labs, Inc. +120e Cyclades Corporation + 0100 Cyclom_Y below first megabyte + 0101 Cyclom_Y above first megabyte + 0102 Cyclom_4Y below first megabyte + 0103 Cyclom_4Y above first megabyte + 0104 Cyclom_8Y below first megabyte + 0105 Cyclom_8Y above first megabyte + 0200 Cyclom_Z below first megabyte + 0201 Cyclom_Z above first megabyte +120f Essential Communications + 0001 Roadrunner serial HIPPI +1210 Hyperparallel Technologies +1211 Braintech Inc +1212 Kingston Technology Corp. +1213 Applied Intelligent Systems, Inc. +1214 Performance Technologies, Inc. +1215 Interware Co., Ltd +1216 Purup Prepress A/S +1217 O2 Micro, Inc. + 6729 6729 + 673a 6730 + 6832 6832 + 6836 6836 +1218 Hybricon Corp. +1219 First Virtual Corporation +121a 3Dfx Interactive, Inc. + 0001 Voodoo + 0002 Voodoo 2 + 0003 Voodoo Banshee + 1092 0003 Monster Fusion + 1092 4000 Monster Fusion + 1092 4002 Monster Fusion + 1092 4801 Monster Fusion AGP + 1092 4803 Monster Fusion AGP + 1092 8030 Monster Fusion + 1092 8035 Monster Fusion AGP + 121a 0001 Voodoo Banshee AGP + 121a 0003 Voodoo Banshee AGP SGRAM + 121a 0004 Voodoo Banshee + 3030 3030 Skywell Magic TwinPower + 0005 Voodoo 3 + 121a 0004 Voodoo3 AGP + 121a 0030 Voodoo3 AGP + 121a 0031 Voodoo3 AGP + 121a 0034 Voodoo3 AGP + 121a 0036 Voodoo3 + 121a 0037 Voodoo3 AGP + 121a 0038 Voodoo3 AGP + 121a 003a Voodoo3 AGP + 121a 0044 Voodoo3 + 121a 004b Velocity 100 + 121a 004c Velocity 200 + 121a 004d Voodoo3 AGP + 121a 004e Voodoo3 AGP + 121a 0051 Voodoo3 AGP + 121a 0052 Voodoo3 AGP + 121a 0060 Voodoo3 3500 TV (NTSC) + 121a 0061 Voodoo3 3500 TV (PAL) + 121a 0062 Voodoo3 3500 TV (SECAM) +121b Advanced Telecommunications Modules +121c Nippon Texaco., Ltd +121d Lippert Automationstechnik GmbH +121e CSPI +121f Arcus Technology, Inc. +1220 Ariel Corporation + 1220 AMCC 5933 TMS320C80 DSP/Imaging board +1221 Contec Co., Ltd +1222 Ancor Communications, Inc. +1223 Heurikon/Computer Products +1224 Interactive Images +1225 Power I/O, Inc. +1227 Tech-Source +1228 Norsk Elektro Optikk A/S +1229 Data Kinesis Inc. +122a Integrated Telecom +122b LG Industrial Systems Co., Ltd +122c Sican GmbH +122d Aztech System Ltd + 1206 368DSP + 50dc 3328 Audio + 80da 3328 Audio +122e Xyratex +122f Andrew Corporation +1230 Fishcamp Engineering +1231 Woodward McCoach, Inc. +1232 GPT Limited +1233 Bus-Tech, Inc. +1234 Technical Corp. +1235 Risq Modular Systems, Inc. +1236 Sigma Designs Corporation + 0000 RealMagic64/GX + 6401 REALmagic 64/GX (SD 6425) +1237 Alta Technology Corporation +1238 Adtran +1239 3DO Company +123a Visicom Laboratories, Inc. +123b Seeq Technology, Inc. +123c Century Systems, Inc. +123d Engineering Design Team, Inc. + 0000 EasyConnect 8/32 + 0002 EasyConnect 8/64 + 0003 EasyIO +123e Simutech, Inc. +123f C-Cube Microsystems + 00e4 MPEG + 8888 Cinemaster C 3.0 DVD Decoder +1240 Marathon Technologies Corp. +1241 DSC Communications +1243 Delphax +1244 AVM Audiovisuelles MKTG & Computer System GmbH + 0700 B1 ISDN + 0a00 A1 ISDN [Fritz] +1245 A.P.D., S.A. +1246 Dipix Technologies, Inc. +1247 Xylon Research, Inc. +1248 Central Data Corporation +1249 Samsung Electronics Co., Ltd. +124a AEG Electrocom GmbH +124b SBS/Greenspring Modular I/O +124c Solitron Technologies, Inc. +124d Stallion Technologies, Inc. + 0000 EasyConnection 8/32 + 0002 EasyConnection 8/64 + 0003 EasyIO +124e Cylink +124f Infotrend Technology, Inc. + 0041 IFT-2000 Series RAID Controller +1250 Hitachi Microcomputer System Ltd +1251 VLSI Solutions Oy +1253 Guzik Technical Enterprises +1254 Linear Systems Ltd. +1255 Optibase Ltd + 1110 MPEG Forge + 1210 MPEG Fusion + 2110 VideoPlex + 2120 VideoPlex CC + 2130 VideoQuest +1256 Perceptive Solutions, Inc. +1257 Vertex Networks, Inc. +1258 Gilbarco, Inc. +1259 Allied Telesyn International + 2560 AT-2560 Fast Ethernet Adapter (i82557B) +125a ABB Power Systems +125b Asix Electronics Corporation +125c Aurora Technologies, Inc. +125d ESS Technology + 0000 ES336H Fax Modem (Early Model) + 1948 Solo? + 1968 ES1968 Maestro 2 + 1969 ES1969 Solo-1 Audiodrive + 1978 ES1978 Maestro Audiodrive + 2808 ES336H Fax Modem (Later Model) + 2898 ES2898 Modem +125e Specialvideo Engineering SRL +125f Concurrent Technologies, Inc. +1260 Harris Semiconductor + 8130 HMP8130 NTSC/PAL Video Decoder + 8131 HMP8131 NTSC/PAL Video Decoder +1261 Matsushita-Kotobuki Electronics Industries, Ltd. +1262 ES Computer Company, Ltd. +1263 Sonic Solutions +1264 Aval Nagasaki Corporation +1265 Casio Computer Co., Ltd. +1266 Microdyne Corporation + 0001 NE10/100 Adapter (i82557B) + 1910 NE2000Plus (RT8029) Ethernet Adapter +1267 S. A. Telecommunications + 5352 PCR2101 + 5a4b Telsat Turbo +1268 Tektronix +1269 Thomson-CSF/TTM +126a Lexmark International, Inc. +126b Adax, Inc. +126c Northern Telecom +126d Splash Technology, Inc. +126e Sumitomo Metal Industries, Ltd. +126f Silicon Motion, Inc. + 0910 SM910 +1270 Olympus Optical Co., Ltd. +1271 GW Instruments +1272 Telematics International +1273 Hughes Network Systems + 0002 DirecPC +1274 Ensoniq + 1371 ES1371 [AudioPCI-97] + 5000 ES1370 [AudioPCI] +1275 Network Appliance Corporation +1276 Switched Network Technologies, Inc. +1277 Comstream +1278 Transtech Parallel Systems Ltd. +1279 Transmeta Corporation +127a Rockwell International + 1002 HCF 56k V90 FaxModem + 1003 HCF 56k V90 FaxModem + 1004 HCF 56k V90 FaxModem + 1005 HCF 56k V90 FaxModem + 122d 4008 MDP3858SP-A SVD Modem + 127a 1005 PCI56RVP Modem + 13df 1005 PCI56RVP Modem + 1436 1005 WS-5614PS3G + 8234 RapidFire 616X ATM155 Adapter +127b Pixera Corporation +127c Crosspoint Solutions, Inc. +127d Vela Research +127e Winnov, L.P. +127f Fujifilm +1280 Photoscript Group Ltd. +1281 Yokogawa Electric Corporation +1282 Davicom Semiconductor, Inc. +1283 Integrated Technology Express, Inc. + 673a IT8330G + 8330 IT8330G + e886 IT8330G +1284 Sahara Networks, Inc. +1285 Platform Technologies, Inc. + 0100 PT-201C-O-P AGOGO-XP sound chip +1286 Mazet GmbH +1287 M-Pact, Inc. + 001e LS220D DVD Decoder + 001f LS220C DVD Decoder +1288 Timestep Corporation +1289 AVC Technology, Inc. +128a Asante Technologies, Inc. +128b Transwitch Corporation +128c Retix Corporation +128d G2 Networks, Inc. + 0021 ATM155 Adapter +128e Hoontech Corporation/Samho Multi Tech Ltd. + 0008 ST128 WSS/SB + 0009 ST128 SAM9407 + 000a ST128 Game Port + 000b ST128 MPU Port + 000c ST128 Ctrl Port +128f Tateno Dennou, Inc. +1290 Sord Computer Corporation +1291 NCS Computer Italia +1292 Tritech Microelectronics Inc +1293 Media Reality Technology +1294 Rhetorex, Inc. +1295 Imagenation Corporation +1296 Kofax Image Products +1297 Holco Enterprise Co, Ltd/Shuttle Computer +1298 Spellcaster Telecommunications Inc. +1299 Knowledge Technology Lab. +129a VMetro, inc. +129b Image Access +129c Jaycor +129d Compcore Multimedia, Inc. +129e Victor Company of Japan, Ltd. +129f OEC Medical Systems, Inc. +12a0 Allen-Bradley Company +12a1 Simpact Associates, Inc. +12a2 Newgen Systems Corporation +12a3 Lucent Technologies +12a4 NTT Electronics Technology Company +12a5 Vision Dynamics Ltd. +12a6 Scalable Networks, Inc. +12a7 AMO GmbH +12a8 News Datacom +12a9 Xiotech Corporation +12aa SDL Communications, Inc. +12ab Yuan Yuan Enterprise Co., Ltd. +12ac Measurex Corporation +12ad Multidata GmbH +12ae Alteon Networks Inc. + 0001 AceNIC Gigabit Ethernet +12af TDK USA Corp +12b0 Jorge Scientific Corp +12b1 GammaLink +12b2 General Signal Networks +12b3 Inter-Face Co Ltd +12b4 FutureTel Inc +12b5 Granite Systems Inc. +12b6 Natural Microsystems +12b7 Cognex Modular Vision Systems Div. - Acumen Inc. +12b8 Korg +12b9 US Robotics/3Com + 1006 WinModem +12ba PMC Sierra +12bb Nippon Unisoft Corporation +12bc Array Microsystems +12bd Computerm Corp. +12be Anchor Chips Inc. + 3041 AN3041Q CO-MEM + 3042 AN3042Q CO-MEM Lite +12bf Fujifilm Microdevices +12c0 Infimed +12c1 GMM Research Corp +12c2 Mentec Limited +12c3 Holtek Microelectronics Inc +12c4 Connect Tech Inc +12c5 Picture Elements Incorporated + 0081 PCIVST [Grayscale Thresholding Engine] +12c6 Mitani Corporation +12c7 Dialogic Corp +12c8 G Force Co, Ltd +12c9 Gigi Operations +12ca Integrated Computing Engines +12cb Antex Electronics Corporation +12cc Pluto Technologies International +12cd Aims Lab +12ce Netspeed Inc. +12cf Prophet Systems, Inc. +12d0 GDE Systems, Inc. +12d1 PSITech +12d2 NVidia / SGS Thomson (Joint Venture) + 0008 NV1 + 0009 DAC64 + 0018 Riva128 + 107b 8030 STB Velocity 128 + 1092 0350 Viper V330 + 1092 1092 Viper V330 + 10b4 1b1b STB Velocity 128 + 10b4 1b20 STB Velocity 128 + 10b4 1b21 STB Velocity 128 + 10b4 1b22 STB Velocity 128 AGP, NTSC TV-Out + 10b4 1b23 STB Velocity 128 AGP, PAL TV-Out + 10b4 1b27 STB Velocity 128 DVD + 10b4 222a STB Velocity 128 AGP + 10b4 2230 STB Velocity 128 + 10b4 2235 STB Velocity 128 AGP + 0019 Riva128ZX + 0020 TNT + 0028 TNT2 + 0029 UTNT2 + 002C VTNT2 + 00A0 ITNT2 +12d3 Vingmed Sound A/S +12d4 DGM&S +12d5 Equator Technologies +12d6 Analogic Corp +12d7 Biotronic SRL +12d8 Pericom Semiconductor +12d9 Aculab PLC +12da True Time Inc. +12db Annapolis Micro Systems, Inc +12dc Symicron Computer Communication Ltd. +12dd Management Graphics +12de Rainbow Technologies +12df SBS Technologies Inc +12e0 Chase Research + 0010 ST16C654 Quad UART + 0020 ST16C654 Quad UART + 0030 ST16C654 Quad UART +12e1 Nintendo Co, Ltd +12e2 Datum Inc. Bancomm-Timing Division +12e3 Imation Corp - Medical Imaging Systems +12e4 Brooktrout Technology Inc +12e5 Apex Semiconductor Inc +12e6 Cirel Systems +12e7 Sunsgroup Corporation +12e8 Crisc Corp +12e9 GE Spacenet +12ea Zuken +12eb Aureal Semiconductor + 0001 Vortex 1 + 0002 Vortex 2 +12ec 3A International, Inc. +12ed Optivision Inc. +12ee Orange Micro +12ef Vienna Systems +12f0 Pentek +12f1 Sorenson Vision Inc +12f2 Gammagraphx, Inc. +12f3 Radstone Technology +12f4 Megatel +12f5 Forks +12f6 Dawson France +12f7 Cognex +12f8 Electronic Design GmbH + 0002 VideoMaker +12f9 Four Fold Ltd +12fb Spectrum Signal Processing +12fc Capital Equipment Corp +12fd I2S +12fe ESD Electronic System Design GmbH +12ff Lexicon +1300 Harman International Industries Inc +1302 Computer Sciences Corp +1303 Innovative Integration +1304 Juniper Networks +1305 Netphone, Inc +1306 Duet Technologies +1307 Computer Boards + 0001 PCI-DAS1602/16 + 000C PCI-PDISO8 + 000D PCI-PDISO16 + 000B PCI-DIO48H + 000F PCI-DAS1200 + 0010 PCI-DAS1602/12 + 0014 PCI-DIO24H + 0015 PCI-DIO24H/CTR3 + 0016 PCI-DIO48H/CTR15 + 0017 PCI-DIO96H + 0018 PCI-CTR05 + 0019 PCI-DAS1200/JR + 001A PCI-DAS1001 + 001B PCI-DAS1002 + 001C PCI-DAS1602JR/16 + 001D PCI-DAS6402/16 + 001E PCI-DAS6402/12 + 001F PCI-DAS16/M1 + 0020 PCI-DDA02/12 + 0021 PCI-DDA04/12 + 0022 PCI-DDA08/12 + 0023 PCI-DDA02/16 + 0024 PCI-DDA04/16 + 0025 PCI-DDA08/16 + 0026 PCI-DAC04/12-HS + 0027 PCI-DAC04/16-HS + 0028 PCI-DIO24 + 0029 PCI-DAS08 + 002C PCI-INT32 + 0033 PCI-DUAL-AC5 + 0034 PCI-DAS-TC + 0035 PCI-DAS64/M1/16 + 0036 PCI-DAS64/M2/16 + 0037 PCI-DAS64/M3/16 + 004C PCI-DAS1000 +1308 Jato Technologies Inc. + 0001 NetCelerator Adapter +1309 AB Semiconductor Ltd +130a Mitsubishi Electric Microcomputer +130b Colorgraphic Communications Corp +130c Ambex Technologies, Inc +130d Accelerix Inc +130e Yamatake-Honeywell Co. Ltd +130f Advanet Inc +1310 Gespac +1311 Videoserver, Inc +1312 Acuity Imaging, Inc +1313 Yaskawa Electric Co. +1316 Teradyne Inc +1317 Bridgecom, Inc +1318 Packet Engines Inc. +1319 Fortemedia, Inc + 0801 Xwave QS3000A [FM801] + 0802 Xwave QS3000A [FM801 game port] +131a Finisar Corp. +131c Nippon Electro-Sensory Devices Corp +131d Sysmic, Inc. +131e Xinex Networks Inc +131f Siig Inc + 1010 Duet 1S(16550)+1P + 1011 Duet 1S(16650)+1P + 1012 Duet 1S(16850)+1P + 1020 CyberParallel (1-port) + 1021 CyberParallel (2-port) + 1034 Trio 2S(16550)+1P + 1035 Trio 2S(16650)+1P + 1036 Trio 2S(16850)+1P + 2010 Duet 1S(16550)+1P + 2011 Duet 1S(16650)+1P + 2012 Duet 1S(16850)+1P + 2020 CyberParallel (1-port) + 2021 CyberParallel (2-port) + 2040 Trio 1S(16550)+2P + 2041 Trio 1S(16650)+2P + 2042 Trio 1S(16850)+2P + 2060 Trio 2S(16550)+1P + 2061 Trio 2S(16650)+1P + 2062 Trio 2S(16850)+1P +1320 Crypto AG +1321 Arcobel Graphics BV +1322 MTT Co., Ltd +1323 Dome Inc +1324 Sphere Communications +1325 Salix Technologies, Inc +1326 Seachange international +1327 Voss scientific +1328 quadrant international +1329 Productivity Enhancement +132a Microcom Inc. +132b Broadband Technologies +132c Micrel Inc +132d Integrated Silicon Solution, Inc. +1330 MMC Networks +1331 Radisys Corp. +1332 Micro Memory +1334 Redcreek Communications, Inc +1335 Videomail, Inc +1337 Third Planet Publishing +1338 BT Electronics +133a Vtel Corp +133b Softcom Microsystems +133c Holontech Corp +133d SS Technologies +133e Virtual Computer Corp +133f SCM Microsystems +1340 Atalla Corp +1341 Kyoto Microcomputer Co +1342 Promax Systems Inc +1343 Phylon Communications Inc +1344 Crucial Technology +1345 Arescom Inc +1347 Odetics +1349 Sumitomo Electric Industries, Ltd. +134a DTC Technology Corp. + 0001 Domex 536 +134b ARK Research Corp. +134c Chori Joho System Co. Ltd +134d PCTel Inc +134e CSTI +134f Algo System Co Ltd +1350 Systec Co. Ltd +1351 Sonix Inc +1353 Dassault A.T. +1354 Dwave System Inc +1355 Kratos Analytical Ltd +1356 The Logical Co +1359 Prisa Networks +135a Brain Boxes +135b Giganet Inc +135c Quatech Inc +135d ABB Network Partner AB +135e Sealevel Systems Inc + 7101 Single Port RS-232/422/485/530 + 7201 Dual Port RS-232/422/485 Interface + 7202 Dual Port RS-232 Interface + 7401 Four Port RS-232 Interface + 7402 Four Port RS-422/485 Interface + 7801 Eight Port RS-232 Interface + 8001 8001 Digital I/O Adapter +1360 Meinberg Funkuhren +1361 Soliton Systems K.K. +1362 Fujifacom Corporation +1363 Phoenix Technology Ltd +1364 ATM Communications Inc +1365 Hypercope GmbH +1366 Teijin Seiki Co. Ltd +1367 Hitachi Zosen Corporation +1368 Skyware Corporation +1369 Digigram +136a High Soft Tech +136b Kawasaki Steel Corporation +136c Adtek System Science Co Ltd +136d Gigalabs Inc +136f Applied Magic Inc +1370 ATL Products +1371 CNet Technology Inc +1373 Silicon Vision Inc +1374 Silicom Ltd +1375 Argosystems Inc +1376 LMC +1377 Electronic Equipment Production & Distribution GmbH +1378 Telemann Co. Ltd +1379 Asahi Kasei Microsystems Co Ltd +137a Mark of the Unicorn Inc +137b PPT Vision +137c Iwatsu Electric Co Ltd +137d Dynachip Corporation +137e Patriot Scientific Corporation +137f Japan Satellite Systems Inc +1380 Sanritz Automation Co Ltd +1381 Brains Co. Ltd +1382 Marian - Electronic & Software +1383 Controlnet Inc +1384 Reality Simulation Systems Inc +1385 Netgear + 620a GA620 +1386 Video Domain Technologies +1387 Systran Corp +1388 Hitachi Information Technology Co Ltd +1389 Applicom International + 0001 PCI1500PFB [Intelligent fieldbus adaptor] +138a Fusion Micromedia Corp +138b Tokimec Inc +138c Silicon Reality +138d Future Techno Designs pte Ltd +138e Basler GmbH +138f Patapsco Designs Inc +1390 Concept Development Inc +1391 Development Concepts Inc +1392 Medialight Inc +1393 Moxa Technologies Co Ltd +1394 Level One Communications +1395 Ambicom Inc +1396 Cipher Systems Inc +1397 Cologne Chip Designs GmbH + 2bd0 ISDN network controller +1398 Clarion co. Ltd +1399 Rios systems Co Ltd +139a Alacritech Inc +139b Mediasonic Multimedia Systems Ltd +139c Quantum 3d Inc +139d EPL limited +139e Media4 +139f Aethra s.r.l. +13a0 Crystal Group Inc +13a1 Kawasaki Heavy Industries Ltd +13a2 Ositech Communications Inc +13a3 Hi-Fn +13a4 Rascom Inc +13a5 Audio Digital Imaging Inc +13a6 Videonics Inc +13a7 Teles AG +13a8 Exar Corp. +13a9 Siemens Medical Systems, Ultrasound Group +13aa Broadband Networks Inc +13ab Arcom Control Systems Ltd +13ac Motion Media Technology Ltd +13ad Nexus Inc +13ae ALD Technology Ltd +13af T.Sqware +13b0 Maxspeed Corp +13b1 Tamura corporation +13b2 Techno Chips Co. Ltd +13b3 Lanart Corporation +13b4 Wellbean Co Inc +13b5 ARM +13b6 Dlog GmbH +13b7 Logic Devices Inc +13b8 Nokia Telecommunications oy +13b9 Elecom Co Ltd +13ba Oxford Instruments +13bb Sanyo Technosound Co Ltd +13bc Bitran Corporation +13bd Sharp corporation +13be Miroku Jyoho Service Co. Ltd +13bf Sharewave Inc +13c0 Microgate Corporation + 0010 SyncLink WAN Adapter +13c1 3ware Inc +13c2 Technotrend Systemtechnik GmbH +13c3 Janz Computer AG +13c4 Phase Metrics +13c5 Alphi Technology Corp +13c6 Condor Engineering Inc +13c7 Blue Chip Technology Ltd +13c8 Apptech Inc +13c9 Eaton Corporation +13ca Iomega Corporation +13cb Yano Electric Co Ltd +13cc Metheus Corporation +13cd Compatible Systems Corporation +13ce Cocom A/S +13cf Studio Audio & Video Ltd +13d0 Techsan Electronics Co Ltd +13d1 Abocom Systems Inc +13d2 Shark Multimedia Inc +13d3 IMC Networks +13d4 Graphics Microsystems Inc +13d5 Media 100 Inc +13d6 K.I. Technology Co Ltd +13d7 Toshiba Engineering Corporation +13d8 Phobos corporation +13d9 Apex PC Solutions Inc +13da Intresource Systems pte Ltd +13db Janich & Klass Computertechnik GmbH +13dc Netboost Corporation +13dd Multimedia Bundle Inc +13de ABB Robotics Products AB +13df E-Tech Inc + 0001 PCI56RVP Modem +13e0 GVC Corporation +13e1 Silicom Multimedia Systems Inc +13e2 Dynamics Research Corporation +13e3 Nest Inc +13e4 Calculex Inc +13e5 Telesoft Design Ltd +13e6 Argosy research Inc +13e7 NAC Incorporated +13e8 Chip Express Corporation +13e9 Chip Express Corporation +13ea Dallas Semiconductor +13eb Hauppauge Computer Works Inc +13ec Zydacron Inc +13ed Raytheion E-Systems +13ee Hayes Microcomputer Products Inc +13ef Coppercom Inc +13f0 Sundance technology Inc +13f1 Oce' - Technologies B.V. +13f2 Ford Microelectronics Inc +13f3 Mcdata Corporation +13f4 Troika Design Inc +13f5 Kansai Electric Co. Ltd +13f6 C-Media Electronics Inc + 0100 CM8338A + 0101 CM8338B + 0111 CM8738 +13f7 Wildfire Communications +13f8 Ad Lib Multimedia Inc +13f9 NTT Advanced Technology Corp. +13fa Pentland Systems Ltd +13fb Aydin Corp +13fc Computer Peripherals International +13fd Micro Science Inc +13fe Advantech Co. Ltd +13ff Silicon Spice Inc +1400 Artx Inc +1401 CR-Systems A/S +1402 Meilhaus Electronic GmbH +1403 Ascor Inc +1404 Fundamental Software Inc +1405 Excalibur Systems Inc +1406 Oce' Printing Systems GmbH +1407 Lava Computer mfg Inc + 8000 Lava Parallel + 8002 Lava Dual Parallel port A + 8003 Lava Dual Parallel port B + 8800 BOCA Research IOPPAR +1408 Aloka Co. Ltd +1409 Timedia Technology Co Ltd +140a DSP Research Inc +140b Ramix Inc +140c Elmic Systems Inc +140d Matsushita Electric Works Ltd +140e Goepel Electronic GmbH +140f Salient Systems Corp +1410 Midas lab Inc +1411 Ikos Systems Inc +1412 IC Ensemble Inc +1413 Addonics +1414 Microsoft Corporation +1415 Oxford Semiconductor Ltd +1416 Multiwave Innovation pte Ltd +1417 Convergenet Technologies Inc +1418 Kyushu electronics systems Inc +1419 Excel Switching Corp +141a Apache Micro Peripherals Inc +141b Zoom Telephonics Inc +141d Digitan Systems Inc +141e Fanuc Ltd +141f Visiontech Ltd +1420 Psion Dacom plc +1421 Ads Technologies Inc +1422 Ygrec Systems Co Ltd +1423 Custom Technology Corp. +1424 Videoserver Connections +1425 ASIC Designers Inc +1426 Storage Technology Corp. +1427 Better On-Line Solutions +1428 Edec Co Ltd +1429 Unex Technology Corp. +142a Kingmax Technology Inc +142b Radiolan +142c Minton Optic Industry Co Ltd +142d Pix stream Inc +142e Vitec Multimedia +142f Radicom Research Inc +1430 ITT Aerospace/Communications Division +1431 Gilat Satellite Networks +1432 Edimax Computer Co. +1433 Eltec Elektronik GmbH +1435 Real Time Devices US Inc. +1436 CIS Technology Inc +1437 Nissin Inc Co +1438 Atmel-dream +1439 Outsource Engineering & Mfg. Inc +143a Stargate Solutions Inc +143b Canon Research Center, America +143c Amlogic Inc +143d Tamarack Microelectronics Inc +143e Jones Futurex Inc +143f Lightwell Co Ltd - Zax Division +1440 ALGOL Corp. +1441 AGIE Ltd +1442 Phoenix Contact GmbH & Co. +1443 Unibrain S.A. +1444 TRW +1445 Logical DO Ltd +1446 Graphin Co Ltd +1447 AIM GmBH +1448 Alesis Studio Electronics +1449 TUT Systems Inc +144a Adlink Technology +144b Loronix Information Systems Inc +144c Catalina Research Inc +144d Samsung Electronics Co Ltd +144e OLITEC +144f Askey Computer Corp. +1450 Octave Communications Ind. +1451 SP3D Chip Design GmBH +1453 MYCOM Inc +1454 Altiga Networks +1455 Logic Plus Plus Inc +1456 Advanced Hardware Architectures +1457 Nuera Communications Inc +1458 Giga-byte Technology +1459 DOOIN Electronics +145a Escalate Networks Inc +145b PRAIM SRL +145c Cryptek +145d Gallant Computer Inc +145e Aashima Technology B.V. +145f Baldor Electric Company +1460 DYNARC INC +1461 Avermedia Technologies Inc +1462 Micro-star International Co Ltd +1463 Fast Corporation +1464 Interactive Circuits & Systems Ltd +1465 GN NETTEST Telecom DIV. +1466 Designpro Inc. +1467 DIGICOM SPA +1468 AMBIT Microsystem Corp. +1469 Cleveland Motion Controls +146a IFR +146b Parascan Technologies Ltd +146c Ruby Tech Corp. +146d Tachyon, INC. +146e Williams Electronics Games, Inc. +146f Multi Dimensional Consulting Inc +1470 Bay Networks +1471 Integrated Telecom Express Inc +1472 DAIKIN Industries, Ltd +1473 ZAPEX Technologies Inc +1474 Doug Carson & Associates +1475 PICAZO Communications +1476 MORTARA Instrument Inc +1477 Net Insight +1478 DIATREND Corporation +1479 TORAY Industries Inc +147a FORMOSA Industrial Computing +147b ABIT Computer Corp. +147c AWARE, Inc. +147d Interworks Computer Products +147e Matsushita Graphic Communication Systems, Inc. +147f NIHON UNISYS, Ltd. +1480 SCII Telecom +1481 BIOPAC Systems Inc +1482 ISYTEC - Integrierte Systemtechnik GmBH +1483 LABWAY Corporation +1484 Logic Corporation +1485 ERMA - Electronic GmBH +1486 L3 Communications Telemetry & Instrumentation +1487 MARQUETTE Medical Systems +1488 KONTRON Electronik GmBH +1489 KYE Systems Corporation +148a OPTO +148b INNOMEDIALOGIC Inc. +148c C.P. Technology Co. Ltd +148d DIGICOM Systems, Inc. +148e OSI Plus Corporation +148f Plant Equipment, Inc. +1490 Stone Microsystems PTY Ltd. +1491 ZEAL Corporation +1492 Time Logic Corporation +1493 MAKER Communications +1494 WINTOP Technology, Inc. +1495 TOKAI Communications Industry Co. Ltd +1496 JOYTECH Computer Co., Ltd. +1497 SMA Regelsysteme GmBH +1498 TEWS Datentechnik GmBH +1499 EMTEC CO., Ltd +149a ANDOR Technology Ltd +149b SEIKO Instruments Inc +149c OVISLINK Corp. +149D NEWTEK Inc +149e Mapletree Networks Inc. +149f LECTRON Co Ltd +14a0 SOFTING GmBH +14a1 Systembase Co Ltd +14a2 Millennium Engineering Inc +14a3 Maverick Networks +14a4 GVC/BCM Advanced Research +14a5 XIONICS Document Technologies Inc +14a6 INOVA Computers GmBH & Co KG +14a7 MYTHOS Systems Inc +14a8 FEATRON Technologies Corporation +14a9 HIVERTEC Inc +14aa Advanced MOS Technology Inc +14ab Mentor Graphics Corp. +14ac Novaweb Technologies Inc +14ad Time Space Radio AB +14ae CTI, Inc +14af Guillemot Corporation +14b0 BST Communication Technology Ltd +14b1 Nextcom K.K. +14b2 ENNOVATE Networks Inc +14b3 XPEED Inc +14b4 PHILIPS Business Electronics B.V. +14b5 Creamware GmBH +14b6 Quantum Data Corp. +14b7 PROXIM Inc + 0001 Symphony 4110 +14b8 Techsoft Technology Co Ltd +14b9 AIRONET Wireless Communications + 0001 PC4800 +14ba INTERNIX Inc. +14bb SEMTECH Corporation +14bc Globespan Semiconductor Inc. +14bd CARDIO Control N.V. +14be L3 Communications +14bf SPIDER Communications Inc. +14c0 COMPAL Electronics Inc +14c1 MYRICOM Inc. +14c2 DTK Computer +14c3 MEDIATEK Corp. +14c4 IWASAKI Information Systems Co Ltd +14c5 Automation Products AB +14c6 Data Race Inc +14c7 Modular Technology Holdings Ltd +14c8 Turbocomm Tech. Inc. +14c9 ODIN Telesystems Inc +14ca PE Logic Corp. +14cb Billionton Systems Inc +14cc NAKAYO Telecommunications Inc +14cd Universal Scientific Ind. +14ce Whistle Communications +14cf TEK Microsystems Inc. +14d0 Ericsson Axe R & D +14d1 Computer Hi-Tech Co Ltd +14d2 Titan Electronics Inc +14d3 CIRTECH (UK) Ltd +14d4 Panacom Technology Corp +14d5 Nitsuko Corporation +14d6 Accusys Inc +14d7 Hirakawa Hewtech Corp +14d8 HOPF Elektronik GmBH +14d9 Alpha Processor Inc +14da National Aerospace Laboratories +14db AFAVLAB Technology Inc +14dc Amplicon Liveline Ltd +14dd Boulder Design Labs Inc +14de Applied Integration Corporation +14df ASIC Communications Corp +14e1 INVERTEX +14e2 INFOLIBRIA +14e3 AMTELCO +14e4 BROADCOM Corporation +14e5 Pixelfusion Ltd +14e6 SHINING Technology Inc +14e7 3CX +14e8 RAYCER Inc +14e9 GARNETS System CO Ltd +14ea PLANEX COMMUNICATIONS Inc +14eb SEIKO EPSON Corp +14ec ACQIRIS +14ed DATAKINETICS Ltd +14ee MASPRO KENKOH Corp +14ef CARRY Computer ENG. CO Ltd +14f0 CANON RESEACH CENTRE FRANCE +14f1 CONEXANT + 2013 HSP MicroModem 56K +14f2 MOBILITY Electronics +14f3 BROADLOGIC +14f4 TOKYO Electronic Industry CO Ltd +14f5 SOPAC Ltd +14f6 COYOTE Technologies LLC +14f7 WOLF Technology Inc +14f8 AUDIOCODES Inc +14f9 AG COMMUNICATIONS +14fa WANDEL & GOCHERMANN +14fb TRANSAS MARINE (UK) Ltd +14fc QUADRICS Supercomputers World +14fd JAPAN Computer Industry Inc +14fe ARCHTEK TELECOM Corp +14ff TWINHEAD INTERNATIONAL Corp +1500 DELTA Electronics, Inc +1501 BANKSOFT CANADA Ltd +1502 MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd +1503 KAWASAKI LSI USA Inc +1504 KAISER Electronics +1505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH +1506 CHAMELEON Systems Inc +# 1507 HTEC Ltd +# Commented out because there are no known HTEC chips and 1507 is already +# used by mistake by Motorola (see vendor ID 1057) +1508 HONDA CONNECTORS/MHOTRONICS Inc +1509 FIRST INTERNATIONAL Computer Inc +150a FORVUS RESEARCH Inc +150b YAMASHITA Systems Corp +150c KYOPAL CO Ltd +150d WARPSPPED Inc +150e C-PORT Corp +150f INTEC GmbH +1510 BEHAVIOR TECH Computer Corp +1511 CENTILLIUM Technology Corp +1512 ROSUN Technologies Inc +1513 Raychem +1514 TFL LAN Inc +1515 Advent design +1516 MYSON Technology Inc +1517 ECHOTEK Corp +1518 PEP MODULAR Computers GmbH +1519 TELEFON AKTIEBOLAGET LM Ericsson +151a GLOBETEK Inc +151b COMBOX Ltd +151c DIGITAL AUDIO LABS Inc +151d Fujitsu Computer Products Of America +151e MATRIX Corp +151f TOPIC SEMICONDUCTOR Corp +1520 CHAPLET System Inc +1521 BELL Corp +1522 MainPine Ltd +1523 MUSIC Semiconductors +1524 ENE Technology Inc +1525 IMPACT Technologies +1526 ISS, Inc +1527 SOLECTRON +1528 ACKSYS +1529 AMERICAN MICROSystems Inc +152a QUICKTURN DESIGN Systems +152b FLYTECH Technology CO Ltd +152c MACRAIGOR Systems LLC +152d QUANTA Computer Inc +152e MELEC Inc +152f PHILIPS - CRYPTO +1530 ACQIS Technology Inc +1531 CHRYON Corp +1532 ECHELON Corp +1533 BALTIMORE +1534 ROAD Corp +1535 EVERGREEN Technologies Inc +1537 DATALEX COMMUNCATIONS +1538 ARALION Inc +1539 ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A. +153a ONO SOKKI +153b TERRATEC Electronic GmbH +153c ANTAL Electronic +153d FILANET Corp +153e TECHWELL Inc +153f MIPS DENMARK +1540 PROVIDEO MULTIMEDIA Co Ltd +1541 MACHONE Communications +1542 VIVID Technology Inc +1543 SILICON Laboratories +1544 DCM DATA Systems +1545 VISIONTEK +1546 IOI Technology Corp +1547 MITUTOYO Corp +1548 JET PROPULSION Laboratory +1549 INTERCONNECT Systems Solutions +154a MAX Technologies Inc +154b COMPUTEX Co Ltd +154c VISUAL Technology Inc +154d PAN INTERNATIONAL Industrial Corp +154e SERVOTEST Ltd +154f STRATABEAM Technology +1550 OPEN NETWORK Co Ltd +1551 SMART Electronic DEVELOPMENT GmBH +1552 RACAL AIRTECH Ltd +1553 CHICONY Electronics Co Ltd +1554 PROLINK Microsystems Corp +1555 GESYTEC GmBH +1556 PLD APPLICATIONS +1557 MEDIASTAR Co Ltd +1558 CLEVO/KAPOK Computer +1559 SI LOGIC Ltd +155a INNOMEDIA Inc +155b PROTAC INTERNATIONAL Corp +1668 Action Tec Electronics Inc +1a08 Sierra semiconductor + 0000 SC15064 +1b13 Jaton Corp +1c1c Symphony + 0001 82C101 +1d44 DPT + a400 PM2x24/PM3224 +1de1 Tekram Technology Co.,Ltd. + 2020 DC-390 + 690c 690c + dc29 DC290 +2001 Temporal Research Ltd +21c3 21st Century Computer Corp. +2348 Racore + 2010 8142 100VG/AnyLAN +2646 Kingston Technologies +270b Xantel Corporation +270f Chaintech Computer Co. Ltd +2711 AVID Technology Inc. +3000 Hansol Electronics Inc. +3142 Post Impression Systems. +3388 Hint Corp + 8011 VXPro II Chipset + 8012 VXPro II Chipset + 8013 VXPro II Chipset +3513 ARCOM Control Systems Ltd +3d3d 3DLabs + 0001 GLINT 300SX + 0002 GLINT 500TX + 0003 GLINT Delta + 0004 Permedia + 0005 Permedia + 0006 GLINT MX + 0007 3D Extreme + 0009 Permedia II 2D+3D + 3d3d 0100 AccelStar II 3D Accelerator + 3d3d 0111 Permedia 3:16 + 3d3d 0114 Santa Ana + 3d3d 0116 Oxygen GVX1 + 3d3d 0119 Scirocco + 3d3d 0120 Santa Ana PCL + 3d3d 0125 Oxygen VX1 + 3d3d 0127 Permedia3 Create! + 0100 Permedia II 2D+3D + 1004 Permedia + 3d04 Permedia + ffff Glint VGA +4005 Avance Logic Inc. + 1064 ALG-2064 + 2064 ALG-2064i + 2128 ALG-2364A GUI Accelerator + 2301 ALG-2301 + 2302 ALG-2302 + 2303 AVG-2302 GUI Accelerator + 2364 ALG-2364A + 2464 ALG-2464 + 2501 ALG-2564A/25128A +4033 Addtron Technology Co, Inc. +4444 Internext Compression Inc +4468 Bridgeport machines +4594 Cogetec Informatique Inc +45fb Baldor Electric Company +4680 Umax Computer Corp +4843 Hercules Computer Technology Inc +4943 Growth Networks +4978 Axil Computer Inc +4a14 NetVin + 5000 NV5000SC +4b10 Buslogic Inc. +4c48 LUNG HWA Electronics +4d51 MediaQ Inc. + 0200 MQ-200 +4ddc ILC Data Device Corp +5053 Voyetra Technologies + 2010 Daytona Audio Adapter +5136 S S Technologies +5143 Qualcomm Inc +5145 Ensoniq (Old) + 3031 Concert AudioPCI +5301 Alliance Semiconductor Corp. + 0001 ProMotion aT3D +5333 S3 Inc. + 0551 Plato/PX (system) + 5631 86c325 [ViRGE] + 8800 86c866 [Vision 866] + 8801 86c964 [Vision 964] + 8810 86c764_0 [Trio 32 vers 0] + 8811 86c764/765 [Trio32/64/64V+] + 8812 86cM65 [Aurora64V+] + 8813 86c764_3 [Trio 32/64 vers 3] + 8814 86c767 [Trio 64UV+] + 8815 86cM65 [Aurora 128] + 883d 86c988 [ViRGE/VX] + 8870 FireGL + 8880 86c868 [Vision 868 VRAM] vers 0 + 8881 86c868 [Vision 868 VRAM] vers 1 + 8882 86c868 [Vision 868 VRAM] vers 2 + 8883 86c868 [Vision 868 VRAM] vers 3 + 88b0 86c928 [Vision 928 VRAM] vers 0 + 88b1 86c928 [Vision 928 VRAM] vers 1 + 88b2 86c928 [Vision 928 VRAM] vers 2 + 88b3 86c928 [Vision 928 VRAM] vers 3 + 88c0 86c864 [Vision 864 DRAM] vers 0 + 88c1 86c864 [Vision 864 DRAM] vers 1 + 88c2 86c864 [Vision 864-P DRAM] vers 2 + 88c3 86c864 [Vision 864-P DRAM] vers 3 + 88d0 86c964 [Vision 964 VRAM] vers 0 + 88d1 86c964 [Vision 964 VRAM] vers 1 + 88d2 86c964 [Vision 964-P VRAM] vers 2 + 88d3 86c964 [Vision 964-P VRAM] vers 3 + 88f0 86c968 [Vision 968 VRAM] rev 0 + 88f1 86c968 [Vision 968 VRAM] rev 1 + 88f2 86c968 [Vision 968 VRAM] rev 2 + 88f3 86c968 [Vision 968 VRAM] rev 3 + 8900 86c755 [Trio 64V2/DX] + 8901 Trio 64V2/DX or /GX + 8902 Plato/PX + 8903 Trio 3D business multimedia + 8904 Trio 64 3D + 1014 00db Integrated Trio3D + 5333 8904 86C365 Trio3D AGP + 8905 Trio 64V+ family + 8906 Trio 64V+ family + 8907 Trio 64V+ family + 8908 Trio 64V+ family + 8909 Trio 64V+ family + 890a Trio 64V+ family + 890b Trio 64V+ family + 890c Trio 64V+ family + 890d Trio 64V+ family + 890e Trio 64V+ family + 890f Trio 64V+ family + 8a01 ViRGE/DX or /GX + 0e11 b032 ViRGE/GX + 10b4 1617 Nitro 3D + 10b4 1717 Nitro 3D + 5333 8a01 ViRGE/DX + 8a10 ViRGE/GX2 + 1092 8a10 Stealth 3D 4000 + 8a13 86c368 [Trio 3D/2X] + 5333 8a13 Trio3D/2X + 8a20 86c794 [Savage 3D] + 8a21 86c795 [Savage 3D/MV] + 8a22 Savage 4 + 105d 0018 SR9 8Mb SDRAM + 105d 002a SR9 Pro 16Mb SDRAM + 105d 003a SR9 Pro 32Mb SDRAM + 105d 092f SR9 Pro+ 16Mb SGRAM + 1092 4207 Stealth III S540 + 1092 4800 Stealth III S540 + 1092 4808 Stealth III S540 + 1092 480e Stealth III S540 + 1092 4904 Stealth III S520 + 1092 4a09 Stealth III S540 + 1092 4a0b Stealth III S540 Xtreme + 1092 4a0f Stealth III S540 + 1092 4e01 Stealth III S540 + 1102 101d 3d Blaster Savage 4 + 1102 101e 3d Blaster Savage 4 + 8a23 Savage 4 + 8c00 ViRGE/M3 + 8c01 ViRGE/MX + 8c02 ViRGE/MX+ + 8c03 ViRGE/MX+MV + ca00 SonicVibes +544c Teralogic Inc +5455 Technische University Berlin + 4458 S5933 +5519 Cnet Technologies, Inc. +5555 Genroco, Inc + 0003 TURBOstor HFP-832 [HiPPI NIC] +5700 Netpower +6356 UltraStor +6374 c't Magazin für Computertechnik + 6773 GPPCI +6409 Logitec Corp. +6666 Decision Computer International Co. + 0001 PCCOM4 + 0002 PCCOM8 +7604 O.N. Electronic Co Ltd. +7bde MIDAC Corporation +7fed PowerTV +8008 Quancom Electronic GmbH + 0010 WDOG1 [PCI-Watchdog 1] + 0011 PWDOG2 [PCI-Watchdog 2] +8086 Intel Corporation + 0007 82379AB + 0039 21145 + 0122 82437FX + 0482 82375EB + 0483 82424ZX [Saturn] + 0484 82378IB [SIO ISA Bridge] + 0486 82430ZX [Aries] + 04a3 82434LX [Mercury/Neptune] + 04d0 82437FX [Triton FX] + 0960 80960RP [i960 RP Microprocessor/Bridge] + 1000 82542 Gigabit Ethernet Adapter + 0e11 b0df NC1632 Gigabit Ethernet Adapter + 0e11 b0e0 NC1633 Gigabit Ethernet Adapter + 0e11 b123 NC1634 Gigabit Ethernet Adapter + 1014 0119 Netfinity Gigabit Ethernet SX Adapter + 8086 1000 EtherExpress PRO/1000 Gigabit Server Adapter + 1209 82559ER + 1221 82092AA_0 + 1222 82092AA_1 + 1223 SAA7116 + 1225 82452KX/GX [Orion] + 1226 82596 + 1227 82865 [Ether Express Pro 100] + 1228 82556 [Ether Express Pro 100 Smart] + 1229 82557 [Ethernet Pro 100] + 0e11 b01e NC3120 + 0e11 b01f NC3122 + 0e11 b02f NC1120 + 0e11 b04a Netelligent 10/100TX NIC with Wake on LAN + 0e11 b0c6 Embedded NC3120 with Wake on LAN + 0e11 b0c7 Embedded NC3121 + 0e11 b0d7 NC3121 with Wake on LAN + 0e11 b0dd NC3131 + 0e11 b0de NC3132 + 0e11 b0e1 NC3133 + 1014 005c Ethernet Pro 10/100 + 1014 105c Netfinity 10/100 + 1033 8000 PC-9821X-B06 + 1033 8016 PK-UG-X006 + 1033 801f PK-UG-X006 + 103c 10C0 Ethernet Pro 10/100TX + 103c 10C3 Ethernet Pro 10/100TX + 103c 1200 Ethernet Pro 10/100TX + 10c3 1100 SmartEther100 SC1100 + 1259 2560 AT-2560 100 + 1259 2561 AT-2560 100 FX Ethernet Adapter + 1266 0001 NE10/100 Adapter + 8086 0001 EtherExpress PRO/100B (TX) + 8086 0002 EtherExpress PRO/100B (T4) + 8086 0003 EtherExpress PRO/10+ + 8086 0004 EtherExpress PRO/100 WfM + 8086 0005 82557 10/100 + 8086 0006 82557 10/100 with Wake on LAN + 8086 0007 82558 10/100 Adapter + 8086 0008 82558 10/100 with Wake on LAN + 8086 0009 EtherExpress PRO/100+ + 8086 000a EtherExpress PRO/100+ Management Adapter + 8086 000b EtherExpress PRO/100+ + 8086 000c EtherExpress PRO/100+ Management Adapter + 8086 000d EtherExpress PRO/100+ Alert On LAN II* Adapter + 8086 000e EtherExpress PRO/100+ Management Adapter with Alert On LAN* + 8086 1009 EtherExpress PRO/100+ Server Adapter + 8086 100C EtherExpress PRO/100+ Server Adapter (PILA8470B) + 8086 10f0 EtherExpress PRO/100+ Dual Port Adapter + 8086 200d EtherExpress PRO/100 Cardbus + 8086 200e EtherExpress PRO/100 LAN+V90 Cardbus Modem + 8086 3000 82559 Fast Ethernet LAN on Motherboard + 8086 3001 82559 Fast Ethernet LOM with Basic Alert on LAN* + 8086 3002 82559 Fast Ethernet LOM with Alert on LAN II* + 122d 430FX - 82437FX TSC [Triton I] + 122e 82371FB PIIX ISA [Triton I] + 1230 82371FB PIIX IDE [Triton I] + 1231 DSVD Modem + 1234 430MX - 82371MX MPIIX [430MX PCIset - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX)] + 1235 430MX - 82437MX MTSC [430MX PCIset - 82437MX Mobile System Controller (MTSC) and 82438MX Mobile Data Path (MTDP)] + 1237 440FX - 82441FX PMC [Natoma] + 1239 82371FB + 123b 82380PB + 123c 82380AB + 1240 752 AGP + 124b 82380FB + 1250 430HX - 82439HX TXC [Triton II] + 1960 80960RP [i960RP Microprocessor] + 101e 0438 MegaRaid 438 + 101e 0466 MegaRaid 466 + 103c 10C6 MegaRaid 438 + 103c 10C7 MegaRaid T5 + 1111 1111 MegaRaid 466 + 113c 03A2 MegaRaid + 5200 EtherExpress PRO/100 + 5201 EtherExpress PRO/100 + 7000 82371SB PIIX3 ISA [Natoma/Triton II] + 7010 82371SB PIIX3 IDE [Natoma/Triton II] + 7020 82371SB PIIX3 USB [Natoma/Triton II] + 7030 430VX - 82437VX TVX [Triton VX] + 7100 430TX - 82439TX MTXC + 7110 82371AB PIIX4 ISA + 7111 82371AB PIIX4 IDE + 7112 82371AB PIIX4 USB + 7113 82371AB PIIX4 ACPI + 7120 82810 GMCH [Graphics Memory Controller Hub] + 7121 82810 CGC [Chipset Graphics Controller] + 7122 82810-DC100 GMCH [Graphics Memory Controller Hub] + 7123 82810-DC100 CGC [Chipset Graphics Controller] + 7180 440LX/EX - 82443LX/EX Host bridge + 7181 440LX/EX - 82443LX/EX AGP bridge + 7190 440BX/ZX - 82443BX/ZX Host bridge + 0e11 0500 Armada 1750 Laptop System Chipset + 7191 440BX/ZX - 82443BX/ZX AGP bridge + 7192 440BX/ZX - 82443BX/ZX Host bridge (AGP disabled) + 0e11 0460 Armada 1700 Laptop System Chipset + 71a0 440GX - 82443GX Host bridge + 71a1 440GX - 82443GX AGP bridge + 71a2 440GX - 82443GX Host bridge (AGP disabled) + 7602 82372FB [PCI-to-USB UHCI] + 7800 i740 + 1092 0100 Stealth II G460 + 8086 0100 Intel740 Graphics Accelerator + 84c4 450KX/GX [Orion] - 82454KX/GX PCI bridge + 84c5 450KX/GX [Orion] - 82453KX/GX Memory controller + 84ca 450NX - 82451NX Memory & I/O Controller + 84cb 450NX - 82454NX PCI Expander Bridge + ffff 450NX/GX [Orion] - 82453KX/GX Memory controller [BUG] +8800 Trigem Computer Inc. + 2008 Video assistent component +8866 T-Square Design Inc. +8888 Silicon Magic +8e0e Computone Corporation +8e2e KTI + 3000 ET32P2 +9004 Adaptec +# FIXME: [dj] In one document I have, lot of these AIC's are actually AHA's + 1078 AIC-7810 + 1160 AIC-1160 [Family Fiber Channel Adapter] + 2178 AIC-7821 + 3860 AHA-2930CU + 3b78 AHA-4844W/4844UW + 5075 AIC-755x + 5078 AHA-7850 + 5175 AIC-755x + 5178 AIC-7851 + 5275 AIC-755x + 5278 AIC-7852 + 5375 AIC-755x + 5378 AIC-7850 + 5475 AIC-2930 + 5478 AIC-7850 + 5575 AVA-2930 + 5578 AIC-7855 + 5675 AIC-755x + 5678 AIC-7850 + 5775 AIC-755x + 5778 AIC-7850 + 5800 AIC-5800 + 5900 ANA-5910/5930/5940 ATM155 & 25 LAN Adapter + 5905 ANA-5910A/5930A/5940A ATM Adapter + 6038 AIC-3860 +# FIXME: This is a cardbus card. The declaration may be duplicative. + 6075 AIC-1480 / APA-1480 + 6078 AIC-7860 + 6178 AIC-7861 + 6278 AIC-7860 + 6378 AIC-7860 + 6478 AIC-786 + 6578 AIC-786x + 6678 AIC-786 + 6778 AIC-786x + 6915 ANA620xx/ANA69011A + 9004 0008 ANA69011A/TX 10/100 + 9004 0009 ANA69011A/TX 10/100 + 9004 0010 ANA62022 2-port 10/100 + 9004 0018 ANA62044 4-port 10/100 + 9004 0020 ANA62022 2-port 10/100 + 9004 0028 ANA69011A/TX 10/100 + 9004 8008 ANA69011A/TX 64 bit 10/100 + 9004 8009 ANA69011A/TX 64 bit 10/100 + 9004 8010 ANA62022 2-port 64 bit 10/100 + 9004 8018 ANA62044 4-port 64 bit 10/100 + 9004 8020 ANA62022 2-port 64 bit 10/100 + 9004 8028 ANA69011A/TX 64 bit 10/100 + 7078 AHA-294x / AIC-7870 + 7178 AHA-294x / AIC-7871 + 7278 AHA-3940 / AIC-7872 + 7378 AHA-3985 / AIC-7873 + 7478 AHA-2944 / AIC-7874 +# FIXME: [dj] Where did the 3rd number come from in 0x7578 & 0x7678 ? + 7578 AHA-3944 / AHA-3944W / 7875 + 7678 AHA-4944W/UW / 7876 + 7778 AIC-787x + 7810 AIC-7810 + 7850 AIC-7850 + 7855 AHA-2930 + 7860 AIC-7860 + 7870 AIC-7870 + 7871 AHA-2940 + 7872 AHA-3940 + 7873 AHA-3980 + 7874 AHA-2944 + 7880 AIC-7880P + 7890 AIC-7890 + 7891 AIC-789x + 7892 AIC-789x + 7893 AIC-789x + 7894 AIC-789x + 7895 AHA-2940U/UW / AHA-39xx / AIC-7895 + 7896 AIC-789x + 7897 AIC-789x + 8078 AIC-7880U + 8178 AIC-7881U + 8278 AHA-3940U/UW / AIC-7882U + 8378 AHA-3940U/UW / AIC-7883U + 8478 AHA-294x / AIC-7884U + 8578 AHA-3944U / AHA-3944UWD / 7885 + 8678 AHA-4944UW / 7886 + 8778 AIC-788x + 8878 7888 + 8b78 ABA-1030 + ec78 AHA-4944W/UW +9005 Adaptec + 0010 AHA-2940U2/W + 0011 2930U2 + 0013 78902 + 001f AHA-2940U2/W / 7890 + 0020 AIC-7890 + 002f AIC-7890 + 0030 AIC-7890 + 003f AIC-7890 + 0050 3940U2 + 0051 3950U2D + 005f 7896 + 0080 7892A + 0081 7892B + 0083 7892D + 008f 7892P + 00c0 7899A + 00c1 7899B + 00c3 7899D + 00cf 7899P +907f Atronics + 2015 IDE-2015PL +9412 Holtek + 6565 6565 +a0a0 AOPEN Inc. +a0f1 UNISYS Corporation +a200 NEC Corporation +a259 Hewlett Packard +a25b Hewlett Packard GmbH PL24-MKT +a304 Sony +a727 3Com Corporation +aa42 Scitex Digital Video +b1b3 Shiva Europe Limited +c001 TSI Telsys +c0a9 Micron/Crucial Technology +c0de Motorola +c0fe Motion Engineering, Inc. +cafe Chrysalis-ITS +cccc Catapult Communications +d4d4 Dy4 Systems Inc +e000 Winbond + e000 W89C940 +e159 Tiger Jet Network Inc. + 0001 Model 300 128k + 0059 0001 128k ISDN-S/T Adapter + 0059 0003 128k ISDN-U Adapter +eabb Aashima Technology B.V. +ecc0 Echo Corporation +edd8 ARK Logic Inc + a091 1000PV [Stingray] + a099 2000PV [Stingray] + a0a1 2000MT + a0a9 2000MI +feda Epigram Inc +fffe VMWare Inc + 0710 Virtual SVGA +ffff Illegal Vendor ID + + +# List of known device classes, subclasses and programming interfaces + +# Syntax: +# C class class_name +# subclass subclass_name <-- single tab +# prog-if prog-if_name <-- two tabs + +C 00 Unclassified device + 00 Non-VGA unclassified device + 01 VGA compatible unclassified device +C 01 Mass storage controller + 00 SCSI storage controller + 01 IDE interface + 02 Floppy disk controller + 03 IPI bus controller + 04 RAID bus controller + 80 Unknown mass storage controller +C 02 Network controller + 00 Ethernet controller + 01 Token ring network controller + 02 FDDI network controller + 03 ATM network controller + 80 Network controller +C 03 Display controller + 00 VGA compatible controller + 00 VGA + 01 8514 + 01 XGA compatible controller + 02 3D controller + 80 Display controller +C 04 Multimedia controller + 00 Multimedia video controller + 01 Multimedia audio controller + 02 Computer telephony device + 80 Multimedia controller +C 05 Memory controller + 00 RAM memory + 01 FLASH memory + 80 Memory controller +C 06 Bridge + 00 Host bridge + 01 ISA bridge + 02 EISA bridge + 03 MicroChannel bridge + 04 PCI bridge + 00 Normal decode + 01 Subtractive decode + 05 PCMCIA bridge + 06 NuBus bridge + 07 CardBus bridge + 08 RACEway bridge + 00 Transparent mode + 01 Endpoint mode + 80 Bridge +C 07 Communication controller + 00 Serial controller + 00 8250 + 01 16450 + 02 16550 + 03 16650 + 04 16750 + 05 16850 + 06 16950 + 01 Parallel controller + 00 SPP + 01 BiDir + 02 ECP + 03 IEEE1284 + FE IEEE1284 Target + 02 Multiport serial controller + 03 Modem + 00 Generic + 01 Hayes/16450 + 02 Hayes/16550 + 03 Hayes/16650 + 04 Hayes/16750 + 80 Communication controller +C 08 Generic system peripheral + 00 PIC + 00 8259 + 01 ISA PIC + 02 EISA PIC + 10 IO-APIC + 20 IO(X)-APIC + 01 DMA controller + 00 8237 + 01 ISA DMA + 02 EISA DMA + 02 Timer + 00 8254 + 01 ISA Timer + 02 EISA Timers + 03 RTC + 00 Generic + 01 ISA RTC + 04 PCI Hot-plug controller + 80 System peripheral +C 09 Input device controller + 00 Keyboard controller + 01 Digitizer Pen + 02 Mouse controller + 03 Scanner controller + 04 Gameport controller + 00 Generic + 10 Extended + 80 Input device controller +C 0A Docking station + 00 Generic Docking Station + 80 Docking Station +C 0B Processor + 00 386 + 01 486 + 02 Pentium + 10 Alpha + 20 Power PC + 30 MIPS + 40 Co-processor +C 0C Serial bus controller + 00 FireWire (IEEE 1394) + 00 Generic + 10 OHCI + 01 ACCESS Bus + 02 SSA + 03 USB Controller + 00 UHCI + 10 OHCI + 80 Unspecified + FE USB Device + 04 Fiber Channel + 05 SMBus +C 0D Wireless controller + 00 IRDA controller + 01 Consumer IR controller + 10 RF controller + 80 Wireless controller +C 0E Intelligent controller + 00 I2O +C 0F Satellite communications controller + 00 Satellite TV controller + 01 Satellite audio communication controller + 03 Satellite voice communication controller + 04 Satellite data communication controller +C 10 Encryption controller + 00 Network and computing encryption device + 01 Entertainment encryption device + 80 Encryption controller +C 11 Signal processing controller + 00 DPIO module + 80 Signal processing controller diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/bulkmem.c linux/drivers/pcmcia/bulkmem.c --- v2.3.26/linux/drivers/pcmcia/bulkmem.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/pcmcia/bulkmem.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ PCMCIA Bulk Memory Services - bulkmem.c 1.32 1999/09/15 15:32:19 + bulkmem.c 1.33 1999/10/25 20:03:33 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/cardbus.c linux/drivers/pcmcia/cardbus.c --- v2.3.26/linux/drivers/pcmcia/cardbus.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/pcmcia/cardbus.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ Cardbus device configuration - cardbus.c 1.61 1999/10/20 22:36:57 + cardbus.c 1.63 1999/11/08 20:47:02 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -190,7 +190,7 @@ sz &= PCI_BASE_ADDRESS_MEM_MASK; sz = FIND_FIRST_BIT(sz); if (sz < PAGE_SIZE) sz = PAGE_SIZE; - if (find_mem_region(&base, sz, "cb_enabler", sz, 0) != 0) { + if (find_mem_region(&base, sz, sz, 0, "cb_enabler") != 0) { printk(KERN_NOTICE "cs: could not allocate %dK memory for" " CardBus socket %d\n", sz/1024, s->sock); return CS_OUT_OF_RESOURCE; @@ -413,7 +413,8 @@ s->io[0].NumPorts = num[B_IO]; s->io[0].BasePort = 0; if (num[B_IO]) { - if (find_io_region(&s->io[0].BasePort, num[B_IO], name) != 0) { + if (find_io_region(&s->io[0].BasePort, num[B_IO], + num[B_IO], name) != 0) { printk(KERN_NOTICE "cs: could not allocate %d IO ports for" " CardBus socket %d\n", num[B_IO], s->sock); goto failed; @@ -423,8 +424,8 @@ s->win[0].size = num[B_M1]; s->win[0].base = 0; if (num[B_M1]) { - if (find_mem_region(&s->win[0].base, num[B_M1], - name, num[B_M1], 0) != 0) { + if (find_mem_region(&s->win[0].base, num[B_M1], num[B_M1], + 0, name) != 0) { printk(KERN_NOTICE "cs: could not allocate %dK memory for" " CardBus socket %d\n", num[B_M1]/1024, s->sock); goto failed; @@ -434,8 +435,8 @@ s->win[1].size = num[B_M2]; s->win[1].base = 0; if (num[B_M2]) { - if (find_mem_region(&s->win[1].base, num[B_M2], - name, num[B_M2], 0) != 0) { + if (find_mem_region(&s->win[1].base, num[B_M2], num[B_M2], + 0, name) != 0) { printk(KERN_NOTICE "cs: could not allocate %dK memory for" " CardBus socket %d\n", num[B_M2]/1024, s->sock); goto failed; diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/cb_enabler.c linux/drivers/pcmcia/cb_enabler.c --- v2.3.26/linux/drivers/pcmcia/cb_enabler.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/pcmcia/cb_enabler.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ Cardbus device enabler - cb_enabler.c 1.24 1999/10/20 00:19:09 + cb_enabler.c 1.25 1999/10/25 20:03:33 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -58,7 +58,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = -"cb_enabler.c 1.24 1999/10/20 00:19:09 (David Hinds)"; +"cb_enabler.c 1.25 1999/10/25 20:03:33 (David Hinds)"; #else #define DEBUG(n, args...) do { } while (0) #endif diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/cirrus.h linux/drivers/pcmcia/cirrus.h --- v2.3.26/linux/drivers/pcmcia/cirrus.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/cirrus.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * cirrus.h 1.3 1999/08/28 04:01:46 + * cirrus.h 1.4 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/cistpl.c linux/drivers/pcmcia/cistpl.c --- v2.3.26/linux/drivers/pcmcia/cistpl.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/pcmcia/cistpl.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ PCMCIA Card Information Structure parser - cistpl.c 1.72 1999/09/15 15:32:19 + cistpl.c 1.74 1999/11/08 20:47:02 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -206,7 +206,7 @@ s->cis_mem.sys_start = 0; vs = NULL; if (find_mem_region(&s->cis_mem.sys_start, s->cap.map_size, - "card services", s->cap.map_size, low)) { + s->cap.map_size, low, "card services")) { printk(KERN_NOTICE "cs: unable to map card memory!\n"); return CS_OUT_OF_RESOURCE; } diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c --- v2.3.26/linux/drivers/pcmcia/cs.c Fri Oct 22 13:21:49 1999 +++ linux/drivers/pcmcia/cs.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ PCMCIA Card Services -- core services - cs.c 1.232 1999/10/20 22:17:24 + cs.c 1.235 1999/11/11 17:52:05 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -70,7 +70,7 @@ int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); static const char *version = -"cs.c 1.232 1999/10/20 22:17:24 (David Hinds)"; +"cs.c 1.235 1999/11/11 17:52:05 (David Hinds)"; #endif static const char *release = "Linux PCMCIA Card Services " CS_RELEASE; @@ -100,7 +100,7 @@ static int setup_delay = HZ/20; /* ticks */ static int resume_delay = HZ/5; /* ticks */ static int shutdown_delay = HZ/40; /* ticks */ -static int vcc_settle = HZ*3/10; /* ticks */ +static int vcc_settle = HZ*4/10; /* ticks */ static int reset_time = 10; /* usecs */ static int unreset_delay = HZ/10; /* ticks */ static int unreset_check = HZ/10; /* ticks */ @@ -268,8 +268,8 @@ /*====================================================================*/ #if defined(CONFIG_PROC_FS) && defined(PCMCIA_DEBUG) -int proc_read_clients(char *buf, char **start, off_t pos, - int count, int *eof, void *data) +static int proc_read_clients(char *buf, char **start, off_t pos, + int count, int *eof, void *data) { socket_info_t *s = data; client_handle_t c; @@ -708,14 +708,28 @@ ======================================================================*/ static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base, - ioaddr_t num, char *name) + ioaddr_t num, u_int lines, char *name) { int i; - ioaddr_t try; - + ioaddr_t try, align; + + align = (*base) ? (1<io[i].NumPorts == 0) { - if (find_io_region(base, num, name) == 0) { + if (find_io_region(base, num, align, name) == 0) { s->io[i].Attributes = attr; s->io[i].BasePort = *base; s->io[i].NumPorts = s->io[i].InUse = num; @@ -727,7 +741,7 @@ /* Try to extend top of window */ try = s->io[i].BasePort + s->io[i].NumPorts; if ((*base == 0) || (*base == try)) - if (find_io_region(&try, num, name) == 0) { + if (find_io_region(&try, num, 0, name) == 0) { *base = try; s->io[i].NumPorts += num; s->io[i].InUse += num; @@ -736,7 +750,7 @@ /* Try to extend bottom of window */ try = s->io[i].BasePort - num; if ((*base == 0) || (*base == try)) - if (find_io_region(&try, num, name) == 0) { + if (find_io_region(&try, num, 0, name) == 0) { s->io[i].BasePort = *base = try; s->io[i].NumPorts += num; s->io[i].InUse += num; @@ -1699,12 +1713,14 @@ return CS_BAD_ATTRIBUTE; if (alloc_io_space(s, req->Attributes1, &req->BasePort1, - req->NumPorts1, handle->dev_info)) + req->NumPorts1, req->IOAddrLines, + handle->dev_info)) return CS_IN_USE; if (req->NumPorts2) { if (alloc_io_space(s, req->Attributes2, &req->BasePort2, - req->NumPorts2, handle->dev_info)) { + req->NumPorts2, req->IOAddrLines, + handle->dev_info)) { release_io_space(s, req->BasePort1, req->NumPorts1); return CS_IN_USE; } @@ -1836,10 +1852,11 @@ win->size = req->Size; align = ((s->cap.features & SS_CAP_MEM_ALIGN) || (req->Attributes & WIN_STRICT_ALIGN)); - if (find_mem_region(&win->base, win->size, (*handle)->dev_info, + if (find_mem_region(&win->base, win->size, (align ? req->Size : s->cap.map_size), (req->Attributes & WIN_MAP_BELOW_1MB) || - !(s->cap.features & SS_CAP_PAGE_REGS))) + !(s->cap.features & SS_CAP_PAGE_REGS), + (*handle)->dev_info)) return CS_IN_USE; req->Base = win->base; (*handle)->state |= CLIENT_WIN_REQ(w); @@ -2202,6 +2219,9 @@ EXPORT_SYMBOL(unregister_ss_entry); EXPORT_SYMBOL(CardServices); EXPORT_SYMBOL(MTDHelperEntry); +#ifdef CONFIG_PROC_FS +EXPORT_SYMBOL(proc_pccard); +#endif static int __init init_pcmcia_cs(void) { diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/cs_internal.h linux/drivers/pcmcia/cs_internal.h --- v2.3.26/linux/drivers/pcmcia/cs_internal.h Mon Oct 4 15:49:29 1999 +++ linux/drivers/pcmcia/cs_internal.h Thu Nov 11 17:03:09 1999 @@ -1,5 +1,5 @@ /* - * cs_internal.h 1.43 1999/09/07 15:19:04 + * cs_internal.h 1.46 1999/11/08 20:46:49 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. */ @@ -241,9 +241,10 @@ /* In rsrc_mgr */ void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long), int force_low); -int find_io_region(ioaddr_t *base, ioaddr_t num, char *name); -int find_mem_region(u_long *base, u_long num, char *name, - u_long align, int force_low); +int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, + char *name); +int find_mem_region(u_long *base, u_long num, u_long align, + int force_low, char *name); int try_irq(u_int Attributes, int irq, int specific); void undo_irq(u_int Attributes, int irq); int adjust_resource_info(client_handle_t handle, adjust_t *adj); @@ -252,15 +253,6 @@ int count, int *eof, void *data); int proc_read_mem(char *buf, char **start, off_t pos, int count, int *eof, void *data); - -/* in pnp components */ -int proc_read_irq(char *buf, char **start, off_t pos, - int count, int *eof, void *data); -void pnp_bios_init(void); -void pnp_proc_init(void); -void pnp_proc_done(void); -void pnp_rsrc_init(void); -void pnp_rsrc_done(void); #define MAX_SOCK 8 extern socket_t sockets; diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c --- v2.3.26/linux/drivers/pcmcia/ds.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/pcmcia/ds.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ PC Card Driver Services - ds.c 1.98 1999/09/15 15:32:19 + ds.c 1.100 1999/11/08 20:47:02 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -57,7 +58,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static const char *version = -"ds.c 1.98 1999/09/15 15:32:19 (David Hinds)"; +"ds.c 1.100 1999/11/08 20:47:02 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -66,7 +67,7 @@ typedef struct driver_info_t { dev_info_t dev_info; - int use_count; + int use_count, status; dev_link_t *(*attach)(void); void (*detach)(dev_link_t *); struct driver_info_t *next; @@ -116,6 +117,11 @@ static int sockets = 0, major_dev = -1; static socket_info_t *socket_table = NULL; +extern struct proc_dir_entry *proc_pccard; + +/* We use this to distinguish in-kernel from modular drivers */ +static int init_status = 1; + /*====================================================================*/ static void cs_error(client_handle_t handle, int func, int ret) @@ -149,6 +155,7 @@ driver = kmalloc(sizeof(driver_info_t), GFP_KERNEL); strncpy(driver->dev_info, (char *)dev_info, DEV_NAME_LEN); driver->use_count = 0; + driver->status = init_status; driver->next = root_driver; root_driver = driver; } @@ -200,6 +207,21 @@ return 0; } /* unregister_pccard_driver */ +/*====================================================================*/ + +#ifdef CONFIG_PROC_FS +static int proc_read_drivers(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + driver_info_t *d; + char *p = buf; + for (d = root_driver; d; d = d->next) + p += sprintf(p, "%-24.24s %d %d\n", d->dev_info, + d->status, d->use_count); + return (p - buf); +} +#endif + /*====================================================================== These manage a ring buffer of events pending for one user process @@ -874,7 +896,15 @@ "Driver Services\n"); else major_dev = i; - + +#ifdef CONFIG_PROC_FS + if (proc_pccard) { + struct proc_dir_entry *ent; + ent = create_proc_entry("drivers", 0, proc_pccard); + ent->read_proc = proc_read_drivers; + } + init_status = 0; +#endif return 0; } @@ -888,6 +918,10 @@ void __exit cleanup_module(void) { int i; +#ifdef CONFIG_PROC_FS + if (proc_pccard) + remove_proc_entry("drivers", proc_pccard); +#endif if (major_dev != -1) unregister_chrdev(major_dev, "pcmcia"); for (i = 0; i < sockets; i++) diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c --- v2.3.26/linux/drivers/pcmcia/i82365.c Fri Oct 22 13:21:50 1999 +++ linux/drivers/pcmcia/i82365.c Thu Nov 11 16:03:37 1999 @@ -3,7 +3,7 @@ Device driver for Intel 82365 and compatible PC Card controllers, and Yenta-compatible PCI-to-CardBus controllers. - i82365.c 1.260 1999/10/21 00:56:07 + i82365.c 1.265 1999/11/10 18:36:21 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -16,7 +16,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -76,7 +76,7 @@ MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static const char *version = -"i82365.c 1.260 1999/10/21 00:56:07 (David Hinds)"; +"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)"; #else #define DEBUG(n, args...) do { } while (0) #endif @@ -189,7 +189,7 @@ #ifdef CONFIG_ISA #ifdef CONFIG_PCI /* PCI card status change interrupts? */ -static int pci_csc = 1; +static int pci_csc = 0; /* PCI IO card functional interrupts? */ static int pci_int = 0; MODULE_PARM(pci_csc, "i"); @@ -903,7 +903,8 @@ { socket_info_t *t = &socket[s]; o2micro_state_t *p = &socket[s].state.o2micro; - if ((t->revision == 0x34) || (t->revision == 0x62)) { + if ((t->revision == 0x34) || (t->revision == 0x62) || + (t->type == IS_OZ6812)) { p->mode_a = i365_get(s, O2_MODE_A_2); p->mode_b = i365_get(s, O2_MODE_B_2); } else { @@ -923,7 +924,8 @@ { socket_info_t *t = &socket[s]; o2micro_state_t *p = &socket[s].state.o2micro; - if ((t->revision == 0x34) || (t->revision == 0x62)) { + if ((t->revision == 0x34) || (t->revision == 0x62) || + (t->type == IS_OZ6812)) { i365_set(s, O2_MODE_A_2, p->mode_a); i365_set(s, O2_MODE_B_2, p->mode_b); } else { @@ -1007,6 +1009,7 @@ flip(p->ccr, TOPIC97_ICR_IRQSEL, pcsc); return 0; } else { + /* no ISA card status change irq */ return !pcsc; } } @@ -1541,7 +1544,8 @@ #ifdef CONFIG_ISA /* Poll if only two interrupts available */ if (!use_pci && !poll_interval) { - u_int tmp = (mask & (mask-1)); + u_int tmp = (mask & 0xff20); + tmp = tmp & (tmp-1); if ((tmp & (tmp-1)) == 0) poll_interval = HZ; } @@ -1627,7 +1631,7 @@ u_short v, u_short d0) { socket_info_t *s = &socket[sockets]; - u_short d, ns; + u_short d, ns, i; u_char a, b, r, max; /* PCI bus enumeration is broken on some systems */ @@ -1666,7 +1670,6 @@ pci_writel(bus, devfn, CB_LEGACY_MODE_BASE, 0); pci_readl(bus, devfn, PCI_BASE_ADDRESS_0, &s->cb_phys); if (s->cb_phys == 0) { - int i; pci_writew(bus, devfn, PCI_COMMAND, CMD_DFLT); for (i = 0; i < sizeof(cb_mem_base)/sizeof(u_int); i++) { s->cb_phys = cb_mem_base[i]; @@ -1710,10 +1713,21 @@ } add_pcic(ns, type); - /* Re-do card type & voltage detection */ - cb_writel(sockets-ns, CB_SOCKET_FORCE, CB_SF_CVSTEST); - __set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/5); + /* Re-do card voltage detection, if needed: this checks for + card presence with no voltage detect bits set */ + for (a = sockets-ns; a < sockets; a++) + if (!(cb_readl(a, CB_SOCKET_STATE) & 0x3c86)) + cb_writel(a, CB_SOCKET_FORCE, CB_SF_CVSTEST); + for (i = 0; i < 200; i++) { + for (a = sockets-ns; a < sockets; a++) + if (!(cb_readl(a, CB_SOCKET_STATE) & 0x3c86)) break; + if (a == sockets) break; + __set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/20); + } + if (i == 200) + printk(KERN_NOTICE "i82365: card voltage interrogation" + " timed out!\n"); /* Set up PCI bus bridge structures if needed */ for (a = 0; a < ns; a++) { diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/i82365.h linux/drivers/pcmcia/i82365.h --- v2.3.26/linux/drivers/pcmcia/i82365.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/i82365.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * i82365.h 1.14 1999/08/28 04:01:47 + * i82365.h 1.15 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/o2micro.h linux/drivers/pcmcia/o2micro.h --- v2.3.26/linux/drivers/pcmcia/o2micro.h Fri Oct 22 13:21:50 1999 +++ linux/drivers/pcmcia/o2micro.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * o2micro.h 1.12 1999/10/16 01:43:24 + * o2micro.h 1.13 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/ricoh.h linux/drivers/pcmcia/ricoh.h --- v2.3.26/linux/drivers/pcmcia/ricoh.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/ricoh.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * ricoh.h 1.8 1999/08/28 04:01:47 + * ricoh.h 1.9 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/rsrc_mgr.c linux/drivers/pcmcia/rsrc_mgr.c --- v2.3.26/linux/drivers/pcmcia/rsrc_mgr.c Wed Oct 27 16:34:12 1999 +++ linux/drivers/pcmcia/rsrc_mgr.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ Resource management routines - rsrc_mgr.c 1.73 1999/10/19 00:54:04 + rsrc_mgr.c 1.76 1999/11/08 20:47:02 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -100,6 +100,14 @@ /*====================================================================== + Linux resource management extensions + +======================================================================*/ + +#define check_io_region(b,n) (0) + +/*====================================================================== + These manage the internal databases of available resources. ======================================================================*/ @@ -180,7 +188,7 @@ b = kmalloc(256, GFP_KERNEL); memset(b, 0, 256); for (i = base, most = 0; i < base+num; i += 8) { - if (check_region(i, 8)) + if (check_region(i, 8) || check_io_region(i, 8)) continue; hole = inb(i); for (j = 1; j < 8; j++) @@ -193,7 +201,7 @@ bad = any = 0; for (i = base; i < base+num; i += 8) { - if (check_region(i, 8)) + if (check_region(i, 8) || check_io_region(i, 8)) continue; for (j = 0; j < 8; j++) if (inb(i+j) != most) break; @@ -344,67 +352,59 @@ These find ranges of I/O ports or memory addresses that are not currently allocated by other devices. + + The 'align' field should reflect the number of bits of address + that need to be preserved from the initial value of *base. It + should be a power of two, greater than or equal to 'num'. A value + of 0 means that all bits of *base are significant. *base should + also be strictly less than 'align'. ======================================================================*/ -int find_io_region(ioaddr_t *base, ioaddr_t num, char *name) +int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align, + char *name) { - ioaddr_t align; + ioaddr_t try; resource_map_t *m; - 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)) { - return -1; - } else { - request_region(*base, num, name); - return 0; - } - } - } - return -1; - } - - for (align = 1; align < num; align *= 2) ; for (m = io_db.next; m != &io_db; m = m->next) { - for (*base = (m->base + align - 1) & (~(align-1)); - *base+align <= m->base + m->num; - *base += align) - if (check_region(*base, num) == 0) { - request_region(*base, num, name); + try = (m->base & ~(align-1)) + *base; + for (try = (try >= m->base) ? try : try+align; + (try >= m->base) && (try+num <= m->base+m->num); + try += align) { + if ((check_region(try, num) == 0) && + (check_io_region(try, num) == 0)) { + *base = try; + request_region(try, num, name); return 0; } + if (!align) break; + } } return -1; } /* find_io_region */ -int find_mem_region(u_long *base, u_long num, char *name, - u_long align, int force_low) +int find_mem_region(u_long *base, u_long num, u_long align, + int force_low, char *name) { + u_long try; resource_map_t *m; - if (*base != 0) { - for (m = mem_db.next; m != &mem_db; m = m->next) { - if ((*base >= m->base) && (*base+num <= m->base+m->num)) - if (check_mem_region(*base, num) == 0) { - request_mem_region(*base, num, name); - return 0; - } - } - return -1; - } - while (1) { for (m = mem_db.next; m != &mem_db; m = m->next) { /* first pass >1MB, second pass <1MB */ if ((force_low != 0) ^ (m->base < 0x100000)) continue; - for (*base = (m->base + align - 1) & (~(align-1)); - *base+num <= m->base+m->num; *base += align) - if (check_mem_region(*base, num) == 0) { - request_mem_region(*base, num, name); + try = (m->base & ~(align-1)) + *base; + for (try = (try >= m->base) ? try : try+align; + (try >= m->base) && (try+num <= m->base+m->num); + try += align) { + if (check_mem_region(try, num) == 0) { + request_mem_region(try, num, name); + *base = try; return 0; } + if (!align) break; + } } if (force_low) break; force_low++; diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/rsrc_mgr.h linux/drivers/pcmcia/rsrc_mgr.h --- v2.3.26/linux/drivers/pcmcia/rsrc_mgr.h Fri Oct 22 13:21:50 1999 +++ linux/drivers/pcmcia/rsrc_mgr.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * rsrc_mgr.h 1.18 1999/08/28 04:01:47 + * rsrc_mgr.h 1.19 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/smc34c90.h linux/drivers/pcmcia/smc34c90.h --- v2.3.26/linux/drivers/pcmcia/smc34c90.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/smc34c90.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * smc34c90.h 1.6 1999/08/28 04:01:47 + * smc34c90.h 1.7 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/tcic.c linux/drivers/pcmcia/tcic.c --- v2.3.26/linux/drivers/pcmcia/tcic.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/pcmcia/tcic.c Thu Nov 11 16:03:37 1999 @@ -2,7 +2,7 @@ Device driver for Databook TCIC-2 PCMCIA controller - tcic.c 1.106 1999/09/15 15:32:19 + tcic.c 1.107 1999/10/25 20:03:34 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -15,7 +15,7 @@ rights and limitations under the License. The initial developer of the original code is David A. Hinds - . Portions created by David A. Hinds + . Portions created by David A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights Reserved. Alternatively, the contents of this file may be used under the @@ -60,7 +60,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); static const char *version = -"tcic.c 1.106 1999/09/15 15:32:19 (David Hinds)"; +"tcic.c 1.107 1999/10/25 20:03:34 (David Hinds)"; #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) #else #define DEBUG(n, args...) diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/tcic.h linux/drivers/pcmcia/tcic.h --- v2.3.26/linux/drivers/pcmcia/tcic.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/tcic.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * tcic.h 1.12 1999/08/28 04:01:47 + * tcic.h 1.13 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/ti113x.h linux/drivers/pcmcia/ti113x.h --- v2.3.26/linux/drivers/pcmcia/ti113x.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/ti113x.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * ti113x.h 1.15 1999/09/03 16:43:35 + * ti113x.h 1.16 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/vg468.h linux/drivers/pcmcia/vg468.h --- v2.3.26/linux/drivers/pcmcia/vg468.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/vg468.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * vg468.h 1.10 1999/08/28 04:01:47 + * vg468.h 1.11 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pcmcia/yenta.h linux/drivers/pcmcia/yenta.h --- v2.3.26/linux/drivers/pcmcia/yenta.h Tue Sep 7 12:14:06 1999 +++ linux/drivers/pcmcia/yenta.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * yenta.h 1.15 1999/08/28 04:01:47 + * yenta.h 1.16 1999/10/25 20:03:34 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c --- v2.3.26/linux/drivers/pnp/isapnp_proc.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/pnp/isapnp_proc.c Tue Nov 9 19:39:02 1999 @@ -247,7 +247,7 @@ static int isapnp_proc_done(void) { if (isapnp_proc_entry) - proc_unregister(&proc_root, isapnp_proc_entry->low_ino); + remove_proc_entry("isapnp",&proc_root); return 0; } #endif /* MODULE */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c --- v2.3.26/linux/drivers/scsi/53c7,8xx.c Fri Sep 10 23:57:30 1999 +++ linux/drivers/scsi/53c7,8xx.c Thu Nov 11 16:57:30 1999 @@ -263,13 +263,6 @@ #include #include -#ifndef LINUX_1_2 -struct proc_dir_entry proc_scsi_ncr53c7xx = { - PROC_SCSI_NCR53C7xx, 9, "ncr53c7xx", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; -#endif - static int check_address (unsigned long addr, int size); static void dump_events (struct Scsi_Host *host, int count); static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host, @@ -1568,9 +1561,7 @@ unsigned char pci_bus, pci_device_fn; static short pci_index=0; /* Device index to PCI BIOS calls */ -#ifndef LINUX_1_2 - tpnt->proc_dir = &proc_scsi_ncr53c7xx; -#endif + tpnt->proc_name = "ncr53c7xx"; for (current_override = count = 0; current_override < OVERRIDE_LIMIT; ++current_override) { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c --- v2.3.26/linux/drivers/scsi/AM53C974.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/AM53C974.c Thu Nov 11 16:57:30 1999 @@ -390,12 +390,6 @@ { {-1, 0, 0, 0},}; /* LILO overrides */ -struct proc_dir_entry proc_scsi_am53c974 = -{ - PROC_SCSI_AM53C974, 8, "am53c974", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #ifdef AM53C974_DEBUG static int deb_stop = 1; @@ -664,7 +658,7 @@ { int count = 0; /* number of boards detected */ - tpnt->proc_dir = &proc_scsi_am53c974; + tpnt->proc_name = "am53c974"; #if defined (CONFIG_PCI) if (pci_present()) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/AM53C974.h linux/drivers/scsi/AM53C974.h --- v2.3.26/linux/drivers/scsi/AM53C974.h Wed Jun 16 19:29:26 1999 +++ linux/drivers/scsi/AM53C974.h Thu Nov 11 16:57:30 1999 @@ -50,10 +50,8 @@ unsigned char max_offset[8]; /* max. sync. offset (setup), only valid if corresponding sync_en is nonzero */ }; -extern struct proc_dir_entry proc_scsi_am53c974; - #define AM53C974 { \ - proc_dir: &proc_scsi_am53c974, \ + proc_name: "am53c974", \ name: "AM53C974", \ detect: AM53C974_detect, \ release: AM53C974_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c --- v2.3.26/linux/drivers/scsi/BusLogic.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/BusLogic.c Thu Nov 11 16:57:30 1999 @@ -140,16 +140,6 @@ static char *BusLogic_CommandFailureReason; - -/* - BusLogic_ProcDirectoryEntry is the BusLogic /proc/scsi directory entry. -*/ - -PROC_DirectoryEntry_T - BusLogic_ProcDirectoryEntry = - { PROC_SCSI_BUSLOGIC, 8, "BusLogic", S_IFDIR | S_IRUGO | S_IXUGO, 2 }; - - /* BusLogic_AnnounceDriver announces the Driver Version and Date, Author's Name, Copyright Notice, and Electronic Mail Address. diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/BusLogic.h linux/drivers/scsi/BusLogic.h --- v2.3.26/linux/drivers/scsi/BusLogic.h Wed Aug 18 16:44:20 1999 +++ linux/drivers/scsi/BusLogic.h Thu Nov 11 17:03:45 1999 @@ -52,7 +52,6 @@ Define prototypes for the BusLogic Driver Interface Functions. */ -extern PROC_DirectoryEntry_T BusLogic_ProcDirectoryEntry; extern const char *BusLogic_DriverInfo(SCSI_Host_T *); extern int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *); extern int BusLogic_ReleaseHostAdapter(SCSI_Host_T *); @@ -69,7 +68,7 @@ */ #define BUSLOGIC \ - { proc_dir: &BusLogic_ProcDirectoryEntry, /* ProcFS Directory Entry */ \ + { proc_name: "BusLogic", /* ProcFS Directory Entry */ \ proc_info: BusLogic_ProcDirectoryInfo, /* ProcFS Info Function */ \ name: "BusLogic", /* Driver Name */ \ detect: BusLogic_DetectHostAdapter, /* Detect Host Adapter */ \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile --- v2.3.26/linux/drivers/scsi/Makefile Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/Makefile Wed Nov 10 08:40:04 1999 @@ -58,7 +58,7 @@ endif ifeq ($(CONFIG_BLK_DEV_SD),y) -L_OBJS += sd.o sd_ioctl.o +L_OBJS += sd.o else ifeq ($(CONFIG_BLK_DEV_SD),m) M_OBJS += sd_mod.o @@ -265,14 +265,22 @@ endif endif -ifeq ($(CONFIG_MAC_SCSI_OLD),y) +ifeq ($(CONFIG_MAC_SCSI),y) L_OBJS += mac_scsi.o else - ifeq ($(CONFIG_MAC_SCSI_OLD),m) + ifeq ($(CONFIG_MAC_SCSI),m) M_OBJS += mac_scsi.o endif endif +ifeq ($(CONFIG_SUN3_SCSI),y) +L_OBJS += sun3_scsi.o +else + ifeq ($(CONFIG_SUN3_SCSI),m) + M_OBJS += sun3_scsi.o + endif +endif + ifeq ($(CONFIG_SCSI_MAC_ESP),y) L_OBJS += mac_esp.o NCR53C9x.o else @@ -721,5 +729,5 @@ sr_mod.o: sr.o sr_ioctl.o sr_vendor.o $(LD) $(LD_RFLAG) -r -o $@ sr.o sr_ioctl.o sr_vendor.o -sd_mod.o: sd.o sd_ioctl.o - $(LD) $(LD_RFLAG) -r -o $@ sd.o sd_ioctl.o +sd_mod.o: sd.o + $(LD) $(LD_RFLAG) -r -o $@ sd.o diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/NCR53C9x.c linux/drivers/scsi/NCR53C9x.c --- v2.3.26/linux/drivers/scsi/NCR53C9x.c Thu Aug 12 10:28:34 1999 +++ linux/drivers/scsi/NCR53C9x.c Thu Nov 11 16:57:30 1999 @@ -94,11 +94,6 @@ /*5*/ do_intr_end }; -struct proc_dir_entry proc_scsi_esp = { - PROC_SCSI_ESP, 3, "esp", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* The master ring of all esp hosts we are managing in this driver. */ struct NCR_ESP *espchain = 0; int nesps = 0, esps_in_use = 0, esps_running = 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/NCR53C9x.h linux/drivers/scsi/NCR53C9x.h --- v2.3.26/linux/drivers/scsi/NCR53C9x.h Thu Aug 12 10:28:34 1999 +++ linux/drivers/scsi/NCR53C9x.h Thu Nov 11 16:57:30 1999 @@ -625,8 +625,6 @@ #define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) -extern struct proc_dir_entry proc_scsi_esp; - /* UGLY, UGLY, UGLY! */ extern int nesps, esps_in_use, esps_running; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c --- v2.3.26/linux/drivers/scsi/NCR53c406a.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/NCR53c406a.c Thu Nov 11 16:57:30 1999 @@ -212,10 +212,6 @@ static volatile int internal_done_errcode = 0; static char info_msg[256]; -struct proc_dir_entry proc_scsi_NCR53c406a = { - PROC_SCSI_NCR53C406A, 7, "NCR53c406a", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; /* ================================================================= */ /* possible BIOS locations */ @@ -571,7 +567,7 @@ #endif USE_DMA tpnt->present = 1; - tpnt->proc_dir = &proc_scsi_NCR53c406a; + tpnt->proc_name = "NCR53c406a"; shpnt = scsi_register(tpnt, 0); shpnt->irq = irq_level; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/NCR53c406a.h linux/drivers/scsi/NCR53c406a.h --- v2.3.26/linux/drivers/scsi/NCR53c406a.h Sun Dec 21 17:04:48 1997 +++ linux/drivers/scsi/NCR53c406a.h Thu Nov 11 16:57:30 1999 @@ -26,7 +26,7 @@ * Use SG_NONE if DMA mode is enabled! */ #define NCR53c406a { \ - proc_dir: &proc_scsi_NCR53c406a /* proc_dir */, \ + proc_name: "NCR53c406a" /* proc_name */, \ name: "NCR53c406a" /* name */, \ detect: NCR53c406a_detect /* detect */, \ info: NCR53c406a_info /* info */, \ @@ -42,8 +42,6 @@ unchecked_isa_dma: 1 /* unchecked_isa_dma */, \ use_clustering: ENABLE_CLUSTERING \ } - -extern struct proc_dir_entry proc_scsi_NCR53c406a; int NCR53c406a_detect(Scsi_Host_Template *); const char* NCR53c406a_info(struct Scsi_Host *); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/a2091.c linux/drivers/scsi/a2091.c --- v2.3.26/linux/drivers/scsi/a2091.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/scsi/a2091.c Thu Nov 11 16:57:30 1999 @@ -21,11 +21,6 @@ #include -struct proc_dir_entry proc_scsi_a2091 = { - PROC_SCSI_A2091, 5, "A2091", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define DMA(ptr) ((a2091_scsiregs *)((ptr)->base)) #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) @@ -201,7 +196,7 @@ return 0; called = 1; - tpnt->proc_dir = &proc_scsi_a2091; + tpnt->proc_name = "A2091"; tpnt->proc_info = &wd33c93_proc_info; while ((key = zorro_find(ZORRO_PROD_CBM_A590_A2091_1, 0, 0)) || diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/a2091.h linux/drivers/scsi/a2091.h --- v2.3.26/linux/drivers/scsi/a2091.h Sun Dec 27 22:19:11 1998 +++ linux/drivers/scsi/a2091.h Thu Nov 11 16:57:30 1999 @@ -31,9 +31,7 @@ #ifdef HOSTS_C -extern struct proc_dir_entry proc_scsi_a2091; - -#define A2091_SCSI { proc_dir: &proc_scsi_a2091, \ +#define A2091_SCSI { proc_name: "A2901", \ name: "Commodore A2091/A590 SCSI", \ detect: a2091_detect, \ release: a2091_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/a3000.c linux/drivers/scsi/a3000.c --- v2.3.26/linux/drivers/scsi/a3000.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/a3000.c Thu Nov 11 16:57:30 1999 @@ -20,11 +20,6 @@ #include -struct proc_dir_entry proc_scsi_a3000 = { - PROC_SCSI_A3000, 5, "A3000", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define DMA(ptr) ((a3000_scsiregs *)((ptr)->base)) #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) @@ -176,7 +171,7 @@ if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(A3000_SCSI)) return 0; - tpnt->proc_dir = &proc_scsi_a3000; + tpnt->proc_name = "A3000"; tpnt->proc_info = &wd33c93_proc_info; a3000_host = scsi_register (tpnt, sizeof(struct WD33C93_hostdata)); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/a3000.h linux/drivers/scsi/a3000.h --- v2.3.26/linux/drivers/scsi/a3000.h Sun Dec 27 22:19:11 1998 +++ linux/drivers/scsi/a3000.h Thu Nov 11 16:57:30 1999 @@ -31,9 +31,7 @@ #ifdef HOSTS_C -extern struct proc_dir_entry proc_scsi_a3000; - -#define A3000_SCSI { proc_dir: &proc_scsi_a3000, \ +#define A3000_SCSI { proc_name: "A3000", \ proc_info: NULL, \ name: "Amiga 3000 built-in SCSI", \ detect: a3000_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c --- v2.3.26/linux/drivers/scsi/advansys.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/advansys.c Thu Nov 11 16:57:30 1999 @@ -4011,19 +4011,6 @@ * --- Driver Data */ -/* Note: All driver global data should be initialized. */ - -#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) -struct proc_dir_entry proc_scsi_advansys = -{ - PROC_SCSI_ADVANSYS, /* unsigned short low_ino */ - 8, /* unsigned short namelen */ - "advansys", /* const char *name */ - S_IFDIR | S_IRUGO | S_IXUGO, /* mode_t mode */ - 2 /* nlink_t nlink */ -}; -#endif /* version >= v1.3.0 */ - /* Number of boards detected in system. */ STATIC int asc_board_count = 0; STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 }; @@ -4481,9 +4468,7 @@ ASC_DBG(1, "advansys_detect: begin\n"); -#if LINUX_VERSION_CODE >= ASC_LINUX_VERSION(1,3,0) - tpnt->proc_dir = &proc_scsi_advansys; -#endif /* version >= v1.3.0 */ + tpnt->proc_name = "advansys"; asc_board_count = 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/advansys.h linux/drivers/scsi/advansys.h --- v2.3.26/linux/drivers/scsi/advansys.h Wed Aug 18 16:44:17 1999 +++ linux/drivers/scsi/advansys.h Thu Nov 11 17:03:43 1999 @@ -40,18 +40,9 @@ int advansys_command(Scsi_Cmnd *); int advansys_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); int advansys_abort(Scsi_Cmnd *); -#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,89) -int advansys_reset(Scsi_Cmnd *); -#else /* version >= v1.3.89 */ int advansys_reset(Scsi_Cmnd *, unsigned int); -#endif /* version >= v1.3.89 */ -#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) -int advansys_biosparam(Disk *, int, int[]); -#else /* version >= v1.3.0 */ int advansys_biosparam(Disk *, kdev_t, int[]); -extern struct proc_dir_entry proc_scsi_advansys; int advansys_proc_info(char *, char **, off_t, int, int, int); -#endif /* version >= v1.3.0 */ /* init/main.c setup function */ void advansys_setup(char *, int *); @@ -59,92 +50,8 @@ /* * AdvanSys Host Driver Scsi_Host_Template (struct SHT) from hosts.h. */ -#if LINUX_VERSION_CODE < ASC_LINUX_VERSION(1,3,0) #define ADVANSYS { \ - NULL, /* struct SHT *next */ \ - NULL, /* int *usage_count */ \ - "advansys", /* char *name */ \ - advansys_detect, /* int (*detect)(struct SHT *) */ \ - advansys_release, /* int (*release)(struct Scsi_Host *) */ \ - advansys_info, /* const char *(*info)(struct Scsi_Host *) */ \ - advansys_command, /* int (*command)(Scsi_Cmnd *) */ \ - advansys_queuecommand, \ - /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \ - advansys_abort, /* int (*abort)(Scsi_Cmnd *) */ \ - advansys_reset, /* int (*reset)(Scsi_Cmnd *) */ \ - NULL, /* int (*slave_attach)(int, int) */ \ - advansys_biosparam, /* int (* bios_param)(Disk *, int, int []) */ \ - /* \ - * The following fields are set per adapter in advansys_detect(). \ - */ \ - 0, /* int can_queue */ \ - 0, /* int this_id */ \ - 0, /* short unsigned int sg_tablesize */ \ - 0, /* short cmd_per_lun */ \ - 0, /* unsigned char present */ \ - /* \ - * Because the driver may control an ISA adapter 'unchecked_isa_dma' \ - * must be set. The flag will be cleared in advansys_detect for non-ISA \ - * adapters. Refer to the comment in scsi_module.c for more information. \ - */ \ - 1, /* unsigned unchecked_isa_dma:1 */ \ - /* \ - * All adapters controlled by this driver are capable of large \ - * scatter-gather lists. According to the mid-level SCSI documentation \ - * this obviates any performance gain provided by setting \ - * 'use_clustering'. But empirically while CPU utilization is increased \ - * by enabling clustering, I/O throughput increases as well. \ - */ \ - ENABLE_CLUSTERING, /* unsigned use_clustering:1 */ \ -} -#elif LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,1,75) -#define ADVANSYS { \ - NULL, /* struct SHT *next */ \ - NULL, \ - /* version < v2.1.23 long *usage_count */ \ - /* version >= v2.1.23 struct module * */ \ - &proc_scsi_advansys, /* struct proc_dir_entry *proc_dir */ \ - advansys_proc_info, \ - /* int (*proc_info)(char *, char **, off_t, int, int, int) */ \ - "advansys", /* const char *name */ \ - advansys_detect, /* int (*detect)(struct SHT *) */ \ - advansys_release, /* int (*release)(struct Scsi_Host *) */ \ - advansys_info, /* const char *(*info)(struct Scsi_Host *) */ \ - advansys_command, /* int (*command)(Scsi_Cmnd *) */ \ - advansys_queuecommand, \ - /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \ - advansys_abort, /* int (*abort)(Scsi_Cmnd *) */ \ - advansys_reset, \ - /* version < v1.3.89 int (*reset)(Scsi_Cmnd *) */ \ - /* version >= v1.3.89 int (*reset)(Scsi_Cmnd *, unsigned int) */ \ - NULL, /* int (*slave_attach)(int, int) */ \ - advansys_biosparam, /* int (* bios_param)(Disk *, kdev_t, int []) */ \ - /* \ - * The following fields are set per adapter in advansys_detect(). \ - */ \ - 0, /* int can_queue */ \ - 0, /* int this_id */ \ - 0, /* short unsigned int sg_tablesize */ \ - 0, /* short cmd_per_lun */ \ - 0, /* unsigned char present */ \ - /* \ - * Because the driver may control an ISA adapter 'unchecked_isa_dma' \ - * must be set. The flag will be cleared in advansys_detect for non-ISA \ - * adapters. Refer to the comment in scsi_module.c for more information. \ - */ \ - 1, /* unsigned unchecked_isa_dma:1 */ \ - /* \ - * All adapters controlled by this driver are capable of large \ - * scatter-gather lists. According to the mid-level SCSI documentation \ - * this obviates any performance gain provided by setting \ - * 'use_clustering'. But empirically while CPU utilization is increased \ - * by enabling clustering, I/O throughput increases as well. \ - */ \ - ENABLE_CLUSTERING, /* unsigned use_clustering:1 */ \ -} -#else /* version >= v2.1.75 */ -#define ADVANSYS { \ - proc_dir: &proc_scsi_advansys, \ + proc_name: "advansys", \ proc_info: advansys_proc_info, \ name: "advansys", \ detect: advansys_detect, \ @@ -170,5 +77,4 @@ */ \ use_clustering: ENABLE_CLUSTERING, \ } -#endif /* version >= v2.1.75 */ #endif /* _ADVANSYS_H */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c --- v2.3.26/linux/drivers/scsi/aha152x.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/scsi/aha152x.c Thu Nov 11 16:57:30 1999 @@ -352,12 +352,6 @@ #include -struct proc_dir_entry proc_scsi_aha152x = -{ - PROC_SCSI_AHA152X, 7, "aha152x", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* DEFINES */ /* For PCMCIA cards, always use AUTOCONF */ @@ -716,8 +710,7 @@ } } -#if 0 -/* called from init/main.c */ +#ifdef PCMCIA void aha152x_setup(char *str, int *ints) { if (setup_count > 2) @@ -745,8 +738,9 @@ } else setup_count++; } -#endif +#endif /* PCMCIA */ +#ifndef MODULE static int __init do_aha152x_setup (char * str) { if (setup_count > 2) { @@ -765,10 +759,9 @@ return 1; } -#ifndef MODULE __setup("aha152x=",do_aha152x_setup); #endif - + /* * Test, if port_base is valid. */ @@ -843,7 +836,7 @@ aha152x_config conf; #endif - tpnt->proc_dir = &proc_scsi_aha152x; + tpnt->proc_name = "aha152x"; for (i = 0; i < IRQS; i++) aha152x_host[i] = (struct Scsi_Host *) NULL; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h --- v2.3.26/linux/drivers/scsi/aha152x.h Wed Aug 18 16:44:56 1999 +++ linux/drivers/scsi/aha152x.h Thu Nov 11 17:04:12 1999 @@ -26,10 +26,8 @@ #define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.7 $" -extern struct proc_dir_entry proc_scsi_aha152x; - /* Initial value of Scsi_Host entry */ -#define AHA152X { proc_dir: &proc_scsi_aha152x, \ +#define AHA152X { proc_name: "a152x", \ proc_info: aha152x_proc_info, \ name: AHA152X_REVID, \ detect: aha152x_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c --- v2.3.26/linux/drivers/scsi/aha1542.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/scsi/aha1542.c Thu Nov 11 16:57:30 1999 @@ -54,11 +54,6 @@ #include -struct proc_dir_entry proc_scsi_aha1542 = { - PROC_SCSI_AHA1542, 7, "aha1542", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #ifdef DEBUG #define DEB(x) x #else @@ -967,7 +962,7 @@ DEB(printk("aha1542_detect: \n")); - tpnt->proc_dir = &proc_scsi_aha1542; + tpnt->proc_name = "aha1542"; #ifdef MODULE bases[0] = aha1542[0]; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aha1542.h linux/drivers/scsi/aha1542.h --- v2.3.26/linux/drivers/scsi/aha1542.h Sun Dec 27 22:19:14 1998 +++ linux/drivers/scsi/aha1542.h Thu Nov 11 16:57:30 1999 @@ -149,9 +149,7 @@ #define NULL 0 #endif -extern struct proc_dir_entry proc_scsi_aha1542; - -#define AHA1542 { proc_dir: &proc_scsi_aha1542, \ +#define AHA1542 { proc_name: "aha1542", \ name: "Adaptec 1542", \ detect: aha1542_detect, \ command: aha1542_command, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c --- v2.3.26/linux/drivers/scsi/aha1740.c Wed Sep 9 08:56:58 1998 +++ linux/drivers/scsi/aha1740.c Thu Nov 11 16:57:30 1999 @@ -44,11 +44,6 @@ #include "aha1740.h" #include -struct proc_dir_entry proc_scsi_aha1740 = { - PROC_SCSI_AHA1740, 7, "aha1740", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH IT WORK, THEN: #define DEBUG diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aha1740.h linux/drivers/scsi/aha1740.h --- v2.3.26/linux/drivers/scsi/aha1740.h Sun Dec 27 22:19:14 1998 +++ linux/drivers/scsi/aha1740.h Thu Nov 11 16:57:30 1999 @@ -170,9 +170,7 @@ #define NULL 0 #endif -extern struct proc_dir_entry proc_scsi_aha1740; - -#define AHA1740 { proc_dir: &proc_scsi_aha1740, \ +#define AHA1740 { proc_name: "aha1740", \ proc_info: aha1740_proc_info, \ name: "Adaptec 174x (EISA)", \ detect: aha1740_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c --- v2.3.26/linux/drivers/scsi/aic7xxx.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/aic7xxx.c Thu Nov 11 16:57:30 1999 @@ -263,12 +263,6 @@ */ #define VIRT_TO_BUS(a) (unsigned int)virt_to_bus((void *)(a)) -struct proc_dir_entry proc_scsi_aic7xxx = { - PROC_SCSI_AIC7XXX, 7, "aic7xxx", - S_IFDIR | S_IRUGO | S_IXUGO, 2, - 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - #define AIC7XXX_C_VERSION "5.1.20" #define NUMBER(arr) (sizeof(arr) / sizeof(arr[0])) @@ -9076,7 +9070,7 @@ "aic7xxx: insmod or else it might trash certain memory areas.\n"); #endif - template->proc_dir = &proc_scsi_aic7xxx; + template->proc_name = "aic7xxx"; template->sg_tablesize = AIC7XXX_MAX_SG; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/aic7xxx.h linux/drivers/scsi/aic7xxx.h --- v2.3.26/linux/drivers/scsi/aic7xxx.h Wed Aug 18 16:44:20 1999 +++ linux/drivers/scsi/aic7xxx.h Thu Nov 11 17:03:44 1999 @@ -43,11 +43,9 @@ * Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields * to do with card config are filled in after the card is detected. */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,65) #define AIC7XXX { \ next: NULL, \ module: NULL, \ - proc_dir: NULL, \ proc_info: aic7xxx_proc_info, \ name: NULL, \ detect: aic7xxx_detect, \ @@ -73,31 +71,6 @@ use_clustering: ENABLE_CLUSTERING, \ use_new_eh_code: 0 \ } -#else -#define AIC7XXX { \ - next: NULL, \ - usage_count: NULL, \ - proc_dir: NULL, \ - proc_info: aic7xxx_proc_info, \ - name: NULL, \ - detect: aic7xxx_detect, \ - release: aic7xxx_release, \ - info: aic7xxx_info, \ - command: NULL, \ - queuecommand: aic7xxx_queue, \ - abort: aic7xxx_abort, \ - reset: aic7xxx_reset, \ - slave_attach: NULL, \ - bios_param: AIC7XXX_BIOSPARAM, \ - can_queue: 255, /* max simultaneous cmds */\ - this_id: -1, /* scsi id of host adapter */\ - sg_tablesize: 0, /* max scatter-gather cmds */\ - cmd_per_lun: 3, /* cmds per lun (linked cmds) */\ - present: 0, /* number of 7xxx's present */\ - unchecked_isa_dma: 0, /* no memory DMA restrictions */\ - use_clustering: ENABLE_CLUSTERING \ -} -#endif extern int aic7xxx_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); extern int aic7xxx_biosparam(Disk *, kdev_t, int[]); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/amiga7xx.c linux/drivers/scsi/amiga7xx.c --- v2.3.26/linux/drivers/scsi/amiga7xx.c Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/amiga7xx.c Thu Nov 11 16:57:30 1999 @@ -31,11 +31,6 @@ #include -struct proc_dir_entry proc_scsi_amiga7xx = { - PROC_SCSI_AMIGA7XX, 8, "Amiga7xx", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - extern int ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, u32 base, int io_port, int irq, int dma, long long options, int clock); @@ -51,7 +46,7 @@ if (called || !MACH_IS_AMIGA) return 0; - tpnt->proc_dir = &proc_scsi_amiga7xx; + tpnt->proc_name = "Amiga7xx"; #ifdef CONFIG_BLZ603EPLUS_SCSI if ((key = zorro_find(ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, 0, 0))) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/amiga7xx.h linux/drivers/scsi/amiga7xx.h --- v2.3.26/linux/drivers/scsi/amiga7xx.h Wed Jun 16 19:29:21 1999 +++ linux/drivers/scsi/amiga7xx.h Thu Nov 11 16:57:30 1999 @@ -25,8 +25,6 @@ #if defined(HOSTS_C) || defined(MODULE) #include -extern struct proc_dir_entry proc_scsi_amiga7xx; - #define AMIGA7XX_SCSI {name: "Amiga NCR53c710 SCSI", \ detect: amiga7xx_detect, \ queuecommand: NCR53c7xx_queue_command, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c --- v2.3.26/linux/drivers/scsi/atari_scsi.c Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/atari_scsi.c Thu Nov 11 16:57:30 1999 @@ -112,11 +112,6 @@ #include -struct proc_dir_entry proc_scsi_atari = { - PROC_SCSI_ATARI, 5, "Atari", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define IS_A_TT() ATARIHW_PRESENT(TT_SCSI) #define SCSI_DMA_WRITE_P(elt,val) \ @@ -616,7 +611,7 @@ called) return( 0 ); - host->proc_dir = &proc_scsi_atari; + host->proc_name = "Atari"; atari_scsi_reg_read = IS_A_TT() ? atari_scsi_tt_reg_read : atari_scsi_falcon_reg_read; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c --- v2.3.26/linux/drivers/scsi/atp870u.c Fri Oct 22 13:21:50 1999 +++ linux/drivers/scsi/atp870u.c Thu Nov 11 16:57:30 1999 @@ -30,12 +30,6 @@ #include -struct proc_dir_entry proc_scsi_atp870u = -{ - PROC_SCSI_ATP870U, 7, "atp870u", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - void mydlyu(unsigned int); /* @@ -1457,7 +1451,7 @@ printk(" NO BIOS32 SUPPORT.\n"); return count; } - tpnt->proc_dir = &proc_scsi_atp870u; + tpnt->proc_name = "atp870u"; for (h = 0; h < 2; h++) { active_idu[h] = 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/atp870u.h linux/drivers/scsi/atp870u.h --- v2.3.26/linux/drivers/scsi/atp870u.h Fri Oct 22 13:21:50 1999 +++ linux/drivers/scsi/atp870u.h Thu Nov 11 16:57:30 1999 @@ -34,16 +34,12 @@ #define NULL 0 #endif -extern struct proc_dir_entry proc_scsi_atp870u; - extern const char *atp870u_info(struct Scsi_Host *); extern int atp870u_proc_info(char *, char **, off_t, int, int, int); #define ATP870U { \ - next: NULL, \ - module: NULL, \ - proc_dir: &proc_scsi_atp870u, \ + proc_name: "atp870u", \ proc_info: atp870u_proc_info, \ name: NULL, \ detect: atp870u_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/blz1230.h linux/drivers/scsi/blz1230.h --- v2.3.26/linux/drivers/scsi/blz1230.h Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/blz1230.h Thu Nov 11 16:57:30 1999 @@ -57,7 +57,7 @@ extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); -#define SCSI_BLZ1230 { proc_dir: &proc_scsi_esp, \ +#define SCSI_BLZ1230 { proc_name: "esp-blz1230", \ proc_info: esp_proc_info, \ name: "Blizzard1230 SCSI IV", \ detect: blz1230_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/blz2060.h linux/drivers/scsi/blz2060.h --- v2.3.26/linux/drivers/scsi/blz2060.h Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/blz2060.h Thu Nov 11 16:57:30 1999 @@ -53,7 +53,7 @@ extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); -#define SCSI_BLZ2060 { proc_dir: &proc_scsi_esp, \ +#define SCSI_BLZ2060 { proc_name: "esp-blz2060", \ proc_info: esp_proc_info, \ name: "Blizzard2060 SCSI", \ detect: blz2060_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/bvme6000.c linux/drivers/scsi/bvme6000.c --- v2.3.26/linux/drivers/scsi/bvme6000.c Sat Aug 1 11:33:50 1998 +++ linux/drivers/scsi/bvme6000.c Thu Nov 11 16:57:30 1999 @@ -23,11 +23,6 @@ #include -struct proc_dir_entry proc_scsi_bvme6000 = { - PROC_SCSI_BVME6000, 8, "BVME6000", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - extern ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, u32 base, int io_port, int irq, int dma, long long options, int clock); @@ -43,7 +38,7 @@ if (!MACH_IS_BVME6000) return 0; - tpnt->proc_dir = &proc_scsi_bvme6000; + tpnt->proc_name = "BVME6000"; options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/bvme6000.h linux/drivers/scsi/bvme6000.h --- v2.3.26/linux/drivers/scsi/bvme6000.h Wed Jun 16 19:29:22 1999 +++ linux/drivers/scsi/bvme6000.h Thu Nov 11 16:57:30 1999 @@ -26,8 +26,6 @@ #if defined(HOSTS_C) || defined(MODULE) #include -extern struct proc_dir_entry proc_scsi_mvme16x; - #define BVME6000_SCSI {name: "BVME6000 NCR53c710 SCSI", \ detect: bvme6000_scsi_detect, \ queuecommand: NCR53c7xx_queue_command, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/cyberstorm.h linux/drivers/scsi/cyberstorm.h --- v2.3.26/linux/drivers/scsi/cyberstorm.h Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/cyberstorm.h Thu Nov 11 16:57:30 1999 @@ -56,7 +56,7 @@ int hostno, int inout); -#define SCSI_CYBERSTORM { proc_dir: &proc_scsi_esp, \ +#define SCSI_CYBERSTORM { proc_name: "esp-cyberstorm", \ proc_info: esp_proc_info, \ name: "CyberStorm SCSI", \ detect: cyber_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/cyberstormII.h linux/drivers/scsi/cyberstormII.h --- v2.3.26/linux/drivers/scsi/cyberstormII.h Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/cyberstormII.h Thu Nov 11 16:57:30 1999 @@ -43,7 +43,7 @@ extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); -#define SCSI_CYBERSTORMII { proc_dir: &proc_scsi_esp, \ +#define SCSI_CYBERSTORMII { proc_name: "esp-cyberstormII", \ proc_info: esp_proc_info, \ name: "CyberStorm Mk II SCSI", \ detect: cyberII_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/dc390.h linux/drivers/scsi/dc390.h --- v2.3.26/linux/drivers/scsi/dc390.h Wed Aug 18 16:44:24 1999 +++ linux/drivers/scsi/dc390.h Thu Nov 11 17:03:48 1999 @@ -34,11 +34,10 @@ # define DC390_release NULL #endif -extern struct proc_dir_entry DC390_proc_scsi_tmscsim; extern int DC390_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); #define DC390_T { \ - proc_dir: &DC390_proc_scsi_tmscsim, \ + proc_name: "tmscsim", \ proc_info: DC390_proc_info, \ name: DC390_BANNER " V" DC390_VERSION, \ detect: DC390_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/dec_esp.h linux/drivers/scsi/dec_esp.h --- v2.3.26/linux/drivers/scsi/dec_esp.h Fri Oct 15 15:25:14 1999 +++ linux/drivers/scsi/dec_esp.h Thu Nov 11 16:57:30 1999 @@ -24,7 +24,7 @@ int hostno, int inout); #define SCSI_DEC_ESP { \ - proc_dir: &proc_scsi_esp, \ + proc_name: "esp", \ proc_info: &esp_proc_info, \ name: "PMAZ-AA", \ detect: dec_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/dtc.c linux/drivers/scsi/dtc.c --- v2.3.26/linux/drivers/scsi/dtc.c Thu Aug 26 13:05:39 1999 +++ linux/drivers/scsi/dtc.c Thu Nov 11 16:57:30 1999 @@ -134,13 +134,6 @@ /*!!!! for dtc, it's a 128 byte buffer at 3900 !!! */ #define DTC_DATA_BUF 0x3900 /* rw 128 bytes long */ - -struct proc_dir_entry proc_scsi_dtc = { - PROC_SCSI_T128, 7, "dtc3x80", - S_IFDIR | S_IRUGO | S_IXUGO, 2 - }; - - static struct override { unsigned int address; int irq; @@ -214,7 +207,7 @@ unsigned int base; int sig, count; - tpnt->proc_dir = &proc_scsi_dtc; + tpnt->proc_name = "dtc3x80"; tpnt->proc_info = &dtc_proc_info; for (count = 0; current_override < NO_OVERRIDES; ++current_override) { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c --- v2.3.26/linux/drivers/scsi/eata.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/scsi/eata.c Thu Nov 11 16:57:30 1999 @@ -424,11 +424,6 @@ #define SPIN_UNLOCK_RESTORE \ spin_unlock_irqrestore(&io_request_lock, spin_flags); -struct proc_dir_entry proc_scsi_eata2x = { - PROC_SCSI_EATA2X, 6, "eata2x", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* Subversion values */ #define ISA 0 #define ESA 1 @@ -1257,7 +1252,7 @@ int eata2x_detect(Scsi_Host_Template *tpnt) { unsigned int j = 0, k; - tpnt->proc_dir = &proc_scsi_eata2x; + tpnt->proc_name = "eata2x"; if(boot_options) option_setup(boot_options); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c --- v2.3.26/linux/drivers/scsi/eata_dma.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/eata_dma.c Thu Nov 11 16:57:30 1999 @@ -92,11 +92,6 @@ #include #include /* for CONFIG_PCI */ -struct proc_dir_entry proc_scsi_eata_dma = { - PROC_SCSI_EATA, 8, "eata_dma", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - static u32 ISAbases[] = {0x1F0, 0x170, 0x330, 0x230}; static unchar EISAbases[] = @@ -1472,7 +1467,7 @@ DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, printk("Using lots of delays to let you read the debugging output\n")); - tpnt->proc_dir = &proc_scsi_eata_dma; + tpnt->proc_name = "eata_dma"; status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA); dma_scratch = scsi_init_malloc(1024, GFP_ATOMIC | GFP_DMA); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c --- v2.3.26/linux/drivers/scsi/eata_pio.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/eata_pio.c Thu Nov 11 16:57:30 1999 @@ -58,11 +58,6 @@ #include #include -struct proc_dir_entry proc_scsi_eata_pio = { - PROC_SCSI_EATA_PIO, 9, "eata_pio", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - static uint ISAbases[MAXISA] = {0x1F0, 0x170, 0x330, 0x230}; static uint ISAirqs[MAXISA] = @@ -946,7 +941,7 @@ DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, printk("Using lots of delays to let you read the debugging output\n")); - tpnt->proc_dir = &proc_scsi_eata_pio; + tpnt->proc_name = "eata_pio"; find_pio_PCI(&gc, tpnt); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/esp.c linux/drivers/scsi/esp.c --- v2.3.26/linux/drivers/scsi/esp.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/esp.c Thu Nov 11 16:57:30 1999 @@ -173,11 +173,6 @@ /*5*/ do_intr_end }; -struct proc_dir_entry proc_scsi_esp = { - PROC_SCSI_ESP, 3, "esp", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* The master ring of all esp hosts we are managing in this driver. */ static struct Sparc_ESP *espchain; static int esps_running = 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/esp.h linux/drivers/scsi/esp.h --- v2.3.26/linux/drivers/scsi/esp.h Wed Aug 18 16:44:24 1999 +++ linux/drivers/scsi/esp.h Thu Nov 11 17:03:50 1999 @@ -414,10 +414,8 @@ extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); -extern struct proc_dir_entry proc_scsi_esp; - #define SCSI_SPARC_ESP { \ - proc_dir: &proc_scsi_esp, \ + proc_name: "esp", \ proc_info: &esp_proc_info, \ name: "Sun ESP 100/100a/200", \ detect: esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/fastlane.h linux/drivers/scsi/fastlane.h --- v2.3.26/linux/drivers/scsi/fastlane.h Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/fastlane.h Thu Nov 11 16:57:30 1999 @@ -48,7 +48,7 @@ extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); -#define SCSI_FASTLANE { proc_dir: &proc_scsi_esp, \ +#define SCSI_FASTLANE { proc_name: "esp-fastlane", \ proc_info: esp_proc_info, \ name: "Fastlane SCSI", \ detect: fastlane_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/fcal.c linux/drivers/scsi/fcal.c --- v2.3.26/linux/drivers/scsi/fcal.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/scsi/fcal.c Thu Nov 11 16:57:30 1999 @@ -68,11 +68,6 @@ 0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17, 0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00 }; -struct proc_dir_entry proc_scsi_fcal = { - PROC_SCSI_FCAL, 4, "fcal", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); static void fcal_select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) @@ -97,7 +92,7 @@ int fcalcount; int i; - tpnt->proc_dir = &proc_scsi_fcal; + tpnt->proc_name = "fcal"; fcalcount = 0; for_each_online_fc_channel(fc) if (fc->posmap) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/fd_mcs.c linux/drivers/scsi/fd_mcs.c --- v2.3.26/linux/drivers/scsi/fd_mcs.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/fd_mcs.c Thu Nov 11 16:57:30 1999 @@ -98,11 +98,6 @@ #include "fd_mcs.h" #define DRIVER_VERSION "v0.2 by ZP Gu" - -struct proc_dir_entry proc_scsi_fd_mcs = { - PROC_SCSI_FD_MCS, 6, "fd_mcs", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; /* START OF USER DEFINABLE OPTIONS */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/fd_mcs.h linux/drivers/scsi/fd_mcs.h --- v2.3.26/linux/drivers/scsi/fd_mcs.h Sun Nov 8 13:50:47 1998 +++ linux/drivers/scsi/fd_mcs.h Thu Nov 11 16:57:30 1999 @@ -32,10 +32,8 @@ extern int fd_mcs_proc_info( char *, char **, off_t, int, int, int ); extern const char *fd_mcs_info(struct Scsi_Host *); -extern struct proc_dir_entry proc_scsi_fd_mcs; - #define FD_MCS {\ - proc_dir: &proc_scsi_fd_mcs, \ + proc_name: "fd_mcs", \ proc_info: fd_mcs_proc_info, \ detect: fd_mcs_detect, \ release: fd_mcs_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c --- v2.3.26/linux/drivers/scsi/fdomain.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/fdomain.c Thu Nov 11 16:57:30 1999 @@ -274,9 +274,7 @@ #define MODULE #endif -#ifdef MODULE #include -#endif #ifdef PCMCIA #undef MODULE @@ -299,11 +297,6 @@ #include #include /* for CONFIG_PCI */ - -struct proc_dir_entry proc_scsi_fdomain = { - PROC_SCSI_FDOMAIN, 7, "fdomain", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; #define VERSION "$Revision: 5.50 $" @@ -884,7 +877,7 @@ unsigned char buf[buflen]; #endif - tpnt->proc_dir = &proc_scsi_fdomain; + tpnt->proc_name = "fdomain"; #ifdef MODULE if (fdomain[0] || fdomain[1] || fdomain[2]) { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/fdomain.h linux/drivers/scsi/fdomain.h --- v2.3.26/linux/drivers/scsi/fdomain.h Thu Jun 4 15:52:21 1998 +++ linux/drivers/scsi/fdomain.h Thu Nov 11 16:57:30 1999 @@ -35,8 +35,6 @@ int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset, int length, int hostno, int inout ); -extern struct proc_dir_entry proc_scsi_fdomain; - #define FDOMAIN_16X0 { proc_info: fdomain_16x0_proc_info, \ detect: fdomain_16x0_detect, \ info: fdomain_16x0_info, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c --- v2.3.26/linux/drivers/scsi/g_NCR5380.c Mon Aug 9 10:25:01 1999 +++ linux/drivers/scsi/g_NCR5380.c Thu Nov 11 16:57:30 1999 @@ -119,11 +119,6 @@ #include #include -struct proc_dir_entry proc_scsi_g_ncr5380 = { - PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define NCR_NOT_SET 0 static int ncr_irq=NCR_NOT_SET; static int ncr_dma=NCR_NOT_SET; @@ -285,7 +280,7 @@ else if (dtc_3181e != NCR_NOT_SET) overrides[0].board=BOARD_DTC3181E; - tpnt->proc_dir = &proc_scsi_g_ncr5380; + tpnt->proc_name = "g_NCR5380"; for (count = 0; current_override < NO_OVERRIDES; ++current_override) { if (!(overrides[current_override].NCR5380_map_name)) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c --- v2.3.26/linux/drivers/scsi/gdth.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/gdth.c Thu Nov 11 16:57:30 1999 @@ -181,24 +181,13 @@ #include #include #include -#if LINUX_VERSION_CODE >= 0x020100 #include -#else -#include -#endif #include #include #include -#if LINUX_VERSION_CODE >= 0x02015F #include -#endif - -#if LINUX_VERSION_CODE >= 0x010300 #include -#else -#include "../block/blk.h" -#endif #include "scsi.h" #include "hosts.h" #include "sd.h" @@ -207,11 +196,7 @@ static void gdth_delay(int milliseconds); static void gdth_eval_mapping(ulong32 size, int *cyls, int *heads, int *secs); -#if LINUX_VERSION_CODE >= 0x010346 static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs); -#else -static void gdth_interrupt(int irq,struct pt_regs *regs); -#endif static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp); static int gdth_async_event(int hanum,int service); static void gdth_log_event(gdth_evt_data *dvr, char *buffer); @@ -254,15 +239,8 @@ static const char *gdth_ctr_name(int hanum); -#if LINUX_VERSION_CODE >= 0x010300 static void gdth_flush(int hanum); -#if LINUX_VERSION_CODE >= 0x020100 static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); -#else -static int halt_called = FALSE; -void gdth_halt(void); -#endif -#endif #ifdef DEBUG_GDTH static unchar DebugState = DEBUG_GDTH; @@ -363,64 +341,6 @@ #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) -#if LINUX_VERSION_CODE < 0x010300 -static void *gdth_mmap(ulong paddr, ulong size) -{ - if (paddr >= high_memory) - return NULL; - else - return (void *)paddr; -} -static void gdth_munmap(void *addr) -{ -} -inline ulong32 virt_to_phys(volatile void *addr) -{ - return (ulong32)addr; -} -inline void *phys_to_virt(ulong32 addr) -{ - return (void *)addr; -} -#define virt_to_bus virt_to_phys -#define bus_to_virt phys_to_virt -#define gdth_readb(addr) (*(volatile unchar *)(addr)) -#define gdth_readw(addr) (*(volatile ushort *)(addr)) -#define gdth_readl(addr) (*(volatile ulong32 *)(addr)) -#define gdth_writeb(b,addr) (*(volatile unchar *)(addr) = (b)) -#define gdth_writew(b,addr) (*(volatile ushort *)(addr) = (b)) -#define gdth_writel(b,addr) (*(volatile ulong32 *)(addr) = (b)) -#define memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) - -#define PCI_SLOT(devfn) ((devfn >> 3) & 0x1f) - -#elif LINUX_VERSION_CODE < 0x020100 -static int remapped = FALSE; -static void *gdth_mmap(ulong paddr, ulong size) -{ - if ( paddr >= high_memory) { - remapped = TRUE; - return vremap(paddr, size); - } else { - return (void *)paddr; - } -} -static void gdth_munmap(void *addr) -{ - if (remapped) - vfree(addr); - remapped = FALSE; -} -#define gdth_readb(addr) readb((ulong)(addr)) -#define gdth_readw(addr) readw((ulong)(addr)) -#define gdth_readl(addr) (ulong32)readl((ulong)(addr)) -#define gdth_writeb(b,addr) writeb((b),(ulong)(addr)) -#define gdth_writew(b,addr) writew((b),(ulong)(addr)) -#define gdth_writel(b,addr) writel((b),(ulong)(addr)) - -#else static void *gdth_mmap(ulong paddr, ulong size) { return ioremap(paddr, size); @@ -435,8 +355,6 @@ #define gdth_writeb(b,addr) writeb((b),(ulong)(addr)) #define gdth_writew(b,addr) writew((b),(ulong)(addr)) #define gdth_writel(b,addr) writel((b),(ulong)(addr)) -#endif - static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ @@ -477,15 +395,8 @@ }; /* __initfunc, __initdata macros */ -#if LINUX_VERSION_CODE >= 0x020126 #include -#else -#define __initfunc(A) A -#define __initdata -#define __init -#endif -#if LINUX_VERSION_CODE >= 0x02015F #define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock) #define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags) #define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags) @@ -494,16 +405,6 @@ #define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(&io_request_lock,flags) #define GDTH_LOCK_SCSI_DOCMD() spin_lock_irq(&io_request_lock) #define GDTH_UNLOCK_SCSI_DOCMD() spin_unlock_irq(&io_request_lock) -#else -#define GDTH_INIT_LOCK_HA(ha) do {} while (0) -#define GDTH_LOCK_HA(ha,flags) do {save_flags(flags); cli();} while (0) -#define GDTH_UNLOCK_HA(ha,flags) do {restore_flags(flags);} while (0) - -#define GDTH_LOCK_SCSI_DONE(flags) do {} while (0) -#define GDTH_UNLOCK_SCSI_DONE(flags) do {} while (0) -#define GDTH_LOCK_SCSI_DOCMD() do {} while (0) -#define GDTH_UNLOCK_SCSI_DOCMD() do {} while (0) -#endif /* LILO and modprobe/insmod parameters */ /* IRQ list for GDT3000/3020 EISA controllers */ @@ -529,7 +430,6 @@ static int rescan = 0; #ifdef MODULE -#if LINUX_VERSION_CODE >= 0x02011A /* parameters for modprobe/insmod */ MODULE_PARM(irq, "i"); MODULE_PARM(disable, "i"); @@ -541,39 +441,23 @@ MODULE_PARM(rescan, "i"); MODULE_AUTHOR("Achim Leubner"); #endif -#endif /* /proc support */ -#if LINUX_VERSION_CODE >= 0x010300 #include -struct proc_dir_entry proc_scsi_gdth = { - PROC_SCSI_GDTH, 4, "gdth", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; #include "gdth_proc.h" #include "gdth_proc.c" -#endif -#if LINUX_VERSION_CODE >= 0x020100 /* notifier block to get a notify on system shutdown/halt/reboot */ static struct notifier_block gdth_notifier = { gdth_halt, NULL, 0 }; -#endif - static void gdth_delay(int milliseconds) { if (milliseconds == 0) { udelay(1); } else { -#if LINUX_VERSION_CODE >= 0x020168 mdelay(milliseconds); -#else - int i; - for (i = 0; i < milliseconds; ++i) - udelay(1000); -#endif } } @@ -636,12 +520,7 @@ { ulong32 base0, base1, base2; ushort device_id, cnt; -#if LINUX_VERSION_CODE >= 0x2015C struct pci_dev *pdev; -#else - int error; - ushort idx; -#endif TRACE(("gdth_search_pci()\n")); @@ -1099,13 +978,8 @@ continue; } gdth_munmap(ha->brd); -#if LINUX_VERSION_CODE >= 0x2015C pci_write_config_dword(pcistr->pdev, PCI_BASE_ADDRESS_0, i); -#else - pcibios_write_config_dword(pcistr->bus, pcistr->device_fn, - PCI_BASE_ADDRESS_0, i); -#endif ha->brd = gdth_mmap(i, sizeof(gdt6m_dpram_str)); if (ha->brd == NULL) { printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); @@ -1436,11 +1310,7 @@ gdth_from_wait = TRUE; do { -#if LINUX_VERSION_CODE >= 0x010346 gdth_interrupt((int)ha->irq,ha,NULL); -#else - gdth_interrupt((int)ha->irq,NULL); -#endif if (wait_hanum==hanum && wait_index==index) { answer_found = TRUE; break; @@ -1821,13 +1691,8 @@ GDTH_LOCK_HA(ha, flags); scp->SCp.this_residual = (int)priority; -#if LINUX_VERSION_CODE >= 0x020000 b = scp->channel; -#else - b = NUMDATA(nscp->host)->busnum; -#endif t = scp->target; -#if LINUX_VERSION_CODE >= 0x010300 if (priority >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) { @@ -1835,7 +1700,6 @@ scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); } } -#endif if (ha->req_first==NULL) { ha->req_first = scp; /* queue was empty */ @@ -1886,11 +1750,7 @@ for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) pscp = (Scsi_Cmnd *)pscp->SCp.ptr; -#if LINUX_VERSION_CODE >= 0x020000 b = nscp->channel; -#else - b = NUMDATA(nscp->host)->busnum; -#endif t = nscp->target; if (nscp->SCp.this_residual >= DEFAULT_PRI) { if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || @@ -1911,9 +1771,7 @@ firsttime = FALSE; } -#if LINUX_VERSION_CODE >= 0x010300 if (nscp->done != gdth_scsi_done) -#endif { if (nscp->SCp.phase == -1) { nscp->SCp.phase = SCSIRAWSERVICE; /* default: raw svc. */ @@ -1958,13 +1816,11 @@ } } else -#if LINUX_VERSION_CODE >= 0x010300 if (nscp->done == gdth_scsi_done) { if (!(cmd_index=gdth_special_cmd(hanum,nscp))) this_cmd = FALSE; next_cmd = FALSE; } else -#endif if (b != ha->virt_bus) { if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || !(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) @@ -2591,11 +2447,7 @@ /* SCSI interface functions */ -#if LINUX_VERSION_CODE >= 0x010346 static void gdth_interrupt(int irq,void *dev_id,struct pt_regs *regs) -#else -static void gdth_interrupt(int irq,struct pt_regs *regs) -#endif { register gdth_ha_str *ha; gdt6m_dpram_str *dp6m_ptr; @@ -2913,9 +2765,7 @@ scp->sense_buffer[2] = NOT_READY; scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); -#if LINUX_VERSION_CODE >= 0x010300 if (scp->done != gdth_scsi_done) -#endif { dvr.size = sizeof(dvr.eu.sync); dvr.eu.sync.ionode = hanum; @@ -3282,11 +3132,7 @@ printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", isa_bios,ha->irq,ha->drq); -#if LINUX_VERSION_CODE >= 0x010346 if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha)) -#else - if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth")) -#endif { printk("GDT-ISA: Unable to allocate IRQ\n"); scsi_unregister(shp); @@ -3294,11 +3140,7 @@ } if (request_dma(ha->drq,"gdth")) { printk("GDT-ISA: Unable to allocate DMA channel\n"); -#if LINUX_VERSION_CODE >= 0x010346 free_irq(ha->irq,NULL); -#else - free_irq(ha->irq); -#endif scsi_unregister(shp); continue; } @@ -3331,11 +3173,7 @@ --gdth_ctr_vcount; if (ha->pscratch != NULL) scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); -#if LINUX_VERSION_CODE >= 0x010346 free_irq(ha->irq,NULL); -#else - free_irq(ha->irq); -#endif scsi_unregister(shp); continue; } @@ -3343,22 +3181,9 @@ hdr_channel = ha->bus_cnt; ha->virt_bus = hdr_channel; -#if LINUX_VERSION_CODE >= 0x020000 shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; shp->max_channel = ha->bus_cnt; -#else - /* register addit. SCSI channels as virtual controllers */ - for (b=1; bbus_cnt+1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 1; - shp->irq = ha->irq; - shp->dma_channel = ha->drq; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } -#endif GDTH_INIT_LOCK_HA(ha); gdth_enable_int(hanum); } @@ -3379,11 +3204,7 @@ printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", eisa_slot>>12,ha->irq); -#if LINUX_VERSION_CODE >= 0x010346 if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth",ha)) -#else - if (request_irq(ha->irq,gdth_interrupt,SA_INTERRUPT,"gdth")) -#endif { printk("GDT-EISA: Unable to allocate IRQ\n"); scsi_unregister(shp); @@ -3418,11 +3239,7 @@ --gdth_ctr_vcount; if (ha->pscratch != NULL) scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); -#if LINUX_VERSION_CODE >= 0x010346 free_irq(ha->irq,NULL); -#else - free_irq(ha->irq); -#endif scsi_unregister(shp); continue; } @@ -3430,36 +3247,16 @@ hdr_channel = ha->bus_cnt; ha->virt_bus = hdr_channel; -#if LINUX_VERSION_CODE >= 0x020000 shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; shp->max_channel = ha->bus_cnt; -#else - /* register addit. SCSI channels as virtual controllers */ - for (b=1; bbus_cnt+1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - TRACE2(("EISA detect Bus %d: shp %x hanum %d\n", - NUMDATA(shp)->busnum,(ulong32)shp, - NUMDATA(shp)->hanum)); - } -#endif GDTH_INIT_LOCK_HA(ha); gdth_enable_int(hanum); } } /* scanning for PCI controllers */ -#if LINUX_VERSION_CODE >= 0x2015C if (pci_present()) -#else - if (pcibios_present()) -#endif { gdth_pci_str pcistr[MAXHA]; @@ -3478,13 +3275,8 @@ printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", pcistr[ctr].bus,PCI_SLOT(pcistr[ctr].device_fn),ha->irq); -#if LINUX_VERSION_CODE >= 0x010346 if (request_irq(ha->irq, gdth_interrupt, SA_INTERRUPT|SA_SHIRQ, "gdth", ha)) -#else - if (request_irq(ha->irq, gdth_interrupt, - SA_INTERRUPT|SA_SHIRQ, "gdth")) -#endif { printk("GDT-PCI: Unable to allocate IRQ\n"); scsi_unregister(shp); @@ -3517,11 +3309,7 @@ --gdth_ctr_vcount; if (ha->pscratch != NULL) scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH); -#if LINUX_VERSION_CODE >= 0x010346 free_irq(ha->irq,NULL); -#else - free_irq(ha->irq); -#endif scsi_unregister(shp); continue; } @@ -3529,22 +3317,9 @@ hdr_channel = ha->bus_cnt; ha->virt_bus = hdr_channel; -#if LINUX_VERSION_CODE >= 0x020000 shp->max_id = ha->tid_cnt; shp->max_lun = MAXLUN; shp->max_channel = ha->bus_cnt; -#else - /* register addit. SCSI channels as virtual controllers */ - for (b=1; bbus_cnt+1; ++b) { - shp = scsi_register(shtp,sizeof(gdth_num_str)); - shp->unchecked_isa_dma = 0; - shp->irq = ha->irq; - shp->dma_channel = 0xff; - gdth_ctr_vtab[gdth_ctr_vcount++] = shp; - NUMDATA(shp)->hanum = (ushort)hanum; - NUMDATA(shp)->busnum = b; - } -#endif GDTH_INIT_LOCK_HA(ha); gdth_enable_int(hanum); } @@ -3560,9 +3335,7 @@ gdth_timer.function = gdth_timeout; add_timer(&gdth_timer); #endif -#if LINUX_VERSION_CODE >= 0x020100 register_reboot_notifier(&gdth_notifier); -#endif } gdth_polling = FALSE; return gdth_ctr_vcount; @@ -3578,16 +3351,10 @@ if (NUMDATA(shp)->busnum == 0) { hanum = NUMDATA(shp)->hanum; ha = HADATA(gdth_ctr_tab[hanum]); -#if LINUX_VERSION_CODE >= 0x010300 gdth_flush(hanum); -#endif if (shp->irq) { -#if LINUX_VERSION_CODE >= 0x010346 free_irq(shp->irq,NULL); -#else - free_irq(shp->irq); -#endif } if (shp->dma_channel != 0xff) { free_dma(shp->dma_channel); @@ -3601,9 +3368,7 @@ #ifdef GDTH_STATISTICS del_timer(&gdth_timer); #endif -#if LINUX_VERSION_CODE >= 0x020100 unregister_reboot_notifier(&gdth_notifier); -#endif } } @@ -3663,17 +3428,12 @@ return SCSI_ABORT_SNOOZE; } -#if LINUX_VERSION_CODE >= 0x010346 int gdth_reset(Scsi_Cmnd *scp, unsigned int reset_flags) -#else -int gdth_reset(Scsi_Cmnd *scp) -#endif { TRACE2(("gdth_reset()\n")); return SCSI_RESET_PUNT; } -#if LINUX_VERSION_CODE >= 0x02015F /* new error handling */ int gdth_eh_abort(Scsi_Cmnd *scp) { @@ -3723,13 +3483,8 @@ TRACE2(("gdth_eh_host_reset()\n")); return FAILED; } -#endif -#if LINUX_VERSION_CODE >= 0x010300 int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) -#else -int gdth_bios_param(Disk *disk,int dev,int *ip) -#endif { unchar t; int hanum; @@ -3793,17 +3548,14 @@ #endif priority = DEFAULT_PRI; -#if LINUX_VERSION_CODE >= 0x010300 if (scp->done == gdth_scsi_done) priority = scp->SCp.this_residual; -#endif gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); gdth_putq( hanum, scp, priority ); gdth_next( hanum ); return 0; } -#if LINUX_VERSION_CODE >= 0x010300 /* flush routine */ static void gdth_flush(int hanum) { @@ -3840,11 +3592,7 @@ } /* shutdown routine */ -#if LINUX_VERSION_CODE >= 0x020100 static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) -#else -void gdth_halt(void) -#endif { int hanum; #ifndef __alpha__ @@ -3853,18 +3601,9 @@ gdth_cmd_str gdtcmd; #endif -#if LINUX_VERSION_CODE >= 0x020100 TRACE2(("gdth_halt() event %d\n",event)); if (event != SYS_RESTART && event != SYS_HALT && event != SYS_POWER_OFF) return NOTIFY_DONE; -#else - TRACE2(("gdth_halt()\n")); - if (halt_called) { - TRACE2(("already called\n")); - return; - } - halt_called = TRUE; -#endif printk("GDT: Flushing all host drives .. "); for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { gdth_flush(hanum); @@ -3893,13 +3632,9 @@ #ifdef GDTH_STATISTICS del_timer(&gdth_timer); #endif -#if LINUX_VERSION_CODE >= 0x020100 unregister_reboot_notifier(&gdth_notifier); return NOTIFY_OK; -#endif } -#endif - /* called from init/main.c */ void __init gdth_setup(char *str,int *ints) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/gdth.h linux/drivers/scsi/gdth.h --- v2.3.26/linux/drivers/scsi/gdth.h Wed Aug 18 16:44:26 1999 +++ linux/drivers/scsi/gdth.h Thu Nov 11 17:03:50 1999 @@ -814,9 +814,7 @@ /* PCI resources */ typedef struct { -#if LINUX_VERSION_CODE >= 0x02015C struct pci_dev *pdev; -#endif ushort device_id; /* device ID (0,..,9) */ unchar bus; /* PCI bus */ unchar device_fn; /* PCI device/function no. */ @@ -888,9 +886,7 @@ gdth_cpar_str cpar; /* controller cache par. */ gdth_bfeat_str bfeat; /* controller features */ gdth_binfo_str binfo; /* controller info */ -#if LINUX_VERSION_CODE >= 0x02015F spinlock_t smp_lock; -#endif } gdth_ha_str; /* structure for scsi_register(), SCSI bus != 0 */ @@ -971,22 +967,16 @@ int gdth_command(Scsi_Cmnd *); int gdth_queuecommand(Scsi_Cmnd *,void (*done)(Scsi_Cmnd *)); int gdth_abort(Scsi_Cmnd *); -#if LINUX_VERSION_CODE >= 0x010346 int gdth_reset(Scsi_Cmnd *, unsigned int reset_flags); -#else -int gdth_reset(Scsi_Cmnd *); -#endif const char *gdth_info(struct Scsi_Host *); -#if LINUX_VERSION_CODE >= 0x02015F int gdth_bios_param(Disk *,kdev_t,int *); -extern struct proc_dir_entry proc_scsi_gdth; int gdth_proc_info(char *,char **,off_t,int,int,int); int gdth_eh_abort(Scsi_Cmnd *scp); int gdth_eh_device_reset(Scsi_Cmnd *scp); int gdth_eh_bus_reset(Scsi_Cmnd *scp); int gdth_eh_host_reset(Scsi_Cmnd *scp); -#define GDTH { proc_dir: &proc_scsi_gdth, \ +#define GDTH { proc_name: "gdth", \ proc_info: gdth_proc_info, \ name: "GDT SCSI Disk Array Controller",\ detect: gdth_detect, \ @@ -1009,51 +999,5 @@ unchecked_isa_dma: 1, \ use_clustering: ENABLE_CLUSTERING, \ use_new_eh_code: 1 /* use new error code */ } -#elif LINUX_VERSION_CODE >= 0x010300 -int gdth_bios_param(Disk *,kdev_t,int *); -extern struct proc_dir_entry proc_scsi_gdth; -int gdth_proc_info(char *,char **,off_t,int,int,int); -#define GDTH { NULL, NULL, \ - &proc_scsi_gdth, \ - gdth_proc_info, \ - "GDT SCSI Disk Array Controller", \ - gdth_detect, \ - gdth_release, \ - gdth_info, \ - gdth_command, \ - gdth_queuecommand, \ - gdth_abort, \ - gdth_reset, \ - NULL, \ - gdth_bios_param, \ - GDTH_MAXCMDS, \ - -1, \ - GDTH_MAXSG, \ - GDTH_MAXC_P_L, \ - 0, \ - 1, \ - ENABLE_CLUSTERING} -#else -int gdth_bios_param(Disk *,int,int *); -#define GDTH { NULL, NULL, \ - "GDT SCSI Disk Array Controller", \ - gdth_detect, \ - gdth_release, \ - gdth_info, \ - gdth_command, \ - gdth_queuecommand, \ - gdth_abort, \ - gdth_reset, \ - NULL, \ - gdth_bios_param, \ - GDTH_MAXCMDS, \ - -1, \ - GDTH_MAXSG, \ - GDTH_MAXC_P_L, \ - 0, \ - 1, \ - ENABLE_CLUSTERING} -#endif - #endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/gvp11.c linux/drivers/scsi/gvp11.c --- v2.3.26/linux/drivers/scsi/gvp11.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/gvp11.c Thu Nov 11 16:57:30 1999 @@ -21,11 +21,6 @@ #include -struct proc_dir_entry proc_scsi_gvp11 = { - PROC_SCSI_GVP11, 5, "GVP11", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define DMA(ptr) ((gvp11_scsiregs *)((ptr)->base)) #define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata)) @@ -200,7 +195,7 @@ return 0; called = 1; - tpnt->proc_dir = &proc_scsi_gvp11; + tpnt->proc_name = "GVP11"; tpnt->proc_info = &wd33c93_proc_info; while (1) { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/gvp11.h linux/drivers/scsi/gvp11.h --- v2.3.26/linux/drivers/scsi/gvp11.h Sun Dec 27 22:19:11 1998 +++ linux/drivers/scsi/gvp11.h Thu Nov 11 16:57:30 1999 @@ -32,9 +32,7 @@ #ifdef HOSTS_C -extern struct proc_dir_entry proc_scsi_gvp11; - -#define GVP11_SCSI { proc_dir: &proc_scsi_gvp11, \ +#define GVP11_SCSI { proc_name: "GVP11", \ name: "GVP Series II SCSI", \ detect: gvp11_detect, \ release: gvp11_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.3.26/linux/drivers/scsi/hosts.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/hosts.c Thu Nov 11 16:57:30 1999 @@ -107,12 +107,12 @@ #include "atari_scsi.h" #endif -#ifdef CONFIG_MAC_SCSI_OLD +#if defined(CONFIG_MAC_SCSI) || defined(CONFIG_MAC_SCSI_OLD) #include "mac_scsi.h" #endif -#ifdef CONFIG_MAC_SCSI -#include "mac_scsinew.h" +#ifdef CONFIG_SUN3_SCSI +#include "sun3_scsi.h" #endif #ifdef CONFIG_SCSI_MAC_ESP @@ -445,6 +445,10 @@ #endif #endif +#ifdef CONFIG_SUN3_SCSI + SUN3_NCR5380, +#endif + #ifdef CONFIG_MVME16x_SCSI MVME16x_SCSI, #endif @@ -699,6 +703,8 @@ retval->loaded_as_module = scsi_loadable_module_flag; retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */ next_scsi_host++; + /* FIXME: what with overflows? Old code suffered from the same, BTW */ + sprintf(retval->proc_name, "%d", retval->host_no); retval->host_queue = NULL; init_waitqueue_head(&retval->host_wait); retval->resetting = 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h --- v2.3.26/linux/drivers/scsi/hosts.h Wed Aug 18 16:44:17 1999 +++ linux/drivers/scsi/hosts.h Thu Nov 11 17:03:43 1999 @@ -277,6 +277,11 @@ */ unsigned emulated:1; + /* + * Name of proc directory + */ + char *proc_name; + } Scsi_Host_Template; /* @@ -322,6 +327,7 @@ /* public: */ unsigned short extra_bytes; unsigned short host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ + char proc_name[4]; int resetting; /* if set, it means that last_reset is a valid value */ unsigned long last_reset; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ibmmca.c linux/drivers/scsi/ibmmca.c --- v2.3.26/linux/drivers/scsi/ibmmca.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/scsi/ibmmca.c Thu Nov 11 16:57:30 1999 @@ -275,15 +275,6 @@ {0x8efe, "IBM SCSI Adapter"}, /* special = 4 */ }; -/*for /proc filesystem */ -struct proc_dir_entry proc_scsi_ibmmca = -{ - PROC_SCSI_IBMMCA, 6, "ibmmca", - S_IFDIR | S_IRUGO | S_IXUGO, 2, - 0, 0, 0, NULL, NULL, NULL, NULL, - NULL, NULL, NULL -}; - /* Max number of logical devices (can be up from 0 to 14). 15 is the address of the adapter itself. */ #define MAX_LOG_DEV 15 diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ibmmca.h linux/drivers/scsi/ibmmca.h --- v2.3.26/linux/drivers/scsi/ibmmca.h Wed Aug 18 16:44:21 1999 +++ linux/drivers/scsi/ibmmca.h Thu Nov 11 17:03:48 1999 @@ -27,11 +27,7 @@ extern int ibmmca_biosparam (Disk *, kdev_t, int *); /*structure for /proc filesystem */ -extern struct proc_dir_entry proc_scsi_ibmmca; -#if LINUX_VERSION_CODE >= ibmmca_header_linux_version(2,1,0) -/* Stuff for Linux >= 2.1.0: */ -/*initialization for Scsi_host_template type (Linux >= 2.1.0) */ /* * 2/8/98 * Note to maintainer of IBMMCA. Do not change this initializer back to @@ -39,7 +35,7 @@ * about this, but it will break things in the future. */ #define IBMMCA { \ - proc_dir: &proc_scsi_ibmmca, /*proc_dir*/ \ + proc_name: "ibmmca", /*proc_name*/ \ proc_info: ibmmca_proc_info, /*proc info fn*/ \ name: "IBM SCSI-Subsystem", /*name*/ \ detect: ibmmca_detect, /*detect fn*/ \ @@ -56,34 +52,5 @@ unchecked_isa_dma: 0, /*32-Bit Busmaster */ \ use_clustering: ENABLE_CLUSTERING /*use_clustering*/ \ } - -#else -/* Stuff for Linux < 2.1.0: */ - -/*initialization for Scsi_host_template type (Linux < 2.1.0) */ -#define IBMMCA { \ - NULL, /*next*/ \ - NULL, /*usage_count*/ \ - &proc_scsi_ibmmca, /*proc_dir*/ \ - ibmmca_proc_info, /*proc info fn*/ \ - "IBM SCSI-Subsystem", /*name*/ \ - ibmmca_detect, /*detect fn*/ \ - ibmmca_release, /*release fn*/ \ - NULL, /*info fn*/ \ - ibmmca_command, /*command fn*/ \ - ibmmca_queuecommand, /*queuecommand fn*/ \ - ibmmca_abort, /*abort fn*/ \ - ibmmca_reset, /*reset fn*/ \ - NULL, /*slave_attach fn*/ \ - ibmmca_biosparam, /*bios fn*/ \ - 16, /*can_queue*/ \ - 7, /*set by detect*/ \ - 16, /*sg_tablesize*/ \ - 1, /*cmd_per_lun*/ \ - 0, /*present*/ \ - 0, /*unchecked_isa_dma*/ \ - ENABLE_CLUSTERING /*use_clustering*/ \ - } -#endif /* kernelversion selection */ #endif /* _IBMMCA_H */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c --- v2.3.26/linux/drivers/scsi/ide-scsi.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/scsi/ide-scsi.c Thu Nov 11 16:57:30 1999 @@ -558,8 +558,6 @@ NULL }; -static struct proc_dir_entry idescsi_proc_dir = {PROC_SCSI_IDESCSI, 8, "ide-scsi", S_IFDIR | S_IRUGO | S_IXUGO, 2}; - /* * idescsi_init will register the driver for each scsi. */ @@ -603,7 +601,7 @@ struct Scsi_Host *host; int id; - host_template->proc_dir = &idescsi_proc_dir; + host_template->proc_name = "ide-scsi"; host = scsi_register(host_template, 0); for (id = 0; id < MAX_HWIFS * MAX_DRIVES && idescsi_drives[id]; id++); host->max_id = id; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/imm.h linux/drivers/scsi/imm.h --- v2.3.26/linux/drivers/scsi/imm.h Wed Aug 18 16:45:00 1999 +++ linux/drivers/scsi/imm.h Thu Nov 11 17:04:13 1999 @@ -146,10 +146,7 @@ static void imm_interrupt(void *); static int imm_out(int, char *, int); -struct proc_dir_entry proc_scsi_imm = -{PROC_SCSI_PPA, 3, "imm", S_IFDIR | S_IRUGO | S_IXUGO, 2}; #else -extern struct proc_dir_entry proc_scsi_imm; #define imm_release 0 #endif @@ -162,7 +159,7 @@ int imm_proc_info(char *, char **, off_t, int, int, int); int imm_biosparam(Disk *, kdev_t, int *); -#define IMM { proc_dir: &proc_scsi_imm, \ +#define IMM { proc_name: "imm", \ proc_info: imm_proc_info, \ name: "Iomega VPI2 (imm) interface",\ detect: imm_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c --- v2.3.26/linux/drivers/scsi/in2000.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/scsi/in2000.c Thu Nov 11 16:57:30 1999 @@ -2023,7 +2023,7 @@ * initialize it. */ - tpnt->proc_dir = &proc_scsi_in2000; /* done more than once? harmless. */ + tpnt->proc_name = "in2000"; detect_count++; instance = scsi_register(tpnt, sizeof(struct IN2000_hostdata)); if (!instance_list) @@ -2186,13 +2186,6 @@ } return 0; } - - - -struct proc_dir_entry proc_scsi_in2000 = { - PROC_SCSI_IN2000, 6, "in2000", - S_IFDIR | S_IRUGO | S_IXUGO, 2 - }; int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/in2000.h linux/drivers/scsi/in2000.h --- v2.3.26/linux/drivers/scsi/in2000.h Mon Oct 4 15:49:29 1999 +++ linux/drivers/scsi/in2000.h Thu Nov 11 17:03:46 1999 @@ -384,13 +384,6 @@ #include -#if LINUX_VERSION_CODE < 0x020100 /* 2.0.xx */ -# define in2000__INITFUNC(function) function -# define in2000__INIT -# define in2000__INITDATA -# define CLISPIN_LOCK(flags) do { save_flags(flags); cli(); } while(0) -# define CLISPIN_UNLOCK(flags) restore_flags(flags) -#else /* 2.1.xxx */ # include # include # define in2000__INITFUNC(function) __initfunc(function) @@ -398,15 +391,12 @@ # define in2000__INITDATA __initdata # define CLISPIN_LOCK(flags) spin_lock_irqsave(&io_request_lock, flags) # define CLISPIN_UNLOCK(flags) spin_unlock_irqrestore(&io_request_lock, flags) -#endif - int in2000_detect(Scsi_Host_Template *) in2000__INIT; int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int in2000_abort(Scsi_Cmnd *); void in2000_setup(char *, int *) in2000__INIT; int in2000_proc_info(char *, char **, off_t, int, int, int); -struct proc_dir_entry proc_scsi_in2000; int in2000_biosparam(struct scsi_disk *, kdev_t, int *); int in2000_reset(Scsi_Cmnd *, unsigned int); @@ -416,34 +406,7 @@ #define IN2000_CPL 2 #define IN2000_HOST_ID 7 -#if LINUX_VERSION_CODE < 0x020100 /* 2.0.xx */ - -#define IN2000 { NULL, /* link pointer for modules */ \ - NULL, /* usage_count for modules */ \ - &proc_scsi_in2000, /* pointer to /proc/scsi directory entry */ \ - in2000_proc_info, /* pointer to proc info function */ \ - "Always IN2000", /* device name */ \ - in2000_detect, /* returns number of in2000's found */ \ - NULL, /* optional unload function for modules */ \ - NULL, /* optional misc info function */ \ - NULL, /* send scsi command, wait for completion */ \ - in2000_queuecommand, /* queue scsi command, don't wait */ \ - in2000_abort, /* abort current command */ \ - in2000_reset, /* reset scsi bus */ \ - NULL, /* slave_attach - unused */ \ - in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \ - IN2000_CAN_Q, /* max commands we can queue up */ \ - IN2000_HOST_ID, /* host-adapter scsi id */ \ - IN2000_SG, /* scatter-gather table size */ \ - IN2000_CPL, /* commands per lun */ \ - 0, /* board counter */ \ - 0, /* unchecked dma */ \ - DISABLE_CLUSTERING \ - } - -#else /* 2.1.xxx */ - -#define IN2000 { proc_dir: &proc_scsi_in2000, /* pointer to /proc/scsi directory entry */ \ +#define IN2000 { proc_name: "in2000", /* name of /proc/scsi directory entry */ \ proc_info: in2000_proc_info, /* pointer to proc info function */ \ name: "Always IN2000", /* device name */ \ detect: in2000_detect, /* returns number of in2000's found */ \ @@ -458,8 +421,5 @@ use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \ use_new_eh_code: 0 /* new error code - not using it yet */ \ } - -#endif - #endif /* IN2000_H */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ini9100u.c linux/drivers/scsi/ini9100u.c --- v2.3.26/linux/drivers/scsi/ini9100u.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/ini9100u.c Thu Nov 11 16:57:30 1999 @@ -116,33 +116,17 @@ #include #endif -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) #include #include #include -#if LINUX_VERSION_CODE <= CVT_LINUX_VERSION(2,1,92) -#include -#endif #include #include -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,23) #include -#endif #include -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) #include -#endif #include #include -#else - -#include -#include -#include -#include "../block/blk.h" -#endif - #include #include #include @@ -169,15 +153,6 @@ char *i91uProductName = "INI-9X00U/UW"; char *i91uVersion = "v1.03g"; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) -struct proc_dir_entry proc_scsi_ini9100u = -{ - PROC_SCSI_INI9100U, 7, "INI9100U", - S_IFDIR | S_IRUGO | S_IXUGO, 2, - 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; -#endif - #define TULSZ(sz) (sizeof(sz) / sizeof(sz[0])) #define TUL_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) @@ -195,7 +170,6 @@ static char *setup_str = (char *) NULL; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr0(int irq, void *dev_id, struct pt_regs *); static void i91u_intr1(int irq, void *dev_id, struct pt_regs *); static void i91u_intr2(int irq, void *dev_id, struct pt_regs *); @@ -204,16 +178,6 @@ static void i91u_intr5(int irq, void *dev_id, struct pt_regs *); static void i91u_intr6(int irq, void *dev_id, struct pt_regs *); static void i91u_intr7(int irq, void *dev_id, struct pt_regs *); -#else -static void i91u_intr0(int irq, struct pt_regs *); -static void i91u_intr1(int irq, struct pt_regs *); -static void i91u_intr2(int irq, struct pt_regs *); -static void i91u_intr3(int irq, struct pt_regs *); -static void i91u_intr4(int irq, struct pt_regs *); -static void i91u_intr5(int irq, struct pt_regs *); -static void i91u_intr6(int irq, struct pt_regs *); -static void i91u_intr7(int irq, struct pt_regs *); -#endif static void i91u_panic(char *msg); @@ -261,12 +225,7 @@ static void i91uAppendSRBToQueue(HCS * pHCB, Scsi_Cmnd * pSRB) { ULONG flags; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pHCB->pSRB_lock), flags); -#else - save_flags(flags); - cli(); -#endif pSRB->next = NULL; /* Pointer to next */ @@ -276,11 +235,7 @@ pHCB->pSRB_tail->next = pSRB; /* Pointer to next */ pHCB->pSRB_tail = pSRB; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); -#else - restore_flags(flags); -#endif return; } @@ -296,22 +251,13 @@ Scsi_Cmnd *pSRB; ULONG flags; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pHCB->pSRB_lock), flags); -#else - save_flags(flags); - cli(); -#endif if ((pSRB = pHCB->pSRB_head) != NULL) { pHCB->pSRB_head = pHCB->pSRB_head->next; pSRB->next = NULL; } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); -#else - restore_flags(flags); -#endif return (pSRB); } @@ -331,7 +277,6 @@ #endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,93) int tul_NewReturnNumberOfAdapters(void) { struct pci_dev *pDev = NULL; /* Start from none */ @@ -363,102 +308,6 @@ return (iAdapters); } -#else /* <01> */ - -/***************************************************************************** - Function name : tul_ReturnNumberOfAdapters - Description : This function will scan PCI bus to get all Orchid card - Input : None. - Output : None. - Return : SUCCESSFUL - Successful scan - ohterwise - No drives founded -*****************************************************************************/ -int tul_ReturnNumberOfAdapters(void) -{ - unsigned int i, iAdapters; - unsigned int dRegValue; - unsigned short command; - WORD wBIOS, wBASE; - BYTE bPCIBusNum, bInterrupt, bPCIDeviceNum; - - iAdapters = 0; - /* - * PCI-bus probe. - */ - if (pcibios_present()) { -#ifdef MMAPIO - unsigned long page_offset, base; -#endif - - int index; - unsigned char pci_bus, pci_devfn; - - bPCIBusNum = 0; - bPCIDeviceNum = 0; - init_i91uAdapter_table(); - for (i = 0; i < TULSZ(i91u_pci_devices); i++) { - index = 0; - while (!(pcibios_find_device(i91u_pci_devices[i].vendor_id, - i91u_pci_devices[i].device_id, - index++, &pci_bus, &pci_devfn))) - { - if (i == 2) { - printk("i91u: The RAID controller is not supported by\n"); - printk("i91u: this driver, we are ignoring it.\n"); - } else { - /* - * Read sundry information from PCI BIOS. - */ - bPCIBusNum = pci_bus; - bPCIDeviceNum = pci_devfn; - pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0, - &dRegValue); - if (dRegValue == -1) { /* Check return code */ - printk("\n\ri91u: tulip read configuration error.\n"); - return (0); /* Read configuration space error */ - } - /* <02> read from base address + 0x50 offset to get the wBIOS balue. */ - wBASE = (WORD) dRegValue; - - /* Now read the interrupt line */ - pcibios_read_config_dword(pci_bus, pci_devfn, PCI_INTERRUPT_LINE, - &dRegValue); - bInterrupt = dRegValue & 0xFF; /* Assign interrupt line */ - pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command); - pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, - command | PCI_COMMAND_MASTER | PCI_COMMAND_IO); - wBASE &= PCI_BASE_ADDRESS_IO_MASK; - wBIOS = TUL_RDWORD(wBASE, 0x50); - -#ifdef MMAPIO - base = wBASE & PAGE_MASK; - page_offset = wBASE - base; - - /* - * replace the next line with this one if you are using 2.1.x: - * temp_p->maddr = ioremap(base, page_offset + 256); - */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,0) - wBASE = ioremap(base, page_offset + 256); -#else - wBASE = (WORD) vremap(base, page_offset + 256); -#endif - if (wBASE) { - wBASE += page_offset; - } -#endif - - if (Addi91u_into_Adapter_table(wBIOS, wBASE, bInterrupt, bPCIBusNum, - bPCIDeviceNum) == 0x0) - iAdapters++; - } - } /* while(pdev=....) */ - } /* for PCI_DEVICES */ - } /* PCI BIOS present */ - return (iAdapters); -} -#endif - int i91u_detect(Scsi_Host_Template * tpnt) { SCB *pSCB; @@ -469,9 +318,7 @@ ULONG dBiosAdr; BYTE *pbBiosAdr; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) - tpnt->proc_dir = &proc_scsi_ini9100u; -#endif + tpnt->proc_name = "INI9100U"; if (setup_called) { /* Setup by i91u_setup */ printk("i91u: processing commandline: "); @@ -486,15 +333,11 @@ #endif } /* Get total number of adapters in the motherboard */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,93) #ifdef CONFIG_PCI iAdapters = tul_NewReturnNumberOfAdapters(); #else iAdapters = tul_ReturnNumberOfAdapters(); #endif -#else - iAdapters = tul_ReturnNumberOfAdapters(); -#endif if (iAdapters == 0) /* If no tulip founded, return */ return (0); @@ -512,16 +355,11 @@ memset((unsigned char *) &tul_hcs[0], 0, i); /* Initialize tul_hcs 0 */ /* Get total memory needed for SCB */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) { i = tul_num_ch * tul_num_scb * sizeof(SCB); if ((tul_scb = (SCB *) kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL) break; } -#else - i = tul_num_ch * tul_num_scb * sizeof(SCB); - tul_scb = (SCB *) scsi_init_malloc(i, GFP_ATOMIC | GFP_DMA); -#endif if (tul_scb == NULL) { printk("i91u: SCB memory allocation error\n"); return (0); @@ -530,11 +368,7 @@ pSCB = tul_scb; for (i = 0; i < tul_num_ch * tul_num_scb; i++, pSCB++) { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pSCB->SCB_SGPAddr = (U32) VIRT_TO_BUS(&pSCB->SCB_SGList[0]); -#else - pSCB->SCB_SGPAddr = (U32) (&pSCB->SCB_SGList[0]); -#endif } for (i = 0, pHCB = &tul_hcs[0]; /* Get pointer for control block */ @@ -542,9 +376,7 @@ i++, pHCB++) { pHCB->pSRB_head = NULL; /* Initial SRB save queue */ pHCB->pSRB_tail = NULL; /* Initial SRB save queue */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */ -#endif request_region(pHCB->HCS_Base, 0x100, "i91u"); /* Register */ get_tulipPCIConfig(pHCB, i); @@ -552,9 +384,7 @@ dBiosAdr = pHCB->HCS_BIOS; dBiosAdr = (dBiosAdr << 4); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pbBiosAdr = phys_to_virt(dBiosAdr); -#endif init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10); pHCB->HCS_Index = i; /* 7/29/98 */ @@ -562,10 +392,8 @@ hreg->io_port = pHCB->HCS_Base; hreg->n_io_port = 0xff; hreg->can_queue = tul_num_scb; /* 03/05/98 */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) hreg->unique_id = pHCB->HCS_Base; hreg->max_id = pHCB->HCS_MaxTar; -#endif hreg->max_lun = 32; /* 10/21/97 */ hreg->irq = pHCB->HCS_Intr; hreg->this_id = pHCB->HCS_SCSI_ID; /* Assign HCS index */ @@ -574,7 +402,6 @@ /* Initial tulip chip */ switch (i) { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) case 0: ok = request_irq(pHCB->HCS_Intr, i91u_intr0, SA_INTERRUPT | SA_SHIRQ, "i91u", NULL); break; @@ -617,7 +444,6 @@ } i91u_panic("i91u: driver needs an IRQ.\n"); } -#endif } tpnt->this_id = -1; @@ -642,11 +468,7 @@ pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW; pSCB->SCB_Flags |= SCF_SENSE; /* Turn on auto request sense */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pSCB->SCB_SensePtr = (U32) VIRT_TO_BUS(SCpnt->sense_buffer); -#else - pSCB->SCB_SensePtr = (U32) (SCpnt->sense_buffer); -#endif pSCB->SCB_SenseLen = SENSE_SIZE; @@ -664,11 +486,7 @@ if (SCpnt->use_sg) { pSrbSG = (struct scatterlist *) SCpnt->request_buffer; if (SCpnt->use_sg == 1) { /* If only one entry in the list *//* treat it as regular I/O */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pSCB->SCB_BufPtr = (U32) VIRT_TO_BUS(pSrbSG->address); -#else - pSCB->SCB_BufPtr = (U32) (pSrbSG->address); -#endif TotalLen = pSrbSG->length; pSCB->SCB_SGLen = 0; } else { /* Assign SG physical address */ @@ -677,11 +495,7 @@ for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0]; /* 1.01g */ i < SCpnt->use_sg; i++, pSG++, pSrbSG++) { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pSG->SG_Ptr = (U32) VIRT_TO_BUS(pSrbSG->address); -#else - pSG->SG_Ptr = (U32) (pSrbSG->address); -#endif TotalLen += pSG->SG_Len = pSrbSG->length; } pSCB->SCB_SGLen = i; @@ -689,11 +503,7 @@ pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ? TotalLen : SCpnt->request_bufflen; } else { /* Non SG */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pSCB->SCB_BufPtr = (U32) VIRT_TO_BUS(SCpnt->request_buffer); -#else - pSCB->SCB_BufPtr = (U32) (SCpnt->request_buffer); -#endif pSCB->SCB_BufLen = SCpnt->request_bufflen; pSCB->SCB_SGLen = 0; } @@ -768,11 +578,7 @@ /* * Return the "logical geometry" */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) int i91u_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array) -#else -int i91u_biosparam(Scsi_Disk * disk, int dev, int *info_array) -#endif { HCS *pHcb; /* Point to Host adapter control block */ TCS *pTcb; @@ -887,196 +693,116 @@ /* * Interrupts handler (main routine of the driver) */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr0(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr0(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[0].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[0]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr1(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr1(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[1].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[1]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr2(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr2(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[2].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[2]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr3(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr3(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[3].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[3]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr4(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr4(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[4].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[4]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr5(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr5(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[5].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[5]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr6(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr6(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[6].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[6]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void i91u_intr7(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void i91u_intr7(int irqno, struct pt_regs *regs) -#endif { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; -#endif if (tul_hcs[7].HCS_Intr != irqno) return; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, flags); -#endif tul_isr(&tul_hcs[7]); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } /* diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ini9100u.h linux/drivers/scsi/ini9100u.h --- v2.3.26/linux/drivers/scsi/ini9100u.h Thu Aug 26 13:05:39 1999 +++ linux/drivers/scsi/ini9100u.h Thu Nov 11 17:04:12 1999 @@ -83,68 +83,16 @@ extern int i91u_abort(Scsi_Cmnd *); extern int i91u_reset(Scsi_Cmnd *, unsigned int); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1, 3, 0) extern int i91u_biosparam(Scsi_Disk *, kdev_t, int *); /*for linux v2.0 */ extern struct proc_dir_entry proc_scsi_ini9100u; -#else -extern int i91u_biosparam(Disk *, int, int *); /*for linux v1.13 */ #endif #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.03g" -#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(1, 3, 0) -#define INI9100U { \ - NULL, \ - NULL, \ - i91u_REVID, \ - i91u_detect, \ - NULL, \ - NULL, \ - i91u_command, \ - i91u_queue, \ - i91u_abort, \ - i91u_reset, \ - NULL, \ - i91u_biosparam, \ - 1, \ - 7, \ - SG_ALL, \ - 1, \ - 0, \ - 0, \ - ENABLE_CLUSTERING \ -} -#else - -#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2, 1, 75) -#define INI9100U { \ - NULL, \ - NULL, \ - &proc_scsi_ini9100u, \ - NULL, \ - i91u_REVID, \ - i91u_detect, \ - NULL, \ - NULL, \ - i91u_command, \ - i91u_queue, \ - i91u_abort, \ - i91u_reset, \ - NULL, \ - i91u_biosparam, \ - 1, \ - 7, \ - SG_ALL, \ - 1, \ - 0, \ - 0, \ - ENABLE_CLUSTERING \ -} -#else /* Version >= 2.1.75 */ #define INI9100U { \ next: NULL, \ module: NULL, \ - proc_dir: &proc_scsi_ini9100u, \ + proc_name: "INI9100U", \ proc_info: NULL, \ name: i91u_REVID, \ detect: i91u_detect, \ @@ -170,9 +118,6 @@ use_clustering: ENABLE_CLUSTERING, \ use_new_eh_code: 0 \ } -#endif -#endif - #define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i)) #define ULONG unsigned long @@ -330,11 +275,9 @@ TCS HCS_Tcs[16]; /* 78 -> 16 Targets */ Scsi_Cmnd *pSRB_head; /* SRB save queue header */ Scsi_Cmnd *pSRB_tail; /* SRB save queue tail */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spinlock_t HCS_AvailLock; spinlock_t HCS_SemaphLock; spinlock_t pSRB_lock; -#endif } HCS; /* Bit Definition for HCB_Flags */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/inia100.c linux/drivers/scsi/inia100.c --- v2.3.26/linux/drivers/scsi/inia100.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/inia100.c Thu Nov 11 16:57:30 1999 @@ -71,56 +71,27 @@ #include #endif -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) #include -#include #include -#include #include -#include -#include #include -#include -#if LINUX_VERSION_CODE <= CVT_LINUX_VERSION(2,1,92) -#include -#endif #include -#include -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,23) #include -#endif #include -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) #include -#endif -#include "sd.h" -#include "scsi.h" -#include "hosts.h" -#include "inia100.h" #include -#include #include - - -#else - #include -#include -#include #include #include - #include #include -#include #include -#include "../block/blk.h" #include "scsi.h" #include "sd.h" #include "hosts.h" #include #include "inia100.h" -#endif #ifdef MODULE Scsi_Host_Template driver_template = INIA100; @@ -134,15 +105,6 @@ char *inia100_ProductName = "INI-A100U2W"; char *inia100_Version = "v1.02c"; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) -struct proc_dir_entry proc_scsi_inia100 = -{ - PROC_SCSI_INIA100, 7, "INIA100", - S_IFDIR | S_IRUGO | S_IXUGO, 2, - 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; -#endif - /* set by inia100_setup according to the command line */ static int setup_called = 0; static int orc_num_ch = MAX_SUPPORTED_ADAPTERS; /* Maximum 4 adapters */ @@ -151,7 +113,6 @@ #define NUMBER(arr) (sizeof(arr) / sizeof(arr[0])) static char *setup_str = (char *) NULL; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr0(int irq, void *dev_id, struct pt_regs *); static void inia100_intr1(int irq, void *dev_id, struct pt_regs *); static void inia100_intr2(int irq, void *dev_id, struct pt_regs *); @@ -160,16 +121,6 @@ static void inia100_intr5(int irq, void *dev_id, struct pt_regs *); static void inia100_intr6(int irq, void *dev_id, struct pt_regs *); static void inia100_intr7(int irq, void *dev_id, struct pt_regs *); -#else -static void inia100_intr0(int irq, struct pt_regs *); -static void inia100_intr1(int irq, struct pt_regs *); -static void inia100_intr2(int irq, struct pt_regs *); -static void inia100_intr3(int irq, struct pt_regs *); -static void inia100_intr4(int irq, struct pt_regs *); -static void inia100_intr5(int irq, struct pt_regs *); -static void inia100_intr6(int irq, struct pt_regs *); -static void inia100_intr7(int irq, struct pt_regs *); -#endif static void inia100_panic(char *msg); void inia100SCBPost(BYTE * pHcb, BYTE * pScb); @@ -203,12 +154,7 @@ { ULONG flags; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pHCB->pSRB_lock), flags); -#else - save_flags(flags); - cli(); -#endif pSRB->next = NULL; /* Pointer to next */ if (pHCB->pSRB_head == NULL) @@ -216,11 +162,7 @@ else pHCB->pSRB_tail->next = pSRB; /* Pointer to next */ pHCB->pSRB_tail = pSRB; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); -#else - restore_flags(flags); -#endif return; } @@ -235,22 +177,12 @@ { Scsi_Cmnd *pSRB; ULONG flags; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_lock_irqsave(&(pHCB->pSRB_lock), flags); -#else - save_flags(flags); - cli(); -#endif - if ((pSRB = (Scsi_Cmnd *) pHCB->pSRB_head) != NULL) { pHCB->pSRB_head = pHCB->pSRB_head->next; pSRB->next = NULL; } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); -#else - restore_flags(flags); -#endif return (pSRB); } @@ -305,28 +237,16 @@ unsigned long page_offset, base; #endif -#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92) struct pci_dev *pdev = NULL; -#else - int index; - unsigned char pci_bus, pci_devfn; -#endif bPCIBusNum = 0; bPCIDeviceNum = 0; init_inia100Adapter_table(); for (i = 0; i < NUMBER(inia100_pci_devices); i++) { -#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92) pdev = NULL; while ((pdev = pci_find_device(inia100_pci_devices[i].vendor_id, inia100_pci_devices[i].device_id, pdev))) -#else - index = 0; - while (!(pcibios_find_device(inia100_pci_devices[i].vendor_id, - inia100_pci_devices[i].device_id, - index++, &pci_bus, &pci_devfn))) -#endif { if (iAdapters >= MAX_SUPPORTED_ADAPTERS) break; /* Never greater than maximum */ @@ -340,7 +260,6 @@ /* * Read sundry information from PCI BIOS. */ -#if LINUX_VERSION_CODE > CVT_LINUX_VERSION(2,1,92) bPCIBusNum = pdev->bus->number; bPCIDeviceNum = pdev->devfn; dRegValue = pdev->resource[0].start; @@ -358,26 +277,6 @@ pci_write_config_word(pdev, PCI_COMMAND, command | PCI_COMMAND_MASTER | PCI_COMMAND_IO); -#else - bPCIBusNum = pci_bus; - bPCIDeviceNum = pci_devfn; - pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0, - &dRegValue); - if (dRegValue == -1) { /* Check return code */ - printk("\n\rinia100: Orchid read configuration error.\n"); - return (0); /* Read configuration space error */ - } - /* <02> read from base address + 0x50 offset to get the wBIOS balue. */ - wBASE = (WORD) dRegValue; - - /* Now read the interrupt line */ - pcibios_read_config_dword(pci_bus, pci_devfn, PCI_INTERRUPT_LINE, - &dRegValue); - bInterrupt = dRegValue & 0xFF; /* Assign interrupt line */ - pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command); - pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, - command | PCI_COMMAND_MASTER | PCI_COMMAND_IO); -#endif wBASE &= PCI_BASE_ADDRESS_IO_MASK; wBIOS = ORC_RDWORD(wBASE, 0x50); @@ -389,11 +288,7 @@ * replace the next line with this one if you are using 2.1.x: * temp_p->maddr = ioremap(base, page_offset + 256); */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,0) wBASE = ioremap(base, page_offset + 256); -#else - wBASE = (WORD) vremap(base, page_offset + 256); -#endif if (wBASE) { wBASE += page_offset; } @@ -426,9 +321,7 @@ ULONG dBiosAdr; BYTE *pbBiosAdr; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) - tpnt->proc_dir = &proc_scsi_inia100; -#endif + tpnt->proc_name = "INIA100"; if (setup_called) { /* Setup by inia100_setup */ printk("inia100: processing commandline: "); @@ -458,9 +351,7 @@ pHCB->pSRB_head = NULL; /* Initial SRB save queue */ pHCB->pSRB_tail = NULL; /* Initial SRB save queue */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */ -#endif /* Get total memory needed for SCB */ sz = orc_num_scb * sizeof(ORC_SCB); if ((pHCB->HCS_virScbArray = (PVOID) kmalloc(sz, GFP_ATOMIC | GFP_DMA)) == NULL) { @@ -485,9 +376,7 @@ dBiosAdr = pHCB->HCS_BIOS; dBiosAdr = (dBiosAdr << 4); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pbBiosAdr = phys_to_virt(dBiosAdr); -#endif if (init_orchid(pHCB)) { /* Initial orchid chip */ printk("inia100: initial orchid fail!!\n"); @@ -501,10 +390,8 @@ hreg->n_io_port = 0xff; hreg->can_queue = orc_num_scb; /* 03/05/98 */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) hreg->unique_id = pHCB->HCS_Base; hreg->max_id = pHCB->HCS_MaxTar; -#endif hreg->max_lun = 32; /* 10/21/97 */ /* @@ -523,7 +410,6 @@ /* Initial orc chip */ switch (i) { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) case 0: ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL); break; @@ -568,7 +454,6 @@ } inia100_panic("inia100: driver needs an IRQ.\n"); } -#endif } tpnt->this_id = -1; @@ -610,21 +495,13 @@ pSCB->SCB_SGLen = (U32) (SCpnt->use_sg * 8); pSrbSG = (struct scatterlist *) SCpnt->request_buffer; for (i = 0; i < SCpnt->use_sg; i++, pSG++, pSrbSG++) { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pSG->SG_Ptr = (U32) (VIRT_TO_BUS(pSrbSG->address)); -#else - pSG->SG_Ptr = (U32) pSrbSG->address; -#endif pSG->SG_Len = (U32) pSrbSG->length; TotalLen += (U32) pSrbSG->length; } } else { /* Non SG */ pSCB->SCB_SGLen = 0x8; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) pSG->SG_Ptr = (U32) (VIRT_TO_BUS(SCpnt->request_buffer)); -#else - pSG->SG_PTR = (U32) SCpnt->request_buffer; -#endif pSG->SG_Len = (U32) SCpnt->request_bufflen; } } @@ -814,11 +691,7 @@ Output : None. Return : pSRB - Pointer to SCSI request block. *****************************************************************************/ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) int inia100_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array) -#else -int inia100_biosparam(Scsi_Disk * disk, int dev, int *info_array) -#endif { ORC_HCS *pHcb; /* Point to Host adapter control block */ ORC_TCS *pTcb; @@ -847,96 +720,58 @@ static void subIntr(ORC_HCS * pHCB, int irqno) { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) unsigned long flags; spin_lock_irqsave(&io_request_lock, flags); -#endif if (pHCB->HCS_Intr != irqno) { -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif return; } orc_interrupt(pHCB); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spin_unlock_irqrestore(&io_request_lock, flags); -#endif } /* * Interrupts handler (main routine of the driver) */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr0(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr0(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[0], irqno); } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr1(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr1(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[1], irqno); } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr2(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr2(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[2], irqno); } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr3(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr3(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[3], irqno); } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr4(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr4(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[4], irqno); } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr5(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr5(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[5], irqno); } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr6(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr6(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[6], irqno); } -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0) static void inia100_intr7(int irqno, void *dev_id, struct pt_regs *regs) -#else -static void inia100_intr7(int irqno, struct pt_regs *regs) -#endif { subIntr(&orc_hcs[7], irqno); } diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/inia100.h linux/drivers/scsi/inia100.h --- v2.3.26/linux/drivers/scsi/inia100.h Fri Oct 22 13:21:50 1999 +++ linux/drivers/scsi/inia100.h Thu Nov 11 17:04:12 1999 @@ -76,69 +76,14 @@ extern int inia100_abort(Scsi_Cmnd *); extern int inia100_reset(Scsi_Cmnd *, unsigned int); -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1, 3, 0) extern int inia100_biosparam(Scsi_Disk *, kdev_t, int *); /*for linux v2.0 */ -extern struct proc_dir_entry proc_scsi_inia100; -#else -extern int inia100_biosparam(Disk *, int, int *); /*for linux v1.13 */ -#endif #define inia100_REVID "Initio INI-A100U2W SCSI device driver; Revision: 1.02c" -#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(1, 3, 0) -#define INIA100 { \ - NULL, \ - NULL, \ - inia100_REVID, \ - inia100_detect, \ - NULL, \ - NULL, \ - inia100_command, \ - inia100_queue, \ - inia100_abort, \ - inia100_reset, \ - NULL, \ - inia100_biosparam, \ - 1, \ -7, \ -SG_ALL, \ -1, \ -0, \ -0, \ -ENABLE_CLUSTERING \ -} - -#else - -#if LINUX_VERSION_CODE < CVT_LINUX_VERSION(2, 1, 75) -#define INIA100 { \ - NULL, \ - NULL, \ - &proc_scsi_inia100, \ - NULL, \ - inia100_REVID, \ - inia100_detect, \ - NULL, \ - NULL, \ - inia100_command, \ - inia100_queue, \ - inia100_abort, \ - inia100_reset, \ - NULL, \ - inia100_biosparam, \ - 1, \ - 7, \ - 0, \ - 1, \ - 0, \ - 0, \ - ENABLE_CLUSTERING \ -} -#else /* Version >= 2.1.75 */ #define INIA100 { \ next: NULL, \ module: NULL, \ - proc_dir: &proc_scsi_inia100, \ + proc_name: "INIA100", \ proc_info: NULL, \ name: inia100_REVID, \ detect: inia100_detect, \ @@ -164,8 +109,6 @@ use_clustering: ENABLE_CLUSTERING, \ use_new_eh_code: 0 \ } -#endif -#endif #define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i)) #define ULONG unsigned long @@ -441,14 +384,10 @@ UBYTE ActiveTags[16][16]; /* 50 */ ORC_TCS HCS_Tcs[16]; /* 28 */ U32 BitAllocFlag[MAX_CHANNELS][8]; /* Max STB is 256, So 256/32 */ -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spinlock_t BitAllocFlagLock; -#endif Scsi_Cmnd *pSRB_head; Scsi_Cmnd *pSRB_tail; -#if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95) spinlock_t pSRB_lock; -#endif } ORC_HCS; /* Bit Definition for HCS_Flags */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ips.c linux/drivers/scsi/ips.c --- v2.3.26/linux/drivers/scsi/ips.c Fri Oct 22 13:21:50 1999 +++ linux/drivers/scsi/ips.c Thu Nov 11 16:57:30 1999 @@ -113,20 +113,6 @@ #define IPS_VERSION_HIGH "1.00" /* MUST be 4 chars */ #define IPS_VERSION_LOW ".00 " /* MUST be 4 chars */ -struct proc_dir_entry proc_scsi_ips = { -#if !defined(PROC_SCSI_IPS) - 0, /* Use dynamic inode allocation */ -#else - PROC_SCSI_IPS, -#endif - 3, "ips", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - -#if LINUX_VERSION_CODE < LinuxVersionCode(2,1,93) - #include -#endif - #if !defined(__i386__) #error "This driver has only been tested on the x86 platform" #endif @@ -262,7 +248,7 @@ DBG("ips_detect"); SHT->proc_info = ips_proc_info; - SHT->proc_dir = &proc_scsi_ips; + SHT->proc_name = "ips"; #if defined(CONFIG_PCI) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ips.h linux/drivers/scsi/ips.h --- v2.3.26/linux/drivers/scsi/ips.h Fri Oct 22 13:21:50 1999 +++ linux/drivers/scsi/ips.h Thu Nov 11 17:03:45 1999 @@ -271,7 +271,6 @@ #define IPS { \ next : NULL, \ module : NULL, \ - proc_dir : NULL, \ proc_info : NULL, \ name : NULL, \ detect : ips_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/jazz_esp.h linux/drivers/scsi/jazz_esp.h --- v2.3.26/linux/drivers/scsi/jazz_esp.h Fri Aug 13 15:07:07 1999 +++ linux/drivers/scsi/jazz_esp.h Thu Nov 11 16:57:30 1999 @@ -21,7 +21,7 @@ int hostno, int inout); #define SCSI_JAZZ_ESP { \ - proc_dir: &proc_scsi_esp, \ + proc_name: "esp", \ proc_info: &esp_proc_info, \ name: "ESP 100/100a/200", \ detect: jazz_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mac53c94.c linux/drivers/scsi/mac53c94.c --- v2.3.26/linux/drivers/scsi/mac53c94.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/scsi/mac53c94.c Thu Nov 11 16:57:30 1999 @@ -26,11 +26,6 @@ #include "hosts.h" #include "mac53c94.h" -struct proc_dir_entry proc_scsi_mac53c94 = { - PROC_SCSI_53C94, 5, "53c94", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - enum fsc_phase { idle, selecting, diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mac53c94.h linux/drivers/scsi/mac53c94.h --- v2.3.26/linux/drivers/scsi/mac53c94.h Fri Oct 15 15:25:14 1999 +++ linux/drivers/scsi/mac53c94.h Thu Nov 11 16:57:30 1999 @@ -7,8 +7,6 @@ #ifndef _MAC53C94_H #define _MAC53C94_H -extern struct proc_dir_entry proc_scsi_mac53c94; - int mac53c94_detect(Scsi_Host_Template *); int mac53c94_command(Scsi_Cmnd *); int mac53c94_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); @@ -16,7 +14,7 @@ int mac53c94_reset(Scsi_Cmnd *, unsigned int); #define SCSI_MAC53C94 { \ - proc_dir: &proc_scsi_mac53c94, \ + proc_name: "53c94", \ name: "53C94", \ detect: mac53c94_detect, \ command: mac53c94_command, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mac_esp.c linux/drivers/scsi/mac_esp.c --- v2.3.26/linux/drivers/scsi/mac_esp.c Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/mac_esp.c Mon Nov 8 11:03:21 1999 @@ -22,25 +22,28 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" #include "NCR53C9x.h" #include "mac_esp.h" -#include "../../arch/m68k/mac/via6522.h" /* huh? */ - #include #include #include #include #include +#include #include #include +#define mac_turnon_irq(x) mac_enable_irq(x) +#define mac_turnoff_irq(x) mac_disable_irq(x) + extern inline void esp_handle(struct NCR_ESP *esp); extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs); @@ -235,6 +238,8 @@ #endif #endif } + +__setup("mac53c9x=", mac_esp_setup); /* * ESP address 'detection' diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mac_esp.h linux/drivers/scsi/mac_esp.h --- v2.3.26/linux/drivers/scsi/mac_esp.h Fri Aug 13 15:06:58 1999 +++ linux/drivers/scsi/mac_esp.h Thu Nov 11 16:57:30 1999 @@ -21,7 +21,7 @@ extern int esp_reset(Scsi_Cmnd *, unsigned int); -#define SCSI_MAC_ESP { proc_dir: &proc_scsi_esp, \ +#define SCSI_MAC_ESP { proc_name: "esp", \ name: "Mac 53C9x SCSI", \ detect: mac_esp_detect, \ release: NULL, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mac_scsi.c linux/drivers/scsi/mac_scsi.c --- v2.3.26/linux/drivers/scsi/mac_scsi.c Wed Aug 18 10:00:52 1999 +++ linux/drivers/scsi/mac_scsi.c Thu Nov 11 16:57:30 1999 @@ -1,95 +1,104 @@ /* - * mac_scsi.c -- Device dependent functions for the Macintosh NCR5380 SCSI - * port (MacII style machines, no DMA). + * Generic Macintosh NCR5380 driver * - * based on: + * Copyright 1998, Michael Schmitz + * + * derived in part from: */ - /* - * atari_scsi.c -- Device dependent functions for the Atari generic SCSI port + * Generic Generic NCR5380 driver + * + * Copyright 1995, Russell King * - * Copyright 1994 Roman Hodek + * ALPHA RELEASE 1. * - * Loosely based on the work of Robert De Vries' team and added: - * - working real DMA - * - Falcon support (untested yet!) ++bjoern fixed and now it works - * - lots of extensions and bug fixes. + * For more information, please consult * - * 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. + * NCR 5380 Family + * SCSI Protocol Controller + * Databook * + * NCR Microelectronics + * 1635 Aeroplaza Drive + * Colorado Springs, CO 80916 + * 1+ (719) 578-3400 + * 1+ (800) 334-5454 */ -#include -#include - -#define NDEBUG_ABORT 0x800000 -#define NDEBUG_TAGS 0x1000000 -#define NDEBUG_MERGING 0x2000000 - -#define NDEBUG (0) - -#define AUTOSENSE -/* MSch: Tested the pseudo-DMA code on Atari for the Mac68k port ... */ -/* Defining neither PSEUDO_DMA nor REAL_DMA -> PIO transfer, sloooow ! */ -/*#define REAL_DMA*/ /* never supported on NCR5380 Macs */ /* - * Usage: define PSEUDO_DMA to use hardware-handshaked PIO mode (TBI) - * undef PSEUDO_DMA to use pure PIO mode + * Options : + * + * PARITY - enable parity checking. Not supported. + * + * SCSI2 - enable support for SCSI-II tagged queueing. Untested. + * + * USLEEP - enable support for devices that don't disconnect. Untested. */ -/*#define PSEUDO_DMA*/ /* currently gives trouble on some Macs */ +/* + * $Log: mac_NCR5380.c,v $ + */ -#ifdef PSEUDO_DMA -#define EMULATE_PSEUDO_DMA -#define DMA_WORKS_RIGHT -#define UNSAFE +#define AUTOSENSE +#if 0 +#define PSEUDO_DMA #endif -/* Support tagged queuing? (on devices that are able to... :-) */ -#define SUPPORT_TAGS -#define MAX_TAGS 32 - #include #include #include #include -#include -#include + +#include +#include #include -#include +#include +#include +#include -#include -#include -#include -#include -#include -#include +#include #include -#include -#include +#include + +#include +#include +#include +#include #include "scsi.h" #include "hosts.h" #include "mac_scsi.h" #include "NCR5380.h" #include "constants.h" -#include -#include +#if 0 +#define NDEBUG (NDEBUG_INTR | NDEBUG_PSEUDO_DMA | NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_RESELECTION) +#else +#define NDEBUG (NDEBUG_ABORT) +#endif -struct proc_dir_entry proc_scsi_mac = { - PROC_SCSI_MAC, 8, "mac_5380", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; +#define USE_WRAPPER +#define RESET_BOOT +#define DRIVER_SETUP /* - * Define RBV_HACK to run the SCSI driver on RBV Macs; undefine to - * try getting better interrupt latency + * BUG can be used to trigger a strange code-size related hang on 2.1 kernels + */ +#ifdef BUG +#undef RESET_BOOT +#undef DRIVER_SETUP +#endif + +/* + * Need to define this to make SCSI work on RBV machines; leave undefined + * to enable interrupts a bit more on other machines + * Changes method of SCSI interrupt disable from software mask to VIA IER! + * (don't know if that's essential) + * + * 990502 (jmt) - not needed (and won't work) on new irq architecture */ -#define RBV_HACK +/* #define RBV_HACK */ #ifdef RBV_HACK #define ENABLE_IRQ() mac_turnon_irq( IRQ_MAC_SCSI ); @@ -99,83 +108,18 @@ #define DISABLE_IRQ() mac_disable_irq( IRQ_MAC_SCSI ); #endif -#define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \ - (mac_scsi_host->hostdata))->dma_len) - -/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms, - * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more - * need ten times the standard value... */ -#ifndef CONFIG_MAC_SCSI_TOSHIBA_DELAY -#define AFTER_RESET_DELAY (HZ/2) -#else -#define AFTER_RESET_DELAY (5*HZ/2) -#endif - -/***************************** Prototypes *****************************/ - -#ifdef REAL_DMA -static int scsi_dma_is_ignored_buserr( unsigned char dma_stat ); -static void mac_scsi_fetch_restbytes( void ); -static long mac_scsi_dma_residual( struct Scsi_Host *instance ); -static int mac_classify_cmd( Scsi_Cmnd *cmd ); -static unsigned long mac_dma_xfer_len( unsigned long wanted_len, - Scsi_Cmnd *cmd, int write_flag ); -#endif -#ifdef PSEUDO_DMA -static int mac_pdma_read(struct Scsi_Host *instance, unsigned char *dst, - int len); -static int mac_pdma_write(struct Scsi_Host *instance, unsigned char *src, - int len); -static unsigned long mac_dma_xfer_len( unsigned long wanted_len, - Scsi_Cmnd *cmd, int write_flag ); -#endif -static void scsi_mac_intr( int irq, void *dummy, struct pt_regs *fp); -static void mac_scsi_reset_boot( void ); -static unsigned char mac_scsi_reg_read( unsigned char reg ); -static void mac_scsi_reg_write( unsigned char reg, unsigned char value); - -/************************* End of Prototypes **************************/ +#define mac_turnon_irq(x) mac_enable_irq(x) +#define mac_turnoff_irq(x) mac_disable_irq(x) +extern void via_scsi_clear(void); -static struct Scsi_Host *mac_scsi_host = NULL; -#if 0 -static unsigned char (*mac_scsi_reg_read)( unsigned char reg ); -static void (*mac_scsi_reg_write)( unsigned char reg, unsigned char value ); +static void scsi_mac_intr(int irq, void *dummy, struct pt_regs *fp); +#ifdef RESET_BOOT +static void mac_scsi_reset_boot(struct Scsi_Host *instance); #endif +static char macscsi_read(struct Scsi_Host *instance, int reg); +static void macscsi_write(struct Scsi_Host *instance, int reg, int value); -#ifdef REAL_DMA -static unsigned long mac_dma_residual, mac_dma_startaddr; -static short mac_dma_active; -/* pointer to the dribble buffer */ -static char *mac_dma_buffer = NULL; -/* precalculated physical address of the dribble buffer */ -static unsigned long mac_dma_phys_buffer; -/* != 0 tells the int handler to copy data from the dribble buffer */ -static char *mac_dma_orig_addr; -/* size of the dribble buffer; 4k seems enough, since the Falcon cannot use - * scatter-gather anyway, so most transfers are 1024 byte only. In the rare - * cases where requests to physical contiguous buffers have been merged, this - * request is <= 4k (one page). So I don't think we have to split transfers - * just due to this buffer size... - */ -#define MAC_BUFFER_SIZE (4096) -#if 1 /* FIXME: is that an issue for Macs?? */ -/* mask for address bits that can't be used with the ST-DMA */ -static unsigned long mac_dma_stram_mask; -#define STRAM_ADDR(a) (((a) & mac_dma_stram_mask) == 0) -#endif -/* number of bytes to cut from a transfer to handle NCR overruns */ -static int mac_read_overruns = 0; -#endif -#ifdef PSEUDO_DMA -static unsigned long mac_pdma_residual, mac_pdma_startaddr, mac_pdma_current; -static short mac_pdma_active; -/* FIXME: is that an issue for Macs?? */ -/* mask for address bits that can't be used with the ST-DMA */ -static unsigned long mac_dma_stram_mask; -#define STRAM_ADDR(a) (((a) & mac_dma_stram_mask) == 0) -static int mac_read_overruns = 0; -#endif static int setup_can_queue = -1; static int setup_cmd_per_lun = -1; static int setup_sg_tablesize = -1; @@ -184,371 +128,35 @@ #endif static int setup_hostid = -1; - -#if defined(REAL_DMA) - -#if 0 /* FIXME */ -static int scsi_dma_is_ignored_buserr( unsigned char dma_stat ) -{ - int i; - unsigned long addr = SCSI_DMA_READ_P( dma_addr ), end_addr; - - if (dma_stat & 0x01) { - - /* A bus error happens when DMA-ing from the last page of a - * physical memory chunk (DMA prefetch!), but that doesn't hurt. - * Check for this case: - */ - - for( i = 0; i < boot_info.num_memory; ++i ) { - end_addr = boot_info.memory[i].addr + - boot_info.memory[i].size; - if (end_addr <= addr && addr <= end_addr + 4) - return( 1 ); - } - } - return( 0 ); -} - - -/* Dead code... wasn't called anyway :-) and causes some trouble, because at - * end-of-DMA, both SCSI ints are triggered simultaneously, so the NCR int has - * to clear the DMA int pending bit before it allows other level 6 interrupts. - */ -static void scsi_dma_buserr (int irq, void *dummy, struct pt_regs *fp) -{ - unsigned char dma_stat = tt_scsi_dma.dma_ctrl; - - /* Don't do anything if a NCR interrupt is pending. Probably it's just - * masked... */ - if (mac_irq_pending( IRQ_MAC_SCSI )) - return; - - printk("Bad SCSI DMA interrupt! dma_addr=0x%08lx dma_stat=%02x dma_cnt=%08lx\n", - SCSI_DMA_READ_P(dma_addr), dma_stat, SCSI_DMA_READ_P(dma_cnt)); - if (dma_stat & 0x80) { - if (!scsi_dma_is_ignored_buserr( dma_stat )) - printk( "SCSI DMA bus error -- bad DMA programming!\n" ); - } - else { - /* Under normal circumstances we never should get to this point, - * since both interrupts are triggered simultaneously and the 5380 - * int has higher priority. When this irq is handled, that DMA - * interrupt is cleared. So a warning message is printed here. - */ - printk( "SCSI DMA intr ?? -- this shouldn't happen!\n" ); - } -} -#endif - -#endif - -void restore_irq(struct pt_regs *regs) -{ - unsigned long flags; - - save_flags(flags); - flags = (flags & ~0x0700) | (regs->sr & 0x0700); - restore_flags(flags); -} - static int polled_scsi_on = 0; -static unsigned char *mac_scsi_regp = NULL; - -void scsi_mac_polled (void) -{ - if (polled_scsi_on) - { - if(NCR5380_read(BUS_AND_STATUS_REG)&BASR_IRQ) - { - printk("SCSI poll\n"); - scsi_mac_intr(IRQ_MAC_SCSI, NULL, NULL); - } - } -} - -static void scsi_mac_intr (int irq, void *dummy, struct pt_regs *fp) -{ - unsigned long flags; -#ifdef REAL_DMA - int dma_stat; - dma_stat = mac_scsi_dma.dma_ctrl; - - INT_PRINTK("scsi%d: NCR5380 interrupt, DMA status = %02x\n", - mac_scsi_host->host_no, dma_stat & 0xff); - - /* Look if it was the DMA that has interrupted: First possibility - * is that a bus error occurred... - */ - if (dma_stat & 0x80) { - if (!scsi_dma_is_ignored_buserr( dma_stat )) { - printk(KERN_ERR "SCSI DMA caused bus error near 0x%08lx\n", - SCSI_DMA_READ_P(dma_addr)); - printk(KERN_CRIT "SCSI DMA bus error -- bad DMA programming!"); - } - } - - /* If the DMA is active but not finished, we have the the case - * that some other 5380 interrupt occurred within the DMA transfer. - * This means we have residual bytes, if the desired end address - * is not yet reached. Maybe we have to fetch some bytes from the - * rest data register, too. The residual must be calculated from - * the address pointer, not the counter register, because only the - * addr reg counts bytes not yet written and pending in the rest - * data reg! - */ - if ((dma_stat & 0x02) && !(dma_stat & 0x40)) { - mac_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P( dma_addr ) - - mac_dma_startaddr); - - DMA_PRINTK("SCSI DMA: There are %ld residual bytes.\n", - mac_dma_residual); - - if ((signed int)mac_dma_residual < 0) - mac_dma_residual = 0; - if ((dma_stat & 1) == 0) { - /* After read operations, we maybe have to - transport some rest bytes */ - mac_scsi_fetch_restbytes(); - } - else { - /* There seems to be a nasty bug in some SCSI-DMA/NCR - combinations: If a target disconnects while a write - operation is going on, the address register of the - DMA may be a few bytes farer than it actually read. - This is probably due to DMA prefetching and a delay - between DMA and NCR. Experiments showed that the - dma_addr is 9 bytes to high, but this could vary. - The problem is, that the residual is thus calculated - wrong and the next transfer will start behind where - it should. So we round up the residual to the next - multiple of a sector size, if it isn't already a - multiple and the originally expected transfer size - was. The latter condition is there to ensure that - the correction is taken only for "real" data - transfers and not for, e.g., the parameters of some - other command. These shouldn't disconnect anyway. - */ - if (mac_dma_residual & 0x1ff) { - DMA_PRINTK("SCSI DMA: DMA bug corrected, " - "difference %ld bytes\n", - 512 - (mac_dma_residual & 0x1ff)); - mac_dma_residual = (mac_dma_residual + 511) & ~0x1ff; - } - } - mac_scsi_dma.dma_ctrl = 0; - } - - /* If the DMA is finished, fetch the rest bytes and turn it off */ - if (dma_stat & 0x40) { - atari_dma_residual = 0; - if ((dma_stat & 1) == 0) - atari_scsi_fetch_restbytes(); - tt_scsi_dma.dma_ctrl = 0; - } - -#endif /* REAL_DMA */ - -#ifdef PSEUDO_DMA - /* determine if there is any residual for the current transfer */ - if (mac_pdma_active) { - /* probably EOP interrupt, signaling i.e. target disconnect. - * We must figure out the residual from the source/destination - * pointers here ... */ - /* Should check bus status here to make sure it wasn't reselect or reset */ - mac_pdma_residual = HOSTDATA_DMALEN - (mac_pdma_current - mac_pdma_startaddr); - mac_pdma_active = 0; - } -#endif - -#ifdef RBV_HACK - mac_turnoff_irq( IRQ_MAC_SCSI ); -#else - mac_disable_irq( IRQ_MAC_SCSI ); -#endif - - save_flags(flags); -#ifndef RBV_HACK /* interferes with level triggered RBV IRQs ?? */ - restore_irq(fp); -#endif - - if ( irq == IRQ_IDX(IRQ_MAC_SCSI) ) - NCR5380_intr (irq, dummy, fp); - - restore_flags(flags); - - /* To be sure the int is not masked */ -#ifdef RBV_HACK - mac_turnon_irq( IRQ_MAC_SCSI ); -#else - mac_enable_irq( IRQ_MAC_SCSI ); -#endif - - /* Clear the IRQ */ - via_scsi_clear(); -} - - -#ifdef REAL_DMA -static void mac_scsi_fetch_restbytes( void ) -{ - int nr; - char *src, *dst; - - /* fetch rest bytes in the DMA register */ - dst = (char *)SCSI_DMA_READ_P( dma_addr ); - if ((nr = ((long)dst & 3))) { - /* there are 'nr' bytes left for the last long address before the - DMA pointer */ - dst = (char *)( (unsigned long)dst & ~3 ); - DMA_PRINTK("SCSI DMA: there are %d rest bytes for phys addr 0x%08lx", - nr, (long)dst); - dst = (char *)PTOV(dst); /* The content of the DMA pointer - * is a physical address! */ - DMA_PRINTK(" = virt addr 0x%08lx\n", (long)dst); - for( src = (char *)&mac_scsi_dma.dma_restdata; nr > 0; --nr ) - *dst++ = *src++; - } -} -#endif /* REAL_DMA */ - -#if 0 /* FIXME : how is the host ID determined on a Mac? */ -#define RTC_READ(reg) \ - ({ unsigned char __val; \ - outb(reg,&tt_rtc.regsel); \ - __val = tt_rtc.data; \ - __val; \ - }) - -#define RTC_WRITE(reg,val) \ - do { \ - outb(reg,&tt_rtc.regsel); \ - tt_rtc.data = (val); \ - } while(0) -#endif - -int mac_scsi_detect (Scsi_Host_Template *host) -{ - static int called = 0; - struct Scsi_Host *instance; - - if (!MACH_IS_MAC || called) - return( 0 ); - - if (macintosh_config->scsi_type != MAC_SCSI_OLD) - return( 0 ); - - host->proc_dir = &proc_scsi_mac; - - /* testing: IIfx SCSI without IOP ?? */ - if (macintosh_config->ident == MAC_MODEL_IIFX) - mac_scsi_regp = via1_regp+0x8000; - else - mac_scsi_regp = via1_regp+0x10000; - -#if 0 /* maybe if different SCSI versions show up ? */ - mac_scsi_reg_read = IS_A_TT() ? atari_scsi_tt_reg_read : - atari_scsi_falcon_reg_read; - mac_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write : -#endif atari_scsi_falcon_reg_write; - - /* setup variables */ - host->can_queue = - (setup_can_queue > 0) ? setup_can_queue : - MAC_SCSI_CAN_QUEUE; - host->cmd_per_lun = - (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : - MAC_SCSI_CMD_PER_LUN; - host->sg_tablesize = - (setup_sg_tablesize >= 0) ? setup_sg_tablesize : MAC_SCSI_SG_TABLESIZE; - - if (setup_hostid >= 0) - host->this_id = setup_hostid; - else { - /* use 7 as default */ - host->this_id = 7; - } - -#ifdef SUPPORT_TAGS - if (setup_use_tagged_queuing < 0) - setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; -#endif - - instance = scsi_register (host, sizeof (struct NCR5380_hostdata)); - mac_scsi_host = instance; +/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms, + * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more + * need ten times the standard value... */ +#define TOSHIBA_DELAY - /* truncation of machspec bit not critical as instance->irq never used */ -#if 0 /* Might work; problem was only with Falcon lock */ - instance->irq = IRQ_MAC_SCSI; +#ifdef TOSHIBA_DELAY +#define AFTER_RESET_DELAY (5*HZ/2) #else - instance->irq = 0; -#endif - mac_scsi_reset_boot(); - NCR5380_init (instance, 0); - - /* This int is actually "pseudo-slow", i.e. it acts like a slow - * interrupt after having cleared the pending flag for the DMA - * interrupt. */ - request_irq(IRQ_MAC_SCSI, scsi_mac_intr, IRQ_TYPE_SLOW, - "SCSI NCR5380", scsi_mac_intr); -#ifdef REAL_DMA - tt_scsi_dma.dma_ctrl = 0; - atari_dma_residual = 0; - - if (is_brokenscsi) { - /* While the read overruns (described by Drew Eckhardt in - * NCR5380.c) never happened on TTs, they do in fact on the Medusa - * (This was the cause why SCSI didn't work right for so long - * there.) Since handling the overruns slows down a bit, I turned - * the #ifdef's into a runtime condition. - * - * In principle it should be sufficient to do max. 1 byte with - * PIO, but there is another problem on the Medusa with the DMA - * rest data register. So 'atari_read_overruns' is currently set - * to 4 to avoid having transfers that aren't a multiple of 4. If - * the rest data bug is fixed, this can be lowered to 1. - */ - mac_read_overruns = 4; - } -#endif /* REAL_DMA */ - -#ifdef PSEUDO_DMA - mac_pdma_residual = 0; - mac_pdma_active = 0; -#endif - - printk(KERN_INFO "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCAT-GAT=%d " -#ifdef SUPPORT_TAGS - "TAGGED-QUEUING=%s " -#endif - "HOSTID=%d", - instance->host_no, instance->hostt->can_queue, - instance->hostt->cmd_per_lun, - instance->hostt->sg_tablesize, -#ifdef SUPPORT_TAGS - setup_use_tagged_queuing ? "yes" : "no", +#define AFTER_RESET_DELAY (HZ/2) #endif - instance->hostt->this_id ); - NCR5380_print_options (instance); - printk ("\n"); - called = 1; - return( 1 ); -} +static volatile unsigned char *mac_scsi_regp = NULL; +static volatile unsigned char *mac_scsi_drq = NULL; +static volatile unsigned char *mac_scsi_nodrq = NULL; -#ifdef MODULE -int mac_scsi_release (struct Scsi_Host *sh) -{ - free_irq(IRQ_MAC_SCSI, scsi_mac_intr); - if (mac_dma_buffer) - scsi_init_free (mac_dma_buffer, MAC_BUFFER_SIZE); - return 1; -} -#endif +/* + * Function : mac_scsi_setup(char *str, int *ints) + * + * Purpose : booter command line initialization of the overrides array, + * + * Inputs : str - unused, ints - array of integer parameters with ints[0] + * equal to the number of ints. + * + */ -void mac_scsi_setup( char *str, int *ints ) -{ +void mac_scsi_setup(char *str, int *ints) { +#ifdef DRIVER_SETUP /* Format of mac5380 parameter is: * mac5380=,,,, * Negative values mean don't change. @@ -606,39 +214,145 @@ setup_use_tagged_queuing = !!ints[5]; } #endif +#endif } -int mac_scsi_reset( Scsi_Cmnd *cmd, unsigned int reset_flags) +__setup("mac5380=", mac_scsi_setup); + +#if 0 +#define MAC_ADDRESS(card) (ecard_address((card), ECARD_IOC, ECARD_SLOW) + 0x800) +#define MAC_IRQ(card) ((card)->irq) +#endif + +/* + * XXX: status debug + */ +static struct Scsi_Host *default_instance; + +/* + * Function : int macscsi_detect(Scsi_Host_Template * tpnt) + * + * Purpose : initializes mac NCR5380 driver based on the + * command line / compile time port and irq definitions. + * + * Inputs : tpnt - template for this SCSI adapter. + * + * Returns : 1 if a host adapter was found, 0 if not. + * + */ + +int macscsi_detect(Scsi_Host_Template * tpnt) { - int rv; - struct NCR5380_hostdata *hostdata = - (struct NCR5380_hostdata *)cmd->host->hostdata; - - /* For doing the reset, SCSI interrupts must be disabled first, - * since the 5380 raises its IRQ line while _RST is active and we - * can't disable interrupts completely, since we need the timer. - */ - /* And abort a maybe active DMA transfer */ - mac_turnoff_irq( IRQ_MAC_SCSI ); -#ifdef REAL_DMA - mac_scsi_dma.dma_ctrl = 0; -#endif /* REAL_DMA */ -#ifdef PSEUDO_DMA - mac_pdma_active = 0; + int count = 0; + static int called = 0; + struct Scsi_Host *instance; + + if (!MACH_IS_MAC || called) + return( 0 ); + + if (macintosh_config->scsi_type != MAC_SCSI_OLD) + return( 0 ); + + tpnt->proc_name = "Mac 5380 SCSI"; + + /* setup variables */ + tpnt->can_queue = + (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; + tpnt->cmd_per_lun = + (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; + tpnt->sg_tablesize = + (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; + + if (setup_hostid >= 0) + tpnt->this_id = setup_hostid; + else { + /* use 7 as default */ + tpnt->this_id = 7; + } + +#ifdef SUPPORT_TAGS + if (setup_use_tagged_queuing < 0) + setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; #endif - rv = NCR5380_reset(cmd, reset_flags); +#if 0 /* loop over multiple adapters (Powerbooks ??) */ + for (count = 0; count < mac_num_scsi; count++) { +#endif + instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + default_instance = instance; - /* Re-enable ints */ - mac_turnon_irq( IRQ_MAC_SCSI ); + if (macintosh_config->ident == MAC_MODEL_IIFX) { + mac_scsi_regp = via1+0x8000; + mac_scsi_drq = via1+0xE000; + mac_scsi_nodrq = via1+0xC000; + } else { + mac_scsi_regp = via1+0x10000; + mac_scsi_drq = via1+0x6000; + mac_scsi_nodrq = via1+0x12000; + } + + + instance->io_port = (unsigned long) mac_scsi_regp; + instance->irq = IRQ_MAC_SCSI; + +#ifdef RESET_BOOT + mac_scsi_reset_boot(instance); +#endif + + NCR5380_init(instance, 0); + + instance->n_io_port = 255; + + ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; + + if (instance->irq != IRQ_NONE) +#ifdef USE_WRAPPER + if (request_irq(instance->irq, scsi_mac_intr, IRQ_FLG_SLOW, "MacSCSI-5380", NULL)) { +#else + if (request_irq(instance->irq, macscsi_intr, IRQ_FLG_SLOW, "MacSCSI-5380", NULL)) { +#endif + printk("scsi%d: IRQ%d not free, interrupts disabled\n", + instance->host_no, instance->irq); + instance->irq = IRQ_NONE; + } + + printk("scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port); + if (instance->irq == IRQ_NONE) + printk ("s disabled"); + else + printk (" %d", instance->irq); + printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", + instance->can_queue, instance->cmd_per_lun, MACSCSI_PUBLIC_RELEASE); + printk("\nscsi%d:", instance->host_no); + NCR5380_print_options(instance); + printk("\n"); +#if 0 /* multiple adapters */ + } +#endif + called = 1; + return 1; - return( rv ); } - -static void mac_scsi_reset_boot( void ) +int macscsi_release (struct Scsi_Host *shpnt) +{ + if (shpnt->irq != IRQ_NONE) + free_irq (shpnt->irq, NULL); + + return 0; +} + +#ifdef RESET_BOOT +/* + * Our 'bus reset on boot' function + */ + +static void mac_scsi_reset_boot(struct Scsi_Host *instance) { unsigned long end; + + NCR5380_local_declare(); + NCR5380_setup(instance); /* * Do a SCSI reset to clean up the bus during initialization. No messing @@ -662,7 +376,7 @@ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); NCR5380_read( RESET_PARITY_INTERRUPT_REG ); - for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) + for( end = jiffies + AFTER_RESET_DELAY; jiffies < end; ) barrier(); /* switch on SCSI IRQ again */ @@ -670,438 +384,359 @@ printk( " done\n" ); } +#endif +const char * macscsi_info (struct Scsi_Host *spnt) { + return ""; +} -const char * mac_scsi_info (struct Scsi_Host *host) +void restore_irq(struct pt_regs *regs) { - /* mac_scsi_detect() is verbose enough... */ - static const char string[] = "Macintosh NCR5380 SCSI"; - return string; -} + unsigned long flags; + save_flags(flags); + flags = (flags & ~0x0700) | (regs->sr & 0x0700); + restore_flags(flags); +} -#if defined(REAL_DMA) +#ifdef USE_WRAPPER +/* + * SCSI interrupt wrapper - just to make sure it's the proper irq, and + * that we leave the handler in a clean state + */ -unsigned long mac_scsi_dma_setup( struct Scsi_Host *instance, void *data, - unsigned long count, int dir ) +static void scsi_mac_intr (int irq, void *dev_id, struct pt_regs *fp) { - unsigned long addr = virt_to_phys( data ); +#ifndef RBV_HACK + unsigned long flags; +#endif - DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, " - "dir = %d\n", instance->host_no, data, addr, count, dir); +#ifdef RBV_HACK + mac_turnoff_irq( IRQ_MAC_SCSI ); +#else + mac_disable_irq( IRQ_MAC_SCSI ); +#endif - if (!STRAM_ADDR(addr)) { - /* If we have a non-DMAable address on a Falcon, use the dribble - * buffer; 'orig_addr' != 0 in the read case tells the interrupt - * handler to copy data from the dribble buffer to the originally - * wanted address. - */ - if (dir) - memcpy( mac_dma_buffer, data, count ); - else - mac_dma_orig_addr = data; - addr = mac_dma_phys_buffer; + if ( irq == IRQ_MAC_SCSI ) { +#ifndef RBV_HACK + save_flags(flags); + restore_irq(fp); +#endif + NCR5380_intr (irq, dev_id, fp); +#ifndef RBV_HACK + restore_flags(flags); +#endif } - - mac_dma_startaddr = addr; /* Needed for calculating residual later. */ - - /* Cache cleanup stuff: On writes, push any dirty cache out before sending - * it to the peripheral. (Must be done before DMA setup, since at least - * the ST-DMA begins to fill internal buffers right after setup. For - * reads, invalidate any cache, may be altered after DMA without CPU - * knowledge. - * - * ++roman: For the Medusa, there's no need at all for that cache stuff, - * because the hardware does bus snooping (fine!). - */ - dma_cache_maintenance( addr, count, dir ); - - if (count == 0) - printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n"); - mac_scsi_dma.dma_ctrl = dir; - SCSI_DMA_WRITE_P( dma_addr, addr ); - SCSI_DMA_WRITE_P( dma_cnt, count ); - mac_scsi_dma.dma_ctrl = dir | 2; + /* To be sure the int is not masked */ +#ifdef RBV_HACK + mac_turnon_irq( IRQ_MAC_SCSI ); +#else + mac_enable_irq( IRQ_MAC_SCSI ); +#endif - return( count ); +#if 1 /* ??? 0 worked */ + /* Clear the IRQ */ + via_scsi_clear(); +#endif } +#endif +/* + * pseudo-DMA transfer functions, copied and modified from Russel King's + * ARM 5380 driver (cumana_1) + * + * Work in progress (sort of), didn't work last time I checked, don't use! + */ -static long mac_scsi_dma_residual( struct Scsi_Host *instance ) -{ - return( mac_dma_residual ); +#ifdef NOT_EFFICIENT +#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) +#define STAT(p) inb((p)+1) +#define IN(p) inb((p)) +#define OUT(v,p) outb((v), (p)) +#else +#if 0 +#define CTRL(p,v) (p[-2308] = (*ctrl = (v))) +#else +#define CTRL(p,v) (*ctrl = (v)) +#endif +#define STAT(p) (p[1<<4]) +#define IN(p) (*(p)) +#define IN2(p) ((unsigned short)(*(volatile unsigned long *)(p))) +#define OUT(v,p) (*(p) = (v)) +#define OUT2(v,p) (*((volatile unsigned long *)(p)) = (v)) +#endif +#define L(v) (((v)<<16)|((v) & 0x0000ffff)) +#define H(v) (((v)>>16)|((v) & 0xffff0000)) +#define ioaddr(v) (v) + +static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, + int len) +{ + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + int oldctrl = *ctrl; + unsigned long *laddr; +#ifdef NOT_EFFICIENT + int iobase = instance->io_port; + int dma_io = mac_scsi_nodrq; +#else + volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port); + volatile unsigned char *dma_io = (unsigned char *)(mac_scsi_nodrq); +#endif + + if(!len) return 0; + + CTRL(iobase, 0x02); + laddr = (unsigned long *)addr; + while(len >= 32) + { + int status; + unsigned long v; + status = STAT(iobase); + if(status & 0x80) + goto end; + if(!(status & 0x40)) + continue; + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); + len -= 32; + if(len == 0) + break; + } + + addr = (unsigned char *)laddr; + CTRL(iobase, 0x12); + while(len > 0) + { + int status; + status = STAT(iobase); + if(status & 0x80) + goto end; + if(status & 0x40) + { + OUT(*addr++, dma_io); + if(--len == 0) + break; + } + + status = STAT(iobase); + if(status & 0x80) + goto end; + if(status & 0x40) + { + OUT(*addr++, dma_io); + if(--len == 0) + break; + } + } +end: + CTRL(iobase, oldctrl|0x40); + return len; } +static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, + int len) +{ + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; + int oldctrl = *ctrl; + unsigned long *laddr; +#ifdef NOT_EFFICIENT + int iobase = instance->io_port; + int dma_io = mac_scsi_nodrq; +#else + volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port); + volatile unsigned char *dma_io = (unsigned char *)((int)mac_scsi_nodrq); +#endif -#define CMD_SURELY_BLOCK_MODE 0 -#define CMD_SURELY_BYTE_MODE 1 -#define CMD_MODE_UNKNOWN 2 + if(!len) return 0; -static int mac_classify_cmd( Scsi_Cmnd *cmd ) -{ - unsigned char opcode = cmd->cmnd[0]; - - if (opcode == READ_DEFECT_DATA || opcode == READ_LONG || - opcode == READ_BUFFER) - return( CMD_SURELY_BYTE_MODE ); - else if (opcode == READ_6 || opcode == READ_10 || - opcode == 0xa8 /* READ_12 */ || opcode == READ_REVERSE || - opcode == RECOVER_BUFFERED_DATA) { - /* In case of a sequential-access target (tape), special care is - * needed here: The transfer is block-mode only if the 'fixed' bit is - * set! */ - if (cmd->device->type == TYPE_TAPE && !(cmd->cmnd[1] & 1)) - return( CMD_SURELY_BYTE_MODE ); - else - return( CMD_SURELY_BLOCK_MODE ); - } - else - return( CMD_MODE_UNKNOWN ); + CTRL(iobase, 0x00); + laddr = (unsigned long *)addr; + while(len >= 32) + { + int status; + status = STAT(iobase); + if(status & 0x80) + goto end; + if(!(status & 0x40)) + continue; + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); + len -= 32; + if(len == 0) + break; + } + + addr = (unsigned char *)laddr; + CTRL(iobase, 0x10); + while(len > 0) + { + int status; + status = STAT(iobase); + if(status & 0x80) + goto end; + if(status & 0x40) + { + *addr++ = IN(dma_io); + if(--len == 0) + break; + } + + status = STAT(iobase); + if(status & 0x80) + goto end; + if(status & 0x40) + { + *addr++ = IN(dma_io); + if(--len == 0) + break; + } + } +end: + CTRL(iobase, oldctrl|0x40); + return len; } -#endif /* REAL_DMA */ +#undef STAT +#undef CTRL +#undef IN +#undef OUT -#if defined(REAL_DMA) || defined(PSEUDO_DMA) -/* This function calculates the number of bytes that can be transferred via - * DMA. On the TT, this is arbitrary, but on the Falcon we have to use the - * ST-DMA chip. There are only multiples of 512 bytes possible and max. - * 255*512 bytes :-( This means also, that defining READ_OVERRUNS is not - * possible on the Falcon, since that would require to program the DMA for - * n*512 - atari_read_overrun bytes. But it seems that the Falcon doesn't have - * the overrun problem, so this question is academic :-) +/* + * NCR 5380 register access functions */ -static unsigned long mac_dma_xfer_len( unsigned long wanted_len, - Scsi_Cmnd *cmd, - int write_flag ) +#ifdef ORIG +#if 0 +#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) +#else +#define CTRL(p,v) (*ctrl = (v)) +#endif + +static char macscsi_read(struct Scsi_Host *instance, int reg) { - unsigned long possible_len, limit; + int iobase = instance->io_port; + int i; + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; -#if defined(REAL_DMA) - if (IS_A_TT()) - /* TT SCSI DMA can transfer arbitrary #bytes */ - return( wanted_len ); - - /* ST DMA chip is stupid -- only multiples of 512 bytes! (and max. - * 255*512 bytes, but this should be enough) - * - * ++roman: Aaargl! Another Falcon-SCSI problem... There are some commands - * that return a number of bytes which cannot be known beforehand. In this - * case, the given transfer length is an "allocation length". Now it - * can happen that this allocation length is a multiple of 512 bytes and - * the DMA is used. But if not n*512 bytes really arrive, some input data - * will be lost in the ST-DMA's FIFO :-( Thus, we have to distinguish - * between commands that do block transfers and those that do byte - * transfers. But this isn't easy... there are lots of vendor specific - * commands, and the user can issue any command via the - * SCSI_IOCTL_SEND_COMMAND. - * - * The solution: We classify SCSI commands in 1) surely block-mode cmd.s, - * 2) surely byte-mode cmd.s and 3) cmd.s with unknown mode. In case 1) - * and 3), the thing to do is obvious: allow any number of blocks via DMA - * or none. In case 2), we apply some heuristic: Byte mode is assumed if - * the transfer (allocation) length is < 1024, hoping that no cmd. not - * explicitly known as byte mode have such big allocation lengths... - * BTW, all the discussion above applies only to reads. DMA writes are - * unproblematic anyways, since the targets aborts the transfer after - * receiving a sufficient number of bytes. - * - * Another point: If the transfer is from/to an non-ST-RAM address, we - * use the dribble buffer and thus can do only STRAM_BUFFER_SIZE bytes. - */ + CTRL(iobase, 0); +#if 0 + i = inb(iobase + 64 + reg); +#else + i = inb(iobase + reg<<4); +#endif + CTRL(iobase, 0x40); - if (write_flag) { - /* Write operation can always use the DMA, but the transfer size must - * be rounded up to the next multiple of 512 (atari_dma_setup() does - * this). - */ - possible_len = wanted_len; - } - else { - /* Read operations: if the wanted transfer length is not a multiple of - * 512, we cannot use DMA, since the ST-DMA cannot split transfers - * (no interrupt on DMA finished!) - */ - if (wanted_len & 0x1ff) - possible_len = 0; - else { - /* Now classify the command (see above) and decide whether it is - * allowed to do DMA at all */ - switch( falcon_classify_cmd( cmd )) { - case CMD_SURELY_BLOCK_MODE: - possible_len = wanted_len; - break; - case CMD_SURELY_BYTE_MODE: - possible_len = 0; /* DMA prohibited */ - break; - case CMD_MODE_UNKNOWN: - default: - /* For unknown commands assume block transfers if the transfer - * size/allocation length is >= 1024 */ - possible_len = (wanted_len < 1024) ? 0 : wanted_len; - break; - } - } - } + return i; +} - /* Last step: apply the hard limit on DMA transfers */ - limit = (atari_dma_buffer && !STRAM_ADDR( virt_to_phys(cmd->SCp.ptr) )) ? - STRAM_BUFFER_SIZE : 255*512; - if (possible_len > limit) - possible_len = limit; - - if (possible_len != wanted_len) - DMA_PRINTK("Sorry, must cut DMA transfer size to %ld bytes " - "instead of %ld\n", possible_len, wanted_len); +static void macscsi_write(struct Scsi_Host *instance, int reg, int value) +{ + int iobase = instance->io_port; + int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; -#else /* REAL_DMA */ - possible_len = wanted_len; + CTRL(iobase, 0); +#if 0 + outb(value, iobase + 64 + reg); +#else + outb(value, iobase + reg<<4); #endif - - return( possible_len ); + CTRL(iobase, 0x40); } -#endif /* REAL_DMA || PSEUDO_DMA */ - - -/* - * FIXME !!! - */ -/* NCR5380 register access functions - */ +#undef CTRL -static unsigned char mac_scsi_reg_read( unsigned char reg ) +#else +static char macscsi_read(struct Scsi_Host *instance, int reg) { return( mac_scsi_regp[reg << 4] ); } -static void mac_scsi_reg_write( unsigned char reg, unsigned char value ) +static void macscsi_write(struct Scsi_Host *instance, int reg, int value) { mac_scsi_regp[reg << 4] = value; } -#include "mac_NCR5380.c" +#endif -#ifdef PSEUDO_DMA +#include "NCR5380.c" /* - * slightly optimized PIO transfer routines, experimental! - * command may time out if interrupts are left enabled + * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; + * reentering NCR5380_print_status seems to have ugly side effects */ -static inline int mac_pdma_read (struct Scsi_Host *instance, unsigned char *dst, int len) +void scsi_mac_debug (void) { - register unsigned char *d = dst; - register i = len; - register unsigned char p, tmp; - -#if (NDEBUG & NDEBUG_PSEUDO_DMA) - printk("pdma_read: reading %d bytes to %p\n", len, dst); -#endif - - mac_pdma_residual = len; - if (mac_pdma_active) { - printk("pseudo-DMA already active in pread!\n"); - return -1; - } - mac_pdma_active = 1; - mac_pdma_startaddr = (unsigned long) dst; - mac_pdma_current = (unsigned long) dst; - - /* - * Get the phase from the bus (sanity check) - * Hopefully, the phase bits are valid here ... - */ - p = NCR5380_read(STATUS_REG) & PHASE_MASK; - if (!(p & SR_IO)) { - PDMA_PRINTK("NCR5380_pread: initial phase mismatch!\n"); - NCR_PRINT_PHASE(NDEBUG_ANY); - return -1; - } - - /* - * The NCR5380 chip will only drive the SCSI bus when the - * phase specified in the appropriate bits of the TARGET COMMAND - * REGISTER match the STATUS REGISTER - */ - -#if 0 /* done in transfer_dma */ - p = PHASE_DATAIN; - NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); -#endif - - for (; i; --i) { - HSH_PRINTK(" read %d ..", i); - /* check if we were interrupted ... */ - if (!mac_pdma_active) { - printk("pwrite: interrupt detected!\n"); - break; - } - - /* - * Wait for assertion of REQ, after which the phase bits will be - * valid - */ - while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ)) - barrier(); - - HSH_PRINTK(" REQ .."); - - /* Check for phase mismatch */ - if ((tmp & PHASE_MASK) != p) { - if (!mac_pdma_active) - printk("scsi%d : phase mismatch after interrupt\n", instance->host_no); - else - printk("scsi%d : phase mismatch w/o interrupt\n", instance->host_no); - NCR_PRINT_PHASE(NDEBUG_ANY); - break; - } - - /* Do actual transfer from SCSI bus to memory */ - *d = NCR5380_read(CURRENT_SCSI_DATA_REG); - - d++; - - /* Handshake ... */ - - /* Assert ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); - HSH_PRINTK(" ACK .."); - - /* Wait for REQ to be dropped */ - while (NCR5380_read(STATUS_REG) & SR_REQ) - barrier(); - HSH_PRINTK(" /REQ .."); - - /* Drop ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - HSH_PRINTK(" /ACK !\n"); - - mac_pdma_current = (unsigned long) d; - mac_pdma_residual--; - } + unsigned long flags; + NCR5380_local_declare(); -#if (NDEBUG & NDEBUG_PSEUDO_DMA) - printk("pdma_read: read at %d bytes to %p\n", i, dst); + if (default_instance) { +#if 0 + NCR5380_setup(default_instance); + if(NCR5380_read(BUS_AND_STATUS_REG)&BASR_IRQ) #endif - - if (mac_pdma_residual) - printk("pread: leaving with residual %ld of %ld\n", - mac_pdma_residual, len); - mac_pdma_active = 0; - - /* ?? */ + save_flags(flags); + cli(); + NCR5380_print_status(default_instance); + restore_flags(flags); + } #if 0 - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_read(RESET_PARITY_INTERRUPT_REG); + polled_scsi_on = 1; #endif - return 0; } - -static inline int mac_pdma_write (struct Scsi_Host *instance, unsigned char *src, int len) -{ - register unsigned char *s = src; - register i = len; - register unsigned char p, tmp; - -#if (NDEBUG & NDEBUG_PSEUDO_DMA) - printk("pdma_write: writing %d bytes from %p\n", len, src); -#endif - - mac_pdma_residual = len; - if (mac_pdma_active) { - printk("pseudo-DMA already active in pwrite!\n"); - return -1; - } - mac_pdma_active = 1; - mac_pdma_startaddr = (unsigned long) src; - mac_pdma_current = (unsigned long) src; - - /* - * Get the phase from the bus (sanity check) - */ - p = NCR5380_read(STATUS_REG) & PHASE_MASK; - if (p & SR_IO) { - printk("NCR5380_pwrite: initial phase mismatch!\n"); - NCR_PRINT_PHASE(NDEBUG_ANY); - return -1; - } - - /* - * The NCR5380 chip will only drive the SCSI bus when the - * phase specified in the appropriate bits of the TARGET COMMAND - * REGISTER match the STATUS REGISTER - */ - -#if 0 /* already done in transfer_dma */ - p = PHASE_DATAOUT; - NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); -#endif - - for (; i; --i) { - /* check if we were interrupted ... */ - if (!mac_pdma_active) { - printk("pwrite: interrupt detected!\n"); - break; - } - - /* - * Wait for assertion of REQ, after which the phase bits will be - * valid - */ - while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ)); - - /* Check for phase mismatch */ - if ((tmp & PHASE_MASK) != p) { - if (!mac_pdma_active) - printk("scsi%d : phase mismatch after interrupt\n", instance->host_no); - else - printk("scsi%d : phase mismatch w/o interrupt\n", instance->host_no); - NCR_PRINT_PHASE(NDEBUG_ANY); - /* should we signal an error here?? */ - break; - } - - /* Do actual transfer to SCSI bus from memory */ - - NCR5380_write(OUTPUT_DATA_REG, *s); +/* + * Helper function for interrupt trouble. More ugly side effects here. + */ - s++; +void scsi_mac_polled (void) +{ + unsigned long flags; + NCR5380_local_declare(); + struct Scsi_Host *instance; - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | - ICR_ASSERT_DATA); - - /* Handshake ... assert ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | - ICR_ASSERT_DATA | ICR_ASSERT_ACK); - - /* ... wait for REQ to be dropped */ - while (NCR5380_read(STATUS_REG) & SR_REQ); - - /* and drop ACK (and DATA) ! */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - - mac_pdma_current = (unsigned long) s; - mac_pdma_residual--; - } - -#if (NDEBUG & NDEBUG_PSEUDO_DMA) - printk("pdma_write: write at %d bytes from %p\n", i, src); +#if 0 + for (instance = first_instance; instance && (instance->hostt == + the_template); instance = instance->next) + if (instance->irq == IRQ_MAC_SCSI && polled_scsi_on) { +#else + instance = default_instance; #endif + NCR5380_setup(instance); + if(NCR5380_read(BUS_AND_STATUS_REG)&BASR_IRQ) + { + printk("SCSI poll\n"); + save_flags(flags); + cli(); +#ifdef USE_WRAPPER + scsi_mac_intr(IRQ_MAC_SCSI, instance, NULL); +#else + macscsi_intr(IRQ_MAC_SCSI, instance, NULL); +#endif + restore_flags(flags); + } +#if 0 + } +#endif +} - if (mac_pdma_residual) - printk("pwrite: leaving with residual %ld of len %ld \n", - mac_pdma_residual, len); - mac_pdma_active = 0; - - return 0; -} -#endif /* PSEUDO_DMA */ #ifdef MODULE -Scsi_Host_Template driver_template = MAC_SCSI; + +Scsi_Host_Template driver_template = MAC_NCR5380; #include "scsi_module.c" #endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mac_scsi.h linux/drivers/scsi/mac_scsi.h --- v2.3.26/linux/drivers/scsi/mac_scsi.h Thu Jul 30 11:17:10 1998 +++ linux/drivers/scsi/mac_scsi.h Mon Nov 8 11:03:21 1999 @@ -1,286 +1,110 @@ /* - * mac_scsi.h -- Header file for the Macintosh native SCSI driver + * Cumana Generic NCR5380 driver defines * - * based on Roman Hodeks atari_scsi.h + * Copyright 1993, Drew Eckhardt + * Visionary Computing + * (Unix and Linux consulting and custom programming) + * drew@colorado.edu + * +1 (303) 440-4894 + * + * ALPHA RELEASE 1. + * + * For more information, please consult + * + * NCR 5380 Family + * SCSI Protocol Controller + * Databook + * + * NCR Microelectronics + * 1635 Aeroplaza Drive + * Colorado Springs, CO 80916 + * 1+ (719) 578-3400 + * 1+ (800) 334-5454 */ /* - * atari_scsi.h -- Header file for the Atari native SCSI driver - * - * Copyright 1994 Roman Hodek - * - * (Loosely based on the work of Robert De Vries' team) - * - * 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. - * + * $Log: cumana_NCR5380.h,v $ */ +#ifndef MAC_NCR5380_H +#define MAC_NCR5380_H -#ifndef MAC_SCSI_H -#define MAC_SCSI_H +#define MACSCSI_PUBLIC_RELEASE 1 -/* (I_HAVE_OVERRUNS stuff removed) */ #ifndef ASM -int mac_scsi_abort (Scsi_Cmnd *); -int mac_scsi_detect (Scsi_Host_Template *); -const char * mac_scsi_info (struct Scsi_Host *host); -int mac_scsi_queue_command (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); -int mac_scsi_reset (Scsi_Cmnd *, unsigned int); -int mac_scsi_proc_info (char *, char **, off_t, int, int, int); -#ifdef MODULE -int mac_scsi_release (struct Scsi_Host *); -#else -#define mac_scsi_release NULL -#endif - -/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher - * values should work, too; try it! (but cmd_per_lun costs memory!) */ - -/* But there seems to be a bug somewhere that requires CAN_QUEUE to be - * 2*CMD_PER_LUN. At least on a TT, no spurious timeouts seen since - * changed CMD_PER_LUN... */ - -/* Note: The Falcon currently uses 8/1 setting due to unsolved problems with - * cmd_per_lun != 1 */ - -#define MAC_SCSI_CAN_QUEUE 16 -#define MAC_SCSI_CMD_PER_LUN 8 -#define MAC_SCSI_SG_TABLESIZE SG_ALL - -#define DEFAULT_USE_TAGGED_QUEUING 0 - - -#if defined (HOSTS_C) || defined (MODULE) - -#define MAC_SCSI { NULL, NULL, NULL, \ - mac_scsi_proc_info, \ - "Macintosh NCR5380 SCSI", \ - mac_scsi_detect, \ - mac_scsi_release, \ - mac_scsi_info, \ - /* command */ NULL, \ - mac_scsi_queue_command, \ - mac_scsi_abort, \ - mac_scsi_reset, \ - /* slave_attach */ NULL, \ - /* bios_param */ NULL, \ - /* can queue */ 0, /* initialized at run-time */ \ - /* host_id */ 0, /* initialized at run-time */ \ - /* scatter gather */ 0, /* initialized at run-time */ \ - /* cmd per lun */ 0, /* initialized at run-time */ \ - /* present */ 0, \ - /* unchecked ISA DMA */ 0, \ - /* use_clustering */ DISABLE_CLUSTERING } +int macscsi_abort (Scsi_Cmnd *); +int macscsi_detect (Scsi_Host_Template *); +int macscsi_release (struct Scsi_Host *); +const char *macscsi_info (struct Scsi_Host *); +int macscsi_reset(Scsi_Cmnd *, unsigned int); +int macscsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +int macscsi_proc_info (char *buffer, char **start, off_t offset, + int length, int hostno, int inout); +#ifndef NULL +#define NULL 0 #endif -#ifndef HOSTS_C +#ifndef CMD_PER_LUN +#define CMD_PER_LUN 2 +#endif -#define NCR5380_implementation_fields /* none */ +#ifndef CAN_QUEUE +#define CAN_QUEUE 16 +#endif -#define NCR5380_read(reg) mac_scsi_reg_read( reg ) -#define NCR5380_write(reg, value) mac_scsi_reg_write( reg, value ) +#ifndef SG_TABLESIZE +#define SG_TABLESIZE SG_NONE +#endif -#define NCR5380_intr mac_scsi_intr -#define NCR5380_queue_command mac_scsi_queue_command -#define NCR5380_abort mac_scsi_abort -#define NCR5380_proc_info mac_scsi_proc_info -#define NCR5380_dma_read_setup(inst,d,c) mac_scsi_dma_setup (inst, d, c, 0) -#define NCR5380_dma_write_setup(inst,d,c) mac_scsi_dma_setup (inst, d, c, 1) -#define NCR5380_dma_residual(inst) mac_scsi_dma_residual( inst ) -#define NCR5380_dma_xfer_len(i,cmd,phase) \ - mac_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1) -#ifdef PSEUDO_DMA -#define NCR5380_pread(inst,d,l) mac_pdma_read (inst, d, l) -#define NCR5380_pwrite(inst,d,l) mac_pdma_write (inst, d, l) +#ifndef USE_TAGGED_QUEUING +#define USE_TAGGED_QUEUING 0 #endif -/* Debugging printk definitions: - * - * ARB -> arbitration - * ASEN -> auto-sense - * DMA -> DMA - * HSH -> PIO handshake - * INF -> information transfer - * INI -> initialization - * INT -> interrupt - * LNK -> linked commands - * MAIN -> NCR5380_main() control flow - * NDAT -> no data-out phase - * NWR -> no write commands - * PIO -> PIO transfers - * PDMA -> pseudo DMA (unused on MAC) - * QU -> queues - * RSL -> reselections - * SEL -> selections - * USL -> usleep cpde (unused on MAC) - * LBS -> last byte sent (unused on MAC) - * RSS -> restarting of selections - * EXT -> extended messages - * ABRT -> aborting and resetting - * TAG -> queue tag handling - * MER -> merging of consec. buffers - * - */ +#include -#if NDEBUG & NDEBUG_ARBITRATION -#define ARB_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define ARB_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_AUTOSENSE -#define ASEN_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define ASEN_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_DMA -#define DMA_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define DMA_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_HANDSHAKE -#define HSH_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define HSH_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_INFORMATION -#define INF_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define INF_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_INIT -#define INI_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define INI_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_INTR -#define INT_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define INT_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_LINKED -#define LNK_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define LNK_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_MAIN -#define MAIN_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define MAIN_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_NO_DATAOUT -#define NDAT_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define NDAT_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_NO_WRITE -#define NWR_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define NWR_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_PIO -#define PIO_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define PIO_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_PSEUDO_DMA -#define PDMA_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define PDMA_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_QUEUES -#define QU_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define QU_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_RESELECTION -#define RSL_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define RSL_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_SELECTION -#define SEL_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define SEL_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_USLEEP -#define USL_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define USL_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_LAST_BYTE_SENT -#define LBS_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define LBS_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_RESTART_SELECT -#define RSS_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define RSS_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_EXTENDED -#define EXT_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define EXT_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_ABORT -#define ABRT_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define ABRT_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_TAGS -#define TAG_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define TAG_PRINTK(format, args...) -#endif -#if NDEBUG & NDEBUG_MERGING -#define MER_PRINTK(format, args...) \ - printk(KERN_DEBUG format , ## args) -#else -#define MER_PRINTK(format, args...) -#endif +#define MAC_NCR5380 { \ +name: "Macintosh NCR5380 SCSI", \ +detect: macscsi_detect, \ +release: macscsi_release, /* Release */ \ +info: macscsi_info, \ +queuecommand: macscsi_queue_command, \ +abort: macscsi_abort, \ +reset: macscsi_reset, \ +bios_param: scsicam_bios_param, /* biosparam */ \ +can_queue: CAN_QUEUE, /* can queue */ \ +this_id: 7, /* id */ \ +sg_tablesize: SG_ALL, /* sg_tablesize */ \ +cmd_per_lun: CMD_PER_LUN, /* cmd per lun */ \ +unchecked_isa_dma: 0, /* unchecked_isa_dma */ \ +use_clustering: DISABLE_CLUSTERING \ + } -/* conditional macros for NCR5380_print_{,phase,status} */ +#ifndef HOSTS_C -#define NCR_PRINT(mask) \ - ((NDEBUG & (mask)) ? NCR5380_print(instance) : (void)0) +#define NCR5380_implementation_fields \ + int port, ctrl -#define NCR_PRINT_PHASE(mask) \ - ((NDEBUG & (mask)) ? NCR5380_print_phase(instance) : (void)0) +#define NCR5380_local_declare() \ + struct Scsi_Host *_instance -#define NCR_PRINT_STATUS(mask) \ - ((NDEBUG & (mask)) ? NCR5380_print_status(instance) : (void)0) +#define NCR5380_setup(instance) \ + _instance = instance -#define NDEBUG_ANY 0xffffffff +#define NCR5380_read(reg) macscsi_read(_instance, reg) +#define NCR5380_write(reg, value) macscsi_write(_instance, reg, value) +#define NCR5380_intr macscsi_intr +#define NCR5380_queue_command macscsi_queue_command +#define NCR5380_abort macscsi_abort +#define NCR5380_reset macscsi_reset +#define NCR5380_proc_info macscsi_proc_info -#endif /* else def HOSTS_C */ -#endif /* ndef ASM */ -#endif /* MAC_SCSI_H */ +#define BOARD_NORMAL 0 +#define BOARD_NCR53C400 1 +#endif /* ndef HOSTS_C */ +#endif /* ndef ASM */ +#endif /* MAC_NCR5380_H */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mca_53c9x.h linux/drivers/scsi/mca_53c9x.h --- v2.3.26/linux/drivers/scsi/mca_53c9x.h Fri Aug 13 15:07:03 1999 +++ linux/drivers/scsi/mca_53c9x.h Thu Nov 11 16:57:30 1999 @@ -31,7 +31,7 @@ int hostno, int inout); -#define MCA_53C9X { proc_dir: &proc_scsi_esp, \ +#define MCA_53C9X { proc_name: "esp", \ name: "NCR 53c9x SCSI", \ detect: mca_esp_detect, \ release: mca_esp_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c --- v2.3.26/linux/drivers/scsi/megaraid.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/megaraid.c Thu Nov 11 16:57:30 1999 @@ -133,13 +133,11 @@ #include #include -#if LINUX_VERSION_CODE >= 0x20100 char kernel_version[] = UTS_RELEASE; MODULE_AUTHOR ("American Megatrends Inc."); MODULE_DESCRIPTION ("AMI MegaRAID driver"); #endif -#endif #include #include @@ -157,11 +155,7 @@ #include #include -#if LINUX_VERSION_CODE < 0x20100 -#include -#else #include -#endif #include #include @@ -180,27 +174,8 @@ *================================================================ */ -#if LINUX_VERSION_CODE < 0x020100 -#define ioremap vremap -#define iounmap vfree - -/* simulate spin locks */ -typedef struct { - volatile char lock; -} spinlock_t; - -#define spin_lock_init(x) { (x)->lock = 0;} -#define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\ - (x)->lock=1; save_flags(flags);\ - cli();} -#define spin_unlock_irqrestore(x,flags) { (x)->lock=0; restore_flags(flags);} - -#endif - -#if LINUX_VERSION_CODE >= 0x020100 #define queue_task_irq(a,b) queue_task(a,b) #define queue_task_irq_off(a,b) queue_task(a,b) -#endif #define MAX_SERBUF 160 #define COM_BASE 0x2f8 @@ -294,11 +269,9 @@ XX scsi id on each channel. Used for Madrona motherboard, where SAF_TE processor id cannot be scanned */ static char *megaraid; -#if LINUX_VERSION_CODE > 0x20100 #ifdef MODULE MODULE_PARM(megaraid, "s"); #endif -#endif static int skip_id; static int numCtlrs = 0; @@ -318,12 +291,6 @@ #endif volatile static spinlock_t mega_lock; -struct proc_dir_entry proc_scsi_megaraid = -{ - PROC_SCSI_MEGARAID, 8, "megaraid", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #if SERDEBUG static char strbuf[MAX_SERBUF + 1]; @@ -930,9 +897,7 @@ megaCfg = (mega_host_config *) devp; mbox = (mega_mailbox *)tmpBox; -#if LINUX_VERSION_CODE >= 0x20100 spin_lock_irqsave (&io_request_lock, flags); -#endif while (megaCfg->host->irq == irq) { @@ -1028,9 +993,7 @@ } -#if LINUX_VERSION_CODE >= 0x20100 spin_unlock_irqrestore (&io_request_lock, flags); -#endif } /*==================================================*/ @@ -1450,20 +1413,11 @@ u16 pciIdx = 0; u16 numFound = 0; -#if LINUX_VERSION_CODE < 0x20100 - while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) { - -#if 0 - } /* keep auto-indenters happy */ -#endif -#else - struct pci_dev *pdev = pci_devices; while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) { pciBus = pdev->bus->number; pciDevFun = pdev->devfn; -#endif if ((flag & BOARD_QUARTZ) && (skip_id == -1)) { u16 magic; pcibios_read_config_word (pciBus, pciDevFun, @@ -1555,14 +1509,8 @@ { int count = 0; - pHostTmpl->proc_dir = &proc_scsi_megaraid; + pHostTmpl->proc_name = "megaraid"; -#if LINUX_VERSION_CODE < 0x20100 - if (!pcibios_present ()) { - printk (KERN_WARNING "megaraid: PCI bios not present." CRLFSTR); - return 0; - } -#endif skip_id = -1; if (megaraid && !strncmp(megaraid,"skip",strlen("skip"))) { if (megaraid[4] != '\0') { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/megaraid.h linux/drivers/scsi/megaraid.h --- v2.3.26/linux/drivers/scsi/megaraid.h Thu Aug 26 13:05:39 1999 +++ linux/drivers/scsi/megaraid.h Thu Nov 11 17:03:50 1999 @@ -605,8 +605,6 @@ mega_scb scbList[MAX_COMMANDS]; } mega_host_config; -extern struct proc_dir_entry proc_scsi_megaraid; - const char *megaraid_info(struct Scsi_Host *); int megaraid_detect(Scsi_Host_Template *); int megaraid_release(struct Scsi_Host *); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mesh.c linux/drivers/scsi/mesh.c --- v2.3.26/linux/drivers/scsi/mesh.c Fri Sep 10 23:57:31 1999 +++ linux/drivers/scsi/mesh.c Thu Nov 11 16:57:30 1999 @@ -65,11 +65,6 @@ #define ALLOW_DEBUG(tgt) ((mesh_debug_targets >> (tgt)) & 1) #define DEBUG_TARGET(cmd) ((cmd) && ALLOW_DEBUG((cmd)->target)) -struct proc_dir_entry proc_scsi_mesh = { - PROC_SCSI_MESH, 4, "mesh", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #undef MESH_DBG #define N_DBG_LOG 50 #define N_DBG_SLOG 20 diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mesh.h linux/drivers/scsi/mesh.h --- v2.3.26/linux/drivers/scsi/mesh.h Tue Aug 31 17:29:14 1999 +++ linux/drivers/scsi/mesh.h Thu Nov 11 16:57:30 1999 @@ -7,8 +7,6 @@ #ifndef _MESH_H #define _MESH_H -extern struct proc_dir_entry proc_scsi_mesh; - int mesh_detect(Scsi_Host_Template *); int mesh_command(Scsi_Cmnd *); int mesh_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); @@ -16,7 +14,7 @@ int mesh_reset(Scsi_Cmnd *, unsigned int); #define SCSI_MESH { \ - proc_dir: &proc_scsi_mesh, \ + proc_name: "mesh", \ name: "MESH", \ detect: mesh_detect, \ command: mesh_command, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mvme16x.c linux/drivers/scsi/mvme16x.c --- v2.3.26/linux/drivers/scsi/mvme16x.c Mon Jul 5 20:35:18 1999 +++ linux/drivers/scsi/mvme16x.c Thu Nov 11 16:57:30 1999 @@ -21,11 +21,6 @@ #include -struct proc_dir_entry proc_scsi_mvme16x = { - PROC_SCSI_MVME16x, 7, "MVME16x", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - extern ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, u32 base, int io_port, int irq, int dma, long long options, int clock); @@ -45,7 +40,7 @@ if (called) return 0; - tpnt->proc_dir = &proc_scsi_mvme16x; + tpnt->proc_name = "MVME16x" options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/mvme16x.h linux/drivers/scsi/mvme16x.h --- v2.3.26/linux/drivers/scsi/mvme16x.h Wed Jun 16 19:29:21 1999 +++ linux/drivers/scsi/mvme16x.h Thu Nov 11 16:57:30 1999 @@ -26,8 +26,6 @@ #if defined(HOSTS_C) || defined(MODULE) #include -extern struct proc_dir_entry proc_scsi_mvme16x; - #define MVME16x_SCSI {name: "MVME16x NCR53c710 SCSI", \ detect: mvme16x_scsi_detect, \ queuecommand: NCR53c7xx_queue_command, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.3.26/linux/drivers/scsi/ncr53c8xx.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/ncr53c8xx.c Thu Nov 11 16:57:30 1999 @@ -733,10 +733,6 @@ ** /proc directory entry and proc_info function */ -static struct proc_dir_entry proc_scsi_ncr53c8xx = { - PROC_SCSI_NCR53C8XX, 9, "ncr53c8xx", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; #ifdef SCSI_NCR_PROC_INFO_SUPPORT static int ncr53c8xx_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int func); @@ -9383,7 +9379,7 @@ ncr_debug = driver_setup.debug; #endif - tpnt->proc_dir = &proc_scsi_ncr53c8xx; + tpnt->proc_name = "ncr53c8xx"; #ifdef SCSI_NCR_PROC_INFO_SUPPORT tpnt->proc_info = ncr53c8xx_proc_info; #endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/oktagon_esp.h linux/drivers/scsi/oktagon_esp.h --- v2.3.26/linux/drivers/scsi/oktagon_esp.h Thu Aug 12 10:28:34 1999 +++ linux/drivers/scsi/oktagon_esp.h Thu Nov 11 16:57:30 1999 @@ -40,7 +40,7 @@ int hostno, int inout); #define SCSI_OKTAGON_ESP { \ - proc_dir: &proc_scsi_esp, \ + proc_name: "esp-oktagon", \ proc_info: &esp_proc_info, \ name: "BSC Oktagon SCSI", \ detect: oktagon_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c --- v2.3.26/linux/drivers/scsi/pas16.c Thu Aug 12 11:10:58 1999 +++ linux/drivers/scsi/pas16.c Thu Nov 11 16:57:30 1999 @@ -131,10 +131,6 @@ #include #include -struct proc_dir_entry proc_scsi_pas16 = { - PROC_SCSI_PAS16, 5, "pas16", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; static int pas_maxi = 0; static int pas_wmaxi = 0; static unsigned short pas16_addr = 0; @@ -392,7 +388,7 @@ unsigned short io_port; int count; - tpnt->proc_dir = &proc_scsi_pas16; + tpnt->proc_name = "pas16"; tpnt->proc_info = &pas16_proc_info; if (pas16_addr != 0) { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c --- v2.3.26/linux/drivers/scsi/pci2000.c Fri Sep 10 23:57:32 1999 +++ linux/drivers/scsi/pci2000.c Thu Nov 11 16:57:30 1999 @@ -53,15 +53,7 @@ #include "pci2000.h" #include "psi_roy.h" -#if LINUX_VERSION_CODE >= LINUXVERSION(2,1,95) #include -#endif -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,93) -#include -#endif - -struct proc_dir_entry Proc_Scsi_Pci2000 = - { PROC_SCSI_PCI2000, 7, "pci2000", S_IFDIR | S_IRUGO | S_IXUGO, 2 }; //#define DEBUG 1 @@ -240,23 +232,13 @@ int pun; int bus; int z; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - int flags; -#else /* version >= v2.1.95 */ unsigned long flags; -#endif /* version >= v2.1.95 */ -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* Disable interrupts, if they aren't already disabled. */ - save_flags (flags); - cli (); -#else /* version >= v2.1.95 */ /* * Disable interrupts, if they aren't already disabled and acquire * the I/O spinlock. */ spin_lock_irqsave (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ DEB(printk ("\npci2000 recieved interrupt ")); for ( z = 0; z < NumAdapters; z++ ) // scan for interrupt to process @@ -345,20 +327,12 @@ OpDone (SCpnt, DID_OK << 16); irq_return:; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* - * Restore the original flags which will enable interrupts - * if and only if they were enabled on entry. - */ - restore_flags (flags); -#else /* version >= v2.1.95 */ /* * Release the I/O spinlock and restore the original flags * which will enable interrupts if and only if they were * enabled on entry. */ spin_unlock_irqrestore (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ } /**************************************************************** * Name: Pci2000_QueueCommand @@ -615,27 +589,15 @@ PADAPTER2000 padapter; int z, zz; int setirq; -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) struct pci_dev *pdev = NULL; -#else - UCHAR pci_bus, pci_device_fn; -#endif -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) if ( !pci_present () ) -#else - if ( !pcibios_present () ) -#endif { printk ("pci2000: PCI BIOS not present\n"); return 0; } -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL ) -#else - while ( !pcibios_find_device (VENDOR_PSI, DEVICE_ROY_1, found, &pci_bus, &pci_device_fn) ) -#endif { pshost = scsi_register (tpnt, sizeof(ADAPTER2000)); padapter = HOSTDATA(pshost); @@ -658,11 +620,7 @@ if ( WaitReady (padapter) ) goto unregister; -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) pshost->irq = pdev->irq; -#else - pcibios_read_config_byte (pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pshost->irq); -#endif setirq = 1; padapter->irqOwned = 0; for ( z = 0; z < installed; z++ ) // scan for shared interrupts @@ -756,11 +714,7 @@ PADAPTER2000 padapter = HOSTDATA (pshost); if ( padapter->irqOwned ) -#if LINUX_VERSION_CODE < LINUXVERSION(1,3,70) - free_irq (pshost->irq); -#else /* version >= v1.3.70 */ free_irq (pshost->irq, padapter); -#endif /* version >= v1.3.70 */ release_region (pshost->io_port, pshost->n_io_port); scsi_unregister(pshost); return 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/pci2000.h linux/drivers/scsi/pci2000.h --- v2.3.26/linux/drivers/scsi/pci2000.h Wed Aug 18 16:44:26 1999 +++ linux/drivers/scsi/pci2000.h Thu Nov 11 17:03:50 1999 @@ -200,13 +200,10 @@ #define NULL 0 #endif -extern struct proc_dir_entry Proc_Scsi_Pci2000; - -#if LINUX_VERSION_CODE >= LINUXVERSION(2,1,75) #define PCI2000 { \ next: NULL, \ module: NULL, \ - proc_dir: &Proc_Scsi_Pci2000, \ + proc_name: "pci2000", \ proc_info: NULL, /* let's not bloat the kernel */ \ name: "PCI-2000 SCSI Intelligent Disk Controller",\ detect: Pci2000_Detect, \ @@ -232,27 +229,4 @@ use_clustering: DISABLE_CLUSTERING, \ use_new_eh_code: 0 \ } -#else -#define PCI2000 { NULL, NULL, \ - &Proc_Scsi_Pci2000,/* proc_dir_entry */ \ - NULL, \ - "PCI-2000 SCSI Intelligent Disk Controller",\ - Pci2000_Detect, \ - Pci2000_Release, \ - NULL, \ - Pci2000_Command, \ - Pci2000_QueueCommand, \ - Pci2000_Abort, \ - Pci2000_Reset, \ - NULL, \ - Pci2000_BiosParam, \ - 16, \ - -1, \ - 16, \ - 1, \ - 0, \ - 0, \ - DISABLE_CLUSTERING } -#endif - #endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/pci2220i.c linux/drivers/scsi/pci2220i.c --- v2.3.26/linux/drivers/scsi/pci2220i.c Fri Sep 10 23:57:32 1999 +++ linux/drivers/scsi/pci2220i.c Thu Nov 11 16:57:30 1999 @@ -47,12 +47,7 @@ #include "hosts.h" #include "pci2220i.h" -#if LINUX_VERSION_CODE >= LINUXVERSION(2,1,95) #include -#endif -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,93) -#include -#endif #define PCI2220I_VERSION "1.11" //#define READ_CMD IDE_COMMAND_READ @@ -62,10 +57,6 @@ #define WRITE_CMD IDE_CMD_WRITE_MULTIPLE #define MAX_BUS_MASTER_BLOCKS SECTORSXFER // This is the maximum we can bus master - -struct proc_dir_entry Proc_Scsi_Pci2220i = - { PROC_SCSI_PCI2220I, 8, "pci2220i", S_IFDIR | S_IRUGO | S_IXUGO, 2 }; - //#define DEBUG 1 #ifdef DEBUG @@ -725,23 +716,13 @@ POUR_DEVICE pdev = padapter->pdev; UCHAR status = IDE_STATUS_BUSY; UCHAR temp, temp1; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - int flags; -#else /* version >= v2.1.95 */ unsigned long flags; -#endif /* version >= v2.1.95 */ -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* Disable interrupts, if they aren't already disabled. */ - save_flags (flags); - cli (); -#else /* version >= v2.1.95 */ /* * Disable interrupts, if they aren't already disabled and acquire * the I/O spinlock. */ spin_lock_irqsave (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ DEB (printk ("\nPCI2220I: Timeout expired ")); if ( padapter->failinprog ) @@ -866,20 +847,12 @@ OpDone (padapter, DecodeError (padapter, status)); timerExpiryDone:; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* - * Restore the original flags which will enable interrupts - * if and only if they were enabled on entry. - */ - restore_flags (flags); -#else /* version >= v2.1.95 */ /* * Release the I/O spinlock and restore the original flags * which will enable interrupts if and only if they were * enabled on entry. */ spin_unlock_irqrestore (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ } /**************************************************************** * Name: SetReconstruct :LOCAL @@ -920,23 +893,13 @@ USHORT minmode; ULONG zl; UCHAR zc; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - int flags; -#else /* version >= v2.1.95 */ unsigned long flags; -#endif /* version >= v2.1.95 */ -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* Disable interrupts, if they aren't already disabled. */ - save_flags (flags); - cli (); -#else /* version >= v2.1.95 */ /* * Disable interrupts, if they aren't already disabled and acquire * the I/O spinlock. */ spin_lock_irqsave (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ padapter = (PADAPTER2220I)data; if ( padapter->SCpnt ) @@ -1132,20 +1095,12 @@ padapter->reconPhase = RECON_PHASE_LAST; reconTimerExpiry:; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* - * Restore the original flags which will enable interrupts - * if and only if they were enabled on entry. - */ - restore_flags (flags); -#else /* version >= v2.1.95 */ /* * Release the I/O spinlock and restore the original flags * which will enable interrupts if and only if they were * enabled on entry. */ spin_unlock_irqrestore (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ } /**************************************************************** * Name: Irq_Handler :LOCAL @@ -1169,23 +1124,13 @@ UCHAR status1; int z; ULONG zl; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - int flags; -#else /* version >= v2.1.95 */ unsigned long flags; -#endif /* version >= v2.1.95 */ -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* Disable interrupts, if they aren't already disabled. */ - save_flags (flags); - cli (); -#else /* version >= v2.1.95 */ /* * Disable interrupts, if they aren't already disabled and acquire * the I/O spinlock. */ spin_lock_irqsave (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ // DEB (printk ("\npci2220i recieved interrupt\n")); @@ -1513,20 +1458,12 @@ OpDone (padapter, zl); irq_return:; -#if LINUX_VERSION_CODE < LINUXVERSION(2,1,95) - /* - * Restore the original flags which will enable interrupts - * if and only if they were enabled on entry. - */ - restore_flags (flags); -#else /* version >= v2.1.95 */ /* * Release the I/O spinlock and restore the original flags * which will enable interrupts if and only if they were * enabled on entry. */ spin_unlock_irqrestore (&io_request_lock, flags); -#endif /* version >= v2.1.95 */ } /**************************************************************** * Name: Pci2220i_QueueCommand @@ -1796,27 +1733,15 @@ int setirq; UCHAR spigot1 = FALSE; UCHAR spigot2 = FALSE; -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) struct pci_dev *pdev = NULL; -#else - UCHAR pci_bus, pci_device_fn; -#endif -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) if ( !pci_present () ) -#else - if ( !pcibios_present () ) -#endif { printk ("pci2220i: PCI BIOS not present\n"); return 0; } -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_DALE_1, pdev)) != NULL ) -#else - while ( !pcibios_find_device (VENDOR_PSI, DEVICE_DALE_1, found, &pci_bus, &pci_device_fn) ) -#endif { pshost = scsi_register (tpnt, sizeof(ADAPTER2220I)); padapter = HOSTDATA(pshost); @@ -1854,11 +1779,7 @@ if ( !inb_p (padapter->regScratchPad + DALE_NUM_DRIVES) ) // if no devices on this board goto unregister; -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) pshost->irq = pdev->irq; -#else - pcibios_read_config_byte (pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pshost->irq); -#endif setirq = 1; for ( z = 0; z < installed; z++ ) // scan for shared interrupts { @@ -1881,11 +1802,7 @@ if ( !padapter->kBuffer ) { printk ("Unable to allocate DMA buffer for PCI-2220I controller.\n"); -#if LINUX_VERSION_CODE < LINUXVERSION(1,3,70) - free_irq (pshost->irq); -#else /* version >= v1.3.70 */ free_irq (pshost->irq, padapter); -#endif /* version >= v1.3.70 */ goto unregister; } PsiHost[installed] = pshost; // save SCSI_HOST pointer @@ -2068,11 +1985,7 @@ outb_p (DiskMirror[1].status, padapter->regScratchPad + DALE_RAID_1_STATUS); if ( padapter->irqOwned ) -#if LINUX_VERSION_CODE < LINUXVERSION(1,3,70) - free_irq (pshost->irq); -#else /* version >= v1.3.70 */ free_irq (pshost->irq, padapter); -#endif /* version >= v1.3.70 */ release_region (pshost->io_port, pshost->n_io_port); kfree (padapter->kBuffer); scsi_unregister(pshost); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/pci2220i.h linux/drivers/scsi/pci2220i.h --- v2.3.26/linux/drivers/scsi/pci2220i.h Wed Aug 18 16:44:27 1999 +++ linux/drivers/scsi/pci2220i.h Thu Nov 11 17:03:51 1999 @@ -293,13 +293,10 @@ #define NULL 0 #endif -extern struct proc_dir_entry Proc_Scsi_Pci2220i; - -#if LINUX_VERSION_CODE >= LINUXVERSION(2,1,75) #define PCI2220I { \ next: NULL, \ module: NULL, \ - proc_dir: &Proc_Scsi_Pci2220i, \ + proc_name: "pci2220i", \ proc_info: NULL, /* let's not bloat the kernel */\ name: "PCI-2220I EIDE Disk Controller", \ detect: Pci2220i_Detect, \ @@ -325,27 +322,4 @@ use_clustering: DISABLE_CLUSTERING, \ use_new_eh_code: 0 \ } -#else -#define PCI2220I { NULL, NULL, \ - &Proc_Scsi_Pci2220i,/* proc_dir_entry */\ - NULL, \ - "PCI-2220I EIDE Disk Controller", \ - Pci2220i_Detect, \ - Pci2220i_Release, \ - NULL, \ - Pci2220i_Command, \ - Pci2220i_QueueCommand, \ - Pci2220i_Abort, \ - Pci2220i_Reset, \ - NULL, \ - Pci2220i_BiosParam, \ - 1, \ - -1, \ - SG_NONE, \ - 1, \ - 0, \ - 0, \ - DISABLE_CLUSTERING } -#endif - #endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/pluto.c linux/drivers/scsi/pluto.c --- v2.3.26/linux/drivers/scsi/pluto.c Tue Aug 31 17:29:14 1999 +++ linux/drivers/scsi/pluto.c Thu Nov 11 16:57:30 1999 @@ -39,11 +39,6 @@ #define PLND(x) #endif -struct proc_dir_entry proc_scsi_pluto = { - PROC_SCSI_PLUTO, 5, "pluto", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - static struct ctrl_inquiry { struct Scsi_Host host; struct pluto pluto; @@ -98,7 +93,7 @@ fc_channel *fc; Scsi_Device dev; - tpnt->proc_dir = &proc_scsi_pluto; + tpnt->proc_name = "pluto"; fcscount = 0; for_each_online_fc_channel(fc) { if (!fc->posmap) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ppa.h linux/drivers/scsi/ppa.h --- v2.3.26/linux/drivers/scsi/ppa.h Wed Aug 18 16:44:59 1999 +++ linux/drivers/scsi/ppa.h Thu Nov 11 17:04:13 1999 @@ -138,10 +138,7 @@ static void ppa_interrupt(void *); static int ppa_out(int, char *, int); -struct proc_dir_entry proc_scsi_ppa = -{PROC_SCSI_PPA, 3, "ppa", S_IFDIR | S_IRUGO | S_IXUGO, 2}; #else -extern struct proc_dir_entry proc_scsi_ppa; #define ppa_release 0 #endif @@ -154,7 +151,7 @@ int ppa_proc_info(char *, char **, off_t, int, int, int); int ppa_biosparam(Disk *, kdev_t, int *); -#define PPA { proc_dir: &proc_scsi_ppa, \ +#define PPA { proc_name: "ppa", \ proc_info: ppa_proc_info, \ name: "Iomega VPI0 (ppa) interface",\ detect: ppa_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/psi240i.c linux/drivers/scsi/psi240i.c --- v2.3.26/linux/drivers/scsi/psi240i.c Fri Sep 10 23:57:32 1999 +++ linux/drivers/scsi/psi240i.c Thu Nov 11 16:57:30 1999 @@ -46,9 +46,6 @@ #include -struct proc_dir_entry Proc_Scsi_Psi240i = - { PROC_SCSI_PSI240I, 7, "psi240i", S_IFDIR | S_IRUGO | S_IXUGO, 2 }; - //#define DEBUG 1 #ifdef DEBUG diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/psi240i.h linux/drivers/scsi/psi240i.h --- v2.3.26/linux/drivers/scsi/psi240i.h Sun Dec 27 22:19:22 1998 +++ linux/drivers/scsi/psi240i.h Thu Nov 11 16:57:30 1999 @@ -318,9 +318,7 @@ #define NULL 0 #endif -extern struct proc_dir_entry Proc_Scsi_Psi240i; - -#define PSI240I { proc_dir: &Proc_Scsi_Psi240i,/* proc_dir_entry */ \ +#define PSI240I { proc_name: "psi240i", \ name: "PSI-240I EIDE Disk Controller",\ detect: Psi240i_Detect, \ command: Psi240i_Command, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c --- v2.3.26/linux/drivers/scsi/qlogicfas.c Fri Sep 10 23:57:32 1999 +++ linux/drivers/scsi/qlogicfas.c Thu Nov 11 16:57:30 1999 @@ -131,11 +131,6 @@ #include "qlogicfas.h" #include -static struct proc_dir_entry proc_scsi_qlogicfas = { - PROC_SCSI_QLOGICFAS, 6, "qlogicfas", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /*----------------------------------------------------------------*/ /* driver state info, local to driver */ static int qbase = 0; /* Port */ @@ -550,7 +545,7 @@ struct Scsi_Host *hreg; /* registered host structure */ unsigned long flags; -host->proc_dir = &proc_scsi_qlogicfas; +host->proc_name = "qlogicfas"; /* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the address - I check 230 first since MIDI cards are typically at 330 diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c --- v2.3.26/linux/drivers/scsi/qlogicfc.c Mon Oct 4 15:49:29 1999 +++ linux/drivers/scsi/qlogicfc.c Thu Nov 11 16:57:30 1999 @@ -698,13 +698,6 @@ static void isp2x00_print_status_entry(struct Status_Entry *); #endif -static struct proc_dir_entry proc_scsi_isp2x00 = -{ - PROC_SCSI_QLOGICFC, 7, "isp2x00", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - - static inline void isp2x00_enable_irqs(struct Scsi_Host *host) { outw(ISP_EN_INT | ISP_EN_RISC, host->io_port + PCI_INTER_CTL); @@ -733,7 +726,7 @@ device_ids[0] = PCI_DEVICE_ID_QLOGIC_ISP2100; device_ids[1] = PCI_DEVICE_ID_QLOGIC_ISP2200; - tmpt->proc_dir = &proc_scsi_isp2x00; + tmpt->proc_name = "isp2x00"; if (pci_present() == 0) { printk("qlogicfc : PCI not present\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c --- v2.3.26/linux/drivers/scsi/qlogicisp.c Fri Sep 10 23:57:32 1999 +++ linux/drivers/scsi/qlogicisp.c Thu Nov 11 16:57:30 1999 @@ -535,12 +535,6 @@ static void isp1020_print_status_entry(struct Status_Entry *); #endif -static struct proc_dir_entry proc_scsi_isp1020 = { - PROC_SCSI_QLOGICISP, 7, "isp1020", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - - static inline void isp1020_enable_irqs(struct Scsi_Host *host) { outw(ISP_EN_INT|ISP_EN_RISC, host->io_port + PCI_INTF_CTL); @@ -562,7 +556,7 @@ ENTER("isp1020_detect"); - tmpt->proc_dir = &proc_scsi_isp1020; + tmpt->proc_name = "isp1020"; if (pci_present() == 0) { printk("qlogicisp : PCI not present\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c --- v2.3.26/linux/drivers/scsi/qlogicpti.c Fri Sep 10 23:57:32 1999 +++ linux/drivers/scsi/qlogicpti.c Thu Nov 11 16:57:30 1999 @@ -132,11 +132,6 @@ QLOGICISP_REQ_QUEUE_LEN) #define RES_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, RES_QUEUE_LEN) -static struct proc_dir_entry proc_scsi_qlogicpti = { - PROC_SCSI_QLOGICPTI, 7, "qlogicpti", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - static inline void qlogicpti_enable_irqs(struct qlogicpti_regs *qregs) { qregs->sbus_ctrl = SBUS_CTRL_ERIRQ | SBUS_CTRL_GENAB; @@ -596,7 +591,7 @@ int qpti_node; int is_pti; - tpnt->proc_dir = &proc_scsi_qlogicpti; + tpnt->proc_name = "qlogicpti"; qptichain = 0; if(!SBus_chain) return 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c --- v2.3.26/linux/drivers/scsi/scsi.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/scsi/scsi.c Thu Nov 11 16:57:30 1999 @@ -70,6 +70,14 @@ #undef USE_STATIC_SCSI_MEMORY +struct proc_dir_entry *proc_scsi = NULL; + +#ifdef CONFIG_PROC_FS +static int scsi_proc_info(char *buffer, char **start, off_t offset, + int length, int inout); +static void scsi_dump_status(int level); +#endif + /* static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $"; */ @@ -141,21 +149,6 @@ volatile struct Scsi_Host *host_active = NULL; -#if CONFIG_PROC_FS -/* - * This is the pointer to the /proc/scsi code. - * It is only initialized to !=0 if the scsi code is present - */ -struct proc_dir_entry proc_scsi_scsi = -{ - PROC_SCSI_SCSI, 4, "scsi", - S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, 0, - NULL, - NULL, NULL, - NULL, NULL, NULL -}; -#endif - const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = { @@ -194,20 +187,12 @@ extern void scsi_old_done(Scsi_Cmnd * SCpnt); extern void scsi_old_times_out(Scsi_Cmnd * SCpnt); -#if CONFIG_PROC_FS -extern int (*dispatch_scsi_info_ptr) (int ino, char *buffer, char **start, - off_t offset, int length, int inout); -extern int dispatch_scsi_info(int ino, char *buffer, char **start, - off_t offset, int length, int inout); -#endif - #define SCSI_BLOCK(DEVICE, HOST) \ ((HOST->block && host_active && HOST != host_active) \ || ((HOST)->can_queue && HOST->host_busy >= HOST->can_queue) \ || ((HOST)->host_blocked) \ || ((DEVICE) != NULL && (DEVICE)->device_blocked) ) -static void scsi_dump_status(int level); struct dev_info { @@ -1997,18 +1982,23 @@ #endif /* Yes we're here... */ -#if CONFIG_PROC_FS - dispatch_scsi_info_ptr = dispatch_scsi_info; + + /* + * This makes /proc/scsi and /proc/scsi/scsi visible. + */ +#ifdef CONFIG_PROC_FS + proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0); + if (!proc_scsi) { + printk (KERN_ERR "cannot init /proc/scsi\n"); + return -ENOMEM; + } + + create_proc_info_entry ("scsi/scsi", 0, 0, scsi_proc_info); #endif /* Init a few things so we can "malloc" memory. */ scsi_loadable_module_flag = 0; - /* Register the /proc/scsi/scsi entry */ -#if CONFIG_PROC_FS - proc_scsi_register(0, &proc_scsi_scsi); -#endif - /* initialize all hosts */ scsi_init(); @@ -2114,8 +2104,8 @@ #ifdef CONFIG_PROC_FS -int scsi_proc_info(char *buffer, char **start, off_t offset, int length, - int hostno, int inout) +static int scsi_proc_info(char *buffer, char **start, off_t offset, + int length, int inout) { Scsi_Cmnd *SCpnt; struct Scsi_Device_Template *SDTpnt; @@ -2191,7 +2181,7 @@ * where token is one of [error,scan,mlqueue,mlcomplete,llqueue, * llcomplete,hlqueue,hlcomplete] */ -#if CONFIG_SCSI_LOGGING /* { */ +#ifdef CONFIG_SCSI_LOGGING /* { */ if (!strncmp("log", buffer + 5, 3)) { char *token; @@ -2627,7 +2617,7 @@ scsi_hosts = tpnt; /* Add the new driver to /proc/scsi */ -#if CONFIG_PROC_FS +#ifdef CONFIG_PROC_FS build_proc_dir_entries(tpnt); #endif @@ -2893,33 +2883,28 @@ for (shpnt = scsi_hostlist; shpnt; shpnt = sh1) { sh1 = shpnt->next; - if (shpnt->hostt == tpnt) { - if (shpnt->loaded_as_module) { - pcount = next_scsi_host; - /* Remove the /proc/scsi directory entry */ -#if CONFIG_PROC_FS - proc_scsi_unregister(tpnt->proc_dir, - shpnt->host_no + PROC_SCSI_FILE); -#endif - if (tpnt->release) - (*tpnt->release) (shpnt); - else { - /* This is the default case for the release function. - * It should do the right thing for most correctly - * written host adapters. - */ - if (shpnt->irq) - free_irq(shpnt->irq, NULL); - if (shpnt->dma_channel != 0xff) - free_dma(shpnt->dma_channel); - if (shpnt->io_port && shpnt->n_io_port) - release_region(shpnt->io_port, shpnt->n_io_port); - } - if (pcount == next_scsi_host) - scsi_unregister(shpnt); - tpnt->present--; - } - } + if (shpnt->hostt != tpnt || !shpnt->loaded_as_module) + continue; + pcount = next_scsi_host; + /* Remove the /proc/scsi directory entry */ + remove_proc_entry(shpnt->proc_name, tpnt->proc_dir); + if (tpnt->release) + (*tpnt->release) (shpnt); + else { + /* This is the default case for the release function. + * It should do the right thing for most correctly + * written host adapters. + */ + if (shpnt->irq) + free_irq(shpnt->irq, NULL); + if (shpnt->dma_channel != 0xff) + free_dma(shpnt->dma_channel); + if (shpnt->io_port && shpnt->n_io_port) + release_region(shpnt->io_port, shpnt->n_io_port); + } + if (pcount == next_scsi_host) + scsi_unregister(shpnt); + tpnt->present--; } /* @@ -2959,9 +2944,7 @@ break; } /* Rebuild the /proc/scsi directory entries */ -#if CONFIG_PROC_FS - proc_scsi_unregister(tpnt->proc_dir, tpnt->proc_dir->low_ino); -#endif + remove_proc_entry(tpnt->proc_name, proc_scsi); MOD_DEC_USE_COUNT; } @@ -3146,6 +3129,7 @@ #endif /* CONFIG_MODULES */ +#ifdef CONFIG_PROC_FS /* * Function: scsi_dump_status * @@ -3166,8 +3150,7 @@ */ static void scsi_dump_status(int level) { -#if CONFIG_PROC_FS -#if CONFIG_SCSI_LOGGING /* { */ +#ifdef CONFIG_SCSI_LOGGING /* { */ int i; struct Scsi_Host *shpnt; Scsi_Cmnd *SCpnt; @@ -3246,8 +3229,8 @@ } /* printk("wait_for_request = %p\n", &wait_for_request); */ #endif /* CONFIG_SCSI_LOGGING */ /* } */ -#endif /* CONFIG_PROC_FS */ } +#endif /* CONFIG_PROC_FS */ #ifdef MODULE @@ -3257,19 +3240,19 @@ int has_space = 0; /* - * This makes /proc/scsi visible. + * This makes /proc/scsi and /proc/scsi/scsi visible. */ -#if CONFIG_PROC_FS - dispatch_scsi_info_ptr = dispatch_scsi_info; +#ifdef CONFIG_PROC_FS + proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0); + if (!proc_scsi) { + printk (KERN_ERR "cannot init /proc/scsi\n"); + return -ENOMEM; + } + create_proc_info_entry ("scsi/scsi", 0, 0, scsi_proc_info); #endif scsi_loadable_module_flag = 1; - /* Register the /proc/scsi/scsi entry */ -#if CONFIG_PROC_FS - proc_scsi_register(0, &proc_scsi_scsi); -#endif - dma_sectors = PAGE_SIZE / SECTOR_SIZE; scsi_dma_free_sectors = dma_sectors; /* @@ -3316,13 +3299,12 @@ { remove_bh(SCSI_BH); -#if CONFIG_PROC_FS - proc_scsi_unregister(0, PROC_SCSI_SCSI); - +#ifdef CONFIG_PROC_FS /* No, we're not here anymore. Don't show the /proc/scsi files. */ - dispatch_scsi_info_ptr = 0L; + remove_proc_entry ("scsi/scsi", 0); + remove_proc_entry ("scsi", 0); #endif - + /* * Free up the DMA pool. */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h --- v2.3.26/linux/drivers/scsi/scsi.h Mon Oct 4 15:49:30 1999 +++ linux/drivers/scsi/scsi.h Thu Nov 11 17:03:44 1999 @@ -16,6 +16,7 @@ #define _SCSI_H #include /* for CONFIG_SCSI_LOGGING */ +#include /* * Some of the public constants are being moved to this file. @@ -404,6 +405,7 @@ extern int max_scsi_hosts; extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int); +extern struct proc_dir_entry *proc_scsi; extern void print_command(unsigned char *); extern void print_sense(const char *, Scsi_Cmnd *); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c --- v2.3.26/linux/drivers/scsi/scsi_debug.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/scsi/scsi_debug.c Thu Nov 11 16:57:30 1999 @@ -30,13 +30,6 @@ #include -struct proc_dir_entry proc_scsi_scsi_debug = -{ - PROC_SCSI_SCSI_DEBUG, 10, "scsi_debug", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - - /* A few options that we want selected */ #define NR_HOSTS_PRESENT 20 @@ -558,7 +551,7 @@ int i; for (i = 0; i < NR_HOSTS_PRESENT; i++) { - tpnt->proc_dir = &proc_scsi_scsi_debug; + tpnt->proc_name = "scsi_debug"; /* Huh? In the loop??? */ scsi_register(tpnt, 0); } return NR_HOSTS_PRESENT; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c --- v2.3.26/linux/drivers/scsi/scsi_ioctl.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/scsi_ioctl.c Thu Nov 11 16:57:30 1999 @@ -404,7 +404,7 @@ put_user(dev->id + (dev->lun << 8) + (dev->channel << 16) - + ((dev->host->hostt->proc_dir->low_ino & 0xff) << 24), + + ((dev->host->host_no & 0xff) << 24), &((Scsi_Idlun *) arg)->dev_id); put_user(dev->host->unique_id, &((Scsi_Idlun *) arg)->host_unique_id); return 0; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/scsi_proc.c linux/drivers/scsi/scsi_proc.c --- v2.3.26/linux/drivers/scsi/scsi_proc.c Tue Sep 7 12:14:06 1999 +++ linux/drivers/scsi/scsi_proc.c Thu Nov 11 16:57:30 1999 @@ -27,6 +27,9 @@ #include #include #include + +#include + #include "scsi.h" #include "hosts.h" @@ -36,27 +39,16 @@ #endif #ifdef CONFIG_PROC_FS -extern int scsi_proc_info(char *, char **, off_t, int, int, int); - -struct scsi_dir { - struct proc_dir_entry entry; - char name[4]; -}; - /* generic_proc_info * Used if the driver currently has no own support for /proc/scsi */ -int generic_proc_info(char *buffer, char **start, off_t offset, - int length, int inode, int inout, +int generic_proc_info(char *buffer, char **start, off_t offset, int length, const char *(*info) (struct Scsi_Host *), struct Scsi_Host *sh) { int len, pos, begin; - if (inout == TRUE) - return (-ENOSYS); /* This is a no-op */ - begin = 0; if (info && sh) { pos = len = sprintf(buffer, "%s\n", info(sh)); @@ -79,70 +71,70 @@ /* dispatch_scsi_info is the central dispatcher * It is the interface between the proc-fs and the SCSI subsystem code */ -extern int dispatch_scsi_info(int ino, char *buffer, char **start, - off_t offset, int length, int func) +static int proc_scsi_read(char *buffer, char **start, off_t offset, + int length, int *eof, void *data) { - struct Scsi_Host *hpnt = scsi_hostlist; + struct Scsi_Host *hpnt = data; + int n; - if (ino == PROC_SCSI_SCSI) { - /* - * This is for the scsi core, rather than any specific - * lowlevel driver. - */ - return (scsi_proc_info(buffer, start, offset, length, 0, func)); - } - while (hpnt) { - if (ino == (hpnt->host_no + PROC_SCSI_FILE)) { - if (hpnt->hostt->proc_info == NULL) - return generic_proc_info(buffer, start, offset, length, - hpnt->host_no, func, - hpnt->hostt->info, - hpnt); - else - return (hpnt->hostt->proc_info(buffer, start, offset, - length, hpnt->host_no, func)); - } - hpnt = hpnt->next; - } - return (-EBADF); + if (hpnt->hostt->proc_info == NULL) + n = generic_proc_info(buffer, start, offset, length, + hpnt->hostt->info, hpnt); + else + n = (hpnt->hostt->proc_info(buffer, start, offset, + length, hpnt->host_no, 0)); + *eof = (n PROC_BLOCK_SIZE) + return -EOVERFLOW; + + if (!(page = (char *) __get_free_page(GFP_KERNEL))) + return -ENOMEM; + copy_from_user(page, buf, count); - shpnt = scsi_hosts; - while (shpnt && shpnt->proc_dir->low_ino != inode->i_ino) - shpnt = shpnt->next; - if (!shpnt || !shpnt->module) - return; - if (fill) - __MOD_INC_USE_COUNT(shpnt->module); + if (hpnt->hostt->proc_info == NULL) + ret = -ENOSYS; else - __MOD_DEC_USE_COUNT(shpnt->module); + ret = hpnt->hostt->proc_info(page, &start, 0, count, + hpnt->host_no, 1); + free_page((ulong) page); + return(ret); } void build_proc_dir_entries(Scsi_Host_Template * tpnt) { struct Scsi_Host *hpnt; - struct scsi_dir *scsi_hba_dir; - proc_scsi_register(0, tpnt->proc_dir); - tpnt->proc_dir->fill_inode = &scsi_proc_fill_inode; + tpnt->proc_dir = create_proc_entry(tpnt->proc_name, S_IFDIR, proc_scsi); + tpnt->proc_dir->owner = tpnt->module; hpnt = scsi_hostlist; while (hpnt) { if (tpnt == hpnt->hostt) { - scsi_hba_dir = scsi_init_malloc(sizeof(struct scsi_dir), GFP_KERNEL); - if (scsi_hba_dir == NULL) + struct proc_dir_entry *p; + p = create_proc_read_entry(hpnt->proc_name, + S_IFREG | S_IRUGO | S_IWUSR, + tpnt->proc_dir, + proc_scsi_read, + (void *)hpnt); + if (!p) panic("Not enough memory to register SCSI HBA in /proc/scsi !\n"); - memset(scsi_hba_dir, 0, sizeof(struct scsi_dir)); - scsi_hba_dir->entry.low_ino = PROC_SCSI_FILE + hpnt->host_no; - scsi_hba_dir->entry.namelen = sprintf(scsi_hba_dir->name, "%d", - hpnt->host_no); - scsi_hba_dir->entry.name = scsi_hba_dir->name; - scsi_hba_dir->entry.mode = S_IFREG | S_IRUGO | S_IWUSR; - proc_scsi_register(tpnt->proc_dir, &scsi_hba_dir->entry); + p->write_proc=proc_scsi_write; + p->owner = tpnt->module; } hpnt = hpnt->next; } @@ -178,28 +170,28 @@ cmdNum; /* cmd number */ } parseHandle; - inline int parseFree(parseHandle * handle) { /* free memory */ kfree(handle->cmdPos); kfree(handle); - return (-1); + return -1; } - parseHandle *parseInit(char *buf, char *cmdList, int cmdNum) { char *ptr; /* temp pointer */ parseHandle *handle; /* new handle */ if (!buf || !cmdList) /* bad input ? */ - return (NULL); - if ((handle = (parseHandle *) kmalloc(sizeof(parseHandle), GFP_KERNEL)) == 0) - return (NULL); /* out of memory */ - if ((handle->cmdPos = (char **) kmalloc(sizeof(int) * cmdNum, GFP_KERNEL)) == 0) { + return NULL; + handle = (parseHandle *) kmalloc(sizeof(parseHandle), GFP_KERNEL); + if (!handle) + return NULL; /* out of memory */ + handle->cmdPos = (char **) kmalloc(sizeof(int) * cmdNum, GFP_KERNEL); + if (!handle->cmdPos) { kfree(handle); - return (NULL); /* out of memory */ + return NULL; /* out of memory */ } handle->buf = handle->bufPos = buf; /* init handle */ handle->cmdList = cmdList; @@ -212,10 +204,9 @@ handle->cmdPos[++cmdNum] = ptr++; } } - return (handle); + return handle; } - int parseOpt(parseHandle * handle, char **param) { int cmdIndex = 0, cmdLen = 0; @@ -299,7 +290,7 @@ return; } -#else +#else /* if !CONFIG_PROC_FS */ void proc_print_scsidevice(Scsi_Device * scd, char *buffer, int *size, int len) { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c --- v2.3.26/linux/drivers/scsi/scsi_syms.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/scsi/scsi_syms.c Thu Nov 11 16:57:30 1999 @@ -73,6 +73,8 @@ EXPORT_SYMBOL(scsi_sleep); EXPORT_SYMBOL(proc_print_scsidevice); +EXPORT_SYMBOL(proc_scsi); + /* * These are here only while I debug the rest of the scsi stuff. */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c --- v2.3.26/linux/drivers/scsi/sd.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/scsi/sd.c Wed Nov 10 20:02:02 1999 @@ -36,21 +36,25 @@ #include #include #include +#include #include #include #include +#include #include #include #define MAJOR_NR SCSI_DISK0_MAJOR #include +#include #include "scsi.h" #include "hosts.h" #include "sd.h" #include #include "constants.h" +#include /* must follow "hosts.h" */ #include @@ -87,8 +91,6 @@ static int *sd_blocksizes; static int *sd_hardsizes; /* Hardware sector size */ -extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - static int check_scsidisk_media_change(kdev_t); static int fop_revalidate_scsidisk(kdev_t); @@ -102,6 +104,80 @@ static int sd_detect(Scsi_Device *); static void sd_detach(Scsi_Device *); +static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) +{ + kdev_t dev = inode->i_rdev; + struct Scsi_Host * host; + Scsi_Device * SDev; + int diskinfo[4]; + struct hd_geometry *loc = (struct hd_geometry *) arg; + + SDev = rscsi_disks[DEVICE_NR(dev)].device; + /* + * If we are in the middle of error recovery, don't let anyone + * else try and use this device. Also, if error recovery fails, it + * may try and take the device offline, in which case all further + * access to the device is prohibited. + */ + + if( !scsi_block_when_processing_errors(SDev) ) + { + return -ENODEV; + } + + switch (cmd) + { + case HDIO_GETGEO: /* Return BIOS disk parameters */ + if(!loc) + return -EINVAL; + + host = rscsi_disks[DEVICE_NR(dev)].device->host; + + /* default to most commonly used values */ + + diskinfo[0] = 0x40; + diskinfo[1] = 0x20; + diskinfo[2] = rscsi_disks[DEVICE_NR(dev)].capacity >> 11; + + /* override with calculated, extended default, or driver values */ + + if(host->hostt->bios_param != NULL) + host->hostt->bios_param(&rscsi_disks[DEVICE_NR(dev)], + dev, + &diskinfo[0]); + else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)], + dev, &diskinfo[0]); + + if (put_user(diskinfo[0], &loc->heads) || + put_user(diskinfo[1], &loc->sectors) || + put_user(diskinfo[2], &loc->cylinders) || + put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start)) + return -EFAULT; + return 0; + case BLKGETSIZE: /* Return device size */ + if (!arg) + return -EINVAL; + return put_user(sd[SD_PARTITION(inode->i_rdev)].nr_sects, (long *) arg); + + case BLKROSET: + case BLKROGET: + case BLKRASET: + case BLKRAGET: + case BLKFLSBUF: + case BLKSSZGET: + case BLKPG: + return blk_ioctl(inode->i_rdev, cmd, arg); + + case BLKRRPART: /* Re-read partition tables */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + return revalidate_scsidisk(dev, 1); + + default: + return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg); + } +} + static void sd_devname(unsigned int disknum, char *buffer) { if (disknum < 26) @@ -119,11 +195,11 @@ } } -struct Scsi_Device_Template sd_template = -{NULL, "disk", "sd", NULL, TYPE_DISK, - SCSI_DISK0_MAJOR, 0, 0, 0, 1, - sd_detect, sd_init, - sd_finish, sd_attach, sd_detach +struct Scsi_Device_Template sd_template = { + NULL, "disk", "sd", NULL, TYPE_DISK, + SCSI_DISK0_MAJOR, 0, 0, 0, 1, + sd_detect, sd_init, + sd_finish, sd_attach, sd_detach }; static int sd_open(struct inode *inode, struct file *filp) diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c --- v2.3.26/linux/drivers/scsi/sd_ioctl.c Sat May 15 23:43:04 1999 +++ linux/drivers/scsi/sd_ioctl.c Wed Dec 31 16:00:00 1969 @@ -1,119 +0,0 @@ -/* - * drivers/scsi/sd_ioctl.c - * - * ioctl handling for SCSI disks - */ - -#include -#include -#include -#include -#include -#include - -#include - -#define MAJOR_NR SCSI_DISK0_MAJOR -#include -#include -#include "scsi.h" -#include -#include "hosts.h" -#include "sd.h" -#include /* must follow "hosts.h" */ - -int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) -{ - kdev_t dev = inode->i_rdev; - int error; - struct Scsi_Host * host; - Scsi_Device * SDev; - int diskinfo[4]; - struct hd_geometry *loc = (struct hd_geometry *) arg; - - SDev = rscsi_disks[DEVICE_NR(dev)].device; - /* - * If we are in the middle of error recovery, don't let anyone - * else try and use this device. Also, if error recovery fails, it - * may try and take the device offline, in which case all further - * access to the device is prohibited. - */ - if( !scsi_block_when_processing_errors(SDev) ) - { - return -ENODEV; - } - - switch (cmd) { - case HDIO_GETGEO: /* Return BIOS disk parameters */ - if (!loc) return -EINVAL; - error = verify_area(VERIFY_WRITE, loc, sizeof(*loc)); - if (error) - return error; - host = rscsi_disks[DEVICE_NR(dev)].device->host; - -/* default to most commonly used values */ - - diskinfo[0] = 0x40; - diskinfo[1] = 0x20; - diskinfo[2] = rscsi_disks[DEVICE_NR(dev)].capacity >> 11; - -/* override with calculated, extended default, or driver values */ - - if(host->hostt->bios_param != NULL) - host->hostt->bios_param(&rscsi_disks[DEVICE_NR(dev)], - dev, - &diskinfo[0]); - else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)], - dev, &diskinfo[0]); - - put_user(diskinfo[0], &loc->heads); - put_user(diskinfo[1], &loc->sectors); - put_user(diskinfo[2], &loc->cylinders); - put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start); - return 0; - case BLKGETSIZE: /* Return device size */ - if (!arg) return -EINVAL; - error = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); - if (error) - return error; - put_user(sd[SD_PARTITION(inode->i_rdev)].nr_sects, - (long *) arg); - return 0; - - case BLKROSET: - case BLKROGET: - case BLKRASET: - case BLKRAGET: - case BLKFLSBUF: - case BLKSSZGET: - case BLKPG: - return blk_ioctl(inode->i_rdev, cmd, arg); - - case BLKRRPART: /* Re-read partition tables */ - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - return revalidate_scsidisk(dev, 1); - - default: - return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg); - } -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c --- v2.3.26/linux/drivers/scsi/seagate.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/scsi/seagate.c Thu Nov 11 16:57:30 1999 @@ -108,12 +108,6 @@ #endif #define DANY( msg... ) DPRINTK( 0xffff, msg ); -static struct proc_dir_entry proc_scsi_seagate = -{ - PROC_SCSI_SEAGATE, 7, "seagate", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #ifndef IRQ #define IRQ 5 #endif @@ -418,7 +412,7 @@ struct Scsi_Host *instance; int i, j; - tpnt->proc_dir = &proc_scsi_seagate; + tpnt->proc_name = "seagate"; /* * First, we try for the manual override. */ DANY ("Autodetecting ST0x / TMC-8xx\n"); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sgiwd93.c linux/drivers/scsi/sgiwd93.c --- v2.3.26/linux/drivers/scsi/sgiwd93.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/scsi/sgiwd93.c Thu Nov 11 16:57:30 1999 @@ -37,11 +37,6 @@ unsigned long padding; }; -struct proc_dir_entry proc_scsi_sgiwd93 = { - PROC_SCSI_SGIWD93, 5, "SGIWD93", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - struct Scsi_Host *sgiwd93_host = NULL; /* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */ @@ -272,7 +267,7 @@ if(called) return 0; /* Should bitch on the console about this... */ - HPsUX->proc_dir = &proc_scsi_sgiwd93; + HPsUX->proc_name = "SGIWD93"; sgiwd93_host = scsi_register(HPsUX, sizeof(struct WD33C93_hostdata)); sgiwd93_host->base = (unsigned char *) hregs; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sgiwd93.h linux/drivers/scsi/sgiwd93.h --- v2.3.26/linux/drivers/scsi/sgiwd93.h Fri Oct 15 15:25:14 1999 +++ linux/drivers/scsi/sgiwd93.h Thu Nov 11 16:57:30 1999 @@ -25,9 +25,7 @@ int wd33c93_abort(Scsi_Cmnd *); int wd33c93_reset(Scsi_Cmnd *, unsigned int); -extern struct proc_dir_entry proc_scsi_sgiwd93; - -#define SGIWD93_SCSI {proc_dir: &proc_scsi_sgiwd93, \ +#define SGIWD93_SCSI {proc_name: "SGIWD93", \ name: "SGI WD93", \ detect: sgiwd93_detect, \ release: sgiwd93_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sim710.c linux/drivers/scsi/sim710.c --- v2.3.26/linux/drivers/scsi/sim710.c Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/sim710.c Thu Nov 11 16:57:30 1999 @@ -172,12 +172,6 @@ #define offsetof(t, m) ((size_t) (&((t *)0)->m)) #endif - -struct proc_dir_entry proc_scsi_sim710 = { - PROC_SCSI_SIM710, 6, "sim710", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define STATE_INITIALISED 0 #define STATE_HALTED 1 #define STATE_IDLE 2 @@ -1441,7 +1435,7 @@ DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n", sizeof(struct sim710_hostdata), size, order)); - tpnt->proc_dir = &proc_scsi_sim710; + tpnt->proc_name = "sim710"; for(indx = 0; indx < no_of_boards; indx++) { host = scsi_register(tpnt, 4); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sim710.h linux/drivers/scsi/sim710.h --- v2.3.26/linux/drivers/scsi/sim710.h Sat Oct 9 11:47:50 1999 +++ linux/drivers/scsi/sim710.h Thu Nov 11 16:57:30 1999 @@ -24,9 +24,7 @@ #if defined(HOSTS_C) || defined(MODULE) #include -extern struct proc_dir_entry proc_scsi_sim710; - -#define SIM710_SCSI { proc_dir: &proc_scsi_sim710, \ +#define SIM710_SCSI { proc_name: "sim710", \ name: "Simple 53c710", \ detect: sim710_detect, \ release: sim710_release, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sun3_scsi.c linux/drivers/scsi/sun3_scsi.c --- v2.3.26/linux/drivers/scsi/sun3_scsi.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/sun3_scsi.c Thu Nov 11 16:57:30 1999 @@ -0,0 +1,416 @@ +/* + * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl) + * + * Adapted from mac_scsinew.c: + */ +/* + * Generic Macintosh NCR5380 driver + * + * Copyright 1998, Michael Schmitz + * + * derived in part from: + */ +/* + * Generic Generic NCR5380 driver + * + * Copyright 1995, Russell King + * + * ALPHA RELEASE 1. + * + * For more information, please consult + * + * NCR 5380 Family + * SCSI Protocol Controller + * Databook + * + * NCR Microelectronics + * 1635 Aeroplaza Drive + * Colorado Springs, CO 80916 + * 1+ (719) 578-3400 + * 1+ (800) 334-5454 + */ + + +/* + * This is from mac_scsi.h, but hey, maybe this is usefull for Sun3 too! :) + * + * Options : + * + * PARITY - enable parity checking. Not supported. + * + * SCSI2 - enable support for SCSI-II tagged queueing. Untested. + * + * USLEEP - enable support for devices that don't disconnect. Untested. + */ + +/* + * $Log: mac_NCR5380.c,v $ + */ + +#define AUTOSENSE +#if 0 +#define PSEUDO_DMA +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "scsi.h" +#include "hosts.h" +#include "sun3_scsi.h" +#include "NCR5380.h" +#include "constants.h" + +#if 0 +#define NDEBUG (NDEBUG_INTR | NDEBUG_PSEUDO_DMA | NDEBUG_ARBITRATION | NDEBUG_SELECTION | NDEBUG_RESELECTION) +#define NCR_TIMEOUT 100 +#else +#define NDEBUG (NDEBUG_ABORT) +#endif + +#define USE_WRAPPER +#define RESET_BOOT +#define DRIVER_SETUP + +/* + * BUG can be used to trigger a strange code-size related hang on 2.1 kernels + */ +#ifdef BUG +#undef RESET_BOOT +#undef DRIVER_SETUP +#endif + +#define ENABLE_IRQ() sun3_enable_irq( IRQ_SUN3_SCSI ); +#define DISABLE_IRQ() sun3_enable_irq( IRQ_SUN3_SCSI ); + +/* extern void via_scsi_clear(void); */ + +static void scsi_sun3_intr(int irq, void *dummy, struct pt_regs *fp); +static char sun3scsi_read(struct Scsi_Host *instance, int reg); +static void sun3scsi_write(struct Scsi_Host *instance, int reg, int value); + +static int setup_can_queue = -1; +static int setup_cmd_per_lun = -1; +static int setup_sg_tablesize = -1; +#ifdef SUPPORT_TAGS +static int setup_use_tagged_queuing = -1; +#endif +static int setup_hostid = -1; + +static int polled_scsi_on = 0; + +#define AFTER_RESET_DELAY (HZ/2) + +static volatile unsigned char *sun3_scsi_regp = IOBASE_SUN3_SCSI; +/* +static volatile unsigned char *sun3_scsi_drq = NULL; +static volatile unsigned char *sun3_scsi_nodrq = NULL; +*/ + +/* + * Function : sun3_scsi_setup(char *str, int *ints) + * + * Purpose : booter command line initialization of the overrides array, + * + * Inputs : str - unused, ints - array of integer parameters with ints[0] + * equal to the number of ints. + * + * TODO: make it actually work! + * + */ + +void sun3_scsi_setup(char *str, int *ints) { + printk("sun3_scsi_setup() called\n"); + setup_can_queue = -1; + setup_cmd_per_lun = -1; + setup_sg_tablesize = -1; + setup_hostid = -1; +#ifdef SUPPORT_TAGS + setup_use_tagged_queuing = -1; +#endif + printk("sun3_scsi_setup() done\n"); +} + +/* + * XXX: status debug + */ +static struct Scsi_Host *default_instance; + +/* + * Function : int sun3scsi_detect(Scsi_Host_Template * tpnt) + * + * Purpose : initializes mac NCR5380 driver based on the + * command line / compile time port and irq definitions. + * + * Inputs : tpnt - template for this SCSI adapter. + * + * Returns : 1 if a host adapter was found, 0 if not. + * + */ + +int sun3scsi_detect(Scsi_Host_Template * tpnt) +{ + unsigned long ioaddr, iopte; + unsigned short *ioptr; + int count = 0; + static int called = 0; + struct Scsi_Host *instance; + + if(called) + return 0; + +printk("sun3scsi_detect(0x%p)\n",tpnt); + + tpnt->proc_name = "Sun3 5380 SCSI"; /* Could you spell "ewww..."? */ + + /* setup variables */ + tpnt->can_queue = + (setup_can_queue > 0) ? setup_can_queue : CAN_QUEUE; + tpnt->cmd_per_lun = + (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : CMD_PER_LUN; + tpnt->sg_tablesize = + (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_TABLESIZE; + + if (setup_hostid >= 0) + tpnt->this_id = setup_hostid; + else { + /* use 7 as default */ + tpnt->this_id = 7; + } + + /* Taken from Sammy's lance driver: */ + /* IOBASE_SUN3_SCSI can be found within the IO pmeg with some effort */ + for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 + SUN3_PMEG_SIZE); + ioaddr += SUN3_PTE_SIZE) { + + iopte = sun3_get_pte(ioaddr); + if(!(iopte & SUN3_PAGE_TYPE_IO)) /* this an io page? */ + continue; + + if(((iopte & SUN3_PAGE_PGNUM_MASK) << PAGE_SHIFT) == + IOBASE_SUN3_SCSI) { + count = 1; +printk("Found ioaddr in pmeg\n"); + break; + } + } + + if(!count) { + printk("No Sun3 NCR5380 found!\n"); + return 0; + } + + sun3_scsi_regp = ioaddr; + + /* doing some stuff like resetting DVMA: */ + ioptr = ioaddr; + *(ioptr+8) = 0; + udelay(10); + *(ioptr+9) = 0; + udelay(10); + *(ioptr+12) = 0; + udelay(10); + *(ioptr+12) = 0x7; + udelay(10); + printk("SCSI status reg = %x\n", *(ioptr+12)); + udelay(10); + *(ioptr+13) = 0; + udelay(10); + +#ifdef SUPPORT_TAGS + if (setup_use_tagged_queuing < 0) + setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING; +#endif + + instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); + default_instance = instance; + +/* + if (macintosh_config->ident == MAC_MODEL_IIFX) { + mac_scsi_regp = via1_regp+0x8000; + mac_scsi_drq = via1_regp+0x6000; + mac_scsi_nodrq = via1_regp+0x12000; + } else { + mac_scsi_regp = via1_regp+0x10000; + mac_scsi_drq = via1_regp+0x6000; + mac_scsi_nodrq = via1_regp+0x12000; + } +*/ + + instance->io_port = (unsigned long) ioaddr; + instance->irq = IRQ_SUN3_SCSI; + + NCR5380_init(instance, 0); + + instance->n_io_port = 32; + + ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0; + + if (instance->irq != IRQ_NONE) + if (sun3_request_irq(instance->irq, sun3scsi_intr, + 0, "Sun3SCSI-5380", NULL)) { + printk("scsi%d: IRQ%d not free, interrupts disabled\n", + instance->host_no, instance->irq); + instance->irq = IRQ_NONE; + } + + printk("scsi%d: generic 5380 at port %lX irq", instance->host_no, instance->io_port); + if (instance->irq == IRQ_NONE) + printk ("s disabled"); + else + printk (" %d", instance->irq); + printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", + instance->can_queue, instance->cmd_per_lun, + SUN3SCSI_PUBLIC_RELEASE); + printk("\nscsi%d:", instance->host_no); + NCR5380_print_options(instance); + printk("\n"); + + called = 1; + return 1; +} + +int sun3scsi_release (struct Scsi_Host *shpnt) +{ + if (shpnt->irq != IRQ_NONE) + free_irq (shpnt->irq, NULL); + + return 0; +} + +#ifdef RESET_BOOT +/* + * Our 'bus reset on boot' function + */ + +static void sun3_scsi_reset_boot(struct Scsi_Host *instance) +{ + unsigned long end; + + NCR5380_local_declare(); + NCR5380_setup(instance); + + /* + * Do a SCSI reset to clean up the bus during initialization. No + * messing with the queues, interrupts, or locks necessary here. + */ + + printk( "Sun3 SCSI: resetting the SCSI bus..." ); + + /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ + sun3_disable_irq( IRQ_SUN3_SCSI ); + + /* get in phase */ + NCR5380_write( TARGET_COMMAND_REG, + PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); + + /* assert RST */ + NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); + + /* The min. reset hold time is 25us, so 40us should be enough */ + udelay( 50 ); + + /* reset RST and interrupt */ + NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); + NCR5380_read( RESET_PARITY_INTERRUPT_REG ); + + for( end = jiffies + AFTER_RESET_DELAY; jiffies < end; ) + barrier(); + + /* switch on SCSI IRQ again */ + sun3_enable_irq( IRQ_SUN3_SCSI ); + + printk( " done\n" ); +} +#endif + +const char * sun3scsi_info (struct Scsi_Host *spnt) { + return ""; +} + + +/* + * NCR 5380 register access functions + */ + +static char sun3scsi_read(struct Scsi_Host *instance, int reg) +{ +/* +printk("sun3scsi_read(instance=0x%p, reg=0x%x): @0x%p= %d\n",instance,reg,sun3_scsi_regp,sun3_scsi_regp[reg]); +*/ + return( sun3_scsi_regp[reg] ); +} + +static void sun3scsi_write(struct Scsi_Host *instance, int reg, int value) +{ +/* + printk("sun3scsi_write(instance=0x%p, reg=0x%x, value=0x%x)\n", instance, reg, value); +*/ + sun3_scsi_regp[reg] = value; +} + +#include "NCR5380.c" + +/* + * Debug stuff - to be called on NMI, or sysrq key. Use at your own risk; + * reentering NCR5380_print_status seems to have ugly side effects + */ + +void sun3_sun3_debug (void) +{ + unsigned long flags; + NCR5380_local_declare(); + + if (default_instance) { + save_flags(flags); + cli(); + NCR5380_print_status(default_instance); + restore_flags(flags); + } +#if 0 + polled_scsi_on = 1; +#endif +} +/* + * Helper function for interrupt trouble. More ugly side effects here. + */ + +void scsi_sun3_polled (void) +{ + unsigned long flags; + NCR5380_local_declare(); + struct Scsi_Host *instance; + + instance = default_instance; + NCR5380_setup(instance); + if(NCR5380_read(BUS_AND_STATUS_REG)&BASR_IRQ) + { + printk("SCSI poll\n"); + save_flags(flags); + cli(); + sun3scsi_intr(IRQ_SUN3_SCSI, instance, NULL); + restore_flags(flags); + } +} + + +#ifdef MODULE + +Scsi_Host_Template driver_template = SUN3_NCR5380; + +#include "scsi_module.c" +#endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sun3_scsi.h linux/drivers/scsi/sun3_scsi.h --- v2.3.26/linux/drivers/scsi/sun3_scsi.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/scsi/sun3_scsi.h Mon Nov 8 11:03:21 1999 @@ -0,0 +1,119 @@ +/* + * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl) + * + * Adapted from mac_scsinew.h: + */ +/* + * Cumana Generic NCR5380 driver defines + * + * Copyright 1993, Drew Eckhardt + * Visionary Computing + * (Unix and Linux consulting and custom programming) + * drew@colorado.edu + * +1 (303) 440-4894 + * + * ALPHA RELEASE 1. + * + * For more information, please consult + * + * NCR 5380 Family + * SCSI Protocol Controller + * Databook + * + * NCR Microelectronics + * 1635 Aeroplaza Drive + * Colorado Springs, CO 80916 + * 1+ (719) 578-3400 + * 1+ (800) 334-5454 + */ + +/* + * $Log: cumana_NCR5380.h,v $ + */ + +#ifndef SUN3_NCR5380_H +#define SUN3_NCR5380_H + +#define SUN3SCSI_PUBLIC_RELEASE 1 + +/* + * Int: level 2 autovector + * IO: type 1, base 0x00140000, 5 bits phys space: A<4..0> + */ +#define IRQ_SUN3_SCSI 2 +#define IOBASE_SUN3_SCSI 0x00140000 + +int sun3scsi_abort (Scsi_Cmnd *); +int sun3scsi_detect (Scsi_Host_Template *); +int sun3scsi_release (struct Scsi_Host *); +const char *sun3scsi_info (struct Scsi_Host *); +int sun3scsi_reset(Scsi_Cmnd *, unsigned int); +int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); +int sun3scsi_proc_info (char *buffer, char **start, off_t offset, + int length, int hostno, int inout); + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef CMD_PER_LUN +#define CMD_PER_LUN 2 +#endif + +#ifndef CAN_QUEUE +#define CAN_QUEUE 16 +#endif + +#ifndef SG_TABLESIZE +#define SG_TABLESIZE SG_NONE +#endif + +#ifndef USE_TAGGED_QUEUING +#define USE_TAGGED_QUEUING 0 +#endif + +#include + +#define SUN3_NCR5380 { \ +name: "Sun3 NCR5380 SCSI", \ +detect: sun3scsi_detect, \ +release: sun3scsi_release, /* Release */ \ +info: sun3scsi_info, \ +queuecommand: sun3scsi_queue_command, \ +abort: sun3scsi_abort, \ +reset: sun3scsi_reset, \ +bios_param: scsicam_bios_param, /* biosparam */ \ +can_queue: CAN_QUEUE, /* can queue */ \ +this_id: 7, /* id */ \ +sg_tablesize: SG_ALL, /* sg_tablesize */ \ +cmd_per_lun: CMD_PER_LUN, /* cmd per lun */ \ +unchecked_isa_dma: 0, /* unchecked_isa_dma */ \ +use_clustering: DISABLE_CLUSTERING \ + } + +#ifndef HOSTS_C + +#define NCR5380_implementation_fields \ + int port, ctrl + +#define NCR5380_local_declare() \ + struct Scsi_Host *_instance + +#define NCR5380_setup(instance) \ + _instance = instance + +#define NCR5380_read(reg) sun3scsi_read(_instance, reg) +#define NCR5380_write(reg, value) sun3scsi_write(_instance, reg, value) + +#define NCR5380_intr sun3scsi_intr +#define NCR5380_queue_command sun3scsi_queue_command +#define NCR5380_abort sun3scsi_abort +#define NCR5380_reset sun3scsi_reset +#define NCR5380_proc_info sun3scsi_proc_info + +#define BOARD_NORMAL 0 +#define BOARD_NCR53C400 1 + +#endif /* ndef HOSTS_C */ +#endif /* SUN3_NCR5380_H */ + diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sun3x_esp.h linux/drivers/scsi/sun3x_esp.h --- v2.3.26/linux/drivers/scsi/sun3x_esp.h Thu Aug 12 10:28:34 1999 +++ linux/drivers/scsi/sun3x_esp.h Thu Nov 11 16:57:30 1999 @@ -18,12 +18,10 @@ extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); -extern struct proc_dir_entry proc_scsi_esp; - #define DMA_PORTS_P (dregs->cond_reg & DMA_INT_ENAB) #define SCSI_SUN3X_ESP { \ - proc_dir: &proc_scsi_esp, \ + proc_name: "esp", \ proc_info: &esp_proc_info, \ name: "Sun ESP 100/100a/200", \ detect: sun3x_esp_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c --- v2.3.26/linux/drivers/scsi/sym53c416.c Fri Sep 10 23:57:32 1999 +++ linux/drivers/scsi/sym53c416.c Thu Nov 11 16:57:30 1999 @@ -170,7 +170,7 @@ #define PIO_MODE 0x80 #define IO_RANGE 0x20 /* 0x00 - 0x1F */ -#define ID "sym53c416" +#define ID "sym53c416" /* Attention: copied to the sym53c416.h */ #define PIO_SIZE 128 /* Size of PIO fifo is 128 bytes */ #define READ_TIMEOUT 150 @@ -237,8 +237,6 @@ static Scsi_Cmnd *current_command = NULL; -struct proc_dir_entry proc_scsi_sym53c416 = {PROC_SCSI_SYM53C416, 7, ID, S_IFDIR | S_IRUGO | S_IXUGO, 2}; - int fastpio = 1; int probeaddrs[] = {0x200, 0x220, 0x240, 0}; @@ -809,13 +807,11 @@ /* Loadable module support */ #ifdef MODULE -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26) MODULE_AUTHOR("Lieven Willems"); MODULE_PARM(sym53c416, "1-2i"); MODULE_PARM(sym53c416_1, "1-2i"); MODULE_PARM(sym53c416_2, "1-2i"); MODULE_PARM(sym53c416_3, "1-2i"); -#endif Scsi_Host_Template driver_template = SYM53C416; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sym53c416.h linux/drivers/scsi/sym53c416.h --- v2.3.26/linux/drivers/scsi/sym53c416.h Wed Aug 18 16:44:23 1999 +++ linux/drivers/scsi/sym53c416.h Thu Nov 11 17:03:48 1999 @@ -29,8 +29,6 @@ #define SYM53C416_SCSI_ID 7 -extern struct proc_dir_entry proc_scsi_sym53c416; - extern int sym53c416_detect(Scsi_Host_Template *); extern const char *sym53c416_info(struct Scsi_Host *); extern int sym53c416_command(Scsi_Cmnd *); @@ -40,10 +38,8 @@ extern int sym53c416_bios_param(Disk *, kdev_t, int *); extern void sym53c416_setup(char *str, int *ints); -#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,75) - #define SYM53C416 { \ - proc_dir: &proc_scsi_sym53c416, \ + proc_name: "sym53c416", \ name: "Symbios Logic 53c416", \ detect: sym53c416_detect, \ info: sym53c416_info, \ @@ -59,33 +55,4 @@ unchecked_isa_dma: 1, \ use_clustering: ENABLE_CLUSTERING \ } - -#else - -#define SYM53C416 { \ - NULL, \ - NULL, \ - &proc_scsi_sym53c416, \ - NULL, \ - "Symbios Logic 53c416", \ - sym53c416_detect, \ - NULL, \ - sym53c416_info, \ - sym53c416_command, \ - sym53c416_queuecommand, \ - sym53c416_abort, \ - sym53c416_reset, \ - NULL, \ - sym53c416_bios_param, \ - 1, \ - SYM53C416_SCSI_ID, \ - 32, /* ???? */ \ - 1, \ - 0, \ - 1, \ - ENABLE_CLUSTERING \ - } - -#endif - #endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c --- v2.3.26/linux/drivers/scsi/sym53c8xx.c Fri Oct 15 15:25:14 1999 +++ linux/drivers/scsi/sym53c8xx.c Thu Nov 11 16:57:30 1999 @@ -635,9 +635,9 @@ #endif #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0) -#define get_pages(order) __get_free_pages(GFP_ATOMIC | GFP_DMA_32BIT, order) +#define sym53c8xx_get_pages(order) __get_free_pages(GFP_ATOMIC | GFP_DMA_32BIT, order) #else -#define get_pages(order) __get_free_pages(GFP_ATOMIC | GFP_DMA_32BIT, order, 0) +#define sym53c8xx_get_pages(order) __get_free_pages(GFP_ATOMIC | GFP_DMA_32BIT, order, 0) #endif /* @@ -668,7 +668,7 @@ j = i; while (!h[j].next) { if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { - h[j].next = (struct m_link *)get_pages(MEMO_PAGE_ORDER); + h[j].next = (struct m_link *)sym53c8xx_get_pages(MEMO_PAGE_ORDER); if (h[j].next) h[j].next->next = 0; break; @@ -828,10 +828,6 @@ ** /proc directory entry and proc_info function */ -static struct proc_dir_entry proc_scsi_sym53c8xx = { - PROC_SCSI_SYM53C8XX, 9, NAME53C8XX, - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; #ifdef SCSI_NCR_PROC_INFO_SUPPORT static int sym53c8xx_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int func); @@ -11382,7 +11378,7 @@ ** Initialize driver general stuff. */ #ifdef SCSI_NCR_PROC_INFO_SUPPORT - tpnt->proc_dir = &proc_scsi_sym53c8xx; + tpnt->proc_name = NAME53C8XX; tpnt->proc_info = sym53c8xx_proc_info; #endif diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c --- v2.3.26/linux/drivers/scsi/t128.c Mon Aug 9 10:25:01 1999 +++ linux/drivers/scsi/t128.c Thu Nov 11 16:57:31 1999 @@ -121,12 +121,6 @@ #include #include -struct proc_dir_entry proc_scsi_t128 = { - PROC_SCSI_T128, 4, "t128", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - - static struct override { unsigned char *address; int irq; @@ -205,7 +199,7 @@ unsigned char *base; int sig, count; - tpnt->proc_dir = &proc_scsi_t128; + tpnt->proc_name = "t128"; tpnt->proc_info = &t128_proc_info; for (count = 0; current_override < NO_OVERRIDES; ++current_override) { diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/tmscsim.c linux/drivers/scsi/tmscsim.c --- v2.3.26/linux/drivers/scsi/tmscsim.c Fri Sep 10 23:57:35 1999 +++ linux/drivers/scsi/tmscsim.c Thu Nov 11 16:57:31 1999 @@ -482,12 +482,6 @@ UCHAR dc390_eepromBuf[MAX_ADAPTER_NUM][EE_LEN]; UCHAR dc390_clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20}; -struct proc_dir_entry DC390_proc_scsi_tmscsim ={ - PROC_SCSI_DC390T, 7 ,"tmscsim", - S_IFDIR | S_IRUGO | S_IXUGO, 2 - }; - - /*********************************************************************** * Functions for access to DC390 EEPROM * and some to emulate it @@ -2024,7 +2018,7 @@ printk (KERN_ERR "DC390: No PCI BIOS found!\n"); if (dc390_adapterCnt) - psht->proc_dir = &DC390_proc_scsi_tmscsim; + psht->proc_name = "tmscsim"; printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt); DC390_UNLOCK_DRV; diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v2.3.26/linux/drivers/scsi/u14-34f.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/scsi/u14-34f.c Thu Nov 11 16:57:31 1999 @@ -374,11 +374,6 @@ #define SPIN_UNLOCK_RESTORE \ spin_unlock_irqrestore(&io_request_lock, spin_flags); -struct proc_dir_entry proc_scsi_u14_34f = { - PROC_SCSI_U14_34F, 6, "u14_34f", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - /* Values for the PRODUCT_ID ports for the 14/34F */ #define PRODUCT_ID1 0x56 #define PRODUCT_ID2 0x40 /* NOTE: Only upper nibble is used */ @@ -955,7 +950,7 @@ { unsigned int j = 0, k; - tpnt->proc_dir = &proc_scsi_u14_34f; + tpnt->proc_name = "u14-34f"; if(boot_options) option_setup(boot_options); diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c --- v2.3.26/linux/drivers/scsi/ultrastor.c Fri Sep 10 23:57:35 1999 +++ linux/drivers/scsi/ultrastor.c Thu Nov 11 16:57:31 1999 @@ -148,11 +148,6 @@ #include "sd.h" #include -struct proc_dir_entry proc_scsi_ultrastor = { - PROC_SCSI_ULTRASTOR, 9, "ultrastor", - S_IFDIR | S_IRUGO | S_IXUGO, 2 -}; - #define FALSE 0 #define TRUE 1 @@ -631,7 +626,7 @@ int ultrastor_detect(Scsi_Host_Template * tpnt) { - tpnt->proc_dir = &proc_scsi_ultrastor; + tpnt->proc_name = "ultrastor"; return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt); } diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c --- v2.3.26/linux/drivers/scsi/wd7000.c Fri Sep 10 23:57:35 1999 +++ linux/drivers/scsi/wd7000.c Thu Nov 11 16:57:31 1999 @@ -171,17 +171,6 @@ #include "wd7000.h" #include - -struct proc_dir_entry proc_scsi_wd7000 = -{ - PROC_SCSI_7000FASST, - 6, - "wd7000", - S_IFDIR | S_IRUGO | S_IXUGO, - 2 -}; - - /* * Mailbox structure sizes. * I prefer to keep the number of ICMBs much larger than the number of @@ -1542,7 +1531,7 @@ for (i = 0; i < IRQS; wd7000_host[i++] = NULL) ; for (i = 0; i < NUM_CONFIGS; biosptr[i++] = -1) ; - tpnt->proc_dir = &proc_scsi_wd7000; + tpnt->proc_name = "wd7000"; tpnt->proc_info = &wd7000_proc_info; /* diff -u --recursive --new-file v2.3.26/linux/drivers/scsi/wd7000.h linux/drivers/scsi/wd7000.h --- v2.3.26/linux/drivers/scsi/wd7000.h Sun Dec 27 22:19:19 1998 +++ linux/drivers/scsi/wd7000.h Thu Nov 11 16:57:31 1999 @@ -14,9 +14,6 @@ #include #include -extern struct proc_dir_entry proc_scsi_wd7000; - - int wd7000_set_info (char *buffer, int length, struct Scsi_Host *host); int wd7000_proc_info (char *buffer, char **start, off_t offset, int length, int hostno, int inout); int wd7000_detect (Scsi_Host_Template *); @@ -45,7 +42,7 @@ #define WD7000_SG 16 #define WD7000 { \ - proc_dir: &proc_scsi_wd7000, \ + proc_name: "wd7000", \ proc_info: wd7000_proc_info, \ name: "Western Digital WD-7000", \ detect: wd7000_detect, \ diff -u --recursive --new-file v2.3.26/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c --- v2.3.26/linux/drivers/sound/sb_card.c Mon Oct 4 15:49:30 1999 +++ linux/drivers/sound/sb_card.c Wed Nov 10 19:54:58 1999 @@ -16,6 +16,8 @@ #include #endif #include +#include +#include #include "sound_config.h" #include "soundmodule.h" @@ -138,6 +140,7 @@ int support = 0; /* Set support to load this as a support module */ int sm_games = 0; /* Mixer - see sb_mixer.c */ int acer = 0; /* Do acer notebook init */ +int isapnp = 0; MODULE_PARM(io, "i"); MODULE_PARM(irq, "i"); @@ -151,24 +154,91 @@ MODULE_PARM(pas2, "i"); MODULE_PARM(sm_games, "i"); MODULE_PARM(esstype, "i"); +MODULE_PARM(isapnp, "i"); void *smw_free = NULL; +static struct { unsigned short vendor, function; char *name; } +isapnp_sb_list[] __initdata = { + {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), "Sound Blaster 16" }, + {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), "Sound Blaster 16" }, + {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), "Sound Blaster 16" }, + {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), "Sound Blaster 16" }, + {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), "Sound Blaster 16" }, + {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), "Sound Blaster 16" }, + {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), "Sound Blaster 16" }, + {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), "ESS 1868" }, + {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), "ESS 1868" }, + {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), "ESS 1869" }, + {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), "ESS 1878" }, + {ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), "ESS 1879" }, + {0,} +}; + + +static int __init sb_probe_isapnp(struct address_info *hw_config, struct address_info *mpu_config) { + int i; + + for (i = 0; isapnp_sb_list[i].vendor != 0; i++) { + struct pci_dev *idev = NULL; + + while ((idev = isapnp_find_dev(NULL, + isapnp_sb_list[i].vendor, + isapnp_sb_list[i].function, + idev))) { + idev->prepare(idev); + idev->activate(idev); + if (!idev->resource[0].start || check_region(idev->resource[0].start,16)) + continue; + hw_config->io_base = idev->resource[0].start; + hw_config->irq = idev->irq_resource[0].start; + hw_config->dma = idev->dma_resource[0].start; + hw_config->dma2 = idev->dma_resource[1].start; +#ifdef CONFIG_MIDI + if (isapnp_sb_list[i].vendor == ISAPNP_VENDOR('E','S','S')) + mpu_config->io_base = idev->resource[2].start; + else + mpu_config->io_base = idev->resource[1].start; +#endif + break; + } + if (!idev) + continue; + printk(KERN_INFO "ISAPnP reports %s at i/o %#x, irq %d, dma %d, %d\n", + isapnp_sb_list[i].name, + hw_config->io_base, hw_config->irq, hw_config->dma, + hw_config->dma2); + return 0; + } + return -ENODEV; +} + int init_module(void) { printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n"); if (mad16 == 0 && trix == 0 && pas2 == 0 && support == 0) { - if (io == -1 || dma == -1 || irq == -1) + if (isapnp == 1) + { + if (sb_probe_isapnp(&config, &config_mpu)<0) + { + printk(KERN_ERR "sb_card: No ISAPnP cards found\n"); + return -EINVAL; + } + } + else { - printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n"); - return -EINVAL; + if (io == -1 || dma == -1 || irq == -1) + { + printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n"); + return -EINVAL; + } + config.io_base = io; + config.irq = irq; + config.dma = dma; + config.dma2 = dma16; } - config.io_base = io; - config.irq = irq; - config.dma = dma; - config.dma2 = dma16; config.card_subtype = type; if (!probe_sb(&config)) @@ -178,7 +248,8 @@ if(config.slots[0]==-1) return -ENODEV; #ifdef CONFIG_MIDI - config_mpu.io_base = mpu_io; + if (isapnp == 0) + config_mpu.io_base = mpu_io; if (probe_sbmpu(&config_mpu)) sbmpu = 1; if (sbmpu) diff -u --recursive --new-file v2.3.26/linux/drivers/usb/Makefile linux/drivers/usb/Makefile --- v2.3.26/linux/drivers/usb/Makefile Sun Nov 7 16:37:34 1999 +++ linux/drivers/usb/Makefile Wed Nov 10 09:49:51 1999 @@ -37,7 +37,7 @@ ifeq ($(CONFIG_USB_UHCI),m) M_OBJS += usb-uhci.o - MIX_OBJS += uhci.o uhci-debug.o + MI_OBJS += uhci.o uhci-debug.o endif ifeq ($(CONFIG_USB_OHCI),y) @@ -45,7 +45,7 @@ endif ifeq ($(CONFIG_USB_OHCI),m) M_OBJS += usb-ohci.o - MIX_OBJS += ohci.o ohci-debug.o + MI_OBJS += ohci.o ohci-debug.o endif ifeq ($(CONFIG_USB_OHCI_HCD),y) @@ -53,7 +53,7 @@ endif ifeq ($(CONFIG_USB_OHCI_HCD),m) M_OBJS += usb-ohci-hcd.o - MIX_OBJS += ohci-hcd.o ohci-root-hub.o + MI_OBJS += ohci-hcd.o ohci-root-hub.o endif ifeq ($(CONFIG_USB_MOUSE),y) @@ -61,7 +61,7 @@ endif ifeq ($(CONFIG_USB_MOUSE),m) M_OBJS += mouse.o - MIX_OBJS += mouse.o + MI_OBJS += mouse.o endif ifeq ($(CONFIG_USB_HP_SCANNER),y) @@ -69,7 +69,7 @@ endif ifeq ($(CONFIG_USB_HP_SCANNER),m) M_OBJS +=hp_scanner.o - MIX_OBJS +=hp_scanner.o + MI_OBJS +=hp_scanner.o endif ifeq ($(CONFIG_USB_HUB),y) @@ -77,7 +77,7 @@ endif ifeq ($(CONFIG_USB_HUB),m) M_OBJS += hub.o - MIX_OBJS += hub.o + MI_OBJS += hub.o endif ifeq ($(CONFIG_USB_ACM),y) @@ -85,7 +85,7 @@ endif ifeq ($(CONFIG_USB_ACM),m) M_OBJS += acm.o - MIX_OBJS += acm.o + MI_OBJS += acm.o endif ifeq ($(CONFIG_USB_PRINTER),y) @@ -94,7 +94,7 @@ ifeq ($(CONFIG_USB_PRINTER),m) M_OBJS += printer.o - MIX_OBJS += printer.o + MI_OBJS += printer.o endif ifeq ($(CONFIG_USB_SERIAL),y) @@ -103,7 +103,7 @@ ifeq ($(CONFIG_USB_SERIAL),m) M_OBJS += usb-serial.o - MIX_OBJS += usb-serial.o + MI_OBJS += usb-serial.o endif ifneq ($(CONFIG_ADB_KEYBOARD),y) @@ -118,7 +118,7 @@ ifeq ($(CONFIG_USB_KBD),m) M_OBJS += usb-keyboard.o - MIX_OBJS += keyboard.o $(KEYMAP).o + MI_OBJS += keyboard.o $(KEYMAP).o endif ifeq ($(CONFIG_USB_AUDIO),y) @@ -127,7 +127,7 @@ ifeq ($(CONFIG_USB_AUDIO),m) M_OBJS += audio.o - MIX_OBJS += audio.o + MI_OBJS += audio.o endif ifeq ($(CONFIG_USB_CPIA),y) @@ -136,7 +136,7 @@ ifeq ($(CONFIG_USB_CPIA),m) M_OBJS += cpia.o - MIX_OBJS += cpia.o + MI_OBJS += cpia.o endif ifeq ($(CONFIG_USB_DC2XX),y) @@ -144,7 +144,7 @@ endif ifeq ($(CONFIG_USB_DC2XX),m) M_OBJS += dc2xx.o - MIX_OBJS += dc2xx.o + MI_OBJS += dc2xx.o endif ifeq ($(CONFIG_USB_SCSI),y) @@ -156,9 +156,9 @@ ifeq ($(CONFIG_USB_SCSI),m) M_OBJS += usb-scsi.o - MIX_OBJS += usb_scsi.o + MI_OBJS += usb_scsi.o ifeq ($(CONFIG_USB_SCSI_DEBUG),y) - MIX_OBJS += usb_scsi_debug.o + MI_OBJS += usb_scsi_debug.o endif endif @@ -168,7 +168,7 @@ ifeq ($(CONFIG_USB_EZUSB),m) M_OBJS += ezusb.o - MIX_OBJS += ezusb.o + MI_OBJS += ezusb.o endif ifeq ($(CONFIG_USB_USS720),y) @@ -177,7 +177,7 @@ ifeq ($(CONFIG_USB_USS720),m) M_OBJS += uss720.o - MIX_OBJS += uss720.o + MI_OBJS += uss720.o endif include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.26/linux/drivers/usb/README.serial linux/drivers/usb/README.serial --- v2.3.26/linux/drivers/usb/README.serial Sat Oct 9 11:47:50 1999 +++ linux/drivers/usb/README.serial Wed Nov 10 08:32:53 1999 @@ -3,14 +3,23 @@ not know the vendor id, and device id of that device (if anyone does, please let me know.) +If your device is not compatible with the above models, you can try +out the "generic" interface. This interface does not provide any type +of control messages sent to the device, and does not support any kind +of device flow control. All that is required of your device is that +it has at least one bulk in endpoint, or one bulk out endpoint. +To enable the driver to recognize your device, build the driver as +a module and load it by the following invocation: + insmod usb-serial.o vendor=0x#### product=0x#### +where the #### is replaced with the hex representation of your device's +vendor id and product id. + The driver can handle enumerating the device, and sending and receiving -data from the converter. However, since I do not have a spec for this -device, and the raw dumps from the Win98 driver are confusing, no control -signals are handled, and the data will most likely come through on a baud +data from the converter. However, since I do not have a spec for the Belkin, +Peracom, and eTek devices, and the raw dumps from the Win98 driver are +confusing, and eTek keeps giving me the run around, no control signals are +currently handled, and the data will most likely come through on a baud rate that you are not expecting. - -But I am working on figuring the control settings out. This release is to -let others try it out, and give some feedback. The major number that the driver uses is 240 (in the local/experimental range.) It will stay there until some agreements are reached on how to diff -u --recursive --new-file v2.3.26/linux/drivers/usb/proc_usb.c linux/drivers/usb/proc_usb.c --- v2.3.26/linux/drivers/usb/proc_usb.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/usb/proc_usb.c Thu Nov 11 10:35:19 1999 @@ -119,6 +119,7 @@ {USB_CLASS_HUB, "hub"}, {USB_CLASS_PRINTER, "print"}, {USB_CLASS_MASS_STORAGE, "stor."}, + {USB_CLASS_DATA, "data"}, {USB_CLASS_VENDOR_SPEC, "vend."}, {-1, "unk."} /* leave as last */ }; diff -u --recursive --new-file v2.3.26/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c --- v2.3.26/linux/drivers/usb/uhci.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/usb/uhci.c Mon Nov 8 12:04:40 1999 @@ -156,7 +156,7 @@ if (rval) *rval += actlength; - if (explength != actlength) { + if (explength != actlength && tmp->pipetype == PIPE_BULK) { /* If the packet is short, none of the */ /* packets after this were processed, so */ /* fix the DT accordingly */ diff -u --recursive --new-file v2.3.26/linux/drivers/usb/usb-serial.c linux/drivers/usb/usb-serial.c --- v2.3.26/linux/drivers/usb/usb-serial.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/usb/usb-serial.c Wed Nov 10 08:32:53 1999 @@ -1,32 +1,41 @@ /* * USB Serial Converter driver * - * Greg Kroah-Hartman (greg@kroah.com) + * (C) Copyright (C) 1999 + * Greg Kroah-Hartman (greg@kroah.com) * - * This was based on the ACM driver by Armin Fuerst (which was based - * on a driver by Brad Keryan) + * 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. * - * Currently only works for the Belkin and Peracom Serial converters. - * Should also work on the Etek serial converter, if anyone knows the - * vendor and device ids for that device. + * This driver was originally based on the ACM driver by Armin Fuerst (which was + * based on a driver by Brad Keryan) * + * See README.serial for more information on using this driver. * + * version 0.2.0 (11/10/99) gkh + * Split up internals to make it easier to add different types of serial + * converters to the code. + * Added a "generic" driver that gets it's vendor and product id + * from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) + * for the idea and sample code (from the usb scanner driver.) + * Cleared up any licensing questions by releasing it under the GNU GPL. + * * version 0.1.2 (10/25/99) gkh - * Fixed bug in detecting device. + * Fixed bug in detecting device. * * version 0.1.1 (10/05/99) gkh - * Changed the major number to not conflict with anything else. + * Changed the major number to not conflict with anything else. * * version 0.1 (09/28/99) gkh - * Can recognize the two different devices and start up a read from - * device when asked to. Writes also work. No control signals yet, this - * all is vendor specific data (i.e. no spec), also no control for - * different baud rates or other bit settings. - * Currently we are using the same devid as the acm driver. This needs - * to change. + * Can recognize the two different devices and start up a read from + * device when asked to. Writes also work. No control signals yet, this + * all is vendor specific data (i.e. no spec), also no control for + * different baud rates or other bit settings. + * Currently we are using the same devid as the acm driver. This needs + * to change. * - * (C) Copyright 1999 Greg Kroah-Hartman (greg@kroah.com) - * */ #include @@ -43,8 +52,8 @@ #include #include - #include "usb.h" + /*#define SERIAL_DEBUG 1*/ #ifdef SERIAL_DEBUG @@ -54,6 +63,19 @@ #endif +/* Module information */ +MODULE_AUTHOR("Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/"); +MODULE_DESCRIPTION("USB Serial Driver"); + +static __u16 vendor = 0; +static __u16 product = 0; +MODULE_PARM(vendor, "i"); +MODULE_PARM_DESC(vendor, "User specified USB idVendor"); + +MODULE_PARM(product, "i"); +MODULE_PARM_DESC(product, "User specified USB idProduct"); + + /* USB Serial devices vendor ids and device ids that this driver supports */ #define BELKIN_VENDOR_ID 0x056c #define BELKIN_SERIAL_CONVERTER 0x8007 @@ -70,41 +92,171 @@ static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum); static void usb_serial_disconnect(struct usb_device *dev, void *ptr); -typedef enum { - unknown = 0, - Belkin = 1, - Peracom = 2 - } SERIAL_TYPE; + +#define MUST_HAVE_NOT 0x01 +#define MUST_HAVE 0x02 +#define DONT_CARE 0x03 + +#define HAS 0x02 +#define HAS_NOT 0x01 + + +/* local function prototypes */ +static int serial_open (struct tty_struct *tty, struct file * filp); +static void serial_close (struct tty_struct *tty, struct file * filp); +static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count); +static void serial_put_char (struct tty_struct *tty, unsigned char ch); +static int serial_write_room (struct tty_struct *tty); +static int serial_chars_in_buffer (struct tty_struct *tty); +static void serial_throttle (struct tty_struct * tty); +static void serial_unthrottle (struct tty_struct * tty); + + +/* function prototypes for the eTek type converters (this included Belkin and Peracom) */ +static int etek_serial_open (struct tty_struct *tty, struct file * filp); +static void etek_serial_close (struct tty_struct *tty, struct file * filp); +static int etek_serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count); +static void etek_serial_put_char (struct tty_struct *tty, unsigned char ch); +static int etek_write_room (struct tty_struct *tty); +static int etek_chars_in_buffer (struct tty_struct *tty); +static void etek_throttle (struct tty_struct * tty); +static void etek_unthrottle (struct tty_struct * tty); + + +/* function prototypes for a "generic" type serial converter (no flow control, not all endpoints needed) */ +static int generic_serial_open (struct tty_struct *tty, struct file * filp); +static void generic_serial_close (struct tty_struct *tty, struct file * filp); +static int generic_serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count); +static void generic_serial_put_char (struct tty_struct *tty, unsigned char ch); +static int generic_write_room (struct tty_struct *tty); +static int generic_chars_in_buffer (struct tty_struct *tty); + + +/* This structure defines the individual serial converter. */ +struct usb_serial_device_type { + char *name; + __u16 *idVendor; + __u16 *idProduct; + char needs_interrupt_in; + char needs_bulk_in; + char needs_bulk_out; + // add function calls + + int (*open)(struct tty_struct * tty, struct file * filp); + void (*close)(struct tty_struct * tty, struct file * filp); + int (*write)(struct tty_struct * tty, int from_user,const unsigned char *buf, int count); + void (*put_char)(struct tty_struct *tty, unsigned char ch); + int (*write_room)(struct tty_struct *tty); + int (*chars_in_buffer)(struct tty_struct *tty); + void (*throttle)(struct tty_struct * tty); + void (*unthrottle)(struct tty_struct * tty); + +}; + + +/* All of the device info needed for the Belkin Serial Converter */ +static __u16 belkin_vendor_id = BELKIN_VENDOR_ID; +static __u16 belkin_product_id = BELKIN_SERIAL_CONVERTER; +static struct usb_serial_device_type belkin_device = { + "Belkin", + &belkin_vendor_id, /* the Belkin vendor id */ + &belkin_product_id, /* the Belkin serial converter product id */ + MUST_HAVE, /* this device must have an interrupt in endpoint */ + MUST_HAVE, /* this device must have a bulk in endpoint */ + MUST_HAVE, /* this device must have a bulk out endpoint */ + etek_serial_open, + etek_serial_close, + etek_serial_write, + etek_serial_put_char, + etek_write_room, + etek_chars_in_buffer, + etek_throttle, + etek_unthrottle +}; + +/* All of the device info needed for the Peracom Serial Converter */ +static __u16 peracom_vendor_id = PERACOM_VENDOR_ID; +static __u16 peracom_product_id = PERACOM_SERIAL_CONVERTER; +static struct usb_serial_device_type peracom_device = { + "Peracom", + &peracom_vendor_id, /* the Peracom vendor id */ + &peracom_product_id, /* the Peracom serial converter product id */ + MUST_HAVE, /* this device must have an interrupt in endpoint */ + MUST_HAVE, /* this device must have a bulk in endpoint */ + MUST_HAVE, /* this device must have a bulk out endpoint */ + etek_serial_open, + etek_serial_close, + etek_serial_write, + etek_serial_put_char, + etek_write_room, + etek_chars_in_buffer, + etek_throttle, + etek_unthrottle +}; + +/* All of the device info needed for the Generic Serial Converter */ +static struct usb_serial_device_type generic_device = { + "Generic", + &vendor, /* use the user specified vendor id */ + &product, /* use the user specified product id */ + DONT_CARE, /* don't have to have an interrupt in endpoint */ + DONT_CARE, /* don't have to have a bulk in endpoint */ + DONT_CARE, /* don't have to have a bulk out endpoint */ + generic_serial_open, + generic_serial_close, + generic_serial_write, + generic_serial_put_char, + generic_write_room, + generic_chars_in_buffer, + NULL, /* generic driver does not implement any flow control */ + NULL /* generic driver does not implement any flow control */ +}; + + +/* To add support for another serial converter, create a usb_serial_device_type + structure for that device, and add it to this list, making sure that the last + entry is NULL. */ +static struct usb_serial_device_type *usb_serial_devices[] = { + &generic_device, + &belkin_device, + &peracom_device, + NULL +}; + + struct usb_serial_state { - struct usb_device * dev; - SERIAL_TYPE type; /* what manufacturer's type of converter */ - void * irq_handle; - unsigned int irqpipe; - struct tty_struct *tty; /* the coresponding tty for this device */ - char present; - char active; + struct usb_device * dev; + struct usb_serial_device_type * type; + void * irq_handle; + unsigned int irqpipe; + struct tty_struct * tty; /* the coresponding tty for this device */ + char present; + char active; - char interrupt_in_inuse; + char has_interrupt_in; /* if this device has an interrupt in pipe or not */ + char interrupt_in_inuse; /* if the interrupt in endpoint is in use */ __u8 interrupt_in_endpoint; __u8 interrupt_in_interval; - __u16 interrupt_in_size; + __u16 interrupt_in_size; /* the size of the interrupt in endpoint */ unsigned int interrupt_in_pipe; unsigned char * interrupt_in_buffer; void * interrupt_in_transfer; - char bulk_in_inuse; + char has_bulk_in; /* if thie device has a bulk in pipe or not */ + char bulk_in_inuse; /* if the bulk in endpoint is in use */ __u8 bulk_in_endpoint; __u8 bulk_in_interval; - __u16 bulk_in_size; + __u16 bulk_in_size; /* the size of the bulk in endpoint */ unsigned int bulk_in_pipe; unsigned char * bulk_in_buffer; void * bulk_in_transfer; - char bulk_out_inuse; + char has_bulk_out; /* if this device has a bulk out pipe or not */ + char bulk_out_inuse; /* if the bulk out endpoint is in use */ __u8 bulk_out_endpoint; __u8 bulk_out_interval; - __u16 bulk_out_size; + __u16 bulk_out_size; /* the size of the bulk out endpoint */ unsigned int bulk_out_pipe; unsigned char * bulk_out_buffer; void * bulk_out_transfer; @@ -197,36 +349,25 @@ - -/* tty interface functions */ +/***************************************************************************** + * Driver tty interface functions + *****************************************************************************/ static int serial_open (struct tty_struct *tty, struct file * filp) { struct usb_serial_state *serial; debug_info("USB: serial_open\n"); + /* assign a serial object to the tty pointer */ serial = &serial_state_table [MINOR(tty->device)-tty->driver.minor_start]; tty->driver_data = serial; serial->tty = tty; - if (!serial->present) { - debug_info("USB Serial: no device registered\n"); - return -EINVAL; + /* pass on to the driver specific version of this function */ + if (serial->type->open) { + return (serial->type->open(tty, filp)); } - - if (serial->active) { - debug_info ("USB Serial: device already open\n"); - return -EINVAL; - } - serial->active = 1; - - /*Start reading from the device*/ - serial->bulk_in_inuse = 1; - serial->bulk_in_transfer = usb_request_bulk (serial->dev, serial->bulk_in_pipe, serial_read_irq, serial->bulk_in_buffer, serial->bulk_in_size, serial); - - /* Need to do device specific setup here (control lines, baud rate, etc.) */ - /* FIXME!!! */ - + return (0); } @@ -246,28 +387,16 @@ return; } - /* Need to change the control lines here */ - /* FIXME */ - - if (serial->bulk_out_inuse){ - usb_terminate_bulk (serial->dev, serial->bulk_out_transfer); - serial->bulk_out_inuse = 0; - } - if (serial->bulk_in_inuse){ - usb_terminate_bulk (serial->dev, serial->bulk_in_transfer); - serial->bulk_in_inuse = 0; + /* pass on to the driver specific version of this function */ + if (serial->type->close) { + serial->type->close(tty, filp); } - - /* release the irq? */ - - serial->active = 0; -} +} static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) { struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; - int written; debug_info("USB Serial: serial_write\n"); @@ -281,26 +410,14 @@ return (-EINVAL); } - if (serial->bulk_out_inuse) { - debug_info ("USB Serial: already writing\n"); - return (0); + /* pass on to the driver specific version of this function */ + if (serial->type->write) { + return (serial->type->write(tty, from_user, buf, count)); } - written = (count > serial->bulk_out_size) ? serial->bulk_out_size : count; - - if (from_user) { - copy_from_user(serial->bulk_out_buffer, buf, written); - } - else { - memcpy (serial->bulk_out_buffer, buf, written); - } - - /* send the data out the bulk port */ - serial->bulk_out_inuse = 1; - serial->bulk_out_transfer = usb_request_bulk (serial->dev, serial->bulk_out_pipe, serial_write_irq, serial->bulk_out_buffer, written, serial); - - return (written); -} + /* no specific driver, so return that we didn't write anything */ + return (0); +} static void serial_put_char (struct tty_struct *tty, unsigned char ch) @@ -319,18 +436,13 @@ return; } - if (serial->bulk_out_inuse) { - debug_info ("USB Serial: already writing\n"); - return; + /* pass on to the driver specific version of this function */ + if (serial->type->put_char) { + serial->type->put_char(tty, ch); } - /* send the single character out the bulk port */ - serial->bulk_out_buffer[0] = ch; - serial->bulk_out_inuse = 1; - serial->bulk_out_transfer = usb_request_bulk (serial->dev, serial->bulk_out_pipe, serial_write_irq, serial->bulk_out_buffer, 1, serial); - return; -} +} static int serial_write_room (struct tty_struct *tty) @@ -349,11 +461,12 @@ return (-EINVAL); } - if (serial->bulk_out_inuse) { - return (0); + /* pass on to the driver specific version of this function */ + if (serial->type->write_room) { + return (serial->type->write_room(tty)); } - return serial->bulk_out_size; + return (0); } @@ -373,8 +486,9 @@ return (-EINVAL); } - if (serial->bulk_out_inuse) { - return (serial->bulk_out_size); + /* pass on to the driver specific version of this function */ + if (serial->type->chars_in_buffer) { + return (serial->type->chars_in_buffer(tty)); } return (0); @@ -397,9 +511,10 @@ return; } - - /* Change the control signals */ - /* FIXME!!! */ + /* pass on to the driver specific version of this function */ + if (serial->type->throttle) { + serial->type->throttle(tty); + } return; } @@ -422,6 +537,153 @@ } + /* pass on to the driver specific version of this function */ + if (serial->type->unthrottle) { + serial->type->unthrottle(tty); + } + + return; +} + + +/***************************************************************************** + * eTek specific driver functions + *****************************************************************************/ +static int etek_serial_open (struct tty_struct *tty, struct file *filp) +{ + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + + debug_info("USB: etek_serial_open\n"); + + if (!serial->present) { + debug_info("USB Serial: no device registered\n"); + return -EINVAL; + } + + if (serial->active) { + debug_info ("USB Serial: device already open\n"); + return -EINVAL; + } + serial->active = 1; + + /*Start reading from the device*/ + serial->bulk_in_inuse = 1; + serial->bulk_in_transfer = usb_request_bulk (serial->dev, serial->bulk_in_pipe, serial_read_irq, serial->bulk_in_buffer, serial->bulk_in_size, serial); + + /* Need to do device specific setup here (control lines, baud rate, etc.) */ + /* FIXME!!! */ + + return (0); +} + + +static void etek_serial_close(struct tty_struct *tty, struct file * filp) +{ + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + debug_info("USB: etek_serial_close\n"); + + /* Need to change the control lines here */ + /* FIXME */ + + /* shutdown our bulk reads and writes */ + if (serial->bulk_out_inuse){ + usb_terminate_bulk (serial->dev, serial->bulk_out_transfer); + serial->bulk_out_inuse = 0; + } + if (serial->bulk_in_inuse){ + usb_terminate_bulk (serial->dev, serial->bulk_in_transfer); + serial->bulk_in_inuse = 0; + } + + /* release the irq? */ + + serial->active = 0; +} + + +static int etek_serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) +{ + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + int written; + + debug_info("USB Serial: etek_serial_write\n"); + + if (serial->bulk_out_inuse) { + debug_info ("USB Serial: already writing\n"); + return (0); + } + + written = (count > serial->bulk_out_size) ? serial->bulk_out_size : count; + + if (from_user) { + copy_from_user(serial->bulk_out_buffer, buf, written); + } + else { + memcpy (serial->bulk_out_buffer, buf, written); + } + + /* send the data out the bulk port */ + serial->bulk_out_inuse = 1; + serial->bulk_out_transfer = usb_request_bulk (serial->dev, serial->bulk_out_pipe, serial_write_irq, serial->bulk_out_buffer, written, serial); + + return (written); +} + + +static void etek_serial_put_char (struct tty_struct *tty, unsigned char ch) +{ + struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; + + debug_info("USB Serial: etek_serial_put_char\n"); + + if (serial->bulk_out_inuse) { + debug_info ("USB Serial: already writing\n"); + return; + } + + /* send the single character out the bulk port */ + serial->bulk_out_buffer[0] = ch; + serial->bulk_out_inuse = 1; + serial->bulk_out_transfer = usb_request_bulk (serial->dev, serial->bulk_out_pipe, serial_write_irq, serial->bulk_out_buffer, 1, serial); + + return; +} + + +static int etek_write_room (struct tty_struct *tty) +{ + struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; + + debug_info("USB Serial: etek_write_room\n"); + + if (serial->bulk_out_inuse) { + return (0); + } + + return (serial->bulk_out_size); +} + + +static int etek_chars_in_buffer (struct tty_struct *tty) +{ + struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; + + debug_info("USB Serial: etek_chars_in_buffer\n"); + + if (serial->bulk_out_inuse) { + return (serial->bulk_out_size); + } + + return (0); +} + + +static void etek_throttle (struct tty_struct * tty) +{ + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + + debug_info("USB Serial: etek_throttle\n"); + /* Change the control signals */ /* FIXME!!! */ @@ -429,136 +691,340 @@ } -static int Get_Free_Serial (void) +static void etek_unthrottle (struct tty_struct * tty) { - int i; + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + + debug_info("USB Serial: etek_unthrottle\n"); + + /* Change the control signals */ + /* FIXME!!! */ + + return; +} + + +/***************************************************************************** + * generic devices specific driver functions + *****************************************************************************/ +static int generic_serial_open (struct tty_struct *tty, struct file *filp) +{ + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + + debug_info("USB: generic_serial_open\n"); + + if (!serial->present) { + debug_info("USB Serial: no device registered\n"); + return -EINVAL; + } + + if (serial->active) { + debug_info ("USB Serial: device already open\n"); + return -EINVAL; + } + serial->active = 1; - for (i=0; i < NUM_PORTS; ++i) { - if (!serial_state_table[i].present) - return (i); + /* if we have a bulk interrupt, start reading from it */ + if (serial->has_bulk_in) { + /*Start reading from the device*/ + serial->bulk_in_inuse = 1; + serial->bulk_in_transfer = usb_request_bulk (serial->dev, serial->bulk_in_pipe, serial_read_irq, serial->bulk_in_buffer, serial->bulk_in_size, serial); } - return (-1); + + return (0); } -static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) +static void generic_serial_close(struct tty_struct *tty, struct file * filp) { - struct usb_serial_state *serial; - struct usb_interface_descriptor *interface; - struct usb_endpoint_descriptor *endpoint; - SERIAL_TYPE type; - int serial_num; -// int ret; - int i; + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + debug_info("USB: generic_serial_close\n"); - /* look at the device descriptor to see if it is a type that we recognize */ - type = unknown; - if ((dev->descriptor.idVendor == BELKIN_VENDOR_ID) && - (dev->descriptor.idProduct == BELKIN_SERIAL_CONVERTER)) { - /* This is the Belkin serial convertor */ - type = Belkin; - } + /* shutdown any bulk reads that might be going on */ + if (serial->bulk_out_inuse){ + usb_terminate_bulk (serial->dev, serial->bulk_out_transfer); + serial->bulk_out_inuse = 0; + } + if (serial->bulk_in_inuse){ + usb_terminate_bulk (serial->dev, serial->bulk_in_transfer); + serial->bulk_in_inuse = 0; + } + + serial->active = 0; +} + + +static int generic_serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) +{ + struct usb_serial_state *serial = (struct usb_serial_state *) tty->driver_data; + int written; - if ((dev->descriptor.idVendor == PERACOM_VENDOR_ID) && - (dev->descriptor.idProduct == PERACOM_SERIAL_CONVERTER)) { - /* This is the Peracom serial convertor */ - type = Peracom; + debug_info("USB Serial: generic_serial_write\n"); + + /* only do something if we have a bulk out endpoint */ + if (serial->has_bulk_out) { + if (serial->bulk_out_inuse) { + debug_info ("USB Serial: already writing\n"); + return (0); } - if (type == unknown) - return NULL; + written = (count > serial->bulk_out_size) ? serial->bulk_out_size : count; + + if (from_user) { + copy_from_user(serial->bulk_out_buffer, buf, written); + } + else { + memcpy (serial->bulk_out_buffer, buf, written); + } - printk (KERN_INFO "USB serial converter detected.\n"); + /* send the data out the bulk port */ + serial->bulk_out_inuse = 1; + serial->bulk_out_transfer = usb_request_bulk (serial->dev, serial->bulk_out_pipe, serial_write_irq, serial->bulk_out_buffer, written, serial); - if (0>(serial_num = Get_Free_Serial())) { - debug_info("USB Serial: Too many devices connected\n"); - return NULL; + return (written); } - serial = &serial_state_table[serial_num]; + /* no bulk out, so return 0 bytes written */ + return (0); +} - memset(serial, 0, sizeof(serial)); - serial->dev = dev; - serial->type = type; - /* we should have 1 bulk in, 1 bulk out, and 1 interrupt in endpoints */ - interface = &dev->actconfig->interface[ifnum].altsetting[0]; - for (i = 0; i < interface->bNumEndpoints; ++i) { - endpoint = &interface->endpoint[i]; - - if ((endpoint->bEndpointAddress & 0x80) && - ((endpoint->bmAttributes & 3) == 0x02)) { - /* we found the bulk in endpoint */ - serial->bulk_in_inuse = 0; - serial->bulk_in_endpoint = endpoint->bEndpointAddress; - serial->bulk_in_size = endpoint->wMaxPacketSize; - serial->bulk_in_interval = endpoint->bInterval; - serial->bulk_in_pipe = usb_rcvbulkpipe (dev, serial->bulk_in_endpoint); - serial->bulk_in_buffer = kmalloc (serial->bulk_in_size, GFP_KERNEL); - if (!serial->bulk_in_buffer) { - printk("USB Serial: Couldn't allocate bulk_in_buffer\n"); - goto probe_error; - } +static void generic_serial_put_char (struct tty_struct *tty, unsigned char ch) +{ + struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; + + debug_info("USB Serial: generic_serial_put_char\n"); + + /* if we have a bulk out endpoint, then shove a character out it */ + if (serial->has_bulk_out) { + if (serial->bulk_out_inuse) { + debug_info ("USB Serial: already writing\n"); + return; } - if (((endpoint->bEndpointAddress & 0x80) == 0x00) && - ((endpoint->bmAttributes & 3) == 0x02)) { - /* we found the bulk out endpoint */ - serial->bulk_out_inuse = 0; - serial->bulk_out_endpoint = endpoint->bEndpointAddress; - serial->bulk_out_size = endpoint->wMaxPacketSize; - serial->bulk_out_interval = endpoint->bInterval; - serial->bulk_out_pipe = usb_rcvbulkpipe (dev, serial->bulk_out_endpoint); - serial->bulk_out_buffer = kmalloc (serial->bulk_out_size, GFP_KERNEL); - if (!serial->bulk_out_buffer) { - printk("USB Serial: Couldn't allocate bulk_out_buffer\n"); - goto probe_error; - } + /* send the single character out the bulk port */ + serial->bulk_out_buffer[0] = ch; + serial->bulk_out_inuse = 1; + serial->bulk_out_transfer = usb_request_bulk (serial->dev, serial->bulk_out_pipe, serial_write_irq, serial->bulk_out_buffer, 1, serial); + } + + return; +} + + +static int generic_write_room (struct tty_struct *tty) +{ + struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; + + debug_info("USB Serial: generic_write_room\n"); + + if (serial->has_bulk_out) { + if (serial->bulk_out_inuse) { + return (0); } - - if ((endpoint->bEndpointAddress & 0x80) && - ((endpoint->bmAttributes & 3) == 0x03)) { - /* we found the interrupt in endpoint */ - serial->interrupt_in_inuse = 0; - serial->interrupt_in_endpoint = endpoint->bEndpointAddress; - serial->interrupt_in_size = endpoint->wMaxPacketSize; - 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->interrupt_in_buffer) { - printk("USB Serial: Couldn't allocate interrupt_in_buffer\n"); - goto probe_error; - } + return (serial->bulk_out_size); + } + + return (0); +} + + +static int generic_chars_in_buffer (struct tty_struct *tty) +{ + struct usb_serial_state *serial = (struct usb_serial_state *)tty->driver_data; + + debug_info("USB Serial: generic_chars_in_buffer\n"); + + if (serial->has_bulk_out) { + if (serial->bulk_out_inuse) { + return (serial->bulk_out_size); } + } + return (0); +} + + +static int Get_Free_Serial (void) +{ + int i; + + for (i=0; i < NUM_PORTS; ++i) { + if (!serial_state_table[i].present) + return (i); } + return (-1); +} + + +static void * usb_serial_probe(struct usb_device *dev, unsigned int ifnum) +{ + struct usb_serial_state *serial = NULL; + struct usb_interface_descriptor *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_endpoint_descriptor *interrupt_in_endpoint = NULL; + struct usb_endpoint_descriptor *bulk_in_endpoint = NULL; + struct usb_endpoint_descriptor *bulk_out_endpoint = NULL; +// SERIAL_TYPE type; + struct usb_serial_device_type *type; + int device_num; + int serial_num; +// int ret; + int i; + char interrupt_pipe; + char bulk_in_pipe; + char bulk_out_pipe; + + /* loop through our list of known serial converters, and see if this device matches */ + device_num = 0; + while (usb_serial_devices[device_num] != NULL) { + type = usb_serial_devices[device_num]; + #ifdef SERIAL_DEBUG + printk ("Looking at %s\nVendor id=%.4x\nProduct id=%.4x", type->name, *(type->idVendor), *(type->idProduct)); + #endif + + /* look at the device descriptor */ + if ((dev->descriptor.idVendor == *(type->idVendor)) && + (dev->descriptor.idProduct == *(type->idProduct))) { + + debug_info("descriptor matches...looking at the endpoints\n") + + /* descriptor matches, let's try to find the endpoints needed */ + interrupt_pipe = bulk_in_pipe = bulk_out_pipe = HAS_NOT; + + /* check out the endpoints */ + interface = &dev->actconfig->interface[ifnum].altsetting[0]; + for (i = 0; i < interface->bNumEndpoints; ++i) { + endpoint = &interface->endpoint[i]; + + if ((endpoint->bEndpointAddress & 0x80) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk in endpoint */ + debug_info("found bulk in\n"); + if (bulk_in_pipe == HAS) { + printk("USB Serial: can't have more than one bulk in endpoint\n"); + goto probe_error; + } + bulk_in_pipe = HAS; + bulk_in_endpoint = endpoint; + } + + if (((endpoint->bEndpointAddress & 0x80) == 0x00) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk out endpoint */ + debug_info("found bulk out\n"); + if (bulk_out_pipe == HAS) { + printk("USB Serial: can't have more than one bulk out endpoint\n"); + goto probe_error; + } + bulk_out_pipe = HAS; + bulk_out_endpoint = endpoint; + } + + if ((endpoint->bEndpointAddress & 0x80) && + ((endpoint->bmAttributes & 3) == 0x03)) { + /* we found a interrupt in endpoint */ + debug_info("found interrupt in\n"); + if (interrupt_pipe == HAS) { + printk("USB Serial: can't have more than one interrupt in endpoint\n"); + goto probe_error; + } + interrupt_pipe = HAS; + interrupt_in_endpoint = endpoint; + } + + } + /* verify that we found all of the endpoints that we need */ + if ((interrupt_pipe & type->needs_interrupt_in) && + (bulk_in_pipe & type->needs_bulk_in) && + (bulk_out_pipe & type->needs_bulk_out)) { + /* found all that we need */ + printk (KERN_INFO "USB serial converter detected.\n"); + + if (0>(serial_num = Get_Free_Serial())) { + debug_info("USB Serial: Too many devices connected\n"); + return NULL; + } + + serial = &serial_state_table[serial_num]; + + memset(serial, 0, sizeof(struct usb_serial_state)); + serial->dev = dev; + serial->type = type; + + /* set up the endpoint information */ + if (bulk_in_endpoint) { + serial->has_bulk_in = 1; + serial->bulk_in_inuse = 0; + serial->bulk_in_endpoint = bulk_in_endpoint->bEndpointAddress; + serial->bulk_in_size = bulk_in_endpoint->wMaxPacketSize; + serial->bulk_in_interval = bulk_in_endpoint->bInterval; + serial->bulk_in_pipe = usb_rcvbulkpipe (dev, serial->bulk_in_endpoint); + serial->bulk_in_buffer = kmalloc (serial->bulk_in_size, GFP_KERNEL); + if (!serial->bulk_in_buffer) { + printk("USB Serial: Couldn't allocate bulk_in_buffer\n"); + goto probe_error; + } + } + + if (bulk_out_endpoint) { + serial->has_bulk_out = 1; + serial->bulk_out_inuse = 0; + serial->bulk_out_endpoint = bulk_out_endpoint->bEndpointAddress; + serial->bulk_out_size = bulk_out_endpoint->wMaxPacketSize; + serial->bulk_out_interval = bulk_out_endpoint->bInterval; + serial->bulk_out_pipe = usb_rcvbulkpipe (dev, serial->bulk_out_endpoint); + serial->bulk_out_buffer = kmalloc (serial->bulk_out_size, GFP_KERNEL); + if (!serial->bulk_out_buffer) { + printk("USB Serial: Couldn't allocate bulk_out_buffer\n"); + goto probe_error; + } + } + + if (interrupt_in_endpoint) { + serial->has_interrupt_in = 1; + serial->interrupt_in_inuse = 0; + serial->interrupt_in_endpoint = interrupt_in_endpoint->bEndpointAddress; + serial->interrupt_in_size = interrupt_in_endpoint->wMaxPacketSize; + serial->interrupt_in_interval = interrupt_in_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->interrupt_in_buffer) { + printk("USB Serial: Couldn't allocate interrupt_in_buffer\n"); + goto probe_error; + } + } + + #if 0 + /* set up an interrupt for out bulk in pipe */ + /* ask for a bulk read */ + serial->bulk_in_inuse = 1; + serial->bulk_in_transfer = usb_request_bulk (serial->dev, serial->bulk_in_pipe, serial_read_irq, serial->bulk_in_buffer, serial->bulk_in_size, serial); + + /* set up our interrupt to be the time for the bulk in read */ + ret = usb_request_irq (dev, serial->bulk_in_pipe, usb_serial_irq, serial->bulk_in_interval, serial, &serial->irq_handle); + if (ret) { + printk(KERN_INFO "USB Serial failed usb_request_irq (0x%x)\n", ret); + goto probe_error; + } + #endif + + serial->present = 1; + MOD_INC_USE_COUNT; + + return serial; + } else { + printk(KERN_INFO "USB Serial, descriptors matched, but endpoints did not\n"); + } + } - /* verify that we found all of the endpoints that we need */ - if ((!serial->bulk_in_buffer) || - (!serial->bulk_out_buffer) || - (!serial->interrupt_in_buffer)) { - printk("USB Serial: did not find all of the required endpoints\n"); - goto probe_error; + /* look at the next type in our list */ + ++device_num; } - - /* set up an interrupt for out bulk in pipe */ - /* ask for a bulk read */ -// serial->bulk_in_inuse = 1; -// serial->bulk_in_transfer = usb_request_bulk (serial->dev, serial->bulk_in_pipe, serial_read_irq, serial->bulk_in_buffer, serial->bulk_in_size, serial); - /* set up our interrupt to be the time for the bulk in read */ -// ret = usb_request_irq (dev, serial->bulk_in_pipe, usb_serial_irq, serial->bulk_in_interval, serial, &serial->irq_handle); -// if (ret) { -// printk(KERN_INFO "USB Serial failed usb_request_irq (0x%x)\n", ret); -// goto probe_error; -// } - - serial->present = 1; - MOD_INC_USE_COUNT; - return serial; probe_error: if (serial) { @@ -636,6 +1102,8 @@ serial_tty_driver.flags = TTY_DRIVER_REAL_RAW; serial_tty_driver.refcount = &serial_refcount; serial_tty_driver.table = serial_tty; + serial_tty_driver.proc_entry = NULL; + serial_tty_driver.other = NULL; serial_tty_driver.termios = serial_termios; serial_tty_driver.termios_locked = serial_termios_locked; diff -u --recursive --new-file v2.3.26/linux/drivers/usb/usb.c linux/drivers/usb/usb.c --- v2.3.26/linux/drivers/usb/usb.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/usb/usb.c Tue Nov 9 08:24:32 1999 @@ -720,7 +720,7 @@ } memset(config->interface, 0, - config->bNumInterfaces*sizeof(struct usb_interface_descriptor)); + config->bNumInterfaces * sizeof(struct usb_interface)); buffer += config->bLength; size -= config->bLength; @@ -1140,13 +1140,16 @@ } if (usb_get_string(dev, dev->string_langid, index, u.buffer, 4) < 0 || - usb_get_string(dev, dev->string_langid, index, u.buffer, - u.desc.bLength) < 0) { + ((ret = usb_get_string(dev, dev->string_langid, index, u.buffer, + u.desc.bLength)) < 0)) { printk(KERN_ERR "usb: error retrieving string\n"); return NULL; } + if (ret > 0) ret /= 2; /* going from 16-bit chars to 8-bit */ len = u.desc.bLength / 2; /* includes terminating null */ + /* after removing bLength & bDescType */ + if (ret < len) len = ret; /* use min of (ret, len) */ ptr = kmalloc(len, GFP_KERNEL); if (!ptr) { diff -u --recursive --new-file v2.3.26/linux/drivers/usb/usb_scsi.c linux/drivers/usb/usb_scsi.c --- v2.3.26/linux/drivers/usb/usb_scsi.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/usb/usb_scsi.c Thu Nov 11 16:57:31 1999 @@ -108,7 +108,7 @@ static struct proc_dir_entry proc_usb_scsi = { - PROC_SCSI_USB_SCSI, + PROC_SCSI_USB_SCSI, /* It's currently b0rken */ 0, NULL, S_IFDIR | S_IRUGO | S_IXUGO, diff -u --recursive --new-file v2.3.26/linux/drivers/video/atafb.c linux/drivers/video/atafb.c --- v2.3.26/linux/drivers/video/atafb.c Thu Aug 12 10:22:33 1999 +++ linux/drivers/video/atafb.c Mon Nov 8 11:03:21 1999 @@ -464,7 +464,7 @@ int mode; strcpy(fix->id,"Atari Builtin"); - fix->smem_start = real_screen_base; + fix->smem_start = (unsigned long)real_screen_base; fix->smem_len = screen_len; fix->type=FB_TYPE_INTERLEAVED_PLANES; fix->type_aux=2; @@ -797,7 +797,7 @@ struct atafb_par *par ) { strcpy(fix->id, "Atari Builtin"); - fix->smem_start = real_screen_base; + fix->smem_start = (unsigned long)real_screen_base; fix->smem_len = screen_len; fix->type = FB_TYPE_INTERLEAVED_PLANES; fix->type_aux = 2; @@ -1760,7 +1760,7 @@ int mode; strcpy(fix->id,"Atari Builtin"); - fix->smem_start = real_screen_base; + fix->smem_start = (unsigned long)real_screen_base; fix->smem_len = screen_len; fix->type = FB_TYPE_INTERLEAVED_PLANES; fix->type_aux = 2; @@ -2104,7 +2104,7 @@ { strcpy(fix->id,"Unknown Extern"); - fix->smem_start=external_addr; + fix->smem_start = (unsigned long)external_addr; fix->smem_len = PAGE_ALIGN(external_len); if (external_depth == 1) { fix->type = FB_TYPE_PACKED_PIXELS; @@ -2488,7 +2488,7 @@ atafb_get_var(&var, con, info); if (con == -1) con=0; - display->screen_base = fix.smem_start; + display->screen_base = (void *)fix.smem_start; display->visual = fix.visual; display->type = fix.type; display->type_aux = fix.type_aux; diff -u --recursive --new-file v2.3.26/linux/fs/bfs/inode.c linux/fs/bfs/inode.c --- v2.3.26/linux/fs/bfs/inode.c Sun Nov 7 16:37:34 1999 +++ linux/fs/bfs/inode.c Tue Nov 9 10:02:33 1999 @@ -263,7 +263,7 @@ struct buffer_head * bh; struct bfs_super_block * bfs_sb; struct inode * inode; - int i, imap_len; + int i, imap_len, bmap_len; MOD_INC_USE_COUNT; lock_super(s); @@ -295,9 +295,11 @@ s->su_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode) + BFS_ROOT_INO - 1; - s->su_bmap = kmalloc(sizeof(struct bfs_bmap) * s->su_lasti, GFP_KERNEL); + bmap_len = sizeof(struct bfs_bmap) * s->su_lasti; + s->su_bmap = kmalloc(bmap_len, GFP_KERNEL); if (!s->su_bmap) goto out; + memset(s->su_bmap, 0, bmap_len); imap_len = s->su_lasti/8 + 1; s->su_imap = kmalloc(imap_len, GFP_KERNEL); if (!s->su_imap) { diff -u --recursive --new-file v2.3.26/linux/fs/binfmt_misc.c linux/fs/binfmt_misc.c --- v2.3.26/linux/fs/binfmt_misc.c Fri Sep 10 23:57:36 1999 +++ linux/fs/binfmt_misc.c Thu Nov 11 16:57:31 1999 @@ -471,24 +471,6 @@ return 0; } -#ifdef MODULE -/* - * This is called as the fill_inode function when an inode - * is going into (fill = 1) or out of service (fill = 0). - * We use it here to manage the module use counts. - * - * Note: only the top-level directory needs to do this; if - * a lower level is referenced, the parent will be as well. - */ -static void bm_modcount(struct inode *inode, int fill) -{ - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -} -#endif - static int __init init_misc_binfmt(void) { int error = -ENOENT; @@ -497,9 +479,7 @@ bm_dir = create_proc_entry("sys/fs/binfmt_misc", S_IFDIR, NULL); if (!bm_dir) goto out; -#ifdef MODULE - bm_dir->fill_inode = bm_modcount; -#endif + bm_dir->owner = THIS_MODULE; status = create_proc_entry("status", S_IFREG | S_IRUGO | S_IWUSR, bm_dir); diff -u --recursive --new-file v2.3.26/linux/fs/buffer.c linux/fs/buffer.c --- v2.3.26/linux/fs/buffer.c Sun Nov 7 16:37:34 1999 +++ linux/fs/buffer.c Thu Nov 11 10:33:42 1999 @@ -91,7 +91,7 @@ }; static struct bh_free_head free_list[NR_SIZES]; -static kmem_cache_t *bh_cachep; +kmem_cache_t *bh_cachep; static int grow_buffers(int size); @@ -130,8 +130,6 @@ int bdflush_min[N_PARAM] = { 0, 10, 5, 25, 0, 1*HZ, 1*HZ, 1, 1}; int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,600*HZ, 6000*HZ, 6000*HZ, 2047, 5}; -void wakeup_bdflush(int); - /* * Rewrote the wait-routines to use the "new" wait-queue functionality, * and getting rid of the cli-sti pairs. The wait-queue routines still @@ -707,7 +705,7 @@ mark_buffer_uptodate(bh, uptodate); /* This is a temporary buffer used for page I/O. */ - page = mem_map + MAP_NR(bh->b_data); + page = bh->b_page; if (!uptodate) SetPageError(page); @@ -760,7 +758,6 @@ return; } - /* * Ok, this is getblk, and it isn't very clear, again to hinder * race-conditions. Most of the code is seldom used, (ie repeating), @@ -823,7 +820,7 @@ unsigned long dirty, tot, hard_dirty_limit, soft_dirty_limit; dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT; - tot = nr_lru_pages + nr_free_pages - nr_free_highpages; + tot = nr_free_buffer_pages(); hard_dirty_limit = tot * bdf_prm.b_un.nfract / 100; soft_dirty_limit = hard_dirty_limit >> 1; @@ -1092,6 +1089,20 @@ return NULL; } +void set_bh_page (struct buffer_head *bh, struct page *page, unsigned int offset) +{ + bh->b_page = page; + if (offset >= PAGE_SIZE) + BUG(); + if (PageHighMem(page)) + /* + * This catches illegal uses and preserves the offset: + */ + bh->b_data = (char *)(0 + offset); + else + bh->b_data = (char *)(page_address(page) + offset); +} + /* * Create the appropriate buffers when given a page for data area and * the size of each buffer.. Use the bh->b_this_page linked list to @@ -1101,7 +1112,7 @@ * from ordinary buffer allocations, and only async requests are allowed * to sleep waiting for buffer heads. */ -static struct buffer_head * create_buffers(unsigned long page, unsigned long size, int async) +static struct buffer_head * create_buffers(struct page * page, unsigned long size, int async) { struct buffer_head *bh, *head; long offset; @@ -1124,7 +1135,8 @@ atomic_set(&bh->b_count, 0); bh->b_size = size; - bh->b_data = (char *) (page+offset); + set_bh_page(bh, page, offset); + bh->b_list = BUF_CLEAN; bh->b_end_io = end_buffer_io_bad; } @@ -1183,7 +1195,7 @@ * They don't show up in the buffer hash table, but they *are* * registered in page->buffers. */ - head = create_buffers(page_address(page), size, 1); + head = create_buffers(page, size, 1); if (page->buffers) BUG(); if (!head) @@ -1273,7 +1285,7 @@ { struct buffer_head *bh, *head, *tail; - head = create_buffers(page_address(page), blocksize, 1); + head = create_buffers(page, blocksize, 1); if (page->buffers) BUG(); @@ -1377,10 +1389,11 @@ unsigned long start_offset, start_bytes, end_bytes; unsigned long bbits, blocks, i, len; struct buffer_head *bh, *head; - char * target_buf; + char *target_buf, *kaddr; int need_balance_dirty; - target_buf = (char *)page_address(page) + offset; + kaddr = (char *)kmap(page); + target_buf = kaddr + offset; if (!PageLocked(page)) BUG(); @@ -1445,7 +1458,7 @@ if (!buffer_uptodate(bh) && (start_offset || (end_bytes && (i == end_block)))) { if (buffer_new(bh)) { - memset(bh->b_data, 0, bh->b_size); + memset(kaddr + i*blocksize, 0, blocksize); } else { ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); @@ -1463,6 +1476,10 @@ len = end_bytes; end_bytes = 0; } + if (target_buf >= kaddr + PAGE_SIZE) + BUG(); + if (target_buf+len-1 >= kaddr + PAGE_SIZE) + BUG(); err = copy_from_user(target_buf, buf, len); target_buf += len; buf += len; @@ -1511,9 +1528,11 @@ */ if (!partial) SetPageUptodate(page); + kunmap(page); return bytes; out: ClearPageUptodate(page); + kunmap(page); return err; } @@ -1714,8 +1733,6 @@ * for them to complete. Clean up the buffer_heads afterwards. */ -#define dprintk(x...) - static int do_kio(struct kiobuf *kiobuf, int rw, int nr, struct buffer_head *bh[], int size) { @@ -1726,8 +1743,6 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - dprintk ("do_kio start %d\n", rw); - if (rw == WRITE) rw = WRITERAW; atomic_add(nr, &kiobuf->io_count); @@ -1753,8 +1768,6 @@ spin_unlock(&unused_list_lock); - dprintk ("do_kio end %d %d\n", iosize, err); - if (iosize) return iosize; if (kiobuf->errno) @@ -1808,12 +1821,6 @@ panic("brw_kiovec: iobuf not initialised"); } - /* DEBUG */ -#if 0 - return iobuf->length; -#endif - dprintk ("brw_kiovec: start\n"); - /* * OK to walk down the iovec doing page IO on each page we find. */ @@ -1822,7 +1829,6 @@ iobuf = iovec[i]; offset = iobuf->offset; length = iobuf->length; - dprintk ("iobuf %d %d %d\n", offset, length, size); for (pageind = 0; pageind < iobuf->nr_pages; pageind++) { map = iobuf->maplist[pageind]; @@ -1842,7 +1848,7 @@ tmp->b_dev = B_FREE; tmp->b_size = size; - tmp->b_data = (char *) (page + offset); + set_bh_page(tmp, map, offset); tmp->b_this_page = tmp; init_buffer(tmp, end_buffer_io_kiobuf, NULL); @@ -1856,8 +1862,6 @@ set_bit(BH_Dirty, &tmp->b_state); } - dprintk ("buffer %d (%d) at %p\n", - bhind, tmp->b_blocknr, tmp->b_data); bh[bhind++] = tmp; length -= size; offset += size; @@ -1892,7 +1896,6 @@ } finished: - dprintk ("brw_kiovec: end (%d, %d)\n", transferred, err); if (transferred) return transferred; return err; @@ -2002,7 +2005,8 @@ unsigned long iblock; struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE]; unsigned int blocksize, blocks; - int nr; + unsigned long kaddr = 0; + int nr, i; if (!PageLocked(page)) PAGE_BUG(page); @@ -2015,6 +2019,7 @@ iblock = page->index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); bh = head; nr = 0; + i = 0; do { if (buffer_uptodate(bh)) @@ -2023,7 +2028,9 @@ if (!buffer_mapped(bh)) { inode->i_op->get_block(inode, iblock, bh, 0); if (!buffer_mapped(bh)) { - memset(bh->b_data, 0, blocksize); + if (!kaddr) + kaddr = kmap(page); + memset((char *)(kaddr + i*blocksize), 0, blocksize); set_bit(BH_Uptodate, &bh->b_state); continue; } @@ -2033,7 +2040,7 @@ atomic_inc(&bh->b_count); arr[nr] = bh; nr++; - } while (iblock++, (bh = bh->b_this_page) != head); + } while (i++, iblock++, (bh = bh->b_this_page) != head); ++current->maj_flt; if (nr) { @@ -2048,6 +2055,8 @@ SetPageUptodate(page); UnlockPage(page); } + if (kaddr) + kunmap(page); return 0; } @@ -2057,8 +2066,7 @@ */ static int grow_buffers(int size) { - unsigned long page; - struct page * page_map; + struct page * page; struct buffer_head *bh, *tmp; struct buffer_head * insert_point; int isize; @@ -2068,8 +2076,9 @@ return 0; } - if (!(page = __get_free_page(GFP_BUFFER))) - return 0; + page = alloc_page(GFP_BUFFER); + if (!page) + goto out; bh = create_buffers(page, size, 0); if (!bh) goto no_buffer_head; @@ -2099,14 +2108,14 @@ free_list[isize].list = bh; spin_unlock(&free_list[isize].lock); - page_map = mem_map + MAP_NR(page); - page_map->buffers = bh; - lru_cache_add(page_map); + page->buffers = bh; + lru_cache_add(page); atomic_inc(&buffermem_pages); return 1; no_buffer_head: - free_page(page); + __free_page(page); +out: return 0; } diff -u --recursive --new-file v2.3.26/linux/fs/coda/sysctl.c linux/fs/coda/sysctl.c --- v2.3.26/linux/fs/coda/sysctl.c Mon Nov 1 13:56:27 1999 +++ linux/fs/coda/sysctl.c Thu Nov 11 16:57:31 1999 @@ -478,15 +478,6 @@ struct proc_dir_entry* proc_fs_coda; -static void coda_proc_modcount(struct inode *inode, int fill) -{ - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; - -} - #endif #define coda_proc_create(name,get_info) \ @@ -502,7 +493,7 @@ #ifdef CONFIG_PROC_FS proc_fs_coda = create_proc_entry("coda", S_IFDIR, proc_root_fs); - proc_fs_coda->fill_inode = &coda_proc_modcount; + proc_fs_coda->owner = THIS_MODULE; coda_proc_create("vfs_stats", coda_vfs_stats_get_info); coda_proc_create("upcall_stats", coda_upcall_stats_get_info); coda_proc_create("permission_stats", coda_permission_stats_get_info); diff -u --recursive --new-file v2.3.26/linux/fs/exec.c linux/fs/exec.c --- v2.3.26/linux/fs/exec.c Mon Nov 1 13:56:27 1999 +++ linux/fs/exec.c Thu Nov 11 10:33:42 1999 @@ -225,17 +225,13 @@ page = bprm->page[i]; new = 0; if (!page) { - /* - * Cannot yet use highmem page because - * we cannot sleep with a kmap held. - */ - page = __get_pages(GFP_USER, 0); + page = alloc_page(GFP_HIGHUSER); bprm->page[i] = page; if (!page) return -ENOMEM; new = 1; } - kaddr = (char *)kmap(page, KM_WRITE); + kaddr = (char *)kmap(page); if (new && offset) memset(kaddr, 0, offset); @@ -247,7 +243,7 @@ } err = copy_from_user(kaddr + offset, str, bytes_to_copy); flush_page_to_ram(page); - kunmap((unsigned long)kaddr, KM_WRITE); + kunmap(page); if (err) return -EFAULT; @@ -462,6 +458,7 @@ /* * Make sure we have a private signal table */ + task_lock(current); oldsig = current->sig; retval = make_private_signals(); if (retval) goto flush_failed; @@ -500,6 +497,7 @@ flush_signal_handlers(current); flush_old_files(current->files); + task_unlock(current); return 0; @@ -508,6 +506,7 @@ kfree(current->sig); flush_failed: current->sig = oldsig; + task_unlock(current); return retval; } @@ -681,12 +680,12 @@ if (offset != PAGE_SIZE) continue; offset = 0; - kunmap((unsigned long)kaddr, KM_WRITE); + kunmap(page); inside: page = bprm->page[bprm->p/PAGE_SIZE]; - kaddr = (char *)kmap(page, KM_WRITE); + kaddr = (char *)kmap(page); } - kunmap((unsigned long)kaddr, KM_WRITE); + kunmap(page); bprm->argc--; } } diff -u --recursive --new-file v2.3.26/linux/fs/ext2/file.c linux/fs/ext2/file.c --- v2.3.26/linux/fs/ext2/file.c Sun Nov 7 16:37:34 1999 +++ linux/fs/ext2/file.c Tue Nov 9 10:05:44 1999 @@ -62,6 +62,8 @@ case 1: offset += file->f_pos; } + if (offset<0) + return -EINVAL; if (((unsigned long long) offset >> 32) != 0) { if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)]) return -EINVAL; diff -u --recursive --new-file v2.3.26/linux/fs/ext2/ioctl.c linux/fs/ext2/ioctl.c --- v2.3.26/linux/fs/ext2/ioctl.c Mon Nov 1 13:56:27 1999 +++ linux/fs/ext2/ioctl.c Mon Nov 8 10:42:35 1999 @@ -23,7 +23,7 @@ switch (cmd) { case EXT2_IOC_GETFLAGS: flags = inode->u.ext2_i.i_flags & EXT2_FL_USER_VISIBLE; - return put_user(inode->u.ext2_i.i_flags, (int *) arg); + return put_user(flags, (int *) arg); case EXT2_IOC_SETFLAGS: { unsigned int oldflags; diff -u --recursive --new-file v2.3.26/linux/fs/minix/bitmap.c linux/fs/minix/bitmap.c --- v2.3.26/linux/fs/minix/bitmap.c Mon Aug 9 12:29:00 1999 +++ linux/fs/minix/bitmap.c Tue Nov 9 15:02:01 1999 @@ -251,13 +251,15 @@ struct buffer_head * bh; int i,j; - if (!dir || !(inode = get_empty_inode())) + inode = get_empty_inode(); + if (!inode) return NULL; sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = 0; j = 8192; bh = NULL; + lock_super(sb); for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) { bh = inode->i_sb->u.minix_sb.s_imap[i]; if ((j = minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) @@ -265,17 +267,20 @@ } if (!bh || j >= 8192) { iput(inode); + unlock_super(sb); return NULL; } if (minix_set_bit(j,bh->b_data)) { /* shouldn't happen */ printk("new_inode: bit already set"); iput(inode); + unlock_super(sb); return NULL; } mark_buffer_dirty(bh, 1); j += i*8192; if (!j || j > inode->i_sb->u.minix_sb.s_ninodes) { iput(inode); + unlock_super(sb); return NULL; } inode->i_nlink = 1; diff -u --recursive --new-file v2.3.26/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c --- v2.3.26/linux/fs/ncpfs/dir.c Mon Nov 1 13:56:27 1999 +++ linux/fs/ncpfs/dir.c Mon Nov 8 18:01:12 1999 @@ -405,14 +405,13 @@ { 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)) + if (dent_addr > (unsigned long)high_memory - sizeof(struct dentry)) goto bad_addr; if ((dent_addr & ~align_mask) != dent_addr) goto bad_align; diff -u --recursive --new-file v2.3.26/linux/fs/ncpfs/mmap.c linux/fs/ncpfs/mmap.c --- v2.3.26/linux/fs/ncpfs/mmap.c Sun Nov 7 16:37:34 1999 +++ linux/fs/ncpfs/mmap.c Thu Nov 11 10:33:42 1999 @@ -43,7 +43,7 @@ int bufsize; int pos; - page = __get_pages(GFP_KERNEL, 0); + page = alloc_page(GFP_KERNEL); if (!page) return page; pg_addr = page_address(page); diff -u --recursive --new-file v2.3.26/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c --- v2.3.26/linux/fs/nfsd/nfsctl.c Sun Nov 7 16:37:34 1999 +++ linux/fs/nfsd/nfsctl.c Thu Nov 11 16:57:31 1999 @@ -257,21 +257,6 @@ extern int (*do_nfsservctl)(int, void *, void *); /* - * This is called as the fill_inode function when an inode - * is going into (fill = 1) or out of service (fill = 0). - * - * We use it here to make sure the module can't be unloaded - * while a /proc inode is in use. - */ -void nfsd_modcount(struct inode *inode, int fill) -{ - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -} - -/* * Initialize the module */ int diff -u --recursive --new-file v2.3.26/linux/fs/nfsd/stats.c linux/fs/nfsd/stats.c --- v2.3.26/linux/fs/nfsd/stats.c Thu Jan 7 09:28:47 1999 +++ linux/fs/nfsd/stats.c Thu Nov 11 16:57:31 1999 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -77,9 +78,7 @@ if ((ent = svc_proc_register(&nfsd_svcstats)) != 0) { ent->read_proc = nfsd_proc_read; -#ifdef MODULE - ent->fill_inode = nfsd_modcount; -#endif + ent->owner = THIS_MODULE; } } diff -u --recursive --new-file v2.3.26/linux/fs/proc/Makefile linux/fs/proc/Makefile --- v2.3.26/linux/fs/proc/Makefile Sun Nov 7 16:37:34 1999 +++ linux/fs/proc/Makefile Tue Nov 9 11:56:37 1999 @@ -8,8 +8,8 @@ # Note 2! The CFLAGS definitions are now in the main makefile. O_TARGET := proc.o -O_OBJS := inode.o root.o base.o generic.o mem.o link.o fd.o array.o \ - kmsg.o scsi.o proc_tty.o sysvipc.o proc_misc.o kcore.o +O_OBJS := inode.o root.o base.o generic.o array.o \ + kmsg.o proc_tty.o proc_misc.o kcore.o ifdef CONFIG_OMIRR O_OBJS := $(O_OBJS) omirr.o endif diff -u --recursive --new-file v2.3.26/linux/fs/proc/array.c linux/fs/proc/array.c --- v2.3.26/linux/fs/proc/array.c Sun Nov 7 16:37:34 1999 +++ linux/fs/proc/array.c Tue Nov 9 19:39:07 1999 @@ -46,6 +46,10 @@ * * Gerhard Wichert : added BIGMEM support * Siemens AG + * + * Al Viro & Jeff Garzik : moved most of the thing into base.c and + * : proc_misc.c. The rest may eventually go into + * : base.c too. */ #include @@ -70,401 +74,7 @@ #include #include #include - - -static int open_kcore(struct inode * inode, struct file * filp) -{ - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; -} - -extern ssize_t read_kcore(struct file *, char *, size_t, loff_t *); - -static struct file_operations proc_kcore_operations = { - NULL, /* lseek */ - read_kcore, - NULL, /* write */ - NULL, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - open_kcore -}; - -struct inode_operations proc_kcore_inode_operations = { - &proc_kcore_operations, -}; - -/* - * This function accesses profiling information. The returned data is - * binary: the sampling step and the actual contents of the profile - * buffer. Use of the program readprofile is recommended in order to - * get meaningful info out of these data. - */ -static ssize_t read_profile(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - unsigned long p = *ppos; - ssize_t read; - char * pnt; - unsigned int sample_step = 1 << prof_shift; - - if (p >= (prof_len+1)*sizeof(unsigned int)) - return 0; - if (count > (prof_len+1)*sizeof(unsigned int) - p) - count = (prof_len+1)*sizeof(unsigned int) - p; - read = 0; - - while (p < sizeof(unsigned int) && count > 0) { - put_user(*((char *)(&sample_step)+p),buf); - buf++; p++; count--; read++; - } - pnt = (char *)prof_buffer + p - sizeof(unsigned int); - copy_to_user(buf,(void *)pnt,count); - read += count; - *ppos += read; - return read; -} - -/* - * Writing to /proc/profile resets the counters - * - * Writing a 'profiling multiplier' value into it also re-sets the profiling - * interrupt frequency, on architectures that support this. - */ -static ssize_t write_profile(struct file * file, const char * buf, - size_t count, loff_t *ppos) -{ -#ifdef __SMP__ - extern int setup_profiling_timer (unsigned int multiplier); - - if (count==sizeof(int)) { - unsigned int multiplier; - - if (copy_from_user(&multiplier, buf, sizeof(int))) - return -EFAULT; - - if (setup_profiling_timer(multiplier)) - return -EINVAL; - } -#endif - - memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer)); - return count; -} - -static struct file_operations proc_profile_operations = { - NULL, /* lseek */ - read_profile, - write_profile, -}; - -struct inode_operations proc_profile_inode_operations = { - &proc_profile_operations, -}; - -static struct page * get_phys_addr(struct mm_struct * mm, unsigned long ptr) -{ - pgd_t *pgd; - pmd_t *pmd; - pte_t pte; - - if (ptr >= TASK_SIZE) - return 0; - pgd = pgd_offset(mm,ptr); - if (pgd_none(*pgd)) - return 0; - if (pgd_bad(*pgd)) { - pgd_ERROR(*pgd); - pgd_clear(pgd); - return 0; - } - pmd = pmd_offset(pgd,ptr); - if (pmd_none(*pmd)) - return 0; - if (pmd_bad(*pmd)) { - pmd_ERROR(*pmd); - pmd_clear(pmd); - return 0; - } - pte = *pte_offset(pmd,ptr); - if (!pte_present(pte)) - return 0; - return pte_page(pte); -} - -static int get_array(struct mm_struct *mm, unsigned long start, unsigned long end, char * buffer) -{ - struct page *page; - unsigned long kaddr; - int size = 0, result = 0; - char c; - - if (start >= end) - return result; - for (;;) { - page = get_phys_addr(mm, start); - if (!page) - return result; - kaddr = kmap(page, KM_READ) + (start & ~PAGE_MASK); - do { - c = *(char *) kaddr; - if (!c) - result = size; - if (size < PAGE_SIZE) - buffer[size++] = c; - else { - kunmap(kaddr, KM_READ); - return result; - } - kaddr++; - start++; - if (!c && start >= end) { - kunmap(kaddr, KM_READ); - return result; - } - } while (kaddr & ~PAGE_MASK); - kunmap(kaddr, KM_READ); - } - return result; -} - -static struct mm_struct *get_mm(int pid) -{ - struct task_struct *p; - struct mm_struct *mm = NULL; - - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (p) - mm = p->mm; - if (mm) - atomic_inc(&mm->mm_users); - read_unlock(&tasklist_lock); - return mm; -} - - -static int get_env(int pid, char * buffer) -{ - struct mm_struct *mm = get_mm(pid); - int res = 0; - if (mm) { - res = get_array(mm, mm->env_start, mm->env_end, buffer); - mmput(mm); - } - return res; -} - -static int get_arg(int pid, char * buffer) -{ - struct mm_struct *mm = get_mm(pid); - int res = 0; - if (mm) { - res = get_array(mm, mm->arg_start, mm->arg_end, buffer); - mmput(mm); - } - return res; -} - -/* - * These bracket the sleeping functions.. - */ -extern void scheduling_functions_start_here(void); -extern void scheduling_functions_end_here(void); -#define first_sched ((unsigned long) scheduling_functions_start_here) -#define last_sched ((unsigned long) scheduling_functions_end_here) - -static unsigned long get_wchan(struct task_struct *p) -{ - if (!p || p == current || p->state == TASK_RUNNING) - return 0; -#if defined(__i386__) - { - unsigned long ebp, esp, eip; - unsigned long stack_page; - int count = 0; - - stack_page = (unsigned long)p; - esp = p->thread.esp; - if (!stack_page || esp < stack_page || esp > 8188+stack_page) - return 0; - /* include/asm-i386/system.h:switch_to() pushes ebp last. */ - ebp = *(unsigned long *) esp; - do { - if (ebp < stack_page || ebp > 8184+stack_page) - return 0; - eip = *(unsigned long *) (ebp+4); - if (eip < first_sched || eip >= last_sched) - return eip; - ebp = *(unsigned long *) ebp; - } while (count++ < 16); - } -#elif defined(__alpha__) - /* - * This one depends on the frame size of schedule(). Do a - * "disass schedule" in gdb to find the frame size. Also, the - * code assumes that sleep_on() follows immediately after - * interruptible_sleep_on() and that add_timer() follows - * immediately after interruptible_sleep(). Ugly, isn't it? - * Maybe adding a wchan field to task_struct would be better, - * after all... - */ - { - unsigned long schedule_frame; - unsigned long pc; - - pc = thread_saved_pc(&p->thread); - if (pc >= first_sched && pc < last_sched) { - schedule_frame = ((unsigned long *)p->thread.ksp)[6]; - return ((unsigned long *)schedule_frame)[12]; - } - return pc; - } -#elif defined(__mips__) - /* - * The same comment as on the Alpha applies here, too ... - */ - { - unsigned long schedule_frame; - unsigned long pc; - - pc = thread_saved_pc(&p->tss); - if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) { - schedule_frame = ((unsigned long *)(long)p->tss.reg30)[16]; - return (unsigned long)((unsigned long *)schedule_frame)[11]; - } - return pc; - } -#elif defined(__mc68000__) - { - unsigned long fp, pc; - unsigned long stack_page; - int count = 0; - - stack_page = (unsigned long)p; - fp = ((struct switch_stack *)p->thread.ksp)->a6; - do { - if (fp < stack_page+sizeof(struct task_struct) || - fp >= 8184+stack_page) - return 0; - pc = ((unsigned long *)fp)[1]; - /* FIXME: This depends on the order of these functions. */ - if (pc < first_sched || pc >= last_sched) - return pc; - fp = *(unsigned long *) fp; - } while (count++ < 16); - } -#elif defined(__powerpc__) - { - unsigned long ip, sp; - unsigned long stack_page = (unsigned long) p; - int count = 0; - - sp = p->thread.ksp; - do { - sp = *(unsigned long *)sp; - if (sp < stack_page || sp >= stack_page + 8188) - return 0; - if (count > 0) { - ip = *(unsigned long *)(sp + 4); - if (ip < first_sched || ip >= last_sched) - return ip; - } - } while (count++ < 16); - } -#elif defined(__arm__) - { - unsigned long fp, lr; - unsigned long stack_page; - int count = 0; - - stack_page = 4096 + (unsigned long)p; - fp = get_css_fp(&p->thread); - do { - if (fp < stack_page || fp > 4092+stack_page) - return 0; - lr = pc_pointer (((unsigned long *)fp)[-1]); - if (lr < first_sched || lr > last_sched) - return lr; - fp = *(unsigned long *) (fp - 12); - } while (count ++ < 16); - } -#elif defined (__sparc__) - { - unsigned long pc, fp, bias = 0; - unsigned long task_base = (unsigned long) p; - struct reg_window *rw; - int count = 0; - -#ifdef __sparc_v9__ - bias = STACK_BIAS; -#endif - fp = p->thread.ksp + bias; - do { - /* Bogus frame pointer? */ - if (fp < (task_base + sizeof(struct task_struct)) || - fp >= (task_base + (2 * PAGE_SIZE))) - break; - rw = (struct reg_window *) fp; - pc = rw->ins[7]; - if (pc < first_sched || pc >= last_sched) - return pc; - fp = rw->ins[6] + bias; - } while (++count < 16); - } -#endif - - return 0; -} - -#if defined(__i386__) -# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) -# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) -#elif defined(__alpha__) - /* - * See arch/alpha/kernel/ptrace.c for details. - */ -# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \ - + (long)&((struct pt_regs *)0)->reg) -# define KSTK_EIP(tsk) \ - (*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk))) -# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) -#elif defined(__arm__) -# ifdef CONFIG_CPU_26 -# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) -# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020]) -# else -# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1021]) -# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) -# endif -#elif defined(__mc68000__) -#define KSTK_EIP(tsk) \ - ({ \ - unsigned long eip = 0; \ - if ((tsk)->thread.esp0 > PAGE_SIZE && \ - MAP_NR((tsk)->thread.esp0) < max_mapnr) \ - eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ - eip; }) -#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) -#elif defined(__powerpc__) -#define KSTK_EIP(tsk) ((tsk)->thread.regs->nip) -#define KSTK_ESP(tsk) ((tsk)->thread.regs->gpr[1]) -#elif defined (__sparc_v9__) -# define KSTK_EIP(tsk) ((tsk)->thread.kregs->tpc) -# define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP]) -#elif defined(__sparc__) -# define KSTK_EIP(tsk) ((tsk)->thread.kregs->pc) -# define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP]) -#elif defined(__mips__) -# define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg \ - - sizeof(struct pt_regs)) -#define KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32) -# define KSTK_EIP(tsk) (*(unsigned long *)(KSTK_TOS(tsk) + PT_REG(cp0_epc))) -# define KSTK_ESP(tsk) (*(unsigned long *)(KSTK_TOS(tsk) + PT_REG(regs[29]))) -#elif defined(__sh__) -# define KSTK_EIP(tsk) ((tsk)->thread.pc) -# define KSTK_ESP(tsk) ((tsk)->thread.sp) -#endif +#include /* Gcc optimizes away "strlen(x)" for constant x */ #define ADDBUF(buffer, string) \ @@ -654,36 +264,27 @@ } -static int get_status(int pid, char * buffer) +/* task is locked, so we are safe here */ + +int proc_pid_status(struct task_struct *task, char * buffer) { char * orig = buffer; - struct task_struct *tsk; - struct mm_struct *mm = NULL; + struct mm_struct *mm = task->mm; - read_lock(&tasklist_lock); - tsk = find_task_by_pid(pid); - if (tsk) - mm = tsk->mm; - if (mm) - atomic_inc(&mm->mm_users); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ - if (!tsk) - return 0; - buffer = task_name(tsk, buffer); - buffer = task_state(tsk, buffer); + buffer = task_name(task, buffer); + buffer = task_state(task, buffer); if (mm) buffer = task_mem(mm, buffer); - buffer = task_sig(tsk, buffer); - buffer = task_cap(tsk, buffer); - if (mm) - mmput(mm); + buffer = task_sig(task, buffer); + buffer = task_cap(task, buffer); return buffer - orig; } -static int get_stat(int pid, char * buffer) +/* task is locked, so we are safe here */ + +int proc_pid_stat(struct task_struct *task, char * buffer) { - struct task_struct *tsk; - struct mm_struct *mm = NULL; + struct mm_struct *mm = task->mm; unsigned long vsize, eip, esp, wchan; long priority, nice; int tty_pgrp; @@ -691,16 +292,7 @@ char state; int res; - read_lock(&tasklist_lock); - tsk = find_task_by_pid(pid); - if (tsk) - mm = tsk->mm; - if (mm) - atomic_inc(&mm->mm_users); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ - if (!tsk) - return 0; - state = *get_task_state(tsk); + state = *get_task_state(task); vsize = eip = esp = 0; if (mm) { struct vm_area_struct *vma; @@ -710,55 +302,55 @@ vsize += vma->vm_end - vma->vm_start; vma = vma->vm_next; } - eip = KSTK_EIP(tsk); - esp = KSTK_ESP(tsk); + eip = KSTK_EIP(task); + esp = KSTK_ESP(task); up(&mm->mmap_sem); } - wchan = get_wchan(tsk); + wchan = get_wchan(task); - collect_sigign_sigcatch(tsk, &sigign, &sigcatch); + collect_sigign_sigcatch(task, &sigign, &sigcatch); - if (tsk->tty) - tty_pgrp = tsk->tty->pgrp; + if (task->tty) + tty_pgrp = task->tty->pgrp; else tty_pgrp = -1; /* scale priority and nice values from timeslices to -20..20 */ /* to make it look like a "normal" Unix priority/nice value */ - priority = tsk->counter; + priority = task->counter; priority = 20 - (priority * 10 + DEF_PRIORITY / 2) / DEF_PRIORITY; - nice = tsk->priority; + nice = task->priority; nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY; res = sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu %lu %lu %d %d\n", - pid, - tsk->comm, + task->pid, + task->comm, state, - tsk->p_pptr->pid, - tsk->pgrp, - tsk->session, - tsk->tty ? kdev_t_to_nr(tsk->tty->device) : 0, + task->p_pptr->pid, + task->pgrp, + task->session, + task->tty ? kdev_t_to_nr(task->tty->device) : 0, tty_pgrp, - tsk->flags, - tsk->min_flt, - tsk->cmin_flt, - tsk->maj_flt, - tsk->cmaj_flt, - tsk->times.tms_utime, - tsk->times.tms_stime, - tsk->times.tms_cutime, - tsk->times.tms_cstime, + task->flags, + task->min_flt, + task->cmin_flt, + task->maj_flt, + task->cmaj_flt, + task->times.tms_utime, + task->times.tms_stime, + task->times.tms_cutime, + task->times.tms_cstime, priority, nice, 0UL /* removed */, - tsk->it_real_value, - tsk->start_time, + task->it_real_value, + task->start_time, vsize, mm ? mm->rss : 0, /* you might want to shift this left 3 */ - tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0, + task->rlim ? task->rlim[RLIMIT_RSS].rlim_cur : 0, mm ? mm->start_code : 0, mm ? mm->end_code : 0, mm ? mm->start_stack : 0, @@ -768,17 +360,15 @@ * It must be decimal for Linux 2.0 compatibility. * Use /proc/#/status for real-time signals. */ - tsk->signal .sig[0] & 0x7fffffffUL, - tsk->blocked.sig[0] & 0x7fffffffUL, + task->signal .sig[0] & 0x7fffffffUL, + task->blocked.sig[0] & 0x7fffffffUL, sigign .sig[0] & 0x7fffffffUL, sigcatch .sig[0] & 0x7fffffffUL, wchan, - tsk->nswap, - tsk->cnswap, - tsk->exit_signal, - tsk->processor); - if (mm) - mmput(mm); + task->nswap, + task->cnswap, + task->exit_signal, + task->processor); return res; } @@ -813,9 +403,9 @@ ++*pages; if (pte_dirty(page)) ++*dirty; - if (MAP_NR(pte_page(page)) >= max_mapnr) + if (pte_pagenr(page) >= max_mapnr) continue; - if (page_count(mem_map + MAP_NR(pte_page(page))) > 1) + if (page_count(pte_page(page)) > 1) ++*shared; } while (address < end); } @@ -855,9 +445,9 @@ } } -static int get_statm(int pid, char * buffer) +int proc_pid_statm(struct task_struct *task, char * buffer) { - struct mm_struct *mm = get_mm(pid); + struct mm_struct *mm = task->mm; int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0; if (mm) { @@ -884,7 +474,6 @@ vma = vma->vm_next; } up(&mm->mmap_sem); - mmput(mm); } return sprintf(buffer,"%d %d %d %d %d %d %d\n", size, resident, share, trs, lrs, drs, dt); @@ -923,10 +512,10 @@ #define MAPS_LINE_MAX MAPS_LINE_MAX8 -static ssize_t read_maps (int pid, struct file * file, char * buf, +ssize_t proc_pid_read_maps (struct task_struct *task, struct file * file, char * buf, size_t count, loff_t *ppos) { - struct task_struct *p; + struct mm_struct *mm = task->mm; struct vm_area_struct * map, * next; char * destptr = buf, * buffer; loff_t lineno; @@ -942,25 +531,19 @@ if (!buffer) goto out; - retval = -EINVAL; - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ - if (!p) - goto freepage_out; - - if (!p->mm || count == 0) + if (!mm || count == 0) goto getlen_out; /* Check whether the mmaps could change if we sleep */ - volatile_task = (p != current || atomic_read(&p->mm->mm_users) > 1); + volatile_task = (task != current || atomic_read(&mm->mm_users) > 1); /* decode f_pos */ lineno = *ppos >> MAPS_LINE_SHIFT; column = *ppos & (MAPS_LINE_LENGTH-1); /* quickly go to line lineno */ - for (map = p->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) + down(&mm->mmap_sem); + for (map = mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++) continue; for ( ; map ; map = next ) { @@ -1019,7 +602,9 @@ i = len-column; if (i > count) i = count; + up(&mm->mmap_sem); copy_to_user(destptr, line+column, i); /* may have slept */ + down(&mm->mmap_sem); destptr += i; count -= i; column += i; @@ -1038,246 +623,34 @@ if (volatile_task) break; } + up(&mm->mmap_sem); /* encode f_pos */ *ppos = (lineno << MAPS_LINE_SHIFT) + column; getlen_out: retval = destptr - buf; - -freepage_out: free_page((unsigned long)buffer); out: return retval; } #ifdef __SMP__ -static int get_pidcpu(int pid, char * buffer) +int proc_pid_cpu(struct task_struct *task, char * buffer) { - struct task_struct * tsk = current ; int i, len; - read_lock(&tasklist_lock); - if (pid != tsk->pid) - tsk = find_task_by_pid(pid); - read_unlock(&tasklist_lock); /* FIXME!! This should be done after the last use */ - - if (tsk == NULL) - return 0; - len = sprintf(buffer, "cpu %lu %lu\n", - tsk->times.tms_utime, - tsk->times.tms_stime); + task->times.tms_utime, + task->times.tms_stime); for (i = 0 ; i < smp_num_cpus; i++) len += sprintf(buffer + len, "cpu%d %lu %lu\n", i, - tsk->per_cpu_utime[cpu_logical_map(i)], - tsk->per_cpu_stime[cpu_logical_map(i)]); + task->per_cpu_utime[cpu_logical_map(i)], + task->per_cpu_stime[cpu_logical_map(i)]); return len; } #endif - -static int process_unauthorized(int type, int pid) -{ - struct task_struct *p; - uid_t euid=0; /* Save the euid keep the lock short */ - int ok = 0; - - read_lock(&tasklist_lock); - - /* - * Grab the lock, find the task, save the uid and - * check it has an mm still (ie its not dead) - */ - - p = find_task_by_pid(pid); - if (p) { - euid=p->euid; - ok = p->dumpable; - if(!cap_issubset(p->cap_permitted, current->cap_permitted)) - ok=0; - } - - read_unlock(&tasklist_lock); - - if (!p) - return 1; - - switch(type) { - case PROC_PID_STATUS: - case PROC_PID_STATM: - case PROC_PID_STAT: - case PROC_PID_MAPS: - case PROC_PID_CMDLINE: - case PROC_PID_CPU: - return 0; - } - if(capable(CAP_DAC_OVERRIDE) || (current->fsuid == euid && ok)) - return 0; - return 1; -} - - -static inline int get_process_array(char * page, int pid, int type) -{ - switch (type) { - case PROC_PID_STATUS: - return get_status(pid, page); - case PROC_PID_ENVIRON: - return get_env(pid, page); - case PROC_PID_CMDLINE: - return get_arg(pid, page); - case PROC_PID_STAT: - return get_stat(pid, page); - case PROC_PID_STATM: - return get_statm(pid, page); -#ifdef __SMP__ - case PROC_PID_CPU: - return get_pidcpu(pid, page); -#endif - } - return -EBADF; -} - -#define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */ - -static ssize_t array_read(struct file * file, char * buf, - size_t count, loff_t *ppos) -{ - struct inode * inode = file->f_dentry->d_inode; - unsigned long page; - char *start; - ssize_t length; - ssize_t end; - unsigned int type, pid; - struct proc_dir_entry *dp; - - if (count > PROC_BLOCK_SIZE) - count = PROC_BLOCK_SIZE; - if (!(page = __get_free_page(GFP_KERNEL))) - return -ENOMEM; - type = inode->i_ino; - pid = type >> 16; - type &= 0x0000ffff; - start = NULL; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - - if (!pid) { /* can't happen */ - free_page(page); - return -EBADF; - } - - if (process_unauthorized(type, pid)) { - free_page(page); - return -EIO; - } - - length = get_process_array((char *) page, pid, type); - if (length < 0) { - free_page(page); - return length; - } - /* Static 4kB (or whatever) block capacity */ - if (*ppos >= length) { - free_page(page); - return 0; - } - if (count + *ppos > length) - count = length - *ppos; - end = count + *ppos; - copy_to_user(buf, (char *) page + *ppos, count); - *ppos = end; - free_page(page); - return count; -} - -static struct file_operations proc_array_operations = { - NULL, /* array_lseek */ - array_read, - NULL, /* array_write */ - NULL, /* array_readdir */ - NULL, /* array_poll */ - NULL, /* array_ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -struct inode_operations proc_array_inode_operations = { - &proc_array_operations, /* default base directory file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; - -static ssize_t arraylong_read(struct file * file, char * buf, - size_t count, loff_t *ppos) -{ - struct inode * inode = file->f_dentry->d_inode; - unsigned int pid = inode->i_ino >> 16; - unsigned int type = inode->i_ino & 0x0000ffff; - - switch (type) { - case PROC_PID_MAPS: - return read_maps(pid, file, buf, count, ppos); - } - return -EINVAL; -} - -static struct file_operations proc_arraylong_operations = { - NULL, /* array_lseek */ - arraylong_read, - NULL, /* array_write */ - NULL, /* array_readdir */ - NULL, /* array_poll */ - NULL, /* array_ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -struct inode_operations proc_arraylong_inode_operations = { - &proc_arraylong_operations, /* default base directory file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; diff -u --recursive --new-file v2.3.26/linux/fs/proc/base.c linux/fs/proc/base.c --- v2.3.26/linux/fs/proc/base.c Tue Aug 31 17:29:14 1999 +++ linux/fs/proc/base.c Mon Nov 8 14:28:34 1999 @@ -4,6 +4,13 @@ * Copyright (C) 1991, 1992 Linus Torvalds * * proc base directory handling functions + * + * 1999, Al Viro. Rewritten. Now it covers the whole per-process part. + * Instead of using magical inumbers to determine the kind of object + * we allocate and fill in-core inodes upon lookup. They don't even + * go into icache. We cache the reference to task_struct upon lookup too. + * Eventually it should become a filesystem in its own. We don't use the + * rest of procfs anymore. */ #include @@ -14,28 +21,336 @@ #include #include #include - -static struct file_operations proc_base_operations = { - NULL, /* lseek - default */ - NULL, /* read - bad */ - NULL, /* write - bad */ - proc_readdir, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; +#include /* - * proc directories can do almost nothing.. + * For hysterical raisins we keep the same inumbers as in the old procfs. + * Feel free to change the macro below - just keep the range distinct from + * inumbers of the rest of procfs (currently those are in 0x0000--0xffff). + * As soon as we'll get a separate superblock we will be able to forget + * about magical ranges too. */ -static struct inode_operations proc_base_inode_operations = { - &proc_base_operations, /* default base directory file-ops */ + +#define fake_ino(pid,ino) (((pid)<<16)|(ino)) + +ssize_t proc_pid_read_maps(struct task_struct*,struct file*,char*,size_t,loff_t*); +int proc_pid_stat(struct task_struct*,char*); +int proc_pid_status(struct task_struct*,char*); +int proc_pid_statm(struct task_struct*,char*); +int proc_pid_cpu(struct task_struct*,char*); + +static struct dentry *proc_fd_link(struct inode *inode) +{ + if (inode->u.proc_i.file) + return dget(inode->u.proc_i.file->f_dentry); + return NULL; +} + +static struct dentry *proc_exe_link(struct inode *inode) +{ + struct mm_struct * mm; + struct vm_area_struct * vma; + struct dentry *result = NULL; + struct task_struct *task = inode->u.proc_i.task; + + if (!task_lock(task)) + return NULL; + mm = task->mm; + if (!mm) + goto out; + down(&mm->mmap_sem); + vma = mm->mmap; + while (vma) { + if ((vma->vm_flags & VM_EXECUTABLE) && + vma->vm_file) { + result = dget(vma->vm_file->f_dentry); + break; + } + vma = vma->vm_next; + } + up(&mm->mmap_sem); +out: + task_unlock(task); + return result; +} + +static struct dentry *proc_cwd_link(struct inode *inode) +{ + struct dentry *result = NULL; + if (task_lock(inode->u.proc_i.task)) { + struct fs_struct *fs = inode->u.proc_i.task->fs; + if (fs) + result = dget(fs->pwd); + task_unlock(inode->u.proc_i.task); + } + return result; +} + +static struct dentry *proc_root_link(struct inode *inode) +{ + struct dentry *result = NULL; + if (task_lock(inode->u.proc_i.task)) { + struct fs_struct *fs = inode->u.proc_i.task->fs; + if (fs) + result = dget(fs->root); + task_unlock(inode->u.proc_i.task); + } + return result; +} + +/* task is locked and can't drop mm, so we are safe */ + +static int proc_pid_environ(struct task_struct *task, char * buffer) +{ + struct mm_struct *mm = task->mm; + int res = 0; + if (mm) + res = access_process_vm(task, mm->env_start, buffer, + mm->env_end - mm->env_start, 0); + return res; +} + +/* task is locked and can't drop mm, so we are safe */ + +static int proc_pid_cmdline(struct task_struct *task, char * buffer) +{ + struct mm_struct *mm = task->mm; + int res = 0; + if (mm) + res = access_process_vm(task, mm->arg_start, buffer, + mm->arg_end - mm->arg_start, 0); + return res; +} + +/************************************************************************/ +/* Here the fs part begins */ +/************************************************************************/ + +/* permission checks */ + +static int standard_permission(struct inode *inode, int mask) +{ + int mode = inode->i_mode; + + if ((mask & S_IWOTH) && IS_RDONLY(inode) && + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) + return -EROFS; /* Nobody gets write access to a read-only fs */ + else if ((mask & S_IWOTH) && IS_IMMUTABLE(inode)) + return -EACCES; /* Nobody gets write access to an immutable file */ + else if (current->fsuid == inode->i_uid) + mode >>= 6; + else if (in_group_p(inode->i_gid)) + mode >>= 3; + if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE)) + return 0; + /* read and search access */ + if ((mask == S_IROTH) || + (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH)))) + if (capable(CAP_DAC_READ_SEARCH)) + return 0; + return -EACCES; +} + +static int proc_permission(struct inode *inode, int mask) +{ + struct dentry *de, *base, *root; + struct super_block *our_sb, *sb, *below; + + if (standard_permission(inode, mask) != 0) + return -EACCES; + + base = current->fs->root; + de = root = proc_root_link(inode); /* Ewww... */ + + if (!de) + return -ENOENT; + + our_sb = base->d_inode->i_sb; + sb = de->d_inode->i_sb; + while (sb != our_sb) { + de = sb->s_root->d_covers; + below = de->d_inode->i_sb; + if (sb == below) + goto out; + sb = below; + } + + if (!is_subdir(de, base)) + goto out; + + dput(root); + return 0; +out: + dput(root); + return -EACCES; +} + +static ssize_t pid_maps_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + struct inode * inode = file->f_dentry->d_inode; + struct task_struct *task = inode->u.proc_i.task; + ssize_t res; + + if (!task_lock(task)) + return -EIO; + res = proc_pid_read_maps(task, file, buf, count, ppos); + task_unlock(task); + return res; +} + +static struct file_operations proc_maps_operations = { + NULL, /* array_lseek */ + pid_maps_read, +}; + +struct inode_operations proc_maps_inode_operations = { + &proc_maps_operations, /* default base directory file-ops */ +}; + +#define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */ + +static ssize_t proc_info_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + struct inode * inode = file->f_dentry->d_inode; + unsigned long page; + ssize_t length; + ssize_t end; + struct task_struct *task = inode->u.proc_i.task; + + if (count > PROC_BLOCK_SIZE) + count = PROC_BLOCK_SIZE; + if (!(page = __get_free_page(GFP_KERNEL))) + return -ENOMEM; + + if (!task_lock(task)) { + free_page(page); + return -EIO; + } + + length = inode->u.proc_i.op.proc_read(task, (char*)page); + + task_unlock(task); + + if (length < 0) { + free_page(page); + return length; + } + /* Static 4kB (or whatever) block capacity */ + if (*ppos >= length) { + free_page(page); + return 0; + } + if (count + *ppos > length) + count = length - *ppos; + end = count + *ppos; + copy_to_user(buf, (char *) page + *ppos, count); + *ppos = end; + free_page(page); + return count; +} + +static struct file_operations proc_info_file_operations = { + NULL, /* lseek */ + proc_info_read, /* read */ +}; + +static struct inode_operations proc_info_inode_operations = { + &proc_info_file_operations, /* default proc file-ops */ +}; + +#define MAY_PTRACE(p) \ +(p==current||(p->p_pptr==current&&(p->flags&PF_PTRACED)&&p->state==TASK_STOPPED)) + +static ssize_t mem_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task; + char *page; + unsigned long src = *ppos; + int copied = 0; + + if (!MAY_PTRACE(task)) + return -ESRCH; + + page = (char *)__get_free_page(GFP_USER); + if (!page) + return -ENOMEM; + + while (count > 0) { + int this_len, retval; + + this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; + retval = access_process_vm(task, src, page, this_len, 0); + if (!retval) { + if (!copied) + copied = -EIO; + break; + } + if (copy_to_user(buf, page, retval)) { + copied = -EFAULT; + break; + } + copied += retval; + src += retval; + buf += retval; + count -= retval; + } + *ppos = src; + free_page((unsigned long) page); + return copied; +} + +static ssize_t mem_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + int copied = 0; + char *page; + struct task_struct *task = file->f_dentry->d_inode->u.proc_i.task; + unsigned long dst = *ppos; + + if (!MAY_PTRACE(task)) + return -ESRCH; + + page = (char *)__get_free_page(GFP_USER); + if (!page) + return -ENOMEM; + + while (count > 0) { + int this_len, retval; + + this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; + if (copy_from_user(page, buf, this_len)) { + copied = -EFAULT; + break; + } + retval = access_process_vm(task, dst, page, this_len, 1); + if (!retval) { + if (!copied) + copied = -EIO; + break; + } + copied += retval; + buf += retval; + dst += retval; + count -= retval; + } + *ppos = dst; + free_page((unsigned long) page); + return copied; +} + +static struct file_operations proc_mem_operations = { + NULL, /* lseek - default */ + mem_read, + mem_write, +}; + +static struct inode_operations proc_mem_inode_operations = { + &proc_mem_operations, /* default base directory file-ops */ NULL, /* create */ - proc_lookup, /* lookup */ + NULL, /* lookup */ NULL, /* link */ NULL, /* unlink */ NULL, /* symlink */ @@ -50,161 +365,653 @@ NULL, /* writepage */ NULL, /* flushpage */ NULL, /* truncate */ - NULL, /* permission */ + proc_permission, /* permission */ NULL, /* smap */ NULL /* revalidate */ }; -/* - * The fill argument is non-zero when the inode is being filled ... - * we don't need to do anything when it's being deleted. - */ -static void proc_pid_fill_inode(struct inode * inode, int fill) +static struct dentry * proc_pid_follow_link(struct dentry *dentry, + struct dentry *base, + unsigned int follow) { - struct task_struct *p; - int pid = inode->i_ino >> 16; - int ino = inode->i_ino & 0xffff; + struct inode *inode = dentry->d_inode; + struct dentry * result; + int error; + + /* We don't need a base pointer in the /proc filesystem */ + dput(base); + + error = proc_permission(inode, MAY_EXEC); + result = ERR_PTR(error); + if (error) + goto out; + + result = inode->u.proc_i.op.proc_get_link(inode); +out: + if (!result) + result = ERR_PTR(-ENOENT); + return result; +} - read_lock(&tasklist_lock); - if (fill && (p = find_task_by_pid(pid)) != NULL) { - uid_t uid = 0; - gid_t gid = 0; - if (p->dumpable || ino == PROC_PID_INO) { - uid = p->euid; - gid = p->egid; - } - inode->i_uid = uid; - inode->i_gid = gid; +static int do_proc_readlink(struct dentry *dentry, char * buffer, int buflen) +{ + struct inode * inode; + char * tmp = (char*)__get_free_page(GFP_KERNEL), *path, *pattern; + int len; + + if (!tmp) + return -ENOMEM; + + /* Check for special dentries.. */ + pattern = NULL; + inode = dentry->d_inode; + if (inode && IS_ROOT(dentry)) { + if (S_ISSOCK(inode->i_mode)) + pattern = "socket:[%lu]"; + if (S_ISFIFO(inode->i_mode)) + pattern = "pipe:[%lu]"; } - read_unlock(&tasklist_lock); + + if (pattern) { + len = sprintf(tmp, pattern, inode->i_ino); + path = tmp; + } else { + path = d_path(dentry, tmp, PAGE_SIZE); + len = tmp + PAGE_SIZE - 1 - path; + } + + if (len < buflen) + buflen = len; + copy_to_user(buffer, path, buflen); + free_page((unsigned long)tmp); + return buflen; } -/* - * This is really a pseudo-entry, and only links - * backwards to the parent with no link from the - * root directory to this. This way we can have just - * one entry for every /proc// directory. - */ -struct proc_dir_entry proc_pid = { - PROC_PID_INO, 5, "", - S_IFDIR | S_IRUGO | S_IXUGO, 2, 0, 0, - 0, &proc_base_inode_operations, - NULL, proc_pid_fill_inode, - NULL, &proc_root, NULL -}; - -static struct proc_dir_entry proc_pid_status = { - PROC_PID_STATUS, 6, "status", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_mem = { - PROC_PID_MEM, 3, "mem", - S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0, - 0, &proc_mem_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_cwd = { - PROC_PID_CWD, 3, "cwd", - S_IFLNK | S_IRWXU, 1, 0, 0, - 0, &proc_link_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_root = { - PROC_PID_ROOT, 4, "root", - S_IFLNK | S_IRWXU, 1, 0, 0, - 0, &proc_link_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_exe = { - PROC_PID_EXE, 3, "exe", - S_IFLNK | S_IRWXU, 1, 0, 0, - 0, &proc_link_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_fd = { - PROC_PID_FD, 2, "fd", - S_IFDIR | S_IRUSR | S_IXUSR, 2, 0, 0, - 0, &proc_fd_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_environ = { - PROC_PID_ENVIRON, 7, "environ", - S_IFREG | S_IRUSR, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_cmdline = { - PROC_PID_CMDLINE, 7, "cmdline", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_stat = { - PROC_PID_STAT, 4, "stat", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_statm = { - PROC_PID_STATM, 5, "statm", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, -}; -static struct proc_dir_entry proc_pid_maps = { - PROC_PID_MAPS, 4, "maps", - S_IFIFO | S_IRUGO, 1, 0, 0, - 0, &proc_arraylong_inode_operations, - NULL, proc_pid_fill_inode, +static int proc_pid_readlink(struct dentry * dentry, char * buffer, int buflen) +{ + int error; + struct inode *inode = dentry->d_inode; + + error = proc_permission(inode, MAY_EXEC); + if (error) + goto out; + + dentry = inode->u.proc_i.op.proc_get_link(inode); + error = -ENOENT; + if (!dentry) + goto out; + + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto out; + + error = do_proc_readlink(dentry, buffer, buflen); + dput(dentry); +out: + return error; +} + +static struct inode_operations proc_pid_link_inode_operations = { + NULL, /* file-operations */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + proc_pid_readlink, /* readlink */ + proc_pid_follow_link, /* follow_link */ }; +/* reading from directory - bad */ + +static ssize_t proc_dir_read (struct file * filp, char * buf, + size_t count, loff_t *ppos) +{ + return -EISDIR; +} + +struct pid_entry { + int type; + int len; + char *name; + mode_t mode; +}; + +enum pid_directory_inos { + PROC_PID_INO = 2, + PROC_PID_STATUS, + PROC_PID_MEM, + PROC_PID_CWD, + PROC_PID_ROOT, + PROC_PID_EXE, + PROC_PID_FD, + PROC_PID_ENVIRON, + PROC_PID_CMDLINE, + PROC_PID_STAT, + PROC_PID_STATM, + PROC_PID_MAPS, #if CONFIG_AP1000 -static struct proc_dir_entry proc_pid_ringbuf = { - PROC_PID_RINGBUF, 7, "ringbuf", - S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0, - 0, &proc_ringbuf_inode_operations, - NULL, proc_pid_fill_inode, + PROC_PID_RINGBUF, +#endif + PROC_PID_CPU, + PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ }; + +#define E(type,name,mode) {(type),sizeof(name)-1,(name),(mode)} +static struct pid_entry base_stuff[] = { + E(PROC_PID_FD, "fd", S_IFDIR|S_IRUSR|S_IXUSR), + E(PROC_PID_ENVIRON, "environ", S_IFREG|S_IRUSR), + E(PROC_PID_STATUS, "status", S_IFREG|S_IRUGO), + E(PROC_PID_CMDLINE, "cmdline", S_IFREG|S_IRUGO), + E(PROC_PID_STAT, "stat", S_IFREG|S_IRUGO), + E(PROC_PID_STATM, "statm", S_IFREG|S_IRUGO), +#ifdef SMP + E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUGO), +#endif +#if CONFIG_AP1000 + E(PROC_PID_RINGBUF, "ringbuf", S_IFREG|S_IRUGO|S_IWUSR), #endif + E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUGO), + E(PROC_PID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR), + E(PROC_PID_CWD, "cwd", S_IFLNK|S_IRWXUGO), + E(PROC_PID_ROOT, "root", S_IFLNK|S_IRWXUGO), + E(PROC_PID_EXE, "exe", S_IFLNK|S_IRWXUGO), + {0,0,NULL,0} +}; +#undef E + +#define NUMBUF 10 + +static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) +{ + struct inode *inode = filp->f_dentry->d_inode; + struct task_struct *p = inode->u.proc_i.task; + unsigned int fd, pid, ino; + int retval; + char buf[NUMBUF]; + + retval = 0; + pid = p->pid; + + fd = filp->f_pos; + switch (fd) { + case 0: + if (filldir(dirent, ".", 1, 0, inode->i_ino) < 0) + goto out; + filp->f_pos++; + case 1: + ino = fake_ino(pid, PROC_PID_INO); + if (filldir(dirent, "..", 2, 1, ino) < 0) + goto out; + filp->f_pos++; + default: + for (fd = filp->f_pos-2; + p->p_pptr && p->files && fd < p->files->max_fds; + fd++, filp->f_pos++) { + unsigned int i,j; + + if (!fcheck_task(p, fd)) + continue; + + j = NUMBUF; + i = fd; + do { + j--; + buf[j] = '0' + (i % 10); + i /= 10; + } while (i); + + ino = fake_ino(pid, PROC_PID_FD_DIR + fd); + if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0) + break; + + } + } +out: + return retval; +} + +static int proc_base_readdir(struct file * filp, + void * dirent, filldir_t filldir) +{ + int i; + int pid; + struct inode *inode = filp->f_dentry->d_inode; + struct pid_entry *p; + + pid = inode->u.proc_i.task->pid; + if (!inode->u.proc_i.task->p_pptr) + return -ENOENT; + i = filp->f_pos; + switch (i) { + case 0: + if (filldir(dirent, ".", 1, i, inode->i_ino) < 0) + return 0; + i++; + filp->f_pos++; + /* fall through */ + case 1: + if (filldir(dirent, "..", 2, i, PROC_ROOT_INO) < 0) + return 0; + i++; + filp->f_pos++; + /* fall through */ + default: + i -= 2; + if (i>=sizeof(base_stuff)/sizeof(base_stuff[0])) + return 1; + p = base_stuff + i; + while (p->name) { + if (filldir(dirent, p->name, p->len, filp->f_pos, fake_ino(pid, p->type)) < 0) + return 0; + filp->f_pos++; + p++; + } + } + return 1; +} + +/* building an inode */ + +static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task, int ino) +{ + struct inode * inode; + + /* We need a new inode */ + + inode = get_empty_inode(); + if (!inode) + goto out; + + /* Common stuff */ + + inode->i_sb = sb; + inode->i_dev = sb->s_dev; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_ino = fake_ino(task->pid, ino); + + inode->u.proc_i.file = NULL; + /* + * grab the reference to task. + */ + inode->u.proc_i.task = task; + atomic_inc(&mem_map[MAP_NR(task)].count); + if (!task->p_pptr) + goto out_unlock; + + inode->i_uid = 0; + inode->i_gid = 0; + if (ino == PROC_PID_INO || task->dumpable) { + inode->i_uid = task->euid; + inode->i_gid = task->egid; + } + +out: + return inode; + +out_unlock: + iput(inode); + return NULL; +} -#ifdef __SMP__ -static struct proc_dir_entry proc_pid_cpu = { - PROC_PID_CPU, 3, "cpu", - S_IFREG | S_IRUGO, 1, 0, 0, - 0, &proc_array_inode_operations, - NULL, proc_pid_fill_inode, +/* dentry stuff */ + +static int pid_fd_revalidate(struct dentry * dentry, int flags) +{ + return 0; +} + +static int pid_base_revalidate(struct dentry * dentry, int flags) +{ + if (dentry->d_inode->u.proc_i.task->p_pptr) + return 1; + d_drop(dentry); + return 0; +} + +static void pid_delete_dentry(struct dentry * dentry) +{ + d_drop(dentry); +} + +static struct dentry_operations pid_fd_dentry_operations = +{ + pid_fd_revalidate, /* revalidate */ + NULL, /* d_hash */ + NULL, /* d_compare */ + pid_delete_dentry /* d_delete(struct dentry *) */ +}; + +static struct dentry_operations pid_dentry_operations = +{ + NULL, /* revalidate */ + NULL, /* d_hash */ + NULL, /* d_compare */ + pid_delete_dentry /* d_delete(struct dentry *) */ +}; + +static struct dentry_operations pid_base_dentry_operations = +{ + pid_base_revalidate, /* revalidate */ + NULL, /* d_hash */ + NULL, /* d_compare */ + pid_delete_dentry /* d_delete(struct dentry *) */ +}; + +/* Lookups */ + +static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) +{ + unsigned int fd, c; + struct task_struct *task = dir->u.proc_i.task; + struct file * file; + struct files_struct * files; + struct inode *inode; + const char *name; + int len; + + fd = 0; + len = dentry->d_name.len; + name = dentry->d_name.name; + if (len > 1 && *name == '0') goto out; + while (len-- > 0) { + c = *name - '0'; + name++; + if (c > 9) + goto out; + fd *= 10; + fd += c; + if (fd & 0xffff8000) + goto out; + } + + inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_FD_DIR+fd); + if (!inode) + goto out; + /* FIXME */ + files = task->files; + if (!files) /* can we ever get here if that's the case? */ + goto out_unlock; + read_lock(&files->file_lock); + file = inode->u.proc_i.file = fcheck_task(task, fd); + if (!file) + goto out_unlock2; + get_file(file); + read_unlock(&files->file_lock); + inode->i_op = &proc_pid_link_inode_operations; + inode->i_size = 64; + inode->i_mode = S_IFLNK; + inode->u.proc_i.op.proc_get_link = proc_fd_link; + if (file->f_mode & 1) + inode->i_mode |= S_IRUSR | S_IXUSR; + if (file->f_mode & 2) + inode->i_mode |= S_IWUSR | S_IXUSR; + dentry->d_op = &pid_fd_dentry_operations; + d_add(dentry, inode); + return NULL; + +out_unlock2: + read_unlock(&files->file_lock); +out_unlock: + iput(inode); +out: + return ERR_PTR(-ENOENT); +} + +static struct file_operations proc_fd_operations = { + NULL, /* lseek - default */ + proc_dir_read, /* read - bad */ + NULL, /* write - bad */ + proc_readfd, /* readdir */ }; -#endif -void __init proc_base_init(void) +/* + * proc directories can do almost nothing.. + */ +static struct inode_operations proc_fd_inode_operations = { + &proc_fd_operations, /* default base directory file-ops */ + NULL, /* create */ + proc_lookupfd, /* 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 */ + NULL, /* flushpage */ + NULL, /* truncate */ + proc_permission, /* permission */ +}; + +static struct dentry *proc_base_lookup(struct inode *dir, struct dentry *dentry) { + struct inode *inode; + int error; + struct task_struct *task = dir->u.proc_i.task; + struct pid_entry *p; + + error = -ENOENT; + inode = NULL; + + for (p = base_stuff; p->name; p++) { + if (p->len != dentry->d_name.len) + continue; + if (!memcmp(dentry->d_name.name, p->name, p->len)) + break; + } + if (!p->name) + goto out; + + error = -EINVAL; + inode = proc_pid_make_inode(dir->i_sb, task, p->type); + if (!inode) + goto out; + + inode->i_mode = p->mode; + /* + * Yes, it does not scale. And it should not. Don't add + * new entries into /proc// without very good reasons. + */ + switch(p->type) { + case PROC_PID_FD: + inode->i_nlink = 2; + inode->i_op = &proc_fd_inode_operations; + break; + case PROC_PID_EXE: + inode->i_op = &proc_pid_link_inode_operations; + inode->u.proc_i.op.proc_get_link = proc_exe_link; + break; + case PROC_PID_CWD: + inode->i_op = &proc_pid_link_inode_operations; + inode->u.proc_i.op.proc_get_link = proc_cwd_link; + break; + case PROC_PID_ROOT: + inode->i_op = &proc_pid_link_inode_operations; + inode->u.proc_i.op.proc_get_link = proc_root_link; + break; + case PROC_PID_ENVIRON: + inode->i_op = &proc_info_inode_operations; + inode->u.proc_i.op.proc_read = proc_pid_environ; + break; + case PROC_PID_STATUS: + inode->i_op = &proc_info_inode_operations; + inode->u.proc_i.op.proc_read = proc_pid_status; + break; + case PROC_PID_STAT: + inode->i_op = &proc_info_inode_operations; + inode->u.proc_i.op.proc_read = proc_pid_stat; + break; + case PROC_PID_CMDLINE: + inode->i_op = &proc_info_inode_operations; + inode->u.proc_i.op.proc_read = proc_pid_cmdline; + break; + case PROC_PID_STATM: + inode->i_op = &proc_info_inode_operations; + inode->u.proc_i.op.proc_read = proc_pid_statm; + break; + case PROC_PID_MAPS: + inode->i_op = &proc_maps_inode_operations; + break; +#ifdef SMP + case PROC_PID_CPU: + inode->i_op = &proc_info_inode_operations; + inode->u.proc_i.op.proc_read = proc_pid_cpu; + break; +#endif #if CONFIG_AP1000 - proc_register(&proc_pid, &proc_pid_ringbuf); + case PROC_PID_RINGBUF: + inode->i_op = &proc_ringbuf_inode_operations; + break; #endif - proc_register(&proc_pid, &proc_pid_status); - proc_register(&proc_pid, &proc_pid_mem); - proc_register(&proc_pid, &proc_pid_cwd); - proc_register(&proc_pid, &proc_pid_root); - proc_register(&proc_pid, &proc_pid_exe); - proc_register(&proc_pid, &proc_pid_fd); - proc_register(&proc_pid, &proc_pid_environ); - proc_register(&proc_pid, &proc_pid_cmdline); - proc_register(&proc_pid, &proc_pid_stat); - proc_register(&proc_pid, &proc_pid_statm); - proc_register(&proc_pid, &proc_pid_maps); -#ifdef __SMP__ - proc_register(&proc_pid, &proc_pid_cpu); -#endif + case PROC_PID_MEM: + inode->i_op = &proc_mem_inode_operations; + break; + default: + printk("procfs: impossible type (%d)",p->type); + iput(inode); + return ERR_PTR(-EINVAL); + } + dentry->d_op = &pid_dentry_operations; + d_add(dentry, inode); + return NULL; + +out: + return ERR_PTR(error); +} + +static struct file_operations proc_base_operations = { + NULL, /* lseek - default */ + proc_dir_read, /* read - bad */ + NULL, /* write - bad */ + proc_base_readdir, /* readdir */ }; +static struct inode_operations proc_base_inode_operations = { + &proc_base_operations, /* default base directory file-ops */ + NULL, /* create */ + proc_base_lookup, /* lookup */ +}; +struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry) +{ + unsigned int pid, c; + struct task_struct *task; + const char *name; + struct inode *inode; + int len; + + pid = 0; + name = dentry->d_name.name; + len = dentry->d_name.len; + while (len-- > 0) { + c = *name - '0'; + name++; + if (c > 9) + goto out; + pid *= 10; + pid += c; + if (!pid) + goto out; + if (pid & 0xffff0000) + goto out; + } + read_lock(&tasklist_lock); + task = find_task_by_pid(pid); + if (task) + atomic_inc(&mem_map[MAP_NR(task)].count); + read_unlock(&tasklist_lock); + if (!task) + goto out; + inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO); + free_task_struct(task); + if (!inode) + goto out; + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; + inode->i_op = &proc_base_inode_operations; + inode->i_nlink = 3; + inode->i_flags|=S_IMMUTABLE; + + dentry->d_op = &pid_base_dentry_operations; + d_add(dentry, inode); + return NULL; +out: + return ERR_PTR(-ENOENT); +} +void proc_pid_delete_inode(struct inode *inode) +{ + if (inode->u.proc_i.file) + fput(inode->u.proc_i.file); + free_task_struct(inode->u.proc_i.task); +} +#define PROC_NUMBUF 10 +#define PROC_MAXPIDS 20 +/* + * Get a few pid's to return for filldir - we need to hold the + * tasklist lock while doing this, and we must release it before + * we actually do the filldir itself, so we use a temp buffer.. + */ +static int get_pid_list(int index, unsigned int *pids) +{ + struct task_struct *p; + int nr_pids = 0; + index -= FIRST_PROCESS_ENTRY; + read_lock(&tasklist_lock); + for_each_task(p) { + int pid = p->pid; + if (!pid) + continue; + if (--index >= 0) + continue; + pids[nr_pids] = pid; + nr_pids++; + if (nr_pids >= PROC_MAXPIDS) + break; + } + read_unlock(&tasklist_lock); + return nr_pids; +} + +int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) +{ + unsigned int pid_array[PROC_MAXPIDS]; + char buf[PROC_NUMBUF]; + unsigned int nr = filp->f_pos; + unsigned int nr_pids, i; + + nr_pids = get_pid_list(nr, pid_array); + + for (i = 0; i < nr_pids; i++) { + int pid = pid_array[i]; + ino_t ino = fake_ino(pid,PROC_PID_INO); + unsigned long j = PROC_NUMBUF; + + do { + j--; + buf[j] = '0' + (pid % 10); + pid /= 10; + } while (pid); + + if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino) < 0) + break; + filp->f_pos++; + } + return 0; +} diff -u --recursive --new-file v2.3.26/linux/fs/proc/fd.c linux/fs/proc/fd.c --- v2.3.26/linux/fs/proc/fd.c Mon Oct 4 15:49:30 1999 +++ linux/fs/proc/fd.c Wed Dec 31 16:00:00 1969 @@ -1,199 +0,0 @@ -/* - * linux/fs/proc/fd.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * proc fd directory handling functions - * - * 01-May-98 Edgar Toernig - * Added support for more than 256 fds. - * Limit raised to 32768. - */ - -#include -#include -#include -#include -#include - -#include - -static int proc_readfd(struct file *, void *, filldir_t); -static struct dentry *proc_lookupfd(struct inode *, struct dentry *); - -static struct file_operations proc_fd_operations = { - NULL, /* lseek - default */ - NULL, /* read - bad */ - NULL, /* write - bad */ - proc_readfd, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -/* - * proc directories can do almost nothing.. - */ -struct inode_operations proc_fd_inode_operations = { - &proc_fd_operations, /* default base directory file-ops */ - NULL, /* create */ - proc_lookupfd, /* 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 */ - NULL, /* flushpage */ - NULL, /* truncate */ - proc_permission, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; - -/* - * NOTE! Normally we'd indicate that a file does not - * exist by creating a negative dentry and returning - * a successful return code. However, for this case - * we do not want to create negative dentries, because - * the state of the world can change behind our backs. - * - * Thus just return -ENOENT instead. - */ -static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry) -{ - unsigned int ino, pid, fd, c; - struct task_struct * p; - struct file * file; - struct inode *inode; - const char *name; - int len, err; - - err = -ENOENT; - ino = dir->i_ino; - pid = ino >> 16; - ino &= 0x0000ffff; - - if (!pid || ino != PROC_PID_FD) - goto out; - - fd = 0; - len = dentry->d_name.len; - name = dentry->d_name.name; - if (len > 1 && *name == '0') goto out; - while (len-- > 0) { - c = *name - '0'; - name++; - if (c > 9) - goto out; - fd *= 10; - fd += c; - if (fd & 0xffff8000) - goto out; - } - - read_lock(&tasklist_lock); - file = NULL; - p = find_task_by_pid(pid); - if (p && p->files) - file = fcheck_task(p, fd); - read_unlock(&tasklist_lock); - - /* - * File handle is invalid if it is out of range, if the process - * has no files (Zombie) if the file is closed, or if its inode - * is NULL - */ - - if (!file) - goto out; - - ino = (pid << 16) + PROC_PID_FD_DIR + fd; - inode = proc_get_inode(dir->i_sb, ino, NULL); - if (inode) { - dentry->d_op = &proc_dentry_operations; - d_add(dentry, inode); - return NULL; - } -out: - return ERR_PTR(err); -} - -#define NUMBUF 10 - -static int proc_readfd(struct file * filp, void * dirent, filldir_t filldir) -{ - struct inode *inode = filp->f_dentry->d_inode; - struct task_struct *p, *tmp; - unsigned int fd, pid, ino; - int retval; - char buf[NUMBUF]; - - retval = 0; - ino = inode->i_ino; - pid = ino >> 16; - ino &= 0x0000ffff; - if (ino != PROC_PID_FD) - goto out; - - for (fd = filp->f_pos; fd < 2; fd++, filp->f_pos++) { - ino = inode->i_ino; - if (fd) - ino = (ino & 0xffff0000) | PROC_PID_INO; - if (filldir(dirent, "..", fd+1, fd, ino) < 0) - goto out; - } - - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (!p) - goto out_unlock; - - for (fd -= 2 ; p->files && fd < p->files->max_fds; fd++, filp->f_pos++) - { - unsigned int i,j; - - if (!fcheck_task(p, fd)) - continue; - - j = NUMBUF; - i = fd; - do { - j--; - buf[j] = '0' + (i % 10); - i /= 10; - } while (i); - - /* Drop the task lock, as the filldir function may block */ - read_unlock(&tasklist_lock); - - ino = (pid << 16) + PROC_PID_FD_DIR + fd; - if (filldir(dirent, buf+j, NUMBUF-j, fd+2, ino) < 0) - goto out; - - read_lock(&tasklist_lock); - /* - * filldir() might have slept, so we must - * re-validate "p". This is fast enough due - * to the pidhash - */ - tmp = find_task_by_pid(pid); - if (p != tmp) - break; - } -out_unlock: - read_unlock(&tasklist_lock); - -out: - return retval; -} diff -u --recursive --new-file v2.3.26/linux/fs/proc/inode-alloc.txt linux/fs/proc/inode-alloc.txt --- v2.3.26/linux/fs/proc/inode-alloc.txt Fri May 8 18:10:30 1998 +++ linux/fs/proc/inode-alloc.txt Thu Nov 11 16:57:31 1999 @@ -1,50 +1,14 @@ -Inode allocations in the proc-fs (hex-numbers): +Current inode allocations in the proc-fs (hex-numbers): 00000000 reserved - 00000001-00000fff static entries + 00000001-00000fff static entries (goners) 001 root-ino - 002 load-avg - 003 uptime - ... - 080 net/* - ... - 100 scsi/* - ... - xxx mca/* - ... - yyy bus/* - ... - fff end 00001000-00001fff dynamic entries - 00002000-00002fff openprom entries - 0001xxxx-7fffxxxx pid-dir entries for pid 1-7fff - 0000 unused - 0001 unused - 0002 pid - 0003 pid/status - ... - 0008 pid/fd - ... - 00xx-00ff unused - 01xx pid/fd/* for fd 0-ff - ... - 01ff end - 0200-ffff unused - 80000000-ffffffff unused - - -New allocation: - - 00000000-0000ffff unchanged - - 0001xxxx-7fffxxxx pid-dir entries for pid 1-7fff - 0000-00ff unchanged - 0100-7fff unused - 8000-ffff pid/fd/* for fd 0-7fff - - 80000000-ffffffff unchanged +Goal: + a) once we'll split the thing into several virtual filesystems we + will get rid of magical ranges (and this file, BTW). diff -u --recursive --new-file v2.3.26/linux/fs/proc/inode.c linux/fs/proc/inode.c --- v2.3.26/linux/fs/proc/inode.c Sun Jul 4 10:18:52 1999 +++ linux/fs/proc/inode.c Thu Nov 11 16:57:31 1999 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -51,9 +52,7 @@ static void proc_put_inode(struct inode *inode) { #ifdef CONFIG_SUN_OPENPROMFS_MODULE - if ((inode->i_ino >= PROC_OPENPROM_FIRST) && - (inode->i_ino < PROC_OPENPROM_FIRST + PROC_NOPENPROM) && - proc_openprom_use) + if (PROC_INODE_OPENPROM(inode) && proc_openprom_use) (*proc_openprom_use)(inode, 0); #endif /* @@ -71,18 +70,16 @@ { struct proc_dir_entry *de = inode->u.generic_ip; -#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) - if ((inode->i_ino >= PROC_OPENPROM_FIRST) && - (inode->i_ino < PROC_OPENPROM_FIRST + PROC_NOPENPROM)) + if (PROC_INODE_PROPER(inode)) { + proc_pid_delete_inode(inode); + return; + } + if (PROC_INODE_OPENPROM(inode)) return; -#endif if (de) { - /* - * Call the fill_inode hook to release module counts. - */ - if (de->fill_inode) - de->fill_inode(inode, 0); + if (de->owner) + __MOD_DEC_USE_COUNT(de->owner); de_put(de); } } @@ -142,113 +139,6 @@ return 1; } -/* - * The standard rules, copied from fs/namei.c:permission(). - */ -static int standard_permission(struct inode *inode, int mask) -{ - int mode = inode->i_mode; - - if ((mask & S_IWOTH) && IS_RDONLY(inode) && - (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) - return -EROFS; /* Nobody gets write access to a read-only fs */ - else if ((mask & S_IWOTH) && IS_IMMUTABLE(inode)) - return -EACCES; /* Nobody gets write access to an immutable file */ - else if (current->fsuid == inode->i_uid) - mode >>= 6; - else if (in_group_p(inode->i_gid)) - mode >>= 3; - if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE)) - return 0; - /* read and search access */ - if ((mask == S_IROTH) || - (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH)))) - if (capable(CAP_DAC_READ_SEARCH)) - return 0; - return -EACCES; -} - -/* - * Set up permission rules for processes looking at other processes. - * You're not allowed to see a process unless it has the same or more - * restricted root than your own. This prevents a chrooted processes - * from escaping through the /proc entries of less restricted - * processes, and thus allows /proc to be safely mounted in a chrooted - * area. - * - * Note that root (uid 0) doesn't get permission for this either, - * since chroot is stronger than root. - * - * XXX TODO: use the dentry mechanism to make off-limits procs simply - * invisible rather than denied? Does each namespace root get its own - * dentry tree? - * - * This also applies the default permissions checks, as it only adds - * restrictions. - * - * Jeremy Fitzhardinge - */ -int proc_permission(struct inode *inode, int mask) -{ - struct task_struct *p; - unsigned long ino = inode->i_ino; - unsigned long pid; - struct dentry *de, *base; - - if (standard_permission(inode, mask) != 0) - return -EACCES; - - /* - * Find the root of the processes being examined (if any). - * XXX Surely there's a better way of doing this? - */ - if (ino >= PROC_OPENPROM_FIRST && - ino < PROC_OPENPROM_FIRST + PROC_NOPENPROM) - return 0; /* already allowed */ - - pid = ino >> 16; - if (pid == 0) - return 0; /* already allowed */ - - de = NULL; - base = current->fs->root; - - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - - if (p && p->fs) - de = p->fs->root; - read_unlock(&tasklist_lock); /* FIXME! */ - - if (p == NULL) - return -EACCES; /* ENOENT? */ - - if (de == NULL) - { - /* kswapd and bdflush don't have proper root or cwd... */ - return -EACCES; - } - - /* XXX locking? */ - for(;;) - { - struct dentry *parent; - - if (de == base) - return 0; /* already allowed */ - - de = de->d_covers; - parent = de->d_parent; - - if (de == parent) - break; - - de = parent; - } - - return -EACCES; /* incompatible roots */ -} - struct inode * proc_get_inode(struct super_block * sb, int ino, struct proc_dir_entry * de) { @@ -269,14 +159,9 @@ goto out_fail; #ifdef CONFIG_SUN_OPENPROMFS_MODULE - if ((inode->i_ino >= PROC_OPENPROM_FIRST) - && (inode->i_ino < PROC_OPENPROM_FIRST + PROC_NOPENPROM) - && proc_openprom_use) + if (PROC_INODE_OPENPROM(inode) && proc_openprom_use) (*proc_openprom_use)(inode, 1); #endif - /* N.B. How can this test ever fail?? */ - if (inode->i_sb != sb) - printk("proc_get_inode: inode fubar\n"); inode->u.generic_ip = (void *) de; if (de) { @@ -291,12 +176,8 @@ inode->i_op = de->ops; if (de->nlink) inode->i_nlink = de->nlink; - /* - * The fill_inode routine should use this call - * to increment module counts, if necessary. - */ - if (de->fill_inode) - de->fill_inode(inode, 1); + if (de->owner) + __MOD_INC_USE_COUNT(de->owner); } /* * Fixup the root inode's nlink value @@ -366,63 +247,7 @@ void proc_read_inode(struct inode * inode) { - unsigned long ino, pid; - struct task_struct * p; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; - inode->i_blocks = 0; - inode->i_blksize = 1024; - ino = inode->i_ino; - if (ino >= PROC_OPENPROM_FIRST && - ino < PROC_OPENPROM_FIRST + PROC_NOPENPROM) - goto out; - inode->i_op = NULL; - inode->i_mode = 0; - inode->i_uid = 0; - inode->i_gid = 0; - inode->i_nlink = 1; - inode->i_size = 0; - - pid = ino >> 16; - if (!pid) - goto out; - - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (!p) - goto out_unlock; - - ino &= 0x0000ffff; - if (ino == PROC_PID_INO || p->dumpable) { - inode->i_uid = p->euid; - inode->i_gid = p->egid; - } - if (ino & PROC_PID_FD_DIR) { - struct file * file; - ino &= 0x7fff; - if (!p->files) /* can we ever get here if that's the case? */ - goto out_unlock; - read_lock(&p->files->file_lock); - file = fcheck_task(p, ino); - if (!file) - goto out_unlock2; - - inode->i_op = &proc_link_inode_operations; - inode->i_size = 64; - inode->i_mode = S_IFLNK; - if (file->f_mode & 1) - inode->i_mode |= S_IRUSR | S_IXUSR; - if (file->f_mode & 2) - inode->i_mode |= S_IWUSR | S_IXUSR; -out_unlock2: - read_unlock(&p->files->file_lock); - } -out_unlock: - /* Defer unlocking until we're done with the task */ - read_unlock(&tasklist_lock); - -out: - return; } void proc_write_inode(struct inode * inode) diff -u --recursive --new-file v2.3.26/linux/fs/proc/kcore.c linux/fs/proc/kcore.c --- v2.3.26/linux/fs/proc/kcore.c Sun Nov 7 16:37:34 1999 +++ linux/fs/proc/kcore.c Wed Nov 10 19:47:57 1999 @@ -5,6 +5,7 @@ * Jeremy Fitzhardinge * Implemented by David Howells * Modified and incorporated into 2.3.x by Tigran Aivazian + * Support to dump vmalloc'd data structures (ELF only), Tigran Aivazian */ #include @@ -14,13 +15,38 @@ #include #include #include +#include +#include #include + +static int open_kcore(struct inode * inode, struct file * filp) +{ + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; +} + +static ssize_t read_kcore(struct file *, char *, size_t, loff_t *); + +static struct file_operations proc_kcore_operations = { + NULL, /* lseek */ + read_kcore, + NULL, /* write */ + NULL, /* readdir */ + NULL, /* poll */ + NULL, /* ioctl */ + NULL, /* mmap */ + open_kcore +}; + +struct inode_operations proc_kcore_inode_operations = { + &proc_kcore_operations, +}; + #ifdef CONFIG_KCORE_AOUT -ssize_t read_kcore(struct file * file, char * buf, +static ssize_t read_kcore(struct file * file, char * buf, size_t count, loff_t *ppos) { - unsigned long p = *ppos, memsize; + unsigned long long p = *ppos, memsize; ssize_t read; ssize_t count1; char * pnt; @@ -77,8 +103,7 @@ *ppos += read; return read; } -#else - +#else /* CONFIG_KCORE_AOUT */ #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) @@ -93,6 +118,31 @@ extern char saved_command_line[]; +static size_t get_kcore_size(int *num_vma, int *elf_buflen) +{ + size_t try, size = 0; + struct vm_struct *m; + + *num_vma = 0; + if (!vmlist) { + *elf_buflen = PAGE_SIZE; + return ((size_t)high_memory - PAGE_OFFSET + PAGE_SIZE); + } + + for (m=vmlist; m; m=m->next) { + try = (size_t)m->addr + m->size; + if (try > size) + size = try; + *num_vma = *num_vma + 1; + } + *elf_buflen = sizeof(struct elfhdr) + + (*num_vma + 2)*sizeof(struct elf_phdr) + + 3 * sizeof(struct memelfnote); + *elf_buflen = PAGE_ALIGN(*elf_buflen); + return (size - PAGE_OFFSET + *elf_buflen); +} + + /*****************************************************************************/ /* * determine size of ELF note @@ -135,118 +185,124 @@ return bufp; } /* end storenote() */ -/*****************************************************************************/ /* * store an ELF coredump header in the supplied buffer - * - assume the memory image is the size specified + * num_vma is the number of elements in vmlist */ -static void elf_kcore_store_hdr(char *bufp, size_t size, off_t dataoff) +static void elf_kcore_store_hdr(char *bufp, int num_vma, int elf_buflen) { struct elf_prstatus prstatus; /* NT_PRSTATUS */ - struct elf_prpsinfo psinfo; /* NT_PRPSINFO */ - struct elf_phdr *nhdr, *dhdr; + struct elf_prpsinfo prpsinfo; /* NT_PRPSINFO */ + struct elf_phdr *nhdr, *phdr; struct elfhdr *elf; struct memelfnote notes[3]; off_t offset = 0; + struct vm_struct *m; - /* acquire an ELF header block from the buffer */ + /* setup ELF header */ elf = (struct elfhdr *) bufp; - bufp += sizeof(*elf); - offset += sizeof(*elf); - - /* set up header */ - memcpy(elf->e_ident,ELFMAG,SELFMAG); + bufp += sizeof(struct elfhdr); + offset += sizeof(struct elfhdr); + memcpy(elf->e_ident, ELFMAG, SELFMAG); elf->e_ident[EI_CLASS] = ELF_CLASS; elf->e_ident[EI_DATA] = ELF_DATA; elf->e_ident[EI_VERSION]= EV_CURRENT; - memset(elf->e_ident+EI_PAD,0,EI_NIDENT-EI_PAD); - + memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); elf->e_type = ET_CORE; elf->e_machine = ELF_ARCH; elf->e_version = EV_CURRENT; elf->e_entry = 0; - elf->e_phoff = sizeof(*elf); + elf->e_phoff = sizeof(struct elfhdr); elf->e_shoff = 0; elf->e_flags = 0; - elf->e_ehsize = sizeof(*elf); + elf->e_ehsize = sizeof(struct elfhdr); elf->e_phentsize= sizeof(struct elf_phdr); - elf->e_phnum = 2; /* no. of segments */ + elf->e_phnum = 2 + num_vma; elf->e_shentsize= 0; elf->e_shnum = 0; elf->e_shstrndx = 0; - /* acquire an ELF program header blocks from the buffer for notes */ + /* setup ELF PT_NOTE program header */ nhdr = (struct elf_phdr *) bufp; - bufp += sizeof(*nhdr); - offset += sizeof(*nhdr); - - /* store program headers for notes dump */ + bufp += sizeof(struct elf_phdr); + offset += sizeof(struct elf_phdr); nhdr->p_type = PT_NOTE; nhdr->p_offset = 0; nhdr->p_vaddr = 0; nhdr->p_paddr = 0; + nhdr->p_filesz = 0; nhdr->p_memsz = 0; nhdr->p_flags = 0; nhdr->p_align = 0; - /* acquire an ELF program header blocks from the buffer for data */ - dhdr = (struct elf_phdr *) bufp; - bufp += sizeof(*dhdr); - offset += sizeof(*dhdr); - - /* store program headers for data dump */ - dhdr->p_type = PT_LOAD; - dhdr->p_flags = PF_R|PF_W|PF_X; - dhdr->p_offset = dataoff; - dhdr->p_vaddr = PAGE_OFFSET; - dhdr->p_paddr = __pa(PAGE_OFFSET); - dhdr->p_filesz = size; - dhdr->p_memsz = size; - dhdr->p_align = PAGE_SIZE; + /* setup ELF PT_LOAD program header */ + phdr = (struct elf_phdr *) bufp; + bufp += sizeof(struct elf_phdr); + offset += sizeof(struct elf_phdr); + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_offset = elf_buflen; + phdr->p_vaddr = PAGE_OFFSET; + phdr->p_paddr = __pa(PAGE_OFFSET); + phdr->p_filesz = phdr->p_memsz = ((unsigned long)high_memory - PAGE_OFFSET); + phdr->p_align = PAGE_SIZE; + + for (m=vmlist; m; m=m->next) { + phdr = (struct elf_phdr *) bufp; + bufp += sizeof(struct elf_phdr); + offset += sizeof(struct elf_phdr); + + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R|PF_W|PF_X; + phdr->p_offset = (size_t)m->addr - PAGE_OFFSET + elf_buflen; + phdr->p_vaddr = (size_t)m->addr; + phdr->p_paddr = __pa(m); + phdr->p_filesz = phdr->p_memsz = m->size; + phdr->p_align = PAGE_SIZE; + } /* * Set up the notes in similar form to SVR4 core dumps made * with info from their /proc. */ nhdr->p_offset = offset; - nhdr->p_filesz = 0; /* set up the process status */ notes[0].name = "CORE"; notes[0].type = NT_PRSTATUS; - notes[0].datasz = sizeof(prstatus); + notes[0].datasz = sizeof(struct elf_prstatus); notes[0].data = &prstatus; - memset(&prstatus,0,sizeof(prstatus)); + memset(&prstatus, 0, sizeof(struct elf_prstatus)); nhdr->p_filesz = notesize(¬es[0]); - bufp = storenote(¬es[0],bufp); + bufp = storenote(¬es[0], bufp); /* set up the process info */ notes[1].name = "CORE"; notes[1].type = NT_PRPSINFO; - notes[1].datasz = sizeof(psinfo); - notes[1].data = &psinfo; + notes[1].datasz = sizeof(struct elf_prpsinfo); + notes[1].data = &prpsinfo; - memset(&psinfo,0,sizeof(psinfo)); - psinfo.pr_state = 0; - psinfo.pr_sname = 'R'; - psinfo.pr_zomb = 0; + memset(&prpsinfo, 0, sizeof(struct elf_prpsinfo)); + prpsinfo.pr_state = 0; + prpsinfo.pr_sname = 'R'; + prpsinfo.pr_zomb = 0; - strcpy(psinfo.pr_fname,"vmlinux"); - strncpy(psinfo.pr_psargs,saved_command_line,ELF_PRARGSZ); + strcpy(prpsinfo.pr_fname, "vmlinux"); + strncpy(prpsinfo.pr_psargs, saved_command_line, ELF_PRARGSZ); nhdr->p_filesz = notesize(¬es[1]); - bufp = storenote(¬es[1],bufp); + bufp = storenote(¬es[1], bufp); /* set up the task structure */ notes[2].name = "CORE"; notes[2].type = NT_TASKSTRUCT; - notes[2].datasz = sizeof(*current); + notes[2].datasz = sizeof(struct task_struct); notes[2].data = current; nhdr->p_filesz = notesize(¬es[2]); - bufp = storenote(¬es[2],bufp); + bufp = storenote(¬es[2], bufp); } /* end elf_kcore_store_hdr() */ @@ -254,85 +310,79 @@ /* * read from the ELF header and then kernel memory */ -ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, +static ssize_t read_kcore(struct file *file, char *buffer, size_t buflen, loff_t *fpos) { - ssize_t acc; + ssize_t acc = 0; size_t size, tsz; - char *page; - - /* work out how much file we allow to be read */ - size = ((size_t)high_memory - PAGE_OFFSET) + PAGE_SIZE; - acc = 0; + char * elf_buffer; + int elf_buflen = 0, num_vma = 0; - /* see if file pointer already beyond EOF */ - if (buflen==0 || *fpos>=size) + /* XXX we need to somehow lock vmlist between here + * and after elf_kcore_store_hdr() returns. + * For now assume that num_vma does not change (TA) + */ + proc_root_kcore.size = size = get_kcore_size(&num_vma, &elf_buflen); + if (buflen == 0 || *fpos >= size) return 0; /* trim buflen to not go beyond EOF */ - if (buflen > size-*fpos) + if (buflen > size - *fpos) buflen = size - *fpos; /* construct an ELF core header if we'll need some of it */ - if (*fpos - -#include -#include -#include -#include -#include -#include -#include - -static int proc_readlink(struct dentry *, char *, int); -static struct dentry * proc_follow_link(struct dentry *, struct dentry *, unsigned int); - -/* - * links can't do much... - */ -static struct file_operations proc_fd_link_operations = { - NULL, /* lseek - default */ - NULL, /* read - bad */ - NULL, /* write - bad */ - NULL, /* readdir - bad */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* very special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -struct inode_operations proc_link_inode_operations = { - &proc_fd_link_operations,/* file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - proc_readlink, /* readlink */ - proc_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - proc_permission, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; - -static struct dentry * proc_follow_link(struct dentry *dentry, - struct dentry *base, - unsigned int follow) -{ - struct inode *inode = dentry->d_inode; - struct task_struct *p; - struct dentry * result; - int ino, pid; - int error; - - /* We don't need a base pointer in the /proc filesystem */ - dput(base); - - error = permission(inode, MAY_EXEC); - result = ERR_PTR(error); - if (error) - goto out; - - ino = inode->i_ino; - pid = ino >> 16; - ino &= 0x0000ffff; - - result = ERR_PTR(-ENOENT); - - switch (ino) { - case PROC_PID_CWD: - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (p && p->fs && p->fs->pwd) - result = dget(p->fs->pwd); - read_unlock(&tasklist_lock); - break; - - case PROC_PID_ROOT: - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (p && p->fs && p->fs->root) - result = dget(p->fs->root); - read_unlock(&tasklist_lock); - break; - - case PROC_PID_EXE: { - struct mm_struct *mm = NULL; - struct vm_area_struct * vma; - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (p) - mm = p->mm; - if (mm) - atomic_inc(&mm->mm_users); - read_unlock(&tasklist_lock); - if (!mm) - break; - down(&mm->mmap_sem); - vma = mm->mmap; - while (vma) { - if ((vma->vm_flags & VM_EXECUTABLE) && - vma->vm_file) { - result = dget(vma->vm_file->f_dentry); - break; - } - vma = vma->vm_next; - } - up(&mm->mmap_sem); - mmput(mm); - break; - } - default: - if (ino & PROC_PID_FD_DIR) { - struct file * file; - struct files_struct *files = NULL; - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - if (p) - files = p->files; - read_unlock(&tasklist_lock); - if (!files) - break; - ino &= 0x7fff; - read_lock(&files->file_lock); - /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ - if (ino < files->max_fds && - (file = files->fd[ino]) && file->f_dentry) - result = dget(file->f_dentry); - read_unlock(&p->files->file_lock); - } - } -out: - return result; -} - -/* - * This pretty-prints the pathname of a dentry, - * clarifying sockets etc. - */ -static int do_proc_readlink(struct dentry *dentry, char * buffer, int buflen) -{ - struct inode * inode; - char * tmp = (char*)__get_free_page(GFP_KERNEL), *path, *pattern; - int len; - - if(tmp==NULL) - return -ENOMEM; - - /* Check for special dentries.. */ - pattern = NULL; - inode = dentry->d_inode; - if (inode && IS_ROOT(dentry)) { - if (S_ISSOCK(inode->i_mode)) - pattern = "socket:[%lu]"; - if (S_ISFIFO(inode->i_mode)) - pattern = "pipe:[%lu]"; - } - - if (pattern) { - len = sprintf(tmp, pattern, inode->i_ino); - path = tmp; - } else { - path = d_path(dentry, tmp, PAGE_SIZE); - len = tmp + PAGE_SIZE - 1 - path; - } - - if (len < buflen) - buflen = len; - dput(dentry); - copy_to_user(buffer, path, buflen); - free_page((unsigned long)tmp); - return buflen; -} - -static int proc_readlink(struct dentry * dentry, char * buffer, int buflen) -{ - int error; - - dentry = proc_follow_link(dentry, NULL, 1); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = -ENOENT; - if (dentry) { - error = do_proc_readlink(dentry, buffer, buflen); - } - } - return error; -} diff -u --recursive --new-file v2.3.26/linux/fs/proc/mem.c linux/fs/proc/mem.c --- v2.3.26/linux/fs/proc/mem.c Mon Nov 1 13:56:27 1999 +++ linux/fs/proc/mem.c Wed Dec 31 16:00:00 1969 @@ -1,355 +0,0 @@ -/* - * linux/fs/proc/mem.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * mem_write isn't really a good idea right now. It needs - * to check a lot more: if the process we try to write to - * dies in the middle right now, mem_write will overwrite - * kernel memory.. This disables it altogether. - */ -#define mem_write NULL - -static int check_range(struct mm_struct * mm, unsigned long addr, int count) -{ - struct vm_area_struct *vma; - int retval; - - vma = find_vma(mm, addr); - if (!vma) - return -EACCES; - if (vma->vm_start > addr) - return -EACCES; - if (!(vma->vm_flags & VM_READ)) - return -EACCES; - while ((retval = vma->vm_end - addr) < count) { - struct vm_area_struct *next = vma->vm_next; - if (!next) - break; - if (vma->vm_end != next->vm_start) - break; - if (!(next->vm_flags & VM_READ)) - break; - vma = next; - } - if (retval > count) - retval = count; - return retval; -} - -static struct task_struct * get_task(int pid) -{ - struct task_struct * tsk = current; - - if (pid != tsk->pid) { - tsk = find_task_by_pid(pid); - - /* Allow accesses only under the same circumstances - * that we would allow ptrace to work. - */ - if (tsk) { - if (!(tsk->flags & PF_PTRACED) - || tsk->state != TASK_STOPPED - || tsk->p_pptr != current) - tsk = NULL; - } - } - return tsk; -} - -static ssize_t mem_read(struct file * file, char * buf, - size_t count, loff_t *ppos) -{ - struct inode * inode = file->f_dentry->d_inode; - pgd_t *page_dir; - pmd_t *page_middle; - pte_t pte; - struct page * page; - struct task_struct * tsk; - unsigned long addr; - unsigned long maddr; /* temporary mapped address */ - char *tmp; - ssize_t scount, i; - - read_lock(&tasklist_lock); - tsk = get_task(inode->i_ino >> 16); - read_unlock(&tasklist_lock); /* FIXME: This should really be done only afetr not using tsk any more!!! */ - if (!tsk) - return -ESRCH; - addr = *ppos; - scount = check_range(tsk->mm, addr, count); - if (scount < 0) - return scount; - tmp = buf; - while (scount > 0) { - if (signal_pending(current)) - break; - page_dir = pgd_offset(tsk->mm,addr); - if (pgd_none(*page_dir)) - break; - if (pgd_bad(*page_dir)) { - pgd_ERROR(*page_dir); - pgd_clear(page_dir); - break; - } - page_middle = pmd_offset(page_dir,addr); - if (pmd_none(*page_middle)) - break; - if (pmd_bad(*page_middle)) { - pmd_ERROR(*page_middle); - pmd_clear(page_middle); - break; - } - pte = *pte_offset(page_middle,addr); - if (!pte_present(pte)) - break; - page = pte_page(pte); - i = PAGE_SIZE-(addr & ~PAGE_MASK); - if (i > scount) - i = scount; - maddr = kmap(page, KM_READ); - copy_to_user(tmp, (char *)maddr + (addr & ~PAGE_MASK), i); - kunmap(maddr, KM_READ); - addr += i; - tmp += i; - scount -= i; - } - *ppos = addr; - return tmp-buf; -} - -#ifndef mem_write - -static ssize_t mem_write(struct file * file, char * buf, - size_t count, loff_t *ppos) -{ - struct inode * inode = file->f_dentry->d_inode; - pgd_t *page_dir; - pmd_t *page_middle; - pte_t pte; - struct page * page; - struct task_struct * tsk; - unsigned long addr; - unsigned long maddr; /* temporary mapped address */ - char *tmp; - long i; - - addr = *ppos; - tsk = get_task(inode->i_ino >> 16); - if (!tsk) - return -ESRCH; - tmp = buf; - while (count > 0) { - if (signal_pending(current)) - break; - page_dir = pgd_offset(tsk,addr); - if (pgd_none(*page_dir)) - break; - if (pgd_bad(*page_dir)) { - pgd_ERROR(*page_dir); - pgd_clear(page_dir); - break; - } - page_middle = pmd_offset(page_dir,addr); - if (pmd_none(*page_middle)) - break; - if (pmd_bad(*page_middle)) { - pmd_ERROR(*page_middle); - pmd_clear(page_middle); - break; - } - pte = *pte_offset(page_middle,addr); - if (!pte_present(pte)) - break; - if (!pte_write(pte)) - break; - page = pte_page(pte); - i = PAGE_SIZE-(addr & ~PAGE_MASK); - if (i > count) - i = count; - maddr = kmap(page, KM_WRITE); - copy_from_user((char *)maddr + (addr & ~PAGE_MASK), tmp, i); - kunmap(maddr, KM_WRITE); - addr += i; - tmp += i; - count -= i; - } - *ppos = addr; - if (tmp != buf) - return tmp-buf; - if (signal_pending(current)) - return -ERESTARTSYS; - return 0; -} - -#endif - -static long long mem_lseek(struct file * file, long long offset, int orig) -{ - switch (orig) { - case 0: - file->f_pos = offset; - return file->f_pos; - case 1: - file->f_pos += offset; - return file->f_pos; - default: - return -EINVAL; - } -} - -/* - * This isn't really reliable by any means.. - */ -int mem_mmap(struct file * file, struct vm_area_struct * vma) -{ - struct task_struct *tsk; - pgd_t *src_dir, *dest_dir; - pmd_t *src_middle, *dest_middle; - pte_t *src_table, *dest_table; - unsigned long stmp, etmp, dtmp, mapnr; - struct vm_area_struct *src_vma = NULL; - struct inode *inode = file->f_dentry->d_inode; - - /* Get the source's task information */ - - tsk = get_task(inode->i_ino >> 16); - - if (!tsk) - return -ESRCH; - - /* Ensure that we have a valid source area. (Has to be mmap'ed and - have valid page information.) We can't map shared memory at the - moment because working out the vm_area_struct & nattach stuff isn't - worth it. */ - - src_vma = tsk->mm->mmap; - stmp = vma->vm_pgoff << PAGE_SHIFT; - etmp = stmp + vma->vm_end - vma->vm_start; - while (stmp < etmp) { - while (src_vma && stmp > src_vma->vm_end) - src_vma = src_vma->vm_next; - if (!src_vma || (src_vma->vm_flags & VM_SHM)) - return -EINVAL; - - src_dir = pgd_offset(tsk->mm, stmp); - if (pgd_none(*src_dir)) - return -EINVAL; - if (pgd_bad(*src_dir)) { - pgd_ERROR(*src_dir); - return -EINVAL; - } - src_middle = pmd_offset(src_dir, stmp); - if (pmd_none(*src_middle)) - return -EINVAL; - if (pmd_bad(*src_middle)) { - pmd_ERROR(*src_middle); - return -EINVAL; - } - src_table = pte_offset(src_middle, stmp); - if (pte_none(*src_table)) - return -EINVAL; - - if (stmp < src_vma->vm_start) { - if (!(src_vma->vm_flags & VM_GROWSDOWN)) - return -EINVAL; - if (src_vma->vm_end - stmp > current->rlim[RLIMIT_STACK].rlim_cur) - return -EINVAL; - } - stmp += PAGE_SIZE; - } - - src_vma = tsk->mm->mmap; - stmp = vma->vm_pgoff << PAGE_SHIFT; - dtmp = vma->vm_start; - - flush_cache_range(vma->vm_mm, vma->vm_start, vma->vm_end); - flush_cache_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end); - while (dtmp < vma->vm_end) { - while (src_vma && stmp > src_vma->vm_end) - src_vma = src_vma->vm_next; - - src_dir = pgd_offset(tsk->mm, stmp); - src_middle = pmd_offset(src_dir, stmp); - src_table = pte_offset(src_middle, stmp); - - dest_dir = pgd_offset(current->mm, dtmp); - dest_middle = pmd_alloc(dest_dir, dtmp); - if (!dest_middle) - return -ENOMEM; - dest_table = pte_alloc(dest_middle, dtmp); - if (!dest_table) - return -ENOMEM; - - if (!pte_present(*src_table)) - handle_mm_fault(tsk, src_vma, stmp, 1); - - if ((vma->vm_flags & VM_WRITE) && !pte_write(*src_table)) - handle_mm_fault(tsk, src_vma, stmp, 1); - - set_pte(src_table, pte_mkdirty(*src_table)); - set_pte(dest_table, *src_table); - mapnr = pte_pagenr(*src_table); - if (mapnr < max_mapnr) - get_page(mem_map + pte_pagenr(*src_table)); - - stmp += PAGE_SIZE; - dtmp += PAGE_SIZE; - } - - flush_tlb_range(vma->vm_mm, vma->vm_start, vma->vm_end); - flush_tlb_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end); - return 0; -} - -static struct file_operations proc_mem_operations = { - mem_lseek, - mem_read, - mem_write, - NULL, /* mem_readdir */ - NULL, /* mem_poll */ - NULL, /* mem_ioctl */ - mem_mmap, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -struct inode_operations proc_mem_inode_operations = { - &proc_mem_operations, /* default base directory file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - proc_permission, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; diff -u --recursive --new-file v2.3.26/linux/fs/proc/net.c linux/fs/proc/net.c --- v2.3.26/linux/fs/proc/net.c Sat Jun 26 12:04:40 1999 +++ linux/fs/proc/net.c Wed Dec 31 16:00:00 1969 @@ -1,124 +0,0 @@ -/* - * linux/fs/proc/net.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - * - * gjh 3/'93 heim@peanuts.informatik.uni-tuebingen.de (Gerald J. Heim) - * most of this file is stolen from base.c - * it works, but you shouldn't use it as a guideline - * for new proc-fs entries. once i'll make it better. - * fvk 3/'93 waltje@uwalt.nl.mugnet.org (Fred N. van Kempen) - * cleaned up the whole thing, moved "net" specific code to - * the NET kernel layer (where it belonged in the first place). - * Michael K. Johnson (johnsonm@stolaf.edu) 3/93 - * Added support from my previous inet.c. Cleaned things up - * quite a bit, modularized the code. - * fvk 4/'93 waltje@uwalt.nl.mugnet.org (Fred N. van Kempen) - * Renamed "route_get_info()" to "rt_get_info()" for consistency. - * Alan Cox (gw4pts@gw4pts.ampr.org) 4/94 - * Dusted off the code and added IPX. Fixed the 4K limit. - * Erik Schoenfelder (schoenfr@ibr.cs.tu-bs.de) - * /proc/net/snmp. - * Alan Cox (gw4pts@gw4pts.ampr.org) 1/95 - * Added AppleTalk slots - * - * proc net directory handling functions - */ -#include -#include -#include -#include -#include -#include - -#include - -#define PROC_BLOCK_SIZE (3*1024) /* 4K page size but our output routines use some slack for overruns */ - -static long proc_readnet(struct inode * inode, struct file * file, - char * buf, unsigned long count) -{ - char * page; - int bytes=count; - int copied=0; - char *start; - struct proc_dir_entry * dp; - - if (count < 0) - return -EINVAL; - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if (!(page = (char*) __get_free_page(GFP_KERNEL))) - return -ENOMEM; - - while (bytes>0) - { - int length, thistime=bytes; - if (bytes > PROC_BLOCK_SIZE) - thistime=PROC_BLOCK_SIZE; - - length = dp->get_info(page, &start, - file->f_pos, - thistime, - (file->f_flags & O_ACCMODE) == O_RDWR); - - /* - * We have been given a non page aligned block of - * the data we asked for + a bit. We have been given - * the start pointer and we know the length.. - */ - - if (length <= 0) - break; - /* - * Copy the bytes - */ - copy_to_user(buf+copied, start, length); - file->f_pos += length; /* Move down the file */ - bytes -= length; - copied += length; - if (length #include #include -#include -#include #include #include #include @@ -30,6 +28,7 @@ #include #include #include +#include #include #include @@ -163,6 +162,8 @@ "Cached: %8u kB\n" "HighTotal: %8lu kB\n" "HighFree: %8lu kB\n" + "LowTotal: %8lu kB\n" + "LowFree: %8lu kB\n" "SwapTotal: %8lu kB\n" "SwapFree: %8lu kB\n", K(i.totalram), @@ -172,6 +173,8 @@ K(atomic_read(&page_cache_size)), K(i.totalhigh), K(i.freehigh), + K(i.totalram-i.totalhigh), + K(i.freeram-i.freehigh), K(i.totalswap), K(i.freeswap)); @@ -545,12 +548,80 @@ return len; } +/* + * This function accesses profiling information. The returned data is + * binary: the sampling step and the actual contents of the profile + * buffer. Use of the program readprofile is recommended in order to + * get meaningful info out of these data. + */ +static ssize_t read_profile(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + ssize_t read; + char * pnt; + unsigned int sample_step = 1 << prof_shift; + + if (p >= (prof_len+1)*sizeof(unsigned int)) + return 0; + if (count > (prof_len+1)*sizeof(unsigned int) - p) + count = (prof_len+1)*sizeof(unsigned int) - p; + read = 0; + + while (p < sizeof(unsigned int) && count > 0) { + put_user(*((char *)(&sample_step)+p),buf); + buf++; p++; count--; read++; + } + pnt = (char *)prof_buffer + p - sizeof(unsigned int); + copy_to_user(buf,(void *)pnt,count); + read += count; + *ppos += read; + return read; +} + +/* + * Writing to /proc/profile resets the counters + * + * Writing a 'profiling multiplier' value into it also re-sets the profiling + * interrupt frequency, on architectures that support this. + */ +static ssize_t write_profile(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ +#ifdef __SMP__ + extern int setup_profiling_timer (unsigned int multiplier); + + if (count==sizeof(int)) { + unsigned int multiplier; + + if (copy_from_user(&multiplier, buf, sizeof(int))) + return -EFAULT; + + if (setup_profiling_timer(multiplier)) + return -EINVAL; + } +#endif + + memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer)); + return count; +} + +static struct file_operations proc_profile_operations = { + NULL, /* lseek */ + read_profile, + write_profile, +}; + +static struct inode_operations proc_profile_inode_operations = { + &proc_profile_operations, +}; + static struct proc_dir_entry proc_root_kmsg = { 0, 4, "kmsg", S_IFREG | S_IRUSR, 1, 0, 0, 0, &proc_kmsg_inode_operations }; -static struct proc_dir_entry proc_root_kcore = { +struct proc_dir_entry proc_root_kcore = { 0, 5, "kcore", S_IFREG | S_IRUSR, 1, 0, 0, 0, &proc_kcore_inode_operations @@ -613,7 +684,7 @@ /* And now for trickier ones */ proc_register(&proc_root, &proc_root_kmsg); proc_register(&proc_root, &proc_root_kcore); - proc_root_kcore.size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE; + proc_root_kcore.size = (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; if (prof_shift) { proc_register(&proc_root, &proc_root_profile); proc_root_profile.size = (1+prof_len) * sizeof(unsigned int); diff -u --recursive --new-file v2.3.26/linux/fs/proc/procfs_syms.c linux/fs/proc/procfs_syms.c --- v2.3.26/linux/fs/proc/procfs_syms.c Mon Nov 1 13:56:27 1999 +++ linux/fs/proc/procfs_syms.c Thu Nov 11 16:57:31 1999 @@ -3,14 +3,6 @@ #include #include -/* - * This is all required so that if we load all of scsi as a module, - * that the scsi code will be able to talk to the /proc/scsi handling - * in the procfs. - */ -extern int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start, - off_t offset, int length, int inout); -extern struct inode_operations proc_scsi_inode_operations; extern struct proc_dir_entry *proc_sys_root; #ifdef CONFIG_SYSCTL @@ -26,14 +18,6 @@ EXPORT_SYMBOL(proc_dir_inode_operations); EXPORT_SYMBOL(proc_net); EXPORT_SYMBOL(proc_bus); - -/* - * This is required so that if we load scsi later, that the - * scsi code can attach to /proc/scsi in the correct manner. - */ -EXPORT_SYMBOL(proc_scsi); -EXPORT_SYMBOL(proc_scsi_inode_operations); -EXPORT_SYMBOL(dispatch_scsi_info_ptr); #if defined(CONFIG_SUN_OPENPROMFS_MODULE) EXPORT_SYMBOL(proc_openprom_register); diff -u --recursive --new-file v2.3.26/linux/fs/proc/root.c linux/fs/proc/root.c --- v2.3.26/linux/fs/proc/root.c Mon Nov 1 13:56:27 1999 +++ linux/fs/proc/root.c Thu Nov 11 16:57:31 1999 @@ -22,11 +22,6 @@ #include #endif -/* - * Offset of the first process in the /proc root directory.. - */ -#define FIRST_PROCESS_ENTRY 256 - static int proc_root_readdir(struct file *, void *, filldir_t); static struct dentry *proc_root_lookup(struct inode *,struct dentry *); static int proc_unlink(struct inode *, struct dentry *); @@ -37,22 +32,12 @@ * These are the generic /proc directory operations. They * use the in-memory "struct proc_dir_entry" tree to parse * the /proc directory. - * - * NOTE! The /proc/scsi directory currently does not correctly - * build up the proc_dir_entry tree, and will show up empty. */ static struct file_operations proc_dir_operations = { NULL, /* lseek - default */ NULL, /* read - bad */ NULL, /* write - bad */ proc_readdir, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ }; /* @@ -62,23 +47,6 @@ &proc_dir_operations, /* default net directory file-ops */ NULL, /* create */ proc_lookup, /* 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 */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ }; /* @@ -90,21 +58,6 @@ proc_lookup, /* lookup */ NULL, /* link */ proc_unlink, /* unlink(struct inode *, struct dentry *) */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ }; /* @@ -117,13 +70,6 @@ NULL, /* read - bad */ NULL, /* write - bad */ proc_root_readdir, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* no fsync */ }; /* @@ -133,23 +79,6 @@ &proc_root_operations, /* default base directory file-ops */ NULL, /* create */ proc_root_lookup, /* 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 */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ }; /* @@ -164,8 +93,7 @@ &proc_root, NULL }; -struct proc_dir_entry *proc_net, *proc_scsi, *proc_bus, *proc_sysvipc, - *proc_root_fs, *proc_root_driver; +struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver; #ifdef CONFIG_MCA struct proc_dir_entry *proc_mca; @@ -268,36 +196,12 @@ NULL, /* read - bad */ NULL, /* write - bad */ OPENPROM_DEFREADDIR, /* readdir */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ }; struct inode_operations proc_openprom_inode_operations = { &proc_openprom_operations,/* default net directory file-ops */ NULL, /* create */ OPENPROM_DEFLOOKUP, /* 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 */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ }; struct proc_dir_entry proc_openprom = { @@ -321,6 +225,73 @@ return PROC_DYNAMIC_FIRST + i; } +int proc_readlink(struct dentry * dentry, char * buffer, int buflen) +{ + struct inode *inode = dentry->d_inode; + struct proc_dir_entry * de; + char *page; + int len = 0; + + de = (struct proc_dir_entry *) inode->u.generic_ip; + if (!de) + return -ENOENT; + if (!(page = (char*) __get_free_page(GFP_KERNEL))) + return -ENOMEM; + + if (de->readlink_proc) + len = de->readlink_proc(de, page); + + if (len > buflen) + len = buflen; + + copy_to_user(buffer, page, len); + free_page((unsigned long) page); + return len; +} + +struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow) +{ + struct inode *inode = dentry->d_inode; + struct proc_dir_entry * de; + char *page; + struct dentry *d; + int len = 0; + + de = (struct proc_dir_entry *) inode->u.generic_ip; + if (!(page = (char*) __get_free_page(GFP_KERNEL))) + return NULL; + + if (de->readlink_proc) + len = de->readlink_proc(de, page); + + d = lookup_dentry(page, base, follow); + free_page((unsigned long) page); + return d; +} + +static struct inode_operations proc_link_inode_operations = { + NULL, /* no file-ops */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + proc_readlink, /* readlink */ + proc_follow_link, /* follow_link */ + NULL, /* get_block */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* flushpage */ + NULL, /* truncate */ + NULL, /* permission */ + NULL, /* smap */ + NULL /* revalidate */ +}; + int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp) { int i; @@ -433,50 +404,6 @@ return lookup_dentry(tmp, base, follow); } -int proc_readlink(struct dentry * dentry, char * buffer, int buflen) -{ - struct inode *inode = dentry->d_inode; - struct proc_dir_entry * de; - char *page; - int len = 0; - - de = (struct proc_dir_entry *) inode->u.generic_ip; - if (!de) - return -ENOENT; - if (!(page = (char*) __get_free_page(GFP_KERNEL))) - return -ENOMEM; - - if (de->readlink_proc) - len = de->readlink_proc(de, page); - - if (len > buflen) - len = buflen; - - copy_to_user(buffer, page, len); - free_page((unsigned long) page); - return len; -} - -struct dentry * proc_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow) -{ - struct inode *inode = dentry->d_inode; - struct proc_dir_entry * de; - char *page; - struct dentry *d; - int len = 0; - - de = (struct proc_dir_entry *) inode->u.generic_ip; - if (!(page = (char*) __get_free_page(GFP_KERNEL))) - return NULL; - - if (de->readlink_proc) - len = de->readlink_proc(de, page); - - d = lookup_dentry(page, base, follow); - free_page((unsigned long) page); - return d; -} - static struct inode_operations proc_self_inode_operations = { NULL, /* no file-ops */ NULL, /* create */ @@ -500,29 +427,6 @@ NULL /* revalidate */ }; -static struct inode_operations proc_link_inode_operations = { - NULL, /* no file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - proc_readlink, /* readlink */ - proc_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; - static struct proc_dir_entry proc_root_self = { 0, 4, "self", S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, 1, 0, 0, @@ -533,21 +437,16 @@ 0, 8, "ppc_htab", S_IFREG | S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 1, 0, 0, 0, &proc_ppc_htab_inode_operations, - NULL, NULL, /* get_info, fill_inode */ - NULL, /* next */ - NULL, NULL /* parent, subdir */ }; #endif void __init proc_root_init(void) { - proc_base_init(); proc_misc_init(); proc_register(&proc_root, &proc_root_self); proc_net = create_proc_entry("net", S_IFDIR, 0); - proc_scsi = create_proc_entry("scsi", S_IFDIR, 0); #ifdef CONFIG_SYSVIPC - proc_sysvipc = create_proc_entry("sysvipc", S_IFDIR, 0); + create_proc_entry("sysvipc", S_IFDIR, 0); #endif #ifdef CONFIG_SYSCTL proc_sys_root = create_proc_entry("sys", S_IFDIR, 0); @@ -613,7 +512,7 @@ if (de->namelen != dentry->d_name.len) continue; if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { - int ino = de->low_ino | (dir->i_ino & ~(0xffff)); + int ino = de->low_ino; error = -EINVAL; inode = proc_get_inode(dir->i_sb, ino, de); break; @@ -631,11 +530,7 @@ static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry) { - unsigned int pid, c; struct task_struct *p; - const char *name; - struct inode *inode; - int len; if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */ extern unsigned long total_forks; @@ -666,40 +561,7 @@ if (!proc_lookup(dir, dentry)) return NULL; - pid = 0; - name = dentry->d_name.name; - len = dentry->d_name.len; - while (len-- > 0) { - c = *name - '0'; - name++; - if (c > 9) { - pid = 0; - break; - } - pid *= 10; - pid += c; - if (!pid) - break; - if (pid & 0xffff0000) { - pid = 0; - break; - } - } - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - read_unlock(&tasklist_lock); - inode = NULL; - if (pid && p) { - unsigned long ino = (pid << 16) + PROC_PID_INO; - inode = proc_get_inode(dir->i_sb, ino, &proc_pid); - if (!inode) - return ERR_PTR(-EINVAL); - inode->i_flags|=S_IMMUTABLE; - } - - dentry->d_op = &proc_dentry_operations; - d_add(dentry, inode); - return NULL; + return proc_pid_lookup(dir, dentry); } /* @@ -738,7 +600,6 @@ filp->f_pos++; /* fall through */ default: - ino &= ~0xffff; de = de->subdir; i -= 2; for (;;) { @@ -751,7 +612,7 @@ } do { - if (filldir(dirent, de->name, de->namelen, filp->f_pos, ino | de->low_ino) < 0) + if (filldir(dirent, de->name, de->namelen, filp->f_pos, de->low_ino) < 0) return 0; filp->f_pos++; de = de->next; @@ -760,69 +621,19 @@ return 1; } -#define PROC_NUMBUF 10 -#define PROC_MAXPIDS 20 - -/* - * Get a few pid's to return for filldir - we need to hold the - * tasklist lock while doing this, and we must release it before - * we actually do the filldir itself, so we use a temp buffer.. - */ -static int get_pid_list(int index, unsigned int *pids) -{ - struct task_struct *p; - int nr_pids = 0; - - index -= FIRST_PROCESS_ENTRY; - read_lock(&tasklist_lock); - for_each_task(p) { - int pid = p->pid; - if (!pid) - continue; - if (--index >= 0) - continue; - pids[nr_pids] = pid; - nr_pids++; - if (nr_pids >= PROC_MAXPIDS) - break; - } - read_unlock(&tasklist_lock); - return nr_pids; -} - static int proc_root_readdir(struct file * filp, void * dirent, filldir_t filldir) { - unsigned int pid_array[PROC_MAXPIDS]; - char buf[PROC_NUMBUF]; unsigned int nr = filp->f_pos; - unsigned int nr_pids, i; if (nr < FIRST_PROCESS_ENTRY) { int error = proc_readdir(filp, dirent, filldir); if (error <= 0) return error; - filp->f_pos = nr = FIRST_PROCESS_ENTRY; + filp->f_pos = FIRST_PROCESS_ENTRY; } - nr_pids = get_pid_list(nr, pid_array); - - for (i = 0; i < nr_pids; i++) { - int pid = pid_array[i]; - ino_t ino = (pid << 16) + PROC_PID_INO; - unsigned long j = PROC_NUMBUF; - - do { - j--; - buf[j] = '0' + (pid % 10); - pid /= 10; - } while (pid); - - if (filldir(dirent, buf+j, PROC_NUMBUF-j, filp->f_pos, ino) < 0) - break; - filp->f_pos++; - } - return 0; + return proc_pid_readdir(filp, dirent, filldir); } static int proc_unlink(struct inode *dir, struct dentry *dentry) diff -u --recursive --new-file v2.3.26/linux/fs/proc/scsi.c linux/fs/proc/scsi.c --- v2.3.26/linux/fs/proc/scsi.c Sat Jun 26 12:04:40 1999 +++ linux/fs/proc/scsi.c Wed Dec 31 16:00:00 1969 @@ -1,219 +0,0 @@ -/* - * linux/fs/proc/scsi.c - * (c) 1995 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de - * - * The original version was derived from linux/fs/proc/net.c, - * which is Copyright (C) 1991, 1992 Linus Torvalds. - * Much has been rewritten, but some of the code still remains. - * - * /proc/scsi directory handling functions - * - * last change: 95/07/04 - * - * Initial version: March '95 - * 95/05/15 Added subdirectories for each driver and show every - * registered HBA as a single file. - * 95/05/30 Added rudimentary write support for parameter passing - * 95/07/04 Fixed bugs in directory handling - * 95/09/13 Update to support the new proc-dir tree - * - * TODO: Improve support to write to the driver files - * Add some more comments - */ -#include -#include -#include -#include -#include - -#include - -/* forward references */ -static ssize_t proc_readscsi(struct file * file, char * buf, - size_t count, loff_t *ppos); -static ssize_t proc_writescsi(struct file * file, const char * buf, - size_t count, loff_t *ppos); -static long long proc_scsilseek(struct file *, long long, int); - -extern void build_proc_dir_hba_entries(uint); - -/* the *_get_info() functions are in the respective scsi driver code */ -int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start, - off_t offset, int length, int inout) = 0; - -static struct file_operations proc_scsi_operations = { - proc_scsilseek, /* lseek */ - proc_readscsi, /* read */ - proc_writescsi, /* write */ - proc_readdir, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* flush */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -/* - * proc directories can do almost nothing.. - */ -struct inode_operations proc_scsi_inode_operations = { -&proc_scsi_operations, /* default scsi directory file-ops */ - NULL, /* create */ - proc_lookup, /* 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 */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; - -int get_not_present_info(char *buffer, char **start, off_t offset, int length) -{ - int len, pos, begin; - - begin = 0; - pos = len = sprintf(buffer, - "No low-level scsi modules are currently present\n"); - if(pos < offset) { - len = 0; - begin = pos; - } - - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); - if(len > length) - len = length; - - return(len); -} - -#define PROC_BLOCK_SIZE (3*1024) /* 4K page size, but our output routines - * use some slack for overruns - */ - -static ssize_t proc_readscsi(struct file * file, char * buf, - size_t count, loff_t *ppos) -{ - struct inode * inode = file->f_dentry->d_inode; - ssize_t length; - ssize_t bytes = count; - ssize_t copied = 0; - ssize_t thistime; - char * page; - char * start; - - if (!(page = (char *) __get_free_page(GFP_KERNEL))) - return(-ENOMEM); - - while (bytes > 0) { - thistime = bytes; - if(bytes > PROC_BLOCK_SIZE) - thistime = PROC_BLOCK_SIZE; - - if(dispatch_scsi_info_ptr) - length = dispatch_scsi_info_ptr(inode->i_ino, page, &start, - *ppos, thistime, 0); - else - length = get_not_present_info(page, &start, *ppos, thistime); - if(length < 0) { - free_page((ulong) page); - return(length); - } - - /* - * We have been given a non page aligned block of - * the data we asked for + a bit. We have been given - * the start pointer and we know the length.. - */ - if (length <= 0) - break; - /* - * Copy the bytes - */ - copy_to_user(buf + copied, start, length); - *ppos += length; /* Move down the file */ - bytes -= length; - copied += length; - - if(length < thistime) - break; /* End of file */ - - } - - free_page((ulong) page); - return(copied); -} - - -static ssize_t proc_writescsi(struct file * file, const char * buf, - size_t count, loff_t *ppos) -{ - struct inode * inode = file->f_dentry->d_inode; - ssize_t ret = 0; - char * page; - - if(count > PROC_BLOCK_SIZE) { - return(-EOVERFLOW); - } - - if(dispatch_scsi_info_ptr != NULL) { - if (!(page = (char *) __get_free_page(GFP_KERNEL))) - return(-ENOMEM); - copy_from_user(page, buf, count); - ret = dispatch_scsi_info_ptr(inode->i_ino, page, 0, 0, count, 1); - } else - return(-ENOPKG); /* Nothing here */ - - free_page((ulong) page); - return(ret); -} - - -static long long proc_scsilseek(struct file * file, long long offset, int orig) -{ - switch (orig) { - case 0: - file->f_pos = offset; - return(file->f_pos); - case 1: - file->f_pos += offset; - return(file->f_pos); - case 2: - return(-EINVAL); - default: - return(-EINVAL); - } -} - -/* - * Overrides for Emacs so that we almost follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ diff -u --recursive --new-file v2.3.26/linux/fs/proc/sysvipc.c linux/fs/proc/sysvipc.c --- v2.3.26/linux/fs/proc/sysvipc.c Sat Jun 26 12:04:40 1999 +++ linux/fs/proc/sysvipc.c Wed Dec 31 16:00:00 1969 @@ -1,141 +0,0 @@ -/* - * linux/fs/proc/sysvipc.c - * - * Copyright (c) 1999 Dragos Acostachioaie - * - * This code is derived from linux/fs/proc/generic.c, - * which is Copyright (C) 1991, 1992 Linus Torvalds. - * - * /proc/sysvipc directory handling functions - */ -#include -#include -#include -#include -#include - -#include - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -/* 4K page size but our output routines use some slack for overruns */ -#define PROC_BLOCK_SIZE (3*1024) - -static ssize_t -proc_sysvipc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) -{ - struct inode * inode = file->f_dentry->d_inode; - char *page; - ssize_t retval=0; - int eof=0; - ssize_t n, count; - char *start; - struct proc_dir_entry * dp; - - dp = (struct proc_dir_entry *) inode->u.generic_ip; - if (!(page = (char*) __get_free_page(GFP_KERNEL))) - return -ENOMEM; - - while ((nbytes > 0) && !eof) - { - count = MIN(PROC_BLOCK_SIZE, nbytes); - - start = NULL; - if (dp->get_info) { - /* - * Handle backwards compatibility with the old net - * routines. - * - * XXX What gives with the file->f_flags & O_ACCMODE - * test? Seems stupid to me.... - */ - n = dp->get_info(page, &start, *ppos, count, - (file->f_flags & O_ACCMODE) == O_RDWR); - if (n < count) - eof = 1; - } else if (dp->read_proc) { - n = dp->read_proc(page, &start, *ppos, - count, &eof, dp->data); - } else - break; - - if (!start) { - /* - * For proc files that are less than 4k - */ - start = page + *ppos; - n -= *ppos; - if (n <= 0) - break; - if (n > count) - n = count; - } - if (n == 0) - break; /* End of file */ - if (n < 0) { - if (retval == 0) - retval = n; - break; - } - - /* This is a hack to allow mangling of file pos independent - * of actual bytes read. Simply place the data at page, - * return the bytes, and set `start' to the desired offset - * as an unsigned int. - Paul.Russell@rustcorp.com.au - */ - n -= copy_to_user(buf, start < page ? page : start, n); - if (n == 0) { - if (retval == 0) - retval = -EFAULT; - break; - } - - *ppos += start < page ? (long)start : n; /* Move down the file */ - nbytes -= n; - buf += n; - retval += n; - } - free_page((unsigned long) page); - return retval; -} - -static struct file_operations proc_sysvipc_operations = { - NULL, /* lseek */ - proc_sysvipc_read, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - NULL /* can't fsync */ -}; - -/* - * proc directories can do almost nothing.. - */ -struct inode_operations proc_sysvipc_inode_operations = { - &proc_sysvipc_operations, /* default net file-ops */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - NULL, /* readlink */ - NULL, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ -}; diff -u --recursive --new-file v2.3.26/linux/fs/romfs/inode.c linux/fs/romfs/inode.c --- v2.3.26/linux/fs/romfs/inode.c Wed Oct 27 16:34:12 1999 +++ linux/fs/romfs/inode.c Tue Nov 9 10:04:29 1999 @@ -34,6 +34,21 @@ * exposed a problem in readdir * 2.1.107 code-freeze spellchecker run * Aug 1998 2.1.118+ VFS changes + * Sep 1998 2.1.122 another VFS change (follow_link) + * Apr 1999 2.2.7 no more EBADF checking in + * lookup/readdir, use ERR_PTR + * Jun 1999 2.3.6 d_alloc_root use changed + * 2.3.9 clean up usage of ENOENT/negative + * dentries in lookup + * clean up page flags setting + * (error, uptodate, locking) in + * in readpage + * use init_special_inode for + * fifos/sockets (and streamline) in + * read_inode, fix _ops table order + * Aug 1999 2.3.16 __initfunc() => __init change + * Oct 1999 2.3.24 page->owner hack obsoleted + * Nov 1999 2.3.27 2.3.25+ page->offset => index change */ /* todo: @@ -404,7 +419,8 @@ get_page(page); buf = page_address(page); - offset = page->offset; + /* 32 bit warning -- but not for us :) */ + offset = page->index << PAGE_CACHE_SHIFT; if (offset < inode->i_size) { avail = inode->i_size-offset; readlen = min(avail, PAGE_SIZE); diff -u --recursive --new-file v2.3.26/linux/fs/udf/misc.c linux/fs/udf/misc.c --- v2.3.26/linux/fs/udf/misc.c Mon Nov 1 13:56:27 1999 +++ linux/fs/udf/misc.c Wed Nov 10 10:00:48 1999 @@ -24,11 +24,10 @@ * 04/19/99 blf partial support for reading/writing specific EA's */ +#include "udfdecl.h" #if defined(__linux__) && defined(__KERNEL__) -#include "udfdecl.h" - #include "udf_sb.h" #include "udf_i.h" @@ -38,7 +37,6 @@ #else -#include "udfdecl.h" #include #include #include diff -u --recursive --new-file v2.3.26/linux/fs/udf/udfdecl.h linux/fs/udf/udfdecl.h --- v2.3.26/linux/fs/udf/udfdecl.h Mon Nov 1 13:56:27 1999 +++ linux/fs/udf/udfdecl.h Thu Nov 11 10:07:21 1999 @@ -3,10 +3,11 @@ #define UDF_VERSION_NOTICE "v0.8.9.3" +#include + #ifdef __KERNEL__ #include -#include #include #include @@ -18,16 +19,14 @@ #error "The UDF Module Current Requires Kernel Version 2.3.7 or greater" #endif +#include /* if we're not defined, we must be compiling outside of the kernel tree */ #if !defined(CONFIG_UDF_FS) && !defined(CONFIG_UDF_FS_MODULE) /* ... so override config */ #define CONFIG_UDF_FS_MODULE -#include /* explicitly include udf_fs_sb.h and udf_fs_i.h */ #include #include -#else -#include /* also gets udf_fs_i.h and udf_fs_sb.h */ #endif struct dentry; @@ -113,7 +112,6 @@ #else #include -#include #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.3.26/linux/fs/ufs/balloc.c linux/fs/ufs/balloc.c --- v2.3.26/linux/fs/ufs/balloc.c Mon Jul 5 19:59:55 1999 +++ linux/fs/ufs/balloc.c Thu Nov 11 10:07:21 1999 @@ -676,7 +676,7 @@ else start = ucpi->c_frotor >> 3; - length = howmany(uspi->s_fpg, 8) - start; + length = ((uspi->s_fpg + 7) >> 3) - start; location = ubh_scanc(UCPI_UBH, ucpi->c_freeoff + start, length, (uspi->s_fpb == 8) ? ufs_fragtable_8fpb : ufs_fragtable_other, 1 << (count - 1 + (uspi->s_fpb & 7))); diff -u --recursive --new-file v2.3.26/linux/fs/ufs/dir.c linux/fs/ufs/dir.c --- v2.3.26/linux/fs/ufs/dir.c Sun Jun 27 10:10:41 1999 +++ linux/fs/ufs/dir.c Thu Nov 11 10:07:21 1999 @@ -168,7 +168,7 @@ error_msg = "inode out of bounds"; if (error_msg != NULL) - ufs_error (sb, function, "bad entry in directory #%lu, size %lu: %s - " + ufs_error (sb, function, "bad entry in directory #%lu, size %Lu: %s - " "offset=%lu, inode=%lu, reclen=%d, namlen=%d", dir->i_ino, dir->i_size, error_msg, offset, (unsigned long) SWAB32(de->d_ino), diff -u --recursive --new-file v2.3.26/linux/fs/ufs/inode.c linux/fs/ufs/inode.c --- v2.3.26/linux/fs/ufs/inode.c Sun Jun 27 10:10:41 1999 +++ linux/fs/ufs/inode.c Thu Nov 11 10:07:21 1999 @@ -610,7 +610,7 @@ inode->u.ufs_i.i_gen = SWAB32(ufs_inode->ui_gen); inode->u.ufs_i.i_shadow = SWAB32(ufs_inode->ui_u3.ui_sun.ui_shadow); inode->u.ufs_i.i_oeftflag = SWAB32(ufs_inode->ui_u3.ui_sun.ui_oeftflag); - inode->u.ufs_i.i_lastfrag = howmany (inode->i_size, uspi->s_fsize); + inode->u.ufs_i.i_lastfrag = (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) ; diff -u --recursive --new-file v2.3.26/linux/fs/ufs/super.c linux/fs/ufs/super.c --- v2.3.26/linux/fs/ufs/super.c Tue Aug 31 17:29:14 1999 +++ linux/fs/ufs/super.c Thu Nov 11 10:07:21 1999 @@ -328,7 +328,7 @@ * on the device. */ size = uspi->s_cssize; - blks = howmany(size, uspi->s_fsize); + blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; base = space = kmalloc(size, GFP_KERNEL); if (!base) goto failed; @@ -405,7 +405,7 @@ uspi = sb->u.ufs_sb.s_uspi; size = uspi->s_cssize; - blks = howmany(size, uspi->s_fsize); + blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; base = space = (char*) sb->u.ufs_sb.s_csp[0]; for (i = 0; i < blks; i += uspi->s_fpb) { size = uspi->s_bsize; diff -u --recursive --new-file v2.3.26/linux/fs/ufs/truncate.c linux/fs/ufs/truncate.c --- v2.3.26/linux/fs/ufs/truncate.c Wed Aug 18 10:15:19 1999 +++ linux/fs/ufs/truncate.c Thu Nov 11 10:07:21 1999 @@ -59,8 +59,8 @@ * Linus */ -#define DIRECT_BLOCK howmany (inode->i_size, uspi->s_bsize) -#define DIRECT_FRAGMENT howmany (inode->i_size, uspi->s_fsize) +#define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift) +#define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift) #define DATA_BUFFER_USED(bh) \ (atomic_read(&bh->b_count) || buffer_locked(bh)) @@ -312,7 +312,7 @@ uspi = sb->u.ufs_sb.s_uspi; dindirect_block = (DIRECT_BLOCK > offset) - ? ((DIRECT_BLOCK - offset) / uspi->s_apb) : 0; + ? ((DIRECT_BLOCK - offset) >> uspi->s_apbshift) : 0; retry = 0; tmp = SWAB32(*p); @@ -382,7 +382,7 @@ retry = 0; tindirect_block = (DIRECT_BLOCK > (UFS_NDADDR + uspi->s_apb + uspi->s_2apb)) - ? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) / uspi->s_2apb) : 0; + ? ((DIRECT_BLOCK - UFS_NDADDR - uspi->s_apb - uspi->s_2apb) >> uspi->s_2apbshift) : 0; p = inode->u.ufs_i.i_u1.i_data + UFS_TIND_BLOCK; if (!(tmp = SWAB32(*p))) return 0; @@ -471,7 +471,7 @@ } } inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->u.ufs_i.i_lastfrag = howmany (inode->i_size, uspi->s_fsize); + inode->u.ufs_i.i_lastfrag = DIRECT_FRAGMENT; mark_inode_dirty(inode); UFSD(("EXIT\n")) } diff -u --recursive --new-file v2.3.26/linux/fs/ufs/util.h linux/fs/ufs/util.h --- v2.3.26/linux/fs/ufs/util.h Mon Apr 12 09:53:45 1999 +++ linux/fs/ufs/util.h Thu Nov 11 10:07:21 1999 @@ -14,7 +14,6 @@ * some useful macros */ #define in_range(b,first,len) ((b)>=(first)&&(b)<(first)+(len)) -#define howmany(x,y) (((x)+(y)-1)/(y)) #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) diff -u --recursive --new-file v2.3.26/linux/include/asm-alpha/div64.h linux/include/asm-alpha/div64.h --- v2.3.26/linux/include/asm-alpha/div64.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/div64.h Mon Nov 8 16:01:59 1999 @@ -0,0 +1,14 @@ +#ifndef __ALPHA_DIV64 +#define __ALPHA_DIV64 + +/* + * Hey, we're already 64-bit, no + * need to play games.. + */ +#define do_div(n,base) ({ \ + int __res; \ + __res = ((unsigned long) n) % (unsigned) base; \ + n = ((unsigned long) n) / (unsigned) base; \ + __res; }) + +#endif diff -u --recursive --new-file v2.3.26/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v2.3.26/linux/include/asm-alpha/processor.h Fri Oct 15 15:25:14 1999 +++ linux/include/asm-alpha/processor.h Mon Nov 8 14:28:34 1999 @@ -126,6 +126,16 @@ #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) +unsigned long get_wchan(struct task_struct *p); +/* +* See arch/alpha/kernel/ptrace.c for details. +*/ +#define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \ + + (long)&((struct pt_regs *)0)->reg) +#define KSTK_EIP(tsk) \ + (*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk))) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + /* NOTE: The task struct and the stack go together! */ #define alloc_task_struct() \ ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) diff -u --recursive --new-file v2.3.26/linux/include/asm-arm/processor.h linux/include/asm-arm/processor.h --- v2.3.26/linux/include/asm-arm/processor.h Fri Oct 22 13:21:53 1999 +++ linux/include/asm-arm/processor.h Mon Nov 8 14:28:34 1999 @@ -107,6 +107,16 @@ #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) +unsigned long get_wchan(struct task_struct *p); + +#ifdef CONFIG_CPU_26 +# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) +# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020]) +#else +# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1021]) +# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) +#endif + extern struct task_struct *alloc_task_struct(void); extern void free_task_struct(struct task_struct *); diff -u --recursive --new-file v2.3.26/linux/include/asm-i386/div64.h linux/include/asm-i386/div64.h --- v2.3.26/linux/include/asm-i386/div64.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-i386/div64.h Mon Nov 8 15:58:38 1999 @@ -0,0 +1,17 @@ +#ifndef __I386_DIV64 +#define __I386_DIV64 + +#define do_div(n,base) ({ \ + unsigned long __upper, __low, __high, __mod; \ + asm("":"=a" (__low), "=d" (__high):"A" (n)); \ + __upper = __high; \ + if (__high) { \ + __upper = __high % (base); \ + __high = __high / (base); \ + } \ + asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (base), "0" (__low), "1" (__upper)); \ + asm("":"=A" (n):"a" (__low),"d" (__high)); \ + __mod; \ +}) + +#endif diff -u --recursive --new-file v2.3.26/linux/include/asm-i386/highmem.h linux/include/asm-i386/highmem.h --- v2.3.26/linux/include/asm-i386/highmem.h Fri Oct 22 13:21:53 1999 +++ linux/include/asm-i386/highmem.h Thu Nov 11 17:02:09 1999 @@ -18,7 +18,12 @@ #ifndef _ASM_HIGHMEM_H #define _ASM_HIGHMEM_H +#ifdef __KERNEL__ + #include +#include +#include +#include /* undef for production */ #define HIGHMEM_DEBUG 1 @@ -28,58 +33,79 @@ extern pte_t *kmap_pte; extern pgprot_t kmap_prot; +extern pte_t *pkmap_page_table; extern void kmap_init(void) __init; -/* kmap helper functions necessary to access the highmem pages in kernel */ -#include -#include +#define PKMAP_BASE (0xff000000UL) + +extern unsigned long FASTCALL(kmap_high(struct page *page)); +extern void FASTCALL(kunmap_high(struct page *page)); -extern inline unsigned long kmap(struct page *page, enum km_type type) +extern inline unsigned long kmap(struct page *page) { + if (in_interrupt()) + BUG(); 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 kmap_high(page); +} - return vaddr; - } +extern inline void kunmap(struct page *page) +{ + if (in_interrupt()) + BUG(); + if (page < highmem_start_page) + return; + kunmap_high(page); } -extern inline void kunmap(unsigned long vaddr, enum km_type type) +/* + * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap + * gives a more generic (and caching) interface. But kmap_atomic can + * be used in IRQ contexts, so in some (very limited) cases we need + * it. + */ +extern inline unsigned long kmap_atomic(struct page *page, enum km_type type) { + enum fixed_addresses idx; + unsigned long vaddr; + + if (page < highmem_start_page) + return page_address(page); + + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #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); - } + if (!pte_none(*(kmap_pte-idx))) + BUG(); #endif + set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + __flush_tlb_one(vaddr); + + return vaddr; } -extern inline void kmap_check(void) +extern inline void kunmap_atomic(unsigned long vaddr, enum km_type type) { #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(); + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); + + if (vaddr < FIXADDR_START) // FIXME + return; + + if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) + BUG(); + + /* + * 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 } + +#endif /* __KERNEL__ */ + #endif /* _ASM_HIGHMEM_H */ diff -u --recursive --new-file v2.3.26/linux/include/asm-i386/io.h linux/include/asm-i386/io.h --- v2.3.26/linux/include/asm-i386/io.h Mon Nov 1 13:56:27 1999 +++ linux/include/asm-i386/io.h Thu Nov 11 17:02:20 1999 @@ -103,9 +103,8 @@ #ifdef __KERNEL__ -#include -#include #include +#include /* * Temporary debugging check to catch old code using diff -u --recursive --new-file v2.3.26/linux/include/asm-i386/kmap_types.h linux/include/asm-i386/kmap_types.h --- v2.3.26/linux/include/asm-i386/kmap_types.h Tue Aug 31 17:29:14 1999 +++ linux/include/asm-i386/kmap_types.h Thu Nov 11 10:33:42 1999 @@ -2,9 +2,9 @@ #define _ASM_KMAP_TYPES_H enum km_type { - KM_READ, - KM_WRITE, - KM_TYPE_NR, + KM_BOUNCE_READ, + KM_BOUNCE_WRITE, + KM_TYPE_NR }; #endif diff -u --recursive --new-file v2.3.26/linux/include/asm-i386/processor.h linux/include/asm-i386/processor.h --- v2.3.26/linux/include/asm-i386/processor.h Wed Oct 27 16:34:12 1999 +++ linux/include/asm-i386/processor.h Thu Nov 11 17:02:06 1999 @@ -406,6 +406,10 @@ return ((unsigned long *)t->esp)[3]; } +unsigned long get_wchan(struct task_struct *p); +#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) +#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) + #define THREAD_SIZE (2*PAGE_SIZE) #define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) #define free_task_struct(p) free_pages((unsigned long) (p), 1) diff -u --recursive --new-file v2.3.26/linux/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h --- v2.3.26/linux/include/asm-m68k/processor.h Tue Sep 7 12:14:07 1999 +++ linux/include/asm-m68k/processor.h Mon Nov 8 14:28:34 1999 @@ -134,6 +134,17 @@ return sw->retpc; } +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) \ + ({ \ + unsigned long eip = 0; \ + if ((tsk)->thread.esp0 > PAGE_SIZE && \ + MAP_NR((tsk)->thread.esp0) < max_mapnr) \ + eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \ + eip; }) +#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp) + #define THREAD_SIZE (2*PAGE_SIZE) /* Allocation and freeing of basic task resources. */ diff -u --recursive --new-file v2.3.26/linux/include/asm-mips/processor.h linux/include/asm-mips/processor.h --- v2.3.26/linux/include/asm-mips/processor.h Mon Jul 19 13:12:47 1999 +++ linux/include/asm-mips/processor.h Mon Nov 8 14:28:34 1999 @@ -206,6 +206,14 @@ */ extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); +unsigned long get_wchan(struct task_struct *p); + +#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg \ + - sizeof(struct pt_regs)) +#define KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32) +#define KSTK_EIP(tsk) (*(unsigned long *)(KSTK_TOS(tsk) + PT_REG(cp0_epc))) +#define KSTK_ESP(tsk) (*(unsigned long *)(KSTK_TOS(tsk) + PT_REG(regs[29]))) + /* Allocation and freeing of basic task resources. */ /* * NOTE! The task struct and the stack go together diff -u --recursive --new-file v2.3.26/linux/include/asm-ppc/div64.h linux/include/asm-ppc/div64.h --- v2.3.26/linux/include/asm-ppc/div64.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-ppc/div64.h Wed Nov 10 10:55:31 1999 @@ -0,0 +1,10 @@ +#ifndef __PPC_DIV64 +#define __PPC_DIV64 + +#define do_div(n,base) ({ \ +int __res; \ +__res = ((unsigned long) n) % (unsigned) base; \ +n = ((unsigned long) n) / (unsigned) base; \ +__res; }) + +#endif diff -u --recursive --new-file v2.3.26/linux/include/asm-ppc/fcntl.h linux/include/asm-ppc/fcntl.h --- v2.3.26/linux/include/asm-ppc/fcntl.h Wed Oct 21 13:31:06 1998 +++ linux/include/asm-ppc/fcntl.h Thu Nov 11 15:59:26 1999 @@ -3,21 +3,23 @@ /* open/fcntl - O_SYNC is only implemented on blocks devices and on files located on an ext2 file system */ -#define O_ACCMODE 0003 -#define O_RDONLY 00 -#define O_WRONLY 01 -#define O_RDWR 02 -#define O_CREAT 0100 /* not fcntl */ -#define O_EXCL 0200 /* not fcntl */ -#define O_NOCTTY 0400 /* not fcntl */ -#define O_TRUNC 01000 /* not fcntl */ -#define O_APPEND 02000 -#define O_NONBLOCK 04000 +#define O_ACCMODE 0003 +#define O_RDONLY 00 +#define O_WRONLY 01 +#define O_RDWR 02 +#define O_CREAT 0100 /* not fcntl */ +#define O_EXCL 0200 /* not fcntl */ +#define O_NOCTTY 0400 /* not fcntl */ +#define O_TRUNC 01000 /* not fcntl */ +#define O_APPEND 02000 +#define O_NONBLOCK 04000 #define O_NDELAY O_NONBLOCK -#define O_SYNC 010000 -#define FASYNC 020000 /* fcntl, for BSD compatibility */ -#define O_DIRECTORY 040000 /* must be a directory */ -#define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_SYNC 010000 +#define FASYNC 020000 /* fcntl, for BSD compatibility */ +#define O_DIRECTORY 040000 /* must be a directory */ +#define O_NOFOLLOW 0100000 /* don't follow links */ +#define O_LARGEFILE 0200000 +#define O_DIRECT 0400000 /* direct disk access hint - currently ignored */ #define F_DUPFD 0 /* dup */ #define F_GETFD 1 /* get f_flags */ diff -u --recursive --new-file v2.3.26/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h --- v2.3.26/linux/include/asm-ppc/processor.h Sun Nov 7 16:37:34 1999 +++ linux/include/asm-ppc/processor.h Wed Nov 10 10:55:31 1999 @@ -316,6 +316,11 @@ #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) ((tsk)->thread.regs->nip) +#define KSTK_ESP(tsk) ((tsk)->thread.regs->gpr[1]) + /* * NOTE! The task struct and the stack go together */ diff -u --recursive --new-file v2.3.26/linux/include/asm-sh/processor.h linux/include/asm-sh/processor.h --- v2.3.26/linux/include/asm-sh/processor.h Wed Oct 27 16:34:12 1999 +++ linux/include/asm-sh/processor.h Mon Nov 8 10:19:19 1999 @@ -189,6 +189,17 @@ return t->pc; } +static inline unsigned long get_wchan(struct task_struct *p) +{ + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + /* FIXME: here the actual wchan calculation should sit */ + return 0; +} + +#define KSTK_EIP(tsk) ((tsk)->thread.pc) +#define KSTK_ESP(tsk) ((tsk)->thread.sp) + #define THREAD_SIZE (2*PAGE_SIZE) extern struct task_struct * alloc_task_struct(void); extern void free_task_struct(struct task_struct *); diff -u --recursive --new-file v2.3.26/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h --- v2.3.26/linux/include/asm-sparc/processor.h Tue Aug 31 17:29:14 1999 +++ linux/include/asm-sparc/processor.h Mon Nov 8 14:28:34 1999 @@ -161,6 +161,11 @@ #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) ((tsk)->thread.kregs->pc) +#define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP]) + #ifdef __KERNEL__ #define THREAD_SIZE (2*PAGE_SIZE) diff -u --recursive --new-file v2.3.26/linux/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h --- v2.3.26/linux/include/asm-sparc64/processor.h Wed Aug 4 15:39:46 1999 +++ linux/include/asm-sparc64/processor.h Mon Nov 8 14:28:34 1999 @@ -209,6 +209,11 @@ #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) +unsigned long get_wchan(struct task_struct *p); + +#define KSTK_EIP(tsk) ((tsk)->thread.kregs->tpc) +#define KSTK_ESP(tsk) ((tsk)->thread.kregs->u_regs[UREG_FP]) + #ifdef __KERNEL__ #define THREAD_SIZE (2*PAGE_SIZE) /* Allocation and freeing of task_struct and kernel stack. */ diff -u --recursive --new-file v2.3.26/linux/include/linux/acpi.h linux/include/linux/acpi.h --- v2.3.26/linux/include/linux/acpi.h Mon Nov 1 13:56:27 1999 +++ linux/include/linux/acpi.h Thu Nov 11 17:03:57 1999 @@ -24,6 +24,158 @@ #include #include +#ifdef __KERNEL__ + +#include +#include + +/* + * Device types + */ +enum +{ + ACPI_SYS_DEV, /* system device (fan, KB controller, ...) */ + ACPI_PCI_DEV, /* generic PCI device */ + ACPI_PCI_BUS, /* PCI bus */ + ACPI_ISA_DEV, /* generic ISA device */ + ACPI_ISA_BUS, /* ISA bus */ + ACPI_USB_DEV, /* generic USB device */ + ACPI_USB_HUB, /* USB hub device */ + ACPI_USB_CTRL, /* USB controller */ + ACPI_SCSI_DEV, /* generic SCSI device */ + ACPI_SCSI_CTRL, /* SCSI controller */ +}; + +typedef int acpi_dev_t; + +/* + * Device addresses + */ +#define ACPI_PCI_ADR(dev) ((dev)->bus->number << 16 | (dev)->devfn) + +/* + * HID (PnP) values + */ +enum +{ + ACPI_UNKNOWN_HID = 0x00000000, /* generic */ + ACPI_KBC_HID = 0x41d00303, /* keyboard controller */ + ACPI_COM_HID = 0x41d00500, /* serial port */ + ACPI_FDC_HID = 0x41d00700, /* floppy controller */ + ACPI_VGA_HID = 0x41d00900, /* VGA controller */ + ACPI_ISA_HID = 0x41d00a00, /* ISA bus */ + ACPI_EISA_HID = 0x41d00a01, /* EISA bus */ + ACPI_PCI_HID = 0x41d00a03, /* PCI bus */ +}; + +typedef int acpi_hid_t; + +/* + * Device states + */ +enum +{ + ACPI_D0, /* fully-on */ + ACPI_D1, /* partial-on */ + ACPI_D2, /* partial-on */ + ACPI_D3, /* fully-off */ +}; + +typedef int acpi_dstate_t; + +struct acpi_dev; + +/* + * Device state transition function + */ +typedef int (*acpi_transition)(struct acpi_dev *dev, acpi_dstate_t state); + +/* + * Static device information + */ +struct acpi_dev_info +{ + acpi_dev_t type; /* device type */ + acpi_hid_t hid; /* PnP identifier */ + acpi_transition transition; /* state transition callback */ + + /* other information like D-states supported, + * D-state latencies, and in-rush current needs + * will go here + */ +}; + +/* + * Dynamic device information + */ +struct acpi_dev +{ + struct acpi_dev_info info; /* static device info */ + unsigned long adr; /* bus address or unique id */ + acpi_dstate_t state; /* current D-state */ + unsigned long accessed; /* last access time */ + unsigned long idle; /* last idle time */ + struct list_head entry; /* linked list entry */ +}; + +#ifdef CONFIG_ACPI + +extern wait_queue_head_t acpi_idle_wait; + +/* + * Register a device with the ACPI subsystem + */ +struct acpi_dev *acpi_register(struct acpi_dev_info *info, unsigned long adr); + +/* + * Unregister a device with ACPI + */ +void acpi_unregister(struct acpi_dev *dev); + +/* + * Update device access time and wake up device, if necessary + */ +extern inline void acpi_access(struct acpi_dev *dev) +{ + extern void acpi_wakeup(struct acpi_dev*); + if (dev) { + if (dev->state != ACPI_D0) + acpi_wakeup(dev); + dev->accessed = jiffies; + } +} + +/* + * Identify device as currently being idle + */ +extern inline void acpi_dev_idle(struct acpi_dev *dev) +{ + if (dev) { + dev->idle = jiffies; + if (waitqueue_active(&acpi_idle_wait)) + wake_up(&acpi_idle_wait); + } +} + +#else /* CONFIG_ACPI */ + +extern inline struct acpi_dev* +acpi_register(struct acpi_dev_info *info, unsigned long adr) +{ + return 0; +} + +extern inline void acpi_unregister(struct acpi_dev *dev) {} +extern inline void acpi_access(struct acpi_dev *dev) {} +extern inline void acpi_dev_idle(struct acpi_dev *dev) {} + +#endif /* CONFIG_ACPI */ + +extern void (*acpi_idle)(void); +extern void (*acpi_power_off)(void); + +#endif /* __KERNEL__ */ + /* RSDP location */ #define ACPI_BIOS_ROM_BASE (0x0e0000) #define ACPI_BIOS_ROM_END (0x100000) @@ -34,6 +186,7 @@ #define ACPI_RSDT_SIG 0x54445352 /* 'RSDT' */ #define ACPI_FACP_SIG 0x50434146 /* 'FACP' */ #define ACPI_DSDT_SIG 0x54445344 /* 'DSDT' */ +#define ACPI_FACS_SIG 0x53434146 /* 'FACS' */ /* PM1_STS/EN flags */ #define ACPI_TMR 0x0001 @@ -94,7 +247,7 @@ __u8 oem[6]; __u8 reserved; __u32 rsdt; -}; +} __attribute__ ((packed)); struct acpi_table { __u32 signature; @@ -106,7 +259,7 @@ __u32 oem_rev; __u32 creator; __u32 creator_rev; -}; +} __attribute__ ((packed)); struct acpi_facp { struct acpi_table hdr; @@ -149,7 +302,7 @@ __u8 reserved5; __u8 reserved6; __u32 flags; -}; +} __attribute__ ((packed)); struct acpi_facs { __u32 signature; @@ -158,7 +311,7 @@ __u32 fw_wake_vector; __u32 global_lock; __u32 flags; -}; +} __attribute__ ((packed)); /* * Sysctl declarations @@ -181,7 +334,7 @@ ACPI_P_LVL3, ACPI_P_LVL2_LAT, ACPI_P_LVL3_LAT, - ACPI_S5_SLP_TYP + ACPI_S5_SLP_TYP, }; #define ACPI_P_LVL_DISABLED 0x80 @@ -223,12 +376,5 @@ #define ACPI_PIIX4_PMREGMISC 0x80 #define ACPI_PIIX4_PMIOSE 0x01 - -#ifdef __KERNEL__ - -extern void (*acpi_idle)(void); -extern void (*acpi_power_off)(void); - -#endif #endif /* _LINUX_ACPI_H */ diff -u --recursive --new-file v2.3.26/linux/include/linux/bootmem.h linux/include/linux/bootmem.h --- v2.3.26/linux/include/linux/bootmem.h Fri Oct 22 13:21:55 1999 +++ linux/include/linux/bootmem.h Thu Nov 11 17:03:07 1999 @@ -1,7 +1,6 @@ #ifndef _LINUX_BOOTMEM_H #define _LINUX_BOOTMEM_H -#include #include #include diff -u --recursive --new-file v2.3.26/linux/include/linux/concap.h linux/include/linux/concap.h --- v2.3.26/linux/include/linux/concap.h Thu Aug 26 13:05:41 1999 +++ linux/include/linux/concap.h Sun Nov 7 16:34:00 1999 @@ -5,7 +5,6 @@ #ifdef __KERNEL__ #include #include -#include /* Stuff to support encapsulation protocols genericly. The encapsulation protocol is processed at the uppermost layer of the network interface. diff -u --recursive --new-file v2.3.26/linux/include/linux/fs.h linux/include/linux/fs.h --- v2.3.26/linux/include/linux/fs.h Sun Nov 7 16:37:34 1999 +++ linux/include/linux/fs.h Thu Nov 11 17:02:09 1999 @@ -224,7 +224,8 @@ struct buffer_head *b_reqnext; /* request queue */ struct buffer_head **b_pprev; /* doubly linked list of hash-queue */ - char *b_data; /* pointer to data block (1024 bytes) */ + char * b_data; /* pointer to data block (512 byte) */ + struct page *b_page; /* the page this bh is mapped to */ void (*b_end_io)(struct buffer_head *bh, int uptodate); /* I/O completion */ void *b_dev_id; @@ -246,8 +247,11 @@ #define buffer_new(bh) __buffer_state(bh,New) #define buffer_protected(bh) __buffer_state(bh,Protected) -#define buffer_page(bh) (mem_map + MAP_NR((bh)->b_data)) -#define touch_buffer(bh) set_bit(PG_referenced, &buffer_page(bh)->flags) +#define bh_offset(bh) ((unsigned long)(bh)->b_data & ~PAGE_MASK) + +extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned int offset); + +#define touch_buffer(bh) set_bit(PG_referenced, &bh->b_page->flags) #include #include @@ -271,6 +275,7 @@ #include #include #include +#include /* * Attribute flags. These should be or-ed together to figure out what @@ -395,6 +400,7 @@ struct bfs_inode_info bfs_i; struct udf_inode_info udf_i; struct ncp_inode_info ncpfs_i; + struct proc_inode_info proc_i; struct socket socket_i; void *generic_ip; } u; @@ -933,6 +939,7 @@ extern unsigned int get_hardblocksize(kdev_t); extern struct buffer_head * bread(kdev_t, int, int); extern struct buffer_head * breada(kdev_t, int, int, unsigned int, unsigned int); +extern void wakeup_bdflush(int wait); extern int brw_page(int, struct page *, kdev_t, int [], int); diff -u --recursive --new-file v2.3.26/linux/include/linux/highmem.h linux/include/linux/highmem.h --- v2.3.26/linux/include/linux/highmem.h Sun Nov 7 16:37:34 1999 +++ linux/include/linux/highmem.h Thu Nov 11 17:02:56 1999 @@ -13,18 +13,19 @@ /* declarations for linux/mm/highmem.c */ extern unsigned long highmem_mapnr; -extern unsigned long nr_free_highpages; +FASTCALL(unsigned int nr_free_highpages(void)); extern struct page * prepare_highmem_swapout(struct page *); extern struct page * replace_with_highmem(struct page *); +extern struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig); #else /* CONFIG_HIGHMEM */ +extern inline unsigned int nr_free_highpages(void) { return 0; } #define prepare_highmem_swapout(page) page #define replace_with_highmem(page) page -#define kmap(page, type) page_address(page) -#define kunmap(vaddr, type) do { } while (0) -#define nr_free_highpages 0UL +#define kmap(page) page_address(page) +#define kunmap(page) do { } while (0) #endif /* CONFIG_HIGHMEM */ @@ -33,9 +34,9 @@ { unsigned long kaddr; - kaddr = kmap(page, KM_WRITE); + kaddr = kmap(page); clear_page((void *)kaddr); - kunmap(kaddr, KM_WRITE); + kunmap(page); } extern inline void memclear_highpage(struct page *page, unsigned int offset, unsigned int size) @@ -44,9 +45,9 @@ if (offset + size > PAGE_SIZE) BUG(); - kaddr = kmap(page, KM_WRITE); + kaddr = kmap(page); memset((void *)(kaddr + offset), 0, size); - kunmap(kaddr, KM_WRITE); + kunmap(page); } /* @@ -58,21 +59,21 @@ if (offset + size > PAGE_SIZE) BUG(); - kaddr = kmap(page, KM_WRITE); + kaddr = kmap(page); memset((void *)(kaddr + offset), 0, size); flush_page_to_ram(page); - kunmap(kaddr, KM_WRITE); + kunmap(page); } extern inline void copy_highpage(struct page *to, struct page *from) { unsigned long vfrom, vto; - vfrom = kmap(from, KM_READ); - vto = kmap(to, KM_WRITE); + vfrom = kmap(from); + vto = kmap(to); copy_page((void *)vto, (void *)vfrom); - kunmap(vfrom, KM_READ); - kunmap(vto, KM_WRITE); + kunmap(from); + kunmap(to); } #endif /* _LINUX_HIGHMEM_H */ diff -u --recursive --new-file v2.3.26/linux/include/linux/i2o.h linux/include/linux/i2o.h --- v2.3.26/linux/include/linux/i2o.h Sun Nov 7 16:37:34 1999 +++ linux/include/linux/i2o.h Wed Nov 10 09:52:18 1999 @@ -100,40 +100,40 @@ u8 reserved; u16 PciVendorID; u16 PciDeviceID; -} i2o_pci_bus, *pi2o_pci_bus; +} i2o_pci_bus; typedef struct _i2o_local_bus { u16 LbBaseIOPort; u16 reserved; u32 LbBaseMemoryAddress; -} i2o_local_bus, *pi2o_local_bus; +} i2o_local_bus; typedef struct _i2o_isa_bus { u16 IsaBaseIOPort; u8 CSN; u8 reserved; u32 IsaBaseMemoryAddress; -} i2o_isa_bus, *pi2o_isa_bus; +} i2o_isa_bus; typedef struct _i2o_eisa_bus_info { u16 EisaBaseIOPort; u8 reserved; u8 EisaSlotNumber; u32 EisaBaseMemoryAddress; -} i2o_eisa_bus, *pi2o_eisa_bus; +} i2o_eisa_bus; typedef struct _i2o_mca_bus { u16 McaBaseIOPort; u8 reserved; u8 McaSlotNumber; u32 McaBaseMemoryAddress; -} i2o_mca_bus, *pi2o_mca_bus; +} i2o_mca_bus; typedef struct _i2o_other_bus { u16 BaseIOPort; u16 reserved; u32 BaseMemoryAddress; -} i2o_other_bus, *pi2o_other_bus; +} i2o_other_bus; typedef struct _i2o_hrt_entry { u32 adapter_id; @@ -149,7 +149,7 @@ i2o_mca_bus mca_bus; i2o_other_bus other_bus; } bus; -} i2o_hrt_entry, *pi2o_hrt_entry; +} i2o_hrt_entry; typedef struct _i2o_hrt { u16 num_entries; @@ -157,7 +157,7 @@ u8 hrt_version; u32 change_ind; i2o_hrt_entry hrt_entry[1]; -} i2o_hrt, *pi2o_hrt; +} i2o_hrt; typedef struct _i2o_lct_entry { u32 entry_size:16; @@ -174,7 +174,7 @@ u32 bios_info:8; u8 identity_tag[8]; u32 event_capabilities; -} i2o_lct_entry, *pi2o_lct_entry; +} i2o_lct_entry; typedef struct _i2o_lct { u32 table_size:16; @@ -183,7 +183,7 @@ u32 iop_flags; u32 current_change_ind; i2o_lct_entry lct_entry[1]; -} i2o_lct, *pi2o_lct; +} i2o_lct; typedef struct _i2o_status_block { u16 org_id; @@ -199,6 +199,7 @@ u8 init_code; u8 reserved2; u32 max_inbound_frames; + u32 cur_inbound_frames; u32 max_outbound_frames; char product_id[24]; u32 expected_lct_size; @@ -211,9 +212,38 @@ u32 current_io_base; u32 reserved3:24; u32 cmd_status:8; -} i2o_status_block, *pi2o_status_block; +} i2o_status_block; +/* Event indicator mask flags */ +#define I2O_EVT_IND_STATE_CHANGE 0x80000000 +#define I2O_EVT_IND_GENERAL_WARNING 0x40000000 +#define I2O_EVT_IND_CONFIGURATION_FLAG 0x20000000 +#define I2O_EVT_IND_LOCK_RELEASE 0x10000000 +#define I2O_EVT_IND_CAPABILITY_CHANGE 0x08000000 +#define I2O_EVT_IND_DEVICE_RESET 0x04000000 +#define I2O_EVT_IND_EVT_MASK_MODIFIED 0x02000000 +#define I2O_EVT_IND_FIELD_MODIFIED 0x01000000 +#define I2O_EVT_IND_VENDOR_EVT 0x00800000 +#define I2O_EVT_IND_DEVICE_STATE 0x00400000 + +/* Event data for generic events */ +#define I2O_EVT_STATE_CHANGE_NORMAL 0x00 +#define I2O_EVT_STATE_CHANGE_SUSPENDED 0x01 +#define I2O_EVT_STATE_CHANGE_RESTART 0x02 +#define I2O_EVT_STATE_CHANGE_NA_RECOVER 0x03 +#define I2O_EVT_STATE_CHANGE_NA_NO_RECOVER 0x04 +#define I2O_EVT_STATE_CHANGE_QUIESCE_REQUEST 0x05 +#define I2O_EVT_STATE_CHANGE_FAILED 0x10 +#define I2O_EVT_STATE_CHANGE_FAULTED 0x11 + +#define I2O_EVT_GEN_WARNING_NORMAL 0x00 +#define I2O_EVT_GEN_WARNING_ERROR_THRESHOLD 0x01 +#define I2O_EVT_GEN_WARNING_MEDIA_FAULT 0x02 +#define I2O_EVT_CAPABILITY_OTHER 0x01 +#define I2O_EVT_CAPABILITY_CHANGED 0x02 + +#define I2O_EVT_SENSOR_STATE_CHANGED 0x01 #ifdef __KERNEL__ /* ioctl stuff only thing exported to users */ @@ -246,7 +276,7 @@ struct i2o_device { - pi2o_lct_entry lct_data;/* Device LCT information */ + i2o_lct_entry *lct_data;/* Device LCT information */ u32 flags; int i2oversion; /* I2O version supported. Actually there * should be high and low version */ @@ -286,7 +316,7 @@ char name[16]; int unit; int type; - int enabled; /* Bus level enable */ + int enabled; #define I2O_TYPE_PCI 0x01 /* PCI I2O controller */ @@ -298,9 +328,9 @@ volatile u32 *reply_port; volatile u32 *irq_mask; /* Interrupt port */ - pi2o_status_block status_block; /* IOP status block */ - pi2o_lct lct; - pi2o_hrt hrt; + i2o_status_block *status_block; /* IOP status block */ + i2o_lct *lct; + i2o_hrt *hrt; u32 mem_offset; /* MFA offset */ u32 mem_phys; /* MFA physical */ @@ -464,22 +494,22 @@ 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, 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_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_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 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 int i2o_event_register(struct i2o_controller *, int, int, u32); +extern int i2o_event_ack(struct i2o_controller *, int, int, u32, void *, int); extern void i2o_run_queue(struct i2o_controller *); extern void i2o_report_status(const char *, const char *, u32 *); @@ -615,7 +645,7 @@ #define I2O_CMD_UTIL_PARAMS_GET 0x06 #define I2O_CMD_UTIL_PARAMS_SET 0x05 #define I2O_CMD_UTIL_EVT_REGISTER 0x13 -#define I2O_CMD_UTIL_ACK 0x14 +#define I2O_CMD_UTIL_EVT_ACK 0x14 #define I2O_CMD_UTIL_CONFIG_DIALOG 0x10 #define I2O_CMD_UTIL_DEVICE_RESERVE 0x0D #define I2O_CMD_UTIL_DEVICE_RELEASE 0x0F diff -u --recursive --new-file v2.3.26/linux/include/linux/ipc.h linux/include/linux/ipc.h --- v2.3.26/linux/include/linux/ipc.h Mon Nov 1 13:56:27 1999 +++ linux/include/linux/ipc.h Tue Nov 9 10:02:36 1999 @@ -42,6 +42,8 @@ #define IPC_UNUSED ((void *) -1) #define IPC_NOID ((void *) -2) /* being allocated/destroyed */ +#define IPCMNI 32768 /* <= MAX_INT limit for ipc arrays (including sysctl changes) */ + #endif /* __KERNEL__ */ #endif /* _LINUX_IPC_H */ diff -u --recursive --new-file v2.3.26/linux/include/linux/isdn.h linux/include/linux/isdn.h --- v2.3.26/linux/include/linux/isdn.h Thu Aug 26 13:05:41 1999 +++ linux/include/linux/isdn.h Sun Nov 7 16:34:00 1999 @@ -1,8 +1,8 @@ -/* $Id: isdn.h,v 1.71 1999/08/23 15:54:22 keil Exp $ +/* $Id: isdn.h,v 1.81 1999/10/27 21:21:18 detabc Exp $ * * Main header for the Linux ISDN subsystem (linklevel). * - * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de) * @@ -21,6 +21,51 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdn.h,v $ + * Revision 1.81 1999/10/27 21:21:18 detabc + * Added support for building logically-bind-group's per interface. + * usefull for outgoing call's with more then one isdn-card. + * + * Switchable support to dont reset the hangup-timeout for + * receive frames. Most part's of the timru-rules for receiving frames + * are now obsolete. If the input- or forwarding-firewall deny + * the frame, the line will be not hold open. + * + * Revision 1.80 1999/10/26 21:09:29 armin + * New bufferlen for phonenumber only with kernel 2.3.x + * + * Revision 1.79 1999/10/16 17:52:38 keil + * Changing the MSN length need new data versions + * + * Revision 1.78 1999/10/08 18:59:33 armin + * Bugfix of too small MSN buffer and checking phone number + * in isdn_tty_getdial() + * + * Revision 1.77 1999/09/23 22:22:42 detabc + * added tcp-keepalive-detect with local response (ipv4 only) + * added host-only-interface support + * (source ipaddr == interface ipaddr) (ipv4 only) + * ok with kernel 2.3.18 and 2.2.12 + * + * Revision 1.76 1999/09/14 10:16:21 keil + * change ABC include + * + * Revision 1.75 1999/09/13 23:25:17 he + * serialized xmitting frames from isdn_ppp and BSENT statcallb + * + * Revision 1.74 1999/09/12 16:19:39 detabc + * added abc features + * low cost routing for net-interfaces (only the HL side). + * need more implementation in the isdnlog-utility + * udp info support (first part). + * different EAZ on outgoing call's. + * more checks on D-Channel callbacks (double use of channels). + * tested and running with kernel 2.3.17 + * + * Revision 1.73 1999/09/06 07:29:36 fritz + * Changed my mail-address. + * + * Revision 1.72 1999/09/04 22:20:19 detabc + * * Revision 1.71 1999/08/23 15:54:22 keil * more backported changes from kernel 2.3.14 * @@ -250,7 +295,6 @@ #ifndef isdn_h #define isdn_h -#include #include #include @@ -279,6 +323,18 @@ #define ISDN_MINOR_PPPMAX (128 + (ISDN_MAX_CHANNELS-1)) #define ISDN_MINOR_STATUS 255 +#undef CONFIG_ISDN_WITH_ABC_CALLB +#undef CONFIG_ISDN_WITH_ABC_UDP_CHECK +#undef CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP +#undef CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL +#undef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ +#undef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT +#undef CONFIG_ISDN_WITH_ABC_IPV4_TCP_KEEPALIVE +#undef CONFIG_ISDN_WITH_ABC_IPV4_DYNADDR +#undef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER +#undef CONFIG_ISDN_WITH_ABC_ICALL_BIND + + /* New ioctl-codes */ #define IIOCNETAIF _IO('I',1) #define IIOCNETDIF _IO('I',2) @@ -302,6 +358,7 @@ #define IIOCNETDIL _IO('I',20) #define IIOCGETCPS _IO('I',21) #define IIOCGETDVR _IO('I',22) +#define IIOCNETLCR _IO('I',23) /* dwabc ioctl for LCR from isdnlog */ #define IIOCNETALN _IO('I',32) #define IIOCNETDLN _IO('I',33) @@ -335,10 +392,15 @@ #define ISDN_USAGE_OUTGOING 128 /* This bit is set, if channel is outgoing */ #define ISDN_MODEM_ANZREG 24 /* Number of Modem-Registers */ -#define ISDN_MSNLEN 20 #define ISDN_LMSNLEN 255 /* Length of tty's Listen-MSN string */ #define ISDN_CMSGLEN 50 /* Length of CONNECT-Message to add for Modem */ +#define ISDN_MSNLEN 32 +#define NET_DV 0x06 /* Data version for isdn_net_ioctl_cfg */ +#define TTY_DV 0x06 /* Data version for iprofd etc. */ + +#define INF_DV 0x01 /* Data version for /dev/isdninfo */ + typedef struct { char drvid[25]; unsigned long arg; @@ -356,10 +418,6 @@ int outgoing; } isdn_net_ioctl_phone; -#define NET_DV 0x05 /* Data version for isdn_net_ioctl_cfg */ -#define TTY_DV 0x05 /* Data version for iprofd etc. */ -#define INF_DV 0x01 /* Data version for /dev/isdninfo */ - typedef struct { char name[10]; /* Name of interface */ char master[10]; /* Name of Master for Bundling */ @@ -438,7 +496,6 @@ #include - #define ISDN_DRVIOCTL_MASK 0x7f /* Mask for Device-ioctl */ /* Until now unused */ @@ -504,12 +561,6 @@ #define ISDN_NET_CALLBACK 0x04 /* activate callback */ #define ISDN_NET_CBHUP 0x08 /* hangup before callback */ #define ISDN_NET_CBOUT 0x10 /* remote machine does callback */ -#if 0 -/* Unused??? */ -#define ISDN_NET_CLONE 0x08 /* clone a tmp interface when called */ -#define ISDN_NET_TMP 0x10 /* tmp interface until getting an IP */ -#define ISDN_NET_DYNAMIC 0x20 /* this link is dynamically allocated */ -#endif #define ISDN_NET_MAGIC 0x49344C02 /* for paranoia-checking */ @@ -591,7 +642,7 @@ struct isdn_net_local_s *last; /* Ptr to last link in bundle */ struct isdn_net_dev_s *netdev; /* Ptr to netdev */ struct sk_buff *first_skb; /* Ptr to skb that triggers dialing */ - struct sk_buff *sav_skb; /* Ptr to skb, rejected by LL-driver*/ + struct sk_buff *volatile sav_skb; /* Ptr to skb, rejected by LL-driver*/ /* Ptr to orig. hard_header_cache */ int (*org_hhc)( struct neighbour *neigh, @@ -743,12 +794,7 @@ atemu emu; /* AT-emulator data */ struct termios normal_termios; /* For saving termios structs */ struct termios callout_termios; -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t open_wait, close_wait; -#else - struct wait_queue *open_wait; - struct wait_queue *close_wait; -#endif struct semaphore write_sem; } modem_info; @@ -826,11 +872,7 @@ ulong flags; /* Misc driver Flags */ int locks; /* Number of locks for this driver */ int channels; /* Number of channels */ -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t st_waitq; /* Wait-Queue for status-read's */ -#else - struct wait_queue *st_waitq; /* Wait-Queue for status-read's */ -#endif int maxbufsize; /* Maximum Buffersize supported */ unsigned long pktcount; /* Until now: unused */ int stavail; /* Chars avail on Status-device */ @@ -841,13 +883,8 @@ unsigned long DLEflag; /* Flags: Insert DLE at next read */ #endif struct sk_buff_head *rpqueue; /* Pointers to start of Rcv-Queue */ -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t *rcv_waitq; /* Wait-Queues for B-Channel-Reads */ wait_queue_head_t *snd_waitq; /* Wait-Queue for B-Channel-Send's */ -#else - struct wait_queue **rcv_waitq; /* Wait-Queues for B-Channel-Reads */ - struct wait_queue **snd_waitq; /* Wait-Queue for B-Channel-Send's */ -#endif char msn2eaz[10][ISDN_MSNLEN]; /* Mapping-Table MSN->EAZ */ } driver; @@ -863,11 +900,7 @@ /* see ISDN_TIMER_..defines */ int global_flags; infostruct *infochain; /* List of open info-devs. */ -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t info_waitq; /* Wait-Queue for isdninfo */ -#else - struct wait_queue *info_waitq; /* Wait-Queue for isdninfo */ -#endif struct timer_list timer; /* Misc.-function Timer */ int chanmap[ISDN_MAX_CHANNELS];/* Map minor->device-channel */ int drvmap[ISDN_MAX_CHANNELS]; /* Map minor->driver-index */ @@ -892,6 +925,7 @@ } isdn_dev; extern isdn_dev *dev; + /* Utility-Macros */ diff -u --recursive --new-file v2.3.26/linux/include/linux/isdn_compat.h linux/include/linux/isdn_compat.h --- v2.3.26/linux/include/linux/isdn_compat.h Thu Aug 26 13:05:41 1999 +++ linux/include/linux/isdn_compat.h Wed Dec 31 16:00:00 1969 @@ -1,116 +0,0 @@ -#ifdef __KERNEL__ -/* Compatibility for various Linux kernel versions */ - -#ifndef _LINUX_ISDN_COMPAT_H -#define _LINUX_ISDN_COMPAT_H - -#ifndef LINUX_VERSION_CODE -#include -#endif - -#ifndef KERNEL_VERSION -#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) -#include - -#define ioremap vremap -#define ioremap_nocache vremap -#define iounmap vfree - -static inline unsigned long copy_from_user(void *to, const void *from, unsigned long n) -{ - int i; - if ((i = verify_area(VERIFY_READ, from, n)) != 0) - return i; - memcpy_fromfs(to, from, n); - return 0; -} - -static inline unsigned long copy_to_user(void *to, const void *from, unsigned long n) -{ - int i; - if ((i = verify_area(VERIFY_WRITE, to, n)) != 0) - return i; - memcpy_tofs(to, from, n); - return 0; -} - -#define GET_USER(x, addr) ( x = get_user(addr) ) -#ifdef __alpha__ /* needed for 2.0.x with alpha-patches */ -#define RWTYPE long -#define LSTYPE long -#define RWARG unsigned long -#else -#define RWTYPE int -#define LSTYPE int -#define RWARG int -#endif -#define LSARG off_t -#else -#include -#define GET_USER get_user -#define PUT_USER put_user -#define RWTYPE long -#define LSTYPE long long -#define RWARG unsigned long -#define LSARG long long -#endif /* LINUX_VERSION_CODE */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,15) -#define SET_SKB_FREE(x) ( x->free = 1 ) -#define idev_kfree_skb(a,b) dev_kfree_skb(a,b) -#else -#define SET_SKB_FREE(x) -#define idev_kfree_skb(a,b) dev_kfree_skb(a) -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,18) -#define COMPAT_HAS_NEW_SYMTAB -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,31) -#define CLOSETYPE void -#define CLOSEVAL -#else -#define CLOSETYPE int -#define CLOSEVAL (0) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,37) -#define test_and_clear_bit clear_bit -#define test_and_set_bit set_bit -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,81) -#define kstat_irqs( PAR ) kstat.interrupts[PAR] -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,91) -#define COMPAT_HAS_NEW_PCI -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13) -#define get_pcibase(ps, nr) ps->base_address[nr] -#else -#define get_pcibase(ps, nr) ps->resource[nr].start -#endif -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,127) -#define schedule_timeout(a) current->timeout = jiffies + (a); schedule (); -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) -#define COMPAT_HAS_NEW_WAITQ -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,12) -#define COMPAT_HAS_NEW_SETUP -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14) -#define net_device device -#endif - -#endif /* __KERNEL__ */ -#endif /* _LINUX_ISDN_COMPAT_H */ diff -u --recursive --new-file v2.3.26/linux/include/linux/isdn_ppp.h linux/include/linux/isdn_ppp.h --- v2.3.26/linux/include/linux/isdn_ppp.h Sun Aug 15 11:49:08 1999 +++ linux/include/linux/isdn_ppp.h Sun Nov 7 16:34:00 1999 @@ -4,7 +4,6 @@ #define _LINUX_ISDN_PPP_H #include -#include #define CALLTYPE_INCOMING 0x1 #define CALLTYPE_OUTGOING 0x2 @@ -207,11 +206,7 @@ struct ippp_buf_queue rq[NUM_RCV_BUFFS]; /* packet queue for isdn_ppp_read() */ struct ippp_buf_queue *first; /* pointer to (current) first packet */ struct ippp_buf_queue *last; /* pointer to (current) last used packet in queue */ -#ifdef COMPAT_HAS_NEW_WAITQ wait_queue_head_t wq; -#else - struct wait_queue *wq; -#endif struct task_struct *tk; unsigned int mpppcfg; unsigned int pppcfg; diff -u --recursive --new-file v2.3.26/linux/include/linux/isdnif.h linux/include/linux/isdnif.h --- v2.3.26/linux/include/linux/isdnif.h Thu Aug 26 13:05:41 1999 +++ linux/include/linux/isdnif.h Sun Nov 7 16:34:00 1999 @@ -1,10 +1,10 @@ -/* $Id: isdnif.h,v 1.30 1999/08/23 15:54:29 keil Exp $ +/* $Id: isdnif.h,v 1.32 1999/10/11 22:03:00 keil Exp $ * * Linux ISDN subsystem * * Definition of the interface between the subsystem and its low-level drivers. * - * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de) + * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de) * Copyright 1995,96 Thinking Objects Software GmbH Wuerzburg * * This program is free software; you can redistribute it and/or modify @@ -22,6 +22,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: isdnif.h,v $ + * Revision 1.32 1999/10/11 22:03:00 keil + * COMPAT_NEED_UACCESS (no include in isdn_compat.h) + * + * Revision 1.31 1999/09/06 07:29:36 fritz + * Changed my mail-address. + * * Revision 1.30 1999/08/23 15:54:29 keil * more backported changes from kernel 2.3.14 * @@ -138,7 +144,6 @@ #define isdnif_h #include -#include /* * Values for general protocol-selection diff -u --recursive --new-file v2.3.26/linux/include/linux/kernelcapi.h linux/include/linux/kernelcapi.h --- v2.3.26/linux/include/linux/kernelcapi.h Thu Aug 12 09:42:34 1999 +++ linux/include/linux/kernelcapi.h Sun Nov 7 16:34:00 1999 @@ -1,11 +1,15 @@ /* - * $Id: kernelcapi.h,v 1.3 1999/07/01 15:26:56 calle Exp $ + * $Id: kernelcapi.h,v 1.4 1999/09/10 17:24:19 calle Exp $ * * Kernel CAPI 2.0 Interface for Linux * * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: kernelcapi.h,v $ + * Revision 1.4 1999/09/10 17:24:19 calle + * Changes for proposed standard for CAPI2.0: + * - AK148 "Linux Exention" + * * Revision 1.3 1999/07/01 15:26:56 calle * complete new version (I love it): * + new hardware independed "capi_driver" interface that will make it easy to: @@ -70,19 +74,19 @@ #ifdef __KERNEL__ struct capi_interface { - int (*capi_installed) (void); + __u16 (*capi_isinstalled) (void); - __u16(*capi_register) (capi_register_params * rparam, __u16 * applidp); - __u16(*capi_release) (__u16 applid); - __u16(*capi_put_message) (__u16 applid, struct sk_buff * msg); - __u16(*capi_get_message) (__u16 applid, struct sk_buff ** msgp); - __u16(*capi_set_signal) (__u16 applid, + __u16 (*capi_register) (capi_register_params * rparam, __u16 * applidp); + __u16 (*capi_release) (__u16 applid); + __u16 (*capi_put_message) (__u16 applid, struct sk_buff * msg); + __u16 (*capi_get_message) (__u16 applid, struct sk_buff ** msgp); + __u16 (*capi_set_signal) (__u16 applid, void (*signal) (__u16 applid, __u32 param), __u32 param); - __u16(*capi_get_manufacturer) (__u16 contr, __u8 buf[CAPI_MANUFACTURER_LEN]); - __u16(*capi_get_version) (__u16 contr, struct capi_version * verp); - __u16(*capi_get_serial) (__u16 contr, __u8 serial[CAPI_SERIAL_LEN]); - __u16(*capi_get_profile) (__u16 contr, struct capi_profile * profp); + __u16 (*capi_get_manufacturer) (__u32 contr, __u8 buf[CAPI_MANUFACTURER_LEN]); + __u16 (*capi_get_version) (__u32 contr, struct capi_version * verp); + __u16(*capi_get_serial) (__u32 contr, __u8 serial[CAPI_SERIAL_LEN]); + __u16(*capi_get_profile) (__u32 contr, struct capi_profile * profp); /* * to init controllers, data is always in user memory @@ -96,7 +100,7 @@ struct capi_interface_user { char name[20]; - void (*callback) (unsigned int cmd, __u16 contr, void *data); + void (*callback) (unsigned int cmd, __u32 contr, void *data); /* internal */ struct capi_interface_user *next; }; diff -u --recursive --new-file v2.3.26/linux/include/linux/mm.h linux/include/linux/mm.h --- v2.3.26/linux/include/linux/mm.h Sun Nov 7 16:37:34 1999 +++ linux/include/linux/mm.h Thu Nov 11 17:02:14 1999 @@ -138,6 +138,7 @@ wait_queue_head_t wait; struct page **pprev_hash; struct buffer_head * buffers; + unsigned long virtual; /* nonzero if kmapped */ } mem_map_t; #define get_page(p) atomic_inc(&(p)->count) @@ -285,12 +286,16 @@ * This is timing-critical - most of the time in getting a new page * goes to clearing the page. If you want a page without the clearing * overhead, just use __get_free_page() directly.. + * + * We have two allocation namespaces - the *get*page*() variants + * return virtual kernel addresses to the allocated page(s), the + * alloc_page*() variants return 'struct page *'. */ -extern struct page * __get_pages(int gfp_mask, unsigned long order); #define __get_free_page(gfp_mask) __get_free_pages((gfp_mask),0) #define __get_dma_pages(gfp_mask, order) __get_free_pages((gfp_mask) | GFP_DMA,(order)) -extern unsigned long FASTCALL(__get_free_pages(int gfp_mask, unsigned long gfp_order)); -extern struct page * get_free_highpage(int gfp_mask); +extern unsigned long FASTCALL(__get_free_pages(int gfp_mask, unsigned long order)); +extern struct page * FASTCALL(alloc_pages(int gfp_mask, unsigned long order)); +#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) extern inline unsigned long get_zeroed_page(int gfp_mask) { @@ -335,7 +340,7 @@ extern int check_pgt_cache(void); extern void paging_init(void); -extern void free_area_init(unsigned long); +extern void free_area_init(unsigned int * zones_size); extern void mem_init(void); extern void show_mem(void); extern void oom(struct task_struct * tsk); diff -u --recursive --new-file v2.3.26/linux/include/linux/module.h linux/include/linux/module.h --- v2.3.26/linux/include/linux/module.h Wed Aug 18 16:43:29 1999 +++ linux/include/linux/module.h Thu Nov 11 17:02:07 1999 @@ -8,6 +8,7 @@ #define _LINUX_MODULE_H #include +#include #ifdef __GENKSYMS__ # define _set_ver(sym) sym diff -u --recursive --new-file v2.3.26/linux/include/linux/msg.h linux/include/linux/msg.h --- v2.3.26/linux/include/linux/msg.h Sat Oct 9 11:47:50 1999 +++ linux/include/linux/msg.h Tue Nov 9 10:02:36 1999 @@ -45,9 +45,9 @@ unsigned short msgseg; }; -#define MSGMNI 128 /* <= 32768 */ /* max # of msg queue identifiers */ -#define MSGMAX 4056 /* <= 4056 (?)*/ /* max size of message (bytes) */ -#define MSGMNB 16384 /* <= MAX_INT */ /* default max size of a message queue */ +#define MSGMNI 128 /* <= IPCMNI */ /* max # of msg queue identifiers */ +#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */ +#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */ /* unused */ #define MSGPOOL (MSGMNI*MSGMNB/1024) /* size in kilobytes of message pool */ diff -u --recursive --new-file v2.3.26/linux/include/linux/nbd.h linux/include/linux/nbd.h --- v2.3.26/linux/include/linux/nbd.h Mon Mar 8 13:05:11 1999 +++ linux/include/linux/nbd.h Wed Nov 10 12:38:13 1999 @@ -1,3 +1,9 @@ +/* + * 1999 Copyright (C) Pavel Machek, pavel@ucw.cz. This code is GPL. + * 1999/11/04 Copyright (C) 1999 VMware, Inc. (Regis "HPReg" Duchesne) + * Made nbd_end_request() use the io_request_lock + */ + #ifndef LINUX_NBD_H #define LINUX_NBD_H @@ -27,12 +33,19 @@ static void nbd_end_request(struct request *req) { + unsigned long flags; + #ifdef PARANOIA requests_out++; #endif + spin_lock_irqsave(&io_request_lock, flags); if (end_that_request_first( req, !req->errors, "nbd" )) - return; + goto out; end_that_request_last( req ); + +out: + spin_unlock_irqrestore(&io_request_lock, flags); + return; } #define MAX_NBD 128 diff -u --recursive --new-file v2.3.26/linux/include/linux/pagemap.h linux/include/linux/pagemap.h --- v2.3.26/linux/include/linux/pagemap.h Sun Nov 7 16:37:34 1999 +++ linux/include/linux/pagemap.h Thu Nov 11 17:02:17 1999 @@ -27,7 +27,7 @@ #define PAGE_CACHE_MASK PAGE_MASK #define PAGE_CACHE_ALIGN(addr) (((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK) -#define page_cache_alloc() __get_pages(GFP_USER, 0) +#define page_cache_alloc() alloc_pages(GFP_HIGHUSER, 0) #define page_cache_free(x) __free_page(x) #define page_cache_release(x) __free_page(x) diff -u --recursive --new-file v2.3.26/linux/include/linux/parport.h linux/include/linux/parport.h --- v2.3.26/linux/include/linux/parport.h Fri Oct 15 15:25:14 1999 +++ linux/include/linux/parport.h Thu Nov 11 17:02:57 1999 @@ -422,6 +422,10 @@ extern int parport_wait_peripheral (struct parport *port, unsigned char mask, unsigned char val); +extern int parport_poll_peripheral (struct parport *port, + unsigned char mask, + unsigned char val, + int usec); /* For architectural drivers */ extern void parport_ieee1284_wakeup (struct parport *port); diff -u --recursive --new-file v2.3.26/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h --- v2.3.26/linux/include/linux/proc_fs.h Mon Nov 1 13:56:27 1999 +++ linux/include/linux/proc_fs.h Thu Nov 11 17:02:19 1999 @@ -9,6 +9,12 @@ */ /* + * Offset of the first process in the /proc root directory.. + */ +#define FIRST_PROCESS_ENTRY 256 + + +/* * We always define these enumerators */ @@ -16,111 +22,6 @@ PROC_ROOT_INO = 1, }; -enum pid_directory_inos { - PROC_PID_INO = 2, - PROC_PID_STATUS, - PROC_PID_MEM, - PROC_PID_CWD, - PROC_PID_ROOT, - PROC_PID_EXE, - PROC_PID_FD, - PROC_PID_ENVIRON, - PROC_PID_CMDLINE, - PROC_PID_STAT, - PROC_PID_STATM, - PROC_PID_MAPS, -#if CONFIG_AP1000 - PROC_PID_RINGBUF, -#endif - PROC_PID_CPU, -}; - -enum pid_subdirectory_inos { - PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ -}; - -enum net_directory_inos { - PROC_NET_LAST -}; - -enum scsi_directory_inos { - PROC_SCSI_SCSI = 256, - PROC_SCSI_ADVANSYS, - PROC_SCSI_PCI2000, - PROC_SCSI_PCI2220I, - PROC_SCSI_PSI240I, - PROC_SCSI_EATA, - PROC_SCSI_EATA_PIO, - PROC_SCSI_AHA152X, - PROC_SCSI_AHA1542, - PROC_SCSI_AHA1740, - PROC_SCSI_AIC7XXX, - PROC_SCSI_BUSLOGIC, - PROC_SCSI_U14_34F, - PROC_SCSI_FDOMAIN, - PROC_SCSI_GDTH, - PROC_SCSI_GENERIC_NCR5380, - PROC_SCSI_IN2000, - PROC_SCSI_PAS16, - PROC_SCSI_QLOGICFAS, - PROC_SCSI_QLOGICISP, - PROC_SCSI_QLOGICFC, - PROC_SCSI_SEAGATE, - PROC_SCSI_T128, - PROC_SCSI_NCR53C7xx, - PROC_SCSI_SYM53C8XX, - PROC_SCSI_NCR53C8XX, - PROC_SCSI_ULTRASTOR, - PROC_SCSI_7000FASST, - PROC_SCSI_IBMMCA, - PROC_SCSI_FD_MCS, - PROC_SCSI_EATA2X, - PROC_SCSI_DC390T, - PROC_SCSI_AM53C974, - PROC_SCSI_SSC, - PROC_SCSI_NCR53C406A, - PROC_SCSI_SYM53C416, - PROC_SCSI_MEGARAID, - PROC_SCSI_PPA, - PROC_SCSI_ATP870U, - PROC_SCSI_ESP, - PROC_SCSI_QLOGICPTI, - PROC_SCSI_AMIGA7XX, - PROC_SCSI_MVME147, - PROC_SCSI_MVME16x, - PROC_SCSI_BVME6000, - PROC_SCSI_SIM710, - PROC_SCSI_A3000, - PROC_SCSI_A2091, - PROC_SCSI_GVP11, - PROC_SCSI_ATARI, - PROC_SCSI_MAC, - PROC_SCSI_IDESCSI, - PROC_SCSI_SGIWD93, - PROC_SCSI_MESH, - PROC_SCSI_53C94, - PROC_SCSI_PLUTO, - PROC_SCSI_INI9100U, - PROC_SCSI_INIA100, - PROC_SCSI_IPH5526_FC, - PROC_SCSI_FCAL, - PROC_SCSI_I2O, - PROC_SCSI_USB_SCSI, - PROC_SCSI_SCSI_DEBUG, - PROC_SCSI_NOT_PRESENT, - PROC_SCSI_FILE, /* I'm assuming here that we */ - PROC_SCSI_LAST = (PROC_SCSI_FILE + 16) /* won't ever see more than */ -}; /* 16 HBAs in one machine */ - -enum mca_directory_inos { - PROC_MCA_MACHINE = (PROC_SCSI_LAST+1), - PROC_MCA_REGISTERS, - PROC_MCA_VIDEO, - PROC_MCA_SCSI, - PROC_MCA_SLOT, /* the 8 adapter slots */ - PROC_MCA_LAST = (PROC_MCA_SLOT + 8) -}; - /* Finally, the dynamically allocatable proc entries are reserved: */ #define PROC_DYNAMIC_FIRST 4096 @@ -144,9 +45,8 @@ * /proc file has a parent, but "subdir" is NULL for all * non-directory entries). * - * "get_info" is called at "read", while "fill_inode" is used to - * fill in file type/protection/owner information specific to the - * particular /proc file. + * "get_info" is called at "read", while "owner" is used to protect module + * from unloading while proc_dir_entry is in use */ typedef int (read_proc_t)(char *page, char **start, off_t off, @@ -166,7 +66,7 @@ unsigned long size; struct inode_operations * ops; get_info_t *get_info; - void (*fill_inode)(struct inode *, int); + struct module *owner; struct proc_dir_entry *next, *parent, *subdir; void *data; read_proc_t *read_proc; @@ -176,30 +76,30 @@ int deleted; /* delete flag */ }; -extern int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start, - off_t offset, int length, int inout); +#define PROC_INODE_PROPER(inode) ((inode)->i_ino & ~0xffff) +#define PROC_INODE_OPENPROM(inode) \ + ((inode->i_ino >= PROC_OPENPROM_FIRST) \ + && (inode->i_ino < PROC_OPENPROM_FIRST + PROC_NOPENPROM)) #ifdef CONFIG_PROC_FS extern struct proc_dir_entry proc_root; extern struct proc_dir_entry *proc_root_fs; extern struct proc_dir_entry *proc_net; -extern struct proc_dir_entry *proc_scsi; extern struct proc_dir_entry proc_sys; extern struct proc_dir_entry proc_openprom; -extern struct proc_dir_entry proc_pid; -extern struct proc_dir_entry proc_pid_fd; extern struct proc_dir_entry *proc_mca; extern struct proc_dir_entry *proc_bus; -extern struct proc_dir_entry *proc_sysvipc; extern struct proc_dir_entry *proc_root_driver; - -extern struct inode_operations proc_scsi_inode_operations; +extern struct proc_dir_entry proc_root_kcore; extern void proc_root_init(void); -extern void proc_base_init(void); extern void proc_misc_init(void); +struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry); +void proc_pid_delete_inode(struct inode *inode); +int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); + extern int proc_register(struct proc_dir_entry *, struct proc_dir_entry *); extern int proc_unregister(struct proc_dir_entry *, int); @@ -208,39 +108,6 @@ extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); -extern inline int proc_scsi_register(struct proc_dir_entry *driver, - struct proc_dir_entry *x) -{ - x->ops = &proc_scsi_inode_operations; - if(x->low_ino < PROC_SCSI_FILE){ - return(proc_register(proc_scsi, x)); - }else{ - return(proc_register(driver, x)); - } -} - -extern inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x) -{ - extern void scsi_init_free(char *ptr, unsigned int size); - - if(x < PROC_SCSI_FILE) - return(proc_unregister(proc_scsi, x)); - else { - struct proc_dir_entry **p = &driver->subdir, *dp; - int ret; - - while ((dp = *p) != NULL) { - if (dp->low_ino == x) - break; - p = &dp->next; - } - ret = proc_unregister(driver, x); - scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4); - return(ret); - } -} - - /* * retrieve the proc_dir_entry associated with /proc/driver/$module_name */ @@ -282,8 +149,6 @@ return (p == NULL) ? -1 : 0; } - - extern struct super_block *proc_super_blocks; extern struct dentry_operations proc_dentry_operations; extern struct super_block *proc_read_super(struct super_block *,void *,int); @@ -292,7 +157,6 @@ extern int proc_statfs(struct super_block *, struct statfs *, int); extern void proc_read_inode(struct inode *); extern void proc_write_inode(struct inode *); -extern int proc_permission(struct inode *, int); extern int proc_match(int, const char *,struct proc_dir_entry *); @@ -326,23 +190,16 @@ extern struct inode_operations proc_dir_inode_operations; extern struct inode_operations proc_file_inode_operations; -extern struct inode_operations proc_netdir_inode_operations; extern struct inode_operations proc_openprom_inode_operations; -extern struct inode_operations proc_mem_inode_operations; extern struct inode_operations proc_sys_inode_operations; -extern struct inode_operations proc_array_inode_operations; -extern struct inode_operations proc_arraylong_inode_operations; extern struct inode_operations proc_kcore_inode_operations; extern struct inode_operations proc_profile_inode_operations; extern struct inode_operations proc_kmsg_inode_operations; -extern struct inode_operations proc_link_inode_operations; -extern struct inode_operations proc_fd_inode_operations; #if CONFIG_AP1000 extern struct inode_operations proc_ringbuf_inode_operations; #endif extern struct inode_operations proc_omirr_inode_operations; extern struct inode_operations proc_ppc_htab_inode_operations; -extern struct inode_operations proc_sysvipc_inode_operations; /* * proc_tty.c @@ -387,16 +244,6 @@ remove_proc_entry(name,proc_net); } -extern inline int proc_net_register(struct proc_dir_entry * x) -{ - return proc_register(proc_net, x); -} - -extern inline int proc_net_unregister(int x) -{ - return proc_unregister(proc_net, x); -} - #else extern inline int proc_register(struct proc_dir_entry *a, struct proc_dir_entry *b) { return 0; } @@ -404,10 +251,6 @@ extern inline struct proc_dir_entry *proc_net_create(const char *name, mode_t mode, get_info_t *get_info) {return NULL;} extern inline void proc_net_remove(const char *name) {} -extern inline int proc_net_register(struct proc_dir_entry * x) { return 0; } -extern inline int proc_net_unregister(int x) { return 0; } -extern inline int proc_scsi_register(struct proc_dir_entry *b, struct proc_dir_entry *c) { return 0; } -extern inline int proc_scsi_unregister(struct proc_dir_entry *a, int x) { return 0; } extern inline struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) { return NULL; } diff -u --recursive --new-file v2.3.26/linux/include/linux/proc_fs_i.h linux/include/linux/proc_fs_i.h --- v2.3.26/linux/include/linux/proc_fs_i.h Wed Dec 31 16:00:00 1969 +++ linux/include/linux/proc_fs_i.h Mon Nov 8 10:19:19 1999 @@ -0,0 +1,9 @@ +struct proc_inode_info { + struct task_struct *task; + int type; + union { + struct dentry *(*proc_get_link)(struct inode *); + int (*proc_read)(struct task_struct *task, char *page); + } op; + struct file *file; +}; diff -u --recursive --new-file v2.3.26/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.3.26/linux/include/linux/sched.h Fri Oct 22 13:21:55 1999 +++ linux/include/linux/sched.h Thu Nov 11 17:02:14 1999 @@ -361,6 +361,8 @@ /* Thread group tracking */ u32 parent_exec_id; u32 self_exec_id; +/* Protection of fields allocatio/deallocation */ + struct semaphore exit_sem; }; /* @@ -427,6 +429,7 @@ /* mm */ NULL, &init_mm, \ /* signals */ SPIN_LOCK_UNLOCKED, &init_signals, {{0}}, {{0}}, NULL, &init_task.sigqueue, 0, 0, \ /* exec cts */ 0,0, \ +/* exit_sem */ __MUTEX_INITIALIZER(name.exit_sem), \ } #ifndef INIT_TASK_SIZE @@ -835,6 +838,21 @@ unhash_pid(p); REMOVE_LINKS(p); write_unlock_irq(&tasklist_lock); +} + +static inline int task_lock(struct task_struct *p) +{ + down(&p->exit_sem); + if (p->p_pptr) + return 1; + /* He's dead, Jim. You take his wallet, I'll take tricoder... */ + up(&p->exit_sem); + return 0; +} + +static inline void task_unlock(struct task_struct *p) +{ + up(&p->exit_sem); } #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.3.26/linux/include/linux/sem.h linux/include/linux/sem.h --- v2.3.26/linux/include/linux/sem.h Mon Nov 1 13:56:27 1999 +++ linux/include/linux/sem.h Tue Nov 9 10:02:36 1999 @@ -60,10 +60,10 @@ int semaem; }; -#define SEMMNI 128 /* <= 32767 max # of semaphore identifiers */ -#define SEMMSL 250 /* <= 512 max num of semaphores per id */ -#define SEMMNS (SEMMNI*SEMMSL) /* <= MAX_INT max # of semaphores in system */ -#define SEMOPM 32 /* <= 160 max num of ops per semop call */ +#define SEMMNI 128 /* <= IPCMNI max # of semaphore identifiers */ +#define SEMMSL 250 /* <= 8 000 max num of semaphores per id */ +#define SEMMNS (SEMMNI*SEMMSL) /* <= INT_MAX max # of semaphores in system */ +#define SEMOPM 32 /* <= 1 000 max num of ops per semop call */ #define SEMVMX 32767 /* <= 32767 semaphore maximum value */ /* unused */ diff -u --recursive --new-file v2.3.26/linux/include/linux/swap.h linux/include/linux/swap.h --- v2.3.26/linux/include/linux/swap.h Sun Nov 7 16:37:34 1999 +++ linux/include/linux/swap.h Thu Nov 11 17:02:07 1999 @@ -61,7 +61,9 @@ }; extern int nr_swap_pages; -extern int nr_free_pages; +FASTCALL(unsigned int nr_free_pages(void)); +FASTCALL(unsigned int nr_free_buffer_pages(void)); +FASTCALL(unsigned int nr_free_highpages(void)); extern int nr_lru_pages; extern struct list_head lru_cache; extern atomic_t nr_async_pages; @@ -112,8 +114,10 @@ extern struct swap_info_struct swap_info[]; extern int is_swap_partition(kdev_t); extern void si_swapinfo(struct sysinfo *); -extern swp_entry_t get_swap_page(void); -extern void swap_free(swp_entry_t); +extern swp_entry_t __get_swap_page(unsigned short); +#define get_swap_page() __get_swap_page(1) +extern void __swap_free(swp_entry_t, unsigned short); +#define swap_free(entry) __swap_free((entry), 1) struct swap_list_t { int head; /* head of priority-ordered swapfile list */ int next; /* swapfile to be used next */ diff -u --recursive --new-file v2.3.26/linux/include/linux/sysctl.h linux/include/linux/sysctl.h --- v2.3.26/linux/include/linux/sysctl.h Sun Nov 7 16:37:34 1999 +++ linux/include/linux/sysctl.h Tue Nov 9 10:03:57 1999 @@ -102,8 +102,11 @@ KERN_MSGMNB=36, /* int: Maximum message queue size */ 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_MAX_THREADS=39, /* int: Maximum nr of threads in the system */ + KERN_RANDOM=40, /* Random driver */ + KERN_SHMALL=41, /* int: Maximum size of shared memory */ + KERN_MSGMNI=42, /* int: msg queue identifiers */ + KERN_SEM=43 /* int: sysv semaphore limits */ }; diff -u --recursive --new-file v2.3.26/linux/include/linux/videodev.h linux/include/linux/videodev.h --- v2.3.26/linux/include/linux/videodev.h Mon Oct 4 15:49:30 1999 +++ linux/include/linux/videodev.h Wed Nov 10 20:01:22 1999 @@ -55,6 +55,10 @@ #define VID_TYPE_SCALES 128 /* Scalable */ #define VID_TYPE_MONOCHROME 256 /* Monochrome only */ #define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ +#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ +#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ +#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ struct video_capability { @@ -230,6 +234,36 @@ int teletext; /* Teletext minor */ }; +/* video_info is biased towards hardware mpeg encode/decode */ +/* but it could apply generically to any hardware compressor/decompressor */ +struct video_info +{ + __u32 frame_count; /* frames output since decode/encode began */ + __u32 h_size; /* current unscaled horizontal size */ + __u32 v_size; /* current unscaled veritcal size */ + __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */ + __u32 picture_type; /* current picture type */ + __u32 temporal_reference; /* current temporal reference */ + __u8 user_data[256]; /* user data last found in compressed stream */ + /* user_data[0] contains user data flags, user_data[1] has count */ +}; + +/* generic structure for setting playback modes */ +struct video_play_mode +{ + int mode; + int p1; + int p2; +}; + +/* for loading microcode / fpga programming */ +struct video_code +{ + char loadwhat[16]; /* name or tag of file being passed */ + int datasize; + __u8 *data; +}; + #define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ #define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ #define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ @@ -253,9 +287,47 @@ #define VIDIOCGUNIT _IOR('v', 21, struct video_unit) /* Get attached units */ #define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get frame buffer */ #define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set frame buffer - root only */ +#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ +#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ +#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ +#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ #define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ +/* VIDIOCSWRITEMODE */ +#define VID_WRITE_MPEG_AUD 0 +#define VID_WRITE_MPEG_VID 1 +#define VID_WRITE_OSD 2 +#define VID_WRITE_TTX 3 +#define VID_WRITE_CC 4 +#define VID_WRITE_MJPEG 5 + +/* VIDIOCSPLAYMODE */ +#define VID_PLAY_VID_OUT_MODE 0 + /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ +#define VID_PLAY_GENLOCK 1 + /* p1: 0 = OFF, 1 = ON */ + /* p2: GENLOCK FINE DELAY value */ +#define VID_PLAY_NORMAL 2 +#define VID_PLAY_PAUSE 3 +#define VID_PLAY_SINGLE_FRAME 4 +#define VID_PLAY_FAST_FORWARD 5 +#define VID_PLAY_SLOW_MOTION 6 +#define VID_PLAY_IMMEDIATE_NORMAL 7 +#define VID_PLAY_SWITCH_CHANNELS 8 +#define VID_PLAY_FREEZE_FRAME 9 +#define VID_PLAY_STILL_MODE 10 +#define VID_PLAY_MASTER_MODE 11 + /* p1: see below */ +#define VID_PLAY_MASTER_NONE 1 +#define VID_PLAY_MASTER_VIDEO 2 +#define VID_PLAY_MASTER_AUDIO 3 +#define VID_PLAY_ACTIVE_SCANLINES 12 + /* p1 = first active; p2 = last active */ +#define VID_PLAY_RESET 13 +#define VID_PLAY_END_MARK 14 + + #define VID_HARDWARE_BT848 1 #define VID_HARDWARE_QCAM_BW 2 @@ -276,7 +348,7 @@ #define VID_HARDWARE_BROADWAY 17 /* Broadway project */ #define VID_HARDWARE_GEMTEK 18 #define VID_HARDWARE_TYPHOON 19 -#define VID_HARDWARE_VINO 20 /* Reserved for SGI Indy Vino */ +#define VID_HARDWARE_VINO 20 /* SGI Indy Vino */ #define VID_HARDWARE_CADET 21 /* Cadet radio */ #define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ #define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ diff -u --recursive --new-file v2.3.26/linux/include/linux/vmalloc.h linux/include/linux/vmalloc.h --- v2.3.26/linux/include/linux/vmalloc.h Wed Aug 18 16:43:52 1999 +++ linux/include/linux/vmalloc.h Thu Nov 11 17:02:16 1999 @@ -20,5 +20,6 @@ void vmfree_area_pages(unsigned long address, unsigned long size); int vmalloc_area_pages(unsigned long address, unsigned long size); +extern struct vm_struct * vmlist; #endif diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/bulkmem.h linux/include/pcmcia/bulkmem.h --- v2.3.26/linux/include/pcmcia/bulkmem.h Tue Sep 7 12:14:07 1999 +++ linux/include/pcmcia/bulkmem.h Thu Nov 11 16:03:37 1999 @@ -1,7 +1,7 @@ /* * Definitions for bulk memory services * - * bulkmem.h 1.10 1999/08/28 04:12:33 + * bulkmem.h 1.11 1999/10/25 20:23:16 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -14,7 +14,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/bus_ops.h linux/include/pcmcia/bus_ops.h --- v2.3.26/linux/include/pcmcia/bus_ops.h Mon Oct 4 15:49:30 1999 +++ linux/include/pcmcia/bus_ops.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * bus_ops.h 1.7 1999/09/10 06:22:33 + * bus_ops.h 1.8 1999/10/25 20:23:16 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/ciscode.h linux/include/pcmcia/ciscode.h --- v2.3.26/linux/include/pcmcia/ciscode.h Tue Sep 7 12:14:07 1999 +++ linux/include/pcmcia/ciscode.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * ciscode.h 1.38 1999/08/28 04:12:32 + * ciscode.h 1.39 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/cisreg.h linux/include/pcmcia/cisreg.h --- v2.3.26/linux/include/pcmcia/cisreg.h Tue Sep 7 12:14:07 1999 +++ linux/include/pcmcia/cisreg.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * cisreg.h 1.13 1999/08/28 04:12:32 + * cisreg.h 1.14 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/cistpl.h linux/include/pcmcia/cistpl.h --- v2.3.26/linux/include/pcmcia/cistpl.h Tue Sep 7 12:14:07 1999 +++ linux/include/pcmcia/cistpl.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * cistpl.h 1.30 1999/08/28 04:12:32 + * cistpl.h 1.31 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/cs.h linux/include/pcmcia/cs.h --- v2.3.26/linux/include/pcmcia/cs.h Fri Oct 22 13:21:55 1999 +++ linux/include/pcmcia/cs.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * cs.h 1.68 1999/10/20 18:59:32 + * cs.h 1.69 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/cs_types.h linux/include/pcmcia/cs_types.h --- v2.3.26/linux/include/pcmcia/cs_types.h Fri Oct 22 13:21:55 1999 +++ linux/include/pcmcia/cs_types.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * cs_types.h 1.15 1999/08/28 04:12:32 + * cs_types.h 1.16 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/driver_ops.h linux/include/pcmcia/driver_ops.h --- v2.3.26/linux/include/pcmcia/driver_ops.h Fri Oct 22 13:21:55 1999 +++ linux/include/pcmcia/driver_ops.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * driver_ops.h 1.13 1999/08/28 04:12:33 + * driver_ops.h 1.14 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/ds.h linux/include/pcmcia/ds.h --- v2.3.26/linux/include/pcmcia/ds.h Fri Oct 22 13:21:55 1999 +++ linux/include/pcmcia/ds.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * ds.h 1.54 1999/09/03 16:44:49 + * ds.h 1.55 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/ftl.h linux/include/pcmcia/ftl.h --- v2.3.26/linux/include/pcmcia/ftl.h Tue Sep 7 12:14:07 1999 +++ linux/include/pcmcia/ftl.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * ftl.h 1.6 1999/08/28 04:12:33 + * ftl.h 1.7 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/mem_op.h linux/include/pcmcia/mem_op.h --- v2.3.26/linux/include/pcmcia/mem_op.h Mon Oct 4 15:49:30 1999 +++ linux/include/pcmcia/mem_op.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * mem_op.h 1.11 1999/09/15 07:14:03 + * mem_op.h 1.12 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/memory.h linux/include/pcmcia/memory.h --- v2.3.26/linux/include/pcmcia/memory.h Tue Sep 7 12:14:07 1999 +++ linux/include/pcmcia/memory.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * memory.h 1.5 1999/08/28 04:12:33 + * memory.h 1.6 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/ss.h linux/include/pcmcia/ss.h --- v2.3.26/linux/include/pcmcia/ss.h Tue Sep 7 12:14:07 1999 +++ linux/include/pcmcia/ss.h Thu Nov 11 16:03:37 1999 @@ -1,5 +1,5 @@ /* - * ss.h 1.24 1999/08/28 04:12:33 + * ss.h 1.25 1999/10/25 20:23:17 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in @@ -12,7 +12,7 @@ * limitations under the License. * * The initial developer of the original code is David A. Hinds - * . Portions created by David A. Hinds + * . Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. * * Alternatively, the contents of this file may be used under the diff -u --recursive --new-file v2.3.26/linux/include/pcmcia/version.h linux/include/pcmcia/version.h --- v2.3.26/linux/include/pcmcia/version.h Fri Oct 22 13:21:55 1999 +++ linux/include/pcmcia/version.h Thu Nov 11 16:03:37 1999 @@ -1,4 +1,4 @@ -/* version.h 1.74 1999/09/29 20:41:44 (David Hinds) */ +/* version.h 1.76 1999/10/26 18:55:56 (David Hinds) */ -#define CS_RELEASE "3.1.2" -#define CS_RELEASE_CODE 0x3102 +#define CS_RELEASE "3.1.4" +#define CS_RELEASE_CODE 0x3104 diff -u --recursive --new-file v2.3.26/linux/ipc/msg.c linux/ipc/msg.c --- v2.3.26/linux/ipc/msg.c Mon Nov 1 13:56:27 1999 +++ linux/ipc/msg.c Tue Nov 9 10:02:36 1999 @@ -11,6 +11,7 @@ * /proc/sysvipc/msg support (c) 1999 Dragos Acostachioaie * * mostly rewritten, threaded and wake-one semantics added + * MSGMAX limit removed, sysctl's added * (c) 1999 Manfred Spraul */ @@ -21,11 +22,15 @@ #include #include #include - #include +#include "util.h" + +/* sysctl: */ +int msg_ctlmax = MSGMAX; +int msg_ctlmnb = MSGMNB; +int msg_ctlmni = MSGMNI; -#define USHRT_MAX 0xffff -/* one ms_receiver structure for each sleeping receiver */ +/* one msg_receiver structure for each sleeping receiver */ struct msg_receiver { struct list_head r_list; struct task_struct* r_tsk; @@ -37,14 +42,27 @@ struct msg_msg* volatile r_msg; }; +/* one msg_sender for each sleeping sender */ +struct msg_sender { + struct list_head list; + struct task_struct* tsk; +}; + +struct msg_msgseg { + struct msg_msgseg* next; + /* the next part of the message follows immediately */ +}; /* one msg_msg structure for each message */ struct msg_msg { struct list_head m_list; long m_type; int m_ts; /* message text size */ + struct msg_msgseg* next; /* the actual message follows immediately */ }; +#define DATALEN_MSG (PAGE_SIZE-sizeof(struct msg_msg)) +#define DATALEN_SEG (PAGE_SIZE-sizeof(struct msg_msgseg)) /* one msq_queue structure for each present queue on the system */ struct msg_queue { @@ -60,13 +78,7 @@ struct list_head q_messages; struct list_head q_receivers; - wait_queue_head_t q_rwait; -}; - -/* one msq_array structure for each possible queue on the system */ -struct msg_array { - spinlock_t lock; - struct msg_queue* q; + struct list_head q_senders; }; #define SEARCH_ANY 1 @@ -74,99 +86,181 @@ #define SEARCH_NOTEQUAL 3 #define SEARCH_LESSEQUAL 4 -static DECLARE_MUTEX(msg_lock); -static struct msg_array msg_que[MSGMNI]; - -static unsigned short msg_seq = 0; -static int msg_used_queues = 0; -static int msg_max_id = -1; - static atomic_t msg_bytes = ATOMIC_INIT(0); static atomic_t msg_hdrs = ATOMIC_INIT(0); +static struct ipc_ids msg_ids; + +#define msg_lock(id) ((struct msg_queue*)ipc_lock(&msg_ids,id)) +#define msg_unlock(id) ipc_unlock(&msg_ids,id) +#define msg_rmid(id) ((struct msg_queue*)ipc_rmid(&msg_ids,id)) +#define msg_checkid(msq, msgid) \ + ipc_checkid(&msg_ids,&msq->q_perm,msgid) +#define msg_buildid(id, seq) \ + ipc_buildid(&msg_ids, id, seq) + static void freeque (int id); static int newque (key_t key, int msgflg); -static int findkey (key_t key); #ifdef CONFIG_PROC_FS static int sysvipc_msg_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data); #endif -/* implemented in ipc/util.c, thread-safe */ -extern int ipcperms (struct ipc_perm *ipcp, short msgflg); - void __init msg_init (void) { - int id; + ipc_init_ids(&msg_ids,msg_ctlmni); - for (id = 0; id < MSGMNI; id++) { - msg_que[id].lock = SPIN_LOCK_UNLOCKED; - msg_que[id].q = NULL; - } #ifdef CONFIG_PROC_FS create_proc_read_entry("sysvipc/msg", 0, 0, sysvipc_msg_read_proc, NULL); #endif } -static int findkey (key_t key) -{ - int id; - struct msg_queue *msq; - - for (id = 0; id <= msg_max_id; id++) { - msq = msg_que[id].q; - if(msq == NULL) - continue; - if (key == msq->q_perm.key) - return id; - } - return -1; -} - static int newque (key_t key, int msgflg) { int id; struct msg_queue *msq; - struct ipc_perm *ipcp; - - for (id = 0; id < MSGMNI; id++) { - if (msg_que[id].q == NULL) - break; - } - if(id == MSGMNI) - return -ENOSPC; msq = (struct msg_queue *) kmalloc (sizeof (*msq), GFP_KERNEL); if (!msq) return -ENOMEM; - - ipcp = &msq->q_perm; - ipcp->mode = (msgflg & S_IRWXUGO); - ipcp->key = key; - ipcp->cuid = ipcp->uid = current->euid; - ipcp->gid = ipcp->cgid = current->egid; - - /* ipcp->seq*MSGMNI must be a positive integer. - * this limits MSGMNI to 32768 - */ - ipcp->seq = msg_seq++; + id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni); + if(id == -1) { + kfree(msq); + return -ENOSPC; + } + msq->q_perm.mode = (msgflg & S_IRWXUGO); + msq->q_perm.key = key; msq->q_stime = msq->q_rtime = 0; msq->q_ctime = CURRENT_TIME; msq->q_cbytes = msq->q_qnum = 0; - msq->q_qbytes = MSGMNB; + msq->q_qbytes = msg_ctlmnb; msq->q_lspid = msq->q_lrpid = 0; INIT_LIST_HEAD(&msq->q_messages); INIT_LIST_HEAD(&msq->q_receivers); - init_waitqueue_head(&msq->q_rwait); + INIT_LIST_HEAD(&msq->q_senders); + msg_unlock(id); + + return msg_buildid(id,msq->q_perm.seq); +} + +static void free_msg(struct msg_msg* msg) +{ + struct msg_msgseg* seg; + seg = msg->next; + kfree(msg); + while(seg != NULL) { + struct msg_msgseg* tmp = seg->next; + kfree(seg); + seg = tmp; + } +} + +static struct msg_msg* load_msg(void* src, int len) +{ + struct msg_msg* msg; + struct msg_msgseg** pseg; + int err; + int alen; + + alen = len; + if(alen > DATALEN_MSG) + alen = DATALEN_MSG; + + msg = (struct msg_msg *) kmalloc (sizeof(*msg) + alen, GFP_KERNEL); + if(msg==NULL) + return ERR_PTR(-ENOMEM); + + msg->next = NULL; + + if (copy_from_user(msg+1, src, alen)) { + err = -EFAULT; + goto out_err; + } + + len -= alen; + src = ((char*)src)+alen; + pseg = &msg->next; + while(len > 0) { + struct msg_msgseg* seg; + alen = len; + if(alen > DATALEN_SEG) + alen = DATALEN_SEG; + seg = (struct msg_msgseg *) kmalloc (sizeof(*seg) + alen, GFP_KERNEL); + if(seg==NULL) { + err=-ENOMEM; + goto out_err; + } + *pseg = seg; + seg->next = NULL; + if(copy_from_user (seg+1, src, alen)) { + err = -EFAULT; + goto out_err; + } + pseg = &seg->next; + len -= alen; + src = ((char*)src)+alen; + } + return msg; + +out_err: + free_msg(msg); + return ERR_PTR(err); +} + +static int store_msg(void* dest, struct msg_msg* msg, int len) +{ + int alen; + struct msg_msgseg *seg; + + alen = len; + if(alen > DATALEN_MSG) + alen = DATALEN_MSG; + if(copy_to_user (dest, msg+1, alen)) + return -1; + + len -= alen; + dest = ((char*)dest)+alen; + seg = msg->next; + while(len > 0) { + alen = len; + if(alen > DATALEN_SEG) + alen = DATALEN_SEG; + if(copy_to_user (dest, seg+1, alen)) + return -1; + len -= alen; + dest = ((char*)dest)+alen; + seg=seg->next; + } + return 0; +} + +static inline void ss_add(struct msg_queue* msq, struct msg_sender* mss) +{ + mss->tsk=current; + current->state=TASK_INTERRUPTIBLE; + list_add_tail(&mss->list,&msq->q_senders); +} + +static inline void ss_del(struct msg_sender* mss) +{ + if(mss->list.next != NULL) + list_del(&mss->list); +} - if (id > msg_max_id) - msg_max_id = id; - spin_lock(&msg_que[id].lock); - msg_que[id].q = msq; - spin_unlock(&msg_que[id].lock); - msg_used_queues++; +static void ss_wakeup(struct list_head* h, int kill) +{ + struct list_head *tmp; - return (int)msq->q_perm.seq * MSGMNI + id; + tmp = h->next; + while (tmp != h) { + struct msg_sender* mss; + + mss = list_entry(tmp,struct msg_sender,list); + tmp = tmp->next; + if(kill) + mss->list.next=NULL; + wake_up_process(mss->tsk); + } } static void expunge_all(struct msg_queue* msq, int res) @@ -189,48 +283,32 @@ struct msg_queue *msq; struct list_head *tmp; - msq=msg_que[id].q; - msg_que[id].q = NULL; - if (id == msg_max_id) { - while ((msg_que[msg_max_id].q == NULL)) { - if(msg_max_id--== 0) - break; - } - } - msg_used_queues--; + msq = msg_rmid(id); expunge_all(msq,-EIDRM); - - while(waitqueue_active(&msq->q_rwait)) { - wake_up(&msq->q_rwait); - spin_unlock(&msg_que[id].lock); - current->policy |= SCHED_YIELD; - schedule(); - spin_lock(&msg_que[id].lock); - } - spin_unlock(&msg_que[id].lock); + ss_wakeup(&msq->q_senders,1); + msg_unlock(id); tmp = msq->q_messages.next; while(tmp != &msq->q_messages) { struct msg_msg* msg = list_entry(tmp,struct msg_msg,m_list); tmp = tmp->next; atomic_dec(&msg_hdrs); - kfree(msg); + free_msg(msg); } atomic_sub(msq->q_cbytes, &msg_bytes); kfree(msq); } - asmlinkage long sys_msgget (key_t key, int msgflg) { int id, ret = -EPERM; struct msg_queue *msq; - down(&msg_lock); + down(&msg_ids.sem); if (key == IPC_PRIVATE) ret = newque(key, msgflg); - else if ((id = findkey (key)) == -1) { /* key not used */ + else if ((id = ipc_findkey(&msg_ids, key)) == -1) { /* key not used */ if (!(msgflg & IPC_CREAT)) ret = -ENOENT; else @@ -238,55 +316,62 @@ } else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) { ret = -EEXIST; } else { - msq = msg_que[id].q; + msq = msg_lock(id); + if(msq==NULL) + BUG(); if (ipcperms(&msq->q_perm, msgflg)) ret = -EACCES; else - ret = (unsigned int) msq->q_perm.seq * MSGMNI + id; + ret = msg_buildid(id, msq->q_perm.seq); + msg_unlock(id); } - up(&msg_lock); + up(&msg_ids.sem); return ret; } asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds *buf) { - int id, err; + int err; struct msg_queue *msq; struct msqid_ds tbuf; struct ipc_perm *ipcp; if (msqid < 0 || cmd < 0) return -EINVAL; - id = msqid % MSGMNI; + switch (cmd) { case IPC_INFO: case MSG_INFO: { struct msginfo msginfo; + int max_id; if (!buf) return -EFAULT; /* We must not return kernel stack data. - * due to variable alignment, it's not enough + * due to padding, it's not enough * to set all member fields. */ memset(&msginfo,0,sizeof(msginfo)); - msginfo.msgmni = MSGMNI; - msginfo.msgmax = MSGMAX; - msginfo.msgmnb = MSGMNB; - msginfo.msgmap = MSGMAP; - msginfo.msgpool = MSGPOOL; - msginfo.msgtql = MSGTQL; + msginfo.msgmni = msg_ctlmni; + msginfo.msgmax = msg_ctlmax; + msginfo.msgmnb = msg_ctlmnb; msginfo.msgssz = MSGSSZ; msginfo.msgseg = MSGSEG; + down(&msg_ids.sem); if (cmd == MSG_INFO) { - msginfo.msgpool = msg_used_queues; + msginfo.msgpool = msg_ids.in_use; msginfo.msgmap = atomic_read(&msg_hdrs); msginfo.msgtql = atomic_read(&msg_bytes); + } else { + msginfo.msgmap = MSGMAP; + msginfo.msgpool = MSGPOOL; + msginfo.msgtql = MSGTQL; } - + max_id = msg_ids.max_id; + up(&msg_ids.sem); if (copy_to_user (buf, &msginfo, sizeof(struct msginfo))) return -EFAULT; - return (msg_max_id < 0) ? 0: msg_max_id; + return (max_id < 0) ? 0: max_id; } case MSG_STAT: case IPC_STAT: @@ -294,19 +379,18 @@ int success_return; if (!buf) return -EFAULT; - if(cmd == MSG_STAT && msqid > MSGMNI) + if(cmd == MSG_STAT && msqid > msg_ids.size) return -EINVAL; - spin_lock(&msg_que[id].lock); - msq = msg_que[id].q; - err = -EINVAL; + msq = msg_lock(msqid); if (msq == NULL) - goto out_unlock; + return -EINVAL; + if(cmd == MSG_STAT) { - success_return = (unsigned int) msq->q_perm.seq * MSGMNI + msqid; + success_return = msg_buildid(msqid, msq->q_perm.seq); } else { err = -EIDRM; - if (msq->q_perm.seq != (unsigned int) msqid / MSGMNI) + if (msg_checkid(msq,msqid)) goto out_unlock; success_return = 0; } @@ -339,7 +423,7 @@ tbuf.msg_lspid = msq->q_lspid; tbuf.msg_lrpid = msq->q_lrpid; - spin_unlock(&msg_que[id].lock); + msg_unlock(msqid); if (copy_to_user (buf, &tbuf, sizeof(*buf))) return -EFAULT; return success_return; @@ -356,32 +440,31 @@ return -EINVAL; } - down(&msg_lock); - spin_lock(&msg_que[id].lock); - msq = msg_que[id].q; - err = -EINVAL; + down(&msg_ids.sem); + msq = msg_lock(msqid); + err=-EINVAL; if (msq == NULL) - goto out_unlock_up; + goto out_up; + err = -EIDRM; - if (msq->q_perm.seq != (unsigned int) msqid / MSGMNI) + if (msg_checkid(msq,msqid)) goto out_unlock_up; ipcp = &msq->q_perm; + err = -EPERM; + if (current->euid != ipcp->cuid && + current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) + /* We _could_ check for CAP_CHOWN above, but we don't */ + goto out_unlock_up; switch (cmd) { case IPC_SET: { int newqbytes; - err = -EPERM; - if (current->euid != ipcp->cuid && - current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) - /* We _could_ check for CAP_CHOWN above, but we don't */ - goto out_unlock_up; - if(tbuf.msg_qbytes == 0) newqbytes = tbuf.msg_lqbytes; else newqbytes = tbuf.msg_qbytes; - if (newqbytes > MSGMNB && !capable(CAP_SYS_RESOURCE)) + if (newqbytes > msg_ctlmnb && !capable(CAP_SYS_RESOURCE)) goto out_unlock_up; msq->q_qbytes = newqbytes; @@ -397,27 +480,23 @@ /* sleeping senders might be able to send * due to a larger queue size. */ - wake_up(&msq->q_rwait); - spin_unlock(&msg_que[id].lock); + ss_wakeup(&msq->q_senders,0); + msg_unlock(msqid); break; } case IPC_RMID: - err = -EPERM; - if (current->euid != ipcp->cuid && - current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) - goto out_unlock; - freeque (id); + freeque (msqid); break; } err = 0; out_up: - up(&msg_lock); + up(&msg_ids.sem); return err; out_unlock_up: - spin_unlock(&msg_que[id].lock); + msg_unlock(msqid); goto out_up; out_unlock: - spin_unlock(&msg_que[id].lock); + msg_unlock(msqid); return err; } @@ -471,67 +550,61 @@ asmlinkage long sys_msgsnd (int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg) { - int id; struct msg_queue *msq; struct msg_msg *msg; long mtype; int err; - if (msgsz > MSGMAX || (long) msgsz < 0 || msqid < 0) + if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0) return -EINVAL; if (get_user(mtype, &msgp->mtype)) return -EFAULT; if (mtype < 1) return -EINVAL; - msg = (struct msg_msg *) kmalloc (sizeof(*msg) + msgsz, GFP_KERNEL); - if(msg==NULL) - return -ENOMEM; + msg = load_msg(msgp->mtext, msgsz); + if(IS_ERR(msg)) + return PTR_ERR(msg); - if (copy_from_user(msg+1, msgp->mtext, msgsz)) { - kfree(msg); - return -EFAULT; - } msg->m_type = mtype; msg->m_ts = msgsz; - id = (unsigned int) msqid % MSGMNI; - spin_lock(&msg_que[id].lock); - err= -EINVAL; -retry: - msq = msg_que[id].q; - if (msq == NULL) + msq = msg_lock(msqid); + err=-EINVAL; + if(msq==NULL) goto out_free; - +retry: err= -EIDRM; - if (msq->q_perm.seq != (unsigned int) msqid / MSGMNI) - goto out_free; + if (msg_checkid(msq,msqid)) + goto out_unlock_free; err=-EACCES; if (ipcperms(&msq->q_perm, S_IWUGO)) - goto out_free; + goto out_unlock_free; - if(msgsz + msq->q_cbytes > msq->q_qbytes) { - DECLARE_WAITQUEUE(wait,current); + if(msgsz + msq->q_cbytes > msq->q_qbytes || + 1 + msq->q_qnum > msq->q_qbytes) { + struct msg_sender s; if(msgflg&IPC_NOWAIT) { err=-EAGAIN; - goto out_free; + goto out_unlock_free; } - current->state = TASK_INTERRUPTIBLE; - add_wait_queue(&msq->q_rwait,&wait); - spin_unlock(&msg_que[id].lock); + ss_add(msq, &s); + msg_unlock(msqid); schedule(); current->state= TASK_RUNNING; + + msq = msg_lock(msqid); + err = -EIDRM; + if(msq==NULL) + goto out_free; + ss_del(&s); - remove_wait_queue(&msq->q_rwait,&wait); if (signal_pending(current)) { - kfree(msg); - return -EINTR; + err=-EINTR; + goto out_unlock_free; } - - spin_lock(&msg_que[id].lock); - err = -EIDRM; goto retry; } @@ -549,10 +622,11 @@ msq->q_lspid = current->pid; msq->q_stime = CURRENT_TIME; +out_unlock_free: + msg_unlock(msqid); out_free: if(msg!=NULL) - kfree(msg); - spin_unlock(&msg_que[id].lock); + free_msg(msg); return err; } @@ -582,7 +656,6 @@ struct msg_receiver msr_d; struct list_head* tmp; struct msg_msg* msg, *found_msg; - int id; int err; int mode; @@ -590,13 +663,10 @@ return -EINVAL; mode = convert_mode(&msgtyp,msgflg); - id = (unsigned int) msqid % MSGMNI; - spin_lock(&msg_que[id].lock); + msq = msg_lock(msqid); + if(msq==NULL) + return -EINVAL; retry: - msq = msg_que[id].q; - err=-EINVAL; - if (msq == NULL) - goto out_unlock; err=-EACCES; if (ipcperms (&msq->q_perm, S_IRUGO)) goto out_unlock; @@ -630,21 +700,19 @@ msq->q_cbytes -= msg->m_ts; atomic_sub(msg->m_ts,&msg_bytes); atomic_dec(&msg_hdrs); - if(waitqueue_active(&msq->q_rwait)) - wake_up(&msq->q_rwait); -out_success_unlock: - spin_unlock(&msg_que[id].lock); + ss_wakeup(&msq->q_senders,0); + msg_unlock(msqid); out_success: msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; if (put_user (msg->m_type, &msgp->mtype) || - copy_to_user (msgp->mtext, msg+1, msgsz)) - { + store_msg(msgp->mtext, msg, msgsz)) { msgsz = -EFAULT; } - kfree(msg); + free_msg(msg); return msgsz; } else { + struct msg_queue *t; /* no message waiting. Prepare for pipelined * receive. */ @@ -657,12 +725,13 @@ msr_d.r_msgtype = msgtyp; msr_d.r_mode = mode; if(msgflg & MSG_NOERROR) - msr_d.r_maxsize = MSGMAX; + msr_d.r_maxsize = INT_MAX; else msr_d.r_maxsize = msgsz; msr_d.r_msg = ERR_PTR(-EAGAIN); current->state = TASK_INTERRUPTIBLE; - spin_unlock(&msg_que[id].lock); + msg_unlock(msqid); + schedule(); current->state = TASK_RUNNING; @@ -670,16 +739,22 @@ if(!IS_ERR(msg)) goto out_success; - spin_lock(&msg_que[id].lock); + t = msg_lock(msqid); + if(t==NULL) + msqid=-1; msg = (struct msg_msg*)msr_d.r_msg; if(!IS_ERR(msg)) { /* our message arived while we waited for * the spinlock. Process it. */ - goto out_success_unlock; + if(msqid!=-1) + msg_unlock(msqid); + goto out_success; } err = PTR_ERR(msg); if(err == -EAGAIN) { + if(msqid==-1) + BUG(); list_del(&msr_d.r_list); if (signal_pending(current)) err=-EINTR; @@ -688,7 +763,8 @@ } } out_unlock: - spin_unlock(&msg_que[id].lock); + if(msqid!=-1) + msg_unlock(msqid); return err; } @@ -699,28 +775,29 @@ off_t begin = 0; int i, len = 0; - down(&msg_lock); + down(&msg_ids.sem); len += sprintf(buffer, " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n"); - for(i = 0; i <= msg_max_id; i++) { - spin_lock(&msg_que[i].lock); - if(msg_que[i].q != NULL) { + for(i = 0; i <= msg_ids.max_id; i++) { + struct msg_queue * msq; + msq = msg_lock(i); + if(msq != NULL) { len += sprintf(buffer + len, "%10d %10d %4o %5u %5u %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", - msg_que[i].q->q_perm.key, - msg_que[i].q->q_perm.seq * MSGMNI + i, - msg_que[i].q->q_perm.mode, - msg_que[i].q->q_cbytes, - msg_que[i].q->q_qnum, - msg_que[i].q->q_lspid, - msg_que[i].q->q_lrpid, - msg_que[i].q->q_perm.uid, - msg_que[i].q->q_perm.gid, - msg_que[i].q->q_perm.cuid, - msg_que[i].q->q_perm.cgid, - msg_que[i].q->q_stime, - msg_que[i].q->q_rtime, - msg_que[i].q->q_ctime); - spin_unlock(&msg_que[i].lock); + msq->q_perm.key, + msg_buildid(i,msq->q_perm.seq), + msq->q_perm.mode, + msq->q_cbytes, + msq->q_qnum, + msq->q_lspid, + msq->q_lrpid, + msq->q_perm.uid, + msq->q_perm.gid, + msq->q_perm.cuid, + msq->q_perm.cgid, + msq->q_stime, + msq->q_rtime, + msq->q_ctime); + msg_unlock(i); pos += len; if(pos < offset) { @@ -729,13 +806,12 @@ } if(pos > offset + length) goto done; - } else { - spin_unlock(&msg_que[i].lock); } + } *eof = 1; done: - up(&msg_lock); + up(&msg_ids.sem); *start = buffer + (offset - begin); len -= (offset - begin); if(len > length) @@ -745,4 +821,3 @@ return len; } #endif - diff -u --recursive --new-file v2.3.26/linux/ipc/sem.c linux/ipc/sem.c --- v2.3.26/linux/ipc/sem.c Mon Nov 1 13:56:27 1999 +++ linux/ipc/sem.c Tue Nov 9 10:02:36 1999 @@ -51,7 +51,8 @@ * * /proc/sysvipc/sem support (c) 1999 Dragos Acostachioaie * - * SMP-threaded (c) 1999 Manfred Spraul + * SMP-threaded, sysctl's added + * (c) 1999 Manfred Spraul */ #include @@ -59,120 +60,91 @@ #include #include #include - #include +#include "util.h" + + +#define sem_lock(id) ((struct semid_ds*)ipc_lock(&sem_ids,id)) +#define sem_unlock(id) ipc_unlock(&sem_ids,id) +#define sem_rmid(id) ((struct semid_ds*)ipc_rmid(&sem_ids,id)) +#define sem_checkid(sma, semid) \ + ipc_checkid(&sem_ids,&sma->sem_perm,semid) +#define sem_buildid(id, seq) \ + ipc_buildid(&sem_ids, id, seq) +static struct ipc_ids sem_ids; -extern int ipcperms (struct ipc_perm *ipcp, short semflg); static int newary (key_t, int, int); -static int findkey (key_t key); static void freeary (int id); #ifdef CONFIG_PROC_FS static int sysvipc_sem_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data); #endif -struct semid_ary -{ - spinlock_t lock; - struct semid_ds* s; -}; - -static struct semid_ary semary[SEMMNI]; - -static DECLARE_MUTEX(sem_lock); -static int max_semid = 0; -static int used_sems = 0; -static int used_semids = 0; - -static unsigned short sem_seq = 0; +#define SEMMSL_FAST 256 /* 512 bytes on stack */ +#define SEMOPM_FAST 64 /* ~ 372 bytes on stack */ -/* anti-deadlock ordering: - * sem_lock < semary[].lock +/* * linked list protection: * sem_undo.id_next, * semid_ds.sem_pending{,last}, - * semid_ds.sem_undo: semary[].lock for read/write + * semid_ds.sem_undo: sem_lock() for read/write * sem_undo.proc_next: only "current" is allowed to read/write that field. * */ +int sem_ctls[4] = {SEMMSL, SEMMNS, SEMOPM, SEMMNI}; +#define sc_semmsl (sem_ctls[0]) +#define sc_semmns (sem_ctls[1]) +#define sc_semopm (sem_ctls[2]) +#define sc_semmni (sem_ctls[3]) + +static int used_sems = 0; + void __init sem_init (void) { - int i; + used_sems = 0; + ipc_init_ids(&sem_ids,sc_semmni); - used_sems = used_semids = max_semid = sem_seq = 0; - for (i = 0; i < SEMMNI; i++) { - semary[i].lock = SPIN_LOCK_UNLOCKED; - semary[i].s = NULL; - } #ifdef CONFIG_PROC_FS create_proc_read_entry("sysvipc/sem", 0, 0, sysvipc_sem_read_proc, NULL); #endif - return; -} - -static int findkey (key_t key) -{ - int id; - struct semid_ds *sma; - - for (id = 0; id <= max_semid; id++) { - sma = semary[id].s; - if(sma==NULL) - continue; - - if (key == sma->sem_perm.key) - return id; - } - return -1; } static int newary (key_t key, int nsems, int semflg) { int id; struct semid_ds *sma; - struct ipc_perm *ipcp; int size; if (!nsems) return -EINVAL; - if (used_sems + nsems > SEMMNS) + if (used_sems + nsems > sc_semmns) return -ENOSPC; - for (id = 0; id < SEMMNI; id++) { - if(semary[id].s == NULL) - goto found; - } - return -ENOSPC; -found: + size = sizeof (*sma) + nsems * sizeof (struct sem); - used_sems += nsems; - sma = (struct semid_ds *) kmalloc (size, GFP_KERNEL); + sma = (struct semid_ds *) ipc_alloc(size); if (!sma) { - used_sems -= nsems; return -ENOMEM; } memset (sma, 0, size); + id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni); + if(id == -1) { + ipc_free(sma, size); + return -ENOSPC; + } + used_sems += nsems; + + sma->sem_perm.mode = (semflg & S_IRWXUGO); + sma->sem_perm.key = key; + sma->sem_base = (struct sem *) &sma[1]; - ipcp = &sma->sem_perm; - ipcp->mode = (semflg & S_IRWXUGO); - ipcp->key = key; - ipcp->cuid = ipcp->uid = current->euid; - ipcp->gid = ipcp->cgid = current->egid; - /* sma->sem_perm.seq*MSGMNI must be a positive integer. - * this limits MSGMNI to 32768 - */ - sma->sem_perm.seq = sem_seq++; /* sma->sem_pending = NULL; */ sma->sem_pending_last = &sma->sem_pending; /* sma->undo = NULL; */ sma->sem_nsems = nsems; sma->sem_ctime = CURRENT_TIME; - if (id > max_semid) - max_semid = id; - used_semids++; - spin_lock(&semary[id].lock); - semary[id].s = sma; - spin_unlock(&semary[id].lock); - return (unsigned int) sma->sem_perm.seq * SEMMNI + id; + sem_unlock(id); + + return sem_buildid(id, sma->sem_perm.seq); } asmlinkage long sys_semget (key_t key, int nsems, int semflg) @@ -180,13 +152,13 @@ int id, err = -EINVAL; struct semid_ds *sma; - if (nsems < 0 || nsems > SEMMSL) + if (nsems < 0 || nsems > sc_semmsl) return -EINVAL; - down(&sem_lock); + down(&sem_ids.sem); if (key == IPC_PRIVATE) { err = newary(key, nsems, semflg); - } else if ((id = findkey (key)) == -1) { /* key not used */ + } else if ((id = ipc_findkey(&sem_ids, key)) == -1) { /* key not used */ if (!(semflg & IPC_CREAT)) err = -ENOENT; else @@ -194,19 +166,46 @@ } else if (semflg & IPC_CREAT && semflg & IPC_EXCL) { err = -EEXIST; } else { - sma = semary[id].s; + sma = sem_lock(id); + if(sma==NULL) + BUG(); if (nsems > sma->sem_nsems) err = -EINVAL; else if (ipcperms(&sma->sem_perm, semflg)) err = -EACCES; else - err = (int) sma->sem_perm.seq * SEMMNI + id; + err = sem_buildid(id, sma->sem_perm.seq); + sem_unlock(id); } - up(&sem_lock); + up(&sem_ids.sem); return err; } +/* doesn't acquire the sem_lock on error! */ +static int sem_revalidate(int semid, struct semid_ds* sma, int nsems, short flg) +{ + struct semid_ds* smanew; + + smanew = sem_lock(semid); + if(smanew==NULL) + return -EIDRM; + if(smanew != sma) + goto out_EIDRM; + if(sem_checkid(sma,semid)) + goto out_EIDRM; + if(sma->sem_nsems != nsems) { +out_EIDRM: + sem_unlock(semid); + return -EIDRM; + } + + if (ipcperms(&sma->sem_perm, flg)) { + sem_unlock(semid); + return -EACCES; + } + return 0; +} /* Manage the doubly linked list sma->sem_pending as a FIFO: * insert new queue elements at the tail sma->sem_pending_last. */ @@ -387,15 +386,9 @@ struct semid_ds *sma; struct sem_undo *un; struct sem_queue *q; + int size; - /* we own both locks, noone can get in */ - sma = semary[id].s; - semary[id].s = NULL; - - used_sems -= sma->sem_nsems; - if (id == max_semid) - while (max_semid && (semary[--max_semid].s == NULL)); - used_semids--; + sma = sem_rmid(id); /* Invalidate the existing undo structures for this semaphore set. * (They will be freed without any further action in sem_exit() @@ -410,40 +403,46 @@ q->prev = NULL; wake_up_process(q->sleeper); /* doesn't sleep */ } + sem_unlock(id); - kfree(sma); + used_sems -= sma->sem_nsems; + size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem); + ipc_free(sma, size); } int semctl_nolock(int semid, int semnum, int cmd, union semun arg) { int err = -EINVAL; - int lid = semid % SEMMNI; switch(cmd) { case IPC_INFO: case SEM_INFO: { struct seminfo seminfo; + int max_id; - seminfo.semmni = SEMMNI; - seminfo.semmns = SEMMNS; - seminfo.semmsl = SEMMSL; - seminfo.semopm = SEMOPM; + memset(&seminfo,0,sizeof(seminfo)); + seminfo.semmni = sc_semmni; + seminfo.semmns = sc_semmns; + seminfo.semmsl = sc_semmsl; + seminfo.semopm = sc_semopm; seminfo.semvmx = SEMVMX; seminfo.semmnu = SEMMNU; seminfo.semmap = SEMMAP; seminfo.semume = SEMUME; - seminfo.semusz = SEMUSZ; - seminfo.semaem = SEMAEM; + down(&sem_ids.sem); if (cmd == SEM_INFO) { - down(&sem_lock); - seminfo.semusz = used_semids; + seminfo.semusz = sem_ids.in_use; seminfo.semaem = used_sems; - up(&sem_lock); + } else { + seminfo.semusz = SEMUSZ; + seminfo.semaem = SEMAEM; } + max_id = sem_ids.max_id; + up(&sem_ids.sem); if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) return -EFAULT; - return max_semid; + return (max_id < 0) ? 0: max_id; } case SEM_STAT: { @@ -451,24 +450,24 @@ struct semid_ds tbuf; int id; - if (semid > max_semid) + if(semid > sem_ids.size) + return -EINVAL; + + sma = sem_lock(semid); + if(sma == NULL) return -EINVAL; - spin_lock(&semary[lid].lock); - err = -EINVAL; - sma = semary[semid].s; - if (sma == NULL) - goto out_unlock; err = -EACCES; if (ipcperms (&sma->sem_perm, S_IRUGO)) goto out_unlock; - id = (unsigned int) sma->sem_perm.seq * SEMMNI + semid; + id = sem_buildid(semid, sma->sem_perm.seq); + memset(&tbuf,0,sizeof(tbuf)); tbuf.sem_perm = sma->sem_perm; tbuf.sem_otime = sma->sem_otime; tbuf.sem_ctime = sma->sem_ctime; tbuf.sem_nsems = sma->sem_nsems; - spin_unlock(&semary[lid].lock); + sem_unlock(semid); if (copy_to_user (arg.buf, &tbuf, sizeof(tbuf))) return -EFAULT; return id; @@ -478,99 +477,136 @@ } return err; out_unlock: - spin_unlock(&semary[lid].lock); + sem_unlock(semid); return err; } -int semctl_locked_unlock(int semid, int semnum, int cmd, union semun arg) +int semctl_main(int semid, int semnum, int cmd, union semun arg) { struct semid_ds *sma; - struct semid_ds tbuf; + struct sem* curr; int err; - int lid = semid % SEMMNI; + ushort fast_sem_io[SEMMSL_FAST]; + ushort* sem_io = fast_sem_io; + int nsems; + + sma = sem_lock(semid); + if(sma==NULL) + return -EINVAL; - sma = semary[lid].s; - err=-EINVAL; - if (sma == NULL) - goto out_unlock; err=-EIDRM; - if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI) + if (sem_checkid(sma,semid)) goto out_unlock; err = -EACCES; - if (ipcperms(&sma->sem_perm, S_IRUGO)) - goto out_unlock; - + if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO)) + goto out_unlock; + + nsems = sma->sem_nsems; switch (cmd) { case GETALL: { ushort *array = arg.array; - ushort sem_io[SEMMSL]; int i; - int nsems = sma->sem_nsems; + + if(nsems > SEMMSL_FAST) { + sem_unlock(semid); + sem_io = ipc_alloc(sizeof(ushort)*nsems); + if(sem_io == NULL) + return -ENOMEM; + err = sem_revalidate(semid, sma, nsems, S_IRUGO); + if(err) + goto out_free; + } for (i = 0; i < sma->sem_nsems; i++) sem_io[i] = sma->sem_base[i].semval; - spin_unlock(&semary[lid].lock); - if (copy_to_user (array, sem_io, nsems*sizeof(ushort))) - return -EFAULT; - return 0; + sem_unlock(semid); + err = 0; + if(copy_to_user(array, sem_io, nsems*sizeof(ushort))) + err = -EFAULT; + goto out_free; + } + case SETALL: + { + int i; + struct sem_undo *un; + + sem_unlock(semid); + + if(nsems > SEMMSL_FAST) { + sem_io = ipc_alloc(sizeof(ushort)*nsems); + if(sem_io == NULL) + return -ENOMEM; + } + + if (copy_from_user (sem_io, arg.array, nsems*sizeof(ushort))) { + err = -EFAULT; + goto out_free; + } + + for (i = 0; i < nsems; i++) { + if (sem_io[i] > SEMVMX) { + err = -ERANGE; + goto out_free; + } + } + err = sem_revalidate(semid, sma, nsems, S_IWUGO); + if(err) + goto out_free; + + for (i = 0; i < nsems; i++) + sma->sem_base[i].semval = sem_io[i]; + for (un = sma->undo; un; un = un->id_next) + for (i = 0; i < nsems; i++) + un->semadj[i] = 0; + sma->sem_ctime = CURRENT_TIME; + /* maybe some queued-up processes were waiting for this */ + update_queue(sma); + err = 0; + goto out_unlock; } case IPC_STAT: + { + struct semid_ds tbuf; memset(&tbuf,0,sizeof(tbuf)); tbuf.sem_perm = sma->sem_perm; tbuf.sem_otime = sma->sem_otime; tbuf.sem_ctime = sma->sem_ctime; tbuf.sem_nsems = sma->sem_nsems; - spin_unlock(&semary[lid].lock); + sem_unlock(semid); if (copy_to_user (arg.buf, &tbuf, sizeof(tbuf))) return -EFAULT; return 0; -default: - err = -EINVAL; } -out_unlock: - spin_unlock(&semary[lid].lock); - return err; - -} - -int semctl_locked(int semid, int semnum, int cmd, union semun arg) -{ - struct semid_ds *sma; - int lid = semid % SEMMNI; - struct sem *curr; - - sma = semary[lid].s; - if (sma == NULL) - return -EINVAL; - - if (ipcperms (&sma->sem_perm, (cmd==SETVAL)?S_IWUGO:S_IRUGO)) - return -EACCES; - - if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI) - return -EIDRM; - - if (semnum >= sma->sem_nsems) - return -EINVAL; + /* GETVAL, GETPID, GETNCTN, GETZCNT, SETVAL: fall-through */ + } + err = -EINVAL; + if(semnum < 0 || semnum >= nsems) + goto out_unlock; curr = &sma->sem_base[semnum]; switch (cmd) { case GETVAL: - return curr->semval; + err = curr->semval; + goto out_unlock; case GETPID: - return curr->sempid & 0xffff; + err = curr->sempid & 0xffff; + goto out_unlock; case GETNCNT: - return count_semncnt(sma,semnum); + err = count_semncnt(sma,semnum); + goto out_unlock; case GETZCNT: - return count_semzcnt(sma,semnum); + err = count_semzcnt(sma,semnum); + goto out_unlock; case SETVAL: { int val = arg.val; struct sem_undo *un; + err = -ERANGE; if (val > SEMVMX || val < 0) - return -ERANGE; + goto out_unlock; for (un = sma->undo; un; un = un->id_next) un->semadj[semnum] = 0; @@ -578,17 +614,22 @@ sma->sem_ctime = CURRENT_TIME; /* maybe some queued-up processes were waiting for this */ update_queue(sma); - return 0; + err = 0; + goto out_unlock; } } - return -EINVAL; +out_unlock: + sem_unlock(semid); +out_free: + if(sem_io != fast_sem_io) + ipc_free(sem_io, sizeof(ushort)*nsems); + return err; } int semctl_down(int semid, int semnum, int cmd, union semun arg) { struct semid_ds *sma; int err; - int lid = semid % SEMMNI; struct semid_ds tbuf; struct ipc_perm *ipcp; @@ -596,66 +637,25 @@ if(copy_from_user (&tbuf, arg.buf, sizeof (tbuf))) return -EFAULT; } - spin_lock(&semary[lid].lock); - sma = semary[lid].s; - err=-EINVAL; - if (sma == NULL) + sma = sem_lock(semid); + if(sma==NULL) + return -EINVAL; + + if (sem_checkid(sma,semid)) { + err=-EIDRM; goto out_unlock; + } ipcp = &sma->sem_perm; - if(cmd == SETALL) { - int i; - struct sem_undo *un; - unsigned int nsems; - ushort sem_io[SEMMSL]; - /* SETALL doesn't belong into this - * group, but I need the semaphore - * for atomically reading nsems - * and changing the semaphore values - */ - err=-EACCES; - if (ipcperms (ipcp, S_IWUGO)) - goto out_unlock; - nsems=sma->sem_nsems; - spin_unlock(&semary[lid].lock); - - if (copy_from_user (sem_io, arg.array, nsems*sizeof(ushort))) - return -EFAULT; - for (i = 0; i < nsems; i++) { - if (sem_io[i] > SEMVMX) { - return -ERANGE; - } - } - /* we still own sem_lock, ie neither ownership - * nor permissions of the sem array could - * have changed. Just continue. - */ - spin_lock(&semary[lid].lock); - for (i = 0; i < nsems; i++) - sma->sem_base[i].semval = sem_io[i]; - for (un = sma->undo; un; un = un->id_next) - for (i = 0; i < nsems; i++) - un->semadj[i] = 0; - sma->sem_ctime = CURRENT_TIME; - /* maybe some queued-up processes were waiting for this */ - update_queue(sma); - err = 0; - goto out_unlock; - } - if (current->euid != ipcp->cuid && current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) { err=-EPERM; goto out_unlock; } - - if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI) { - err=-EIDRM; - goto out_unlock; - } + switch(cmd){ case IPC_RMID: - freeary(lid); + freeary(semid); err = 0; break; case IPC_SET: @@ -664,27 +664,28 @@ ipcp->mode = (ipcp->mode & ~S_IRWXUGO) | (tbuf.sem_perm.mode & S_IRWXUGO); sma->sem_ctime = CURRENT_TIME; + sem_unlock(semid); err = 0; break; default: + sem_unlock(semid); err = -EINVAL; + break; } + return err; out_unlock: - spin_unlock(&semary[lid].lock); + sem_unlock(semid); return err; } asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) { - int lid; /* lock id */ int err = -EINVAL; - if (semid < 0 || semnum < 0 || cmd < 0) + if (semid < 0) return -EINVAL; - lid = semid % SEMMNI; - switch(cmd) { case IPC_INFO: case SEM_INFO: @@ -692,25 +693,20 @@ err = semctl_nolock(semid,semnum,cmd,arg); return err; case GETALL: - case IPC_STAT: - spin_lock(&semary[lid].lock); - err = semctl_locked_unlock(semid,semnum,cmd,arg); - return err; case GETVAL: case GETPID: case GETNCNT: case GETZCNT: + case IPC_STAT: case SETVAL: - spin_lock(&semary[lid].lock); - err= semctl_locked(semid,semnum,cmd,arg); - spin_unlock(&semary[lid].lock); - return err; case SETALL: + err = semctl_main(semid,semnum,cmd,arg); + return err; case IPC_RMID: case IPC_SET: - down(&sem_lock); - err= semctl_down(semid,semnum,cmd,arg); - up(&sem_lock); + down(&sem_ids.sem); + err = semctl_down(semid,semnum,cmd,arg); + up(&sem_ids.sem); return err; default: return -EINVAL; @@ -734,33 +730,27 @@ return un->proc_next; } +/* returns without sem_lock on error! */ static int alloc_undo(struct semid_ds *sma, struct sem_undo** unp, int semid, int alter) { - int size; + int size, nsems, error; struct sem_undo *un; - int error,id; - id = (unsigned int) semid % SEMMNI; - size = sizeof(struct sem_undo) + sizeof(short)*sma->sem_nsems; - spin_unlock(&semary[id].lock); + + nsems = sma->sem_nsems; + size = sizeof(struct sem_undo) + sizeof(short)*nsems; + sem_unlock(semid); un = (struct sem_undo *) kmalloc(size, GFP_KERNEL); - spin_lock(&semary[id].lock); - if (!un) { + if (!un) return -ENOMEM; - } - sma = semary[id].s; - error = -EIDRM; - if (sma == NULL) - goto out; - if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI) - goto out; - if (size != sizeof(struct sem_undo) + sizeof(short)*sma->sem_nsems) - goto out; - error = -EACCES; - if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) - goto out; memset(un, 0, size); + error = sem_revalidate(semid, sma, nsems, alter ? S_IWUGO : S_IRUGO); + if(error) { + kfree(un); + return error; + } + un->semadj = (short *) &un[1]; un->semid = semid; un->proc_next = current->semundo; @@ -769,42 +759,42 @@ sma->undo = un; *unp = un; return 0; -out: - kfree(un); - return error; } asmlinkage long sys_semop (int semid, struct sembuf *tsops, unsigned nsops) { - int id, error = -EINVAL; + int error = -EINVAL; struct semid_ds *sma; - struct sembuf sops[SEMOPM], *sop; + struct sembuf fast_sops[SEMOPM_FAST]; + struct sembuf* sops = fast_sops, *sop; struct sem_undo *un; int undos = 0, decrease = 0, alter = 0; struct sem_queue queue; if (nsops < 1 || semid < 0) return -EINVAL; - - if (nsops > SEMOPM) + if (nsops > sc_semopm) return -E2BIG; - if (copy_from_user (sops, tsops, nsops * sizeof(*tsops))) - return -EFAULT; - - id = (unsigned int) semid % SEMMNI; - spin_lock(&semary[id].lock); - sma = semary[id].s; - error = -EINVAL; - if (sma == NULL) - goto out; + if(nsops > SEMOPM_FAST) { + sops = kmalloc(sizeof(*sops)*nsops,GFP_KERNEL); + if(sops==NULL) + return -ENOMEM; + } + if (copy_from_user (sops, tsops, nsops * sizeof(*tsops))) { + error=-EFAULT; + goto out_free; + } + sma = sem_lock(semid); + error=-EINVAL; + if(sma==NULL) + goto out_free; error = -EIDRM; - if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI) - goto out; - + if (sem_checkid(sma,semid)) + goto out_unlock_free; error = -EFBIG; for (sop = sops; sop < sops + nsops; sop++) { if (sop->sem_num >= sma->sem_nsems) - goto out; + goto out_unlock_free; if (sop->sem_flg & SEM_UNDO) undos++; if (sop->sem_op < 0) @@ -816,7 +806,7 @@ error = -EACCES; if (ipcperms(&sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) - goto out; + goto out_unlock_free; if (undos) { /* Make sure we have an undo structure * for this process and this semaphore set. @@ -832,8 +822,8 @@ } if (!un) { error = alloc_undo(sma,&un,semid,alter); - if(error<0) - goto out; + if(error) + goto out_free; } } else un = NULL; @@ -852,25 +842,30 @@ queue.undo = un; queue.pid = current->pid; queue.alter = decrease; - queue.id = id; - current->semsleeping = &queue; + queue.id = semid; if (alter) append_to_queue(sma ,&queue); else prepend_to_queue(sma ,&queue); + current->semsleeping = &queue; for (;;) { + struct semid_ds* tmp; queue.status = -EINTR; queue.sleeper = current; current->state = TASK_INTERRUPTIBLE; - spin_unlock(&semary[id].lock); + sem_unlock(semid); schedule(); - /* we can lock the semary even if it was - * deleted. - */ - spin_lock(&semary[id].lock); + tmp = sem_lock(semid); + if(tmp==NULL) { + if(queue.status != -EIDRM) + BUG(); + current->semsleeping = NULL; + error = -EIDRM; + goto out_free; + } /* * If queue.status == 1 we where woken up and * have to retry else we simply return. @@ -890,7 +885,7 @@ break; /* Everything done by update_queue */ current->semsleeping = NULL; - goto out; + goto out_unlock_free; } } current->semsleeping = NULL; @@ -898,8 +893,11 @@ update: if (alter) update_queue (sma); -out: - spin_unlock(&semary[id].lock); +out_unlock_free: + sem_unlock(semid); +out_free: + if(sops != fast_sops) + kfree(sops); return error; } @@ -925,34 +923,32 @@ /* If the current process was sleeping for a semaphore, * remove it from the queue. */ - /* semsleeping is part of "current", and it - * is never modified by another thread. - * No synchronization required. - */ if ((q = current->semsleeping)) { - spin_lock(&semary[current->semsleeping->id].lock); + int semid = q->id; + sma = sem_lock(semid); + current->semsleeping = NULL; - if (q->prev) + if (q->prev) { + if(sma==NULL) + BUG(); remove_from_queue(q->sma,q); - current->semsleeping = NULL; - spin_unlock(&semary[current->semsleeping->id].lock); + } + if(sma!=NULL) + sem_unlock(semid); } for (up = ¤t->semundo; (u = *up); *up = u->proc_next, kfree(u)) { int semid = u->semid; - int lid; if(semid == -1) continue; - lid = semid % SEMMNI; - spin_lock(&semary[lid].lock); + sma = sem_lock(semid); + if (sma == NULL) + continue; if (u->semid == -1) goto next_entry; - sma = semary[lid].s; - if (sma == NULL) - goto next_entry; - if (sma->sem_perm.seq != (unsigned int) u->semid / SEMMNI) + if (sem_checkid(sma,u->semid)) goto next_entry; /* remove u from the sma->undo list */ @@ -977,7 +973,7 @@ /* maybe some queued-up processes were waiting for this */ update_queue(sma); next_entry: - spin_unlock(&semary[lid].lock); + sem_unlock(semid); } current->semundo = NULL; } @@ -990,35 +986,37 @@ int i, len = 0; len += sprintf(buffer, " key semid perms nsems uid gid cuid cgid otime ctime\n"); - down(&sem_lock); + down(&sem_ids.sem); - for(i = 0; i < SEMMNI; i++) - if(semary[i].s != NULL) { - spin_lock(&semary[i].lock); + for(i = 0; i <= sem_ids.max_id; i++) { + struct semid_ds *sma; + sma = sem_lock(i); + if(sma) { len += sprintf(buffer + len, "%10d %10d %4o %5u %5u %5u %5u %5u %10lu %10lu\n", - semary[i].s->sem_perm.key, - semary[i].s->sem_perm.seq * SEMMNI + i, - semary[i].s->sem_perm.mode, - semary[i].s->sem_nsems, - semary[i].s->sem_perm.uid, - semary[i].s->sem_perm.gid, - semary[i].s->sem_perm.cuid, - semary[i].s->sem_perm.cgid, - semary[i].s->sem_otime, - semary[i].s->sem_ctime); - spin_unlock(&semary[i].lock); + sma->sem_perm.key, + sem_buildid(i,sma->sem_perm.seq), + sma->sem_perm.mode, + sma->sem_nsems, + sma->sem_perm.uid, + sma->sem_perm.gid, + sma->sem_perm.cuid, + sma->sem_perm.cgid, + sma->sem_otime, + sma->sem_ctime); + sem_unlock(i); pos += len; if(pos < offset) { len = 0; - begin = pos; + begin = pos; } if(pos > offset + length) goto done; } + } *eof = 1; done: - up(&sem_lock); + up(&sem_ids.sem); *start = buffer + (offset - begin); len -= (offset - begin); if(len > length) diff -u --recursive --new-file v2.3.26/linux/ipc/shm.c linux/ipc/shm.c --- v2.3.26/linux/ipc/shm.c Sun Nov 7 16:37:34 1999 +++ linux/ipc/shm.c Thu Nov 11 16:45:25 1999 @@ -36,6 +36,7 @@ pte_t **shm_dir; /* ptr to array of ptrs to frames -> SHMMAX */ struct vm_area_struct *attaches; /* descriptors for attaches */ int id; /* backreference to id for shm_close */ + struct semaphore sem; }; static int findkey (key_t key); @@ -61,6 +62,9 @@ static unsigned int num_segs = 0; static unsigned short shm_seq = 0; /* incremented, for recognizing stale ids */ +/* locks order: + shm_lock -> pagecache_lock (end of shm_swap) + shp->sem -> other spinlocks (shm_nopage) */ spinlock_t shm_lock = SPIN_LOCK_UNLOCKED; /* some statistics */ @@ -260,6 +264,7 @@ shp->u.shm_ctime = CURRENT_TIME; shp->shm_npages = numpages; shp->id = id; + init_MUTEX(&shp->sem); spin_lock(&shm_lock); @@ -770,19 +775,20 @@ idx = (address - shmd->vm_start) >> PAGE_SHIFT; idx += shmd->vm_pgoff; + down(&shp->sem); spin_lock(&shm_lock); -again: pte = SHM_ENTRY(shp,idx); if (!pte_present(pte)) { + /* page not present so shm_swap can't race with us + and the semaphore protects us by other tasks that + could potentially fault on our pte under us */ if (pte_none(pte)) { spin_unlock(&shm_lock); - page = get_free_highpage(GFP_HIGHUSER); + page = alloc_page(GFP_HIGHUSER); if (!page) goto oom; clear_highpage(page); spin_lock(&shm_lock); - if (pte_val(pte) != pte_val(SHM_ENTRY(shp, idx))) - goto changed; } else { swp_entry_t entry = pte_to_swp_entry(pte); @@ -803,9 +809,6 @@ unlock_kernel(); spin_lock(&shm_lock); shm_swp--; - pte = SHM_ENTRY(shp, idx); - if (pte_present(pte)) - goto present; } shm_rss++; pte = pte_mkdirty(mk_pte(page, PAGE_SHARED)); @@ -813,21 +816,15 @@ } else --current->maj_flt; /* was incremented in do_no_page */ -done: /* pte_val(pte) == SHM_ENTRY (shp, idx) */ get_page(pte_page(pte)); spin_unlock(&shm_lock); + up(&shp->sem); current->min_flt++; return pte_page(pte); -changed: - __free_page(page); - goto again; -present: - if (page) - free_page_and_swap_cache(page); - goto done; oom: + up(&shp->sem); return NOPAGE_OOM; } @@ -851,7 +848,11 @@ if (!counter) return 0; lock_kernel(); - swap_entry = get_swap_page(); + /* subtle: preload the swap count for the swap cache. We can't + increase the count inside the critical section as we can't release + the shm_lock there. And we can't acquire the big lock with the + shm_lock held (otherwise we would deadlock too easily). */ + swap_entry = __get_swap_page(2); if (!swap_entry.val) { unlock_kernel(); return 0; @@ -893,7 +894,7 @@ failed: spin_unlock(&shm_lock); lock_kernel(); - swap_free(swap_entry); + __swap_free(swap_entry, 2); unlock_kernel(); return 0; } @@ -905,11 +906,16 @@ swap_successes++; shm_swp++; shm_rss--; + + /* add the locked page to the swap cache before allowing + the swapin path to run lookup_swap_cache(). This avoids + reading a not yet uptodate block from disk. + NOTE: we just accounted the swap space reference for this + swap cache page at __get_swap_page() time. */ + add_to_swap_cache(page_map, swap_entry); spin_unlock(&shm_lock); lock_kernel(); - swap_duplicate(swap_entry); - add_to_swap_cache(page_map, swap_entry); rw_swap_page(WRITE, page_map, 0); unlock_kernel(); diff -u --recursive --new-file v2.3.26/linux/ipc/util.c linux/ipc/util.c --- v2.3.26/linux/ipc/util.c Sun Nov 7 16:37:34 1999 +++ linux/ipc/util.c Tue Nov 9 10:02:36 1999 @@ -6,6 +6,8 @@ * get BSD style process accounting right. * Occurs in several places in the IPC code. * Chris Evans, + * Nov 1999 - ipc helper functions, unified SMP locking + * Manfred Spraul */ #include @@ -13,12 +15,13 @@ #include #include #include - -#include "util.h" +#include +#include +#include #if defined(CONFIG_SYSVIPC) -extern void sem_init (void), msg_init (void), shm_init (void); +#include "util.h" void __init ipc_init (void) { @@ -26,6 +29,157 @@ msg_init(); shm_init(); return; +} + +void __init ipc_init_ids(struct ipc_ids* ids, int size) +{ + int i; + sema_init(&ids->sem,1); + ids->size = size; + if(size == 0) + return; + if(size > IPCMNI) + size = IPCMNI; + + ids->in_use = 0; + ids->max_id = -1; + ids->seq = 0; + { + int seq_limit = INT_MAX/SEQ_MULTIPLIER; + if(seq_limit > USHRT_MAX) + ids->seq_max = USHRT_MAX; + else + ids->seq_max = seq_limit; + } + + ids->entries = ipc_alloc(sizeof(struct ipc_id)*size); + + if(ids->entries == NULL) { + printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n"); + ids->size = 0; + } + ids->ary = SPIN_LOCK_UNLOCKED; + for(i=0;ientries[i].p = NULL; + } +} + +int ipc_findkey(struct ipc_ids* ids, key_t key) +{ + int id; + struct ipc_perm* p; + + for (id = 0; id <= ids->max_id; id++) { + p = ids->entries[id].p; + if(p==NULL) + continue; + if (key == p->key) + return id; + } + return -1; +} + +static int grow_ary(struct ipc_ids* ids, int newsize) +{ + struct ipc_id* new; + struct ipc_id* old; + int i; + + if(newsize > IPCMNI) + newsize = IPCMNI; + if(newsize <= ids->size) + return newsize; + + new = ipc_alloc(sizeof(struct ipc_id)*newsize); + if(new == NULL) + return ids->size; + memcpy(new, ids->entries, sizeof(struct ipc_id)*ids->size); + for(i=ids->size;iary); + + old = ids->entries; + ids->entries = new; + i = ids->size; + ids->size = newsize; + spin_unlock(&ids->ary); + ipc_free(old, sizeof(struct ipc_id)*i); + return ids->size; +} + +int ipc_addid(struct ipc_ids* ids, struct ipc_perm* new, int size) +{ + int id; + + size = grow_ary(ids,size); + for (id = 0; id < size; id++) { + if(ids->entries[id].p == NULL) + goto found; + } + return -1; +found: + ids->in_use++; + if (id > ids->max_id) + ids->max_id = id; + + new->cuid = new->uid = current->euid; + new->gid = new->cgid = current->egid; + + new->seq = ids->seq++; + if(ids->seq > ids->seq_max) + ids->seq = 0; + + ipc_lock(ids,id); + ids->entries[id].p = new; + return id; +} + +struct ipc_perm* ipc_rmid(struct ipc_ids* ids, int id) +{ + struct ipc_perm* p; + int lid = id % SEQ_MULTIPLIER; + if(lid > ids->size) + BUG(); + p = ids->entries[lid].p; + ids->entries[lid].p = NULL; + if(p==NULL) + BUG(); + ids->in_use--; + + if (lid == ids->max_id) { + do { + lid--; + if(lid == -1) + break; + } while (ids->entries[lid].p == NULL); + ids->max_id = lid; + } + return p; +} + +void* ipc_alloc(int size) +{ + void* out; + if(size > PAGE_SIZE) { + lock_kernel(); + out = vmalloc(size); + unlock_kernel(); + } else { + out = kmalloc(size, GFP_KERNEL); + } + return out; +} + +void ipc_free(void* ptr, int size) +{ + if(size > PAGE_SIZE) { + lock_kernel(); + vfree(ptr); + unlock_kernel(); + } else { + kfree(ptr); + } } /* diff -u --recursive --new-file v2.3.26/linux/ipc/util.h linux/ipc/util.h --- v2.3.26/linux/ipc/util.h Sun Nov 7 16:37:34 1999 +++ linux/ipc/util.h Tue Nov 9 10:02:36 1999 @@ -1,12 +1,78 @@ /* * linux/ipc/util.h * Copyright (C) 1999 Christoph Rohland + * + * ipc helper functions (c) 1999 Manfred Spraul */ -/* - * IPCMNI is the absolute maximum for ipc identifier. This is used to - * detect stale identifiers +#define USHRT_MAX 0xffff +#define SEQ_MULTIPLIER (IPCMNI) + +void sem_init (void); +void msg_init (void); +void shm_init (void); + +struct ipc_ids { + int size; + int in_use; + int max_id; + unsigned short seq; + unsigned short seq_max; + struct semaphore sem; + spinlock_t ary; + struct ipc_id* entries; +}; + +struct ipc_id { + struct ipc_perm* p; +}; + + +void __init ipc_init_ids(struct ipc_ids* ids, int size); + +/* must be called with ids->sem acquired.*/ +int ipc_findkey(struct ipc_ids* ids, key_t key); +int ipc_addid(struct ipc_ids* ids, struct ipc_perm* new, int size); + +/* must be called with both locks acquired. */ +struct ipc_perm* ipc_rmid(struct ipc_ids* ids, int id); + +int ipcperms (struct ipc_perm *ipcp, short flg); + +/* for rare, potentially huge allocations. + * both function can sleep */ -#define IPCMNI (1<<15) +void* ipc_alloc(int size); +void ipc_free(void* ptr, int size); + +extern inline struct ipc_perm* ipc_lock(struct ipc_ids* ids, int id) +{ + struct ipc_perm* out; + int lid = id % SEQ_MULTIPLIER; + if(lid > ids->size) + return NULL; + + spin_lock(&ids->ary); + out = ids->entries[lid].p; + if(out==NULL) + spin_unlock(&ids->ary); + return out; +} + +extern inline void ipc_unlock(struct ipc_ids* ids, int id) +{ + spin_unlock(&ids->ary); +} + +extern inline int ipc_buildid(struct ipc_ids* ids, int id, int seq) +{ + return SEQ_MULTIPLIER*seq + id; +} + +extern inline int ipc_checkid(struct ipc_ids* ids, struct ipc_perm* ipcp, int uid) +{ + if(uid/SEQ_MULTIPLIER != ipcp->seq) + return 1; + return 0; +} -extern int ipcperms (struct ipc_perm *ipcp, short shmflg); diff -u --recursive --new-file v2.3.26/linux/kernel/exit.c linux/kernel/exit.c --- v2.3.26/linux/kernel/exit.c Mon Nov 1 13:56:27 1999 +++ linux/kernel/exit.c Mon Nov 8 10:19:19 1999 @@ -402,6 +402,7 @@ #ifdef CONFIG_BSD_PROCESS_ACCT acct_process(code); #endif + task_lock(tsk); sem_exit(); __exit_mm(tsk); #if CONFIG_AP1000 @@ -414,6 +415,7 @@ tsk->state = TASK_ZOMBIE; tsk->exit_code = code; exit_notify(); + task_unlock(tsk); #ifdef DEBUG_PROC_TREE audit_ptree(); #endif diff -u --recursive --new-file v2.3.26/linux/kernel/fork.c linux/kernel/fork.c --- v2.3.26/linux/kernel/fork.c Wed Oct 27 16:34:12 1999 +++ linux/kernel/fork.c Mon Nov 8 10:19:19 1999 @@ -650,6 +650,7 @@ p->p_cptr = NULL; init_waitqueue_head(&p->wait_chldexit); p->vfork_sem = NULL; + sema_init(&p->exit_sem, 1); p->sigpending = 0; sigemptyset(&p->signal); diff -u --recursive --new-file v2.3.26/linux/kernel/kmod.c linux/kernel/kmod.c --- v2.3.26/linux/kernel/kmod.c Thu Nov 12 09:58:32 1998 +++ linux/kernel/kmod.c Wed Nov 10 10:00:11 1999 @@ -23,22 +23,36 @@ char modprobe_path[256] = "/sbin/modprobe"; static inline void -use_init_file_context(void) +use_init_fs_context(void) { - struct fs_struct * fs; - - lock_kernel(); + struct fs_struct *our_fs, *init_fs; /* - * Don't use the user's root, use init's root instead. - * Note that we can use "init_task" (which is not actually - * the same as the user-level "init" process) because we - * started "init" with a CLONE_FS + * Make modprobe's fs context be a copy of init's. + * + * We cannot use the user's fs context, because it + * may have a different root than init. + * Since init was created with CLONE_FS, we can grab + * its fs context from "init_task". + * + * The fs context has to be a copy. If it is shared + * with init, then any chdir() call in modprobe will + * also affect init and the other threads sharing + * init_task's fs context. + * + * We created the exec_modprobe thread without CLONE_FS, + * so we can update the fields in our fs context freely. */ - exit_fs(current); /* current->fs->count--; */ - fs = init_task.fs; - current->fs = fs; - atomic_inc(&fs->count); + lock_kernel(); + + our_fs = current->fs; + dput(our_fs->root); + dput(our_fs->pwd); + + init_fs = init_task.fs; + our_fs->umask = init_fs->umask; + our_fs->root = dget(init_fs->root); + our_fs->pwd = dget(init_fs->pwd); unlock_kernel(); } @@ -49,7 +63,10 @@ char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL }; int i; - use_init_file_context(); + current->session = 1; + current->pgrp = 1; + + use_init_fs_context(); /* Prevent parent user process from sending signals to child. Otherwise, if the modprobe program does not exist, it might @@ -104,7 +121,7 @@ return -EPERM; } - pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS); + pid = kernel_thread(exec_modprobe, (void*) module_name, 0); if (pid < 0) { printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid); return pid; @@ -126,8 +143,8 @@ spin_unlock_irq(¤t->sigmask_lock); if (waitpid_result != pid) { - printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n", - pid, waitpid_result); + printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n", + module_name, pid, -waitpid_result); } return 0; } diff -u --recursive --new-file v2.3.26/linux/kernel/ksyms.c linux/kernel/ksyms.c --- v2.3.26/linux/kernel/ksyms.c Sun Nov 7 16:37:34 1999 +++ linux/kernel/ksyms.c Wed Nov 10 10:24:21 1999 @@ -93,7 +93,6 @@ /* 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); diff -u --recursive --new-file v2.3.26/linux/kernel/ptrace.c linux/kernel/ptrace.c --- v2.3.26/linux/kernel/ptrace.c Fri Oct 22 13:21:55 1999 +++ linux/kernel/ptrace.c Thu Nov 11 10:33:42 1999 @@ -50,15 +50,15 @@ flush_cache_page(vma, addr); if (write) { - maddr = kmap(page, KM_WRITE); + maddr = kmap(page); memcpy((char *)maddr + (addr & ~PAGE_MASK), buf, len); flush_page_to_ram(page); - kunmap(maddr, KM_WRITE); + kunmap(page); } else { - maddr = kmap(page, KM_READ); + maddr = kmap(page); memcpy(buf, (char *)maddr + (addr & ~PAGE_MASK), len); flush_page_to_ram(page); - kunmap(maddr, KM_READ); + kunmap(page); } return len; diff -u --recursive --new-file v2.3.26/linux/kernel/resource.c linux/kernel/resource.c --- v2.3.26/linux/kernel/resource.c Fri Sep 10 23:57:37 1999 +++ linux/kernel/resource.c Tue Nov 9 10:02:33 1999 @@ -20,7 +20,7 @@ static rwlock_t resource_lock = RW_LOCK_UNLOCKED; /* - * This generates reports for /proc/ioports and /proc/memory + * This generates reports for /proc/ioports and /proc/iomem */ static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end) { diff -u --recursive --new-file v2.3.26/linux/kernel/sysctl.c linux/kernel/sysctl.c --- v2.3.26/linux/kernel/sysctl.c Sun Nov 7 16:37:34 1999 +++ linux/kernel/sysctl.c Tue Nov 9 10:02:36 1999 @@ -50,6 +50,10 @@ #endif #ifdef CONFIG_SYSVIPC extern size_t shm_prm[]; +extern int msg_ctlmax; +extern int msg_ctlmnb; +extern int msg_ctlmni; +extern int sem_ctls[]; #endif #ifdef __sparc__ @@ -215,6 +219,14 @@ #ifdef CONFIG_SYSVIPC {KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof (size_t), 0644, NULL, &proc_doulongvec_minmax}, + {KERN_MSGMAX, "msgmax", &msg_ctlmax, sizeof (int), + 0644, NULL, &proc_dointvec}, + {KERN_MSGMNI, "msgmni", &msg_ctlmni, sizeof (int), + 0644, NULL, &proc_dointvec}, + {KERN_MSGMNB, "msgmnb", &msg_ctlmnb, sizeof (int), + 0644, NULL, &proc_dointvec}, + {KERN_SEM, "sem", &sem_ctls, 4*sizeof (int), + 0644, NULL, &proc_dointvec}, #endif #ifdef CONFIG_MAGIC_SYSRQ {KERN_SYSRQ, "sysrq", &sysrq_enabled, sizeof (int), diff -u --recursive --new-file v2.3.26/linux/lib/vsprintf.c linux/lib/vsprintf.c --- v2.3.26/linux/lib/vsprintf.c Sat Jul 24 16:42:01 1999 +++ linux/lib/vsprintf.c Mon Nov 8 17:03:01 1999 @@ -14,6 +14,8 @@ #include #include +#include + unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) { unsigned long result = 0,value; @@ -66,14 +68,7 @@ #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ -#define do_div(n,base) ({ \ -int __res; \ -__res = ((unsigned long) n) % (unsigned) base; \ -n = ((unsigned long) n) / (unsigned) base; \ -__res; }) - -static char * number(char * str, long num, int base, int size, int precision - ,int type) +static char * number(char * str, long long num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -145,7 +140,7 @@ int vsprintf(char *buf, const char *fmt, va_list args) { int len; - unsigned long num; + unsigned long long num; int i, base; char * str; const char *s; @@ -295,18 +290,23 @@ --fmt; continue; } - if (qualifier == 'l') + if (qualifier == 'L') + num = va_arg(args, long long); + else if (qualifier == 'l') { num = va_arg(args, unsigned long); - else if (qualifier == 'z') + if (flags & SIGN) + num = (signed long) num; + } else if (qualifier == 'z') { num = va_arg(args, size_t); - else if (qualifier == 'h') { + } else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & SIGN) - num = (short) num; - } else if (flags & SIGN) - num = va_arg(args, int); - else + num = (signed short) num; + } else { num = va_arg(args, unsigned int); + if (flags & SIGN) + num = (signed int) num; + } str = number(str, num, base, field_width, precision, flags); } *str = '\0'; diff -u --recursive --new-file v2.3.26/linux/mm/filemap.c linux/mm/filemap.c --- v2.3.26/linux/mm/filemap.c Sun Nov 7 16:37:34 1999 +++ linux/mm/filemap.c Thu Nov 11 10:33:42 1999 @@ -21,11 +21,13 @@ #include #include #include -#include +#include #include #include +#include + /* * Shared mappings implemented 30.11.1994. It's not fully working yet, * though. @@ -1142,12 +1144,10 @@ if (size > count) size = count; - /* - * FIXME: We cannot yet sleep with kmaps held. - */ - kaddr = kmap(page, KM_READ); - left = __copy_to_user(desc->buf, (void *)(kaddr+offset), size); - kunmap(kaddr, KM_READ); + + kaddr = kmap(page); + left = __copy_to_user(desc->buf, (void *)(kaddr + offset), size); + kunmap(page); if (left) { size -= left; @@ -1200,9 +1200,11 @@ size = count; old_fs = get_fs(); set_fs(KERNEL_DS); - kaddr = kmap(page, KM_READ); - written = file->f_op->write(file, (char *)kaddr + offset, size, &file->f_pos); - kunmap(kaddr, KM_READ); + + kaddr = kmap(page); + written = file->f_op->write(file, (char *)kaddr + offset, + size, &file->f_pos); + kunmap(page); set_fs(old_fs); if (written < 0) { desc->error = written; @@ -1347,8 +1349,6 @@ struct page *new_page = page_cache_alloc(); if (new_page) { - if (PageHighMem(new_page) || PageHighMem(old_page)) - BUG(); copy_highpage(new_page, old_page); flush_page_to_ram(new_page); } else @@ -1530,8 +1530,6 @@ return 0; } } - if (PageHighMem(page)) - BUG(); pgoff = (address - vma->vm_start) >> PAGE_CACHE_SHIFT; pgoff += vma->vm_pgoff; if (page->index != pgoff) { diff -u --recursive --new-file v2.3.26/linux/mm/highmem.c linux/mm/highmem.c --- v2.3.26/linux/mm/highmem.c Mon Nov 1 13:56:27 1999 +++ linux/mm/highmem.c Thu Nov 11 10:33:42 1999 @@ -4,19 +4,25 @@ * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de * Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de * + * * Redesigned the x86 32-bit VM architecture to deal with * 64-bit physical space. With current x86 CPUs this * means up to 64 Gigabytes physical RAM. * + * Rewrote high memory support to move the page cache into + * high memory. Implemented permanent (schedulable) kmaps + * based on Linus' idea. + * * Copyright (C) 1999 Ingo Molnar */ #include #include #include +#include +#include unsigned long highmem_mapnr; -unsigned long nr_free_highpages = 0; struct page * prepare_highmem_swapout(struct page * page) { @@ -34,9 +40,9 @@ if (!regular_page) return NULL; - vaddr = kmap(page, KM_READ); + vaddr = kmap(page); copy_page((void *)regular_page, (void *)vaddr); - kunmap(vaddr, KM_READ); + kunmap(page); /* * ok, we can just forget about our highmem page since @@ -52,10 +58,10 @@ struct page *highpage; unsigned long vaddr; - if (PageHighMem(page) || !nr_free_highpages) + if (PageHighMem(page) || !nr_free_highpages()) return page; - highpage = get_free_highpage(GFP_ATOMIC|__GFP_HIGHMEM); + highpage = alloc_page(GFP_ATOMIC|__GFP_HIGHMEM); if (!highpage) return page; if (!PageHighMem(highpage)) { @@ -63,9 +69,9 @@ return page; } - vaddr = kmap(highpage, KM_WRITE); + vaddr = kmap(page); copy_page((void *)vaddr, (void *)page_address(page)); - kunmap(vaddr, KM_WRITE); + kunmap(page); /* Preserve the caching of the swap_entry. */ highpage->index = page->index; @@ -79,3 +85,275 @@ return highpage; } + +/* + * Right now we initialize only a single pte table. It can be extended + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +#ifdef CONFIG_X86_PAE +#define LAST_PKMAP 2048 +#else +#define LAST_PKMAP 4096 +#endif +#define LAST_PKMAP_MASK (LAST_PKMAP-1) +#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +/* + * Virtual_count is not a pure "count". + * 0 means that it is not mapped, and has not been mapped + * since a TLB flush - it is usable. + * 1 means that there are no users, but it has been mapped + * since the last TLB flush - so we can't use it. + * n means that there are (n-1) current users of it. + */ +static int pkmap_count[LAST_PKMAP]; +static unsigned int last_pkmap_nr = 0; +static spinlock_t kmap_lock; + +pte_t * pkmap_page_table; + +static DECLARE_WAIT_QUEUE_HEAD(pkmap_map_wait); + +static void flush_all_zero_pkmaps(void) +{ + int i; + + for (i = 0; i < LAST_PKMAP; i++) { + struct page *page; + pte_t pte; + /* + * zero means we don't have anything to do, + * >1 means that it is still in use. Only + * a count of 1 means that it is free but + * needs to be unmapped + */ + if (pkmap_count[i] != 1) + continue; + pkmap_count[i] = 0; + pte = pkmap_page_table[i]; + if (pte_none(pte)) + continue; + pte_clear(pkmap_page_table+i); + page = pte_page(pte); + page->virtual = 0; + } + flush_tlb_all(); +} + +static unsigned long map_new_virtual(struct page *page) +{ + unsigned long vaddr; + int count = LAST_PKMAP; + + /* Find an empty entry */ + for (;;) { + last_pkmap_nr = (last_pkmap_nr + 1) & LAST_PKMAP_MASK; + if (!last_pkmap_nr) + flush_all_zero_pkmaps(); + if (!pkmap_count[last_pkmap_nr]) + break; /* Found a usable entry */ + if (--count) + continue; + + /* + * Sleep for somebody else to unmap their entries + */ + { + DECLARE_WAITQUEUE(wait, current); + + current->state = TASK_UNINTERRUPTIBLE; + add_wait_queue(&pkmap_map_wait, &wait); + spin_unlock(&kmap_lock); + // it's not quite possible to saturate the + // pkmap pool right now. + BUG(); + schedule(); + remove_wait_queue(&pkmap_map_wait, &wait); + spin_lock(&kmap_lock); + } + + /* Somebody else might have mapped it while we slept */ + if (page->virtual) + return page->virtual; + + /* Re-start */ + count = LAST_PKMAP; + } + vaddr = PKMAP_ADDR(last_pkmap_nr); + pkmap_page_table[last_pkmap_nr] = mk_pte(page, kmap_prot); + + /* + * Subtle! For some reason if we dont do this TLB flush then + * we get data corruption and weird behavior in dbench runs. + * But invlpg this should not be necessery ... Any ideas? + */ + __flush_tlb_one(vaddr); + pkmap_count[last_pkmap_nr] = 1; + page->virtual = vaddr; + + return vaddr; +} + +unsigned long kmap_high(struct page *page) +{ + unsigned long vaddr; + + if (!PageHighMem(page)) + BUG(); + /* + * For highmem pages, we can't trust "virtual" until + * after we have the lock. + * + * We cannot call this from interrupts, as it may block + */ + spin_lock(&kmap_lock); + vaddr = page->virtual; + if (!vaddr) + vaddr = map_new_virtual(page); + pkmap_count[PKMAP_NR(vaddr)]++; + if (pkmap_count[PKMAP_NR(vaddr)] < 2) + BUG(); + spin_unlock(&kmap_lock); + return vaddr; +} + +void kunmap_high(struct page *page) +{ + unsigned long vaddr; + unsigned long nr; + + spin_lock(&kmap_lock); + vaddr = page->virtual; + if (!vaddr) + BUG(); + nr = PKMAP_NR(vaddr); + + /* + * A count must never go down to zero + * without a TLB flush! + */ + switch (--pkmap_count[nr]) { + case 0: + BUG(); + case 1: + wake_up(&pkmap_map_wait); + } + spin_unlock(&kmap_lock); +} + +/* + * Simple bounce buffer support for highmem pages. + * This will be moved to the block layer in 2.5. + */ + +extern kmem_cache_t *bh_cachep; + +static inline void copy_from_high_bh (struct buffer_head *to, + struct buffer_head *from) +{ + struct page *p_from; + unsigned long vfrom; + + p_from = from->b_page; + vfrom = kmap_atomic(p_from, KM_BOUNCE_WRITE); + memcpy(to->b_data, (char *)vfrom + bh_offset(from), to->b_size); + kunmap_atomic(vfrom, KM_BOUNCE_WRITE); +} + +static inline void copy_to_high_bh_irq (struct buffer_head *to, + struct buffer_head *from) +{ + struct page *p_to; + unsigned long vto; + + p_to = to->b_page; + vto = kmap_atomic(p_to, KM_BOUNCE_WRITE); + memcpy((char *)vto + bh_offset(to), from->b_data, to->b_size); + kunmap_atomic(vto, KM_BOUNCE_WRITE); +} + +static inline void bounce_end_io (struct buffer_head *bh, int uptodate) +{ + struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_dev_id); + + bh_orig->b_end_io(bh_orig, uptodate); + __free_page(bh->b_page); + kmem_cache_free(bh_cachep, bh); +} + +static void bounce_end_io_write (struct buffer_head *bh, int uptodate) +{ + bounce_end_io(bh, uptodate); +} + +static void bounce_end_io_read (struct buffer_head *bh, int uptodate) +{ + struct buffer_head *bh_orig = (struct buffer_head *)(bh->b_dev_id); + + if (uptodate) + copy_to_high_bh_irq(bh_orig, bh); + bounce_end_io(bh, uptodate); +} + +struct buffer_head * create_bounce(int rw, struct buffer_head * bh_orig) +{ + struct page *page; + struct buffer_head *bh; + + if (!PageHighMem(bh_orig->b_page)) + return bh_orig; + +repeat_bh: + bh = kmem_cache_alloc(bh_cachep, SLAB_BUFFER); + if (!bh) { + wakeup_bdflush(1); + current->policy |= SCHED_YIELD; + schedule(); + goto repeat_bh; + } + /* + * This is wasteful for 1k buffers, but this is a stopgap measure + * and we are being ineffective anyway. This approach simplifies + * things immensly. On boxes with more than 4GB RAM this should + * not be an issue anyway. + */ +repeat_page: + page = alloc_page(GFP_BUFFER); + if (!page) { + wakeup_bdflush(1); + current->policy |= SCHED_YIELD; + schedule(); + goto repeat_page; + } + set_bh_page(bh, page, 0); + + bh->b_next = NULL; + bh->b_blocknr = bh_orig->b_blocknr; + bh->b_size = bh_orig->b_size; + bh->b_list = -1; + bh->b_dev = bh_orig->b_dev; + bh->b_count = bh_orig->b_count; + bh->b_rdev = bh_orig->b_rdev; + bh->b_state = bh_orig->b_state; + bh->b_flushtime = 0; + bh->b_next_free = NULL; + bh->b_prev_free = NULL; + /* bh->b_this_page */ + bh->b_reqnext = NULL; + bh->b_pprev = NULL; + /* bh->b_page */ + if (rw == WRITE) { + bh->b_end_io = bounce_end_io_write; + copy_from_high_bh(bh, bh_orig); + } else + bh->b_end_io = bounce_end_io_read; + bh->b_dev_id = (void *)bh_orig; + bh->b_rsector = -1; + memset(&bh->b_wait, -1, sizeof(bh->b_wait)); + bh->b_kiobuf = NULL; + + return bh; +} + diff -u --recursive --new-file v2.3.26/linux/mm/memory.c linux/mm/memory.c --- v2.3.26/linux/mm/memory.c Sun Nov 7 16:37:34 1999 +++ linux/mm/memory.c Thu Nov 11 10:33:42 1999 @@ -808,7 +808,7 @@ * Ok, we need to copy. Oh, well.. */ spin_unlock(&tsk->mm->page_table_lock); - new_page = get_free_highpage(GFP_HIGHUSER); + new_page = alloc_page(GFP_HIGHUSER); if (!new_page) return -1; spin_lock(&tsk->mm->page_table_lock); @@ -1025,7 +1025,7 @@ struct page *page = NULL; pte_t entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot)); if (write_access) { - page = get_free_highpage(GFP_HIGHUSER); + page = alloc_page(GFP_HIGHUSER); if (!page) return -1; if (PageHighMem(page)) diff -u --recursive --new-file v2.3.26/linux/mm/mmap.c linux/mm/mmap.c --- v2.3.26/linux/mm/mmap.c Mon Nov 1 13:56:27 1999 +++ linux/mm/mmap.c Wed Nov 10 09:13:07 1999 @@ -64,7 +64,7 @@ free = atomic_read(&buffermem_pages); free += atomic_read(&page_cache_size); - free += nr_free_pages; + free += nr_free_pages(); free += nr_swap_pages; return free > pages; } diff -u --recursive --new-file v2.3.26/linux/mm/page_alloc.c linux/mm/page_alloc.c --- v2.3.26/linux/mm/page_alloc.c Sun Nov 7 16:37:34 1999 +++ linux/mm/page_alloc.c Thu Nov 11 10:33:42 1999 @@ -4,6 +4,7 @@ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds * Swap reorganised 29.12.95, Stephen Tweedie * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 + * Reshaped it to be a zoned allocator, Ingo Molnar, Red Hat, 1999 */ #include @@ -22,7 +23,6 @@ #include int nr_swap_pages = 0; -int nr_free_pages = 0; int nr_lru_pages; LIST_HEAD(lru_cache); @@ -36,30 +36,46 @@ #if CONFIG_AP1000 /* the AP+ needs to allocate 8MB contiguous, aligned chunks of ram for the ring buffers */ -#define NR_MEM_LISTS 12 +#define MAX_ORDER 12 #else -#define NR_MEM_LISTS 10 +#define MAX_ORDER 10 #endif -struct free_area_struct { +typedef struct free_area_struct { struct list_head free_list; unsigned int * map; - unsigned long count; -}; +} free_area_t; -#define MEM_TYPE_DMA 0 -#define MEM_TYPE_NORMAL 1 -#define MEM_TYPE_HIGH 2 - -static const char *mem_type_strs[] = {"DMA", "Normal", "High"}; +#define ZONE_DMA 0 +#define ZONE_NORMAL 1 #ifdef CONFIG_HIGHMEM -#define NR_MEM_TYPES 3 +# define ZONE_HIGHMEM 2 +# define NR_ZONES 3 #else -#define NR_MEM_TYPES 2 +# define NR_ZONES 2 #endif -static struct free_area_struct free_area[NR_MEM_TYPES][NR_MEM_LISTS]; +typedef struct zone_struct { + spinlock_t lock; + unsigned long offset; + unsigned long size; + free_area_t free_area[MAX_ORDER]; + + unsigned long free_pages; + unsigned long pages_low, pages_high; + int low_on_memory; + char * name; +} zone_t; + +static zone_t zones[NR_ZONES] = + { + { name: "DMA" }, + { name: "Normal" }, +#ifdef CONFIG_HIGHMEM + { name: "HighMem" } +#endif + }; /* * Free_page() adds the page to the free lists. This is optimized for @@ -73,13 +89,6 @@ * for the normal case, giving better asm-code. */ -/* - * Buddy system. Hairy. You really aren't expected to understand this - * - * Hint: -mask = 1+~mask - */ -spinlock_t page_alloc_lock = SPIN_LOCK_UNLOCKED; - #define memlist_init(x) INIT_LIST_HEAD(x) #define memlist_add_head list_add #define memlist_add_tail list_add_tail @@ -88,35 +97,54 @@ #define memlist_next(x) ((x)->next) #define memlist_prev(x) ((x)->prev) -static inline void free_pages_ok(struct page *page, unsigned long map_nr, unsigned long order) +/* + * Temporary debugging check. + */ +#define BAD_RANGE(zone,x) ((((x)-mem_map) < zone->offset) || (((x)-mem_map) >= zone->offset+zone->size)) + +/* + * Buddy system. Hairy. You really aren't expected to understand this + * + * Hint: -mask = 1+~mask + */ + +static inline void free_pages_ok (struct page *page, unsigned long map_nr, unsigned long order) { struct free_area_struct *area; - unsigned long index = map_nr >> (1 + order); - unsigned long mask = (~0UL) << order; + unsigned long index, page_idx, mask, offset; unsigned long flags; struct page *buddy; + zone_t *zone; + int i; - spin_lock_irqsave(&page_alloc_lock, flags); - -#define list(x) (mem_map+(x)) - -#ifdef CONFIG_HIGHMEM - if (map_nr >= highmem_mapnr) { - area = free_area[MEM_TYPE_HIGH]; - nr_free_highpages -= mask; - } else -#endif - if (PageDMA(page)) - area = free_area[MEM_TYPE_DMA]; - else - area = free_area[MEM_TYPE_NORMAL]; + /* + * Which zone is this page belonging to. + * + * (NR_ZONES is low, and we do not want (yet) to introduce + * put page->zone, it increases the size of mem_map[] + * unnecesserily. This small loop is basically equivalent + * to the previous #ifdef jungle, speed-wise.) + */ + i = NR_ZONES-1; + zone = zones + i; + for ( ; i >= 0; i--, zone--) + if (map_nr >= zone->offset) + break; + mask = (~0UL) << order; + offset = zone->offset; + area = zone->free_area; area += order; + page_idx = map_nr - zone->offset; + page_idx &= mask; + index = page_idx >> (1 + order); + mask = (~0UL) << order; + + spin_lock_irqsave(&zone->lock, flags); - map_nr &= mask; - nr_free_pages -= mask; + zone->free_pages -= mask; - while (mask + (1 << (NR_MEM_LISTS-1))) { + while (mask + (1 << (MAX_ORDER-1))) { if (!test_and_change_bit(index, area->map)) /* * the buddy page is still allocated. @@ -125,21 +153,22 @@ /* * Move the buddy up one level. */ - buddy = list(map_nr ^ -mask); - page = list(map_nr); + buddy = mem_map + offset + (page_idx ^ -mask); + page = mem_map + offset + page_idx; + if (BAD_RANGE(zone,buddy)) + BUG(); + if (BAD_RANGE(zone,page)) + BUG(); - area->count--; memlist_del(&buddy->list); mask <<= 1; area++; index >>= 1; - map_nr &= mask; + page_idx &= mask; } - area->count++; - memlist_add_head(&(list(map_nr))->list, &area->free_list); -#undef list + memlist_add_head(&mem_map[offset + page_idx].list, &area->free_list); - spin_unlock_irqrestore(&page_alloc_lock, flags); + spin_unlock_irqrestore(&zone->lock, flags); } /* @@ -147,10 +176,9 @@ */ #define MARK_USED(index, order, area) \ change_bit((index) >> (1+(order)), (area)->map) -#define CAN_DMA(x) (PageDMA(x)) #define ADDRESS(x) (PAGE_OFFSET + ((x) << PAGE_SHIFT)) -int __free_page(struct page *page) +int __free_page (struct page *page) { if (!PageReserved(page) && put_page_testzero(page)) { if (PageSwapCache(page)) @@ -164,7 +192,7 @@ return 0; } -int free_pages(unsigned long addr, unsigned long order) +int free_pages (unsigned long addr, unsigned long order) { unsigned long map_nr = MAP_NR(addr); @@ -182,16 +210,17 @@ return 0; } -static inline unsigned long EXPAND (struct page *map, unsigned long index, +static inline unsigned long EXPAND (zone_t *zone, struct page *map, unsigned long index, int low, int high, struct free_area_struct * area) { unsigned long size = 1 << high; while (high > low) { + if (BAD_RANGE(zone,map)) + BUG(); area--; high--; size >>= 1; - area->count++; memlist_add_head(&(map)->list, &(area)->free_list); MARK_USED(index, high, area); index += size; @@ -201,79 +230,62 @@ return index; } -static inline struct page * rmqueue (int order, unsigned type) +static inline struct page * rmqueue (zone_t *zone, unsigned long order) { - struct free_area_struct * area = free_area[type]+order; + struct free_area_struct * area = zone->free_area + order; unsigned long curr_order = order, map_nr; - struct page *page; struct list_head *head, *curr; + unsigned long flags; + struct page *page; + spin_lock_irqsave(&zone->lock, flags); do { head = &area->free_list; curr = memlist_next(head); if (curr != head) { + unsigned int index; + page = memlist_entry(curr, struct page, list); memlist_del(curr); - area->count--; - map_nr = page - mem_map; - MARK_USED(map_nr, curr_order, area); - nr_free_pages -= 1 << order; - map_nr = EXPAND(page, map_nr, order, curr_order, area); + map_nr = page - mem_map; + index = map_nr - zone->offset; + MARK_USED(index, curr_order, area); + zone->free_pages -= 1 << order; + map_nr = zone->offset + EXPAND(zone, page, index, order, curr_order, area); + spin_unlock_irqrestore(&zone->lock, flags); + page = mem_map + map_nr; + if (BAD_RANGE(zone,page)) + BUG(); return page; } curr_order++; area++; - } while (curr_order < NR_MEM_LISTS); + } while (curr_order < MAX_ORDER); + spin_unlock_irqrestore(&zone->lock, flags); return NULL; } -static inline int balance_lowmemory (int gfp_mask) +static inline int balance_memory (zone_t *zone, int gfp_mask) { int freed; - static int low_on_memory = 0; -#ifndef CONFIG_HIGHMEM - if (nr_free_pages > freepages.min) { - if (!low_on_memory) + if (zone->free_pages > zone->pages_low) { + if (!zone->low_on_memory) return 1; - if (nr_free_pages >= freepages.high) { - low_on_memory = 0; + /* + * Simple hysteresis: exit 'low memory mode' if + * the upper limit has been reached: + */ + if (zone->free_pages >= zone->pages_high) { + zone->low_on_memory = 0; return 1; } } + zone->low_on_memory = 1; - low_on_memory = 1; -#else - static int low_on_highmemory = 0; - - if (gfp_mask & __GFP_HIGHMEM) - { - if (nr_free_pages > freepages.min) { - if (!low_on_highmemory) { - return 1; - } - if (nr_free_pages >= freepages.high) { - low_on_highmemory = 0; - return 1; - } - } - low_on_highmemory = 1; - } else { - if (nr_free_pages-nr_free_highpages > freepages.min) { - if (!low_on_memory) { - return 1; - } - if (nr_free_pages-nr_free_highpages >= freepages.high) { - low_on_memory = 0; - return 1; - } - } - low_on_memory = 1; - } -#endif current->flags |= PF_MEMALLOC; freed = try_to_free_pages(gfp_mask); current->flags &= ~PF_MEMALLOC; @@ -283,13 +295,12 @@ return 1; } -struct page * __get_pages(int gfp_mask, unsigned long order) +static inline struct page * __get_pages (zone_t *zone, unsigned int gfp_mask, + unsigned long order) { - unsigned long flags; struct page *page; - unsigned type; - if (order >= NR_MEM_LISTS) + if (order >= MAX_ORDER) goto nopage; /* @@ -303,32 +314,20 @@ * further thought. */ if (!(current->flags & PF_MEMALLOC)) - goto lowmemory; - -ok_to_allocate: -#ifdef CONFIG_HIGHMEM - if (gfp_mask & __GFP_HIGHMEM) - type = MEM_TYPE_HIGH; - else -#endif - if (gfp_mask & __GFP_DMA) - type = MEM_TYPE_DMA; - else - type = MEM_TYPE_NORMAL; - - spin_lock_irqsave(&page_alloc_lock, flags); + if (!balance_memory(zone, gfp_mask)) + goto nopage; + /* + * We are falling back to lower-level zones if allocation + * in a higher zone fails. This assumes a hierarchical + * dependency between zones, which is true currently. If + * you need something else then move this loop outside + * this function, into the zone-specific allocator. + */ do { - page = rmqueue(order, type); - if (page) { -#ifdef CONFIG_HIGHMEM - if (type == MEM_TYPE_HIGH) - nr_free_highpages -= 1 << order; -#endif - spin_unlock_irqrestore(&page_alloc_lock, flags); + page = rmqueue(zone, order); + if (page) return page; - } - } while (type-- > 0) ; - spin_unlock_irqrestore(&page_alloc_lock, flags); + } while (zone-- != zones) ; /* * If we can schedule, do so, and make sure to yield. @@ -342,26 +341,73 @@ nopage: return NULL; +} -lowmemory: - if (balance_lowmemory(gfp_mask)) - goto ok_to_allocate; - goto nopage; +static inline zone_t * gfp_mask_to_zone (int gfp_mask) +{ + zone_t *zone; + +#if CONFIG_HIGHMEM + if (gfp_mask & __GFP_HIGHMEM) + zone = zones + ZONE_HIGHMEM; + else +#endif + if (gfp_mask & __GFP_DMA) + zone = zones + ZONE_DMA; + else + zone = zones + ZONE_NORMAL; + return zone; } -unsigned long __get_free_pages(int gfp_mask, unsigned long order) +unsigned long __get_free_pages (int gfp_mask, unsigned long order) { struct page *page; - page = __get_pages(gfp_mask, order); + + page = __get_pages(gfp_mask_to_zone(gfp_mask), gfp_mask, order); if (!page) return 0; return page_address(page); } -struct page * get_free_highpage(int gfp_mask) +struct page * alloc_pages (int gfp_mask, unsigned long order) +{ + return __get_pages(gfp_mask_to_zone(gfp_mask), gfp_mask, order); +} + +/* + * Total amount of free (allocatable) RAM: + */ +unsigned int nr_free_pages (void) +{ + unsigned int sum; + zone_t *zone; + + sum = 0; + for (zone = zones; zone < zones+NR_ZONES; zone++) + sum += zone->free_pages; + return sum; +} + +/* + * Amount of free RAM allocatable as buffer memory: + */ +unsigned int nr_free_buffer_pages (void) +{ + unsigned int sum; + zone_t *zone; + + sum = nr_lru_pages; + for (zone = zones; zone <= zones+ZONE_NORMAL; zone++) + sum += zone->free_pages; + return sum; +} + +#if CONFIG_HIGHMEM +unsigned int nr_free_highpages (void) { - return __get_pages(gfp_mask, 0); + return zones[ZONE_HIGHMEM].free_pages; } +#endif /* * Show free area list (used inside shift_scroll-lock stuff) @@ -370,32 +416,39 @@ */ void show_free_areas(void) { - unsigned long order, flags; + unsigned long order; unsigned type; - spin_lock_irqsave(&page_alloc_lock, flags); - printk("Free pages: %6dkB (%6ldkB HighMem)\n", - nr_free_pages<<(PAGE_SHIFT-10), - nr_free_highpages<<(PAGE_SHIFT-10)); + printk("Free pages: %6dkB (%6dkB HighMem)\n", + nr_free_pages()<<(PAGE_SHIFT-10), + nr_free_highpages()<<(PAGE_SHIFT-10)); printk("( Free: %d, lru_cache: %d (%d %d %d) )\n", - nr_free_pages, + nr_free_pages(), nr_lru_pages, freepages.min, freepages.low, freepages.high); - for (type = 0; type < NR_MEM_TYPES; type++) { + for (type = 0; type < NR_ZONES; type++) { + zone_t *zone = zones + type; unsigned long total = 0; - printk(" %s: ", mem_type_strs[type]); - for (order = 0; order < NR_MEM_LISTS; order++) { - unsigned long nr = free_area[type][order].count; + printk(" %s: ", zone->name); + for (order = 0; order < MAX_ORDER; order++) { + unsigned long i, nr; + + nr = 0; + for (i = 0; i < zone->size; i += 1<offset + i; + if (!page_count(page)) + nr++; + } total += nr * ((PAGE_SIZE>>10) << order); printk("%lu*%lukB ", nr, (unsigned long)((PAGE_SIZE>>10) << order)); } printk("= %lukB)\n", total); } - spin_unlock_irqrestore(&page_alloc_lock, flags); #ifdef SWAP_CACHE_INFO show_swap_cache_info(); @@ -405,18 +458,24 @@ #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) /* - * set up the free-area data structures: + * Set up the zone data structures: * - mark all pages reserved * - mark all memory queues empty * - clear the memory bitmaps */ -volatile int data; -void __init free_area_init(unsigned long end_mem_pages) +void __init free_area_init(unsigned int *zones_size) { mem_map_t * p; unsigned long i, j; unsigned long map_size; + unsigned int totalpages, offset; + + totalpages = 0; + for (i = 0; i < NR_ZONES; i++) + totalpages += zones_size[i]; + printk("totalpages: %08x\n", totalpages); + i = totalpages >> 7; /* * Select nr of pages we try to keep free for important stuff * with a minimum of 10 pages and a maximum of 256 pages, so @@ -424,7 +483,7 @@ * This is fairly arbitrary, but based on some behaviour * analysis. */ - i = end_mem_pages >> 7; + i = totalpages >> 7; if (i < 10) i = 10; if (i > 256) @@ -434,11 +493,10 @@ freepages.high = i * 3; /* - * Most architectures just pick 'start_mem'. Some architectures - * (with lots of mem and discontinous memory maps) have to search - * for a good area. + * Some architectures (with lots of mem and discontinous memory + * maps) have to search for a good mem_map area: */ - map_size = end_mem_pages*sizeof(struct page); + map_size = totalpages*sizeof(struct page); mem_map = (struct page *) alloc_bootmem(map_size); memset(mem_map, 0, map_size); @@ -447,27 +505,39 @@ * up by free_all_bootmem() once the early boot process is * done. */ - for (p = mem_map; p < mem_map + end_mem_pages; p++) { + for (p = mem_map; p < mem_map + totalpages; p++) { set_page_count(p, 0); p->flags = (1 << PG_DMA); SetPageReserved(p); init_waitqueue_head(&p->wait); memlist_init(&p->list); } - - for (j = 0 ; j < NR_MEM_TYPES ; j++) { + + offset = 0; + for (j = 0; j < NR_ZONES; j++) { + zone_t *zone = zones + j; unsigned long mask = -1; - for (i = 0 ; i < NR_MEM_LISTS ; i++) { + unsigned long size; + + size = zones_size[j]; + zone->size = size; + zone->offset = offset; + zone->pages_low = freepages.low; + zone->pages_high = freepages.high; + zone->low_on_memory = 0; + + offset += size; + for (i = 0; i < MAX_ORDER; i++) { unsigned long bitmap_size; unsigned int * map; - memlist_init(&free_area[j][i].free_list); + memlist_init(&zone->free_area[i].free_list); mask += mask; - end_mem_pages = (end_mem_pages + ~mask) & mask; - bitmap_size = end_mem_pages >> i; + size = (size + ~mask) & mask; + bitmap_size = size >> i; bitmap_size = (bitmap_size + 7) >> 3; bitmap_size = LONG_ALIGN(bitmap_size); map = (unsigned int *) alloc_bootmem(bitmap_size); - free_area[j][i].map = map; + zone->free_area[i].map = map; memset((void *) map, 0, bitmap_size); } } diff -u --recursive --new-file v2.3.26/linux/mm/swapfile.c linux/mm/swapfile.c --- v2.3.26/linux/mm/swapfile.c Sun Nov 7 16:37:34 1999 +++ linux/mm/swapfile.c Thu Nov 11 15:57:27 1999 @@ -25,7 +25,7 @@ #define SWAPFILE_CLUSTER 256 -static inline int scan_swap_map(struct swap_info_struct *si) +static inline int scan_swap_map(struct swap_info_struct *si, unsigned short count) { unsigned long offset; /* @@ -73,7 +73,7 @@ si->lowest_bit++; if (offset == si->highest_bit) si->highest_bit--; - si->swap_map[offset] = 1; + si->swap_map[offset] = count; nr_swap_pages--; si->cluster_next = offset+1; return offset; @@ -81,7 +81,7 @@ return 0; } -swp_entry_t get_swap_page(void) +swp_entry_t __get_swap_page(unsigned short count) { struct swap_info_struct * p; unsigned long offset; @@ -94,11 +94,13 @@ goto out; if (nr_swap_pages == 0) goto out; + if (count >= SWAP_MAP_MAX) + goto bad_count; while (1) { p = &swap_info[type]; if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { - offset = scan_swap_map(p); + offset = scan_swap_map(p, count); if (offset) { entry = SWP_ENTRY(type,offset); type = swap_info[type].next; @@ -123,10 +125,15 @@ } out: return entry; + +bad_count: + printk(KERN_ERR "get_swap_page: bad count %hd from %p\n", + count, __builtin_return_address(0)); + goto out; } -void swap_free(swp_entry_t entry) +void __swap_free(swp_entry_t entry, unsigned short count) { struct swap_info_struct * p; unsigned long offset, type; @@ -148,7 +155,9 @@ if (!p->swap_map[offset]) goto bad_free; if (p->swap_map[offset] < SWAP_MAP_MAX) { - if (!--p->swap_map[offset]) { + if (p->swap_map[offset] < count) + goto bad_count; + if (!(p->swap_map[offset] -= count)) { if (offset < p->lowest_bit) p->lowest_bit = offset; if (offset > p->highest_bit) @@ -170,6 +179,9 @@ goto out; bad_free: printk("VM: Bad swap entry %08lx\n", entry.val); + goto out; +bad_count: + printk(KERN_ERR "VM: Bad count %hd current count %hd\n", count, p->swap_map[offset]); goto out; } diff -u --recursive --new-file v2.3.26/linux/mm/vmalloc.c linux/mm/vmalloc.c --- v2.3.26/linux/mm/vmalloc.c Wed Oct 27 16:34:12 1999 +++ linux/mm/vmalloc.c Thu Nov 11 10:33:42 1999 @@ -10,7 +10,7 @@ #include -static struct vm_struct * vmlist = NULL; +struct vm_struct * vmlist = NULL; static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned long size) { @@ -97,7 +97,7 @@ struct page * page; if (!pte_none(*pte)) printk(KERN_ERR "alloc_area_pte: page already exists\n"); - page = get_free_highpage(GFP_KERNEL|__GFP_HIGHMEM); + page = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); if (!page) return -ENOMEM; set_pte(pte, mk_pte(page, PAGE_KERNEL)); @@ -204,7 +204,7 @@ struct vm_struct *area; size = PAGE_ALIGN(size); - if (!size || size > (max_mapnr << PAGE_SHIFT)) { + if (!size || (size >> PAGE_SHIFT) > max_mapnr) { BUG(); return NULL; } diff -u --recursive --new-file v2.3.26/linux/mm/vmscan.c linux/mm/vmscan.c --- v2.3.26/linux/mm/vmscan.c Mon Nov 1 13:56:27 1999 +++ linux/mm/vmscan.c Wed Nov 10 09:13:07 1999 @@ -503,7 +503,7 @@ do { /* kswapd is critical to provide GFP_ATOMIC allocations (not GFP_HIGHMEM ones). */ - if (nr_free_pages - nr_free_highpages >= freepages.high) + if (nr_free_buffer_pages() >= freepages.high) break; if (!do_try_to_free_pages(GFP_KSWAPD)) diff -u --recursive --new-file v2.3.26/linux/net/core/dev.c linux/net/core/dev.c --- v2.3.26/linux/net/core/dev.c Mon Nov 1 13:56:27 1999 +++ linux/net/core/dev.c Tue Nov 9 11:55:53 1999 @@ -354,14 +354,18 @@ int dev_alloc_name(struct net_device *dev, const char *name) { int i; + char buf[32]; /* * If you need over 100 please also fix the algorithm... */ for(i=0;i<100;i++) { - sprintf(dev->name,name,i); - if(__dev_get_by_name(dev->name)==NULL) + sprintf(buf,name,i); + if(__dev_get_by_name(buf)==NULL) + { + strcpy(dev->name, buf); return i; + } } return -ENFILE; /* Over 100 of the things .. bail out! */ } @@ -1994,19 +1998,9 @@ * present) and leaves us with a valid list of present and active devices. * */ -extern int lance_init(void); -extern int bpq_init(void); -extern int scc_init(void); -extern void sdla_setup(void); -extern void dlci_setup(void); -extern int dmascc_init(void); -extern int lapbeth_init(void); -extern void arcnet_init(void); +extern void net_device_init(void); extern void ip_auto_config(void); -#ifdef CONFIG_8xx -extern int cpm_enet_init(void); -#endif /* CONFIG_8xx */ int __init net_dev_init(void) { @@ -2030,51 +2024,6 @@ br_init(); #endif - /* - * This is Very Ugly(tm). - * - * Some devices want to be initialized early.. - */ - -#if defined(CONFIG_SCC) - scc_init(); -#endif -#if defined(CONFIG_DMASCC) - dmascc_init(); -#endif -#if defined(CONFIG_BPQETHER) - bpq_init(); -#endif -#if defined(CONFIG_DLCI) - dlci_setup(); -#endif -#if defined(CONFIG_SDLA) - sdla_setup(); -#endif -#if defined(CONFIG_LAPBETHER) - lapbeth_init(); -#endif -#if defined(CONFIG_PLIP) - plip_init(); -#endif -#if defined(CONFIG_ARCNET) - arcnet_init(); -#endif -#if defined(CONFIG_8xx) - cpm_enet_init(); -#endif - /* - * SLHC if present needs attaching so other people see it - * even if not opened. - */ - -#ifdef CONFIG_INET -#if (defined(CONFIG_SLIP) && defined(CONFIG_SLIP_COMPRESSED)) \ - || defined(CONFIG_PPP) \ - || (defined(CONFIG_ISDN) && defined(CONFIG_ISDN_PPP)) - slhc_install(); -#endif -#endif #ifdef CONFIG_NET_PROFILE net_profile_init(); @@ -2101,6 +2050,12 @@ dev->xmit_lock_owner = -1; dev->iflink = -1; dev_hold(dev); + /* + * We can allocate the name ahead of time. If the + * init fails the name will be reissued correctly. + */ + if (strchr(dev->name, '%')) + dev_alloc_name(dev, dev->name); if (dev->init && dev->init(dev)) { /* * It failed to come up. Unhook it. @@ -2135,6 +2090,12 @@ dst_init(); dev_mcast_init(); + + /* + * Initialise network devices + */ + + net_device_init(); #ifdef CONFIG_IP_PNP ip_auto_config(); diff -u --recursive --new-file v2.3.26/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c --- v2.3.26/linux/net/ipv4/tcp_input.c Mon Oct 11 15:38:15 1999 +++ linux/net/ipv4/tcp_input.c Thu Nov 11 15:48:50 1999 @@ -1401,11 +1401,6 @@ tcp_send_ack(sk); - if (!sk->dead) { - wake_up_interruptible(sk->sleep); - sock_wake_async(sk->socket, 1, POLL_HUP); - } - switch(sk->state) { case TCP_SYN_RECV: case TCP_ESTABLISHED: @@ -1440,7 +1435,11 @@ */ printk("tcp_fin: Impossible, sk->state=%d\n", sk->state); break; - }; + } + if (!sk->dead) { + wake_up_interruptible(sk->sleep); + sock_wake_async(sk->socket, 1, POLL_HUP); + } } /* These routines update the SACK block as out-of-order packets arrive or diff -u --recursive --new-file v2.3.26/linux/net/irda/irmod.c linux/net/irda/irmod.c --- v2.3.26/linux/net/irda/irmod.c Sun Nov 7 16:37:34 1999 +++ linux/net/irda/irmod.c Thu Nov 11 16:57:31 1999 @@ -525,24 +525,6 @@ #endif } -/* - * Function irda_proc_modcount (inode, fill) - * - * Use by the proc file system functions to prevent the irda module - * being removed while the use is standing in the net/irda directory - */ -void irda_proc_modcount(struct inode *inode, int fill) -{ -#ifdef MODULE -#ifdef CONFIG_PROC_FS - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -#endif /* CONFIG_PROC_FS */ -#endif /* MODULE */ -} - #ifdef MODULE MODULE_AUTHOR("Dag Brattli "); diff -u --recursive --new-file v2.3.26/linux/net/irda/irproc.c linux/net/irda/irproc.c --- v2.3.26/linux/net/irda/irproc.c Mon Nov 1 13:56:27 1999 +++ linux/net/irda/irproc.c Thu Nov 11 16:57:31 1999 @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -70,9 +71,7 @@ int i; proc_irda = create_proc_entry("net/irda", S_IFDIR, NULL); -#ifdef MODULE - proc_irda->fill_inode = &irda_proc_modcount; -#endif /* MODULE */ + proc_irda->owner = THIS_MODULE; for (i=0;ifill_inode = rpc_modcount; -#endif + ent->owner = THIS_MODULE; proc_net_rpc = ent; } } @@ -183,21 +181,6 @@ } #ifdef MODULE -/* - * This is called as the proc_dir_entry fill_inode function - * when an inode is going into or out of service (fill == 1 - * or 0 respectively). - * - * We use it here to keep the module from being unloaded - * while /proc inodes are in use. - */ -void rpc_modcount(struct inode *inode, int fill) -{ - if (fill) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -} int init_module(void) diff -u --recursive --new-file v2.3.26/linux/net/sunrpc/sysctl.c linux/net/sunrpc/sysctl.c --- v2.3.26/linux/net/sunrpc/sysctl.c Thu Jan 7 09:28:47 1999 +++ linux/net/sunrpc/sysctl.c Thu Nov 11 16:57:31 1999 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -38,11 +39,9 @@ { if (!sunrpc_table_header) { sunrpc_table_header = register_sysctl_table(sunrpc_table, 1); -#ifdef MODULE #ifdef CONFIG_PROC_FS if (sunrpc_table[0].de) - sunrpc_table[0].de->fill_inode = rpc_modcount; -#endif + sunrpc_table[0].de->owner = THIS_MODULE; #endif } diff -u --recursive --new-file v2.3.26/linux/scripts/usb/procusb linux/scripts/usb/procusb --- v2.3.26/linux/scripts/usb/procusb Wed Dec 31 16:00:00 1969 +++ linux/scripts/usb/procusb Wed Nov 10 15:11:35 1999 @@ -0,0 +1,44 @@ +#!/usr/bin/perl + +# Reads /proc/bus/usb/devices and selectively lists and/or +# interprets it. + +$DEVFILENAME = "/proc/bus/usb/devices"; +$PROGNAME = $0; + +print "\n"; + +$TAGS = $ARGV[0]; # save user TAGS +if (length ($TAGS) == 0) +{ + print "usage: $PROGNAME tags\n"; + print " where 'tags' can be any number of 'TBDPCIE' or 'A(LL)'\n"; + exit 1; +} + +$ALL = ($TAGS =~ /all/i) || ($TAGS =~ /a/i); + +# TBD: Check that $TAGS is valid. +if (! $ALL) +{ +} + +if (! open (DEVNUM, "<$DEVFILENAME")) +{ + print "$PROGNAME: cannot open '$DEVFILENAME'\n"; + exit 1; +} + +while ($line = ) # read a text line from DEVNUM +{ + if (($ALL) || ($line =~ /^[$TAGS]:/i)) # any of TAGS at beg. of line? + { + print "$line"; # still has newline char on it + # TBD: add more/paging functionality. + } +} # end while DEVNUM + +close (DEVNUM); +print "\n"; + +# END. diff -u --recursive --new-file v2.3.26/linux/scripts/usb/usbtree linux/scripts/usb/usbtree --- v2.3.26/linux/scripts/usb/usbtree Wed Dec 31 16:00:00 1969 +++ linux/scripts/usb/usbtree Mon Nov 8 13:27:10 1999 @@ -0,0 +1,90 @@ +#!/usr/bin/perl + +# Reads /proc/bus/usb/devices and selectively lists and/or +# interprets it. + +$DEVFILENAME = "/proc/bus/usb/devices"; +$PROGNAME = $0; + +print "\n"; + +$TAGS = $ARGV[0]; # save user TAGS +if (length ($TAGS) == 0) +{ +} + +if (! open (DEVNUM, "<$DEVFILENAME")) +{ + print "$PROGNAME: cannot open '$DEVFILENAME'\n"; + exit 1; +} + +while ($line = ) # read a text line from DEVNUM +{ + # skip all lines except those that begin with "T:" or "D:" or "I:". + if (($line !~ "^T:") && ($line !~ "^I:") && ($line !~ "^D:")) + { + next; # to the next line + } + + chomp $line; # remove line endings + + # First convert '=' signs to spaces. + $line =~ tr/=/ /; + + # and convert all ( and ) to spaces. + $line =~ tr/(/ /; + $line =~ tr/)/ /; + + # split the line at spaces. + @fields = split / +/, $line; + + if ($line =~ "^T:") + { + # split yields: $level, $port, $devnum, $speed, $maxchild. + + $level = @fields [2]; + $port = @fields [6]; + $devnum = @fields [10]; + $speed = @fields [12]; + $maxchild = @fields [14]; + $devclass = "?"; + $intclass = "?"; + $driver = "?"; + + if (($devnum == -1) && ($level == 0)) + { + print "/: Dev# -1, root hub/$maxchild ports, $speed Mbps\n"; + } + next; + } # end T: line + elsif ($line =~ "^D:") + { # for D: line + $devclass = @fields [5]; + next; + } + else + { # for I: line + $intclass = @fields [9]; + $ifnum = @fields [2]; + $driver = @fields [15]; + } # end I: line + + if ($level > 1) + { + $temp = $level; + while ($temp > 1) + { + print " "; + $temp--; + } + } + + print sprintf ("|__ Port# $port: Dev# $devnum, If# $ifnum, Class=$devclass, Ifc=$intclass, Driver=$driver%s, $speed Mbps\n", + ($maxchild == 0) ? "" : ("/" . $maxchild . " ports")); +} # end while DEVNUM + +close (DEVNUM); +print "\n"; + +# END.