diff -u --recursive --new-file v2.4.0-test3/linux/CREDITS linux/CREDITS --- v2.4.0-test3/linux/CREDITS Mon Jul 10 16:47:18 2000 +++ linux/CREDITS Tue Jul 11 19:03:13 2000 @@ -1387,6 +1387,7 @@ W: http://www.kroah.com/linux-usb/ D: USB Serial Converter driver framework, USB Handspring Visor driver D: ConnectTech WHITEHeat USB driver, Generic USB Serial driver +D: USB Bluetooth driver D: bits and pieces of USB core code. N: Russell Kroll diff -u --recursive --new-file v2.4.0-test3/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.4.0-test3/linux/Documentation/Configure.help Mon Jul 10 16:47:18 2000 +++ linux/Documentation/Configure.help Thu Jul 13 09:42:51 2000 @@ -7218,6 +7218,14 @@ If you want to do that, say M here. The module will be called sealevel.o. +SyncLink HDLC/SYNCPPP support +CONFIG_SYNCLINK_SYNCPPP + Enables HDLC/SYNCPPP support for the SyncLink WAN driver. + Normally the SyncLink WAN driver works with the main PPP + driver (ppp.c) and pppd program. HDLC/SYNCPPP support allows use + of the Cisco HDLC/PPP driver (syncppp.c). + The SyncLink WAN driver (in character devices) must also be enabled. + Frame Relay (DLCI) support CONFIG_DLCI This is support for the frame relay protocol; frame relay is a fast @@ -8458,7 +8466,7 @@ This is yet another chipset driver for the COM90xx cards, but this time only using memory-mapped mode, and no IO ports at all. This driver is completely untested, so if you have one of these cards, - please mail David.Woodhouse@mvhi.com, especially if it works! + please mail dwmw2@infradead.org, especially if it works! This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you @@ -9551,6 +9559,182 @@ http://www.linuxdoc.org/docs.html#howto . Probably the quota support is only useful for multi user systems. If unsure, say N. +Memory Technology Device (MTD) support +CONFIG_MTD + Memory Technology Devices are flash, RAM and similar chips, often + used for solid state filesystems on embedded devices. This option + will provide the generic support for MTD drivers to register + themselves with the kernel and for potential users of MTD devices + to enumerate the devices which are present and obtain a handle on + them. It will also allow you to select individual drivers for + particular hardware and users of MTD device. If unsure, say N. + +M-Systems Disk-On-Chip 1000 support +CONFIG_MTD_DOC1000 + This provides an MTD device driver for the M-Systems DiskOnChip + 1000 devices, which are obsolete so you probably want to say 'N'. + +M-Systems Disk-On-Chip 2000 support +CONFIG_MTD_DOC2000 + This provides an MTD device driver for the M-Systems DiskOnChip + 2000 devices. If you use this, you probably also want the NFTL + 'NAND Flash Translation Layer' below, which is used to emulate + a block device by using a kind of filesystem on the flash chips. + +M-Systems Disk-On-Chip Millennium support +CONFIG_MTD_DOC2001 + This provides an MTD device driver for the M-Systems DiskOnChip + Millennium devices. If you use this, you probably also want the + NFTL 'NAND Flash Translation Layer' below, which is used to emulate + a block device by using a kind of filesystem on the flash chips. + +Use extra onboard system memory as MTD device +CONFIG_MTD_SLRAM + If your CPU cannot cache all of the physical memory in your machine, + you can still use it for storage or swap by using this driver to + present it to the system as a Memory Technology Device. + +Ramix PMC551 PCI Mezzanine ram card support +CONFIG_MTD_PMC551 + This provides an MTD device driver for the Ramix PMC551 RAM card. + If you have one, you probably want to enable this. + +PMC551 256M DRAM Bugfix. +CONFIG_MTD_PMC551_BUGFIX + Some PMC551 boards hacve invalid column and row mux values. This + option will fix them, but will break other memory configurations. + +Debugging RAM test driver +CONFIG_MTD_MTDRAM + This enables a test MTD device driver which uses vmalloc() to + provide storage. You probably want to say 'N' unless you're + testing stuff, or unless you want to use it in place of a ramdisk + when I've eventually got round to making the CONFIG_BLK_DEV option + and you've turned it off. + +Common Flash Interface (CFI) support +CONFIG_MTD_CFI + Intel's Common Flash Interface specification provides a universal + method for probing the capabilities of flash devices. If you wish + to support any device which uses CFI-compliant devices, you need + to enable this option. + +CFI support for Intel/Sharp Extended Command Set chips +CONFIG_MTD_CFI_INTELEXT + The Common Flash Interface defines a number of different command + sets which a CFI-compliant chip may claim to implement. This code + provides support for one of those command sets, used on Intel + Strataflash and other parts. + +Flash chip mapping in physical memory +CONFIG_MTD_PHYSMAP + This provides a 'mapping' driver which allows the CFI probe and + command set driver code to communicate with flash chips which + are mapped physically into the CPU's memory. You will need to + configure the physical address and size of the flash chips on + your particular board. + +Physical start location of flash chip mapping +CONFIG_MTD_PHYSMAP_START + This is the physical memory location at which the flash chips + are mapped on your particular target board. Refer to the + memory map which should hopefully be in the documentation for + your board. + +Physical length of flash chip mapping +CONFIG_MTD_PHYSMAP_LEN + This is the total length of the mapping of the flash chips on + your particular board. If there is space, or aliases, in the + physical memory map between the chips, this could be larger + than the total amount of flash present. Refer to the memory + map which should hopefully be in the documentation for your + board. + +Flash chip mapping on Mixcom piggyback card +CONFIG_MTD_MIXMEM + This supports the paging arrangement for access to flash chips + on the Mixcom piggyback card, allowing the flash chip drivers + to get on with their job of driving the flash chips without + having to know about the paging. If you have one of these boards, + you probably want to enable this mapping driver. + +Flash chip mapping on Nora +CONFIG_MTD_NORA + If you had to ask, you don't have one. Say 'N'. + +Flash chip mapping on Octagon 5066 SBC +CONFIG_MTD_OCTAGON + This provides a 'mapping' driver which supports the way in which + the flash chips are connected in the Octagon-5066 Single Board + Computer. You will also need to complete and enable the driver + for JEDEC flash chips. + +Flash chip mapping on RPXlite PPC board +CONFIG_MTD_RPXLITE + The RPXLite PowerPC board has CFI-compliant chips mapped in + a strange sparse mapping. This 'mapping' driver supports that + arrangement, allowing the CFI probe and command set driver code + to communicate with the chips on the RPXLite board. + +Flash chip mapping on Tempustech VMAX SBC301 +CONFIG_MTD_VMAX + This provides a 'mapping' driver which supports the way in which + the flash chips are connected in the Tempustech VMAX SBC301 Single + Board Computer. You will also need to complete and enable the driver + for JEDEC flash chips. + +Direct chardevice access to MTD devices +CONFIG_MTD_CHAR + This provides a character device for each MTD device present in + the system, allowing the user to read and write directly to the + memory chips, and also use ioctl() to obtain information about + the device, or to erase parts of it. + +Pseudo-blockdevice access to MTD devices +CONFIG_MTD_BLOCK + Although flash chips have an erase size too large to useful as + block devices, it is possible to use MTD devices which are based + on RAM chips in this manner. This blockdevice user of MTD devices + performs that function. At the moment, it is also required for + the Journalling Flash File System to obtain a handle on the MTD + device when it's mounted - although the JFFS doesn't actually use + any of the functions of the mtdblock device. + + Later, it may be extended to perform read/erase/modify/write cycles + on flash chips to emulate a smaller block size. Needless to say, + this is very unsafe, but could be useful for filesystems which are + almost never written to. + +FTL (Flash Translation Layer) support +CONFIG_FTL + This provides support for the original Flash Translation Layer which + is part of the PCMCIA specification. It uses a kind of pseudo- + filesystem on a flash device to emulate a block device with 512-byte + sectors, on top of which you put a 'normal' filesystem. You may find + that the algorithms used in this code are patented unless you live + in the Free World where software patents aren't legal - in the USA + you are only permitted to use this on PCMCIA hardware, although + under the terms of the GPL you're obviously permitted to copy, + modify and distribute the code as you wish. Just not use it. + +NFTL (NAND Flash Translation Layer) support +CONFIG_NFTL + This provides support for the NAND Flash Translation Layer which is + used on M-Systems' DiskOnChip devices. It uses a kind of pseudo- + filesystem on a flash device to emulate a block device with 512-byte + sectors, on top of which you put a 'normal' filesystem. You may find + that the algorithms used in this code are patented unless you live + in the Free World where software patents aren't legal - in the USA + you are only permitted to use this on DiskOnChip hardware, although + under the terms of the GPL you're obviously permitted to copy, + modify and distribute the code as you wish. Just not use it. + +Write support for NFTL (EXPERIMENTAL) +CONFIG_NFTL_RW + If you're lucky, this will actually work. Don't whinge if it doesn't. + Contact dwmw2@infradead.org if you want to help to make it more + reliable. + Support for USB CONFIG_USB Universal Serial Bus (USB) is a specification for a serial bus @@ -10781,6 +10965,22 @@ whenever you want), say M here and read Documentation/modules.txt. The module will be called efs.o. +Journalling Flash File System (JFFS) support (EXPERIMENTAL) +CONFIG_JFFS_FS + JFFS is a new file system designed for use on flash memory devices + rather than on block devices. It was developed on the 2.0 kernel + by Axis Communications AB for use on their Linux-based products, + and released under GPL, then 'borrowed' and ported to work with + the 2.4 kernel and the new Memory Technology Device system. + + The 2.4 port is experimental and not yet supported by Axis. Basically, + the good bits are probably theirs, and if it's broken in 2.4 it's + probably our fault. See http://www.developer.axis.com/software/jffs/ + for more information about JFFS. + + Any potential patches or queries should be sent to Axis' mailing + list for JFFS: + UFS file system support (read-only) CONFIG_UFS_FS BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, @@ -12433,7 +12633,7 @@ fieldbus cards made by Applicom International. More information about these cards can be found on the WWW at the address http://www.applicom-int.com/ , or by email from David Woodhouse - . + . To compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here @@ -12615,15 +12815,6 @@ backlight at all, or it might print a lot of errors to the console, especially if you are using gpm. -Ignore multiple suspend/resume cycles -CONFIG_APM_IGNORE_SUSPEND_BOUNCE - This option is necessary on the Dell Inspiron 3200 and others, but - should be safe for all other laptops. When enabled, a system suspend - event that occurs within three seconds of a resume is ignored. - Without this the Inspiron will shut itself off a few seconds after - you open the lid, requiring you to press the power button to resume - it a second time. Say Y. - RTC stores time in GMT CONFIG_APM_RTC_IS_GMT Say Y here if your RTC (Real Time Clock a.k.a. hardware clock) @@ -14935,16 +15126,10 @@ There are four types of PowerPC chips supported. The more common types (601, 603, 604, 740, 750), the Motorola embedded versions (821, 823, 850, 855, 860), the IBM embedded versions (403 and - 405) and the high end 64 bit Power processors (Power 3, Power 4). - Unless you are building a kernel for one of the embedded - processor systems, or a 64 bit IBM RS/6000, choose 6xx. - -CONFIG_PPC64BRIDGE - Currently there is not a 64 bit PowerPC Linux kernel. As a result - if you choose the CONFIG_POWER3 or CONFIG_POWER4 options you - must choose this option as well. This enables gcc to emit - both 32 and 64 bit instructions as well as cause your kernel - to be built as a 32 bit kernel. + 405) and the high end 64 bit Power processors (Power 3, Power 4). + Unless you are building a kernel for one of the embedded + processor systems, or a 64 bit IBM RS/6000, choose 6xx. Note that + the kernel runs in 32-bit mode even on 64-bit chips. Machine Type CONFIG_PMAC diff -u --recursive --new-file v2.4.0-test3/linux/Documentation/DocBook/parportbook.tmpl linux/Documentation/DocBook/parportbook.tmpl --- v2.4.0-test3/linux/Documentation/DocBook/parportbook.tmpl Mon Jul 10 16:47:18 2000 +++ linux/Documentation/DocBook/parportbook.tmpl Wed Jul 12 16:24:33 2000 @@ -386,7 +386,7 @@ announces it. The parport_announce_port function walks down the list of parallel port device drivers (struct parport_drivers) calling the - attach function of each. + attach function of each (which may block). @@ -394,7 +394,7 @@ registering a port with the parport_unregister_port function, and device drivers are notified using the detach - callback. + callback (which may not block). @@ -656,9 +656,31 @@ to the attach function when it is called, or alternatively can be found from the list of detected parallel ports directly with the (now deprecated) - parport_enumerate function. + parport_enumerate function. A better way of + doing this is with parport_find_number or + parport_find_base functions, which find ports + by number and by base I/O address respectively. + + +#include <parport.h> + + + struct parport *parport_find_number + int number + + + + +#include <parport.h> + + + struct parport *parport_find_base + unsigned long base + + + The next three parameters, pf, kf, and irq_func, are @@ -2202,6 +2224,9 @@ !Fdrivers/parport/daisy.c parport_find_class !Fdrivers/parport/share.c parport_register_driver !Fdrivers/parport/share.c parport_unregister_driver +!Fdrivers/parport/share.c parport_get_port +!Fdrivers/parport/share.c parport_put_port +!Fdrivers/parport/share.c parport_find_number parport_find_base !Fdrivers/parport/share.c parport_register_device !Fdrivers/parport/share.c parport_unregister_device !Fdrivers/parport/daisy.c parport_open diff -u --recursive --new-file v2.4.0-test3/linux/Documentation/filesystems/Locking linux/Documentation/filesystems/Locking --- v2.4.0-test3/linux/Documentation/filesystems/Locking Mon Jul 10 16:47:18 2000 +++ linux/Documentation/filesystems/Locking Wed Jul 12 21:58:41 2000 @@ -66,6 +66,7 @@ revalidate: no (see below) Additionally, ->rmdir() has i_zombie on victim and so does ->rename() in case when target exists and is a directory. + ->rename() on directories has (per-superblock) ->s_vfs_rename_sem. ->revalidate(), it may be called both with and without the i_sem on dentry->d_inode. VFS never calls it with i_zombie on dentry->d_inode, but watch for other methods directly calling this one... @@ -226,7 +227,7 @@ mmap: no open: maybe (see below) flush: yes -release: yes +release: no fsync: yes (see below) fasync: yes (see below) lock: yes @@ -238,12 +239,13 @@ end up in ->i_fop/->proc_fops, i.e. ones that belong to character devices (chrdev_open() takes lock before replacing ->f_op and calling the secondary method. As soon as we fix the handling of module reference counters all -instances of ->open() will be called without the BKL. At the same point -->release() will lose BKL. Currently ext2_release() is *the* source of -contention on fs-intensive loads and dropping BKL on ->release() will get -rid of that (we will still need some locking for cases when we close a file -that had been opened r/w, but that can be done using the internal locking with -smaller critical areas). sock_close() is also going to win from that change. +instances of ->open() will be called without the BKL. + +Note: ext2_release() was *the* source of contention on fs-intensive +loads and dropping BKL on ->release() helps to get rid of that (we still +grab BKL for cases when we close a file that had been opened r/w, but that +can and should be done using the internal locking with smaller critical areas). +Current worst offender is ext2_get_block()... ->fasync() is a mess. This area needs a big cleanup and that will probably affect locking. diff -u --recursive --new-file v2.4.0-test3/linux/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt --- v2.4.0-test3/linux/Documentation/kernel-parameters.txt Fri Jun 23 21:55:06 2000 +++ linux/Documentation/kernel-parameters.txt Wed Jul 12 16:25:15 2000 @@ -1,4 +1,4 @@ -June 2000 Kernel Parameters v2.4.0 +July 2000 Kernel Parameters v2.4.0 ~~~~~~~~~~~~~~~~~ The following is a consolidated list of the kernel parameters as implemented @@ -80,6 +80,8 @@ AM53C974= [HW,SCSI] + amijoy= [HW,JOY] Amiga joystick support + apm= [APM] Advanced Power Management. applicom= [HW] @@ -139,6 +141,12 @@ dasd= [HW,NET] + db9= [HW,JOY] + + db9_2= [HW,JOY] + + db9_3= [HW,JOY] + debug [KNL] Enable kernel debugging (events log level). decnet= [HW,NET] @@ -179,6 +187,12 @@ ftape= [HW] Floppy Tape subsystem debugging options. + gc= [HW,JOY] + + gc_2= [HW,JOY] + + gc_3= [HW,JOY] + gdth= [HW,SCSI] gscd= [HW,CD] @@ -194,10 +208,6 @@ hisax= [HW,ISDN] - in2000= [HW,SCSI] - - init= [KNL] - ibmmcascsi= [HW,MCA,SCSI] IBM MicroChannel SCSI adapter. icn= [HW,ISDN] @@ -208,40 +218,20 @@ idebus= [HW] (E)IDE subsystem : VLB/PCI bus speed. + idle= [HW] + + in2000= [HW,SCSI] + + init= [KNL] + ip= [PNP] isp16= [HW,CD] iucv= [HW,NET] - js_am= [HW,JOY] - - js_an= [HW,JOY] - - js_as= [HW.JOY] - - js_console= [HW,JOY] - - js_console2= [HW,JOY] - - js_console3= [HW,JOY] - - js_db9= [HW,JOY] - - js_db9_2= [HW,JOY] - - js_db9_3= [HW,JOY] - - js_l4= [HW,JOY] - - js_pci= [HW,JOY,PCI] + js= [HW,JOY] Analog joystick - js_tg= [HW,JOY] - - js_tg_2= [HW,JOY] - - js_tg_3= [HW,JOY] - kbd-reset [VT] load_ramdisk= [RAM] List of ramdisks to load from floppy. @@ -354,6 +344,8 @@ nosync [HW, M68K] Disables sync negotiation for all devices. + notsc [BUGS=ix86] Disable Time Stamp Counter + nowb [ARM] opl3= [HW,SOUND] @@ -483,6 +475,12 @@ t128= [HW,SCSI] tdfx= [HW,DRM] + + tgfx= [HW,JOY] + + tgfx_2= [HW,JOY] + + tgfx_3= [HW,JOY] tmc8xx= [HW,SCSI] diff -u --recursive --new-file v2.4.0-test3/linux/Documentation/usb/ov511.txt linux/Documentation/usb/ov511.txt --- v2.4.0-test3/linux/Documentation/usb/ov511.txt Mon Jul 10 16:47:18 2000 +++ linux/Documentation/usb/ov511.txt Tue Jul 11 10:46:38 2000 @@ -6,7 +6,9 @@ Homepage: http://alpha.dyndns.org/ov511 NEW IN THIS VERSION: - o Preliminary support for YUV422 and YUV422P V4L modes + o Sensor detection fixes + o More efficient/reliable buffer allocation + o Many minor fixes INTRODUCTION: @@ -176,7 +178,7 @@ WORKING FEATURES: o Color streaming/capture at 640x480, 448x336, 384x288, 352x288, and 320x240 - o YUV420 color + o YUV420 and YUV422P color o Monochrome o Setting/getting of saturation, contrast and brightness (no hue yet; only works with OV7610, not the OV7620 or OV7620AE) diff -u --recursive --new-file v2.4.0-test3/linux/Documentation/usb/usb-help.txt linux/Documentation/usb/usb-help.txt --- v2.4.0-test3/linux/Documentation/usb/usb-help.txt Tue Apr 11 15:09:11 2000 +++ linux/Documentation/usb/usb-help.txt Wed Jul 12 20:07:39 2000 @@ -1,5 +1,5 @@ usb-help.txt -2000-March-24 +2000-July-12 For USB help other than the readme files that are located in linux/Documentation/usb/*, see the following: @@ -7,10 +7,12 @@ Linux-USB project: http://www.linux-usb.org mirrors at http://www.suse.cz/development/linux-usb/ and http://usb.in.tum.de/linux-usb/ -Linux USB Guide: http://linuxusbguide.sourceforge.net +Linux USB Guide: http://linux-usb.sourceforge.net Linux-USB device overview (working devices and drivers): http://www.qbik.ch/usb/devices/ -The Linux-USB mailing list is linux-usb@suse.com . +The Linux-USB mailing lists are: + linux-usb-users@lists.sourceforge.net for general user help + linux-usb-devel@lists.sourceforge.net for developer discussions ### diff -u --recursive --new-file v2.4.0-test3/linux/MAINTAINERS linux/MAINTAINERS --- v2.4.0-test3/linux/MAINTAINERS Mon Jul 10 16:47:18 2000 +++ linux/MAINTAINERS Wed Jul 12 20:07:39 2000 @@ -600,6 +600,13 @@ W: http://www.melware.de S: Maintained +JOURNALLING FLASH FILE SYSTEM (JFFS) +P: Axis Communications AB +M: jffs-dev@axis.com +L: jffs-dev@axis.com +W: http://www.developer.axis.com/software/jffs/ +S: Maintained + JOYSTICK DRIVER P: Vojtech Pavlik M: vojtech@suse.cz @@ -645,11 +652,6 @@ L: linuxppc-dev@lists.linuxppc.org S: Maintained -MAESTRO PCI SOUND DRIVER -P: Zach Brown -M: zab@zabbo.net -S: Odd Fixes - M68K P: Jes Sorensen M: Jes.Sorensen@cern.ch @@ -670,6 +672,18 @@ W: http://www.tazenda.demon.co.uk/phil/linux-hp S: Maintained +MAESTRO PCI SOUND DRIVER +P: Zach Brown +M: zab@zabbo.net +S: Odd Fixes + +MEMORY TECHNOLOGY DEVICES +P: David Woodhouse +M: dwmw2@redhat.com +W: http://www.linux-mtd.infradead.org/ +L: mtd@infradead.org +S: Maintained + MIPS P: Ralf Baechle M: ralf@gnu.ai.mit.edu @@ -1142,72 +1156,91 @@ USB ACM DRIVER P: Vojtech Pavlik M: vojtech@suse.cz -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Supported +USB BLUETOOTH DRIVER +P: Greg Kroah-Hartman +M: greg@kroah.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net +S: Maintained +W: http://www.kroah.com/linux-usb/ + USB HID/HIDBP/INPUT DRIVERS P: Vojtech Pavlik M: vojtech@suse.cz -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net W: http://www.suse.cz/development/input/ S: Supported USB HUB P: Johannes Erdfelt M: jerdfelt@sventech.com -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Maintained USB OHCI DRIVER P: Roman Weissgaerber M: weissg@vienna.at -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Maintained USB OV511 DRIVER P: Mark McClelland M: mmcclelland@delphi.com -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net W: http://alpha.dyndns.org/ov511/ S: Maintained USB PEGASUS DRIVER P: Petko Manolov M: petkan@spct.net -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Maintained USB PRINTER DRIVER P: Vojtech Pavlik M: vojtech@suse.cz -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Supported USB SERIAL DIGI ACCELEPORT DRIVER P: Peter Berger and Al Borchers M: pberger@brimson.com M: alborchers@steinerpoint.com -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Supported USB SERIAL DRIVER P: Greg Kroah-Hartman M: greg@kroah.com -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Maintained W: http://www.kroah.com/linux-usb/ USB MASS STORAGE DRIVER P: Matthew Dharm M: mdharm-usb@one-eyed-alien.net -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net S: Maintained W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ USB UHCI DRIVER P: Georg Acher M: usb@in.tum.de -L: linux-usb@suse.com +L: linux-usb-users@lists.sourceforge.net +L: linux-usb-devel@lists.sourceforge.net W: http://usb.in.tum.de S: Maintained diff -u --recursive --new-file v2.4.0-test3/linux/Makefile linux/Makefile --- v2.4.0-test3/linux/Makefile Mon Jul 10 16:47:18 2000 +++ linux/Makefile Mon Jul 10 16:47:34 2000 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -test3 +EXTRAVERSION = -test4 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -u --recursive --new-file v2.4.0-test3/linux/arch/alpha/boot/tools/objstrip.c linux/arch/alpha/boot/tools/objstrip.c --- v2.4.0-test3/linux/arch/alpha/boot/tools/objstrip.c Sun Aug 4 03:37:59 1996 +++ linux/arch/alpha/boot/tools/objstrip.c Tue Jul 11 19:02:37 2000 @@ -150,7 +150,7 @@ prog_name, inname); exit(1); } - if (!elf_check_arch(elf->e_machine)) { + if (!elf_check_arch(elf)) { fprintf(stderr, "%s: is not for this processor (e_machine=%d)\n", prog_name, elf->e_machine); exit(1); diff -u --recursive --new-file v2.4.0-test3/linux/arch/alpha/kernel/sys_nautilus.c linux/arch/alpha/kernel/sys_nautilus.c --- v2.4.0-test3/linux/arch/alpha/kernel/sys_nautilus.c Thu Mar 2 14:36:22 2000 +++ linux/arch/alpha/kernel/sys_nautilus.c Tue Jul 11 14:26:47 2000 @@ -53,6 +53,11 @@ static void __init nautilus_init_irq(void) { + if (alpha_using_srm) { + alpha_mv.device_interrupt = srm_device_interrupt; + alpha_mv.kill_arch = NULL; + } + init_i8259a_irqs(); common_init_isa_dma(); } diff -u --recursive --new-file v2.4.0-test3/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c --- v2.4.0-test3/linux/arch/alpha/kernel/time.c Wed Apr 26 16:34:06 2000 +++ linux/arch/alpha/kernel/time.c Tue Jul 11 10:55:38 2000 @@ -45,7 +45,7 @@ #include "irq_impl.h" extern rwlock_t xtime_lock; -extern volatile unsigned long lost_ticks; /* kernel/sched.c */ +extern unsigned long wall_jiffies; /* kernel/timer.c */ static int set_rtc_mmss(unsigned long); @@ -312,7 +312,7 @@ sec = xtime.tv_sec; usec = xtime.tv_usec; partial_tick = state.partial_tick; - lost = lost_ticks; + lost = jiffies - wall_jiffies; read_unlock_irqrestore(&xtime_lock, flags); @@ -363,12 +363,12 @@ time. Without this, a full-tick error is possible. */ #ifdef CONFIG_SMP - delta_usec = lost_ticks * (1000000 / HZ); + delta_usec = (jiffies - wall_jiffies) * (1000000 / HZ); #else delta_usec = rpcc() - state.last_time; delta_usec = (delta_usec * state.scaled_ticks_per_cycle + state.partial_tick - + (lost_ticks << FIX_SHIFT)) * 15625; + + ((jiffies - wall_jiffies) << FIX_SHIFT)) * 15625; delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; #endif diff -u --recursive --new-file v2.4.0-test3/linux/arch/arm/config.in linux/arch/arm/config.in --- v2.4.0-test3/linux/arch/arm/config.in Mon Jul 10 16:47:18 2000 +++ linux/arch/arm/config.in Wed Jul 12 15:12:11 2000 @@ -15,6 +15,14 @@ bool 'Prompt for obsolete code/drivers' CONFIG_OBSOLETE endmenu +mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu mainmenu_option next_comment comment 'System Type' @@ -156,17 +164,6 @@ define_bool CONFIG_ISA_DMA n fi endmenu - - -mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool ' Kernel module loader' CONFIG_KMOD -fi -endmenu - mainmenu_option next_comment comment 'General setup' diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/Makefile linux/arch/i386/Makefile --- v2.4.0-test3/linux/arch/i386/Makefile Fri Jun 23 21:55:07 2000 +++ linux/arch/i386/Makefile Tue Jul 11 14:19:13 2000 @@ -114,6 +114,8 @@ zlilo: vmlinux @$(MAKEBOOT) BOOTIMAGE=zImage zlilo +tmp: + @$(MAKEBOOT) BOOTIMAGE=bzImage zlilo bzlilo: vmlinux @$(MAKEBOOT) BOOTIMAGE=bzImage zlilo diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/config.in linux/arch/i386/config.in --- v2.4.0-test3/linux/arch/i386/config.in Mon Jul 10 16:47:19 2000 +++ linux/arch/i386/config.in Wed Jul 12 15:12:11 2000 @@ -16,6 +16,15 @@ endmenu mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'Processor type and features' choice 'Processor family' \ "386 CONFIG_M386 \ @@ -146,15 +155,6 @@ endmenu mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool ' Set version information on all module symbols' CONFIG_MODVERSIONS - bool ' Kernel module loader' CONFIG_KMOD -fi -endmenu - -mainmenu_option next_comment comment 'General setup' bool 'Networking support' CONFIG_NET @@ -225,7 +225,6 @@ bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK - bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT bool ' Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS bool ' Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.4.0-test3/linux/arch/i386/defconfig Mon Jul 10 16:47:19 2000 +++ linux/arch/i386/defconfig Thu Jul 13 14:25:50 2000 @@ -12,6 +12,13 @@ # CONFIG_EXPERIMENTAL is not set # +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# # Processor type and features # # CONFIG_M386 is not set @@ -46,13 +53,6 @@ # CONFIG_MTRR is not set CONFIG_SMP=y CONFIG_HAVE_DEC_LOCK=y - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set # # General setup diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c --- v2.4.0-test3/linux/arch/i386/kernel/apm.c Mon Jul 10 16:47:19 2000 +++ linux/arch/i386/kernel/apm.c Wed Jul 12 21:58:41 2000 @@ -142,6 +142,8 @@ * fixed by sfr). * Make power off work on SMP again (Tony Hoyle * and ) modified by sfr. + * Remove CONFIG_APM_SUSPEND_BOUNCE. The bounce ignore + * interval is now configurable. * * APM 1.1 Reference: * @@ -178,6 +180,8 @@ #include #include #include +#include +#include #include #include @@ -267,10 +271,9 @@ #define APM_CHECK_TIMEOUT (HZ) /* - * If CONFIG_APM_IGNORE_SUSPEND_BOUNCE is defined then - * ignore suspend events for this amount of time after a resume + * Ignore suspend events for this amount of time after a resume */ -#define BOUNCE_INTERVAL (3 * HZ) +#define DEFAULT_BOUNCE_INTERVAL (3 * HZ) /* * Save a segment register away @@ -314,28 +317,30 @@ unsigned short segment; } apm_bios_entry; #ifdef CONFIG_APM_CPU_IDLE -static int clock_slowed = 0; +static int clock_slowed; #endif -static int suspends_pending = 0; -static int standbys_pending = 0; -static int waiting_for_resume = 0; +static int suspends_pending; +static int standbys_pending; +static int waiting_for_resume; +static int ignore_normal_resume; +static int bounce_interval = DEFAULT_BOUNCE_INTERVAL; #ifdef CONFIG_APM_RTC_IS_GMT # define clock_cmos_diff 0 # define got_clock_diff 1 #else static long clock_cmos_diff; -static int got_clock_diff = 0; +static int got_clock_diff; #endif -static int debug = 0; -static int apm_disabled = 0; +static int debug; +static int apm_disabled; #ifdef CONFIG_SMP -static int power_off = 0; +static int power_off; #else static int power_off = 1; #endif -static int exit_kapmd = 0; -static int kapmd_running = 0; +static int exit_kapmd; +static int kapmd_running; static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); @@ -912,16 +917,16 @@ set_time(); if (err == APM_NO_ERROR) err = APM_SUCCESS; - if (err != APM_SUCCESS) { + if (err != APM_SUCCESS) apm_error("suspend", err); - send_event(APM_NORMAL_RESUME); - sti(); - queue_event(APM_NORMAL_RESUME, NULL); - } + send_event(APM_NORMAL_RESUME); + sti(); + queue_event(APM_NORMAL_RESUME, NULL); for (as = user_list; as != NULL; as = as->next) { as->suspend_wait = 0; as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO); } + ignore_normal_resume = 1; wake_up_interruptible(&apm_suspend_waitqueue); return err; } @@ -942,7 +947,7 @@ apm_event_t event; apm_eventinfo_t info; - static int notified = 0; + static int notified; /* we don't use the eventinfo */ error = apm_get_event(&event, &info); @@ -958,10 +963,8 @@ static void check_events(void) { apm_event_t event; -#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE - static unsigned long last_resume = 0; - static int ignore_bounce = 0; -#endif + static unsigned long last_resume; + static int ignore_bounce; while ((event = get_event()) != 0) { if (debug) { @@ -972,11 +975,12 @@ printk(KERN_DEBUG "apm: received unknown " "event 0x%02x\n", event); } -#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE if (ignore_bounce - && ((jiffies - last_resume) > BOUNCE_INTERVAL)) + && ((jiffies - last_resume) > bounce_interval)) ignore_bounce = 0; -#endif + if (ignore_normal_resume && (event != APM_NORMAL_RESUME)) + ignore_normal_resume = 0; + switch (event) { case APM_SYS_STANDBY: case APM_USER_STANDBY: @@ -994,10 +998,11 @@ break; #endif case APM_SYS_SUSPEND: -#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE - if (ignore_bounce) + if (ignore_bounce) { + if (apm_bios_info.version > 0x100) + apm_set_power_state(APM_STATE_REJECT); break; -#endif + } /* * If we are already processing a SUSPEND, * then further SUSPEND events from the BIOS @@ -1020,14 +1025,14 @@ case APM_CRITICAL_RESUME: case APM_STANDBY_RESUME: waiting_for_resume = 0; -#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE last_resume = jiffies; ignore_bounce = 1; -#endif - set_time(); - send_event(event); - sti(); - queue_event(event, NULL); + if ((event != APM_NORMAL_RESUME) + || (ignore_normal_resume == 0)) { + set_time(); + send_event(event); + queue_event(event, NULL); + } break; case APM_CAPABILITY_CHANGE: @@ -1264,6 +1269,7 @@ if (check_apm_user(as, "release")) return 0; filp->private_data = NULL; + lock_kernel(); if (as->standbys_pending > 0) { standbys_pending -= as->standbys_pending; if (standbys_pending <= 0) @@ -1288,6 +1294,7 @@ else as1->next = as->next; } + unlock_kernel(); kfree_s(as, sizeof(*as)); return 0; } @@ -1519,6 +1526,7 @@ return 0; } +#ifndef MODULE static int __init apm_setup(char *str) { int invert; @@ -1536,6 +1544,9 @@ if ((strncmp(str, "power-off", 9) == 0) || (strncmp(str, "power_off", 9) == 0)) power_off = !invert; + if ((strncmp(str, "bounce-interval=", 16) == 0) || + (strncmp(str, "bounce_interval=", 16) == 0)) + bounce_interval = simple_strtol(str + 16, NULL, 0); str = strchr(str, ','); if (str != NULL) str += strspn(str, ", \t"); @@ -1544,6 +1555,7 @@ } __setup("apm=", apm_setup); +#endif static struct file_operations apm_bios_fops = { owner: THIS_MODULE, @@ -1702,5 +1714,9 @@ MODULE_DESCRIPTION("Advanced Power Management"); MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Enable debug mode"); +MODULE_PARM(power_off, "i"); +MODULE_PARM_DESC(power_off, "Enable power off"); +MODULE_PARM(bounce_interval, "i"); +MODULE_PARM_DESC(bounce_interval, "Set the number of ticks to ignore suspend bounces"); EXPORT_NO_SYMBOLS; diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c --- v2.4.0-test3/linux/arch/i386/kernel/i386_ksyms.c Fri Jun 23 21:55:07 2000 +++ linux/arch/i386/kernel/i386_ksyms.c Tue Jul 11 11:17:45 2000 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,7 @@ EXPORT_SYMBOL(strtok); EXPORT_SYMBOL(strpbrk); +EXPORT_SYMBOL(simple_strtol); EXPORT_SYMBOL(strncpy_from_user); EXPORT_SYMBOL(__strncpy_from_user); diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/kernel/microcode.c linux/arch/i386/kernel/microcode.c --- v2.4.0-test3/linux/arch/i386/kernel/microcode.c Mon Jul 10 16:47:19 2000 +++ linux/arch/i386/kernel/microcode.c Wed Jul 12 21:58:41 2000 @@ -147,7 +147,9 @@ static int microcode_release(struct inode *inode, struct file *file) { + lock_kernel(); clear_bit(MICROCODE_IS_OPEN, µcode_status); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c --- v2.4.0-test3/linux/arch/i386/kernel/mtrr.c Fri Jun 23 21:55:07 2000 +++ linux/arch/i386/kernel/mtrr.c Wed Jul 12 21:58:41 2000 @@ -251,6 +251,7 @@ #include #include #include +#include #include #include @@ -1532,6 +1533,7 @@ unsigned int *fcount = file->private_data; if (fcount == NULL) return 0; + lock_kernel(); max = get_num_var_ranges (); for (i = 0; i < max; ++i) { @@ -1541,6 +1543,7 @@ --fcount[i]; } } + unlock_kernel(); kfree (fcount); file->private_data = NULL; return 0; diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- v2.4.0-test3/linux/arch/i386/kernel/smp.c Mon Jun 19 16:31:57 2000 +++ linux/arch/i386/kernel/smp.c Wed Jul 12 12:47:20 2000 @@ -392,6 +392,8 @@ * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; + static volatile struct call_data_struct { void (*func) (void *info); void *info; @@ -422,9 +424,8 @@ { struct call_data_struct data; int ret, cpus = smp_num_cpus-1; - static spinlock_t lock = SPIN_LOCK_UNLOCKED; - if(cpus == 0) + if (!cpus) return 0; data.func = func; @@ -434,21 +435,21 @@ if (wait) atomic_set(&data.finished, 0); - spin_lock_bh(&lock); + spin_lock_bh(&call_lock); call_data = &data; /* Send a message to all other CPUs and wait for them to respond */ send_IPI_allbutself(CALL_FUNCTION_VECTOR); /* Wait for response */ - /* FIXME: lock-up detection, backtrace on lock-up */ - while(atomic_read(&data.started) != cpus) + while (atomic_read(&data.started) != cpus) barrier(); ret = 0; if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock_bh(&lock); + spin_unlock_bh(&call_lock); + return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/i386/kernel/visws_apic.c linux/arch/i386/kernel/visws_apic.c --- v2.4.0-test3/linux/arch/i386/kernel/visws_apic.c Wed Apr 26 16:34:06 2000 +++ linux/arch/i386/kernel/visws_apic.c Thu Jul 13 09:29:34 2000 @@ -91,6 +91,8 @@ static void startup_cobalt_irq(unsigned int irq); #define shutdown_cobalt_irq disable_cobalt_irq +static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED; + static struct hw_interrupt_type cobalt_irq_type = { "Cobalt-APIC", startup_cobalt_irq, diff -u --recursive --new-file v2.4.0-test3/linux/arch/ia64/boot/bootloader.c linux/arch/ia64/boot/bootloader.c --- v2.4.0-test3/linux/arch/ia64/boot/bootloader.c Thu Feb 10 17:11:03 2000 +++ linux/arch/ia64/boot/bootloader.c Tue Jul 11 19:02:37 2000 @@ -157,7 +157,7 @@ cons_write("not an ELF executable\n"); return; } - if (!elf_check_arch(elf->e_machine)) { + if (!elf_check_arch(elf)) { cons_write("kernel not for this processor\n"); return; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/ia64/config.in linux/arch/ia64/config.in --- v2.4.0-test3/linux/arch/ia64/config.in Mon Jul 10 16:47:19 2000 +++ linux/arch/ia64/config.in Wed Jul 12 15:12:11 2000 @@ -4,6 +4,20 @@ mainmenu_name "Kernel configuration of Linux for IA-64 machines" mainmenu_option next_comment + comment 'Code maturity level options' + bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL +endmenu + +mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'General setup' define_bool CONFIG_IA64 y @@ -66,20 +80,6 @@ else define_bool CONFIG_PCMCIA n fi - -mainmenu_option next_comment - comment 'Code maturity level options' - bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL -endmenu - -mainmenu_option next_comment - comment 'Loadable module support' - bool 'Enable loadable module support' CONFIG_MODULES - if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD - fi -endmenu source drivers/parport/Config.in diff -u --recursive --new-file v2.4.0-test3/linux/arch/m68k/atari/joystick.c linux/arch/m68k/atari/joystick.c --- v2.4.0-test3/linux/arch/m68k/atari/joystick.c Fri Jun 23 21:55:07 2000 +++ linux/arch/m68k/atari/joystick.c Wed Jul 12 21:58:42 2000 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -60,11 +61,13 @@ { int minor = DEVICE_NR(inode->i_rdev); + lock_kernel(); joystick[minor].active = 0; joystick[minor].ready = 0; if ((joystick[0].active == 0) && (joystick[1].active == 0)) ikbd_joystick_disable(); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/m68k/bvme6000/rtc.c linux/arch/m68k/bvme6000/rtc.c --- v2.4.0-test3/linux/arch/m68k/bvme6000/rtc.c Thu Feb 10 17:11:04 2000 +++ linux/arch/m68k/bvme6000/rtc.c Wed Jul 12 21:58:42 2000 @@ -15,6 +15,7 @@ #include #include #include /* For struct rtc_time and ioctls, etc */ +#include #include #include @@ -149,7 +150,9 @@ static int rtc_release(struct inode *inode, struct file *file) { + lock_kernel(); rtc_status = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/m68k/config.in linux/arch/m68k/config.in --- v2.4.0-test3/linux/arch/m68k/config.in Mon Jul 10 16:47:19 2000 +++ linux/arch/m68k/config.in Wed Jul 12 15:12:11 2000 @@ -13,6 +13,15 @@ endmenu mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'Platform dependent setup' define_bool CONFIG_ISA n @@ -134,15 +143,6 @@ source drivers/pci/Config.in fi -endmenu - -mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool ' Kernel module loader' CONFIG_KMOD -fi endmenu source drivers/mtd/Config.in diff -u --recursive --new-file v2.4.0-test3/linux/arch/m68k/mvme16x/rtc.c linux/arch/m68k/mvme16x/rtc.c --- v2.4.0-test3/linux/arch/m68k/mvme16x/rtc.c Thu Feb 10 17:11:04 2000 +++ linux/arch/m68k/mvme16x/rtc.c Wed Jul 12 21:58:42 2000 @@ -15,6 +15,7 @@ #include #include #include /* For struct rtc_time and ioctls, etc */ +#include #include #include @@ -138,7 +139,9 @@ static int rtc_release(struct inode *inode, struct file *file) { + lock_kernel(); rtc_status = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/Makefile linux/arch/mips/Makefile --- v2.4.0-test3/linux/arch/mips/Makefile Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/Makefile Tue Jul 11 11:14:42 2000 @@ -143,6 +143,15 @@ endif # +# Orion Board +# +ifdef CONFIG_ORION +LIBS += arch/mips/orion/orionkern.a +SUBDIRS += arch/mips/orion +LINKSCRIPT = arch/mips/orion/ld.script.orion +endif + +# # Choosing incompatible machines durings configuration will result in # error messages during linking. Select a default linkscript if # none has been choosen above. @@ -179,6 +188,13 @@ balo: vmlinux $(BAGETBOOT) balo +endif + +ifdef CONFIG_ORION +ORIONBOOT = $(MAKE) -C arch/$(ARCH)/orion + +orionboot: + $(ORIONBOOT) orionboot endif MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/cobalt/reset.c linux/arch/mips/cobalt/reset.c --- v2.4.0-test3/linux/arch/mips/cobalt/reset.c Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/cobalt/reset.c Thu Jul 13 09:39:49 2000 @@ -1,6 +1,7 @@ /* * Reset a Cobalt Qube. */ +#include #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/config.in linux/arch/mips/config.in --- v2.4.0-test3/linux/arch/mips/config.in Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/config.in Wed Jul 12 15:12:11 2000 @@ -10,6 +10,15 @@ endmenu mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'Machine selection' if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61 @@ -21,6 +30,7 @@ fi bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION bool 'Support for NEC DDB Vrc-5074 (EXPERIMENTAL)' CONFIG_DDB5074 + bool 'Support for Galileo Evaluation board or CoSine Orion' CONFIG_ORION fi bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000 bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700 @@ -157,12 +167,6 @@ bool 'Sysctl support' CONFIG_SYSCTL source drivers/parport/Config.in - - bool 'Enable loadable module support' CONFIG_MODULES - if [ "$CONFIG_MODULES" = "y" ]; then - bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool ' Kernel module loader' CONFIG_KMOD - fi if [ "$CONFIG_DECSTATION" = "y" ]; then bool 'TURBOchannel support' CONFIG_TC diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/dec/time.c linux/arch/mips/dec/time.c --- v2.4.0-test3/linux/arch/mips/dec/time.c Tue Aug 31 17:29:12 1999 +++ linux/arch/mips/dec/time.c Wed Jul 12 15:14:41 2000 @@ -25,7 +25,8 @@ #include #include -extern volatile unsigned long lost_ticks; +extern volatile unsigned long wall_jiffies; +extern rwlock_t xtime_lock; /* * Change this if you have some constant time drift @@ -47,69 +48,69 @@ */ static unsigned long do_fast_gettimeoffset(void) { - u32 count; - unsigned long res, tmp; + u32 count; + unsigned long res, tmp; - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies = 0; - unsigned long quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient = 0; - - tmp = jiffies; - - quotient = cached_quotient; - - if (last_jiffies != tmp) { - last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=&r"(quotient) - : "r"(timerhi), - "m"(timerlo), - "r"(tmp), - "r"(USECS_PER_JIFFY) - : "$1"); - cached_quotient = quotient; - } - /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + /* Last jiffy when do_fast_gettimeoffset() was called. */ + static unsigned long last_jiffies = 0; + unsigned long quotient; + + /* + * Cached "1/(clocks per usec)*2^32" value. + * It has to be recalculated once each jiffy. + */ + static unsigned long cached_quotient = 0; + + tmp = jiffies; + + quotient = cached_quotient; + + if (tmp && last_jiffies != tmp) { + last_jiffies = tmp; + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "lwu\t%0,%2\n\t" + "dsll32\t$1,%1,0\n\t" + "or\t$1,$1,%0\n\t" + "ddivu\t$0,$1,%3\n\t" + "mflo\t$1\n\t" + "dsll32\t%0,%4,0\n\t" + "nop\n\t" + "ddivu\t$0,%0,$1\n\t" + "mflo\t%0\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=&r"(quotient) + :"r"(timerhi), + "m"(timerlo), + "r"(tmp), + "r"(USECS_PER_JIFFY) + :"$1"); + cached_quotient = quotient; + } + /* Get last timer tick in absolute kernel time */ + count = read_32bit_cp0_register(CP0_COUNT); - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; //printk("count: %08lx, %08lx:%08lx\n", count, timerhi, timerlo); - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - : "=r"(res) - : "r"(count), - "r"(quotient)); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; + __asm__("multu\t%1,%2\n\t" + "mfhi\t%0" + :"=r"(res) + :"r"(count), + "r"(quotient)); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY - 1; - return res; + return res; } /* This function must be called with interrupts disabled @@ -148,11 +149,11 @@ static unsigned long do_slow_gettimeoffset(void) { - /* - * This is a kludge until I find a way for the - * DECstations without bus cycle counter. HK - */ - return 0; + /* + * This is a kludge until I find a way for the + * DECstations without bus cycle counter. HK + */ + return 0; } static unsigned long (*do_gettimeoffset) (void) = do_slow_gettimeoffset; @@ -162,47 +163,47 @@ */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; + unsigned long flags; - save_and_cli(flags); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. - */ - if (lost_ticks) - tv->tv_usec += USECS_PER_JIFFY; - - restore_flags(flags); - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } + read_lock_irqsave(&xtime_lock, flags); + *tv = xtime; + tv->tv_usec += do_gettimeoffset(); + + /* + * xtime is atomically updated in timer_bh. lost_ticks is + * nonzero if the timer bottom half hasnt executed yet. + */ + if (jiffies - wall_jiffies) + tv->tv_usec += USECS_PER_JIFFY; + + read_unlock_irqrestore(&xtime_lock, flags); + + if (tv->tv_usec >= 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } } void do_settimeofday(struct timeval *tv) { - cli(); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! - */ - tv->tv_usec -= do_gettimeoffset(); - - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - xtime = *tv; - time_state = TIME_BAD; - time_maxerror = MAXPHASE; - time_esterror = MAXPHASE; - sti(); + write_lock_irq(&xtime_lock); + /* This is revolting. We need to set the xtime.tv_usec + * correctly. However, the value in this location is + * is value at the last tick. + * Discover what correction gettimeofday + * would have done, and then undo it! + */ + tv->tv_usec -= do_gettimeoffset(); + + if (tv->tv_usec < 0) { + tv->tv_usec += 1000000; + tv->tv_sec--; + } + xtime = *tv; + time_state = TIME_BAD; + time_maxerror = MAXPHASE; + time_esterror = MAXPHASE; + write_unlock_irq(&xtime_lock); } /* @@ -214,53 +215,57 @@ */ static int set_rtc_mmss(unsigned long nowtime) { - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned char save_control, save_freq_select; + + save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ + CMOS_WRITE((save_control | RTC_SET), RTC_CONTROL); + + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ + CMOS_WRITE((save_freq_select | RTC_DIV_RESET2), RTC_FREQ_SELECT); + + cmos_minutes = CMOS_READ(RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + } + CMOS_WRITE(real_seconds, RTC_SECONDS); + CMOS_WRITE(real_minutes, RTC_MINUTES); + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; } - CMOS_WRITE(real_seconds, RTC_SECONDS); - CMOS_WRITE(real_minutes, RTC_MINUTES); - } else - retval = -1; - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - return retval; + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + + return retval; } /* last time the cmos clock got updated */ @@ -271,40 +276,74 @@ * as well as call the "do_timer()" routine every clocktick */ static void inline - timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile unsigned char dummy; + volatile unsigned char dummy; - dummy = CMOS_READ(RTC_REG_C); /* ACK RTC Interrupt */ - do_timer(regs); + dummy = CMOS_READ(RTC_REG_C); /* ACK RTC Interrupt */ - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec > 500000 - (tick >> 1) && - xtime.tv_usec < 500000 + (tick >> 1)) - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + if (!user_mode(regs)) { + if (prof_buffer && current->pid) { + extern int _stext; + unsigned long pc = regs->cp0_epc; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + /* + * Dont ignore out-of-bounds pc values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (pc > prof_len - 1) + pc = prof_len - 1; + atomic_inc((atomic_t *) & prof_buffer[pc]); + } + } + do_timer(regs); + + /* + * If we have an externally synchronized Linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + read_lock(&xtime_lock); + if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec > 500000 - (tick >> 1) && + xtime.tv_usec < 500000 + (tick >> 1)) + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + /* As we return to user mode fire off the other CPU schedulers.. this is + basically because we don't yet share IRQ's around. This message is + rigged to be safe on the 386 - basically it's a hack, so don't look + closely for now.. */ + /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */ + read_unlock(&xtime_lock); } static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - unsigned int count; - - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; + unsigned int count; - timer_interrupt(irq, dev_id, regs); + /* + * The cycle counter is only 32 bit which is good for about + * a minute at current count rates of upto 150MHz or so. + */ + count = read_32bit_cp0_register(CP0_COUNT); + timerhi += (count < timerlo); /* Wrap around */ + timerlo = count; + + timer_interrupt(irq, dev_id, regs); + + if (!jiffies) { + /* + * If jiffies has overflowed in this timer_interrupt we must + * update the timer[hi]/[lo] to make do_fast_gettimeoffset() + * quotient calc still valid. -arca + */ + timerhi = timerlo = 0; + } } /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. @@ -326,114 +365,114 @@ unsigned int day, unsigned int hour, unsigned int min, unsigned int sec) { - if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ - mon += 12; /* Puts Feb last since it has leap day */ - year -= 1; - } - return ((( - (unsigned long) (year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + - year * 365 - 719499 - ) * 24 + hour /* now have hours */ - ) * 60 + min /* now have minutes */ - ) * 60 + sec; /* finally seconds */ + if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */ + mon += 12; /* Puts Feb last since it has leap day */ + year -= 1; + } + return ((( + (unsigned long) (year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + + year * 365 - 719499 + ) * 24 + hour /* now have hours */ + ) * 60 + min /* now have minutes */ + ) * 60 + sec; /* finally seconds */ } char cyclecounter_available; static inline void init_cycle_counter(void) { - switch (mips_cputype) { - case CPU_UNKNOWN: - case CPU_R2000: - case CPU_R3000: - case CPU_R3000A: - case CPU_R3041: - case CPU_R3051: - case CPU_R3052: - case CPU_R3081: - case CPU_R3081E: - case CPU_R6000: - case CPU_R6000A: - case CPU_R8000: /* Not shure about that one, play safe */ - cyclecounter_available = 0; - break; - case CPU_R4000PC: - case CPU_R4000SC: - case CPU_R4000MC: - case CPU_R4200: - case CPU_R4400PC: - case CPU_R4400SC: - case CPU_R4400MC: - case CPU_R4600: - case CPU_R10000: - case CPU_R4300: - case CPU_R4650: - case CPU_R4700: - case CPU_R5000: - case CPU_R5000A: - case CPU_R4640: - case CPU_NEVADA: - cyclecounter_available = 1; - break; - } + switch (mips_cputype) { + case CPU_UNKNOWN: + case CPU_R2000: + case CPU_R3000: + case CPU_R3000A: + case CPU_R3041: + case CPU_R3051: + case CPU_R3052: + case CPU_R3081: + case CPU_R3081E: + case CPU_R6000: + case CPU_R6000A: + case CPU_R8000: /* Not shure about that one, play safe */ + cyclecounter_available = 0; + break; + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4200: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R4600: + case CPU_R10000: + case CPU_R4300: + case CPU_R4650: + case CPU_R4700: + case CPU_R5000: + case CPU_R5000A: + case CPU_R4640: + case CPU_NEVADA: + cyclecounter_available = 1; + break; + } } -struct irqaction irq0 = -{timer_interrupt, SA_INTERRUPT, 0, - "timer", NULL, NULL}; - +struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, + "timer", NULL, NULL}; void (*board_time_init) (struct irqaction * irq); void __init time_init(void) { - unsigned int year, mon, day, hour, min, sec; - int i; + unsigned int year, mon, day, hour, min, sec; + int i; - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0; i < 1000000; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - /* - * The DECstation RTC is used as a TOY (Time Of Year). - * The PROM will reset the year to either '70, '71 or '72. - * This hack will only work until Dec 31 2001. - */ - year += 1927; - - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_usec = 0; - - init_cycle_counter(); - - if (cyclecounter_available) { - write_32bit_cp0_register(CP0_COUNT, 0); - do_gettimeoffset = do_fast_gettimeoffset; - irq0.handler = r4k_timer_interrupt; - } - board_time_init(&irq0); + /* The Linux interpretation of the CMOS clock register contents: + * When the Update-In-Progress (UIP) flag goes from 1 to 0, the + * RTC registers show the second which has precisely just started. + * Let's hope other operating systems interpret the RTC the same way. + */ + /* read RTC exactly on falling edge of update flag */ + for (i = 0; i < 1000000; i++) /* may take up to 1 second... */ + if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) + break; + for (i = 0; i < 1000000; i++) /* must try at least 2.228 ms */ + if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + break; + do { /* Isn't this overkill ? UIP above should guarantee consistency */ + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + } while (sec != CMOS_READ(RTC_SECONDS)); + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + /* + * The DECstation RTC is used as a TOY (Time Of Year). + * The PROM will reset the year to either '70, '71 or '72. + * This hack will only work until Dec 31 2001. + */ + year += 1928; + + write_lock_irq(&xtime_lock); + xtime.tv_sec = mktime(year, mon, day, hour, min, sec); + xtime.tv_usec = 0; + write_unlock_irq(&xtime_lock); + + init_cycle_counter(); + + if (cyclecounter_available) { + write_32bit_cp0_register(CP0_COUNT, 0); + do_gettimeoffset = do_fast_gettimeoffset; + irq0.handler = r4k_timer_interrupt; + } + board_time_init(&irq0); } diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/defconfig linux/arch/mips/defconfig --- v2.4.0-test3/linux/arch/mips/defconfig Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/defconfig Tue Jul 11 11:14:42 2000 @@ -16,6 +16,7 @@ # CONFIG_COBALT_MICRO_SERVER is not set # CONFIG_DECSTATION is not set # CONFIG_DDB5074 is not set +# CONFIG_ORION is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_OLIVETTI_M700 is not set CONFIG_SGI_IP22=y @@ -110,12 +111,8 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -# CONFIG_SKB_LARGE is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/defconfig-cobalt linux/arch/mips/defconfig-cobalt --- v2.4.0-test3/linux/arch/mips/defconfig-cobalt Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/defconfig-cobalt Tue Jul 11 11:14:42 2000 @@ -17,6 +17,7 @@ CONFIG_COBALT_28=y # CONFIG_DECSTATION is not set # CONFIG_DDB5074 is not set +# CONFIG_ORION is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set @@ -114,12 +115,8 @@ # CONFIG_IP_PIMSM_V1 is not set # CONFIG_IP_PIMSM_V2 is not set CONFIG_IP_ALIAS=y +# CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/defconfig-decstation linux/arch/mips/defconfig-decstation --- v2.4.0-test3/linux/arch/mips/defconfig-decstation Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/defconfig-decstation Tue Jul 11 11:14:42 2000 @@ -16,6 +16,7 @@ # CONFIG_COBALT_MICRO_SERVER is not set CONFIG_DECSTATION=y # CONFIG_DDB5074 is not set +# CONFIG_ORION is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set @@ -106,12 +107,8 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -# CONFIG_SKB_LARGE is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/defconfig-ip22 linux/arch/mips/defconfig-ip22 --- v2.4.0-test3/linux/arch/mips/defconfig-ip22 Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/defconfig-ip22 Tue Jul 11 11:14:42 2000 @@ -16,6 +16,7 @@ # CONFIG_COBALT_MICRO_SERVER is not set # CONFIG_DECSTATION is not set # CONFIG_DDB5074 is not set +# CONFIG_ORION is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_OLIVETTI_M700 is not set CONFIG_SGI_IP22=y @@ -110,12 +111,8 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -# CONFIG_SKB_LARGE is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/defconfig-orion linux/arch/mips/defconfig-orion --- v2.4.0-test3/linux/arch/mips/defconfig-orion Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/defconfig-orion Tue Jul 11 11:14:42 2000 @@ -0,0 +1,281 @@ +# +# Automatically generated make config: don't edit +# + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_ALGOR_P4032 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_COBALT_MICRO_SERVER is not set +# CONFIG_DECSTATION is not set +# CONFIG_DDB5074 is not set +CONFIG_ORION=y +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SBUS is not set +# CONFIG_ISA is not set +# CONFIG_PCI is not set + +# +# CPU selection +# +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +CONFIG_CPU_R5000=y +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_WB is not set + +# +# General setup +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_KCORE_ELF=y +CONFIG_ELF_KERNEL=y +# CONFIG_BINFMT_IRIX is not set +# CONFIG_FORWARD_KEYBOARD is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_NET=y +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_SYSCTL is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_MODULES is not set +# CONFIG_PCMCIA is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +# CONFIG_UNIX is not set +# CONFIG_INET is not set +# CONFIG_ATM is not set + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_ECONET_AUNUDP is not set +# CONFIG_ECONET_NATIVE is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +# CONFIG_NETDEVICES is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL is not set +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set + +# +# Video For Linux +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_AGP is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set +# CONFIG_SMB_FS is not set +# CONFIG_NCPFS_NLS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_MAGIC_SYSRQ is not set diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/defconfig-rm200 linux/arch/mips/defconfig-rm200 --- v2.4.0-test3/linux/arch/mips/defconfig-rm200 Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/defconfig-rm200 Tue Jul 11 11:14:42 2000 @@ -16,6 +16,7 @@ # CONFIG_COBALT_MICRO_SERVER is not set # CONFIG_DECSTATION is not set # CONFIG_DDB5074 is not set +# CONFIG_ORION is not set # CONFIG_MIPS_MAGNUM_4000 is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set @@ -112,12 +113,8 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -# CONFIG_SKB_LARGE is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile --- v2.4.0-test3/linux/arch/mips/kernel/Makefile Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/kernel/Makefile Tue Jul 11 11:14:42 2000 @@ -39,7 +39,9 @@ ifndef CONFIG_BAGET_MIPS O_OBJS += time.o ifndef CONFIG_SGI_IP22 - OX_OBJS += irq.o + ifndef CONFIG_ORION + OX_OBJS += irq.o + endif endif endif endif diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/kernel/irixelf.c linux/arch/mips/kernel/irixelf.c --- v2.4.0-test3/linux/arch/mips/kernel/irixelf.c Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/kernel/irixelf.c Tue Jul 11 15:43:45 2000 @@ -255,7 +255,7 @@ /* First of all, some simple consistency checks */ if ((interp_elf_ex->e_type != ET_EXEC && interp_elf_ex->e_type != ET_DYN) || - !elf_check_arch(interp_elf_ex->e_machine) || + !irix_elf_check_arch(interp_elf_ex) || !interpreter->f_op->mmap) { printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type); return 0xffffffff; @@ -395,7 +395,7 @@ /* First of all, some simple consistency checks */ if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || - !elf_check_arch(ehp->e_machine) || !bprm->file->f_op->mmap) { + !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) { return -ENOEXEC; } @@ -810,7 +810,7 @@ /* First of all, some simple consistency checks. */ if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || - !elf_check_arch(elf_ex.e_machine) || !file->f_op->mmap) + !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap) return -ENOEXEC; /* Now read in all of the header information. */ @@ -1156,7 +1156,7 @@ psinfo.pr_state = i; psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; psinfo.pr_zomb = psinfo.pr_sname == 'Z'; - psinfo.pr_nice = current->priority-15; + psinfo.pr_nice = current->nice; psinfo.pr_flag = current->flags; psinfo.pr_uid = current->uid; psinfo.pr_gid = current->gid; diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c --- v2.4.0-test3/linux/arch/mips/kernel/irq.c Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/kernel/irq.c Tue Jul 11 11:18:53 2000 @@ -8,6 +8,7 @@ * Copyright (C) 1992 Linus Torvalds * Copyright (C) 1994 - 2000 Ralf Baechle */ +#include #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/kernel/mips_ksyms.c linux/arch/mips/kernel/mips_ksyms.c --- v2.4.0-test3/linux/arch/mips/kernel/mips_ksyms.c Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/kernel/mips_ksyms.c Wed Jul 12 15:14:41 2000 @@ -49,6 +49,7 @@ EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memmove); +EXPORT_SYMBOL(simple_strtol); EXPORT_SYMBOL_NOVERS(strcat); EXPORT_SYMBOL_NOVERS(strchr); EXPORT_SYMBOL_NOVERS(strlen); diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c --- v2.4.0-test3/linux/arch/mips/kernel/setup.c Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/kernel/setup.c Tue Jul 11 11:14:48 2000 @@ -1,5 +1,4 @@ -/* $Id: setup.c,v 1.28 2000/03/13 22:21:44 harald Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -25,6 +24,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_RAM #include #endif @@ -201,6 +201,9 @@ case PRID_IMP_R10000: mips_cputype = CPU_R10000; break; + case PRID_IMP_RM7000: + mips_cputype = CPU_R5000; + break; default: mips_cputype = CPU_UNKNOWN; } @@ -250,10 +253,6 @@ void __init setup_arch(char **cmdline_p) { -#ifdef CONFIG_BLK_DEV_INITRD - unsigned long tmp; - unsigned long *initrd_header; -#endif void baget_setup(void); void cobalt_setup(void); void decstation_setup(void); @@ -262,6 +261,7 @@ void sni_rm200_pci_setup(void); void sgi_setup(void); void ddb_setup(void); + void orion_setup(void); /* Save defaults for configuration-dependent routines. */ irq_setup = default_irq_setup; @@ -316,6 +316,11 @@ #ifdef CONFIG_DDB5074 case MACH_GROUP_NEC_DDB: ddb_setup(); + break; +#endif +#ifdef CONFIG_ORION + case MACH_GROUP_ORION: + orion_setup(); break; #endif default: diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c --- v2.4.0-test3/linux/arch/mips/kernel/time.c Mon Jul 10 16:47:19 2000 +++ linux/arch/mips/kernel/time.c Tue Jul 11 11:14:48 2000 @@ -25,7 +25,7 @@ #include #include -extern volatile unsigned long lost_ticks; +extern volatile unsigned long wall_jiffies; unsigned long r4k_interval = 0; extern rwlock_t xtime_lock; @@ -226,10 +226,10 @@ tv->tv_usec += do_gettimeoffset(); /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. + * xtime is atomically updated in timer_bh. jiffies - wall_jiffies + * is nonzero if the timer bottom half hasnt executed yet. */ - if (lost_ticks) + if (jiffies - wall_jiffies) tv->tv_usec += USECS_PER_JIFFY; read_unlock_irqrestore (&xtime_lock, flags); diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/ld.script.big linux/arch/mips/ld.script.big --- v2.4.0-test3/linux/arch/mips/ld.script.big Sat Feb 26 22:31:40 2000 +++ linux/arch/mips/ld.script.big Wed Jul 12 15:14:41 2000 @@ -91,6 +91,15 @@ _end = . ; PROVIDE (end = .); } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + /* These are needed for ELF backends which have not yet been converted to the new style linker. */ .stab 0 : { *(.stab) } diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/ld.script.little linux/arch/mips/ld.script.little --- v2.4.0-test3/linux/arch/mips/ld.script.little Sat Feb 26 22:31:40 2000 +++ linux/arch/mips/ld.script.little Wed Jul 12 15:14:41 2000 @@ -91,6 +91,15 @@ _end = . ; PROVIDE (end = .); } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + /* These are needed for ELF backends which have not yet been converted to the new style linker. */ .stab 0 : { *(.stab) } diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/Makefile linux/arch/mips/orion/Makefile --- v2.4.0-test3/linux/arch/mips/orion/Makefile Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/Makefile Tue Jul 11 11:14:48 2000 @@ -0,0 +1,48 @@ +# +# 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. +# +# +# Produce a bootimage for the IPSX +# Copyright (C) 2000 Cort Dougan +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +OBJS = promcon.o char.o serial.8530.o orion.hw.init.o setup.o irq.o int-handler.o + +all: orionkern.a + +orionkern.a: $(OBJS) initrd.o #no_initrd.o + $(AR) rcs orionkern.a $(OBJS) initrd.o #no_initrd.o + sync + +initrd.c: piggyback ramdisk.image.gz + ./piggyback initrd < ramdisk.image.gz > initrd.c + +piggyback: piggyback.c + $(HOSTCC) $(HOSTCFLAGS) -o piggyback piggyback.c + +orionboot: orion.ctl + +patchapp: patchapp.c + $(HOSTCC) -o $@ $^ + +orion.ctl: patchapp ../../../vmlinux + $(OBJCOPY) -Obinary ../../../vmlinux orion.nosym + ./patchapp orion.nosym orion + cp -f orion.bin orion.ctl + +# Don't build dependencies, this may die if $(CC) isn't gcc +dep: + +clean: + rm -f patchapp orion.bin orion.nosym orion.ctl initrd.c + +dummy: + +include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/int-handler.S linux/arch/mips/orion/int-handler.S --- v2.4.0-test3/linux/arch/mips/orion/int-handler.S Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/int-handler.S Tue Jul 11 11:14:48 2000 @@ -0,0 +1,53 @@ +#include +#include +#include +#include + + .text + .set mips1 + .set reorder + .set macro + .set noat + .align 5 + +NESTED(orionIRQ, PT_SIZE, sp) + SAVE_ALL + CLI # Important: mark KERNEL mode ! + /* + * Get pending interrupts + */ + mfc0 t0,CP0_CAUSE # get pending interrupts + mfc0 t1,CP0_STATUS # get enabled interrupts + and t0,t1 # isolate allowed ones + andi t0,0xff00 # isolate pending bits + sll t0,16 # shift the pending bits down + beqz t0,3f # no pending intrs, then spurious + nop # delay slot + + /* + * Find irq with highest priority + * FIXME: This is slow - use binary search + */ + la a0,7 +1: bltz t0,2f # found pending irq + subu a0,1 + sll t0,1 + b 1b + nop # delay slot + +call_do_IRQ: +2: move a1,sp + jal do_IRQ + nop # delay slot + + mfc0 t0,CP0_STATUS # disable interrupts + ori t0,1 + xori t0,1 + mtc0 t0,CP0_STATUS + + la a1, ret_from_irq + jr a1 + +3: j spurious_interrupt +END(orionIRQ) + diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/irq.c linux/arch/mips/orion/irq.c --- v2.4.0-test3/linux/arch/mips/orion/irq.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/irq.c Tue Jul 11 11:14:48 2000 @@ -0,0 +1,284 @@ +/* + * Code to handle irqs on Orion boards + * -- Cort + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +void (*board_time_init)(struct irqaction *irq); +extern asmlinkage void orionIRQ(void); +irq_cpustat_t irq_stat [NR_CPUS]; +unsigned int local_bh_count[NR_CPUS]; +unsigned int local_irq_count[NR_CPUS]; +unsigned long spurious_count = 0; +irq_desc_t irq_desc[NR_IRQS]; + +static void galileo_ack(unsigned int irq_nr) +{ + *((unsigned long *) (((unsigned)( 0x14000000 )|0xA0000000) + 0xC18) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ; +} + +struct hw_interrupt_type galileo_pic = { + " Galileo ", + NULL, + NULL, + NULL, /* unmask_irq */ + NULL, /* mask_irq */ + galileo_ack, /* mask_and_ack */ + 0 +}; + +/* Function for careful CP0 interrupt mask access */ +static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) +{ + unsigned long status = read_32bit_cp0_register(CP0_STATUS); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_32bit_cp0_register(CP0_STATUS, status); +} + +static inline void mask_irq(unsigned int irq_nr) +{ + modify_cp0_intmask(irq_nr, 0); +} + +static inline void unmask_irq(unsigned int irq_nr) +{ + modify_cp0_intmask(0, irq_nr); +} + +void disable_irq(unsigned int irq_nr) +{ + unsigned long flags; + + save_and_cli(flags); + mask_irq(irq_nr); + restore_flags(flags); +} + +void enable_irq(unsigned int irq_nr) +{ + unsigned long flags; + + save_and_cli(flags); + unmask_irq(irq_nr); + restore_flags(flags); +} + +/*static struct irqaction *irq_action[NR_IRQS] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +*/ +void __init orion_time_init(struct irqaction *irq) +{ + __u32 timer_count; + + irq_desc[2].handler = &galileo_pic; + irq_desc[2].action = irq; + + /* This code was provided by the CoSine guys and despite its + * appearance init's the timer. + * -- Cort + */ + *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x864) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ; + + *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x850) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ; + + timer_count = 300000000/100; + + *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x850) ) = (((( timer_count )&0xff)<<24)+ ((( timer_count )&0xff00)<<8)+ ((( timer_count )&0xff0000)>>8)+ ((( timer_count )&0xff000000)>>24)) ; + + *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0xC1C) ) = (((( 0x100 )&0xff)<<24)+ ((( 0x100 )&0xff00)<<8)+ ((( 0x100 )&0xff0000)>>8)+ ((( 0x100 )&0xff000000)>>24)) ; + + *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0x864) ) = (((( 0x03 )&0xff)<<24)+ ((( 0x03 )&0xff00)<<8)+ ((( 0x03 )&0xff0000)>>8)+ ((( 0x03 )&0xff000000)>>24)) ; + + *((__u32 *) (((unsigned)( 0x14000000 )|0xA0000000) + 0xC18) ) = (((( 0 )&0xff)<<24)+ ((( 0 )&0xff00)<<8)+ ((( 0 )&0xff0000)>>8)+ ((( 0 )&0xff000000)>>24)) ; +} + +int get_irq_list(char *buf) +{ + int i, len = 0, j; + struct irqaction * action; + + len += sprintf(buf+len, " "); + for (j=0; jhandler ) + continue; + len += sprintf(buf+len, "%3d: ", i); + len += sprintf(buf+len, "%10u ", kstat_irqs(i)); + if ( irq_desc[i].handler ) + len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename ); + else + len += sprintf(buf+len, " None "); + len += sprintf(buf+len, " %s",action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ", %s", action->name); + } + len += sprintf(buf+len, "\n"); + } + len += sprintf(buf+len, "BAD: %10lu\n", spurious_count); + return len; +} + +asmlinkage void do_IRQ(int irq, struct pt_regs * regs) +{ + struct irqaction *action; + int do_random, cpu; + int status; + + cpu = smp_processor_id(); + irq_enter(cpu); + kstat.irqs[cpu][irq]++; + status = 0; + + if (irq_desc[irq].handler->ack) + irq_desc[irq].handler->ack(irq); + + action = irq_desc[irq].action; + if (action && action->handler) + { + if (!(action->flags & SA_INTERRUPT)) + __sti(); + do { + status |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while ( action ); + __cli(); + if (irq_desc[irq].handler) + { + if (irq_desc[irq].handler->end) + irq_desc[irq].handler->end(irq); + else if (irq_desc[irq].handler->enable) + irq_desc[irq].handler->enable(irq); + } + } + + irq_exit(cpu); + + if (softirq_state[cpu].active&softirq_state[cpu].mask) + do_softirq(); + + /* unmasking and bottom half handling is done magically for us. */ +} + +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, const char * devname, void *dev_id) +{ + struct irqaction *old, **p, *action; + unsigned long flags; + + if (irq >= NR_IRQS) + return -EINVAL; + if (!handler) + { + /* Free */ + for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) + { + /* Found it - now free it */ + save_flags(flags); + cli(); + *p = action->next; + restore_flags(flags); + kfree(action); + return 0; + } + return -ENOENT; + } + + action = (struct irqaction *) + kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if (!action) + return -ENOMEM; + + save_flags(flags); + cli(); + + action->handler = handler; + action->flags = irqflags; + action->mask = 0; + action->name = devname; + action->dev_id = dev_id; + action->next = NULL; + enable_irq(irq); + + p = &irq_desc[irq].action; + + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & action->flags & SA_SHIRQ)) + return -EBUSY; + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + } + *p = action; + + restore_flags(flags); + return 0; +} + +void free_irq(unsigned int irq, void *dev_id) +{ + request_irq(irq, NULL, 0, NULL, dev_id); +} + + +unsigned long probe_irq_on (void) +{ + return 0; +} + +int probe_irq_off (unsigned long irqs) +{ + return 0; +} + +int (*irq_cannonicalize)(int irq); + +int orion_irq_cannonicalize(int i) +{ + return i; +} + +void __init init_IRQ(void) +{ + + irq_cannonicalize = orion_irq_cannonicalize; + set_except_vector(0, orionIRQ); +} + +EXPORT_SYMBOL(irq_cannonicalize); + diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/ld.script.orion linux/arch/mips/orion/ld.script.orion --- v2.4.0-test3/linux/arch/mips/orion/ld.script.orion Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/ld.script.orion Tue Jul 11 11:14:48 2000 @@ -0,0 +1,113 @@ +OUTPUT_FORMAT("elf32-bigmips") +OUTPUT_ARCH(mips) +ENTRY(kernel_entry) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0x80100000; + /* app_header is needed for the Orion bootloader -- Cort */ + .app_header : { *(.app_header) } + .init : { *(.init) } =0 + .text : + { + _ftext = . ; + *(.text) + *(.rodata) + *(.rodata1) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } =0 + _etext = .; + PROVIDE (etext = .); + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + /* Startup code */ + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); /* Align double page for init_task_union */ + __init_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + .fini : { *(.fini) } =0 + .reginfo : { *(.reginfo) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. It would + be more correct to do this: + . = .; + The current expression does not correctly handle the case of a + text segment ending precisely at the end of a page; it causes the + data segment to skip a page. The above expression does not have + this problem, but it will currently (2/95) cause BFD to allocate + a single segment, combining both text and data, for this case. + This will prevent the text segment from being shared among + multiple executions of the program; I think that is more + important than losing a page of the virtual address space (note + that no actual memory is lost; the page which is skipped can not + be referenced). */ + . = .; + .data : + { + _fdata = . ; + *(.data) + CONSTRUCTORS + } + .data1 : { *(.data1) } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + .got : { *(.got.plt) *(.got) } + .dynamic : { *(.dynamic) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + + __bss_start = .; + _fbss = .; + .sbss : { *(.sbss) *(.scommon) } + .bss : + { + *(.dynbss) + *(.bss) + *(COMMON) + _end = . ; + PROVIDE (end = .); + } + /* These are needed for ELF backends which have not yet been + converted to the new style linker. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the .debug DWARF section are relative to the beginning of the + section so we begin .debug at 0. It's not clear yet what needs to happen + for the others. */ + .debug 0 : { *(.debug) } + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_sfnames 0 : { *(.debug_sfnames) } + .line 0 : { *(.line) } + /* These must appear regardless of . */ + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +} diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/misc.c linux/arch/mips/orion/misc.c --- v2.4.0-test3/linux/arch/mips/orion/misc.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/misc.c Wed Jul 12 12:48:37 2000 @@ -0,0 +1,100 @@ +/* + * Catch-all for Orion-specify code that doesn't fit easily elsewhere. + * -- Cort + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_BLK_DEV_RAM +#include +#endif +#include +#ifdef CONFIG_RTC +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE] = {0, }; +extern int _end; + +static unsigned char orion_rtc_read_data(unsigned long addr) +{ + return 0; +} + +static void orion_rtc_write_data(unsigned char data, unsigned long addr) +{ +} + +static int orion_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops orion_rtc_ops = { + &orion_rtc_read_data, + &orion_rtc_write_data, + &orion_rtc_bcd_mode +}; + +extern void InitCIB(void); +extern void InitQpic(void); +extern void InitCupid(void); + +void __init orion_setup(void) +{ + InitCIB(); + InitQpic(); + InitCupid(); +} + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) + + + +int orion_sysinit(void) +{ + unsigned long mem_size, free_start, free_end, start_pfn, bootmap_size; + + mips_machgroup = MACH_GROUP_ORION; + /* 64 MB non-upgradable */ + mem_size = 32 << 20; + + free_start = PHYSADDR(PFN_ALIGN(&_end)); + free_end = mem_size; + start_pfn = PFN_UP((unsigned long)&_end); + + /* Register all the contiguous memory with the bootmem allocator + and free it. Be careful about the bootmem freemap. */ + bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT); + + /* Free the entire available memory after the _end symbol. */ + free_start += bootmap_size; + free_bootmem(free_start, free_end-free_start); +} diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/no_initrd.c linux/arch/mips/orion/no_initrd.c --- v2.4.0-test3/linux/arch/mips/orion/no_initrd.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/no_initrd.c Tue Jul 11 11:14:48 2000 @@ -0,0 +1,2 @@ +unsigned long *orion_initrd_start = 0; +unsigned long orion_initrd_size = 0; diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/piggyback.c linux/arch/mips/orion/piggyback.c --- v2.4.0-test3/linux/arch/mips/orion/piggyback.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/piggyback.c Tue Jul 11 11:14:48 2000 @@ -0,0 +1,59 @@ +#include +#include + +extern long ce_exec_config[]; + +int main(int argc, char *argv[]) +{ + int i, cnt, pos, len; + unsigned int cksum, val; + unsigned char *lp; + unsigned char buf[8192]; + if (argc != 2) + { + fprintf(stderr, "usage: %s name out-file\n", + argv[0]); + exit(1); + } + fprintf(stdout, "/*\n"); + fprintf(stdout, "* Miscellaneous data structures:\n"); + fprintf(stdout, "* WARNING - this file is automatically generated!\n"); + fprintf(stdout, "*/\n"); + fprintf(stdout, "\n"); + fprintf(stdout, "unsigned long orion_%s_start[] = {\n", argv[1]); + pos = 0; + cksum = 0; + while ((len = read(0, buf, sizeof(buf))) > 0) + { + cnt = 0; + lp = (unsigned char *)buf; + len = (len + 3) & ~3; /* Round up to longwords */ + for (i = 0; i < len; i += 4) + { + if (cnt == 0) + { + fprintf(stdout, "\t"); + } + fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); + val = *(unsigned long *)lp; + cksum ^= val; + lp += 4; + if (++cnt == 4) + { + cnt = 0; + fprintf(stdout, ", /* %x */\n", pos+i-12); + fflush(stdout); + } else + { + fprintf(stdout, ","); + } + } + pos += len; + } + fprintf(stdout, "0 };\n"); + fprintf(stdout, "unsigned long orion_%s_size = 0x%x;\n", argv[1], pos); + fflush(stdout); + fclose(stdout); + fprintf(stderr, "cksum = %x\n", cksum); + exit(0); +} diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/promcon.c linux/arch/mips/orion/promcon.c --- v2.4.0-test3/linux/arch/mips/orion/promcon.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/promcon.c Tue Jul 11 11:14:48 2000 @@ -0,0 +1,172 @@ +/* + * Wrap-around code for a console using the + * SGI PROM io-routines. + * + * Copyright (c) 1999 Ulf Carlsson + * + * Derived from DECstation promcon.c + * Copyright (c) 1998 Harald Koerfgen + */ + +#include +#include +#include +#include +#include +#include +/* +#include +*/ +extern void prom_printf(char *fmt, ...); +unsigned long splx(unsigned long mask){return 0;} +#if 0 +unsigned long ramsize=0x100000; +unsigned long RamSize(){return ramsize;} +extern void prom_printf(char *fmt, ...); +unsigned long splx(unsigned long mask){return 0;} +long PssSetIntHandler(unsigned long intnum, void *handler){} +long PssEnableInt(unsigned long intnum){} +long PssDisableInt(unsigned long intnum){} +unsigned long t_ident(char name[4], unsigned long node, unsigned long *tid){} +#endif + +extern void SerialPollConout(unsigned char c); +static void prom_console_write(struct console *co, const char *s, + unsigned count) +{ + unsigned i; + + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + if (*s == 10) + SerialPollConout(13); + SerialPollConout(*s++); + } +} +extern int prom_getchar(void); +static int prom_console_wait_key(struct console *co) +{ + return prom_getchar(); +} + +extern void SerialPollInit(void); +extern void SerialSetup(unsigned long baud, unsigned long console, unsigned long host, unsigned long intr_desc); +static int __init prom_console_setup(struct console *co, char *options) +{ + SerialSetup(19200,1,1,3); + SerialPollInit(); + SerialPollOn(); + return 0; +} + +static kdev_t prom_console_device(struct console *c) +{ + return MKDEV(TTY_MAJOR, 64 + c->index); +} + +static struct console sercons = +{ + "ttyS", + prom_console_write, + NULL, + prom_console_device, + prom_console_wait_key, + NULL, + prom_console_setup, + CON_PRINTBUFFER, + -1, + 0, + NULL +}; + +/* + * Register console. + */ + +void serial_console_init(void) +{ + register_console(&sercons); +} + +extern void prom_putchar(int mychar); + +static char ppbuf[1000]; + + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ch, *bptr; + int i; + + va_start(args, fmt); + i = vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while((ch = *(bptr++)) != 0) { + if(ch == '\n') + prom_putchar('\r'); + + prom_putchar(ch); + } + va_end(args); + return; +} + + + +void prom_putchar(int mychar){} +int prom_getchar(void){return 0;} +struct app_header_s { + unsigned long MAGIC_JMP; + unsigned long MAGIC_NOP; + unsigned long header_tag; + unsigned long header_flags; + unsigned long header_length; + unsigned long header_cksum; + + void *load_addr; + void *end_addr; + void *start_addr; + char *app_name_p; + char *version_p; + char *date_p; + char *time_p; + unsigned long type; + unsigned long crc; + unsigned long reserved; +}; +typedef struct app_header_s app_header_t; +char linked_app_name[]="linux"; +char *linked_app_name_p=&linked_app_name[0]; + +char linked_app_ver[]="2.4 -test1"; +char *linked_app_ver_p=&linked_app_ver[0]; + +char linked_app_date[]="today"; +char *linked_app_date_p=&linked_app_date[0]; + +char linked_app_time[]="now"; +char *linked_app_time_p=&linked_app_time[0]; +extern void *__bss_start; +extern void *kernel_entry; + +app_header_t app_header __attribute__ ((section (".app_header"))) = { + (0x10000000 | (((sizeof(app_header_t)>>2)-1) & 0xffff)) , + 0 , + (((( 0x4321 ) & 0xFFFF) << 16) | (( 0x0100 ) & 0xFFFF)) , + 0x80000000 , + sizeof(app_header_t), + 0, + &app_header, + &__bss_start, + &kernel_entry, + linked_app_name, + linked_app_ver, + linked_app_date, + linked_app_time, + 0 +}; diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/orion/setup.c linux/arch/mips/orion/setup.c --- v2.4.0-test3/linux/arch/mips/orion/setup.c Wed Dec 31 16:00:00 1969 +++ linux/arch/mips/orion/setup.c Wed Jul 12 12:48:37 2000 @@ -0,0 +1,125 @@ +/* + * Catch-all for Orion-specific code that doesn't fit easily elsewhere. + * -- Cort + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_BLK_DEV_RAM +#include +#endif +#include +#ifdef CONFIG_RTC +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char arcs_cmdline[CL_SIZE] = { "console=ttyS0,19200" }; +extern int _end; + +static unsigned char orion_rtc_read_data(unsigned long addr) +{ + return 0; +} + +static void orion_rtc_write_data(unsigned char data, unsigned long addr) +{ +} + +static int orion_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops orion_rtc_ops = { + &orion_rtc_read_data, + &orion_rtc_write_data, + &orion_rtc_bcd_mode +}; + +extern void InitCIB(void); +extern void InitQpic(void); +extern void InitCupid(void); + +void __init orion_setup(void) +{ + extern void (*board_time_init)(struct irqaction *irq); + void orion_time_init(struct irqaction *); + + rtc_ops = &orion_rtc_ops; + board_time_init = orion_time_init; + mips_io_port_base = GT64120_BASE; + + InitCIB(); + InitQpic(); + InitCupid(); +} + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) + +unsigned long mem_size; +int __init prom_init(int a, char **b, char **c, int *d) +{ + unsigned long free_start, free_end, start_pfn, bootmap_size; + extern unsigned long orion_initrd_start[], orion_initrd_size; + + mips_machgroup = MACH_GROUP_ORION; + /* 64 MB non-upgradable */ + mem_size = 64 << 20; + + free_start = PHYSADDR(PFN_ALIGN(&_end)); + free_end = mem_size; + start_pfn = PFN_UP((unsigned long)&_end); + + /* Register all the contiguous memory with the bootmem allocator + and free it. Be careful about the bootmem freemap. */ + bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT); + + /* Free the entire available memory after the _end symbol. */ + free_start += bootmap_size; + free_bootmem(free_start, free_end-free_start); + + initrd_start = (ulong)orion_initrd_start; + initrd_end = (ulong)orion_initrd_start + (ulong)orion_initrd_size; + initrd_below_start_ok = 1; + + return 0; +} + +void prom_free_prom_memory (void) +{ +} + +int page_is_ram(unsigned long pagenr) +{ + if ( pagenr < (mem_size >> PAGE_SHIFT) ) + return 1; + return 0; +} diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips/tools/offset.c linux/arch/mips/tools/offset.c --- v2.4.0-test3/linux/arch/mips/tools/offset.c Tue May 23 15:31:33 2000 +++ linux/arch/mips/tools/offset.c Tue Jul 11 11:14:48 2000 @@ -81,7 +81,7 @@ offset("#define TASK_SIGPENDING ", struct task_struct, sigpending); offset("#define TASK_NEED_RESCHED ", struct task_struct, need_resched); offset("#define TASK_COUNTER ", struct task_struct, counter); - offset("#define TASK_PRIORITY ", struct task_struct, priority); + offset("#define TASK_NICE ", struct task_struct, nice); offset("#define TASK_MM ", struct task_struct, mm); size("#define TASK_STRUCT_SIZE ", struct task_struct); linefeed; diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/config.in linux/arch/mips64/config.in --- v2.4.0-test3/linux/arch/mips64/config.in Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/config.in Wed Jul 12 15:12:11 2000 @@ -11,6 +11,15 @@ endmenu mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'Machine selection' bool 'Support for SGI IP22' CONFIG_SGI_IP22 bool 'Support for SGI IP27' CONFIG_SGI_IP27 @@ -108,14 +117,6 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC endmenu - -mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD -fi source drivers/pci/Config.in diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/defconfig linux/arch/mips64/defconfig --- v2.4.0-test3/linux/arch/mips64/defconfig Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/defconfig Tue Jul 11 11:14:48 2000 @@ -102,12 +102,8 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # # diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/defconfig-ip22 linux/arch/mips64/defconfig-ip22 --- v2.4.0-test3/linux/arch/mips64/defconfig-ip22 Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/defconfig-ip22 Tue Jul 11 11:14:48 2000 @@ -92,12 +92,8 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # # diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/defconfig-ip27 linux/arch/mips64/defconfig-ip27 --- v2.4.0-test3/linux/arch/mips64/defconfig-ip27 Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/defconfig-ip27 Tue Jul 11 11:14:48 2000 @@ -102,12 +102,8 @@ # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_IP_ALIAS is not set +# CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set - -# -# (it is safe to leave these untouched) -# -CONFIG_SKB_LARGE=y # # diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/kernel/binfmt_elf32.c linux/arch/mips64/kernel/binfmt_elf32.c --- v2.4.0-test3/linux/arch/mips64/kernel/binfmt_elf32.c Tue May 23 15:31:33 2000 +++ linux/arch/mips64/kernel/binfmt_elf32.c Tue Jul 11 19:02:37 2000 @@ -28,7 +28,7 @@ typedef double elf_fpreg_t; typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; -#define elf_check_arch(x) ((x) == EM_MIPS || (x) == EM_MIPS_RS4_BE) +#define elf_check_arch(x) ((x)->e_machine == EM_MIPS || (x)->e_machine == EM_MIPS_RS4_BE) #define TASK32_SIZE 0x80000000UL #undef ELF_ET_DYN_BASE diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/kernel/head.S linux/arch/mips64/kernel/head.S --- v2.4.0-test3/linux/arch/mips64/kernel/head.S Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/kernel/head.S Wed Jul 12 15:14:41 2000 @@ -100,10 +100,6 @@ ARC64_TWIDDLE_PC - /* Note that all firmware passed argument registers still - have their values. */ - jal prom_init # initialize firmware - CLI # disable interrupts mfc0 t0, CP0_STATUS @@ -127,6 +123,10 @@ dsrl32 t0, t0, 0 mtc0 t0, CP0_WATCHHI #endif + /* Note that all firmware passed argument registers still + have their values. */ + jal prom_init # initialize firmware + jal start_kernel 1: b 1b # just in case ... END(kernel_entry) diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/kernel/mips64_ksyms.c linux/arch/mips64/kernel/mips64_ksyms.c --- v2.4.0-test3/linux/arch/mips64/kernel/mips64_ksyms.c Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/kernel/mips64_ksyms.c Wed Jul 12 15:14:41 2000 @@ -46,6 +46,7 @@ EXPORT_SYMBOL_NOVERS(memset); EXPORT_SYMBOL_NOVERS(memcpy); EXPORT_SYMBOL_NOVERS(memmove); +EXPORT_SYMBOL(simple_strtol); EXPORT_SYMBOL_NOVERS(strcat); EXPORT_SYMBOL_NOVERS(strchr); EXPORT_SYMBOL_NOVERS(strlen); diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/kernel/process.c linux/arch/mips64/kernel/process.c --- v2.4.0-test3/linux/arch/mips64/kernel/process.c Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/kernel/process.c Wed Jul 12 15:14:41 2000 @@ -1,13 +1,11 @@ -/* $Id: process.c,v 1.4 2000/01/16 01:34:01 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 - 1999 by Ralf Baechle and others. - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others. + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ -#include #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/kernel/r4k_tlb.S linux/arch/mips64/kernel/r4k_tlb.S --- v2.4.0-test3/linux/arch/mips64/kernel/r4k_tlb.S Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/kernel/r4k_tlb.S Wed Jul 12 15:14:41 2000 @@ -1,5 +1,4 @@ -/* $Id: r4k_tlb.S,v 1.3 2000/06/30 00:48:29 kanoj Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -7,6 +6,7 @@ * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) */ +#include #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/kernel/r4k_tlb_glue.S linux/arch/mips64/kernel/r4k_tlb_glue.S --- v2.4.0-test3/linux/arch/mips64/kernel/r4k_tlb_glue.S Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/kernel/r4k_tlb_glue.S Tue Jul 11 11:14:48 2000 @@ -33,14 +33,13 @@ ld $2, PT_R2(sp) #endif dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible li a1, \writebit sd a2, PT_BVADDR(sp) move a0, sp - __BUILD_\interruptible jal do_page_fault + j ret_from_sys_call END(__\name) - RESTORE_ALL - eret .endm tlb_handler xtlb_mod sti 1 diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/kernel/signal32.c linux/arch/mips64/kernel/signal32.c --- v2.4.0-test3/linux/arch/mips64/kernel/signal32.c Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/kernel/signal32.c Wed Jul 12 15:14:41 2000 @@ -4,10 +4,9 @@ * for more details. * * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1994 - 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1994 - 2000 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ -#include #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/ld.script.elf32 linux/arch/mips64/ld.script.elf32 --- v2.4.0-test3/linux/arch/mips64/ld.script.elf32 Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/ld.script.elf32 Wed Jul 12 15:14:41 2000 @@ -83,6 +83,15 @@ *(COMMON) _end = . ; } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + /* These are needed for ELF backends which have not yet been converted to the new style linker. */ .stab 0 : { *(.stab) } diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/ld.script.elf64 linux/arch/mips64/ld.script.elf64 --- v2.4.0-test3/linux/arch/mips64/ld.script.elf64 Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/ld.script.elf64 Wed Jul 12 15:14:41 2000 @@ -92,6 +92,15 @@ *(COMMON) _end = . ; } + + /* Sections to be discarded */ + /DISCARD/ : + { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + /* These are needed for ELF backends which have not yet been converted to the new style linker. */ .stab 0 : { *(.stab) } diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-init.c linux/arch/mips64/sgi-ip27/ip27-init.c --- v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-init.c Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/sgi-ip27/ip27-init.c Tue Jul 11 11:18:53 2000 @@ -1,3 +1,4 @@ +#include #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-irq.c linux/arch/mips64/sgi-ip27/ip27-irq.c --- v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-irq.c Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/sgi-ip27/ip27-irq.c Tue Jul 11 11:18:53 2000 @@ -4,8 +4,8 @@ * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ +#include #include - #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-rtc.c linux/arch/mips64/sgi-ip27/ip27-rtc.c --- v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-rtc.c Fri Jun 23 21:55:07 2000 +++ linux/arch/mips64/sgi-ip27/ip27-rtc.c Wed Jul 12 21:58:42 2000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -179,7 +180,9 @@ * in use, and clear the data. */ + lock_kernel(); rtc_status &= ~RTC_IS_OPEN; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-setup.c linux/arch/mips64/sgi-ip27/ip27-setup.c --- v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-setup.c Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/sgi-ip27/ip27-setup.c Thu Jul 13 09:39:49 2000 @@ -26,7 +26,6 @@ #include #include #include -#include /* Check against user dumbness. */ #ifdef CONFIG_VT diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-timer.c linux/arch/mips64/sgi-ip27/ip27-timer.c --- v2.4.0-test3/linux/arch/mips64/sgi-ip27/ip27-timer.c Mon Jul 10 16:47:20 2000 +++ linux/arch/mips64/sgi-ip27/ip27-timer.c Tue Jul 11 11:18:53 2000 @@ -2,6 +2,7 @@ * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) * Copytight (C) 1999, 2000 Silicon Graphics, Inc. */ +#include #include #include #include @@ -38,7 +39,7 @@ static long last_rtc_update = 0; /* Last time the rtc clock got updated */ extern rwlock_t xtime_lock; -extern volatile unsigned long lost_ticks; +extern volatile unsigned long wall_jiffies; static int set_rtc_mmss(unsigned long nowtime) @@ -175,7 +176,7 @@ read_lock_irqsave(&xtime_lock, flags); usec = do_gettimeoffset(); { - unsigned long lost = lost_ticks; + unsigned long lost = jiffies - wall_jiffies; if (lost) usec += lost * (1000000 / HZ); } @@ -196,7 +197,7 @@ { write_lock_irq(&xtime_lock); tv->tv_usec -= do_gettimeoffset(); - tv->tv_usec -= lost_ticks * (1000000 / HZ); + tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); while (tv->tv_usec < 0) { tv->tv_usec += 1000000; diff -u --recursive --new-file v2.4.0-test3/linux/arch/mips64/tools/offset.c linux/arch/mips64/tools/offset.c --- v2.4.0-test3/linux/arch/mips64/tools/offset.c Tue May 23 15:31:33 2000 +++ linux/arch/mips64/tools/offset.c Tue Jul 11 11:14:48 2000 @@ -1,10 +1,9 @@ -/* $Id: offset.c,v 1.4 1999/12/04 03:59:01 ralf Exp $ - * +/* * offset.c: Calculate pt_regs and task_struct offsets. * * Copyright (C) 1996 David S. Miller - * Copyright (C) 1997, 1998, 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include #include @@ -80,7 +79,7 @@ offset("#define TASK_SIGPENDING ", struct task_struct, sigpending); offset("#define TASK_NEED_RESCHED ", struct task_struct, need_resched); offset("#define TASK_COUNTER ", struct task_struct, counter); - offset("#define TASK_PRIORITY ", struct task_struct, priority); + offset("#define TASK_NICE ", struct task_struct, nice); offset("#define TASK_MM ", struct task_struct, mm); offset("#define TASK_PROCESSOR ", struct task_struct, processor); size("#define TASK_STRUCT_SIZE ", struct task_struct); diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/8xx_io/Config.in linux/arch/ppc/8xx_io/Config.in --- v2.4.0-test3/linux/arch/ppc/8xx_io/Config.in Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/8xx_io/Config.in Thu Jul 13 09:42:50 2000 @@ -13,8 +13,16 @@ fi fi bool '860T FEC Ethernet' CONFIG_FEC_ENET - bool 'Use SMC2 for UART' CONFIG_8xxSMC2 - bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC + bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS +fi +bool 'Use SMC2 for UART' CONFIG_8xxSMC2 +if [ "$CONFIG_8xxSMC2" = "y" ]; then + bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_8xx_ALTSMC2 +fi +bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC + +if [ "$CONFIG_TQM860" = "y" -o "$CONFIG_TQM860L" = "y" -o "$CONFIG_TQM8xxL" = "y" ]; then + bool 'Use SMC2 for Console' TQM_SMC2_CONSOLE fi # This doesn't really belong here, but it is convenient to ask diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/8xx_io/commproc.h linux/arch/ppc/8xx_io/commproc.h --- v2.4.0-test3/linux/arch/ppc/8xx_io/commproc.h Thu Nov 18 20:25:37 1999 +++ linux/arch/ppc/8xx_io/commproc.h Thu Jul 13 09:42:50 2000 @@ -191,7 +191,9 @@ /* SMC Event and Mask register. */ -#define SMCM_TXE ((unsigned char)0x10) +#define SMCM_BRKE ((unsigned char)0x40) /* When in UART Mode */ +#define SMCM_BRK ((unsigned char)0x10) /* When in UART Mode */ +#define SMCM_TXE ((unsigned char)0x10) /* When in Transparent Mode */ #define SMCM_BSY ((unsigned char)0x04) #define SMCM_TX ((unsigned char)0x02) #define SMCM_RX ((unsigned char)0x01) @@ -456,6 +458,81 @@ #define SICR_ENET_MASK ((uint)0x000000ff) #define SICR_ENET_CLKRT ((uint)0x0000003d) #endif + +#if (defined(CONFIG_TQM860) || defined(CONFIG_TQM860L)) +/* + * TQM860 and TQM860L Configuration: + * + * Signal PAR DIR ODR DAT Function + * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet + * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet + * Port A, 14 1 0 - - TXD for Ethernet (SCC1) + * Port A, 15 1 0 - - RXD for Ethernet (SCC1) + * Port C, 7 0 0 0 - -> ETH-LOOP + * Port C, 10 0 0 1 - CD for Ethernet (SCC1) + * Port C, 11 0 0 1 - CTS for Ethernet (SCC1) + * Port C, 15 * * 0 - TENA/RTS for Ethernet + */ + +#define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */ +#define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ + +#define PC_ENET_TENA ((ushort)0x0001) /* PC 15 */ +#define PC_ENET_CLSN ((ushort)0x0010) /* PC 11 */ +#define PC_ENET_RENA ((ushort)0x0020) /* PC 10 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x00000026) + +#endif /* CONFIG_TQM860, TQM860L */ + +#ifdef CONFIG_TQM8xxL +/* + * TQM8xxL Configuration (except TQM860L): + * + * Signal PAR DIR ODR DAT Function + * Port A, 5 1 0 - - TCLK (CLK3) for Ethernet + * Port A, 7 1 0 - - RCLK (CLK1) for Ethernet + * Port A, 12 1 0 - - TXD for Ethernet (SCC2) + * Port A, 13 1 0 - - RXD for Ethernet (SCC2) + * Port B, 18 1 1 - - TENA/RTS for Ethernet on STK8xx + * Port C, 7 0 0 0 - -> ETH-LOOP + * Port C, 8 0 0 1 - CD for Ethernet (SCC2) + * Port C, 9 0 0 1 - CTS for Ethernet (SCC2) + * Port C, 14 * * 0 - TENA/RTS for Ethernet on FPS850 + * + * Note: Using PC14 as RTS2 (TENA) does not work on the TQM850L when + * used with the starter-kit mainboard; we *must* use PB18 instead. + * For the FPS850 system, we *must* use PC14 :-( + */ + +#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */ +#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */ +#define PA_ENET_RCLK ((ushort)0x0100) /* PA 7 */ +#define PA_ENET_TCLK ((ushort)0x0400) /* PA 5 */ + +#ifndef CONFIG_FPS850 /* not valid on FPS board */ +#define PB_ENET_TENA ((uint)0x00002000) +#endif /* !CONFIG_FPS850 */ + +#ifdef CONFIG_FPS850 /* FPS uses default configuration */ +#define PC_ENET_TENA ((ushort)0x0002) /* PC 14 */ +#endif /* CONFIG_FPS850 */ +#define PC_ENET_CLSN ((ushort)0x0040) /* PC 9 */ +#define PC_ENET_RENA ((ushort)0x0080) /* PC 8 */ + +/* Control bits in the SICR to route TCLK (CLK3) and RCLK (CLK1) to + * SCC2. Also, make sure GR2 (bit 16) and SC2 (bit 17) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002600) + +#endif /* CONFIG_TQM8xxL */ /* SCC Event register as used by Ethernet. */ diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/8xx_io/enet.c linux/arch/ppc/8xx_io/enet.c --- v2.4.0-test3/linux/arch/ppc/8xx_io/enet.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/8xx_io/enet.c Thu Jul 13 09:42:50 2000 @@ -73,40 +73,14 @@ * finished otherwise it sets the 'lp->tx_full' flag. * * The MBX has a control register external to the MPC8xx that has some - * control of the Ethernet interface. Control Register 1 has the - * following format: - * bit 0 - Set to enable Ethernet transceiver - * bit 1 - Set to enable Ethernet internal loopback - * bit 2 - Set to auto select AUI or TP port - * bit 3 - if bit 2 is 0, set to select TP port - * bit 4 - Set to disable full duplex (loopback) - * bit 5 - Set to disable XCVR collision test - * bit 6, 7 - Used for RS-232 control. + * control of the Ethernet interface. Information is in the manual for + * your board. * - * EPPC-Bug sets this register to 0x98 for normal Ethernet operation, - * so we should not have to touch it. + * The RPX boards have an external control/status register. Consult the + * programming documents for details unique to your board. * - * The following I/O is used by the MBX implementation of the MPC8xx to - * the MC68160 transceiver. It DOES NOT exactly follow the cookbook - * example from the MPC860 manual. - * Port A, 15 - SCC1 Ethernet Rx - * Port A, 14 - SCC1 Ethernet Tx - * Port A, 6 (CLK2) - SCC1 Ethernet Tx Clk - * Port A, 4 (CLK4) - SCC1 Ethernet Rx Clk - * Port C, 15 - SCC1 Ethernet Tx Enable - * Port C, 11 - SCC1 Ethernet Collision - * Port C, 10 - SCC1 Ethernet Rx Enable - * - * The RPX-Lite (that I had :-), was the MPC850SAR. It has a control - * register to enable Ethernet functions in the 68160, and the Ethernet - * was controlled by SCC2. So, the pin I/O was like this: - * Port A, 13 - SCC2 Ethernet Rx - * Port A, 12 - SCC2 Ethernet Tx - * Port A, 6 (CLK2) - Ethernet Tx Clk - * Port A, 4 (CLK4) - Ethernet Rx Clk - * Port B, 18 (RTS2) - Ethernet Tx Enable - * Port C, 8 (CD2) - Ethernet Rx Enable - * Port C, 9 (CTS2) - SCC Ethernet Collision + * For the TQM8xx(L) modules, there is no control register interface. + * All functions are directly controlled using I/O pins. See commproc.h. */ /* The transmitter timeout @@ -119,12 +93,21 @@ * We don't need to allocate pages for the transmitter. We just use * the skbuffer directly. */ +#ifdef CONFIG_ENET_BIG_BUFFERS +#define CPM_ENET_RX_PAGES 32 +#define CPM_ENET_RX_FRSIZE 2048 +#define CPM_ENET_RX_FRPPG (PAGE_SIZE / CPM_ENET_RX_FRSIZE) +#define RX_RING_SIZE (CPM_ENET_RX_FRPPG * CPM_ENET_RX_PAGES) +#define TX_RING_SIZE 64 /* Must be power of two */ +#define TX_RING_MOD_MASK 63 /* for this to work */ +#else #define CPM_ENET_RX_PAGES 4 #define CPM_ENET_RX_FRSIZE 2048 #define CPM_ENET_RX_FRPPG (PAGE_SIZE / CPM_ENET_RX_FRSIZE) #define RX_RING_SIZE (CPM_ENET_RX_FRPPG * CPM_ENET_RX_PAGES) #define TX_RING_SIZE 8 /* Must be power of two */ #define TX_RING_MOD_MASK 7 /* for this to work */ +#endif /* The CPM stores dest/src/type, data, and checksum for receive packets. */ @@ -896,11 +879,16 @@ /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ -#ifdef CONFIG_MBX +#if (defined(CONFIG_MBX) || defined(CONFIG_TQM860) || defined(CONFIG_TQM860L) || defined(CONFIG_FPS850)) immap->im_ioport.iop_pcpar |= PC_ENET_TENA; immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; #endif +#if (defined(CONFIG_TQM8xxL) && !defined(CONFIG_FPS850)) + cp->cp_pbpar |= PB_ENET_TENA; + cp->cp_pbdir |= PB_ENET_TENA; +#endif + #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; @@ -927,6 +915,7 @@ immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK; immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK; #endif + dev->base_addr = (unsigned long)ep; dev->priv = cep; diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/8xx_io/uart.c linux/arch/ppc/8xx_io/uart.c --- v2.4.0-test3/linux/arch/ppc/8xx_io/uart.c Mon Jul 10 16:47:20 2000 +++ linux/arch/ppc/8xx_io/uart.c Thu Jul 13 09:42:50 2000 @@ -41,8 +41,10 @@ #include #include #include "commproc.h" - + #ifdef CONFIG_KGDB +extern void breakpoint(void); +extern void set_debug_traps(void); extern int kgdb_output_string (const char* s, unsigned int count); #endif @@ -56,10 +58,17 @@ #endif #endif +#if 0 +/* SCC2 for console +*/ +#undef CONFIG_SERIAL_CONSOLE_PORT +#define CONFIG_SERIAL_CONSOLE_PORT 2 +#endif + #define TX_WAKEUP ASYNC_SHARE_IRQ static char *serial_name = "CPM UART driver"; -static char *serial_version = "0.02"; +static char *serial_version = "0.03"; static DECLARE_TASK_QUEUE(tq_serial); @@ -89,54 +98,33 @@ * needs. For example, the port address is the CPM parameter ram * offset for the SCC or SMC. The maximum number of ports is 4 SCCs and * 2 SMCs. The "hub6" field is used to indicate the channel number, with - * 0 and 1 indicating the SMCs and 2, 3, 4, and 5 are the SCCs. - * Since these ports are so versatile, I don't yet have a strategy for - * their management. For example, SCC1 is used for Ethernet. Right - * now, just don't put them in the table. Of course, right now I just - * want the SMC to work as a uart :-).. + * a flag indicating SCC or SMC, and the number is used as an index into + * the CPM parameter area for this device. * The "type" field is currently set to 0, for PORT_UNKNOWN. It is * not currently used. I should probably use it to indicate the port - * type of CMS or SCC. + * type of SMC or SCC. * The SMCs do not support any modem control signals. */ #define smc_scc_num hub6 - -#ifdef CONFIG_8xxSMC2 -/* SMC2 is sometimes used for low performance TDM interfaces. Define - * this as 1 if you want SMC2 as a serial port UART managed by this driver. - * Define this as 0 if you wish to use SMC2 for something else. - */ -#define USE_SMC2 1 -#else -#define USE_SMC2 0 -#endif - -/* Define SCC to ttySx mapping. -*/ -#define SCC_NUM_BASE (USE_SMC2 + 1) /* SCC base tty "number" */ - -/* Define which SCC is the first one to use for a serial port. These - * are 0-based numbers, i.e. this assumes the first SCC (SCC1) is used - * for Ethernet, and the first available SCC for serial UART is SCC2. - * NOTE: IF YOU CHANGE THIS, you have to change the PROFF_xxx and - * interrupt vectors in the table below to match. - */ -#define SCC_IDX_BASE 1 /* table index */ +#define NUM_IS_SCC ((int)0x00010000) +#define PORT_NUM(P) ((P) & 0x0000ffff) /* Processors other than the 860 only get SMCs configured by default. * Either they don't have SCCs or they are allocated somewhere else. * Of course, there are now 860s without some SCCs, so we will need to * address that someday. + * The Embedded Planet Multimedia I/O cards use TDM interfaces to the + * stereo codec parts, and we use SMC2 to help support that. */ static struct serial_state rs_table[] = { /* UART CLK PORT IRQ FLAGS NUM */ { 0, 0, PROFF_SMC1, CPMVEC_SMC1, 0, 0 }, /* SMC1 ttyS0 */ -#if USE_SMC2 +#ifdef CONFIG_8xxSMC2 { 0, 0, PROFF_SMC2, CPMVEC_SMC2, 0, 1 }, /* SMC2 ttyS1 */ #endif #ifdef CONFIG_8xxSCC - { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, SCC_NUM_BASE}, /* SCC2 ttyS2 */ - { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, SCC_NUM_BASE + 1}, /* SCC3 ttyS3 */ + { 0, 0, PROFF_SCC2, CPMVEC_SCC2, 0, (NUM_IS_SCC | 1) }, /* SCC2 ttyS2 */ + { 0, 0, PROFF_SCC3, CPMVEC_SCC3, 0, (NUM_IS_SCC | 2) }, /* SCC3 ttyS3 */ #endif }; @@ -245,13 +233,14 @@ return; save_flags(flags); cli(); - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &cpmp->cp_smc[idx]; - smcp->smc_smcm &= ~SMCM_TX; + idx = PORT_NUM(info->state->smc_scc_num); + if (info->state->smc_scc_num & NUM_IS_SCC) { + sccp = &cpmp->cp_scc[idx]; + sccp->scc_sccm &= ~UART_SCCM_TX; } else { - sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~UART_SCCM_TX; + smcp = &cpmp->cp_smc[idx]; + smcp->smc_smcm &= ~SMCM_TX; } restore_flags(flags); } @@ -267,14 +256,15 @@ if (serial_paranoia_check(info, tty->device, "rs_stop")) return; + idx = PORT_NUM(info->state->smc_scc_num); save_flags(flags); cli(); - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { - smcp = &cpmp->cp_smc[idx]; - smcp->smc_smcm |= SMCM_TX; + if (info->state->smc_scc_num & NUM_IS_SCC) { + sccp = &cpmp->cp_scc[idx]; + sccp->scc_sccm |= UART_SCCM_TX; } else { - sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm |= UART_SCCM_TX; + smcp = &cpmp->cp_smc[idx]; + smcp->smc_smcm |= SMCM_TX; } restore_flags(flags); } @@ -372,7 +362,7 @@ icount->rx++; #ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, *status); + printk("DR%02x:%02x...", ch, status); #endif *tty->flip.flag_buf_ptr = 0; if (status & (BD_SC_BR | BD_SC_FR | @@ -452,10 +442,28 @@ queue_task(&tty->flip.tqueue, &tq_timer); } +static _INLINE_ void receive_break(ser_info_t *info) +{ + struct tty_struct *tty = info->tty; + + info->state->icount.brk++; + /* Check to see if there is room in the tty buffer for + * the break. If not, we exit now, losing the break. FIXME + */ + if ((tty->flip.count + 1) >= TTY_FLIPBUF_SIZE) + return; + *(tty->flip.flag_buf_ptr++) = TTY_BREAK; + *(tty->flip.char_buf_ptr++) = 0; + tty->flip.count++; + + queue_task(&tty->flip.tqueue, &tq_timer); +} + static _INLINE_ void transmit_chars(ser_info_t *info) { - if (info->flags & TX_WAKEUP) { + if ((info->flags & TX_WAKEUP) || + (info->tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) { rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); } @@ -549,24 +557,27 @@ info = (ser_info_t *)dev_id; - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { + idx = PORT_NUM(info->state->smc_scc_num); + if (info->state->smc_scc_num & NUM_IS_SCC) { + sccp = &cpmp->cp_scc[idx]; + events = sccp->scc_scce; + if (events & SCCM_RX) + receive_chars(info); + if (events & SCCM_TX) + transmit_chars(info); + sccp->scc_scce = events; + } + else { smcp = &cpmp->cp_smc[idx]; events = smcp->smc_smce; + if (events & SMCM_BRKE) + receive_break(info); if (events & SMCM_RX) receive_chars(info); if (events & SMCM_TX) transmit_chars(info); smcp->smc_smce = events; } - else { - sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE]; - events = sccp->scc_scce; - if (events & SCCM_RX) - receive_chars(info); - if (events & SCCM_TX) - transmit_chars(info); - sccp->scc_scce = events; - } #ifdef SERIAL_DEBUG_INTR printk("rs_interrupt_single(%d, %x)...", @@ -691,7 +702,16 @@ */ change_speed(info); - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { + idx = PORT_NUM(info->state->smc_scc_num); + if (info->state->smc_scc_num & NUM_IS_SCC) { + sccp = &cpmp->cp_scc[idx]; + scup = (scc_uart_t *)&cpmp->cp_dparam[state->port]; + scup->scc_genscc.scc_mrblr = RX_BUF_SIZE; + scup->scc_maxidl = RX_BUF_SIZE; + sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX); + sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + } + else { smcp = &cpmp->cp_smc[idx]; /* Enable interrupts and I/O. @@ -708,22 +728,10 @@ * are coming. */ up = (smc_uart_t *)&cpmp->cp_dparam[state->port]; - up->smc_mrblr = RX_BUF_SIZE; up->smc_maxidl = RX_BUF_SIZE; - up->smc_brkcr = 1; /* number of break chars */ } - else { - sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE]; - scup = (scc_uart_t *)&cpmp->cp_dparam[state->port]; - - scup->scc_genscc.scc_mrblr = RX_BUF_SIZE; - scup->scc_maxidl = RX_BUF_SIZE; - - sccp->scc_sccm |= (UART_SCCM_TX | UART_SCCM_RX); - sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - } info->flags |= ASYNC_INITIALIZED; restore_flags(flags); @@ -758,7 +766,19 @@ save_flags(flags); cli(); /* Disable interrupts */ - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { + idx = PORT_NUM(state->smc_scc_num); + if (state->smc_scc_num & NUM_IS_SCC) { + sccp = &cpmp->cp_scc[idx]; + sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#ifdef CONFIG_SERIAL_CONSOLE + /* We can't disable the transmitter if this is the + * system console. + */ + if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT) +#endif + sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); + } + else { smcp = &cpmp->cp_smc[idx]; /* Disable interrupts and I/O. @@ -768,15 +788,10 @@ /* We can't disable the transmitter if this is the * system console. */ - if (idx != CONFIG_SERIAL_CONSOLE_PORT) + if ((state - rs_table) != CONFIG_SERIAL_CONSOLE_PORT) #endif smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); } - else { - sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); - sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - } if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags); @@ -795,6 +810,7 @@ unsigned cflag, cval, scval, prev_mode; int i, bits, sbits, idx; unsigned long flags; + struct serial_state *state; volatile smc_t *smcp; volatile scc_t *sccp; @@ -802,6 +818,8 @@ return; cflag = info->tty->termios->c_cflag; + state = info->state; + /* Character length programmed into the mode register is the * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, * 1 or 2 stop bits, minus 1. @@ -903,7 +921,12 @@ * stops bits (there is always at least one). */ bits++; - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { + idx = PORT_NUM(state->smc_scc_num); + if (state->smc_scc_num & NUM_IS_SCC) { + sccp = &cpmp->cp_scc[idx]; + sccp->scc_pmsr = (sbits << 12) | scval; + } + else { smcp = &cpmp->cp_smc[idx]; /* Set the mode register. We want to keep a copy of the @@ -914,12 +937,8 @@ smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); } - else { - sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE]; - sccp->scc_pmsr = (sbits << 12) | scval; - } - m8xx_cpm_setbrg(info->state->smc_scc_num, baud_rate); + m8xx_cpm_setbrg((state - rs_table), baud_rate); restore_flags(flags); } @@ -961,9 +980,9 @@ volatile cbd_t *bdp; #ifdef CONFIG_KGDB - /* Try to let stub handle output. Returns true if it did. */ - if (kgdb_output_string(buf, count)) - return ret; + /* Try to let stub handle output. Returns true if it did. */ + if (kgdb_output_string(buf, count)) + return ret; #endif if (serial_paranoia_check(info, tty->device, "rs_write")) @@ -986,8 +1005,7 @@ } if (from_user) { - c -= copy_from_user(__va(bdp->cbd_bufaddr), buf, c); - if (!c) { + if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) { if (!ret) ret = -EFAULT; break; @@ -1271,30 +1289,31 @@ * command. We take advantage of the begin/end functions to make this * happen. */ +static ushort smc_chan_map[] = { + CPM_CR_CH_SMC1, + CPM_CR_CH_SMC2 +}; + +static ushort scc_chan_map[] = { + CPM_CR_CH_SCC1, + CPM_CR_CH_SCC2, + CPM_CR_CH_SCC3, + CPM_CR_CH_SCC4 +}; + static void begin_break(ser_info_t *info) { volatile cpm8xx_t *cp; ushort chan; - ushort num; + int idx; cp = cpmp; - if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) { - if (num == 0) - chan = CPM_CR_CH_SMC1; - else - chan = CPM_CR_CH_SMC2; - } - else { - num -= SCC_NUM_BASE; - switch (num) { - case 0: chan = CPM_CR_CH_SCC1; break; - case 1: chan = CPM_CR_CH_SCC2; break; - case 2: chan = CPM_CR_CH_SCC3; break; - case 3: chan = CPM_CR_CH_SCC4; break; - default: return; - } - } + idx = PORT_NUM(info->state->smc_scc_num); + if (info->state->smc_scc_num & NUM_IS_SCC) + chan = scc_chan_map[idx]; + else + chan = smc_chan_map[idx]; cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_STOP_TX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); } @@ -1303,26 +1322,15 @@ { volatile cpm8xx_t *cp; ushort chan; - ushort num; + int idx; cp = cpmp; - if ((num = info->state->smc_scc_num) < SCC_NUM_BASE) { - if (num == 0) - chan = CPM_CR_CH_SMC1; - else - chan = CPM_CR_CH_SMC2; - } - else { - num -= SCC_NUM_BASE; - switch (num) { - case 0: chan = CPM_CR_CH_SCC1; break; - case 1: chan = CPM_CR_CH_SCC2; break; - case 2: chan = CPM_CR_CH_SCC3; break; - case 3: chan = CPM_CR_CH_SCC4; break; - default: return; - } - } + idx = PORT_NUM(info->state->smc_scc_num); + if (info->state->smc_scc_num & NUM_IS_SCC) + chan = scc_chan_map[idx]; + else + chan = smc_chan_map[idx]; cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_RESTART_TX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); } @@ -1623,16 +1631,17 @@ */ info->read_status_mask &= ~BD_SC_EMPTY; if (info->flags & ASYNC_INITIALIZED) { - if ((idx = info->state->smc_scc_num) < SCC_NUM_BASE) { + idx = PORT_NUM(info->state->smc_scc_num); + if (info->state->smc_scc_num & NUM_IS_SCC) { + sccp = &cpmp->cp_scc[idx]; + sccp->scc_sccm &= ~UART_SCCM_RX; + sccp->scc_gsmrl &= ~SCC_GSMRL_ENR; + } + else { smcp = &cpmp->cp_smc[idx]; smcp->smc_smcm &= ~SMCM_RX; smcp->smc_smcmr &= ~SMCMR_REN; } - else { - sccp = &cpmp->cp_scc[idx - SCC_IDX_BASE]; - sccp->scc_sccm &= ~UART_SCCM_RX; - sccp->scc_gsmrl &= ~SCC_GSMRL_ENR; - } /* * Before we drop DTR, make sure the UART transmitter * has completely drained; this is especially @@ -1713,7 +1722,18 @@ break; if (timeout && ((orig_jiffies + timeout) < jiffies)) break; + + /* The 'tx_cur' is really the next buffer to send. We + * have to back up to the previous BD and wait for it + * to go. This isn't perfect, because all this indicates + * is the buffer is available. There are still characters + * in the CPM FIFO. + */ bdp = info->tx_cur; + if (bdp == info->tx_bd_base) + bdp += (TX_NUM_FIFO-1); + else + bdp--; } while (bdp->cbd_sc & BD_SC_READY); current->state = TASK_RUNNING; #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT @@ -1803,7 +1823,7 @@ */ if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR)) || - (info->state->smc_scc_num < SCC_NUM_BASE)) { + !(info->state->smc_scc_num & NUM_IS_SCC)) { if (info->flags & ASYNC_CALLOUT_ACTIVE) return -EBUSY; info->flags |= ASYNC_NORMAL_ACTIVE; @@ -1981,8 +2001,8 @@ ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", state->line, - (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC", - state->port, state->irq); + (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC", + (unsigned int)(state->port), state->irq); if (!state->port || (state->type == PORT_UNKNOWN)) { ret += sprintf(buf+ret, "\n"); @@ -2070,7 +2090,7 @@ done: if (off >= len+begin) return 0; - *start = page + (off-begin); + *start = page + (begin-off); return ((count < begin+len-off) ? count : begin+len-off); } @@ -2229,7 +2249,7 @@ /* * Receive character from the serial port. This only works well - * before the port is initialize for real use. + * before the port is initialized for real use. */ static int my_console_wait_key(int idx, int xmon, char *obuf) { @@ -2350,7 +2370,7 @@ /* To avoid data cache CPM DMA coherency problems, allocate a * buffer in the CPM DPRAM. This will work until the CPM and * serial ports are initialized. At that time a memory buffer - * will be allcoated. + * will be allocated. * The port is already initialized from the boot procedure, all * we do here is give it a different buffer and make it a FIFO. */ @@ -2382,7 +2402,7 @@ static kdev_t serial_console_device(struct console *c) { - return MKDEV(TTYAUX_MAJOR, 64 + c->index); + return MKDEV(TTY_MAJOR, 64 + c->index); } @@ -2411,12 +2431,9 @@ #endif -/* This will be used for all boards when the MBX board information - * is modified to include a default baud rate. - */ -#ifndef CONFIG_MBX +/* Index in baud rate table of the default console baud rate. +*/ static int baud_idx; -#endif /* * The serial driver boot-time initialization code! @@ -2425,7 +2442,7 @@ { struct serial_state * state; ser_info_t *info; - uint mem_addr, dp_addr; + uint mem_addr, dp_addr, iobits; int i, j, idx; ushort chan; volatile cbd_t *bdp; @@ -2442,7 +2459,6 @@ /* Initialize the tty_driver structure */ - /*memset(&serial_driver, 0, sizeof(struct tty_driver));*/ __clear_user(&serial_driver,sizeof(struct tty_driver)); serial_driver.magic = TTY_DRIVER_MAGIC; serial_driver.driver_name = "serial"; @@ -2454,11 +2470,7 @@ serial_driver.subtype = SERIAL_TYPE_NORMAL; serial_driver.init_termios = tty_std_termios; serial_driver.init_termios.c_cflag = -#ifndef CONFIG_MBX baud_idx | CS8 | CREAD | HUPCL | CLOCAL; -#else - B9600 | CS8 | CREAD | HUPCL | CLOCAL; -#endif serial_driver.flags = TTY_DRIVER_REAL_RAW; serial_driver.refcount = &serial_refcount; serial_driver.table = serial_table; @@ -2502,29 +2514,16 @@ cp = cpmp; /* Get pointer to Communication Processor */ immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ - /* Configure SMCs Tx/Rx instead of port B parallel I/O. - */ -#if USE_SMC2 - cp->cp_pbpar |= 0x00000cc0; - cp->cp_pbdir &= ~0x00000cc0; - cp->cp_pbodr &= ~0x00000cc0; -#else - /* This will only enable SMC1 if you want SMC2 for something else. - */ - cp->cp_pbpar |= 0x000000c0; - cp->cp_pbdir &= ~0x000000c0; - cp->cp_pbodr &= ~0x000000c0; -#endif - /* Configure SCC2 and SCC3 instead of port A parallel I/O. + /* Configure SCC2, SCC3, and SCC4 instead of port A parallel I/O. */ -#if defined(CONFIG_MPC860) || defined(CONFIG_MPC860T) +#ifdef CONFIG_8xxSCC #ifndef CONFIG_MBX /* The "standard" configuration through the 860. */ - immap->im_ioport.iop_papar |= 0x003c; - immap->im_ioport.iop_padir &= ~0x003c; - immap->im_ioport.iop_paodr &= ~0x003c; + immap->im_ioport.iop_papar |= 0x00fc; + immap->im_ioport.iop_padir &= ~0x00fc; + immap->im_ioport.iop_paodr &= ~0x00fc; #else /* On the MBX, SCC3 is through Port D. */ @@ -2547,11 +2546,21 @@ */ cp->cp_sicr &= ~0x00ffff00; cp->cp_sicr |= 0x001b1200; -#endif - /* Wire BRG1 to SMC1 and BRG2 to SMC2. +#ifdef CONFIG_PP04 + /* Frequentis PP04 forced to RS-232 until we know better. + * Port C 12 and 13 low enables RS-232 on SCC3 and SCC4. + */ + immap->im_ioport.iop_pcdir |= 0x000c; + immap->im_ioport.iop_pcpar &= ~0x000c; + immap->im_ioport.iop_pcdat &= ~0x000c; + + /* This enables the TX driver. */ - cp->cp_simode = 0x10000000; + cp->cp_pbpar &= ~0x6000; + cp->cp_pbdat &= ~0x6000; +#endif +#endif for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { state->magic = SSTATE_MAGIC; @@ -2568,8 +2577,8 @@ state->icount.frame = state->icount.parity = 0; state->icount.overrun = state->icount.brk = 0; printk(KERN_INFO "ttyS%02d at 0x%04x is a %s\n", - i, state->port, - (state->smc_scc_num < SCC_NUM_BASE) ? "SMC" : "SCC"); + i, (unsigned int)(state->port), + (state->smc_scc_num & NUM_IS_SCC) ? "SCC" : "SMC"); #ifdef CONFIG_SERIAL_CONSOLE /* If we just printed the message on the console port, and * we are about to initialize it for general use, we have @@ -2581,7 +2590,6 @@ #endif info = kmalloc(sizeof(ser_info_t), GFP_KERNEL); if (info) { - /*memset(info, 0, sizeof(ser_info_t));*/ __clear_user(info,sizeof(ser_info_t)); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); @@ -2621,16 +2629,17 @@ bdp->cbd_bufaddr = __pa(mem_addr); bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; - if ((idx = state->smc_scc_num) < SCC_NUM_BASE) { + idx = PORT_NUM(info->state->smc_scc_num); + if (info->state->smc_scc_num & NUM_IS_SCC) { + scp = &cp->cp_scc[idx]; + sup = (scc_uart_t *)&cp->cp_dparam[state->port]; + sup->scc_genscc.scc_rbase = dp_addr; + } + else { sp = &cp->cp_smc[idx]; up = (smc_uart_t *)&cp->cp_dparam[state->port]; up->smc_rbase = dp_addr; } - else { - scp = &cp->cp_scc[idx - SCC_IDX_BASE]; - sup = (scc_uart_t *)&cp->cp_dparam[state->port]; - sup->scc_genscc.scc_rbase = dp_addr; - } dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO); @@ -2654,56 +2663,21 @@ bdp->cbd_bufaddr = __pa(mem_addr); bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT); - if (idx < SCC_NUM_BASE) { - up->smc_tbase = dp_addr; + if (info->state->smc_scc_num & NUM_IS_SCC) { + sup->scc_genscc.scc_tbase = dp_addr; /* Set up the uart parameters in the * parameter ram. */ - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; + sup->scc_genscc.scc_rfcr = SMC_EB; + sup->scc_genscc.scc_tfcr = SMC_EB; /* Set this to 1 for now, so we get single * character interrupts. Using idle charater * time requires some additional tuning. */ - up->smc_mrblr = RX_BUF_SIZE; - up->smc_maxidl = RX_BUF_SIZE; - up->smc_brkcr = 1; - - /* Send the CPM an initialize command. - */ - if (state->smc_scc_num == 0) - chan = CPM_CR_CH_SMC1; - else - chan = CPM_CR_CH_SMC2; - - cp->cp_cpcr = mk_cr_cmd(chan, - CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Disable all interrupts and clear all pending - * events. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - } - else { - sup->scc_genscc.scc_tbase = dp_addr; - - /* Set up the uart parameters in the - * parameter ram. - */ - sup->scc_genscc.scc_rfcr = SMC_EB; - sup->scc_genscc.scc_tfcr = SMC_EB; - - sup->scc_genscc.scc_mrblr = RX_BUF_SIZE; - sup->scc_maxidl = RX_BUF_SIZE; + sup->scc_genscc.scc_mrblr = 1; + sup->scc_maxidl = 0; sup->scc_brkcr = 1; sup->scc_parec = 0; sup->scc_frmec = 0; @@ -2724,10 +2698,7 @@ /* Send the CPM an initialize command. */ - if (state->smc_scc_num == 2) - chan = CPM_CR_CH_SCC2; - else - chan = CPM_CR_CH_SCC3; + chan = scc_chan_map[idx]; cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; @@ -2747,6 +2718,91 @@ scp->scc_scce = 0xffff; scp->scc_dsr = 0x7e7e; scp->scc_pmsr = 0x3000; + + /* If the port is the console, enable Rx and Tx. + */ +#ifdef CONFIG_SERIAL_CONSOLE + if (i == CONFIG_SERIAL_CONSOLE_PORT) + scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#endif + } + else { + /* Configure SMCs Tx/Rx instead of port B + * parallel I/O. On 823/850 these are on + * port A for SMC2. + */ +#ifndef CONFIG_8xx_ALTSMC2 + iobits = 0xc0 << (idx * 4); + cp->cp_pbpar |= iobits; + cp->cp_pbdir &= ~iobits; + cp->cp_pbodr &= ~iobits; +#else + if (idx == 0) { + /* SMC1 on Port B, like all 8xx. + */ + iobits = 0xc0; + cp->cp_pbpar |= iobits; + cp->cp_pbdir &= ~iobits; + cp->cp_pbodr &= ~iobits; + } + else { + /* SMC2 is on Port A. + */ + iobits = 0x300; + immap->im_ioport.iop_papar |= iobits; + immap->im_ioport.iop_padir &= ~iobits; + immap->im_ioport.iop_paodr &= ~iobits; + } +#endif + + /* Connect the baud rate generator to the + * SMC based upon index in rs_table. Also + * make sure it is connected to NMSI. + */ + cp->cp_simode &= ~(0xffff << (idx * 16)); + cp->cp_simode |= (i << ((idx * 16) + 12)); + + up->smc_tbase = dp_addr; + + /* Set up the uart parameters in the + * parameter ram. + */ + up->smc_rfcr = SMC_EB; + up->smc_tfcr = SMC_EB; + + /* Set this to 1 for now, so we get single + * character interrupts. Using idle charater + * time requires some additional tuning. + */ + up->smc_mrblr = 1; + up->smc_maxidl = 0; + up->smc_brkcr = 1; + + /* Send the CPM an initialize command. + */ + chan = smc_chan_map[idx]; + + cp->cp_cpcr = mk_cr_cmd(chan, + CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; + + /* Disable all interrupts and clear all pending + * events. + */ + sp->smc_smcm = 0; + sp->smc_smce = 0xff; + + /* If the port is the console, enable Rx and Tx. + */ +#ifdef CONFIG_SERIAL_CONSOLE + if (i == CONFIG_SERIAL_CONSOLE_PORT) + sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; +#endif } /* Install interrupt handler. @@ -2755,19 +2811,8 @@ /* Set up the baud rate generator. */ -#ifndef CONFIG_MBX - m8xx_cpm_setbrg(state->smc_scc_num, - baud_table[baud_idx]); -#else - m8xx_cpm_setbrg(state->smc_scc_num, 9600); -#endif + m8xx_cpm_setbrg(i, baud_table[baud_idx]); - /* If the port is the console, enable Rx and Tx. - */ -#ifdef CONFIG_SERIAL_CONSOLE - if (i == CONFIG_SERIAL_CONSOLE_PORT) - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -#endif } } @@ -2780,13 +2825,14 @@ static int __init serial_console_setup(struct console *co, char *options) { struct serial_state *ser; - uint mem_addr, dp_addr, bidx; + uint mem_addr, dp_addr, bidx, idx; + ushort chan; volatile cbd_t *bdp; volatile cpm8xx_t *cp; volatile smc_t *sp; + volatile scc_t *scp; volatile smc_uart_t *up; - -#ifndef CONFIG_MBX + volatile scc_uart_t *sup; bd_t *bd; bd = (bd_t *)__res; @@ -2797,40 +2843,41 @@ co->cflag = CREAD|CLOCAL|bidx|CS8; baud_idx = bidx; -#else - co->cflag = CREAD|CLOCAL|B9600|CS8; -#endif ser = rs_table + co->index; cp = cpmp; /* Get pointer to Communication Processor */ - /* Right now, assume we are using SMCs. - */ - sp = &cp->cp_smc[ser->smc_scc_num]; + idx = PORT_NUM(ser->smc_scc_num); + if (ser->smc_scc_num & NUM_IS_SCC) { + scp = &cp->cp_scc[idx]; + sup = (scc_uart_t *)&cp->cp_dparam[ser->port]; + } + else { + sp = &cp->cp_smc[idx]; + up = (smc_uart_t *)&cpmp->cp_dparam[ser->port]; + } + /* When we get here, the CPM has been reset, so we need * to configure the port. * We need to allocate a transmit and receive buffer descriptor * from dual port ram, and a character buffer area from host mem. */ - up = (smc_uart_t *)&cp->cp_dparam[ser->port]; - cp->cp_pbpar = 0x00c0; /* Enable SMC1 instead of Port B I/O */ /* Allocate space for two buffer descriptors in the DP ram. */ dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2); - /* Allocate space for an input FIFO, plus a few bytes for output. - * Allocate bytes to maintain word alignment. - */ - mem_addr = m8xx_cpm_hostalloc(RX_BUF_SIZE + 4); + /* Allocate space for two 2 byte FIFOs in the host memory. + */ + mem_addr = m8xx_cpm_hostalloc(8); /* Set the physical address of the host memory buffers in * the buffer descriptors. */ bdp = (cbd_t *)&cp->cp_dpmem[dp_addr]; bdp->cbd_bufaddr = __pa(mem_addr); - (bdp+1)->cbd_bufaddr = __pa(mem_addr+RX_BUF_SIZE); + (bdp+1)->cbd_bufaddr = __pa(mem_addr+4); /* For the receive, set empty and wrap. * For transmit, set wrap. @@ -2840,39 +2887,98 @@ /* Set up the uart parameters in the parameter ram. */ - up->smc_rbase = dp_addr; /* Base of receive buffer desc. */ - up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */ - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; + if (ser->smc_scc_num & NUM_IS_SCC) { - up->smc_mrblr = RX_BUF_SIZE; /* receive buffer length */ - up->smc_maxidl = RX_BUF_SIZE; + sup->scc_genscc.scc_rbase = dp_addr; + sup->scc_genscc.scc_tbase = dp_addr + sizeof(cbd_t); - /* Send the CPM an initialize command. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG; - /* - * delay for a bit - this is necessary on my board! - * -- Cort - */ - printk(""); - while (cp->cp_cpcr & CPM_CR_FLG); - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; + /* Set up the uart parameters in the + * parameter ram. + */ + sup->scc_genscc.scc_rfcr = SMC_EB; + sup->scc_genscc.scc_tfcr = SMC_EB; - /* Set up the baud rate generator. - */ -#ifndef CONFIG_MBX - m8xx_cpm_setbrg(ser->smc_scc_num, bd->bi_baudrate); -#else - m8xx_cpm_setbrg(ser->smc_scc_num, 9600); -#endif + /* Set this to 1 for now, so we get single + * character interrupts. Using idle charater + * time requires some additional tuning. + */ + sup->scc_genscc.scc_mrblr = 1; + sup->scc_maxidl = 0; + sup->scc_brkcr = 1; + sup->scc_parec = 0; + sup->scc_frmec = 0; + sup->scc_nosec = 0; + sup->scc_brkec = 0; + sup->scc_uaddr1 = 0; + sup->scc_uaddr2 = 0; + sup->scc_toseq = 0; + sup->scc_char1 = 0x8000; + sup->scc_char2 = 0x8000; + sup->scc_char3 = 0x8000; + sup->scc_char4 = 0x8000; + sup->scc_char5 = 0x8000; + sup->scc_char6 = 0x8000; + sup->scc_char7 = 0x8000; + sup->scc_char8 = 0x8000; + sup->scc_rccm = 0xc0ff; + + /* Send the CPM an initialize command. + */ + chan = scc_chan_map[idx]; + + cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + scp->scc_gsmrh = 0; + scp->scc_gsmrl = + (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); + + /* Disable all interrupts and clear all pending + * events. + */ + scp->scc_sccm = 0; + scp->scc_scce = 0xffff; + scp->scc_dsr = 0x7e7e; + scp->scc_pmsr = 0x3000; + + scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + } + else { + up->smc_rbase = dp_addr; /* Base of receive buffer desc. */ + up->smc_tbase = dp_addr+sizeof(cbd_t); /* Base of xmt buffer desc. */ + up->smc_rfcr = SMC_EB; + up->smc_tfcr = SMC_EB; + + /* Set this to 1 for now, so we get single character interrupts. + */ + up->smc_mrblr = 1; /* receive buffer length */ + up->smc_maxidl = 0; /* wait forever for next char */ - /* And finally, enable Rx and Tx. + /* Send the CPM an initialize command. + */ + chan = smc_chan_map[idx]; + cp->cp_cpcr = mk_cr_cmd(chan, CPM_CR_INIT_TRX) | CPM_CR_FLG; + printk(""); + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; + + /* And finally, enable Rx and Tx. + */ + sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; + } + + /* Set up the baud rate generator. */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; + m8xx_cpm_setbrg((ser - rs_table), bd->bi_baudrate); return 0; } + diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/amiga/chipram.c linux/arch/ppc/amiga/chipram.c --- v2.4.0-test3/linux/arch/ppc/amiga/chipram.c Mon Jul 10 16:47:20 2000 +++ linux/arch/ppc/amiga/chipram.c Tue Jul 11 11:18:53 2000 @@ -5,6 +5,7 @@ ** - 64-bit aligned allocations for full AGA compatibility */ +#include #include #include #include diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/coffboot/Makefile linux/arch/ppc/coffboot/Makefile --- v2.4.0-test3/linux/arch/ppc/coffboot/Makefile Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/coffboot/Makefile Thu Jul 13 09:42:50 2000 @@ -42,7 +42,7 @@ cp vmlinux.coff $(TFTPIMAGE) cp vmlinux.elf $(TFTPIMAGE).elf -znetboot.initrd: vmlinux.coff.initrd +znetboot.initrd: vmlinux.coff.initrd vmlinux.elf.initrd cp vmlinux.coff.initrd $(TFTPIMAGE) cp vmlinux.elf.initrd $(TFTPIMAGE).elf @@ -81,7 +81,7 @@ ln -sf vmlinux.coff zImage vmlinux.coff.initrd: coffboot.initrd hack-coff - $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@ + $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd $@ ./hack-coff $@ vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/config.in linux/arch/ppc/config.in --- v2.4.0-test3/linux/arch/ppc/config.in Mon Jul 10 16:47:20 2000 +++ linux/arch/ppc/config.in Thu Jul 13 09:42:50 2000 @@ -12,17 +12,28 @@ endmenu mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'Platform support' define_bool CONFIG_PPC y choice 'Processor Type' \ "6xx/7xx/7400 CONFIG_6xx \ 4xx CONFIG_4xx \ - POWER3/POWER4(64-Bit) CONFIG_PPC64BRIDGE \ + POWER3 CONFIG_POWER3 \ + POWER4 CONFIG_POWER4 \ 8260 CONFIG_8260 \ 8xx CONFIG_8xx" 6xx -if [ "$CONFIG_PPC64BRIDGE" = "y" ]; then - bool 'Power 4 support' CONFIG_POWER4 +if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then + define_bool CONFIG_PPC64BRIDGE y + define_bool CONFIG_ALL_PPC y fi if [ "$CONFIG_8260" = "y" ]; then @@ -43,6 +54,9 @@ "RPX-Lite CONFIG_RPXLITE \ RPX-Classic CONFIG_RPXCLASSIC \ BSE-IP CONFIG_BSEIP \ + TQM8xxL CONFIG_TQM8xxL \ + TQM860L CONFIG_TQM860L \ + TQM860 CONFIG_TQM860 \ MBX CONFIG_MBX \ WinCept CONFIG_WINCEPT" RPX-Lite fi @@ -54,14 +68,14 @@ APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP fi -if [ "$CONFIG_PPC64BRIDGE" = "y" ]; then - define_bool CONFIG_ALL_PPC y -fi - if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then define_bool CONFIG_ALL_PPC n fi +if [ "$CONFIG_TQM8xxL" = "y" ]; then + bool 'FPS850 Mainboard' CONFIG_FPS850 +fi + bool 'Symmetric multi-processing support' CONFIG_SMP if [ "$CONFIG_6xx" = "y" ];then bool 'AltiVec Support' CONFIG_ALTIVEC @@ -77,15 +91,6 @@ endmenu mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool ' Set version information on all module symbols' CONFIG_MODVERSIONS - bool ' Kernel module loader' CONFIG_KMOD -fi -endmenu - -mainmenu_option next_comment comment 'General setup' define_bool CONFIG_ISA n @@ -149,6 +154,7 @@ bool 'Support for ADB keyboard' CONFIG_ADB_KEYBOARD bool 'Support for ADB mouse' CONFIG_ADBMOUSE fi + tristate 'Support for /dev/rtc' CONFIG_PPC_RTC bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile --- v2.4.0-test3/linux/arch/ppc/kernel/Makefile Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/Makefile Thu Jul 13 09:42:50 2000 @@ -99,7 +99,8 @@ ifeq ($(CONFIG_ALL_PPC),y) O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o \ chrp_setup.o chrp_time.o chrp_pci.o open_pic.o indirect_pci.o \ - prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o + prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o \ + pmac_backlight.o OX_OBJS += prep_setup.o endif ifeq ($(CONFIG_GEMINI),y) diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/bitops.c linux/arch/ppc/kernel/bitops.c --- v2.4.0-test3/linux/arch/ppc/kernel/bitops.c Thu Jul 31 13:09:17 1997 +++ linux/arch/ppc/kernel/bitops.c Thu Jul 13 09:42:50 2000 @@ -6,60 +6,58 @@ #include /* - * I left these here since the problems with "cc" make it difficult to keep - * them in bitops.h -- Cort + * If the bitops are not inlined in bitops.h, they are defined here. + * -- paulus */ -void set_bit(int nr, volatile void *addr) +#if !__INLINE_BITOPS +void set_bit(int nr, volatile void * addr) { - unsigned int t; - unsigned int mask = 1 << (nr & 0x1f); - volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - - if ((unsigned long)addr & 3) - printk(KERN_ERR "set_bit(%x, %p)\n", nr, addr); - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 - or %0,%0,%1 - stwcx. %0,0,%2 + unsigned long old; + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); + + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%3 + or %0,%0,%2 + stwcx. %0,0,%3 bne 1b" - : "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) - : "cc"); + SMP_MB + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc" ); } void clear_bit(int nr, volatile void *addr) { - unsigned int t; - unsigned int mask = 1 << (nr & 0x1f); - volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + unsigned long old; + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - if ((unsigned long)addr & 3) - printk(KERN_ERR "clear_bit(%x, %p)\n", nr, addr); - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 - andc %0,%0,%1 - stwcx. %0,0,%2 + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%3 + andc %0,%0,%2 + stwcx. %0,0,%3 bne 1b" - : "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) + SMP_MB + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) : "cc"); } void change_bit(int nr, volatile void *addr) { - unsigned int t; - unsigned int mask = 1 << (nr & 0x1f); - volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + unsigned long old; + unsigned long mask = 1 << (nr & 0x1f); + unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - if ((unsigned long)addr & 3) - printk(KERN_ERR "change_bit(%x, %p)\n", nr, addr); - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 - xor %0,%0,%1 - stwcx. %0,0,%2 + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%3 + xor %0,%0,%2 + stwcx. %0,0,%3 bne 1b" - : "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) + SMP_MB + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) : "cc"); } @@ -69,15 +67,14 @@ unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - if ((unsigned long)addr & 3) - printk(KERN_ERR "test_and_set_bit(%x, %p)\n", nr, addr); - __asm__ __volatile__("\n\ -1: lwarx %0,0,%3 - or %1,%0,%2 - stwcx. %1,0,%3 - bne 1b" - : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%4 + or %1,%0,%3 + stwcx. %1,0,%4 + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) : "cc"); return (old & mask) != 0; @@ -89,15 +86,14 @@ unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - if ((unsigned long)addr & 3) - printk(KERN_ERR "test_and_clear_bit(%x, %p)\n", nr, addr); - __asm__ __volatile__("\n\ -1: lwarx %0,0,%3 - andc %1,%0,%2 - stwcx. %1,0,%3 - bne 1b" - : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%4 + andc %1,%0,%3 + stwcx. %1,0,%4 + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) : "cc"); return (old & mask) != 0; @@ -109,93 +105,16 @@ unsigned int mask = 1 << (nr & 0x1f); volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); - if ((unsigned long)addr & 3) - printk(KERN_ERR "test_and_change_bit(%x, %p)\n", nr, addr); - __asm__ __volatile__("\n\ -1: lwarx %0,0,%3 - xor %1,%0,%2 - stwcx. %1,0,%3 - bne 1b" - : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%4 + xor %1,%0,%3 + stwcx. %1,0,%4 + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) : "cc"); return (old & mask) != 0; } - -/* I put it in bitops.h -- Cort */ -#if 0 -int ffz(unsigned int x) -{ - int n; - - x = ~x & (x+1); /* set LS zero to 1, other bits to 0 */ - __asm__ ("cntlzw %0,%1" : "=r" (n) : "r" (x)); - return 31 - n; -} - -/* - * This implementation of find_{first,next}_zero_bit was stolen from - * Linus' asm-alpha/bitops.h. - */ - -int find_first_zero_bit(void * addr, int size) -{ - unsigned int * p = ((unsigned int *) addr); - unsigned int result = 0; - unsigned int tmp; - - if (size == 0) - return 0; - while (size & ~31UL) { - if (~(tmp = *(p++))) - goto found_middle; - result += 32; - size -= 32; - } - if (!size) - return result; - tmp = *p; - tmp |= ~0UL << size; -found_middle: - return result + ffz(tmp); -} - -/* - * Find next zero bit in a bitmap reasonably efficiently.. - */ -int find_next_zero_bit(void * addr, int size, int offset) -{ - unsigned int * p = ((unsigned int *) addr) + (offset >> 5); - unsigned int result = offset & ~31UL; - unsigned int tmp; - - if (offset >= size) - return size; - size -= result; - offset &= 31UL; - if (offset) { - tmp = *(p++); - tmp |= ~0UL >> (32-offset); - if (size < 32) - goto found_first; - if (~tmp) - goto found_middle; - size -= 32; - result += 32; - } - while (size & ~31UL) { - if (~(tmp = *(p++))) - goto found_middle; - result += 32; - size -= 32; - } - if (!size) - return result; - tmp = *p; -found_first: - tmp |= ~0UL << size; -found_middle: - return result + ffz(tmp); -} -#endif +#endif /* !__INLINE_BITOPS */ diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c --- v2.4.0-test3/linux/arch/ppc/kernel/chrp_pci.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/chrp_pci.c Thu Jul 13 09:42:50 2000 @@ -288,7 +288,9 @@ chrp_pcibios_fixup(void) { struct pci_dev *dev; +#ifdef CONFIG_POWER4 int i; +#endif int *brp; struct device_node *np; extern struct pci_ops generic_pci_ops; diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/chrp_setup.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/chrp_setup.c Thu Jul 13 09:42:50 2000 @@ -51,7 +51,7 @@ #include #include -#include "time.h" +#include #include "local_irq.h" #include "i8259.h" #include "open_pic.h" diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/chrp_time.c linux/arch/ppc/kernel/chrp_time.c --- v2.4.0-test3/linux/arch/ppc/kernel/chrp_time.c Tue May 23 15:31:34 2000 +++ linux/arch/ppc/kernel/chrp_time.c Thu Jul 13 09:42:50 2000 @@ -26,7 +26,7 @@ #include #include #include -#include "time.h" +#include static int nvram_as1 = NVRAM_AS1; static int nvram_as0 = NVRAM_AS0; diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S --- v2.4.0-test3/linux/arch/ppc/kernel/entry.S Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/entry.S Thu Jul 13 09:42:50 2000 @@ -5,8 +5,8 @@ * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP - * Copyright (C) 1996 Cort Dougan + * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP + * Copyright (C) 1996 Cort Dougan * Adapted for Power Macintosh by Paul Mackerras. * Low-level exception handlers and MMU support * rewritten by Paul Mackerras. @@ -83,7 +83,9 @@ #endif /* SHOW_SYSCALLS */ cmpi 0,r0,0x7777 /* Special case for 'sys_sigreturn' */ beq- 10f - lwz r10,TASK_PTRACE(r2) + cmpi 0,r0,0x6666 /* Special case for 'sys_rt_sigreturn' */ + beq- 16f + lwz r10,TASK_FLAGS(r2) andi. r10,r10,PT_TRACESYS bne- 50f cmpli 0,r0,NR_syscalls @@ -129,6 +131,12 @@ /* sys_sigreturn */ 10: addi r3,r1,STACK_FRAME_OVERHEAD bl sys_sigreturn + cmpi 0,r3,0 /* Check for restarted system call */ + bge ret_from_except + b 20b +/* sys_rt_sigreturn */ +16: addi r3,r1,STACK_FRAME_OVERHEAD + bl sys_rt_sigreturn cmpi 0,r3,0 /* Check for restarted system call */ bge ret_from_except b 20b diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/feature.c linux/arch/ppc/kernel/feature.c --- v2.4.0-test3/linux/arch/ppc/kernel/feature.c Thu May 11 15:30:06 2000 +++ linux/arch/ppc/kernel/feature.c Thu Jul 13 09:42:50 2000 @@ -2,6 +2,7 @@ * arch/ppc/kernel/feature.c * * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) + * Ben. Herrenschmidt (bh40@calva.net) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,7 +31,7 @@ #undef DEBUG_FEATURE #define MAX_FEATURE_CONTROLLERS 2 -#define MAX_FEATURE_OFFSET 0x50 +#define MAX_FEATURE_OFFSET 0x100 #define FREG(c,r) (&(((c)->reg)[(r)>>2])) typedef struct feature_bit { @@ -70,6 +71,7 @@ {0x38,0,0}, /* FEATURE_IDE2_reset */ {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ {0x38,0,0}, /* FEATURE_Mediabay_content */ + {0x38,0,0}, /* FEATURE_Airport_reset */ }; /* Those bits are from a PowerBook. It's possible that desktop machines @@ -102,6 +104,7 @@ {0x38,0,0}, /* FEATURE_IDE2_reset */ {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ {0x38,0,0}, /* FEATURE_Mediabay_content */ + {0x38,0,0}, /* FEATURE_Airport_reset */ }; /* @@ -135,6 +138,7 @@ {0x38,0,0}, /* FEATURE_IDE2_reset */ {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */ {0x38,0,0}, /* FEATURE_Mediabay_content */ + {0x38,0,0}, /* FEATURE_Airport_reset */ }; /* Those bits are for Core99 machines (iBook,G4,iMacSL/DV,Pismo,...). @@ -166,6 +170,7 @@ {0x3c,1,0x40000000}, /* FEATURE_IDE2_reset */ {0x34,0,0x00001000}, /* FEATURE_Mediabay_IDE_switch */ {0x34,0,0x00000100}, /* FEATURE_Mediabay_content */ + {0x40,1,0x08000000}, /* FEATURE_Airport_reset */ }; /* definition of a feature controller object */ @@ -177,22 +182,33 @@ }; /* static functions */ -static void +static struct feature_controller* feature_add_controller(struct device_node *controller_device, fbit* bits); static struct feature_controller* feature_lookup_controller(struct device_node *device); -/* static varialbles */ +static void heathrow_prepare_for_sleep(struct feature_controller* ctrler); +static void heathrow_wakeup(struct feature_controller* ctrler); +static void core99_prepare_for_sleep(struct feature_controller* ctrler); +static void core99_wake_up(struct feature_controller* ctrler); + +/* static variables */ static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS]; static int controller_count = 0; +/* Core99 stuffs */ +static volatile u32* uninorth_base = NULL; +static volatile u32* keylargo_base = NULL; +static int uninorth_rev; +static int keylargo_rev; void feature_init(void) { struct device_node *np; - + u32 *rev; + if (_machine != _MACH_Pmac) return; @@ -202,7 +218,14 @@ * plus some gpio's which could eventually be handled here. */ if (device_is_compatible(np, "Keylargo")) { - feature_add_controller(np, feature_bits_keylargo); + struct feature_controller* ctrler = + feature_add_controller(np, feature_bits_keylargo); + if (ctrler) { + keylargo_base = ctrler->reg; + rev = (u32 *)get_property(ctrler->device, "revision-id", NULL); + if (rev) + keylargo_rev = *rev; + } } else if (device_is_compatible(np, "paddington")) { feature_add_controller(np, feature_bits_paddington); } else { @@ -222,6 +245,18 @@ } } + /* Handle core99 Uni-N */ + np = find_devices("uni-n"); + if (np && np->n_addrs > 0) { + uninorth_base = ioremap(np->addrs[0].address, 0x1000); + rev = (u32 *)get_property(np, "device-rev", NULL); + if (rev) + uninorth_rev = *rev; + } + if (uninorth_base && keylargo_base) + printk("Uni-N revision: %d, KeyLargo revision: %d\n", + uninorth_rev, keylargo_rev); + if (controller_count) printk(KERN_INFO "Registered %d feature controller(s)\n", controller_count); @@ -236,7 +271,7 @@ #endif } -static void +static struct feature_controller* feature_add_controller(struct device_node *controller_device, fbit* bits) { struct feature_controller* controller; @@ -244,7 +279,7 @@ if (controller_count >= MAX_FEATURE_CONTROLLERS) { printk(KERN_INFO "Feature controller %s skipped(MAX:%d)\n", controller_device->full_name, MAX_FEATURE_CONTROLLERS); - return; + return NULL; } controller = &controllers[controller_count]; @@ -253,7 +288,7 @@ if (controller_device->n_addrs == 0) { printk(KERN_ERR "No addresses for %s\n", controller_device->full_name); - return; + return NULL; } controller->reg = (volatile u32 *)ioremap( @@ -262,12 +297,14 @@ if (bits == NULL) { printk(KERN_INFO "Twiddling the magic ohare bits\n"); out_le32(FREG(controller,OHARE_FEATURE_REG), STARMAX_FEATURES); - return; + return NULL; } spin_lock_init(&controller->lock); controller_count++; + + return controller; } static struct feature_controller* @@ -387,5 +424,120 @@ */ value = (in_le32(FREG(controller, bit->reg)) & bit->mask); return bit->polarity ? (value == 0) : (value == bit->mask); +} + +/* + * Core99 functions + * + * Note: We currently assume there is _one_ UniN chip and _one_ KeyLargo + * chip, which is the case on all Core99 machines so far + */ + +/* Only one GMAC is assumed */ +void +feature_set_gmac_power(struct device_node* device, int power) +{ + if (!uninorth_base) + return; + if (power) + out_le32(uninorth_base + 0x20/4, + in_le32(uninorth_base + 0x20/4) | 0x02000000); + else + out_le32(uninorth_base + 0x20/4, + in_le32(uninorth_base + 0x20/4) & ~0x02000000); + udelay(20); +} + +/* Pass the node of the correct controller, please */ +void +feature_set_usb_power(struct device_node* device, int power) +{ +} + +/* Not yet implemented */ +void +feature_set_firewire_power(struct device_node* device, int power) +{ +} + +void +feature_prepare_for_sleep(void) +{ + /* We assume gatwick is second */ + struct feature_controller* ctrler = &controllers[0]; + + if (!ctrler) + return; + if (controller_count > 1 && + device_is_compatible(ctrler->device, "gatwick")) + ctrler = &controllers[1]; + + if (ctrler->bits == feature_bits_heathrow || + ctrler->bits == feature_bits_paddington) { + heathrow_prepare_for_sleep(ctrler); + return; + } + if (ctrler->bits == feature_bits_keylargo) { + core99_prepare_for_sleep(ctrler); + return; + } +} + + +void +feature_wake_up(void) +{ + struct feature_controller* ctrler = &controllers[0]; + + if (!ctrler) + return; + if (controller_count > 1 && + device_is_compatible(ctrler->device, "gatwick")) + ctrler = &controllers[1]; + + if (ctrler->bits == feature_bits_heathrow || + ctrler->bits == feature_bits_paddington) { + heathrow_wakeup(ctrler); + return; + } + if (ctrler->bits == feature_bits_keylargo) { + core99_wake_up(ctrler); + return; + } +} + +static u32 save_fcr0; +//static u32 save_fcr1; +//static u32 save_fcr2; +static u32 save_mbcr; + +static void +heathrow_prepare_for_sleep(struct feature_controller* ctrler) +{ + save_mbcr = in_le32(FREG(ctrler, 0x34)); + save_fcr0 = in_le32(FREG(ctrler, 0x38)); + + out_le32(FREG(ctrler, 0x38), save_fcr0 & ~HRW_IOBUS_ENABLE); +} + +static void +heathrow_wakeup(struct feature_controller* ctrler) +{ + out_le32(FREG(ctrler, 0x38), save_fcr0); + out_le32(FREG(ctrler, 0x34), save_mbcr); + + out_le32(FREG(ctrler, 0x38), save_fcr0 | HRW_IOBUS_ENABLE); +} + +static void +core99_prepare_for_sleep(struct feature_controller* ctrler) +{ + /* Not yet implemented */ +} + +static void +core99_wake_up(struct feature_controller* ctrler) +{ + /* Not yet implemented */ } diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/gemini_setup.c linux/arch/ppc/kernel/gemini_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/gemini_setup.c Thu May 11 15:30:06 2000 +++ linux/arch/ppc/kernel/gemini_setup.c Thu Jul 13 09:42:50 2000 @@ -30,7 +30,7 @@ #include #include -#include "time.h" +#include #include "local_irq.h" #include "open_pic.h" diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S --- v2.4.0-test3/linux/arch/ppc/kernel/head.S Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/head.S Thu Jul 13 09:42:50 2000 @@ -171,6 +171,9 @@ #ifndef CONFIG_POWER4 /* POWER4 doesn't have BATs */ bl initial_bats +#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) + bl setup_disp_bat +#endif #else /* CONFIG_POWER4 */ /* * Load up the SDR1 and segment register values now @@ -1603,23 +1606,37 @@ mtspr DBAT0U,r11 /* bit in upper BAT register */ mtspr IBAT0L,r8 mtspr IBAT0U,r11 -#if 0 /* Useful debug code, please leave in for now so I don't have to - * look at docs when I need to setup a BAT ... - */ -setup_screen_bat: - li r3,0 - mtspr DBAT1U,r3 - lis r3,0xfa00 - CLR_TOP32(r3) - lis r4,0xfa00 - CLR_TOP32(r4) - ori r4,r4,0x2a - mtspr DBAT1L,r4 - ori r3,r3,(BL_16M<<2)|0x2 /* set up BAT registers for 604 */ - mtspr DBAT1U,r3 -#endif isync blr + +#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) +setup_disp_bat: + /* + * setup the display bat prepared for us in prom.c + */ + mflr r8 + bl reloc_offset + mtlr r8 + lis r8, disp_BATL@h + ori r8, r8, disp_BATL@l + add r8, r3, r8 + lwz r8, 0(r8) + lis r11, disp_BATU@h + ori r11, r11, disp_BATU@l + add r11, r3, r11 + lwz r11, 0(r11) + mtspr IBAT3L,r8 + mtspr IBAT3U,r11 + mfspr r9,PVR + rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ + cmpi 0,r9,1 + beq 1f + mtspr DBAT3L,r8 + mtspr DBAT3U,r11 +1: + blr + +#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ #endif /* CONFIG_POWER4 */ #ifdef CONFIG_8260 diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c --- v2.4.0-test3/linux/arch/ppc/kernel/idle.c Wed Apr 26 16:34:07 2000 +++ linux/arch/ppc/kernel/idle.c Thu Jul 13 09:42:50 2000 @@ -48,7 +48,7 @@ int idled(void) { /* endless loop with no priority at all */ - current->priority = 0; + current->nice = 20; current->counter = -100; init_idle(); for (;;) @@ -304,3 +304,4 @@ return; } } + diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c --- v2.4.0-test3/linux/arch/ppc/kernel/irq.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/irq.c Thu Jul 13 09:42:50 2000 @@ -74,8 +74,7 @@ irq_desc_t irq_desc[NR_IRQS]; int ppc_spurious_interrupts = 0; -unsigned int local_bh_count[NR_CPUS]; -unsigned int local_irq_count[NR_CPUS]; +irq_cpustat_t irq_stat [NR_CPUS]; struct irqaction *ppc_irq_action[NR_IRQS]; unsigned int ppc_cached_irq_mask[NR_MASK_WORDS]; unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; @@ -248,6 +247,7 @@ len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename ); else len += sprintf(buf+len, " None "); + len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); len += sprintf(buf+len, " %s",action->name); for (action=action->next; action; action = action->next) { len += sprintf(buf+len, ", %s", action->name); @@ -368,12 +368,12 @@ printk("\n%s, CPU %d:\n", str, cpu); printk("irq: %d [%d %d]\n", atomic_read(&global_irq_count), - local_irq_count[0], - local_irq_count[1]); + local_irq_count(0), + local_irq_count(1)); printk("bh: %d [%d %d]\n", atomic_read(&global_bh_count), - local_bh_count[0], - local_bh_count[1]); + local_bh_count(0), + local_bh_count(1)); stack = (unsigned long *) &str; for (i = 40; i ; i--) { unsigned long x = *++stack; @@ -408,7 +408,7 @@ * already executing in one.. */ if (!atomic_read(&global_irq_count)) { - if (local_bh_count[cpu] + if (local_bh_count(cpu) || !atomic_read(&global_bh_count)) break; } @@ -430,7 +430,7 @@ continue; if (global_irq_lock) continue; - if (!local_bh_count[cpu] + if (!local_bh_count(cpu) && atomic_read(&global_bh_count)) continue; if (!test_and_set_bit(0,&global_irq_lock)) @@ -521,7 +521,7 @@ if (flags & (1 << 15)) { int cpu = smp_processor_id(); __cli(); - if (!local_irq_count[cpu]) + if (!local_irq_count(cpu)) get_irqlock(cpu); } } @@ -530,7 +530,7 @@ { int cpu = smp_processor_id(); - if (!local_irq_count[cpu]) + if (!local_irq_count(cpu)) release_irqlock(cpu); __sti(); } @@ -554,7 +554,7 @@ retval = 2 + local_enabled; /* check for global flags if we're not in an interrupt */ - if (!local_irq_count[smp_processor_id()]) { + if (!local_irq_count(smp_processor_id())) { if (local_enabled) retval = 1; if (global_irq_holder == (unsigned char) smp_processor_id()) diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/m8260_setup.c linux/arch/ppc/kernel/m8260_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/m8260_setup.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/m8260_setup.c Thu Jul 13 09:42:50 2000 @@ -44,7 +44,7 @@ #include #include -#include "time.h" +#include #include "ppc8260_pic.h" static int m8260_set_rtc_time(unsigned long time); diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/m8xx_setup.c linux/arch/ppc/kernel/m8xx_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/m8xx_setup.c Thu May 11 15:30:06 2000 +++ linux/arch/ppc/kernel/m8xx_setup.c Thu Jul 13 09:42:50 2000 @@ -45,7 +45,7 @@ #include #include -#include "time.h" +#include #include "ppc8xx_pic.h" static int m8xx_set_rtc_time(unsigned long time); diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S --- v2.4.0-test3/linux/arch/ppc/kernel/misc.S Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/misc.S Thu Jul 13 09:42:50 2000 @@ -1205,6 +1205,17 @@ .long sys_ni_syscall /* streams2 */ .long sys_vfork .long sys_getrlimit /* 190 */ - .rept NR_syscalls-190 + .long sys_ni_syscall /* 191 */ /* Unused */ + .long sys_ni_syscall /* 192 - reserved - mmap2 */ + .long sys_ni_syscall /* 193 - reserved - truncate64 */ + .long sys_ni_syscall /* 194 - reserved - ftruncate64 */ + .long sys_ni_syscall /* 195 - reserved - stat64 */ + .long sys_ni_syscall /* 196 - reserved - lstat64 */ + .long sys_ni_syscall /* 197 - reserved - fstat64 */ + .long sys_pciconfig_read /* 198 */ + .long sys_pciconfig_write /* 199 */ + .long sys_pciconfig_iobase /* 200 */ + .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ + .rept NR_syscalls-201 .long sys_ni_syscall .endr diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/oak_setup.c linux/arch/ppc/kernel/oak_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/oak_setup.c Thu Feb 10 17:11:04 2000 +++ linux/arch/ppc/kernel/oak_setup.c Thu Jul 13 09:42:50 2000 @@ -28,7 +28,7 @@ #include "local_irq.h" #include "ppc4xx_pic.h" -#include "time.h" +#include #include "oak_setup.h" diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/open_pic.c linux/arch/ppc/kernel/open_pic.c --- v2.4.0-test3/linux/arch/ppc/kernel/open_pic.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/open_pic.c Thu Jul 13 09:42:50 2000 @@ -261,12 +261,15 @@ while(np) { int j, pri; pri = strcmp(np->name, "programmer-switch") ? 2 : 7; - for (j=0;jn_intrs;j++) + for (j=0;jn_intrs;j++) { openpic_initirq( np->intrs[j].line, pri, np->intrs[j].line, - np->intrs[j].sense, + 0, np->intrs[j].sense); + if (np->intrs[j].sense) + irq_desc[np->intrs[j].line].status = IRQ_LEVEL; + } np = np->next; } } diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c --- v2.4.0-test3/linux/arch/ppc/kernel/pci.c Tue Mar 7 14:32:25 2000 +++ linux/arch/ppc/kernel/pci.c Thu Jul 13 09:42:50 2000 @@ -4,11 +4,14 @@ */ #include +#include #include #include #include #include #include +#include +#include #include #include @@ -19,6 +22,7 @@ #include #include #include +#include #include "pci.h" @@ -184,3 +188,146 @@ } return 0; } + +/* + * Those syscalls are derived from the Alpha versions, they + * allow userland apps to retreive the per-device iobase and + * mem-base. They also provide wrapper for userland to do + * config space accesses. + * The "host_number" returns the number of the Uni-N sub bridge + */ + +asmlinkage int +sys_pciconfig_read(unsigned long bus, unsigned long dfn, + unsigned long off, unsigned long len, + unsigned char *buf) +{ + unsigned char ubyte; + unsigned short ushort; + unsigned int uint; + long err = 0; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (!pcibios_present()) + return -ENOSYS; + + switch (len) { + case 1: + err = pcibios_read_config_byte(bus, dfn, off, &ubyte); + put_user(ubyte, buf); + break; + case 2: + err = pcibios_read_config_word(bus, dfn, off, &ushort); + put_user(ushort, (unsigned short *)buf); + break; + case 4: + err = pcibios_read_config_dword(bus, dfn, off, &uint); + put_user(uint, (unsigned int *)buf); + break; + default: + err = -EINVAL; + break; + } + return err; +} + +asmlinkage int +sys_pciconfig_write(unsigned long bus, unsigned long dfn, + unsigned long off, unsigned long len, + unsigned char *buf) +{ + unsigned char ubyte; + unsigned short ushort; + unsigned int uint; + long err = 0; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (!pcibios_present()) + return -ENOSYS; + + switch (len) { + case 1: + err = get_user(ubyte, buf); + if (err) + break; + err = pcibios_write_config_byte(bus, dfn, off, ubyte); + if (err != PCIBIOS_SUCCESSFUL) { + err = -EFAULT; + } + break; + case 2: + err = get_user(ushort, (unsigned short *)buf); + if (err) + break; + err = pcibios_write_config_word(bus, dfn, off, ushort); + if (err != PCIBIOS_SUCCESSFUL) { + err = -EFAULT; + } + break; + case 4: + err = get_user(uint, (unsigned int *)buf); + if (err) + break; + err = pcibios_write_config_dword(bus, dfn, off, uint); + if (err != PCIBIOS_SUCCESSFUL) { + err = -EFAULT; + } + break; + default: + err = -EINVAL; + break; + } + return err; +} + +void * +pci_dev_io_base(unsigned char bus, unsigned char devfn) +{ + /* Defaults to old way */ + if (!ppc_md.pci_dev_io_base) + return pci_io_base(bus); + return ppc_md.pci_dev_io_base(bus, devfn); +} + +void * +pci_dev_mem_base(unsigned char bus, unsigned char devfn) +{ + /* Default memory base is 0 (1:1 mapping) */ + if (!ppc_md.pci_dev_mem_base) + return 0; + return ppc_md.pci_dev_mem_base(bus, devfn); +} + +/* Returns the root-bridge number (Uni-N number) of a device */ +int +pci_dev_root_bridge(unsigned char bus, unsigned char devfn) +{ + /* Defaults to 0 */ + if (!ppc_md.pci_dev_root_bridge) + return 0; + return ppc_md.pci_dev_root_bridge(bus, devfn); +} + +/* Provide information on locations of various I/O regions in physical + * memory. Do this on a per-card basis so that we choose the right + * root bridge. + * Note that the returned IO or memory base is a physical address + */ + +asmlinkage long +sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) +{ + switch (which) { + case IOBASE_BRIDGE_NUMBER: + return (long)pci_dev_root_bridge(bus, devfn); + case IOBASE_MEMORY: + return (long)pci_dev_mem_base(bus, devfn); + case IOBASE_IO: + return (long)pci_dev_io_base(bus, devfn); + } + + return -EOPNOTSUPP; +} + diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/pmac_backlight.c linux/arch/ppc/kernel/pmac_backlight.c --- v2.4.0-test3/linux/arch/ppc/kernel/pmac_backlight.c Wed Dec 31 16:00:00 1969 +++ linux/arch/ppc/kernel/pmac_backlight.c Thu Jul 13 09:42:50 2000 @@ -0,0 +1,148 @@ +/* + * Miscellaneous procedures for dealing with the PowerMac hardware. + * Contains support for the backlight. + * + * Copyright (C) 2000 Benjamin Herrenschmidt + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static struct backlight_controller *backlighter = NULL; +static void* backlighter_data = NULL; +static int backlight_autosave = 0; +static int backlight_level = BACKLIGHT_MAX; +static int backlight_enabled = 1; + +void __pmac +register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type) +{ + struct device_node* bk_node; + char *prop; + int valid = 0; + + bk_node = find_devices("backlight"); + +#ifdef CONFIG_ADB_PMU + /* Special case for the old PowerBook since I can't test on it */ + if ((machine_is_compatible("AAPL,3400/2400") || machine_is_compatible("AAPL,3500") + || machine_is_compatible("AAPL,PowerBook1998") + || machine_is_compatible("AAPL,PowerBook1999")) + && !strcmp(type, "pmu")) + valid = 1; + else +#endif + { + if (bk_node) + prop = get_property(bk_node, "backlight-control", NULL); + if (prop && !strncmp(prop, type, strlen(type))) + valid = 1; + } + if (!valid) + return; + backlighter = ctrler; + backlighter_data = data; + + if (bk_node && !backlight_autosave) + prop = get_property(bk_node, "bklt", NULL); + else + prop = NULL; + if (prop) { + backlight_level = ((*prop)+1) >> 1; + if (backlight_level > BACKLIGHT_MAX) + backlight_level = BACKLIGHT_MAX; + } + +#ifdef CONFIG_ADB_PMU + backlight_autosave = machine_is_compatible("AAPL,3400/2400") + || machine_is_compatible("AAPL,3500"); + if (backlight_autosave) { + struct adb_request req; + pmu_request(&req, NULL, 2, 0xd9, 0); + while (!req.complete) + pmu_poll(); + backlight_level = req.reply[1] >> 4; + } +#endif + if (!backlighter->set_enable(1, backlight_level, data)) + backlight_enabled = 1; + + printk(KERN_INFO "Registered \"%s\" backlight controller, level: %d/15\n", + type, backlight_level); +} + +void __pmac +unregister_backlight_controller(struct backlight_controller *ctrler, void *data) +{ + /* We keep the current backlight level (for now) */ + if (ctrler == backlighter && data == backlighter_data) + backlighter = NULL; +} + +int __pmac +set_backlight_enable(int enable) +{ + int rc; + + if (!backlighter) + return -ENODEV; + rc = backlighter->set_enable(enable, backlight_level, backlighter_data); + if (!rc) + backlight_enabled = enable; + return rc; +} + +int __pmac +get_backlight_enable(void) +{ + if (!backlighter) + return -ENODEV; + return backlight_enabled; +} + +int __pmac +set_backlight_level(int level) +{ + int rc = 0; + + if (!backlighter) + return -ENODEV; + if (level < BACKLIGHT_MIN) + level = BACKLIGHT_OFF; + if (level > BACKLIGHT_MAX) + level = BACKLIGHT_MAX; + if (backlight_enabled) + rc = backlighter->set_level(level, backlighter_data); + if (!rc) + backlight_level = level; + if (!rc && !backlight_autosave) { + level <<=1; + if (level & 0x10) + level |= 0x01; + // -- todo: save to property "bklt" + } + return rc; +} + +int __pmac +get_backlight_level(void) +{ + if (!backlighter) + return -ENODEV; + return backlight_level; +} diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/pmac_nvram.c linux/arch/ppc/kernel/pmac_nvram.c --- v2.4.0-test3/linux/arch/ppc/kernel/pmac_nvram.c Thu May 11 15:30:06 2000 +++ linux/arch/ppc/kernel/pmac_nvram.c Thu Jul 13 09:42:50 2000 @@ -19,20 +19,8 @@ #undef DEBUG -/* - * Read and write the non-volatile RAM on PowerMacs and CHRP machines. - */ -static int nvram_naddrs; -static volatile unsigned char *nvram_addr; -static volatile unsigned char *nvram_data; -static int nvram_mult, is_core_99; -static char* nvram_image; -static int core99_bank = 0; - -extern int pmac_newworld; - #define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */ - + #define CORE99_SIGNATURE 0x5a #define CORE99_ADLER_START 0x14 @@ -60,8 +48,29 @@ u32 reserved[2]; }; +/* + * Read and write the non-volatile RAM on PowerMacs and CHRP machines. + */ +static int nvram_naddrs; +static volatile unsigned char *nvram_addr; +static volatile unsigned char *nvram_data; +static int nvram_mult, is_core_99; +static int core99_bank = 0; static int nvram_partitions[3]; +/* FIXME: kmalloc fails to allocate the image now that I had to move it + * before time_init(). For now, I allocate a static buffer here + * but it's a waste of space on all but core99 machines + */ +#if 0 +static char* nvram_image; +#else +__pmac static char nvram_image[NVRAM_SIZE]; +#endif + +extern int pmac_newworld; + + static u8 chrp_checksum(struct chrp_header* hdr) { @@ -189,6 +198,7 @@ hdr = (struct chrp_header *)buffer; offset = 0; + buffer[16] = 0; do { for (i=0;i<16;i++) buffer[i] = nvram_read_byte(offset+i); @@ -234,11 +244,13 @@ printk(KERN_ERR "nvram: no address\n"); return; } +#if 0 nvram_image = kmalloc(NVRAM_SIZE, GFP_KERNEL); if (!nvram_image) { printk(KERN_ERR "nvram: can't allocate image\n"); return; } +#endif nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); #ifdef DEBUG printk("nvram: Checking bank 0...\n"); @@ -267,6 +279,7 @@ printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n", nvram_naddrs); } + lookup_partitions(); } void diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c --- v2.4.0-test3/linux/arch/ppc/kernel/pmac_pci.c Thu May 11 15:30:06 2000 +++ linux/arch/ppc/kernel/pmac_pci.c Thu Jul 13 09:42:50 2000 @@ -34,6 +34,7 @@ struct device_node* node; volatile unsigned int* cfg_addr; volatile unsigned int* cfg_data; + void* iobase; }; static struct uninorth_data uninorth_bridges[3]; @@ -54,6 +55,7 @@ #define BANDIT_MAGIC 0x50 #define BANDIT_COHERENT 0x40 +/* Obsolete, should be replaced by pmac_pci_dev_io_base() (below) */ __pmac void *pci_io_base(unsigned int bus) { @@ -83,6 +85,72 @@ return 0; } +/* This routines figures out on which root bridge a given PCI device + * is attached. + */ +__pmac +int +pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn) +{ + struct device_node *node, *bridge_node; + int bridge = uninorth_default; + + if (uninorth_count == 0) + return 0; + if (bus == 0 && PCI_SLOT(dev_fn) < 11) + return 0; + + /* We look for the OF device corresponding to this bus/devfn pair. If we + * don't find it, we default to the external PCI */ + bridge_node = NULL; + node = find_pci_device_OFnode(bus, dev_fn & 0xf8); + if (node) { + /* note: we don't stop on the first occurence since we need to go + * up to the root bridge */ + do { + if (node->type && !strcmp(node->type, "pci") + && device_is_compatible(node, "uni-north")) + bridge_node = node; + node=node->parent; + } while (node); + } + if (bridge_node) { + int i; + for (i=0;itype, "pci")) - bridge_node = node; - node=node->parent; - } while (node); - } - if (bridge_node) { - int i; - for (i=0;iaddress + 0x800000, 0x1000); uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000); uninorth_bridges[i].node = dev; + uninorth_bridges[i].iobase = (void *)addr->address; /* XXX This is the bridge with the PCI expansion bus. This is also the * address of the bus that will receive type 1 config accesses and io * accesses. Appears to be correct for iMac DV and G4 Sawtooth too. diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c --- v2.4.0-test3/linux/arch/ppc/kernel/pmac_pic.c Thu May 11 15:30:06 2000 +++ linux/arch/ppc/kernel/pmac_pic.c Thu Jul 13 09:42:50 2000 @@ -61,14 +61,32 @@ openpic_enable_irq(irq_nr); } +static void pmac_openpic_ack_irq(unsigned int irq_nr) +{ + if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) + openpic_eoi(smp_processor_id()); + openpic_disable_irq(irq_nr); +} + +static void pmac_openpic_end_irq(unsigned int irq_nr) +{ + if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) + openpic_eoi(smp_processor_id()); + openpic_enable_irq(irq_nr); +} + struct hw_interrupt_type pmac_open_pic = { " OpenPIC ", NULL, NULL, pmac_openpic_unmask_irq, pmac_openpic_mask_irq, - pmac_openpic_mask_irq, - 0 + /* Theorically, the mask&ack should be NULL for OpenPIC. However, doing + * so shows tons of bogus interrupts coming in. + */ + pmac_openpic_ack_irq, + pmac_openpic_end_irq, + NULL }; static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) @@ -141,7 +159,8 @@ pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - 0 + pmac_unmask_irq, + NULL }; struct hw_interrupt_type gatwick_pic = { @@ -151,7 +170,8 @@ pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - 0 + pmac_unmask_irq, + NULL }; static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) @@ -199,17 +219,13 @@ } #endif /* CONFIG_SMP */ - /* Yeah, I know, this could be a separate get_irq function */ - if (has_openpic) - { + if (has_openpic) { irq = openpic_irq(smp_processor_id()); if (irq == OPENPIC_VEC_SPURIOUS) /* We get those when doing polled ADB requests, * using -2 is a temp hack to disable the printk */ irq = -2; /*-1; */ - else - openpic_eoi(smp_processor_id()); } else { diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/pmac_setup.c Thu May 11 15:30:06 2000 +++ linux/arch/ppc/kernel/pmac_setup.c Thu Jul 13 09:42:50 2000 @@ -62,17 +62,18 @@ #include #include -#include "time.h" +#include #include "local_irq.h" #include "pmac_pic.h" #undef SHOW_GATWICK_IRQS -unsigned long pmac_get_rtc_time(void); -int pmac_set_rtc_time(unsigned long nowtime); -void pmac_read_rtc_time(void); -void pmac_calibrate_decr(void); -void pmac_setup_pci_ptrs(void); +extern void pmac_time_init(void); +extern unsigned long pmac_get_rtc_time(void); +extern int pmac_set_rtc_time(unsigned long nowtime); +extern void pmac_read_rtc_time(void); +extern void pmac_calibrate_decr(void); +extern void pmac_setup_pci_ptrs(void); extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int mackbd_getkeycode(unsigned int scancode); @@ -91,6 +92,11 @@ extern char pckbd_unexpected_up(unsigned char keycode); extern void pckbd_leds(unsigned char leds); extern void pckbd_init_hw(void); +extern void pmac_nvram_update(void); + +extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn); +extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn); +extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn); unsigned char drive_info; @@ -98,6 +104,8 @@ int ppc_override_l2cr_value; int has_l2cache = 0; +static int current_root_goodness = -1; + extern char saved_command_line[]; extern int pmac_newworld; @@ -300,7 +308,9 @@ #ifdef CONFIG_ADB_PMU find_via_pmu(); #endif - +#ifdef CONFIG_NVRAM + pmac_nvram_init(); +#endif #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif @@ -364,27 +374,25 @@ init_uninorth(void) { /* - * Turns on the gmac clock so that it responds to PCI cycles - * later, the driver may want to turn it off again to save - * power when interface is down + * Turns OFF the gmac clock. The gmac driver will turn + * it back ON when the interface is enabled. This save + * power on portables. + * + * Note: We could also try to turn OFF the PHY. Since this + * has to be done by both the gmac driver and this code, + * I'll probably end-up moving some of this out of the + * modular gmac driver into a non-modular stub containing + * some basic PHY management and power management stuffs */ - struct device_node* uni_n = find_devices("uni-n"); struct device_node* gmac = find_devices("ethernet"); - unsigned long* addr; - - if (!uni_n || uni_n->n_addrs < 1) - return; - addr = ioremap(uni_n->addrs[0].address, 0x300); while(gmac) { if (device_is_compatible(gmac, "gmac")) break; gmac = gmac->next; } - if (gmac) { - *(addr + 8) |= 2; - eieio(); - } + if (gmac) + feature_set_gmac_power(gmac, 0); } extern char *bootpath; @@ -402,9 +410,6 @@ #ifdef CONFIG_ADB_PMU via_pmu_start(); #endif -#ifdef CONFIG_NVRAM - pmac_nvram_init(); -#endif #ifdef CONFIG_PMAC_PBOOK media_bay_init(); #endif @@ -476,13 +481,14 @@ /* can't be __init - can be called whenever a disk is first accessed */ __pmac -void note_bootable_part(kdev_t dev, int part) +void note_bootable_part(kdev_t dev, int part, int goodness) { static int found_boot = 0; char *p; /* Do nothing if the root has been set already. */ - if (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE)) + if ((goodness < current_root_goodness) && + (ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE))) return; p = strstr(saved_command_line, "root="); if (p != NULL && (p == saved_command_line || p[-1] == ' ')) @@ -495,7 +501,7 @@ if (boot_dev == 0 || dev == boot_dev) { ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part); boot_dev = NODEV; - printk(" (root on %d)", part); + current_root_goodness = goodness; } } @@ -666,10 +672,14 @@ ppc_md.power_off = pmac_power_off; ppc_md.halt = pmac_halt; - ppc_md.time_init = NULL; + ppc_md.time_init = pmac_time_init; ppc_md.set_rtc_time = pmac_set_rtc_time; ppc_md.get_rtc_time = pmac_get_rtc_time; ppc_md.calibrate_decr = pmac_calibrate_decr; + + ppc_md.pci_dev_io_base = pmac_pci_dev_io_base; + ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base; + ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge; #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) ppc_md.kbd_setkeycode = mackbd_setkeycode; diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/pmac_time.c linux/arch/ppc/kernel/pmac_time.c --- v2.4.0-test3/linux/arch/ppc/kernel/pmac_time.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/pmac_time.c Thu Jul 13 09:42:50 2000 @@ -26,7 +26,8 @@ #include #include -#include "time.h" +#include +#include extern rwlock_t xtime_lock; @@ -54,8 +55,30 @@ /* Bits in IFR and IER */ #define T1_INT 0x40 /* Timer 1 interrupt */ -__pmac +extern struct timezone sys_tz; + +__init +void pmac_time_init(void) +{ +#ifdef CONFIG_NVRAM + s32 delta = 0; + int dst; + + delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16; + delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8; + delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb); + if (delta & 0x00800000UL) + delta |= 0xFF000000UL; + dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0); + printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60, + dst ? "on" : "off"); + sys_tz.tz_minuteswest = -delta/60; + /* I _suppose_ this is 0:off, 1:on */ + sys_tz.tz_dsttime = dst; +#endif +} +__pmac unsigned long pmac_get_rtc_time(void) { #ifdef CONFIG_ADB @@ -95,7 +118,34 @@ int pmac_set_rtc_time(unsigned long nowtime) { - return 0; + struct adb_request req; + + nowtime += RTC_OFFSET - sys_tz.tz_minuteswest * 60; + + switch (sys_ctrler) { + case SYS_CTRLER_CUDA: + if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME, + nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) + return 0; + while (!req.complete) + cuda_poll(); +// if (req.reply_len != 7) + printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", + req.reply_len); + return 1; + case SYS_CTRLER_PMU: + if (pmu_request(&req, NULL, 5, PMU_SET_RTC, + nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0) + return 0; + while (!req.complete) + pmu_poll(); + if (req.reply_len != 5) + printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", + req.reply_len); + return 1; + default: + return 0; + } } /* diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c --- v2.4.0-test3/linux/arch/ppc/kernel/ppc_ksyms.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/ppc_ksyms.c Thu Jul 13 09:42:50 2000 @@ -35,10 +35,11 @@ #include #include #include +#include #ifdef CONFIG_SMP #include #endif /* CONFIG_SMP */ -#include "time.h" +#include /* Tell string.h we don't want memcpy etc. as cpp defines */ #define EXPORT_SYMTAB_STROPS @@ -76,8 +77,7 @@ EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(disable_irq_nosync); -EXPORT_SYMBOL(local_irq_count); -EXPORT_SYMBOL(local_bh_count); +EXPORT_SYMBOL(irq_stat); #ifdef CONFIG_SMP EXPORT_SYMBOL(kernel_flag); #endif /* CONFIG_SMP */ @@ -96,6 +96,10 @@ EXPORT_SYMBOL(ucSystemType); #endif #endif +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pci_dev_io_base); +EXPORT_SYMBOL(pci_dev_mem_base); +#endif #if !__INLINE_BITOPS EXPORT_SYMBOL(set_bit); @@ -234,6 +238,9 @@ EXPORT_SYMBOL(feature_set); EXPORT_SYMBOL(feature_clear); EXPORT_SYMBOL(feature_test); +EXPORT_SYMBOL(feature_set_gmac_power); +EXPORT_SYMBOL(feature_set_usb_power); +EXPORT_SYMBOL(feature_set_firewire_power); #endif /* defined(CONFIG_ALL_PPC) */ #if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(note_scsi_host); @@ -242,7 +249,13 @@ #ifdef CONFIG_NVRAM EXPORT_SYMBOL(nvram_read_byte); EXPORT_SYMBOL(nvram_write_byte); +EXPORT_SYMBOL(pmac_xpram_read); +EXPORT_SYMBOL(pmac_xpram_write); #endif /* CONFIG_NVRAM */ +#ifdef CONFIG_PPC_RTC +EXPORT_SYMBOL(mktime); +EXPORT_SYMBOL(to_tm); +#endif EXPORT_SYMBOL_NOVERS(__ashrdi3); EXPORT_SYMBOL_NOVERS(__ashldi3); diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/prep_setup.c Wed Apr 26 16:34:07 2000 +++ linux/arch/ppc/kernel/prep_setup.c Thu Jul 13 09:42:50 2000 @@ -49,7 +49,7 @@ #include #include -#include "time.h" +#include #include "local_irq.h" #include "i8259.h" #include "open_pic.h" diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/prep_time.c linux/arch/ppc/kernel/prep_time.c --- v2.4.0-test3/linux/arch/ppc/kernel/prep_time.c Tue Aug 31 17:29:13 1999 +++ linux/arch/ppc/kernel/prep_time.c Thu Jul 13 09:42:50 2000 @@ -27,7 +27,7 @@ #include #include -#include "time.h" +#include /* * The motorola uses the m48t18 rtc (includes DS1643) whose registers diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c --- v2.4.0-test3/linux/arch/ppc/kernel/prom.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/prom.c Thu Jul 13 09:42:50 2000 @@ -118,10 +118,16 @@ #ifdef CONFIG_BOOTX_TEXT +#define NO_SCROLL + static void clearscreen(void); static void flushscreen(void); +#ifndef NO_SCROLL static void scrollscreen(void); +#endif + +static void prepare_disp_BAT(void); static void draw_byte(unsigned char c, long locX, long locY); static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb); @@ -134,6 +140,9 @@ static long g_max_loc_X = 0; static long g_max_loc_Y = 0; +unsigned long disp_BATL = 0; +unsigned long disp_BATU = 0; + #define cmapsz (16*256) static unsigned char vga_font[cmapsz]; @@ -473,9 +482,10 @@ } #ifdef CONFIG_BOOTX_TEXT + prepare_disp_BAT(); prom_drawstring(RELOC("booting...\n")); flushscreen(); - RELOC(bootx_text_mapped) = 0; + RELOC(bootx_text_mapped) = 1; #endif } @@ -748,11 +758,15 @@ #ifdef CONFIG_BOOTX_TEXT if (!chrp && RELOC(disp_bi)) { + RELOC(prom_stdout) = 0; /* stop OF output */ clearscreen(); + prepare_disp_BAT(); prom_welcome(PTRRELOC(RELOC(disp_bi)), phys); prom_drawstring(RELOC("booting...\n")); + RELOC(bootx_text_mapped) = 1; + } else { + RELOC(bootx_text_mapped) = 0; } - RELOC(bootx_text_mapped) = 0; #endif prom_print(RELOC("returning from prom_init\n")); @@ -820,6 +834,45 @@ } prom_drawstring(RELOC("\n\n")); } + +/* Calc BAT values for mapping the display and store them + * in disp_BATH and disp_BATL. Those values are then used + * from head.S to map the display during identify_machine() + * and MMU_Init() + * + * For now, the display is mapped in place (1:1). This should + * be changed if the display physical address overlaps + * KERNELBASE, which is fortunately not the case on any machine + * I know of. This mapping is temporary and will disappear as + * soon as the setup done by MMU_Init() is applied + * + * For now, we align the BAT and then map 8Mb on 601 and 16Mb + * on other PPCs. This may cause trouble if the framebuffer + * is really badly aligned, but I didn't encounter this case + * yet. + */ +__init +static void +prepare_disp_BAT(void) +{ + unsigned long offset = reloc_offset(); + boot_infos_t* bi = PTRRELOC(RELOC(disp_bi)); + unsigned long addr = (unsigned long)bi->dispDeviceBase; + + if ((_get_PVR() >> 16) != 1) { + /* 603, 604, G3, G4, ... */ + addr &= 0xFF000000UL; + RELOC(disp_BATU) = addr | (BL_16M<<2) | 2; + RELOC(disp_BATL) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW); + } else { + /* 601 */ + addr &= 0xFF800000UL; + RELOC(disp_BATU) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4; + RELOC(disp_BATL) = addr | BL_8M | 0x40; + } + bi->logicalDisplayBase = bi->dispDeviceBase; +} + #endif static int prom_set_color(ihandle ih, int i, int r, int g, int b) @@ -1133,14 +1186,14 @@ /* All newworld machines now use the interrupt tree */ struct device_node *np = allnodes; - while(np) { + while(np && (_machine == _MACH_Pmac)) { if (get_property(np, "interrupt-parent", 0)) { pmac_newworld = 1; break; } np = np->allnext; } - if (boot_infos == 0 && pmac_newworld) + if ((_machine == _MACH_chrp) || (boot_infos == 0 && pmac_newworld)) use_of_interrupt_tree = 1; mem = finish_node(allnodes, mem, NULL, 0, 0); @@ -1746,8 +1799,17 @@ int l; for (np = allnodes; np != 0; np = np->allnext) { - if (np->parent == NULL || np->parent->type == NULL - || strcmp(np->parent->type, "pci") != 0) + int in_macio = 0; + struct device_node* parent = np->parent; + while(parent) { + char *pname = (char *)get_property(parent, "name", &l); + if (pname && strcmp(pname, "mac-io") == 0) { + in_macio = 1; + break; + } + parent = parent->parent; + } + if (in_macio) continue; reg = (unsigned int *) get_property(np, "reg", &l); if (reg == 0 || l < sizeof(struct reg_property)) @@ -2014,11 +2076,14 @@ void map_bootx_text(void) { + unsigned long base, offset, size; if (disp_bi == 0) return; - disp_bi->logicalDisplayBase = - ioremap((unsigned long) disp_bi->dispDeviceBase, - disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3]); + base = ((unsigned long) disp_bi->dispDeviceBase) & 0xFFFFF000UL; + offset = ((unsigned long) disp_bi->dispDeviceBase) - base; + size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset + + disp_bi->dispDeviceRect[0]; + disp_bi->logicalDisplayBase = ioremap(base, size) + offset; bootx_text_mapped = 1; } @@ -2084,6 +2149,7 @@ } } +#ifndef NO_SCROLL __pmac static void scrollscreen(void) @@ -2113,6 +2179,7 @@ dst += (bi->dispDeviceRowBytes >> 2); } } +#endif /* ndef NO_SCROLL */ __pmac void @@ -2148,7 +2215,7 @@ RELOC(g_loc_Y)++; cline = 1; } -#if 0 +#ifndef NO_SCROLL while (RELOC(g_loc_Y) >= RELOC(g_max_loc_Y)) { scrollscreen(); RELOC(g_loc_Y)--; diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/setup.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/setup.c Thu Jul 13 09:42:50 2000 @@ -75,9 +75,6 @@ unsigned long r6, unsigned long r7); -#ifdef CONFIG_BOOTX_TEXT -extern void map_bootx_text(void); -#endif #ifdef CONFIG_XMON extern void xmon_map_scc(void); #endif @@ -110,6 +107,14 @@ struct machdep_calls ppc_md; /* + * These are used in binfmt_elf.c to put aux entries on the stack + * for each elf executable being started. + */ +int dcache_bsize; +int icache_bsize; +int ucache_bsize; + +/* * Perhaps we can put the pmac screen_info[] here * on pmac as well so we don't need the ifdef's. * Until we get multiple-console support in here @@ -131,14 +136,6 @@ }; /* - * These are used in binfmt_elf.c to put aux entries on the stack - * for each elf executable being started. - */ -int dcache_bsize; -int icache_bsize; -int ucache_bsize; - -/* * I really need to add multiple-console support... -- Cort */ int __init pmac_display_supported(char *name) @@ -286,7 +283,7 @@ case 0x000C: len += sprintf(len+buffer, "7400 (G4"); #ifdef CONFIG_ALTIVEC - len += sprintf(len+buffer, ", altivec enabled"); + len += sprintf(len+buffer, ", altivec supported"); #endif /* CONFIG_ALTIVEC */ len += sprintf(len+buffer, ")\n"); break; @@ -686,14 +683,9 @@ extern char *klimit; extern void do_init_bootmem(void); -#ifdef CONFIG_BOOTX_TEXT - map_bootx_text(); -#endif - #ifdef CONFIG_ALL_PPC feature_init(); #endif - #ifdef CONFIG_XMON xmon_map_scc(); if (strstr(cmd_line, "xmon")) diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c --- v2.4.0-test3/linux/arch/ppc/kernel/signal.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/signal.c Thu Jul 13 09:42:50 2000 @@ -1,8 +1,6 @@ /* * linux/arch/ppc/kernel/signal.c * - * $Id: signal.c,v 1.27 1999/08/03 19:16:38 cort Exp $ - * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -156,13 +154,6 @@ } -asmlinkage int sys_rt_sigreturn(unsigned long __unused) -{ - printk("sys_rt_sigreturn(): %s/%d not yet implemented.\n", - current->comm,current->pid); - do_exit(SIGSEGV); -} - asmlinkage int sys_sigaltstack(const stack_t *uss, stack_t *uoss) { @@ -206,13 +197,11 @@ * When we have signals to deliver, we set up on the * user stack, going down from the original stack pointer: * a sigregs struct - * one or more sigcontext structs + * one or more sigcontext structs with * a gap of __SIGNAL_FRAMESIZE bytes * * Each of these things must be a multiple of 16 bytes in size. * - * XXX ultimately we will have to stack up a siginfo and ucontext - * for each rt signal. */ struct sigregs { elf_gregset_t gp_regs; @@ -223,6 +212,149 @@ int abigap[56]; }; +struct rt_sigframe +{ + unsigned long _unused[2]; + struct siginfo *pinfo; + void *puc; + struct siginfo info; + struct ucontext uc; +}; + + +/* + * When we have rt signals to deliver, we set up on the + * user stack, going down from the original stack pointer: + * a sigregs struct + * one rt_sigframe struct (siginfo + ucontext) + * a gap of __SIGNAL_FRAMESIZE bytes + * + * Each of these things must be a multiple of 16 bytes in size. + * + */ +asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +{ + struct rt_sigframe *rt_sf; + struct sigcontext_struct sigctx; + struct sigregs *sr; + int ret; + elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */ + sigset_t set; + stack_t st; + unsigned long prevsp; + + rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); + if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx)) + || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set)) + || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st))) + goto badframe; + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + rt_sf++; /* Look at next rt_sigframe */ + if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) { + /* Last stacked signal - restore registers - + * sigctx is initialized to point to the + * preamble frame (where registers are stored) + * see handle_signal() + */ + sr = (struct sigregs *) sigctx.regs; + if (regs->msr & MSR_FP ) + giveup_fpu(current); + if (copy_from_user(saved_regs, &sr->gp_regs, + sizeof(sr->gp_regs))) + goto badframe; + saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE) + | (saved_regs[PT_MSR] & MSR_USERCHANGE); + memcpy(regs, saved_regs, GP_REGS_SIZE); + if (copy_from_user(current->thread.fpr, &sr->fp_regs, + sizeof(sr->fp_regs))) + goto badframe; + /* This function sets back the stack flags into + the current task structure. */ + sys_sigaltstack(&st, NULL); + + ret = regs->result; + } else { + /* More signals to go */ + /* Set up registers for next signal handler */ + regs->gpr[1] = (unsigned long)rt_sf - __SIGNAL_FRAMESIZE; + if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))) + goto badframe; + sr = (struct sigregs *) sigctx.regs; + regs->gpr[3] = ret = sigctx.signal; + /* Get the siginfo */ + get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo); + /* Get the ucontext */ + get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc); + regs->gpr[6] = (unsigned long) rt_sf; + + regs->link = (unsigned long) &sr->tramp; + regs->nip = sigctx.handler; + if (get_user(prevsp, &sr->gp_regs[PT_R1]) + || put_user(prevsp, (unsigned long *) regs->gpr[1])) + goto badframe; + } + return ret; + +badframe: + lock_kernel(); + do_exit(SIGSEGV); +} + +static void +setup_rt_frame(struct pt_regs *regs, struct sigregs *frame, + signed long newsp) +{ + struct rt_sigframe *rt_sf = (struct rt_sigframe *) newsp; + + /* Set up preamble frame */ + if (verify_area(VERIFY_WRITE, frame, sizeof(*frame))) + goto badframe; + if (regs->msr & MSR_FP) + giveup_fpu(current); + if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE) + || __copy_to_user(&frame->fp_regs, current->thread.fpr, + ELF_NFPREG * sizeof(double)) + /* Set up to return from user space. + It calls the sc exception at offset 0x9999 + for sys_rt_sigreturn(). + */ + || __put_user(0x38006666UL, &frame->tramp[0]) /* li r0,0x6666 */ + || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */ + goto badframe; + flush_icache_range((unsigned long) &frame->tramp[0], + (unsigned long) &frame->tramp[2]); + + /* Retrieve rt_sigframe from stack and + set up registers for signal handler + */ + newsp -= __SIGNAL_FRAMESIZE; + if (put_user(regs->gpr[1], (unsigned long *)newsp) + || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler) + || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal) + || get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo) + || get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc)) + goto badframe; + + regs->gpr[1] = newsp; + regs->gpr[6] = (unsigned long) rt_sf; + regs->link = (unsigned long) frame->tramp; + + return; + +badframe: +#if DEBUG_SIG + printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n", + regs, frame, newsp); +#endif + lock_kernel(); + do_exit(SIGSEGV); +} + /* * Do a signal return; undo the signal stack. */ @@ -341,6 +473,7 @@ unsigned long *newspp, unsigned long frame) { struct sigcontext_struct *sc; + struct rt_sigframe *rt_sf; if (regs->trap == 0x0C00 /* System Call! */ && ((int)regs->result == -ERESTARTNOHAND || @@ -348,20 +481,47 @@ !(ka->sa.sa_flags & SA_RESTART)))) regs->result = -EINTR; - /* Put another sigcontext on the stack */ - *newspp -= sizeof(*sc); - sc = (struct sigcontext_struct *) *newspp; - if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) - goto badframe; + /* Set up Signal Frame */ + if (ka->sa.sa_flags & SA_SIGINFO) { + /* Put a Real Time Context onto stack */ + *newspp -= sizeof(*rt_sf); + rt_sf = (struct rt_sigframe *) *newspp; + if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf))) + goto badframe; - if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler) - || __put_user(oldset->sig[0], &sc->oldmask) + if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler) + || __put_user(&rt_sf->info, &rt_sf->pinfo) + || __put_user(&rt_sf->uc, &rt_sf->puc) + /* Put the siginfo */ + || __copy_to_user(&rt_sf->info, info, sizeof(*info)) + /* Create the ucontext */ + || __put_user(0, &rt_sf->uc.uc_flags) + || __put_user(0, &rt_sf->uc.uc_link) + || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) + || __put_user(sas_ss_flags(regs->gpr[1]), + &rt_sf->uc.uc_stack.ss_flags) + || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) + || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset)) + /* mcontext.regs points to preamble register frame */ + || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs) + || __put_user(sig, &rt_sf->uc.uc_mcontext.signal)) + goto badframe; + } else { + /* Put another sigcontext on the stack */ + *newspp -= sizeof(*sc); + sc = (struct sigcontext_struct *) *newspp; + if (verify_area(VERIFY_WRITE, sc, sizeof(*sc))) + goto badframe; + + if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler) + || __put_user(oldset->sig[0], &sc->oldmask) #if _NSIG_WORDS > 1 - || __put_user(oldset->sig[1], &sc->_unused[3]) + || __put_user(oldset->sig[1], &sc->_unused[3]) #endif - || __put_user((struct pt_regs *)frame, &sc->regs) - || __put_user(sig, &sc->signal)) - goto badframe; + || __put_user((struct pt_regs *)frame, &sc->regs) + || __put_user(sig, &sc->signal)) + goto badframe; + } if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; @@ -517,7 +677,10 @@ if (newsp == frame) return 0; /* no signals delivered */ - setup_frame(regs, (struct sigregs *) frame, newsp); + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(regs, (struct sigregs *) frame, newsp); + else + setup_frame(regs, (struct sigregs *) frame, newsp); return 1; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c --- v2.4.0-test3/linux/arch/ppc/kernel/smp.c Mon Jul 10 16:47:20 2000 +++ linux/arch/ppc/kernel/smp.c Thu Jul 13 09:42:50 2000 @@ -39,7 +39,7 @@ #include #include -#include "time.h" +#include #include "open_pic.h" int smp_threads_ready = 0; volatile int smp_commenced = 0; diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c --- v2.4.0-test3/linux/arch/ppc/kernel/syscalls.c Mon Jul 10 16:47:20 2000 +++ linux/arch/ppc/kernel/syscalls.c Thu Jul 13 09:42:50 2000 @@ -274,3 +274,13 @@ error = error ? -EFAULT : 0; return error; } + +#ifndef CONFIG_PCI +/* + * Those are normally defined in arch/ppc/kernel/pci.c. But when CONFIG_PCI is + * not defined, this file is not linked at all, so here are the "empty" versions + */ +asmlinkage int sys_pciconfig_read() { return -ENOSYS; } +asmlinkage int sys_pciconfig_write() { return -ENOSYS; } +asmlinkage long sys_pciconfig_iobase() { return -ENOSYS; } +#endif diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c --- v2.4.0-test3/linux/arch/ppc/kernel/time.c Fri Jun 23 21:55:07 2000 +++ linux/arch/ppc/kernel/time.c Thu Jul 13 09:42:50 2000 @@ -44,7 +44,7 @@ #include #include -#include "time.h" +#include void smp_local_timer_interrupt(struct pt_regs *); @@ -70,7 +70,9 @@ int timer_interrupt(struct pt_regs * regs) { int dval, d; +#if 0 unsigned long flags; +#endif unsigned long cpu = smp_processor_id(); hardirq_enter(cpu); @@ -120,6 +122,13 @@ if ( !smp_processor_id() ) { do_timer(regs); +#if 0 + /* -- BenH -- I'm removing this for now since it can cause various + * troubles with local-time RTCs. Now that we have a + * /dev/rtc that uses ppc_md.set_rtc_time() on mac, it + * should be possible to program the RTC from userland + * in all cases. + */ /* * update the rtc when needed */ @@ -135,6 +144,7 @@ last_rtc_update = xtime.tv_sec; } read_unlock_irqrestore(&xtime_lock, flags); +#endif } #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/time.h linux/arch/ppc/kernel/time.h --- v2.4.0-test3/linux/arch/ppc/kernel/time.h Tue Jan 11 22:31:38 2000 +++ linux/arch/ppc/kernel/time.h Wed Dec 31 16:00:00 1969 @@ -1,42 +0,0 @@ -/* - * $Id: time.h,v 1.12 1999/08/27 04:21:23 cort Exp $ - * Common time prototypes and such for all ppc machines. - * - * Written by Cort Dougan (cort@cs.nmt.edu) to merge - * Paul Mackerras' version and mine for PReP and Pmac. - */ - -#include -#include - -#include - -/* time.c */ -extern unsigned decrementer_count; -extern unsigned count_period_num; -extern unsigned count_period_den; -extern unsigned long mktime(unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, unsigned int); -extern void to_tm(int tim, struct rtc_time * tm); -extern time_t last_rtc_update; - -int via_calibrate_decr(void); - -/* Accessor functions for the decrementer register. */ -static __inline__ unsigned int get_dec(void) -{ -#if defined(CONFIG_4xx) - return (mfspr(SPRN_PIT)); -#else - return (mfspr(SPRN_DEC)); -#endif -} - -static __inline__ void set_dec(unsigned int val) -{ -#if defined(CONFIG_4xx) - mtspr(SPRN_PIT, val); -#else - mtspr(SPRN_DEC, val); -#endif -} diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/kernel/walnut_setup.c linux/arch/ppc/kernel/walnut_setup.c --- v2.4.0-test3/linux/arch/ppc/kernel/walnut_setup.c Thu Feb 10 17:11:05 2000 +++ linux/arch/ppc/kernel/walnut_setup.c Thu Jul 13 09:42:51 2000 @@ -28,7 +28,7 @@ #include "local_irq.h" #include "ppc4xx_pic.h" -#include "time.h" +#include #include "walnut_setup.h" diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/mbxboot/m8xx_tty.c linux/arch/ppc/mbxboot/m8xx_tty.c --- v2.4.0-test3/linux/arch/ppc/mbxboot/m8xx_tty.c Sat Oct 9 11:47:50 1999 +++ linux/arch/ppc/mbxboot/m8xx_tty.c Thu Jul 13 09:42:51 2000 @@ -21,6 +21,17 @@ #define CSR1_COMEN (u_char)0x02 #endif +#ifdef TQM_SMC2_CONSOLE +#define PROFF_CONS PROFF_SMC2 +#define CPM_CR_CH_CONS CPM_CR_CH_SMC2 +#define SMC_INDEX 1 +static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport); +#else +#define PROFF_CONS PROFF_SMC1 +#define CPM_CR_CH_CONS CPM_CR_CH_SMC1 +#define SMC_INDEX 0 +#endif + static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); void @@ -33,8 +44,8 @@ uint dpaddr, memaddr; cp = cpmp; - sp = (smc_t*)&(cp->cp_smc[0]); - up = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; + sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); + up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS]; /* Disable transmitter/receiver. */ @@ -42,18 +53,26 @@ #ifndef CONFIG_MBX { - /* Initialize SMC1 and use it for the console port. + /* Initialize SMCx and use it for the console port. */ /* Enable SDMA. */ ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; +#ifdef TQM_SMC2_CONSOLE + /* Use Port A for SMC2 instead of other functions. + */ + iopp->iop_papar |= 0x00c0; + iopp->iop_padir &= ~0x00c0; + iopp->iop_paodr &= ~0x00c0; +#else /* Use Port B for SMCs instead of other functions. */ cp->cp_pbpar |= 0x00000cc0; cp->cp_pbdir &= ~0x00000cc0; cp->cp_pbodr &= ~0x00000cc0; +#endif /* Allocate space for two buffer descriptors in the DP ram. * For now, this address seems OK, but it may have to @@ -61,8 +80,7 @@ */ dpaddr = 0x0800; - /* Grab a few bytes from the top of memory. EPPC-Bug isn't - * running any more, so we can do this. + /* Grab a few bytes from the top of memory for SMC FIFOs. */ memaddr = (bd->bi_memsize - 32) & ~15; @@ -95,9 +113,14 @@ /* Set up the baud rate generator. * See 8xx_io/commproc.c for details. + * This wires BRG1 to SMC1 and BRG2 to SMC2; */ cp->cp_simode = 0x10000000; +#ifdef TQM_SMC2_CONSOLE + cp->cp_brgc2 = +#else cp->cp_brgc1 = +#endif ((((bd->bi_intfreq * 1000000)/16) / bd->bi_baudrate) << 1) | CPM_BRG_EN; #else /* CONFIG_MBX */ @@ -167,14 +190,14 @@ } else { #endif /* ndef CONFIG_MBX */ - /* SMC1 is used as console port. + /* SMCx is used as console port. */ tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; /* Issue a stop transmit, and wait for it. */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_STOP_TX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); } @@ -191,7 +214,7 @@ /* Initialize Tx/Rx parameters. */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_SMC1, CPM_CR_INIT_TRX) | CPM_CR_FLG; + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; while (cp->cp_cpcr & CPM_CR_FLG); /* Enable transmitter/receiver. @@ -206,7 +229,7 @@ volatile char *buf; volatile smc_uart_t *up; - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; + up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; /* Wait for last character to go. @@ -227,7 +250,7 @@ volatile smc_uart_t *up; char c; - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; + up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; /* Wait for character to show up. @@ -246,7 +269,7 @@ volatile cbd_t *rbdf; volatile smc_uart_t *up; - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_SMC1]; + up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; return(!(rbdf->cbd_sc & BD_SC_EMPTY)); diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/mbxboot/misc.c linux/arch/ppc/mbxboot/misc.c --- v2.4.0-test3/linux/arch/ppc/mbxboot/misc.c Tue May 23 15:31:34 2000 +++ linux/arch/ppc/mbxboot/misc.c Thu Jul 13 09:42:51 2000 @@ -225,7 +225,9 @@ s.avail_out = dstlen; r = inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { - puts("inflate returned %d\n"); + puts("inflate returned "); + puthex(r); + puts("\n"); exit(); } *lenp = s.next_out - (unsigned char *) dst; diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c --- v2.4.0-test3/linux/arch/ppc/mm/init.c Fri Jun 23 21:55:08 2000 +++ linux/arch/ppc/mm/init.c Thu Jul 13 09:42:51 2000 @@ -931,6 +931,9 @@ /* How about ppc_md.md_find_end_of_memory instead of these * ifdefs? -- Dan. */ +#ifdef CONFIG_BOOTX_TEXT +extern boot_infos_t *disp_bi; +#endif void __init MMU_init(void) { if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); @@ -1050,6 +1053,11 @@ #endif #endif /* CONFIG_8xx */ if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); +#ifdef CONFIG_BOOTX_TEXT + /* Must be done last, or ppc_md.progress will die */ + if (_machine == _MACH_Pmac) + map_bootx_text(); +#endif } #endif /* CONFIG_4xx */ diff -u --recursive --new-file v2.4.0-test3/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c --- v2.4.0-test3/linux/arch/ppc/xmon/xmon.c Fri Jun 23 21:55:08 2000 +++ linux/arch/ppc/xmon/xmon.c Thu Jul 13 09:42:51 2000 @@ -84,8 +84,10 @@ static struct bpt *at_breakpoint(unsigned pc); static void bpt_cmds(void); static void cacheflush(void); +#if 0 /* Makes compile with -Wall */ static char *pretty_print_addr(unsigned long addr); static char *lookup_name(unsigned long addr); +#endif static void csum(void); extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned); @@ -1493,6 +1495,7 @@ lineptr = str; } +#if 0 /* Makes compile with -Wall */ static char *pretty_print_addr(unsigned long addr) { printf("%08x", addr); @@ -1500,14 +1503,15 @@ printf(" %s", lookup_name(addr) ); return NULL; } +#endif +#if 0 /* Makes compile with -Wall */ static char *lookup_name(unsigned long addr) { extern char *sysmap; extern unsigned long sysmap_size; char *c = sysmap; unsigned long cmp; - if ( !sysmap || !sysmap_size ) return NULL; return NULL; @@ -1525,4 +1529,4 @@ return last; #endif } - +#endif diff -u --recursive --new-file v2.4.0-test3/linux/arch/s390/config.in linux/arch/s390/config.in --- v2.4.0-test3/linux/arch/s390/config.in Mon Jul 10 16:47:20 2000 +++ linux/arch/s390/config.in Wed Jul 12 15:12:11 2000 @@ -14,21 +14,21 @@ endmenu mainmenu_option next_comment -comment 'Processor type and features' -bool 'Symmetric multi-processing support' CONFIG_SMP -bool 'IEEE FPU emulation' CONFIG_IEEEFPU_EMULATION -endmenu - -mainmenu_option next_comment comment 'Loadable module support' bool 'Enable loadable module support' CONFIG_MODULES if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD fi endmenu mainmenu_option next_comment +comment 'Processor type and features' +bool 'Symmetric multi-processing support' CONFIG_SMP +bool 'IEEE FPU emulation' CONFIG_IEEEFPU_EMULATION +endmenu + +mainmenu_option next_comment comment 'General setup' bool 'Fast IRQ handling' CONFIG_FAST_IRQ bool 'Builtin IPL record support' CONFIG_IPL @@ -56,9 +56,6 @@ fi source fs/Config.in - -# Not sure about this one. dwmw2 -# source drivers/mtd/Config.in # source drivers/char/Config.in diff -u --recursive --new-file v2.4.0-test3/linux/arch/sh/config.in linux/arch/sh/config.in --- v2.4.0-test3/linux/arch/sh/config.in Mon Jul 10 16:47:20 2000 +++ linux/arch/sh/config.in Wed Jul 12 15:12:11 2000 @@ -14,6 +14,15 @@ endmenu mainmenu_option next_comment +comment 'Loadable module support' +bool 'Enable loadable module support' CONFIG_MODULES +if [ "$CONFIG_MODULES" = "y" ]; then + bool ' Set version information on all module symbols' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD +fi +endmenu + +mainmenu_option next_comment comment 'Processor type and features' choice 'SuperH system type' \ "Generic CONFIG_SH_GENERIC \ @@ -44,15 +53,6 @@ else hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 hex 'I/O port offset address' CONFIG_IOPORT_START ba000000 -fi -endmenu - -mainmenu_option next_comment -comment 'Loadable module support' -bool 'Enable loadable module support' CONFIG_MODULES -if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD fi endmenu diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/defconfig linux/arch/sparc/defconfig --- v2.4.0-test3/linux/arch/sparc/defconfig Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/defconfig Tue Jul 11 19:02:37 2000 @@ -300,7 +300,7 @@ CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m -CONFIG_NCP_FS=m +# CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set # CONFIG_NCPFS_STRONG is not set diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/pcic.c linux/arch/sparc/kernel/pcic.c --- v2.4.0-test3/linux/arch/sparc/kernel/pcic.c Fri Jun 23 21:55:08 2000 +++ linux/arch/sparc/kernel/pcic.c Tue Jul 11 19:01:59 2000 @@ -1,4 +1,4 @@ -/* $Id: pcic.c,v 1.15 2000/06/20 01:10:00 anton Exp $ +/* $Id: pcic.c,v 1.16 2000/07/11 01:38:57 davem Exp $ * pcic.c: Sparc/PCI controller support * * Copyright (C) 1998 V. Roganov and G. Raiko @@ -808,7 +808,7 @@ return offset + count; } -extern volatile unsigned long lost_ticks; +extern volatile unsigned long wall_jiffies; static void pci_do_gettimeofday(struct timeval *tv) { @@ -819,10 +819,11 @@ tv->tv_usec += do_gettimeoffset(); /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. + * xtime is atomically updated in timer_bh. The difference + * between jiffies and wall_jiffies is nonzero if the timer + * bottom half hasnt executed yet. */ - if (lost_ticks) + if ((jiffies - wall_jiffies) != 0) tv->tv_usec += USECS_PER_JIFFY; restore_flags(flags); diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c --- v2.4.0-test3/linux/arch/sparc/kernel/process.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/kernel/process.c Tue Jul 11 19:02:37 2000 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.147 2000/05/09 17:40:13 davem Exp $ +/* $Id: process.c,v 1.151 2000/07/11 23:22:17 davem Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -109,7 +109,7 @@ int cpu_idle(void) { /* endless idle loop with no priority at all */ - current->priority = 0; + current->nice = 20; current->counter = -100; init_idle(); @@ -126,9 +126,10 @@ extern char reboot_command []; +extern int serial_console; + #ifdef CONFIG_SUN_CONSOLE extern void (*prom_palette)(int); -extern int serial_console; #endif void machine_halt(void) @@ -169,7 +170,7 @@ void machine_power_off(void) { #ifdef CONFIG_SUN_AUXIO - if (auxio_power_register) + if (auxio_power_register && !serial_console) *auxio_power_register |= AUXIO_POWER_OFF; #endif machine_halt(); @@ -233,6 +234,7 @@ void smp_show_backtrace_all_cpus(void) { xc0((smpfunc_t) show_backtrace); + show_backtrace(); } #endif diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/smp.c linux/arch/sparc/kernel/smp.c --- v2.4.0-test3/linux/arch/sparc/kernel/smp.c Fri Jan 28 15:09:07 2000 +++ linux/arch/sparc/kernel/smp.c Tue Jul 11 11:07:55 2000 @@ -143,31 +143,37 @@ } void smp_flush_cache_all(void) -{ xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); } +{ + xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all)); + local_flush_cache_all(); +} void smp_flush_tlb_all(void) -{ xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all)); } +{ + xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all)); + local_flush_tlb_all(); +} void smp_flush_cache_mm(struct mm_struct *mm) -{ +{ if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_cache_mm(mm); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm); + + local_flush_cache_mm(mm); } } void smp_flush_tlb_mm(struct mm_struct *mm) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) { - local_flush_tlb_mm(mm); - } else { + if(mm->cpu_vm_mask != (1 << smp_processor_id())) { xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm); if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm) mm->cpu_vm_mask = (1 << smp_processor_id()); } + + local_flush_tlb_mm(mm); } } @@ -175,11 +181,10 @@ unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_cache_range(mm, start, end); - else - xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) mm, - start, end); + if(mm->cpu_vm_mask != (1 << smp_processor_id())) + xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) mm, start, end); + + local_flush_cache_range(mm, start, end); } } @@ -187,11 +192,10 @@ unsigned long end) { if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_tlb_range(mm, start, end); - else - xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) mm, - start, end); + if(mm->cpu_vm_mask != (1 << smp_processor_id())) + xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) mm, start, end); + + local_flush_tlb_range(mm, start, end); } } @@ -200,11 +204,10 @@ struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_cache_page(vma, page); - else - xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), - (unsigned long) vma, page); + if(mm->cpu_vm_mask != (1 << smp_processor_id())) + xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page); + + local_flush_cache_page(vma, page); } } @@ -213,10 +216,10 @@ struct mm_struct *mm = vma->vm_mm; if(mm->context != NO_CONTEXT) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_tlb_page(vma, page); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page); + + local_flush_tlb_page(vma, page); } } @@ -230,6 +233,7 @@ */ #if 1 xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page); + local_flush_page_to_ram(page); #else local_flush_page_to_ram(page); #endif @@ -237,10 +241,10 @@ void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr) { - if(mm->cpu_vm_mask == (1 << smp_processor_id())) - local_flush_sig_insns(mm, insn_addr); - else + if(mm->cpu_vm_mask != (1 << smp_processor_id())) xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr); + + local_flush_sig_insns(mm, insn_addr); } /* Reschedule call back. */ diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/sparc_ksyms.c linux/arch/sparc/kernel/sparc_ksyms.c --- v2.4.0-test3/linux/arch/sparc/kernel/sparc_ksyms.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/kernel/sparc_ksyms.c Tue Jul 11 19:02:37 2000 @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.99 2000/06/30 10:18:38 davem Exp $ +/* $Id: sparc_ksyms.c,v 1.101 2000/07/12 00:25:32 anton Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -19,6 +19,9 @@ #include #include #include +#ifdef CONFIG_PCI +#include +#endif #include #include @@ -42,9 +45,6 @@ #include #include #endif -#ifdef CONFIG_PCI -#include -#endif #include #include @@ -254,6 +254,7 @@ EXPORT_SYMBOL(strpbrk); EXPORT_SYMBOL(strtok); EXPORT_SYMBOL(strstr); +EXPORT_SYMBOL(page_kernel); /* Special internal versions of library functions. */ EXPORT_SYMBOL(__copy_1page); diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/sun4d_smp.c linux/arch/sparc/kernel/sun4d_smp.c --- v2.4.0-test3/linux/arch/sparc/kernel/sun4d_smp.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/kernel/sun4d_smp.c Tue Jul 11 11:07:55 2000 @@ -376,9 +376,6 @@ } } - /* First, run local copy. */ - func(arg1, arg2, arg3, arg4, arg5); - { register int i; @@ -396,8 +393,7 @@ } spin_unlock_irqrestore(&cross_call_lock, flags); - } else - func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ + } } /* Running cross calls. */ diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/sun4m_smp.c linux/arch/sparc/kernel/sun4m_smp.c --- v2.4.0-test3/linux/arch/sparc/kernel/sun4m_smp.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/kernel/sun4m_smp.c Tue Jul 11 11:07:55 2000 @@ -405,9 +405,6 @@ } } - /* First, run local copy. */ - func(arg1, arg2, arg3, arg4, arg5); - { register int i; @@ -425,8 +422,7 @@ } spin_unlock_irqrestore(&cross_call_lock, flags); - } else - func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */ + } } /* Running cross calls. */ diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/sys_sparc.c linux/arch/sparc/kernel/sys_sparc.c --- v2.4.0-test3/linux/arch/sparc/kernel/sys_sparc.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/kernel/sys_sparc.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.65 2000/07/06 01:41:29 davem Exp $ +/* $Id: sys_sparc.c,v 1.66 2000/07/10 20:57:35 davem Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c --- v2.4.0-test3/linux/arch/sparc/kernel/sys_sunos.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/kernel/sys_sunos.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.128 2000/07/06 01:41:29 davem Exp $ +/* $Id: sys_sunos.c,v 1.129 2000/07/10 20:57:35 davem Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/mm/init.c linux/arch/sparc/mm/init.c --- v2.4.0-test3/linux/arch/sparc/mm/init.c Fri Jun 23 21:55:08 2000 +++ linux/arch/sparc/mm/init.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.86 2000/06/04 06:23:52 anton Exp $ +/* $Id: init.c,v 1.88 2000/07/10 20:56:53 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -37,10 +37,12 @@ unsigned long phys_base; +unsigned long page_kernel; + struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS]; unsigned long sparc_unmapped_base; -struct pgtable_cache_struct pgt_quicklists = { 0, 0, 0, 0, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED }; +struct pgtable_cache_struct pgt_quicklists = { 0, 0, 0, 0 }; /* References to section boundaries */ extern char __init_begin, __init_end, _start, _end, etext , edata; diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/mm/srmmu.c linux/arch/sparc/mm/srmmu.c --- v2.4.0-test3/linux/arch/sparc/mm/srmmu.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/mm/srmmu.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: srmmu.c,v 1.215 2000/06/30 13:25:28 anton Exp $ +/* $Id: srmmu.c,v 1.218 2000/07/10 23:22:32 anton Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -57,6 +57,8 @@ extern unsigned long last_valid_pfn; +extern unsigned long page_kernel; + pgd_t *srmmu_swapper_pg_dir; #ifdef CONFIG_SMP @@ -442,7 +444,6 @@ if(srmmu_pmd_none(*pmd)) { pte_t *page = (pte_t *)srmmu_get_nocache(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE); if(page) { - spin_unlock(&pte_spinlock); srmmu_pmd_set(pmd, page); return page + address; } @@ -467,7 +468,6 @@ if(srmmu_pgd_none(*pgd)) { pmd_t *page = (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE); if(page) { - spin_unlock(&pte_spinlock); srmmu_pgd_set(pgd, page); return page + address; } @@ -2101,6 +2101,7 @@ static void smp_flush_page_for_dma(unsigned long page) { xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_for_dma), page); + local_flush_page_for_dma(page); } #endif @@ -2129,6 +2130,7 @@ BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF; /* Functions */ diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc/mm/sun4c.c linux/arch/sparc/mm/sun4c.c --- v2.4.0-test3/linux/arch/sparc/mm/sun4c.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc/mm/sun4c.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.195 2000/06/30 13:25:28 anton Exp $ +/* $Id: sun4c.c,v 1.196 2000/07/07 07:33:11 anton Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -45,6 +45,8 @@ extern int num_segmaps, num_contexts; +extern unsigned long page_kernel; + #ifdef CONFIG_SUN4 #define SUN4C_VAC_SIZE sun4c_vacinfo.num_bytes #else @@ -2604,6 +2606,7 @@ BTFIXUPSET_INT(page_copy, pgprot_val(SUN4C_PAGE_COPY)); BTFIXUPSET_INT(page_readonly, pgprot_val(SUN4C_PAGE_READONLY)); BTFIXUPSET_INT(page_kernel, pgprot_val(SUN4C_PAGE_KERNEL)); + page_kernel = pgprot_val(SUN4C_PAGE_KERNEL); pg_iobits = _SUN4C_PAGE_PRESENT | _SUN4C_READABLE | _SUN4C_WRITEABLE | _SUN4C_PAGE_IO | _SUN4C_PAGE_NOCACHE; diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/config.in linux/arch/sparc64/config.in --- v2.4.0-test3/linux/arch/sparc64/config.in Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/config.in Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.116 2000/07/06 01:41:29 davem Exp $ +# $Id: config.in,v 1.117 2000/07/10 20:57:35 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig --- v2.4.0-test3/linux/arch/sparc64/defconfig Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/defconfig Tue Jul 11 19:02:37 2000 @@ -437,17 +437,17 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_SMB_FS=m -CONFIG_NCP_FS=m -CONFIG_NCPFS_PACKET_SIGNING=y -CONFIG_NCPFS_IOCTL_LOCKING=y -CONFIG_NCPFS_STRONG=y -CONFIG_NCPFS_NFS_NS=y -CONFIG_NCPFS_OS2_NS=y -CONFIG_NCPFS_SMALLDOS=y -CONFIG_NCPFS_MOUNT_SUBDIR=y -CONFIG_NCPFS_NDS_DOMAINS=y -CONFIG_NCPFS_NLS=y -CONFIG_NCPFS_EXTRAS=y +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set # # Partition Types diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/binfmt_elf32.c linux/arch/sparc64/kernel/binfmt_elf32.c --- v2.4.0-test3/linux/arch/sparc64/kernel/binfmt_elf32.c Tue Feb 1 01:35:43 2000 +++ linux/arch/sparc64/kernel/binfmt_elf32.c Tue Jul 11 19:02:37 2000 @@ -79,7 +79,7 @@ } pr_un; } elf_xregset_t; -#define elf_check_arch(x) (((x) == EM_SPARC) || ((x) == EM_SPARC32PLUS)) +#define elf_check_arch(x) (((x)->e_machine == EM_SPARC) || ((x)->e_machine == EM_SPARC32PLUS)) #define ELF_ET_DYN_BASE 0x08000000 diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/entry.S linux/arch/sparc64/kernel/entry.S --- v2.4.0-test3/linux/arch/sparc64/kernel/entry.S Fri Jun 23 21:55:08 2000 +++ linux/arch/sparc64/kernel/entry.S Tue Jul 11 15:46:08 2000 @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.116 2000/06/19 06:24:37 davem Exp $ +/* $Id: entry.S,v 1.117 2000/07/11 02:21:12 davem Exp $ * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -1094,3 +1094,58 @@ restore %g0, %g0, %g0 2: retl nop + +/* This need not obtain the xtime_lock as it is coded in + * an implicitly SMP safe way already. + */ + .align 64 + .globl do_gettimeofday +do_gettimeofday: /* %o0 = timevalp */ + /* Load doubles must be used on xtime so that what we get + * is guarenteed to be atomic, this is why we can run this + * with interrupts on full blast. Don't touch this... -DaveM + * + * Note with time_t changes to the timeval type, I must now use + * nucleus atomic quad 128-bit loads. + */ + sethi %hi(timer_tick_offset), %g3 + sethi %hi(xtime), %g2 + sethi %hi(timer_tick_compare), %g1 + ldx [%g3 + %lo(timer_tick_offset)], %g3 + or %g2, %lo(xtime), %g2 + or %g1, %lo(timer_tick_compare), %g1 +1: ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o4 + rd %tick, %o1 + ldx [%g1], %g7 + ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %o2 + xor %o4, %o2, %o2 + xor %o5, %o3, %o3 + orcc %o2, %o3, %g0 + bne,pn %xcc, 1b + sethi %hi(wall_jiffies), %o2 + sethi %hi(jiffies), %o3 + ldx [%o2 + %lo(wall_jiffies)], %o2 + ldx [%o3 + %lo(jiffies)], %o3 + sub %o3, %o2, %o2 + sethi %hi(timer_ticks_per_usec_quotient), %o3 + add %g3, %o1, %o1 + ldx [%o3 + %lo(timer_ticks_per_usec_quotient)], %o3 + sub %o1, %g7, %o1 + mulx %o3, %o1, %o1 + brz,pt %o2, 1f + srlx %o1, 32, %o1 + sethi %hi(10000), %g2 + or %g2, %lo(10000), %g2 + add %o1, %g2, %o1 +1: sethi %hi(1000000), %o2 + srlx %o5, 32, %o5 + or %o2, %lo(1000000), %o2 + add %o5, %o1, %o5 + cmp %o5, %o2 + bl,a,pn %xcc, 1f + stx %o4, [%o0 + 0x0] + add %o4, 0x1, %o4 + sub %o5, %o2, %o5 + stx %o4, [%o0 + 0x0] +1: retl + st %o5, [%o0 + 0x8] diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/power.c linux/arch/sparc64/kernel/power.c --- v2.4.0-test3/linux/arch/sparc64/kernel/power.c Wed Apr 26 16:34:07 2000 +++ linux/arch/sparc64/kernel/power.c Tue Jul 11 15:46:08 2000 @@ -1,4 +1,4 @@ -/* $Id: power.c,v 1.6 2000/04/13 00:59:59 davem Exp $ +/* $Id: power.c,v 1.8 2000/07/11 22:41:33 davem Exp $ * power.c: Power management driver. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -35,10 +35,12 @@ extern void machine_halt(void); +extern int serial_console; + void machine_power_off(void) { #ifdef CONFIG_PCI - if (power_reg != 0UL) { + if (power_reg != 0UL && !serial_console) { /* Both register bits seem to have the * same effect, so until I figure out * what the difference is... @@ -53,7 +55,7 @@ static int powerd(void *__unused) { static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; - char *argv[] = { "/usr/bin/shutdown", "-h", "now", NULL }; + char *argv[] = { "/sbin/shutdown", "-h", "now", NULL }; daemonize(); sprintf(current->comm, "powerd"); @@ -67,7 +69,7 @@ } /* Ok, down we go... */ - if (execve("/usr/bin/shutdown", argv, envp) < 0) { + if (execve("/sbin/shutdown", argv, envp) < 0) { printk("powerd: shutdown execution failed\n"); button_pressed = 0; goto again; diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c --- v2.4.0-test3/linux/arch/sparc64/kernel/process.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/kernel/process.c Tue Jul 11 15:46:08 2000 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.108 2000/06/30 10:18:38 davem Exp $ +/* $Id: process.c,v 1.109 2000/07/11 01:38:57 davem Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -80,7 +80,7 @@ #define unidle_me() (cpu_data[current->processor].idle_volume = 0) int cpu_idle(void) { - current->priority = 0; + current->nice = 20; current->counter = -100; init_idle(); diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/sys_sparc.c linux/arch/sparc64/kernel/sys_sparc.c --- v2.4.0-test3/linux/arch/sparc64/kernel/sys_sparc.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/kernel/sys_sparc.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.43 2000/07/06 01:41:29 davem Exp $ +/* $Id: sys_sparc.c,v 1.44 2000/07/10 20:57:35 davem Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c --- v2.4.0-test3/linux/arch/sparc64/kernel/sys_sparc32.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/kernel/sys_sparc32.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.154 2000/07/06 01:41:29 davem Exp $ +/* $Id: sys_sparc32.c,v 1.155 2000/07/10 20:57:35 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c --- v2.4.0-test3/linux/arch/sparc64/kernel/sys_sunos32.c Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/kernel/sys_sunos32.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.51 2000/07/06 01:41:29 davem Exp $ +/* $Id: sys_sunos32.c,v 1.52 2000/07/10 20:57:35 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/kernel/time.c linux/arch/sparc64/kernel/time.c --- v2.4.0-test3/linux/arch/sparc64/kernel/time.c Tue May 23 15:31:34 2000 +++ linux/arch/sparc64/kernel/time.c Tue Jul 11 15:46:08 2000 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.26 2000/05/09 17:40:14 davem Exp $ +/* $Id: time.c,v 1.28 2000/07/11 02:21:12 davem Exp $ * time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -46,8 +46,8 @@ * interrupts, one at level14 and one with softint bit 0. */ unsigned long timer_tick_offset; -static unsigned long timer_tick_compare; -static unsigned long timer_ticks_per_usec_quotient; +unsigned long timer_tick_compare; +unsigned long timer_ticks_per_usec_quotient; static __inline__ void timer_check_rtc(void) { @@ -500,58 +500,6 @@ : "g1", "g2"); return (ticks * timer_ticks_per_usec_quotient) >> 32UL; -} - -/* This need not obtain the xtime_lock as it is coded in - * an implicitly SMP safe way already. - */ -void do_gettimeofday(struct timeval *tv) -{ - /* Load doubles must be used on xtime so that what we get - * is guarenteed to be atomic, this is why we can run this - * with interrupts on full blast. Don't touch this... -DaveM - * - * Note with time_t changes to the timeval type, I must now use - * nucleus atomic quad 128-bit loads. - */ - __asm__ __volatile__(" - sethi %hi(timer_tick_offset), %g3 - sethi %hi(xtime), %g2 - sethi %hi(timer_tick_compare), %g1 - ldx [%g3 + %lo(timer_tick_offset)], %g3 - or %g2, %lo(xtime), %g2 - or %g1, %lo(timer_tick_compare), %g1 -1: ldda [%g2] 0x24, %o4 - rd %tick, %o1 - ldx [%g1], %g7 - ldda [%g2] 0x24, %o2 - xor %o4, %o2, %o2 - xor %o5, %o3, %o3 - orcc %o2, %o3, %g0 - bne,pn %xcc, 1b - sethi %hi(lost_ticks), %o2 - sethi %hi(timer_ticks_per_usec_quotient), %o3 - ldx [%o2 + %lo(lost_ticks)], %o2 - add %g3, %o1, %o1 - ldx [%o3 + %lo(timer_ticks_per_usec_quotient)], %o3 - sub %o1, %g7, %o1 - mulx %o3, %o1, %o1 - brz,pt %o2, 1f - srlx %o1, 32, %o1 - sethi %hi(10000), %g2 - or %g2, %lo(10000), %g2 - add %o1, %g2, %o1 -1: sethi %hi(1000000), %o2 - srlx %o5, 32, %o5 - or %o2, %lo(1000000), %o2 - add %o5, %o1, %o5 - cmp %o5, %o2 - bl,a,pn %xcc, 1f - stx %o4, [%o0 + 0x0] - add %o4, 0x1, %o4 - sub %o5, %o2, %o5 - stx %o4, [%o0 + 0x0] -1: st %o5, [%o0 + 0x8]"); } void do_settimeofday(struct timeval *tv) diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/lib/Makefile linux/arch/sparc64/lib/Makefile --- v2.4.0-test3/linux/arch/sparc64/lib/Makefile Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/lib/Makefile Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.22 2000/03/31 04:06:23 davem Exp $ +# $Id: Makefile,v 1.23 2000/07/10 20:57:34 davem Exp $ # Makefile for Sparc64 library files.. # diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/lib/dec_and_lock.S linux/arch/sparc64/lib/dec_and_lock.S --- v2.4.0-test3/linux/arch/sparc64/lib/dec_and_lock.S Mon Jul 10 16:47:20 2000 +++ linux/arch/sparc64/lib/dec_and_lock.S Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id$ +/* $Id: dec_and_lock.S,v 1.1 2000/07/10 20:57:34 davem Exp $ * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()" * using cas and ldstub instructions. * diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/mm/ultra.S linux/arch/sparc64/mm/ultra.S --- v2.4.0-test3/linux/arch/sparc64/mm/ultra.S Mon Jul 10 16:47:21 2000 +++ linux/arch/sparc64/mm/ultra.S Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: ultra.S,v 1.43 2000/05/09 17:40:14 davem Exp $ +/* $Id: ultra.S,v 1.44 2000/07/10 20:57:35 davem Exp $ * ultra.S: Don't expand these all over the place... * * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com) diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/solaris/fs.c linux/arch/sparc64/solaris/fs.c --- v2.4.0-test3/linux/arch/sparc64/solaris/fs.c Mon Jul 10 16:47:21 2000 +++ linux/arch/sparc64/solaris/fs.c Tue Jul 11 11:07:55 2000 @@ -1,4 +1,4 @@ -/* $Id: fs.c,v 1.20 2000/07/06 01:41:30 davem Exp $ +/* $Id: fs.c,v 1.21 2000/07/10 20:57:35 davem Exp $ * fs.c: fs related syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/solaris/socksys.c linux/arch/sparc64/solaris/socksys.c --- v2.4.0-test3/linux/arch/sparc64/solaris/socksys.c Fri Jun 23 21:55:08 2000 +++ linux/arch/sparc64/solaris/socksys.c Wed Jul 12 21:58:42 2000 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -118,6 +119,7 @@ struct T_primsg *it; /* XXX: check this */ + lock_kernel(); sock = (struct sol_socket_struct *)filp->private_data; SOLDD(("sock release %016lx(%016lx)\n", sock, filp)); it = sock->pfirst; @@ -131,6 +133,7 @@ filp->private_data = NULL; SOLDD(("socksys_release %016lx\n", sock)); mykfree((char*)sock); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/arch/sparc64/solaris/timod.c linux/arch/sparc64/solaris/timod.c --- v2.4.0-test3/linux/arch/sparc64/solaris/timod.c Fri Jun 23 21:55:08 2000 +++ linux/arch/sparc64/solaris/timod.c Wed Jul 12 16:45:30 2000 @@ -1,4 +1,4 @@ -/* $Id: timod.c,v 1.7 2000/06/09 07:35:30 davem Exp $ +/* $Id: timod.c,v 1.9 2000/07/12 23:21:02 davem Exp $ * timod.c: timod emulation. * * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz) @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -619,22 +620,6 @@ return -EINVAL; } -/* copied directly from fs/select.c */ - -static void free_wait(poll_table * p) -{ - struct poll_table_entry * entry = p->entry + p->nr; - - SOLD("entry"); - while (p->nr > 0) { - p->nr--; - entry--; - remove_wait_queue(entry->wait_address,&entry->wait); - } - SOLD("done"); -} - - int timod_getmsg(unsigned int fd, char *ctl_buf, int ctl_maxlen, s32 *ctl_len, char *data_buf, int data_maxlen, s32 *data_len, int *flags_p) { @@ -670,14 +655,8 @@ } if (!(filp->f_flags & O_NONBLOCK)) { poll_table wait_table, *wait; - struct poll_table_entry *entry; - SOLD("getting poll_table"); - entry = (struct poll_table_entry *)__get_free_page(GFP_KERNEL); - if (!entry) - return -ENOMEM; - SOLD("got one"); - wait_table.nr = 0; - wait_table.entry = entry; + + poll_initwait(&wait_table); wait = &wait_table; for(;;) { SOLD("loop"); @@ -705,13 +684,17 @@ SOLD("avoiding lockup"); break ; } + if(wait_table.error) { + SOLD("wait-table error"); + poll_freewait(&wait_table); + return wait_table.error; + } SOLD("scheduling"); schedule(); } SOLD("loop done"); current->state = TASK_RUNNING; - free_wait(&wait_table); - free_page((unsigned long)entry); + poll_freewait(&wait_table); if (signal_pending(current)) { SOLD("signal pending"); return -EINTR; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acorn/net/ether1.c linux/drivers/acorn/net/ether1.c --- v2.4.0-test3/linux/drivers/acorn/net/ether1.c Tue May 23 15:31:34 2000 +++ linux/drivers/acorn/net/ether1.c Tue Jul 11 11:12:23 2000 @@ -70,7 +70,7 @@ static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); static void ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int ether1_close(struct net_device *dev); -static struct enet_statistics *ether1_getstats(struct net_device *dev); +static struct net_device_stats *ether1_getstats(struct net_device *dev); static void ether1_setmulticastlist(struct net_device *dev); static void ether1_timeout(struct net_device *dev); @@ -661,7 +661,7 @@ return -EAGAIN; } - memset (&priv->stats, 0, sizeof (struct enet_statistics)); + memset (&priv->stats, 0, sizeof (struct net_device_stats)); if (ether1_init_for_open (dev)) { free_irq (dev->irq, dev); @@ -978,7 +978,7 @@ return 0; } -static struct enet_statistics * +static struct net_device_stats * ether1_getstats (struct net_device *dev) { struct ether1_priv *priv = (struct ether1_priv *)dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acorn/net/ether1.h linux/drivers/acorn/net/ether1.h --- v2.4.0-test3/linux/drivers/acorn/net/ether1.h Sun Feb 20 21:12:38 2000 +++ linux/drivers/acorn/net/ether1.h Tue Jul 11 11:12:23 2000 @@ -31,7 +31,7 @@ #define IDPROM_ADDRESS (dev->base_addr + 0x09) struct ether1_priv { - struct enet_statistics stats; + struct net_device_stats stats; unsigned int tx_link; unsigned int tx_head; volatile unsigned int tx_tail; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acorn/net/ether3.c linux/drivers/acorn/net/ether3.c --- v2.4.0-test3/linux/drivers/acorn/net/ether3.c Tue May 23 15:31:34 2000 +++ linux/drivers/acorn/net/ether3.c Tue Jul 11 11:12:23 2000 @@ -83,7 +83,7 @@ static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); static void ether3_interrupt (int irq, void *dev_id, struct pt_regs *regs); static int ether3_close (struct net_device *dev); -static struct enet_statistics *ether3_getstats (struct net_device *dev); +static struct net_device_stats *ether3_getstats (struct net_device *dev); static void ether3_setmulticastlist (struct net_device *dev); static void ether3_timeout(struct net_device *dev); @@ -338,7 +338,7 @@ struct dev_priv *priv = (struct dev_priv *)dev->priv; int i; - memset(&priv->stats, 0, sizeof(struct enet_statistics)); + memset(&priv->stats, 0, sizeof(struct net_device_stats)); /* Reset the chip */ ether3_outw(CFG2_RESET, REG_CONFIG2); @@ -459,7 +459,7 @@ * Get the current statistics. This may be called with the card open or * closed. */ -static struct enet_statistics *ether3_getstats(struct net_device *dev) +static struct net_device_stats *ether3_getstats(struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; return &priv->stats; @@ -690,7 +690,7 @@ } else goto dropping; } else { - struct enet_statistics *stats = &priv->stats; + struct net_device_stats *stats = &priv->stats; ether3_outw(next_ptr >> 8, REG_RECVEND); if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++; if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acorn/net/ether3.h linux/drivers/acorn/net/ether3.h --- v2.4.0-test3/linux/drivers/acorn/net/ether3.h Sun Feb 20 21:12:38 2000 +++ linux/drivers/acorn/net/ether3.h Tue Jul 11 11:12:23 2000 @@ -154,7 +154,7 @@ unsigned char tx_head; /* buffer nr to insert next packet */ unsigned char tx_tail; /* buffer nr of transmitting packet */ unsigned int rx_head; /* address to fetch next packet from */ - struct enet_statistics stats; + struct net_device_stats stats; struct timer_list timer; int broken; /* 0 = ok, 1 = something went wrong */ }; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/Makefile linux/drivers/acpi/Makefile --- v2.4.0-test3/linux/drivers/acpi/Makefile Mon Jul 10 16:47:21 2000 +++ linux/drivers/acpi/Makefile Wed Jul 12 13:21:57 2000 @@ -11,7 +11,7 @@ O_OBJS := M_OBJS := -ACPI_OBJS := osd.o +ACPI_OBJS := driver.o ec.o cpu.o os.o sys.o tables.o ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard */*.c)) EXTRA_CFLAGS += -I./include -D_LINUX diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/cpu.c linux/drivers/acpi/cpu.c --- v2.4.0-test3/linux/drivers/acpi/cpu.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/acpi/cpu.c Wed Jul 12 13:21:57 2000 @@ -0,0 +1,307 @@ +/* + * cpu.c - Processor handling + * + * Copyright (C) 2000 Andrew Henroid + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include "acpi.h" +#include "driver.h" + +unsigned long acpi_c2_exit_latency = ACPI_INFINITE; +unsigned long acpi_c3_exit_latency = ACPI_INFINITE; +unsigned long acpi_c2_enter_latency = ACPI_INFINITE; +unsigned long acpi_c3_enter_latency = ACPI_INFINITE; + +static unsigned long acpi_pblk = ACPI_INVALID; +static int acpi_c2_tested = 0; +static int acpi_c3_tested = 0; + +/* + * Clear busmaster activity flag + */ +static inline void +acpi_clear_bm_activity(struct acpi_facp *facp) +{ + acpi_write_pm1_status(facp, ACPI_BM); +} + +/* + * Returns 1 if there has been busmaster activity + */ +static inline int +acpi_bm_activity(struct acpi_facp *facp) +{ + return acpi_read_pm1_status(facp) & ACPI_BM; +} + +/* + * Set system to sleep through busmaster requests + */ +static void +acpi_sleep_on_busmaster(struct acpi_facp *facp) +{ + u32 pm1_cntr = acpi_read_pm1_control(facp); + if (pm1_cntr & ACPI_BM_RLD) { + pm1_cntr &= ~ACPI_BM_RLD; + acpi_write_pm1_control(facp, pm1_cntr); + } +} + +/* + * Set system to wake on busmaster requests + */ +static void +acpi_wake_on_busmaster(struct acpi_facp *facp) +{ + u32 pm1_cntr = acpi_read_pm1_control(facp); + if (!(pm1_cntr & ACPI_BM_RLD)) { + pm1_cntr |= ACPI_BM_RLD; + acpi_write_pm1_control(facp, pm1_cntr); + } + acpi_clear_bm_activity(facp); +} + +/* The ACPI timer is just the low 24 bits */ +#define TIME_BEGIN(tmr) inl(tmr) +#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff) + +/* + * Idle loop (uniprocessor only) + */ +static void +acpi_idle(void) +{ + static int sleep_level = 1; + struct acpi_facp *facp = &acpi_facp; + + if (!facp + || facp->hdr.signature != ACPI_FACP_SIG + || !facp->pm_tmr + || !acpi_pblk) + goto not_initialized; + + /* + * start from the previous sleep level.. + */ + if (sleep_level == 1) + goto sleep1; + if (sleep_level == 2) + goto sleep2; + sleep3: + sleep_level = 3; + if (!acpi_c3_tested) { + printk(KERN_DEBUG "ACPI C3 works\n"); + acpi_c3_tested = 1; + } + acpi_wake_on_busmaster(facp); + if (facp->pm2_cnt) + goto sleep3_with_arbiter; + + for (;;) { + unsigned long time; + unsigned int pm_tmr = facp->pm_tmr; + + __cli(); + if (current->need_resched) + goto out; + if (acpi_bm_activity(facp)) + goto sleep2; + + time = TIME_BEGIN(pm_tmr); + inb(acpi_pblk + ACPI_P_LVL3); + /* Dummy read, force synchronization with the PMU */ + inl(pm_tmr); + time = TIME_END(pm_tmr, time); + + __sti(); + if (time < acpi_c3_exit_latency) + goto sleep2; + } + + sleep3_with_arbiter: + for (;;) { + unsigned long time; + u8 arbiter; + unsigned int pm2_cntr = facp->pm2_cnt; + unsigned int pm_tmr = facp->pm_tmr; + + __cli(); + if (current->need_resched) + goto out; + if (acpi_bm_activity(facp)) + goto sleep2; + + time = TIME_BEGIN(pm_tmr); + arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS; + /* Disable arbiter, park on CPU */ + outb(arbiter | ACPI_ARB_DIS, pm2_cntr); + inb(acpi_pblk + ACPI_P_LVL3); + /* Dummy read, force synchronization with the PMU */ + inl(pm_tmr); + time = TIME_END(pm_tmr, time); + /* Enable arbiter again.. */ + outb(arbiter, pm2_cntr); + + __sti(); + if (time < acpi_c3_exit_latency) + goto sleep2; + } + + sleep2: + sleep_level = 2; + if (!acpi_c2_tested) { + printk(KERN_DEBUG "ACPI C2 works\n"); + acpi_c2_tested = 1; + } + acpi_wake_on_busmaster(facp); /* Required to track BM activity.. */ + for (;;) { + unsigned long time; + unsigned int pm_tmr = facp->pm_tmr; + + __cli(); + if (current->need_resched) + goto out; + + time = TIME_BEGIN(pm_tmr); + inb(acpi_pblk + ACPI_P_LVL2); + /* Dummy read, force synchronization with the PMU */ + inl(pm_tmr); + time = TIME_END(pm_tmr, time); + + __sti(); + if (time < acpi_c2_exit_latency) + goto sleep1; + if (acpi_bm_activity(facp)) { + acpi_clear_bm_activity(facp); + continue; + } + if (time > acpi_c3_enter_latency) + goto sleep3; + } + + sleep1: + sleep_level = 1; + acpi_sleep_on_busmaster(facp); + for (;;) { + unsigned long time; + unsigned int pm_tmr = facp->pm_tmr; + + __cli(); + if (current->need_resched) + goto out; + time = TIME_BEGIN(pm_tmr); + safe_halt(); + time = TIME_END(pm_tmr, time); + if (time > acpi_c2_enter_latency) + goto sleep2; + } + + not_initialized: + for (;;) { + __cli(); + if (current->need_resched) + goto out; + safe_halt(); + } + + out: + __sti(); +} + +/* + * Get processor information + */ +static ACPI_STATUS +acpi_find_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +{ + ACPI_OBJECT obj; + ACPI_CX_STATE lat[4]; + ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE]; + ACPI_BUFFER buf; + int i, count; + + buf.length = sizeof(obj); + buf.pointer = &obj; + if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf))) + return AE_OK; + + printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n", + obj.processor.proc_id, + obj.processor.pblk_address, + obj.processor.pblk_length); + if (acpi_pblk != ACPI_INVALID + || !obj.processor.pblk_address + || obj.processor.pblk_length != 6) + return AE_OK; + + acpi_pblk = obj.processor.pblk_address; + + buf.length = sizeof(lat); + buf.pointer = lat; + if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf))) + return AE_OK; + + if (lat[2].latency < MAX_CX_STATE_LATENCY) { + printk(KERN_INFO "ACPI: C2 supported\n"); + acpi_c2_exit_latency = lat[2].latency; + } + if (lat[3].latency < MAX_CX_STATE_LATENCY) { + printk(KERN_INFO "ACPI: C3 supported\n"); + acpi_c3_exit_latency = lat[3].latency; + } + + memset(throttle, 0, sizeof(throttle)); + buf.length = sizeof(throttle); + buf.pointer = throttle; + + if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf))) + return AE_OK; + + for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) { + if (throttle[i].percent_of_clock) + count++; + } + count--; + if (count > 0) + printk(KERN_INFO "ACPI: %d throttling states\n", count); + + return AE_OK; +} + +int +acpi_cpu_init(void) +{ + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, + ACPI_ROOT_OBJECT, + ACPI_INT32_MAX, + acpi_find_cpu, + NULL, + NULL); + +#ifdef CONFIG_SMP + if (smp_num_cpus == 1) + pm_idle = acpi_idle; +#else + pm_idle = acpi_idle; +#endif + + return 0; +} diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/driver.c linux/drivers/acpi/driver.c --- v2.4.0-test3/linux/drivers/acpi/driver.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/acpi/driver.c Wed Jul 12 13:21:57 2000 @@ -0,0 +1,388 @@ +/* + * driver.c - ACPI driver + * + * Copyright (C) 2000 Andrew Henroid + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "acpi.h" +#include "driver.h" + +struct acpi_run_entry +{ + void (*callback)(void*); + void *context; + struct tq_struct task; +}; + +static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED; +static volatile u32 acpi_event_status = 0; +static volatile acpi_sstate_t acpi_event_state = ACPI_S0; +static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); + +static volatile int acpi_thread_pid = -1; +static DECLARE_TASK_QUEUE(acpi_thread_run); +static DECLARE_WAIT_QUEUE_HEAD(acpi_thread_wait); + +static struct ctl_table_header *acpi_sysctl = NULL; + +/* + * Examine/modify value + */ +static int +acpi_do_ulong(ctl_table * ctl, + int write, + struct file *file, + void *buffer, + size_t * len) +{ + char str[2 * sizeof(unsigned long) + 4], *strend; + unsigned long val; + int size; + + if (!write) { + if (file->f_pos) { + *len = 0; + return 0; + } + + val = *(unsigned long *) ctl->data; + size = sprintf(str, "0x%08lx\n", val); + if (*len >= size) { + copy_to_user(buffer, str, size); + *len = size; + } + else + *len = 0; + } + else { + size = sizeof(str) - 1; + if (size > *len) + size = *len; + copy_from_user(str, buffer, size); + str[size] = '\0'; + val = simple_strtoul(str, &strend, 0); + if (strend == str) + return -EINVAL; + *(unsigned long *) ctl->data = val; + } + + file->f_pos += *len; + return 0; +} + +/* + * Handle ACPI event + */ +static u32 +acpi_event(void *context) +{ + unsigned long flags; + int event = (int) context; + int mask = 0; + + switch (event) { + case ACPI_EVENT_POWER_BUTTON: mask = ACPI_PWRBTN; break; + case ACPI_EVENT_SLEEP_BUTTON: mask = ACPI_SLPBTN; break; + default: return AE_ERROR; + } + + if (mask) { + // notify process waiting on /dev/acpi + spin_lock_irqsave(&acpi_event_lock, flags); + acpi_event_status |= mask; + spin_unlock_irqrestore(&acpi_event_lock, flags); + acpi_event_state = acpi_sleep_state; + wake_up_interruptible(&acpi_event_wait); + } + + return AE_OK; +} + +/* + * Wait for next event + */ +static int +acpi_do_event(ctl_table * ctl, + int write, + struct file *file, + void *buffer, + size_t * len) +{ + u32 event_status = 0; + acpi_sstate_t event_state = 0; + char str[27]; + int size; + + if (write) + return -EPERM; + if (*len < sizeof(str)) { + *len = 0; + return 0; + } + + for (;;) { + unsigned long flags; + + // we need an atomic exchange here + spin_lock_irqsave(&acpi_event_lock, flags); + event_status = acpi_event_status; + acpi_event_status = 0; + spin_unlock_irqrestore(&acpi_event_lock, flags); + event_state = acpi_event_state; + + if (event_status) + break; + + // wait for an event to arrive + interruptible_sleep_on(&acpi_event_wait); + if (signal_pending(current)) + return -ERESTARTSYS; + } + + size = sprintf(str, + "0x%08x 0x%08x 0x%01x\n", + event_status, + 0, + event_state); + copy_to_user(buffer, str, size); + *len = size; + file->f_pos += size; + + return 0; +} + +/* + * Enter system sleep state + */ +static int +acpi_do_sleep(ctl_table * ctl, + int write, + struct file *file, + void *buffer, + size_t * len) +{ + if (!write) { + if (file->f_pos) { + *len = 0; + return 0; + } + } + else { +#ifdef CONFIG_ACPI_S1_SLEEP + int status = acpi_enter_sx(ACPI_S1); + if (status) + return status; +#endif + } + file->f_pos += *len; + return 0; +} + +/* + * Run queued callback + */ +static void +acpi_run_exec(void *context) +{ + struct acpi_run_entry *entry + = (struct acpi_run_entry*) context; + (*entry->callback)(entry->context); + kfree(entry); +} + +/* + * Queue for execution by the ACPI thread + */ +int +acpi_run(void (*callback)(void*), void *context) +{ + struct acpi_run_entry *entry; + + entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + if (!entry) + return -1; + + memset(entry, 0, sizeof(entry)); + entry->callback = callback; + entry->context = context; + entry->task.routine = acpi_run_exec; + entry->task.data = entry; + + queue_task(&entry->task, &acpi_thread_run); + + if (waitqueue_active(&acpi_thread_wait)) + wake_up(&acpi_thread_wait); + + return 0; +} + +static struct ctl_table acpi_table[] = +{ + {ACPI_P_LVL2_LAT, "c2_exit_latency", + &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency), + 0644, NULL, &acpi_do_ulong}, + + {ACPI_ENTER_LVL2_LAT, "c2_enter_latency", + &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency), + 0644, NULL, &acpi_do_ulong}, + + {ACPI_P_LVL3_LAT, "c3_exit_latency", + &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency), + 0644, NULL, &acpi_do_ulong}, + + {ACPI_ENTER_LVL3_LAT, "c3_enter_latency", + &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency), + 0644, NULL, &acpi_do_ulong}, + + {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep}, + + {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event}, + + {0} +}; + +static struct ctl_table acpi_dir_table[] = +{ + {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table}, + {0} +}; + +/* + * Initialize and run interpreter within a kernel thread + */ +static int +acpi_thread(void *context) +{ + /* + * initialize + */ + exit_files(current); + daemonize(); + strcpy(current->comm, "acpi"); + + if (!ACPI_SUCCESS(acpi_initialize(NULL))) { + printk(KERN_ERR "ACPI: initialize failed\n"); + return -ENODEV; + } + + if (acpi_load_tables()) + return -ENODEV; + + if (PM_IS_ACTIVE()) { + printk(KERN_NOTICE "ACPI: APM is already active.\n"); + acpi_terminate(); + return -ENODEV; + } + + pm_active = 1; + + if (!ACPI_SUCCESS(acpi_enable())) { + printk(KERN_ERR "ACPI: enable failed\n"); + acpi_terminate(); + return -ENODEV; + } + + acpi_cpu_init(); + acpi_sys_init(); + acpi_ec_init(); + + if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( + ACPI_EVENT_POWER_BUTTON, + acpi_event, + (void *) ACPI_EVENT_POWER_BUTTON))) { + printk(KERN_ERR "ACPI: power button enable failed\n"); + } + if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( + ACPI_EVENT_SLEEP_BUTTON, + acpi_event, + (void *) ACPI_EVENT_SLEEP_BUTTON))) { + printk(KERN_ERR "ACPI: sleep button enable failed\n"); + } + + acpi_sysctl = register_sysctl_table(acpi_dir_table, 1); + + /* + * run + */ + for (;;) { + interruptible_sleep_on(&acpi_thread_wait); + if (signal_pending(current)) + break; + do { + run_task_queue(&acpi_thread_run); + } while (acpi_thread_run); + } + + /* + * terminate + */ + unregister_sysctl_table(acpi_sysctl); + acpi_terminate(); + + acpi_thread_pid = -1; + + return 0; +} + +/* + * Start the interpreter + */ +int __init +acpi_init(void) +{ + acpi_thread_pid = kernel_thread(acpi_thread, + NULL, + (CLONE_FS | CLONE_FILES + | CLONE_SIGHAND | SIGCHLD)); + return ((acpi_thread_pid >= 0) ? 0:-ENODEV); +} + +/* + * Terminate the interpreter + */ +void __exit +acpi_exit(void) +{ + int count; + + if (!kill_proc(acpi_thread_pid, SIGTERM, 1)) { + // wait until thread terminates (at most 5 seconds) + count = 5 * HZ; + while (acpi_thread_pid >= 0 && --count) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(1); + } + } + + pm_idle = NULL; + pm_power_off = NULL; + pm_active = 0; +} + +module_init(acpi_init); +module_exit(acpi_exit); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/driver.h linux/drivers/acpi/driver.h --- v2.4.0-test3/linux/drivers/acpi/driver.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/acpi/driver.h Wed Jul 12 13:21:57 2000 @@ -0,0 +1,115 @@ +/* + * driver.h - ACPI driver + * + * Copyright (C) 2000 Andrew Henroid + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __DRIVER_H +#define __DRIVER_H + +#include +#include +#include +#include +#include + +#define ACPI_MAX_THROTTLE 10 +#define ACPI_INVALID ~0UL +#define ACPI_INFINITE ~0UL + +/* + * cpu.c + */ +int acpi_cpu_init(void); + +extern unsigned long acpi_c2_exit_latency; +extern unsigned long acpi_c3_exit_latency; +extern unsigned long acpi_c2_enter_latency; +extern unsigned long acpi_c3_enter_latency; + +/* + * driver.c + */ +int acpi_run(void (*callback)(void*), void *context); + +/* + * ec.c + */ +int acpi_ec_init(void); +int acpi_ec_read(int addr, int *value); +int acpi_ec_write(int addr, int value); + +/* + * sys.c + */ +int acpi_sys_init(void); +int acpi_enter_sx(acpi_sstate_t state); + +extern volatile acpi_sstate_t acpi_sleep_state; + +/* + * tables.c + */ +extern struct acpi_facp acpi_facp; + +int acpi_load_tables(void); + +/* + * access ACPI registers + */ + +extern inline u32 +acpi_read_pm1_control(struct acpi_facp *facp) +{ + u32 value = 0; + if (facp->pm1a_cnt) + value = inw(facp->pm1a_cnt); + if (facp->pm1b_cnt) + value |= inw(facp->pm1b_cnt); + return value; +} + +extern inline void +acpi_write_pm1_control(struct acpi_facp *facp, u32 value) +{ + if (facp->pm1a_cnt) + outw(value, facp->pm1a_cnt); + if (facp->pm1b_cnt) + outw(value, facp->pm1b_cnt); +} + +extern inline u32 +acpi_read_pm1_status(struct acpi_facp *facp) +{ + u32 value = 0; + if (facp->pm1a_evt) + value = inw(facp->pm1a_evt); + if (facp->pm1b_evt) + value |= inw(facp->pm1b_evt); + return value; +} + +extern inline void +acpi_write_pm1_status(struct acpi_facp *facp, u32 value) +{ + if (facp->pm1a_evt) + outw(value, facp->pm1a_evt); + if (facp->pm1b_evt) + outw(value, facp->pm1b_evt); +} + +#endif /* __DRIVER_H */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/ec.c linux/drivers/acpi/ec.c --- v2.4.0-test3/linux/drivers/acpi/ec.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/acpi/ec.c Thu Jul 13 09:39:49 2000 @@ -0,0 +1,191 @@ +/* + * ec.c - Embedded controller support + * + * Copyright (C) 2000 Andrew Henroid + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include "acpi.h" +#include "driver.h" + +enum +{ + ACPI_EC_HID = 0x090cd041, +}; + +enum +{ + ACPI_EC_SMI = 0x40, + ACPI_EC_SCI = 0x20, + ACPI_EC_BURST = 0x10, + ACPI_EC_CMD = 0x08, + ACPI_EC_IBF = 0x02, + ACPI_EC_OBF = 0x01 +}; + +enum +{ + ACPI_EC_READ = 0x80, + ACPI_EC_WRITE = 0x81, + ACPI_EC_BURST_ENABLE = 0x82, + ACPI_EC_BURST_DISABLE = 0x83, + ACPI_EC_QUERY = 0x84, +}; + + +static int acpi_ec_data = 0; +static int acpi_ec_status = 0; +static DECLARE_WAIT_QUEUE_HEAD(acpi_ec_wait); + +/* + * handle GPE + */ +static void +acpi_ec_gpe(void *context) +{ + printk(KERN_INFO "ACPI: EC GPE\n"); + if (waitqueue_active(&acpi_ec_wait)) + wake_up_interruptible(&acpi_ec_wait); +} + +/* + * wait for read/write status to clear + */ +static void +acpi_ec_wait_control(void) +{ + udelay(1); + while(inb(acpi_ec_status) & ACPI_EC_IBF) + udelay(10); +} + +/* + * read a byte from the EC + */ +int +acpi_ec_read(int addr, int *value) +{ + if (!acpi_ec_data || !acpi_ec_status) + return -1; + + outb(ACPI_EC_READ, acpi_ec_status); + acpi_ec_wait_control(); + outb(addr, acpi_ec_data); + acpi_ec_wait_control(); + interruptible_sleep_on(&acpi_ec_wait); + *value = inb(acpi_ec_data); + + return 0; +} + +/* + * write a byte to the EC + */ +int +acpi_ec_write(int addr, int value) +{ + if (!acpi_ec_data || !acpi_ec_status) + return -1; + + outb(ACPI_EC_WRITE, acpi_ec_status); + acpi_ec_wait_control(); + outb(addr, acpi_ec_data); + acpi_ec_wait_control(); + outb(value, acpi_ec_data); + acpi_ec_wait_control(); + interruptible_sleep_on(&acpi_ec_wait); + + return 0; +} + +/* + * Get processor information + */ +static ACPI_STATUS +acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value) +{ + ACPI_BUFFER buf; + ACPI_OBJECT obj; + RESOURCE *res; + int gpe; + + buf.length = sizeof(obj); + buf.pointer = &obj; + if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_HID", NULL, &buf)) + || obj.type != ACPI_TYPE_NUMBER + || obj.number.value != ACPI_EC_HID) + return AE_OK; + + buf.length = 0; + buf.pointer = NULL; + if (acpi_get_current_resources(handle, &buf) != AE_BUFFER_OVERFLOW) + return AE_OK; + + buf.pointer = kmalloc(buf.length, GFP_KERNEL); + if (!buf.pointer) + return AE_OK; + + if (!ACPI_SUCCESS(acpi_get_current_resources(handle, &buf))) { + kfree(buf.pointer); + return AE_OK; + } + + res = (RESOURCE*) buf.pointer; + acpi_ec_data = (int) res->data.io.min_base_address; + res = (RESOURCE*)((u8*) buf.pointer + res->length); + acpi_ec_status = (int) res->data.io.min_base_address; + + kfree(buf.pointer); + + buf.length = sizeof(obj); + buf.pointer = &obj; + if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf)) + || obj.type != ACPI_TYPE_NUMBER) + return AE_OK; + gpe = (int) obj.number.value; + + printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,%d)\n", + acpi_ec_data, acpi_ec_status, gpe); + + if (!ACPI_SUCCESS(acpi_install_gpe_handler( + gpe, + (ACPI_EVENT_LEVEL_TRIGGERED + | ACPI_EVENT_EDGE_TRIGGERED), + acpi_ec_gpe, + NULL))) + return AE_OK; + + return AE_OK; +} + +int +acpi_ec_init(void) +{ + acpi_walk_namespace(ACPI_TYPE_DEVICE, + ACPI_ROOT_OBJECT, + ACPI_INT32_MAX, + acpi_find_ec, + NULL, + NULL); + return 0; +} diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/os.c linux/drivers/acpi/os.c --- v2.4.0-test3/linux/drivers/acpi/os.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/acpi/os.c Thu Jul 13 09:39:49 2000 @@ -0,0 +1,379 @@ +/* + * os.c - OS-dependent functions + * + * Copyright (C) 2000 Andrew Henroid + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "acpi.h" +#include "driver.h" + +static int acpi_irq_irq = 0; +static OSD_HANDLER acpi_irq_handler = NULL; +static void *acpi_irq_context = NULL; + +char * +strupr(char *str) +{ + char *s = str; + while (*s) { + *s = TOUPPER(*s); + s++; + } + return str; +} + +ACPI_STATUS +acpi_os_initialize(void) +{ + return AE_OK; +} + +ACPI_STATUS +acpi_os_terminate(void) +{ + if (acpi_irq_handler) { + acpi_os_remove_interrupt_handler(acpi_irq_irq, + acpi_irq_handler); + } + return AE_OK; +} + +s32 +acpi_os_printf(const char *fmt,...) +{ + s32 size; + va_list args; + va_start(args, fmt); + size = acpi_os_vprintf(fmt, args); + va_end(args); + return size; +} + +s32 +acpi_os_vprintf(const char *fmt, va_list args) +{ + static char buffer[512]; + int size = vsprintf(buffer, fmt, args); + printk(KERN_DEBUG "ACPI: %s", buffer); + return size; +} + +void * +acpi_os_allocate(u32 size) +{ + return kmalloc(size, GFP_KERNEL); +} + +void * +acpi_os_callocate(u32 size) +{ + void *ptr = acpi_os_allocate(size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +void +acpi_os_free(void *ptr) +{ + kfree(ptr); +} + +ACPI_STATUS +acpi_os_map_memory(void *phys, u32 size, void **virt) +{ + if ((unsigned long) phys < virt_to_phys(high_memory)) { + *virt = phys_to_virt((unsigned long) phys); + return AE_OK; + } + + *virt = ioremap((unsigned long) phys, size); + if (!*virt) + return AE_ERROR; + + return AE_OK; +} + +void +acpi_os_unmap_memory(void *virt, u32 size) +{ + if (virt >= high_memory) + iounmap(virt); +} + +static void +acpi_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + (*acpi_irq_handler)(acpi_irq_context); +} + +ACPI_STATUS +acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) +{ + acpi_irq_irq = irq; + acpi_irq_handler = handler; + acpi_irq_context = context; + if (request_irq(irq, + acpi_irq, + SA_INTERRUPT | SA_SHIRQ, + "acpi", + acpi_irq)) { + printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq); + return AE_ERROR; + } + return AE_OK; +} + +ACPI_STATUS +acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) +{ + if (acpi_irq_handler) { + free_irq(irq, acpi_irq); + acpi_irq_handler = NULL; + } + return AE_OK; +} + +/* + * Running in interpreter thread context, safe to sleep + */ + +void +acpi_os_sleep(u32 sec, u32 ms) +{ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ * sec + (ms * HZ) / 1000); +} + +void +acpi_os_sleep_usec(u32 us) +{ + udelay(us); +} + +u8 +acpi_os_in8(ACPI_IO_ADDRESS port) +{ + return inb(port); +} + +u16 +acpi_os_in16(ACPI_IO_ADDRESS port) +{ + return inw(port); +} + +u32 +acpi_os_in32(ACPI_IO_ADDRESS port) +{ + return inl(port); +} + +void +acpi_os_out8(ACPI_IO_ADDRESS port, u8 val) +{ + outb(val, port); +} + +void +acpi_os_out16(ACPI_IO_ADDRESS port, u16 val) +{ + outw(val, port); +} + +void +acpi_os_out32(ACPI_IO_ADDRESS port, u32 val) +{ + outl(val, port); +} + +ACPI_STATUS +acpi_os_read_pci_cfg_byte( + u32 bus, + u32 func, + u32 addr, + u8 * val) +{ + int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); + if (!val || !dev || pci_read_config_byte(dev, addr, val)) + return AE_ERROR; + return AE_OK; +} + +ACPI_STATUS +acpi_os_read_pci_cfg_word( + u32 bus, + u32 func, + u32 addr, + u16 * val) +{ + int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); + if (!val || !dev || pci_read_config_word(dev, addr, val)) + return AE_ERROR; + return AE_OK; +} + +ACPI_STATUS +acpi_os_read_pci_cfg_dword( + u32 bus, + u32 func, + u32 addr, + u32 * val) +{ + int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); + if (!val || !dev || pci_read_config_dword(dev, addr, val)) + return AE_ERROR; + return AE_OK; +} + +ACPI_STATUS +acpi_os_write_pci_cfg_byte( + u32 bus, + u32 func, + u32 addr, + u8 val) +{ + int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); + if (!dev || pci_write_config_byte(dev, addr, val)) + return AE_ERROR; + return AE_OK; +} + +ACPI_STATUS +acpi_os_write_pci_cfg_word( + u32 bus, + u32 func, + u32 addr, + u16 val) +{ + int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); + if (!dev || pci_write_config_word(dev, addr, val)) + return AE_ERROR; + return AE_OK; +} + +ACPI_STATUS +acpi_os_write_pci_cfg_dword( + u32 bus, + u32 func, + u32 addr, + u32 val) +{ + int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); + struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); + if (!dev || pci_write_config_dword(dev, addr, val)) + return AE_ERROR; + return AE_OK; +} + +/* + * Queue for interpreter thread + */ + +ACPI_STATUS +acpi_os_queue_for_execution( + u32 priority, + OSD_EXECUTION_CALLBACK callback, + void *context) +{ + if (acpi_run(callback, context)) + return AE_ERROR; + return AE_OK; +} + +/* + * Semaphores are unused, interpreter access is single threaded + */ + +ACPI_STATUS +acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle) +{ + *handle = (ACPI_HANDLE) 0; + return AE_OK; +} + +ACPI_STATUS +acpi_os_delete_semaphore(ACPI_HANDLE handle) +{ + return AE_OK; +} + +ACPI_STATUS +acpi_os_wait_semaphore(ACPI_HANDLE handle, u32 units, u32 timeout) +{ + return AE_OK; +} + +ACPI_STATUS +acpi_os_signal_semaphore(ACPI_HANDLE handle, u32 units) +{ + return AE_OK; +} + +ACPI_STATUS +acpi_os_breakpoint(char *msg) +{ + acpi_os_printf("breakpoint: %s", msg); + return AE_OK; +} + +void +acpi_os_dbg_trap(char *msg) +{ + acpi_os_printf("trap: %s", msg); +} + +void +acpi_os_dbg_assert(void *failure, void *file, u32 line, char *msg) +{ + acpi_os_printf("assert: %s", msg); +} + +u32 +acpi_os_get_line(char *buffer) +{ + return 0; +} + +/* + * We just have to assume we're dealing with valid memory + */ + +BOOLEAN +acpi_os_readable(void *ptr, u32 len) +{ + return 1; +} + +BOOLEAN +acpi_os_writable(void *ptr, u32 len) +{ + return 1; +} diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/osd.c linux/drivers/acpi/osd.c --- v2.4.0-test3/linux/drivers/acpi/osd.c Mon Jul 10 16:47:21 2000 +++ linux/drivers/acpi/osd.c Wed Dec 31 16:00:00 1969 @@ -1,1319 +0,0 @@ -/* - * osd.c - Linux specific code - * - * Copyright (C) 2000 Andrew Henroid - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "acpi.h" - -#define ACPI_MAX_THROTTLE 10 -#define ACPI_INVALID ~0UL -#define ACPI_INFINITE ~0UL - -static struct acpi_facp *acpi_facp = NULL; - -static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED; -static volatile u32 acpi_event_status = 0; -static volatile acpi_sstate_t acpi_event_state = ACPI_S0; -static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); -static int acpi_irq_irq = 0; -static OSD_HANDLER acpi_irq_handler = NULL; -static void *acpi_irq_context = NULL; - -static unsigned long acpi_pblk = ACPI_INVALID; -static unsigned long acpi_c2_exit_latency = ACPI_INFINITE; -static unsigned long acpi_c3_exit_latency = ACPI_INFINITE; -static unsigned long acpi_c2_enter_latency = ACPI_INFINITE; -static unsigned long acpi_c3_enter_latency = ACPI_INFINITE; -static int acpi_c2_tested = 0; -static int acpi_c3_tested = 0; - -struct acpi_intrp_entry -{ - int priority; - OSD_EXECUTION_CALLBACK callback; - void *context; - struct list_head list; -}; - -struct acpi_enter_sx_ctx -{ - wait_queue_head_t wait; - int state; -}; - -static volatile int acpi_intrp_pid = -1; -static DECLARE_WAIT_QUEUE_HEAD(acpi_intrp_wait); -static LIST_HEAD(acpi_intrp_exec); -static spinlock_t acpi_intrp_exec_lock = SPIN_LOCK_UNLOCKED; - -#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb)) -#define ACPI_SLP_TYPA(value) \ - ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) -#define ACPI_SLP_TYPB(value) \ - ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) - -static volatile acpi_sstate_t acpi_sleep_state = ACPI_S0; -static unsigned long acpi_slptyp[ACPI_S5 + 1] = {ACPI_INVALID,}; - -static struct ctl_table_header *acpi_sysctl = NULL; - -static int acpi_do_ulong(ctl_table * ctl, - int write, - struct file *file, - void *buffer, - size_t * len); -static int acpi_do_sleep(ctl_table * ctl, - int write, - struct file *file, - void *buffer, - size_t * len); -static int acpi_do_event(ctl_table * ctl, - int write, - struct file *file, - void *buffer, - size_t * len); - -static struct ctl_table acpi_table[] = -{ - {ACPI_P_LVL2_LAT, "c2_exit_latency", - &acpi_c2_exit_latency, sizeof(acpi_c2_exit_latency), - 0644, NULL, &acpi_do_ulong}, - - {ACPI_ENTER_LVL2_LAT, "c2_enter_latency", - &acpi_c2_enter_latency, sizeof(acpi_c2_enter_latency), - 0644, NULL, &acpi_do_ulong}, - - {ACPI_P_LVL3_LAT, "c3_exit_latency", - &acpi_c3_exit_latency, sizeof(acpi_c3_exit_latency), - 0644, NULL, &acpi_do_ulong}, - - {ACPI_ENTER_LVL3_LAT, "c3_enter_latency", - &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency), - 0644, NULL, &acpi_do_ulong}, - - {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep}, - - {ACPI_EVENT, "event", NULL, 0, 0400, NULL, &acpi_do_event}, - - {0} -}; - -static struct ctl_table acpi_dir_table[] = -{ - {CTL_ACPI, "acpi", NULL, 0, 0555, acpi_table}, - {0} -}; - -static u32 FASTCALL(acpi_read_pm1_control(struct acpi_facp *)); -static u32 FASTCALL(acpi_read_pm1_status(struct acpi_facp *)); -static void FASTCALL(acpi_write_pm1_control(struct acpi_facp *, u32)); -static void FASTCALL(acpi_write_pm1_status(struct acpi_facp *, u32)); - -/* - * Get the value of the PM1 control register (ACPI_SCI_EN, ...) - */ -static u32 -acpi_read_pm1_control(struct acpi_facp *facp) -{ - u32 value = 0; - if (facp->pm1a_cnt) - value = inw(facp->pm1a_cnt); - if (facp->pm1b_cnt) - value |= inw(facp->pm1b_cnt); - return value; -} - -/* - * Set the value of the PM1 control register (ACPI_BM_RLD, ...) - */ -static void -acpi_write_pm1_control(struct acpi_facp *facp, u32 value) -{ - if (facp->pm1a_cnt) - outw(value, facp->pm1a_cnt); - if (facp->pm1b_cnt) - outw(value, facp->pm1b_cnt); -} - -/* - * Get the value of the fixed event status register - */ -static u32 -acpi_read_pm1_status(struct acpi_facp *facp) -{ - u32 value = 0; - if (facp->pm1a_evt) - value = inw(facp->pm1a_evt); - if (facp->pm1b_evt) - value |= inw(facp->pm1b_evt); - return value; -} - -/* - * Set the value of the fixed event status register (clear events) - */ -static void -acpi_write_pm1_status(struct acpi_facp *facp, u32 value) -{ - if (facp->pm1a_evt) - outw(value, facp->pm1a_evt); - if (facp->pm1b_evt) - outw(value, facp->pm1b_evt); -} - -/* - * Examine/modify value - */ -static int -acpi_do_ulong(ctl_table * ctl, - int write, - struct file *file, - void *buffer, - size_t * len) -{ - char str[2 * sizeof(unsigned long) + 4], *strend; - unsigned long val; - int size; - - if (!write) { - if (file->f_pos) { - *len = 0; - return 0; - } - - val = *(unsigned long *) ctl->data; - size = sprintf(str, "0x%08lx\n", val); - if (*len >= size) { - copy_to_user(buffer, str, size); - *len = size; - } - else - *len = 0; - } - else { - size = sizeof(str) - 1; - if (size > *len) - size = *len; - copy_from_user(str, buffer, size); - str[size] = '\0'; - val = simple_strtoul(str, &strend, 0); - if (strend == str) - return -EINVAL; - *(unsigned long *) ctl->data = val; - } - - file->f_pos += *len; - return 0; -} - -/* - * Handle ACPI event - */ -u32 -acpi_event(void *context) -{ - unsigned long flags; - int event = (int) context; - int mask = 0; - - switch (event) { - case ACPI_EVENT_POWER_BUTTON: - mask = ACPI_PWRBTN; - break; - case ACPI_EVENT_SLEEP_BUTTON: - mask = ACPI_SLPBTN; - break; - } - - if (mask) { - // notify process waiting on /dev/acpi - spin_lock_irqsave(&acpi_event_lock, flags); - acpi_event_status |= mask; - spin_unlock_irqrestore(&acpi_event_lock, flags); - acpi_event_state = acpi_sleep_state; - wake_up_interruptible(&acpi_event_wait); - } - - return AE_OK; -} - -/* - * Wait for next event - */ -int -acpi_do_event(ctl_table * ctl, - int write, - struct file *file, - void *buffer, - size_t * len) -{ - u32 event_status = 0; - acpi_sstate_t event_state = 0; - char str[27]; - int size; - - if (write) - return -EPERM; - if (*len < sizeof(str)) { - *len = 0; - return 0; - } - - for (;;) { - unsigned long flags; - - // we need an atomic exchange here - spin_lock_irqsave(&acpi_event_lock, flags); - event_status = acpi_event_status; - acpi_event_status = 0; - spin_unlock_irqrestore(&acpi_event_lock, flags); - event_state = acpi_event_state; - - if (event_status) - break; - - // wait for an event to arrive - interruptible_sleep_on(&acpi_event_wait); - if (signal_pending(current)) - return -ERESTARTSYS; - } - - size = sprintf(str, - "0x%08x 0x%08x 0x%01x\n", - event_status, - 0, - event_state); - copy_to_user(buffer, str, size); - *len = size; - file->f_pos += size; - - return 0; -} - -/* - * Enter system sleep state - */ -static void -acpi_enter_sx(void *context) -{ - struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context; - struct acpi_facp *facp = acpi_facp; - ACPI_OBJECT_LIST arg_list; - ACPI_OBJECT arg; - u16 value; - - /* - * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. - */ - - // run the _PTS method - memset(&arg_list, 0, sizeof(arg_list)); - arg_list.count = 1; - arg_list.pointer = &arg; - - memset(&arg, 0, sizeof(arg)); - arg.type = ACPI_TYPE_NUMBER; - arg.number.value = ctx->state; - - acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL); - - // clear wake status - acpi_write_pm1_status(facp, ACPI_WAK); - - acpi_sleep_state = ctx->state; - - // set ACPI_SLP_TYPA/b and ACPI_SLP_EN - __cli(); - if (facp->pm1a_cnt) { - value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK; - value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state]) - | ACPI_SLP_EN); - outw(value, facp->pm1a_cnt); - } - if (facp->pm1b_cnt) { - value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK; - value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state]) - | ACPI_SLP_EN); - outw(value, facp->pm1b_cnt); - } - __sti(); - - if (ctx->state != ACPI_S1) { - printk(KERN_ERR "ACPI: S%d failed\n", ctx->state); - goto out; - } - - // wait until S1 is entered - while (!(acpi_read_pm1_status(facp) & ACPI_WAK)) - safe_halt(); - - // run the _WAK method - memset(&arg_list, 0, sizeof(arg_list)); - arg_list.count = 1; - arg_list.pointer = &arg; - - memset(&arg, 0, sizeof(arg)); - arg.type = ACPI_TYPE_NUMBER; - arg.number.value = ctx->state; - - acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL); - - out: - acpi_sleep_state = ACPI_S0; - - if (waitqueue_active(&ctx->wait)) - wake_up_interruptible(&ctx->wait); -} - -/* - * Enter system sleep state and wait for completion - */ -static int -acpi_enter_sx_and_wait(acpi_sstate_t state) -{ - struct acpi_enter_sx_ctx ctx; - - if (!acpi_facp - || acpi_facp->hdr.signature != ACPI_FACP_SIG - || acpi_slptyp[state] == ACPI_INVALID) - return -EINVAL; - - init_waitqueue_head(&ctx.wait); - ctx.state = state; - - if (acpi_os_queue_for_execution(0, acpi_enter_sx, &ctx)) - return -1; - - interruptible_sleep_on(&ctx.wait); - if (signal_pending(current)) - return -ERESTARTSYS; - - return 0; -} - -/* - * Enter system sleep state - */ -static int -acpi_do_sleep(ctl_table * ctl, - int write, - struct file *file, - void *buffer, - size_t * len) -{ - if (!write) { - if (file->f_pos) { - *len = 0; - return 0; - } - } - else { -#ifdef CONFIG_ACPI_S1_SLEEP - int status = acpi_enter_sx_and_wait(ACPI_S1); - if (status) - return status; -#endif - } - file->f_pos += *len; - return 0; -} - -/* - * Clear busmaster activity flag - */ -static inline void -acpi_clear_bm_activity(struct acpi_facp *facp) -{ - acpi_write_pm1_status(facp, ACPI_BM); -} - -/* - * Returns 1 if there has been busmaster activity - */ -static inline int -acpi_bm_activity(struct acpi_facp *facp) -{ - return acpi_read_pm1_status(facp) & ACPI_BM; -} - -/* - * Set system to sleep through busmaster requests - */ -static void -acpi_sleep_on_busmaster(struct acpi_facp *facp) -{ - u32 pm1_cntr = acpi_read_pm1_control(facp); - if (pm1_cntr & ACPI_BM_RLD) { - pm1_cntr &= ~ACPI_BM_RLD; - acpi_write_pm1_control(facp, pm1_cntr); - } -} - -/* - * Set system to wake on busmaster requests - */ -static void -acpi_wake_on_busmaster(struct acpi_facp *facp) -{ - u32 pm1_cntr = acpi_read_pm1_control(facp); - if (!(pm1_cntr & ACPI_BM_RLD)) { - pm1_cntr |= ACPI_BM_RLD; - acpi_write_pm1_control(facp, pm1_cntr); - } - acpi_clear_bm_activity(facp); -} - -/* The ACPI timer is just the low 24 bits */ -#define TIME_BEGIN(tmr) inl(tmr) -#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff) - -/* - * Idle loop (uniprocessor only) - */ -void -acpi_idle(void) -{ - static int sleep_level = 1; - struct acpi_facp *facp = acpi_facp; - - if (!facp - || facp->hdr.signature != ACPI_FACP_SIG - || !facp->pm_tmr - || !acpi_pblk) - goto not_initialized; - - /* - * start from the previous sleep level.. - */ - if (sleep_level == 1) - goto sleep1; - if (sleep_level == 2) - goto sleep2; - sleep3: - sleep_level = 3; - if (!acpi_c3_tested) { - printk(KERN_DEBUG "ACPI C3 works\n"); - acpi_c3_tested = 1; - } - acpi_wake_on_busmaster(facp); - if (facp->pm2_cnt) - goto sleep3_with_arbiter; - - for (;;) { - unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; - - __cli(); - if (current->need_resched) - goto out; - if (acpi_bm_activity(facp)) - goto sleep2; - - time = TIME_BEGIN(pm_tmr); - inb(acpi_pblk + ACPI_P_LVL3); - /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); - - __sti(); - if (time < acpi_c3_exit_latency) - goto sleep2; - } - - sleep3_with_arbiter: - for (;;) { - unsigned long time; - u8 arbiter; - unsigned int pm2_cntr = facp->pm2_cnt; - unsigned int pm_tmr = facp->pm_tmr; - - __cli(); - if (current->need_resched) - goto out; - if (acpi_bm_activity(facp)) - goto sleep2; - - time = TIME_BEGIN(pm_tmr); - arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS; - /* Disable arbiter, park on CPU */ - outb(arbiter | ACPI_ARB_DIS, pm2_cntr); - inb(acpi_pblk + ACPI_P_LVL3); - /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); - /* Enable arbiter again.. */ - outb(arbiter, pm2_cntr); - - __sti(); - if (time < acpi_c3_exit_latency) - goto sleep2; - } - - sleep2: - sleep_level = 2; - if (!acpi_c2_tested) { - printk(KERN_DEBUG "ACPI C2 works\n"); - acpi_c2_tested = 1; - } - acpi_wake_on_busmaster(facp); /* Required to track BM activity.. */ - for (;;) { - unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; - - __cli(); - if (current->need_resched) - goto out; - - time = TIME_BEGIN(pm_tmr); - inb(acpi_pblk + ACPI_P_LVL2); - /* Dummy read, force synchronization with the PMU */ - inl(pm_tmr); - time = TIME_END(pm_tmr, time); - - __sti(); - if (time < acpi_c2_exit_latency) - goto sleep1; - if (acpi_bm_activity(facp)) { - acpi_clear_bm_activity(facp); - continue; - } - if (time > acpi_c3_enter_latency) - goto sleep3; - } - - sleep1: - sleep_level = 1; - acpi_sleep_on_busmaster(facp); - for (;;) { - unsigned long time; - unsigned int pm_tmr = facp->pm_tmr; - - __cli(); - if (current->need_resched) - goto out; - time = TIME_BEGIN(pm_tmr); - safe_halt(); - time = TIME_END(pm_tmr, time); - if (time > acpi_c2_enter_latency) - goto sleep2; - } - - not_initialized: - for (;;) { - __cli(); - if (current->need_resched) - goto out; - safe_halt(); - } - - out: - __sti(); -} - -/* - * Enter soft-off (S5) - */ -static void -acpi_power_off(void) -{ - struct acpi_enter_sx_ctx ctx; - - if (!acpi_facp - || acpi_facp->hdr.signature != ACPI_FACP_SIG - || acpi_slptyp[ACPI_S5] == ACPI_INVALID) - return; - - init_waitqueue_head(&ctx.wait); - ctx.state = ACPI_S5; - acpi_enter_sx(&ctx); -} - -/* - * Get processor information - */ -static ACPI_STATUS -acpi_get_cpu_info(ACPI_HANDLE handle, u32 level, void *ctx, void **value) -{ - ACPI_OBJECT obj; - ACPI_CX_STATE lat[4]; - ACPI_CPU_THROTTLING_STATE throttle[ACPI_MAX_THROTTLE]; - ACPI_BUFFER buf; - int i, count; - - buf.length = sizeof(obj); - buf.pointer = &obj; - if (!ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buf))) - return AE_OK; - - printk(KERN_INFO "ACPI: PBLK %d @ 0x%04x:%d\n", - obj.processor.proc_id, - obj.processor.pblk_address, - obj.processor.pblk_length); - if (acpi_pblk != ACPI_INVALID - || !obj.processor.pblk_address - || obj.processor.pblk_length != 6) - return AE_OK; - - acpi_pblk = obj.processor.pblk_address; - - buf.length = sizeof(lat); - buf.pointer = lat; - if (!ACPI_SUCCESS(acpi_get_processor_cx_info(handle, &buf))) - return AE_OK; - - if (lat[2].latency < MAX_CX_STATE_LATENCY) { - printk(KERN_INFO "ACPI: C2 supported\n"); - acpi_c2_exit_latency = lat[2].latency; - } - if (lat[3].latency < MAX_CX_STATE_LATENCY) { - printk(KERN_INFO "ACPI: C3 supported\n"); - acpi_c3_exit_latency = lat[3].latency; - } - - memset(throttle, 0, sizeof(throttle)); - buf.length = sizeof(throttle); - buf.pointer = throttle; - - if (!ACPI_SUCCESS(acpi_get_processor_throttling_info(handle, &buf))) - return AE_OK; - - for (i = 0, count = 0; i < ACPI_MAX_THROTTLE; i++) { - if (throttle[i].percent_of_clock) - count++; - } - count--; - if (count > 0) - printk(KERN_INFO "ACPI: %d throttling states\n", count); - - return AE_OK; -} - -/* - * Fetch the FACP information - */ -static int -acpi_fetch_facp(void) -{ - ACPI_BUFFER buffer; - - buffer.pointer = acpi_facp; - buffer.length = sizeof(*acpi_facp); - if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) { - printk(KERN_ERR "ACPI: no FACP\n"); - kfree(acpi_facp); - return -ENODEV; - } - - if (acpi_facp->p_lvl2_lat - && acpi_facp->p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) { - acpi_c2_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl2_lat); - acpi_c2_enter_latency - = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); - } - if (acpi_facp->p_lvl3_lat - && acpi_facp->p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) { - acpi_c3_exit_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl3_lat); - acpi_c3_enter_latency - = ACPI_uS_TO_TMR_TICKS(acpi_facp->p_lvl3_lat * 5); - } - - return 0; -} - -/* - * Execute callbacks (interpret methods) - */ -static void -acpi_intrp_run(void) -{ - for (;;) { - struct acpi_intrp_entry *entry; - unsigned long flags; - - interruptible_sleep_on(&acpi_intrp_wait); - if (signal_pending(current)) - return; - - for (;;) { - entry = NULL; - - spin_lock_irqsave(&acpi_intrp_exec_lock, flags); - if (!list_empty(&acpi_intrp_exec)) { - entry = list_entry(acpi_intrp_exec.next, - struct acpi_intrp_entry, - list); - list_del(&entry->list); - } - spin_unlock_irqrestore(&acpi_intrp_exec_lock, flags); - - if (!entry) - break; - - (*entry->callback)(entry->context); - - kfree(entry); - } - } -} - -/* - * Initialize and run interpreter within a kernel thread - */ -static int -acpi_intrp_thread(void *context) -{ - ACPI_STATUS status; - u8 sx, typa, typb; - - /* - * initialize interpreter - */ - exit_files(current); - daemonize(); - strcpy(current->comm, "acpi"); - - if (!ACPI_SUCCESS(acpi_initialize(NULL))) { - printk(KERN_ERR "ACPI: initialize failed\n"); - return -ENODEV; - } - - if (!ACPI_SUCCESS(acpi_load_firmware_tables())) { - printk(KERN_ERR "ACPI: table load failed\n"); - acpi_terminate(); - return -ENODEV; - } - - if (acpi_fetch_facp()) { - acpi_terminate(); - return -ENODEV; - } - - status = acpi_load_namespace(); - if (!ACPI_SUCCESS(status) && status != AE_CTRL_PENDING) { - printk(KERN_ERR "ACPI: namespace load failed\n"); - acpi_terminate(); - return -ENODEV; - } - - printk(KERN_INFO "ACPI: ACPI support found\n"); - - acpi_walk_namespace(ACPI_TYPE_PROCESSOR, - ACPI_ROOT_OBJECT, - ACPI_INT32_MAX, - acpi_get_cpu_info, - NULL, - NULL); - - for (sx = ACPI_S0; sx <= ACPI_S5; sx++) { - int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1); - if (ACPI_SUCCESS( - acpi_hw_obtain_sleep_type_register_data(ca_sx, - &typa, - &typb))) - acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb); - else - acpi_slptyp[sx] = ACPI_INVALID; - } - if (acpi_slptyp[ACPI_S1] != ACPI_INVALID) - printk(KERN_INFO "ACPI: S1 supported\n"); - if (acpi_slptyp[ACPI_S5] != ACPI_INVALID) - printk(KERN_INFO "ACPI: S5 supported\n"); - - if (!ACPI_SUCCESS(acpi_enable())) { - printk(KERN_ERR "ACPI: enable failed\n"); - acpi_terminate(); - return -ENODEV; - } - - if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( - ACPI_EVENT_POWER_BUTTON, - acpi_event, - (void *) ACPI_EVENT_POWER_BUTTON))) { - printk(KERN_ERR "ACPI: power button enable failed\n"); - } - if (!ACPI_SUCCESS(acpi_install_fixed_event_handler( - ACPI_EVENT_SLEEP_BUTTON, - acpi_event, - (void *) ACPI_EVENT_SLEEP_BUTTON))) { - printk(KERN_ERR "ACPI: sleep button enable failed\n"); - } - -#ifdef CONFIG_SMP - if (smp_num_cpus == 1) - pm_idle = acpi_idle; -#else - pm_idle = acpi_idle; -#endif - pm_power_off = acpi_power_off; - - acpi_sysctl = register_sysctl_table(acpi_dir_table, 1); - - /* - * run interpreter - */ - acpi_intrp_run(); - - /* - * terminate interpreter - */ - unregister_sysctl_table(acpi_sysctl); - acpi_terminate(); - - acpi_intrp_pid = -1; - - return 0; -} - -/* - * Start the interpreter - */ -int __init -acpi_init(void) -{ - acpi_facp = kmalloc(sizeof(*acpi_facp), GFP_KERNEL); - if (!acpi_facp) - return -ENOMEM; - memset(acpi_facp, 0, sizeof(*acpi_facp)); - - acpi_intrp_pid = kernel_thread(acpi_intrp_thread, - NULL, - (CLONE_FS | CLONE_FILES - | CLONE_SIGHAND | SIGCHLD)); - return ((acpi_intrp_pid >= 0) ? 0:-ENODEV); -} - -/* - * Terminate the interpreter - */ -void __exit -acpi_exit(void) -{ - int count; - - if (!kill_proc(acpi_intrp_pid, SIGTERM, 1)) { - // wait until interpreter thread terminates (at most 5 seconds) - count = 5 * HZ; - while (acpi_intrp_pid >= 0 && --count) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(1); - } - } - - // clean up after the interpreter - - if (acpi_irq_handler) { - acpi_os_remove_interrupt_handler(acpi_irq_irq, - acpi_irq_handler); - } - - if (pm_power_off == acpi_power_off) - pm_power_off = NULL; - if (pm_idle == acpi_idle) - pm_idle = NULL; - - kfree(acpi_facp); -} - -module_init(acpi_init); -module_exit(acpi_exit); - -/* - * OS-dependent functions - * - */ - -char * -strupr(char *str) -{ - char *s = str; - while (*s) { - *s = TOUPPER(*s); - s++; - } - return str; -} - -ACPI_STATUS -acpi_os_initialize(void) -{ - return AE_OK; -} - -ACPI_STATUS -acpi_os_terminate(void) -{ - return AE_OK; -} - -s32 -acpi_os_printf(const char *fmt,...) -{ - s32 size; - va_list args; - va_start(args, fmt); - size = acpi_os_vprintf(fmt, args); - va_end(args); - return size; -} - -s32 -acpi_os_vprintf(const char *fmt, va_list args) -{ - static char buffer[512]; - int size = vsprintf(buffer, fmt, args); - printk(KERN_DEBUG "%s", buffer); - return size; -} - -void * -acpi_os_allocate(u32 size) -{ - return kmalloc(size, GFP_KERNEL); -} - -void * -acpi_os_callocate(u32 size) -{ - void *ptr = acpi_os_allocate(size); - if (ptr) - memset(ptr, 0, size); - return ptr; -} - -void -acpi_os_free(void *ptr) -{ - kfree(ptr); -} - -ACPI_STATUS -acpi_os_map_memory(void *phys, u32 size, void **virt) -{ - if ((unsigned long) phys < virt_to_phys(high_memory)) { - *virt = phys_to_virt((unsigned long) phys); - return AE_OK; - } - - *virt = ioremap((unsigned long) phys, size); - if (!*virt) - return AE_ERROR; - - return AE_OK; -} - -void -acpi_os_unmap_memory(void *virt, u32 size) -{ - if (virt >= high_memory) - iounmap(virt); -} - -static void -acpi_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - (*acpi_irq_handler)(acpi_irq_context); -} - -ACPI_STATUS -acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) -{ - acpi_irq_irq = irq; - acpi_irq_handler = handler; - acpi_irq_context = context; - if (request_irq(irq, - acpi_irq, - SA_INTERRUPT | SA_SHIRQ, - "acpi", - acpi_irq)) { - printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq); - return AE_ERROR; - } - return AE_OK; -} - -ACPI_STATUS -acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) -{ - if (acpi_irq_handler) { - free_irq(irq, acpi_irq); - acpi_irq_handler = NULL; - } - return AE_OK; -} - -/* - * Running in interpreter thread context, safe to sleep - */ - -void -acpi_os_sleep(u32 sec, u32 ms) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ * sec + (ms * HZ) / 1000); -} - -void -acpi_os_sleep_usec(u32 us) -{ - udelay(us); -} - -u8 -acpi_os_in8(ACPI_IO_ADDRESS port) -{ - return inb(port); -} - -u16 -acpi_os_in16(ACPI_IO_ADDRESS port) -{ - return inw(port); -} - -u32 -acpi_os_in32(ACPI_IO_ADDRESS port) -{ - return inl(port); -} - -void -acpi_os_out8(ACPI_IO_ADDRESS port, u8 val) -{ - outb(val, port); -} - -void -acpi_os_out16(ACPI_IO_ADDRESS port, u16 val) -{ - outw(val, port); -} - -void -acpi_os_out32(ACPI_IO_ADDRESS port, u32 val) -{ - outl(val, port); -} - -ACPI_STATUS -acpi_os_read_pci_cfg_byte( - u32 bus, - u32 func, - u32 addr, - u8 * val) -{ - int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); - struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); - if (!val || !dev || pci_read_config_byte(dev, addr, val)) - return AE_ERROR; - return AE_OK; -} - -ACPI_STATUS -acpi_os_read_pci_cfg_word( - u32 bus, - u32 func, - u32 addr, - u16 * val) -{ - int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); - struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); - if (!val || !dev || pci_read_config_word(dev, addr, val)) - return AE_ERROR; - return AE_OK; -} - -ACPI_STATUS -acpi_os_read_pci_cfg_dword( - u32 bus, - u32 func, - u32 addr, - u32 * val) -{ - int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); - struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); - if (!val || !dev || pci_read_config_dword(dev, addr, val)) - return AE_ERROR; - return AE_OK; -} - -ACPI_STATUS -acpi_os_write_pci_cfg_byte( - u32 bus, - u32 func, - u32 addr, - u8 val) -{ - int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); - struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); - if (!dev || pci_write_config_byte(dev, addr, val)) - return AE_ERROR; - return AE_OK; -} - -ACPI_STATUS -acpi_os_write_pci_cfg_word( - u32 bus, - u32 func, - u32 addr, - u16 val) -{ - int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); - struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); - if (!dev || pci_write_config_word(dev, addr, val)) - return AE_ERROR; - return AE_OK; -} - -ACPI_STATUS -acpi_os_write_pci_cfg_dword( - u32 bus, - u32 func, - u32 addr, - u32 val) -{ - int devfn = PCI_DEVFN((func >> 16) & 0xffff, func & 0xffff); - struct pci_dev *dev = pci_find_slot(bus & 0xffff, devfn); - if (!dev || pci_write_config_dword(dev, addr, val)) - return AE_ERROR; - return AE_OK; -} - -/* - * Queue for interpreter thread - */ - -ACPI_STATUS -acpi_os_queue_for_execution( - u32 priority, - OSD_EXECUTION_CALLBACK callback, - void *context) -{ - struct acpi_intrp_entry *entry; - unsigned long flags; - - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); - if (!entry) - return AE_ERROR; - - memset(entry, 0, sizeof(entry)); - entry->priority = priority; - entry->callback = callback; - entry->context = context; - INIT_LIST_HEAD(&entry->list); - - if (!waitqueue_active(&acpi_intrp_wait)) { - kfree(entry); - return AE_ERROR; - } - - spin_lock_irqsave(&acpi_intrp_exec_lock, flags); - list_add(&entry->list, &acpi_intrp_exec); - wake_up(&acpi_intrp_wait); - spin_unlock_irqrestore(&acpi_intrp_exec_lock, flags); - - return AE_OK; -} - -/* - * Semaphores are unused, interpreter access is single threaded - */ - -ACPI_STATUS -acpi_os_create_semaphore(u32 max_units, u32 init, ACPI_HANDLE * handle) -{ - *handle = (ACPI_HANDLE) 0; - return AE_OK; -} - -ACPI_STATUS -acpi_os_delete_semaphore(ACPI_HANDLE handle) -{ - return AE_OK; -} - -ACPI_STATUS -acpi_os_wait_semaphore(ACPI_HANDLE handle, u32 units, u32 timeout) -{ - return AE_OK; -} - -ACPI_STATUS -acpi_os_signal_semaphore(ACPI_HANDLE handle, u32 units) -{ - return AE_OK; -} - -ACPI_STATUS -acpi_os_breakpoint(char *msg) -{ - acpi_os_printf("breakpoint: %s", msg); - return AE_OK; -} - -void -acpi_os_dbg_trap(char *msg) -{ - acpi_os_printf("trap: %s", msg); -} - -void -acpi_os_dbg_assert(void *failure, void *file, u32 line, char *msg) -{ - acpi_os_printf("assert: %s", msg); -} - -u32 -acpi_os_get_line(char *buffer) -{ - return 0; -} - -/* - * We just have to assume we're dealing with valid memory - */ - -BOOLEAN -acpi_os_readable(void *ptr, u32 len) -{ - return 1; -} - -BOOLEAN -acpi_os_writable(void *ptr, u32 len) -{ - return 1; -} diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/sys.c linux/drivers/acpi/sys.c --- v2.4.0-test3/linux/drivers/acpi/sys.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/acpi/sys.c Thu Jul 13 09:39:49 2000 @@ -0,0 +1,182 @@ +/* + * sys.c - System management (suspend, ...) + * + * Copyright (C) 2000 Andrew Henroid + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include "acpi.h" +#include "driver.h" + +#define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb)) +#define ACPI_SLP_TYPA(value) \ + ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) +#define ACPI_SLP_TYPB(value) \ + ((((value) & 0xff) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK) + +struct acpi_enter_sx_ctx +{ + wait_queue_head_t wait; + int state; +}; + +volatile acpi_sstate_t acpi_sleep_state = ACPI_S0; +static unsigned long acpi_slptyp[ACPI_S5 + 1] = {ACPI_INVALID,}; + +/* + * Enter system sleep state + */ +static void +acpi_enter_sx_async(void *context) +{ + struct acpi_enter_sx_ctx *ctx = (struct acpi_enter_sx_ctx*) context; + struct acpi_facp *facp = &acpi_facp; + ACPI_OBJECT_LIST arg_list; + ACPI_OBJECT arg; + u16 value; + + /* + * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. + */ + + // run the _PTS method + memset(&arg_list, 0, sizeof(arg_list)); + arg_list.count = 1; + arg_list.pointer = &arg; + + memset(&arg, 0, sizeof(arg)); + arg.type = ACPI_TYPE_NUMBER; + arg.number.value = ctx->state; + + acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL); + + // clear wake status + acpi_write_pm1_status(facp, ACPI_WAK); + + acpi_sleep_state = ctx->state; + + // set ACPI_SLP_TYPA/b and ACPI_SLP_EN + __cli(); + if (facp->pm1a_cnt) { + value = inw(facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK; + value |= (ACPI_SLP_TYPA(acpi_slptyp[ctx->state]) + | ACPI_SLP_EN); + outw(value, facp->pm1a_cnt); + } + if (facp->pm1b_cnt) { + value = inw(facp->pm1b_cnt) & ~ACPI_SLP_TYP_MASK; + value |= (ACPI_SLP_TYPB(acpi_slptyp[ctx->state]) + | ACPI_SLP_EN); + outw(value, facp->pm1b_cnt); + } + __sti(); + + if (ctx->state != ACPI_S1) { + printk(KERN_ERR "ACPI: S%d failed\n", ctx->state); + goto out; + } + + // wait until S1 is entered + while (!(acpi_read_pm1_status(facp) & ACPI_WAK)) + safe_halt(); + + // run the _WAK method + memset(&arg_list, 0, sizeof(arg_list)); + arg_list.count = 1; + arg_list.pointer = &arg; + + memset(&arg, 0, sizeof(arg)); + arg.type = ACPI_TYPE_NUMBER; + arg.number.value = ctx->state; + + acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL); + + out: + acpi_sleep_state = ACPI_S0; + + if (waitqueue_active(&ctx->wait)) + wake_up_interruptible(&ctx->wait); +} + +/* + * Enter soft-off (S5) + */ +static void +acpi_power_off(void) +{ + struct acpi_enter_sx_ctx ctx; + + if (acpi_facp.hdr.signature != ACPI_FACP_SIG + || acpi_slptyp[ACPI_S5] == ACPI_INVALID) + return; + + init_waitqueue_head(&ctx.wait); + ctx.state = ACPI_S5; + acpi_enter_sx_async(&ctx); +} + +/* + * Enter system sleep state and wait for completion + */ +int +acpi_enter_sx(acpi_sstate_t state) +{ + struct acpi_enter_sx_ctx ctx; + + if (acpi_facp.hdr.signature != ACPI_FACP_SIG + || acpi_slptyp[state] == ACPI_INVALID) + return -EINVAL; + + init_waitqueue_head(&ctx.wait); + ctx.state = state; + + if (acpi_os_queue_for_execution(0, acpi_enter_sx_async, &ctx)) + return -1; + + interruptible_sleep_on(&ctx.wait); + if (signal_pending(current)) + return -ERESTARTSYS; + + return 0; +} + +int +acpi_sys_init(void) +{ + u8 sx, typa, typb; + + for (sx = ACPI_S0; sx <= ACPI_S5; sx++) { + int ca_sx = (sx <= ACPI_S4) ? sx : (sx + 1); + if (ACPI_SUCCESS( + acpi_hw_obtain_sleep_type_register_data(ca_sx, + &typa, + &typb))) + acpi_slptyp[sx] = ACPI_SLP_TYP(typa, typb); + else + acpi_slptyp[sx] = ACPI_INVALID; + } + if (acpi_slptyp[ACPI_S1] != ACPI_INVALID) + printk(KERN_INFO "ACPI: S1 supported\n"); + if (acpi_slptyp[ACPI_S5] != ACPI_INVALID) + printk(KERN_INFO "ACPI: S5 supported\n"); + + pm_power_off = acpi_power_off; + + return 0; +} diff -u --recursive --new-file v2.4.0-test3/linux/drivers/acpi/tables.c linux/drivers/acpi/tables.c --- v2.4.0-test3/linux/drivers/acpi/tables.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/acpi/tables.c Thu Jul 13 09:39:49 2000 @@ -0,0 +1,303 @@ +/* + * tables.c - ACPI tables, chipset, and errata handling + * + * Copyright (C) 2000 Andrew Henroid + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include "acpi.h" +#include "driver.h" + +struct acpi_facp acpi_facp; + +#define ACPI_DUMMY_CHECKSUM 9 +#define ACPI_DUMMY_PBLK 51 + +static u8 acpi_dummy_dsdt[] = +{ + 0x44, 0x53, 0x44, 0x54, // "DSDT" + 0x38, 0x00, 0x00, 0x00, // length + 0x01, // revision + 0x00, // checksum + 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00, // "LINUX" + 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY" + 0x01, 0x00, 0x00, 0x00, // OEM rev + 0x4c, 0x4e, 0x55, 0x58, // "LNUX" + 0x01, 0x00, 0x00, 0x00, // creator rev + 0x10, // Scope + 0x13, // PkgLength + 0x5c, 0x5f, 0x50, 0x52, 0x5f, // \_PR_ + 0x5b, 0x83, // Processor + 0x0b, // PkgLength + 0x43, 0x50, 0x55, 0x30, // CPU0 + 0x00, // ID + 0x00, 0x00, 0x00, 0x00, // PBLK + 0x06 // PBLK size +}; + +/* + * Calculate and set ACPI table checksum + */ +static void +acpi_set_checksum(u8 *table, int size) +{ + int i, sum = 0; + for (i = 0; i < size; i++) + sum += (int) table[i]; + sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff)); + table[ACPI_DUMMY_CHECKSUM] = sum; +} + +/* + * Init PIIX4 device, create a fake FACP + */ +static int +acpi_init_piix4(struct pci_dev *dev) +{ + u32 base, pblk; + u16 cmd; + u8 pmregmisc; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + if (!(cmd & PCI_COMMAND_IO)) + return -ENODEV; + + pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc); + if (!(pmregmisc & ACPI_PIIX4_PMIOSE)) + return -ENODEV; + + base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES); + if (!base) + return -ENODEV; + + printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); + + memset(&acpi_facp, 0, sizeof(acpi_facp)); + acpi_facp.hdr.signature = ACPI_FACP_SIG; + acpi_facp.hdr.length = sizeof(acpi_facp); + acpi_facp.int_model = ACPI_PIIX4_INT_MODEL; + acpi_facp.sci_int = ACPI_PIIX4_SCI_INT; + acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD; + acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE; + acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE; + acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ; + acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT; + acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT; + acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT; + acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR; + acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0; + acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN; + acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN; + acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN; + acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN; + acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN; + acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; + acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; + + acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); + acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); + + pblk = base + ACPI_PIIX4_P_BLK; + memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); + acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); + acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); + + return 0; +} + +/* + * Init VIA ACPI device and create a fake FACP + */ +static int +acpi_init_via(struct pci_dev *dev) +{ + u32 base, pblk; + u8 tmp, irq; + + pci_read_config_byte(dev, 0x41, &tmp); + if (!(tmp & 0x80)) + return -ENODEV; + + base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES); + if (!base) { + base = pci_resource_start(dev, PCI_BASE_ADDRESS_4); + if (!base) + return -ENODEV; + } + + pci_read_config_byte(dev, 0x42, &irq); + + printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base); + + memset(&acpi_facp, 0, sizeof(acpi_facp)); + acpi_facp.hdr.signature = ACPI_FACP_SIG; + acpi_facp.hdr.length = sizeof(acpi_facp); + acpi_facp.int_model = ACPI_VIA_INT_MODEL; + acpi_facp.sci_int = irq; + acpi_facp.smi_cmd = base + ACPI_VIA_SMI_CMD; + acpi_facp.acpi_enable = ACPI_VIA_ACPI_ENABLE; + acpi_facp.acpi_disable = ACPI_VIA_ACPI_DISABLE; + acpi_facp.pm1a_evt = base + ACPI_VIA_PM1_EVT; + acpi_facp.pm1a_cnt = base + ACPI_VIA_PM1_CNT; + acpi_facp.pm_tmr = base + ACPI_VIA_PM_TMR; + acpi_facp.gpe0 = base + ACPI_VIA_GPE0; + + acpi_facp.pm1_evt_len = ACPI_VIA_PM1_EVT_LEN; + acpi_facp.pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN; + acpi_facp.pm_tm_len = ACPI_VIA_PM_TM_LEN; + acpi_facp.gpe0_len = ACPI_VIA_GPE0_LEN; + acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT; + acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT; + + acpi_facp.duty_offset = ACPI_VIA_DUTY_OFFSET; + acpi_facp.duty_width = ACPI_VIA_DUTY_WIDTH; + + acpi_facp.day_alarm = ACPI_VIA_DAY_ALARM; + acpi_facp.mon_alarm = ACPI_VIA_MON_ALARM; + acpi_facp.century = ACPI_VIA_CENTURY; + + acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp)); + acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp); + + pblk = base + ACPI_VIA_P_BLK; + memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk)); + acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt)); + acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt); + + return 0; +} + +typedef enum +{ + CH_UNKNOWN = 0, + CH_INTEL_PIIX4, + CH_VIA_586, + CH_VIA_686A, +} acpi_chip_t; + +/* indexed by value of each enum in acpi_chip_t */ +const static struct +{ + int (*chip_init)(struct pci_dev *dev); +} acpi_chip_info[] = +{ + {NULL,}, + {acpi_init_piix4}, + {acpi_init_via}, + {acpi_init_via}, +}; + +static struct pci_device_id acpi_pci_tbl[] = +{ + {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4}, + {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586}, + {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A}, + {0,} /* terminate list */ +}; + +static int +acpi_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return acpi_chip_info[id->driver_data].chip_init(dev); +} + +static struct pci_driver acpi_driver = +{ + name: "acpi", + id_table: acpi_pci_tbl, + probe: acpi_probe, +}; +static int acpi_driver_registered = 0; + +/* + * Locate a known ACPI chipset + */ +static int +acpi_find_chipset(void) +{ + if (pci_register_driver(&acpi_driver) < 1) + return -ENODEV; + acpi_driver_registered = 1; + return 0; +} + +/* + * Fetch the FACP information + */ +static int +acpi_fetch_facp(void) +{ + ACPI_BUFFER buffer; + + memset(&acpi_facp, 0, sizeof(acpi_facp)); + buffer.pointer = &acpi_facp; + buffer.length = sizeof(acpi_facp); + if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) { + printk(KERN_ERR "ACPI: missing FACP\n"); + return -ENODEV; + } + + if (acpi_facp.p_lvl2_lat + && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) { + acpi_c2_exit_latency + = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat); + acpi_c2_enter_latency + = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); + } + if (acpi_facp.p_lvl3_lat + && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) { + acpi_c3_exit_latency + = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat); + acpi_c3_enter_latency + = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5); + } + + return 0; +} + +/* + * Find and load ACPI tables + */ +int +acpi_load_tables(void) +{ + if (ACPI_SUCCESS(acpi_load_firmware_tables())) + { + printk(KERN_INFO "ACPI: support found\n"); + } + else if (acpi_find_chipset()) { + acpi_terminate(); + return -1; + } + + if (acpi_fetch_facp()) { + acpi_terminate(); + return -1; + } + + if (!ACPI_SUCCESS(acpi_load_namespace())) { + printk(KERN_ERR "ACPI: namespace load failed\n"); + acpi_terminate(); + return -1; + } + + return 0; +} diff -u --recursive --new-file v2.4.0-test3/linux/drivers/block/acsi_slm.c linux/drivers/block/acsi_slm.c --- v2.4.0-test3/linux/drivers/block/acsi_slm.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/block/acsi_slm.c Wed Jul 12 21:58:42 2000 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -799,10 +800,12 @@ device = MINOR(inode->i_rdev); sip = &slm_info[device]; + lock_kernel(); if (file->f_mode & 2) sip->wbusy = 0; if (file->f_mode & 1) sip->rbusy = 0; + unlock_kernel(); return( 0 ); } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- v2.4.0-test3/linux/drivers/block/ll_rw_blk.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/block/ll_rw_blk.c Wed Jul 12 20:07:39 2000 @@ -578,7 +578,6 @@ static inline void __make_request(request_queue_t * q, int rw, struct buffer_head * bh) { - int major = MAJOR(bh->b_rdev); unsigned int sector, count; int max_segments = MAX_SEGMENTS; struct request * req = NULL; @@ -590,26 +589,6 @@ count = bh->b_size >> 9; sector = bh->b_rsector; - if (blk_size[major]) { - unsigned long maxsector = (blk_size[major][MINOR(bh->b_rdev)] << 1) + 1; - - if (maxsector < count || maxsector - count < sector) { - bh->b_state &= (1 << BH_Lock) | (1 << BH_Mapped); - if (!blk_size[major][MINOR(bh->b_rdev)]) - goto end_io; - /* This may well happen - the kernel calls bread() - without checking the size of the device, e.g., - when mounting a device. */ - printk(KERN_INFO - "attempt to access beyond end of device\n"); - printk(KERN_INFO "%s: rw=%d, want=%d, limit=%d\n", - kdevname(bh->b_rdev), rw, - (sector + count)>>1, - blk_size[major][MINOR(bh->b_rdev)]); - goto end_io; - } - } - rw_ahead = 0; /* normal case; gets changed below for READA */ switch (rw) { case READA: @@ -758,9 +737,35 @@ bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state)); } -int generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh) +void generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { - int ret; + int major = MAJOR(bh->b_rdev); + + if (blk_size[major]) { + unsigned long maxsector = (blk_size[major][MINOR(bh->b_rdev)] << 1) + 1; + unsigned int sector, count; + + count = bh->b_size >> 9; + sector = bh->b_rsector; + + if (maxsector < count || maxsector - count < sector) { + bh->b_state &= (1 << BH_Lock) | (1 << BH_Mapped); + if (blk_size[major][MINOR(bh->b_rdev)]) { + + /* This may well happen - the kernel calls bread() + without checking the size of the device, e.g., + when mounting a device. */ + printk(KERN_INFO + "attempt to access beyond end of device\n"); + printk(KERN_INFO "%s: rw=%d, want=%d, limit=%d\n", + kdevname(bh->b_rdev), rw, + (sector + count)>>1, + blk_size[major][MINOR(bh->b_rdev)]); + } + bh->b_end_io(bh, 0); + return; + } + } /* * Resolve the mapping until finished. (drivers are @@ -768,12 +773,9 @@ * by explicitly returning 0) */ while (q->make_request_fn) { - ret = q->make_request_fn(q, rw, bh); - if (ret > 0) { - q = blk_get_queue(bh->b_rdev); - continue; - } - return ret; + if (q->make_request_fn(q, rw, bh) == 0) + return; + q = blk_get_queue(bh->b_rdev); } /* * Does the block device want us to queue @@ -784,16 +786,13 @@ if (q && !q->plugged) (q->request_fn)(q); spin_unlock_irq(&io_request_lock); - - return 0; } /* This function can be used to request a number of buffers from a block device. Currently the only restriction is that all buffers must belong to the same device */ -static void __ll_rw_block(int rw, int nr, struct buffer_head * bhs[], - int haslock) +void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]) { struct buffer_head *bh; request_queue_t *q; @@ -840,13 +839,9 @@ bh = bhs[i]; /* Only one thread can actually submit the I/O. */ - if (haslock) { - if (!buffer_locked(bh)) - BUG(); - } else { - if (test_and_set_bit(BH_Lock, &bh->b_state)) - continue; - } + if (test_and_set_bit(BH_Lock, &bh->b_state)) + continue; + set_bit(BH_Req, &bh->b_state); /* @@ -865,15 +860,6 @@ buffer_IO_error(bhs[i]); } -void ll_rw_block(int rw, int nr, struct buffer_head * bh[]) -{ - __ll_rw_block(rw, nr, bh, 0); -} - -void ll_rw_block_locked(int rw, int nr, struct buffer_head * bh[]) -{ - __ll_rw_block(rw, nr, bh, 1); -} #ifdef CONFIG_STRAM_SWAP extern int stram_device_init (void); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/block/lvm.c linux/drivers/block/lvm.c --- v2.4.0-test3/linux/drivers/block/lvm.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/block/lvm.c Wed Jul 12 21:58:42 2000 @@ -301,6 +301,7 @@ static struct file_operations lvm_chr_fops = { + owner: THIS_MODULE, open: lvm_chr_open, release: lvm_chr_close, ioctl: lvm_chr_ioctl, @@ -517,8 +518,6 @@ /* Group special file open */ if (VG_CHR(minor) > MAX_VG) return -ENXIO; - MOD_INC_USE_COUNT; - lvm_chr_open_count++; return 0; } /* lvm_chr_open() */ @@ -743,6 +742,7 @@ "%s -- lvm_chr_close VG#: %d\n", lvm_name, VG_CHR(minor)); #endif + lock_kernel(); #ifdef LVM_TOTAL_RESET if (lvm_reset_spindown > 0) { lvm_reset_spindown = 0; @@ -755,10 +755,7 @@ lock = 0; /* release lock */ wake_up_interruptible(&lvm_wait); } - -#ifdef MODULE - if (GET_USE_COUNT(&__this_module) > 0) MOD_DEC_USE_COUNT; -#endif + unlock_kernel(); return 0; } /* lvm_chr_close() */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/block/md.c linux/drivers/block/md.c --- v2.4.0-test3/linux/drivers/block/md.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/block/md.c Wed Jul 12 12:42:19 2000 @@ -2908,7 +2908,7 @@ * many dirty RAID5 blocks. */ current->policy = SCHED_OTHER; - current->priority = 40; + current->nice = -20; // md_unlock_kernel(); up(thread->sem); @@ -3336,7 +3336,7 @@ /* * Resync has low priority. */ - current->priority = 1; + current->nice = 19; is_mddev_idle(mddev); /* this also initializes IO event counters */ for (m = 0; m < SYNC_MARKS; m++) { @@ -3412,7 +3412,7 @@ currspeed = (j-mddev->resync_mark_cnt)/((jiffies-mddev->resync_mark)/HZ +1) +1; if (currspeed > sysctl_speed_limit_min) { - current->priority = 1; + current->nice = 19; if ((currspeed > sysctl_speed_limit_max) || !is_mddev_idle(mddev)) { @@ -3422,7 +3422,7 @@ goto repeat; } } else - current->priority = 40; + current->nice = -20; } fsync_dev(read_disk); printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev)); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/block/paride/paride.c linux/drivers/block/paride/paride.c --- v2.4.0-test3/linux/drivers/block/paride/paride.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/block/paride/paride.c Wed Jul 12 16:24:33 2000 @@ -13,10 +13,11 @@ 1.02 GRG 1998.05.05 init_proto, release_proto, ktti 1.03 GRG 1998.08.15 eliminate compiler warning 1.04 GRG 1998.11.28 added support for FRIQ - + 1.05 TMW 2000.06.06 use parport_find_number instead of + parport_enumerate */ -#define PI_VERSION "1.04" +#define PI_VERSION "1.05" #include #include @@ -238,22 +239,25 @@ { #ifdef CONFIG_PARPORT - struct parport *pp; - - pp = parport_enumerate(); + struct parport *port; - while((pp)&&(pp->base != pi->port)) pp = pp->next; + port = parport_find_base (pi->port); + if (!port) return; - if (!pp) return; + pi->pardev = parport_register_device(port, + pi->device,NULL, + pi_wake_up,NULL, + 0,(void *)pi); + parport_put_port (port); + if (!pi->pardev) return; - pi->pardev = (void *) parport_register_device( - pp,pi->device,NULL,pi_wake_up,NULL,0,(void *)pi); init_waitqueue_head(&pi->parq); - if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,pp->name); + if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port, + port->name); - pi->parname = (char *)pp->name; + pi->parname = (char *)port->name; #endif } @@ -406,6 +410,7 @@ { int k; for (k=0;k #include #include +#include #include @@ -604,10 +605,12 @@ if ((unit >= PG_UNITS) || (PG.access <= 0)) return -EINVAL; + lock_kernel(); PG.access--; kfree(PG.bufptr); PG.bufptr = NULL; + unlock_kernel(); return 0; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/block/paride/pt.c linux/drivers/block/paride/pt.c --- v2.4.0-test3/linux/drivers/block/paride/pt.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/block/paride/pt.c Wed Jul 12 21:58:42 2000 @@ -149,6 +149,7 @@ #include #include #include +#include #include @@ -773,6 +774,7 @@ if ((unit >= PT_UNITS) || (PT.access <= 0)) return -EINVAL; + lock_kernel(); if (PT.flags & PT_WRITING) pt_write_fm(unit); if (PT.flags & PT_REWIND) pt_rewind(unit); @@ -781,6 +783,7 @@ kfree(PT.bufptr); PT.bufptr = NULL; + unlock_kernel(); return 0; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.4.0-test3/linux/drivers/block/rd.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/block/rd.c Wed Jul 12 21:58:42 2000 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -298,11 +299,14 @@ { extern void free_initrd_mem(unsigned long, unsigned long); - if (--initrd_users) return 0; - blkdev_put(inode->i_bdev, BDEV_FILE); - iput(inode); - free_initrd_mem(initrd_start, initrd_end); - initrd_start = 0; + lock_kernel(); + if (!--initrd_users) { + blkdev_put(inode->i_bdev, BDEV_FILE); + iput(inode); + free_initrd_mem(initrd_start, initrd_end); + initrd_start = 0; + } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/acquirewdt.c linux/drivers/char/acquirewdt.c --- v2.4.0-test3/linux/drivers/char/acquirewdt.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/acquirewdt.c Wed Jul 12 21:58:42 2000 @@ -38,6 +38,7 @@ #include #include #include +#include static int acq_is_open=0; static spinlock_t acq_lock; @@ -140,6 +141,7 @@ static int acq_close(struct inode *inode, struct file *file) { + lock_kernel(); if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) { spin_lock(&acq_lock); @@ -149,6 +151,7 @@ acq_is_open=0; spin_unlock(&acq_lock); } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/agp/agpgart_fe.c linux/drivers/char/agp/agpgart_fe.c --- v2.4.0-test3/linux/drivers/char/agp/agpgart_fe.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/agp/agpgart_fe.c Wed Jul 12 21:58:42 2000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -605,14 +606,17 @@ agp_file_private *priv = (agp_file_private *) file->private_data; agp_kern_info kerninfo; + lock_kernel(); AGP_LOCK(); if (agp_fe.backend_acquired != TRUE) { AGP_UNLOCK(); + unlock_kernel(); return -EPERM; } if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags))) { AGP_UNLOCK(); + unlock_kernel(); return -EPERM; } agp_copy_info(&kerninfo); @@ -624,42 +628,51 @@ if (test_bit(AGP_FF_IS_CLIENT, &priv->access_flags)) { if ((size + offset) > current_size) { AGP_UNLOCK(); + unlock_kernel(); return -EINVAL; } client = agp_find_client_by_pid(current->pid); if (client == NULL) { AGP_UNLOCK(); + unlock_kernel(); return -EPERM; } if (!agp_find_seg_in_client(client, offset, size, vma->vm_page_prot)) { AGP_UNLOCK(); + unlock_kernel(); return -EINVAL; } if (remap_page_range(vma->vm_start, (kerninfo.aper_base + offset), size, vma->vm_page_prot)) { AGP_UNLOCK(); + unlock_kernel(); return -EAGAIN; } AGP_UNLOCK(); + unlock_kernel(); return 0; } if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) { if (size != current_size) { AGP_UNLOCK(); + unlock_kernel(); return -EINVAL; } if (remap_page_range(vma->vm_start, kerninfo.aper_base, size, vma->vm_page_prot)) { AGP_UNLOCK(); + unlock_kernel(); return -EAGAIN; } AGP_UNLOCK(); + unlock_kernel(); return 0; } AGP_UNLOCK(); + unlock_kernel(); return -EPERM; } @@ -667,6 +680,7 @@ { agp_file_private *priv = (agp_file_private *) file->private_data; + lock_kernel(); AGP_LOCK(); if (test_bit(AGP_FF_IS_CONTROLLER, &priv->access_flags)) { @@ -688,6 +702,7 @@ agp_remove_file_private(priv); kfree(priv); AGP_UNLOCK(); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/applicom.c linux/drivers/char/applicom.c --- v2.4.0-test3/linux/drivers/char/applicom.c Thu May 11 15:30:06 2000 +++ linux/drivers/char/applicom.c Wed Jul 12 21:58:42 2000 @@ -101,21 +101,18 @@ static unsigned int DeviceErrorCount; /* number of device error */ static loff_t ac_llseek(struct file *, loff_t, int); -static int ac_open(struct inode *, struct file *); static ssize_t ac_read (struct file *, char *, size_t, loff_t *); static ssize_t ac_write (struct file *, const char *, size_t, loff_t *); static int ac_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -static int ac_release(struct inode *, struct file *); static void ac_interrupt(int, void *, struct pt_regs *); struct file_operations ac_fops = { + owner:THIS_MODULE, llseek:ac_llseek, read:ac_read, write:ac_write, ioctl:ac_ioctl, - open:ac_open, - release:ac_release, }; struct miscdevice ac_miscdev = { @@ -124,6 +121,8 @@ &ac_fops }; +static int dummy; /* dev_id for request_irq() */ + int ac_register_board(unsigned long physloc, unsigned long loc, unsigned char boardno) { @@ -180,7 +179,7 @@ iounmap((void *) apbs[i].RamIO); if (apbs[i].irq) - free_irq(apbs[i].irq, &ac_open); + free_irq(apbs[i].irq, &dummy); } } @@ -226,7 +225,7 @@ continue; } - if (request_irq(dev->irq, &ac_interrupt, SA_SHIRQ, "Applicom PCI", &ac_open)) { + if (request_irq(dev->irq, &ac_interrupt, SA_SHIRQ, "Applicom PCI", &dummy)) { printk(KERN_INFO "Could not allocate IRQ %d for PCI Applicom device.\n", dev->irq); iounmap(RamIO); apbs[boardno - 1].RamIO = 0; @@ -277,7 +276,7 @@ printk(KERN_NOTICE "Applicom ISA card found at mem 0x%lx, irq %d\n", mem + (LEN_RAM_IO*i), irq); if (!numisa) { - if (request_irq(irq, &ac_interrupt, SA_SHIRQ, "Applicom ISA", &ac_open)) { + if (request_irq(irq, &ac_interrupt, SA_SHIRQ, "Applicom ISA", &dummy)) { printk(KERN_WARNING "Could not allocate IRQ %d for ISA Applicom device.\n", irq); iounmap((void *) RamIO); apbs[boardno - 1].RamIO = 0; @@ -345,19 +344,6 @@ { return -ESPIPE; } - -static int ac_open(struct inode *inode, struct file *filp) -{ - MOD_INC_USE_COUNT; - return 0; -} - -static int ac_release(struct inode *inode, struct file *file) -{ - MOD_DEC_USE_COUNT; - return 0; -} - static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t * ppos) { diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c --- v2.4.0-test3/linux/drivers/char/busmouse.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/busmouse.c Wed Jul 12 21:58:42 2000 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -167,6 +168,7 @@ struct busmouse_data *mse = (struct busmouse_data *)file->private_data; int ret = 0; + lock_kernel(); busmouse_fasync(-1, file, 0); if (--mse->active == 0) { @@ -178,6 +180,7 @@ } mse->ready = 0; } + unlock_kernel(); return ret; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c --- v2.4.0-test3/linux/drivers/char/cyclades.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/cyclades.c Wed Jul 12 16:19:41 2000 @@ -2,7 +2,7 @@ #define Z_WAKE #undef Z_EXT_CHARS_IN_BUFFER static char rcsid[] = -"$Revision: 2.3.2.7 $$Date: 2000/06/01 18:26:34 $"; +"$Revision: 2.3.2.8 $$Date: 2000/07/06 18:14:16 $"; /* * linux/drivers/char/cyclades.c @@ -25,6 +25,11 @@ * This version supports shared IRQ's (only for PCI boards). * * $Log: cyclades.c,v $ + * Revision 2.3.2.8 2000/07/06 18:14:16 ivan + * Fixed the PCI detection function to work properly on Alpha systems. + * Implemented support for TIOCSERGETLSR ioctl. + * Implemented full support for non-standard baud rates. + * * Revision 2.3.2.7 2000/06/01 18:26:34 ivan * Request PLX I/O region, although driver doesn't use it, to avoid * problems with other drivers accessing it. @@ -1363,9 +1368,16 @@ while (char_count-- > 0){ if (!info->xmit_cnt){ - cy_writeb((u_long)base_addr+(CySRER<xmit_buf == 0){ @@ -3176,6 +3188,30 @@ * ------------------------------------------------------------ */ +static void +cyy_baud_calc(struct cyclades_port *info, uclong baud) +{ + int co, co_val, bpr; + uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000); + + if (baud == 0) { + info->tbpr = info->tco = info->rbpr = info->rco = 0; + return; + } + + /* determine which prescaler to use */ + for (co = 4, co_val = 2048; co; co--, co_val >>= 2) { + if (cy_clock / co_val / baud > 63) + break; + } + + bpr = (cy_clock / co_val * 2 / baud + 1) / 2; + if (bpr > 255) + bpr = 255; + + info->tbpr = info->rbpr = bpr; + info->tco = info->rco = co; +} /* * This routine finds or computes the various line characteristics. @@ -3189,7 +3225,7 @@ int card,chip,channel,index; unsigned cflag, iflag; unsigned short chip_number; - int baud; + int baud, baud_rate = 0; int i; @@ -3225,12 +3261,14 @@ index = cy_card[card].bus_index; /* baud rate */ - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { - baud = info->baud; - } else { - baud = tty_get_baud_rate(info->tty); - } - if (baud > CD1400_MAX_SPEED) { + baud = tty_get_baud_rate(info->tty); + if ((baud == 38400) && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { + if (info->custom_divisor) + baud_rate = info->baud / info->custom_divisor; + else + baud_rate = info->baud; + } else if (baud > CD1400_MAX_SPEED) { baud = CD1400_MAX_SPEED; } /* find the baud index */ @@ -3243,22 +3281,29 @@ i = 19; /* CD1400_MAX_SPEED */ } - - if(info->chip_rev >= CD1400_REV_J) { - /* It is a CD1400 rev. J or later */ - info->tbpr = baud_bpr_60[i]; /* Tx BPR */ - info->tco = baud_co_60[i]; /* Tx CO */ - info->rbpr = baud_bpr_60[i]; /* Rx BPR */ - info->rco = baud_co_60[i]; /* Rx CO */ + if ((baud == 38400) && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { + cyy_baud_calc(info, baud_rate); } else { - info->tbpr = baud_bpr_25[i]; /* Tx BPR */ - info->tco = baud_co_25[i]; /* Tx CO */ - info->rbpr = baud_bpr_25[i]; /* Rx BPR */ - info->rco = baud_co_25[i]; /* Rx CO */ + if(info->chip_rev >= CD1400_REV_J) { + /* It is a CD1400 rev. J or later */ + info->tbpr = baud_bpr_60[i]; /* Tx BPR */ + info->tco = baud_co_60[i]; /* Tx CO */ + info->rbpr = baud_bpr_60[i]; /* Rx BPR */ + info->rco = baud_co_60[i]; /* Rx CO */ + } else { + info->tbpr = baud_bpr_25[i]; /* Tx BPR */ + info->tco = baud_co_25[i]; /* Tx CO */ + info->rbpr = baud_bpr_25[i]; /* Rx BPR */ + info->rco = baud_co_25[i]; /* Rx CO */ + } } if (baud_table[i] == 134) { - info->timeout = (info->xmit_fifo_size*HZ*15/269) + 2; /* get it right for 134.5 baud */ + info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2; + } else if ((baud == 38400) && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { + info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2; } else if (baud_table[i]) { info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2; /* this needs to be propagated into the card info */ @@ -3447,19 +3492,24 @@ buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; /* baud rate */ - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) { - baud = info->baud; - } else { - baud = tty_get_baud_rate(info->tty); - } - if (baud > CYZ_MAX_SPEED) { + baud = tty_get_baud_rate(info->tty); + if ((baud == 38400) && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { + if (info->custom_divisor) + baud_rate = info->baud / info->custom_divisor; + else + baud_rate = info->baud; + } else if (baud > CYZ_MAX_SPEED) { baud = CYZ_MAX_SPEED; } cy_writel(&ch_ctrl->comm_baud , baud); if (baud == 134) { - info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2; /* get it right for 134.5 baud */ + info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2; + } else if ((baud == 38400) && + ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { + info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2; } else if (baud) { info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2; /* this needs to be propagated into the card info */ @@ -3549,8 +3599,6 @@ clear_bit(TTY_IO_ERROR, &info->tty->flags); } } - - } /* set_line_char */ @@ -3571,7 +3619,7 @@ tmp.flags = info->flags; tmp.close_delay = info->close_delay; tmp.baud_base = info->baud; - tmp.custom_divisor = 0; /*!!!*/ + tmp.custom_divisor = info->custom_divisor; tmp.hub6 = 0; /*!!!*/ return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0; } /* get_serial_info */ @@ -3597,6 +3645,7 @@ info->flags = ((info->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); info->baud = new_serial.baud_base; + info->custom_divisor = new_serial.custom_divisor; goto check_and_exit; } @@ -3607,6 +3656,7 @@ */ info->baud = new_serial.baud_base; + info->custom_divisor = new_serial.custom_divisor; info->flags = ((info->flags & ~ASYNC_FLAGS) | (new_serial.flags & ASYNC_FLAGS)); info->close_delay = new_serial.close_delay * HZ/100; @@ -3621,6 +3671,43 @@ } } /* set_serial_info */ +/* + * get_lsr_info - get line status register info + * + * Purpose: Let user call ioctl() to get info when the UART physically + * is emptied. On bus types like RS485, the transmitter must + * release the bus after transmitting. This must be done when + * the transmit shift register is empty, not be done when the + * transmit holding register is empty. This functionality + * allows an RS485 driver to be written in user space. + */ +static int get_lsr_info(struct cyclades_port *info, unsigned int *value) +{ + int card, chip, channel, index; + unsigned char status; + unsigned int result; + unsigned long flags; + unsigned char *base_addr; + + card = info->card; + channel = (info->line) - (cy_card[card].first_line); + if (!IS_CYC_Z(cy_card[card])) { + chip = channel>>2; + channel &= 0x03; + index = cy_card[card].bus_index; + base_addr = (unsigned char *) + (cy_card[card].base_addr + (cy_chip_offset[chip]<tco = 0; info->rbpr = 0; info->rco = 0; + info->custom_divisor = 0; info->close_delay = 5*HZ/10; info->closing_wait = CLOSING_WAIT_DELAY; info->icount.cts = info->icount.dsr = @@ -5596,6 +5680,7 @@ info->cor3 = 0x08; /* _very_ small rcv threshold */ info->cor4 = 0; info->cor5 = 0; + info->custom_divisor = 0; info->close_delay = 5*HZ/10; info->closing_wait = CLOSING_WAIT_DELAY; info->icount.cts = info->icount.dsr = diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/drm/ffb_drv.c linux/drivers/char/drm/ffb_drv.c --- v2.4.0-test3/linux/drivers/char/drm/ffb_drv.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/drm/ffb_drv.c Wed Jul 12 21:58:42 2000 @@ -6,6 +6,8 @@ #include "drmP.h" +#include +#include #include #include @@ -44,6 +46,7 @@ extern int ffb_context_switch(drm_device_t *, int, int); static struct file_operations ffb_fops = { + owner: THIS_MODULE, open: ffb_open, flush: drm_flush, release: ffb_release, @@ -501,7 +504,6 @@ DRM_DEBUG("open_count = %d\n", dev->open_count); ret = drm_open_helper(inode, filp, dev); if (!ret) { - MOD_INC_USE_COUNT; atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -517,9 +519,11 @@ static int ffb_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int ret = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("open_count = %d\n", dev->open_count); if (dev->lock.hw_lock != NULL && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) @@ -541,7 +545,6 @@ ret = drm_release(inode, filp); if (!ret) { - MOD_DEC_USE_COUNT; atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -550,14 +553,18 @@ atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); - return ffb_takedown(dev); + ret = ffb_takedown(dev); + unlock_kernel(); + return ret; } spin_unlock(&dev->count_lock); } + unlock_kernel(); return ret; } @@ -756,6 +763,7 @@ DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", vma->vm_start, vma->vm_end, VM_OFFSET(vma)); + lock_kernel(); minor = MINOR(filp->f_dentry->d_inode->i_rdev); ffb_priv = NULL; for (i = 0; i < ffb_dev_table_size; i++) { @@ -763,13 +771,15 @@ if (ffb_priv->miscdev.minor == minor) break; } - if (i >= ffb_dev_table_size) + if (i >= ffb_dev_table_size) { + unlock_kernel(); return -EINVAL; - + } /* We don't support/need dma mappings, so... */ - if (!VM_OFFSET(vma)) + if (!VM_OFFSET(vma)) { + unlock_kernel(); return -EINVAL; - + } for (i = 0; i < dev->map_count; i++) { unsigned long off; @@ -781,16 +791,19 @@ break; } - if (i >= dev->map_count) + if (i >= dev->map_count) { + unlock_kernel(); return -EINVAL; - + } if (!map || - ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) + ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) { + unlock_kernel(); return -EPERM; - - if (map->size != (vma->vm_end - vma->vm_start)) + } + if (map->size != (vma->vm_end - vma->vm_start)) { + unlock_kernel(); return -EINVAL; - + } /* Set read-only attribute before mappings are created * so it works for fb/reg maps too. */ @@ -813,9 +826,10 @@ if (io_remap_page_range(vma->vm_start, ffb_priv->card_phys_base + VM_OFFSET(vma), vma->vm_end - vma->vm_start, - vma->vm_page_prot, 0)) + vma->vm_page_prot, 0)) { + unlock_kernel(); return -EAGAIN; - + } vma->vm_ops = &drm_vm_ops; break; case _DRM_SHM: @@ -828,8 +842,10 @@ vma->vm_flags |= VM_LOCKED; break; default: + unlock_kernel(); return -EINVAL; /* This should never happen. */ }; + unlock_kernel(); vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/drm/gamma_drv.c linux/drivers/char/drm/gamma_drv.c --- v2.4.0-test3/linux/drivers/char/drm/gamma_drv.c Sun Mar 19 18:35:30 2000 +++ linux/drivers/char/drm/gamma_drv.c Wed Jul 12 21:58:42 2000 @@ -29,6 +29,8 @@ */ #include +#include +#include #include "drmP.h" #include "gamma_drv.h" EXPORT_SYMBOL(gamma_init); @@ -44,14 +46,15 @@ static drm_device_t gamma_device; static struct file_operations gamma_fops = { - open: gamma_open, - flush: drm_flush, - release: gamma_release, - ioctl: gamma_ioctl, - mmap: drm_mmap, - read: drm_read, - fasync: drm_fasync, - poll: drm_poll, + owner: THIS_MODULE, + open: gamma_open, + flush: drm_flush, + release: gamma_release, + ioctl: gamma_ioctl, + mmap: drm_mmap, + read: drm_read, + fasync: drm_fasync, + poll: drm_poll, }; static struct miscdevice gamma_misc = { @@ -407,7 +410,6 @@ DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -422,12 +424,13 @@ int gamma_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -436,13 +439,17 @@ atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); - return gamma_takedown(dev); + retcode = gamma_takedown(dev); + unlock_kernel(); + return retcode; } spin_unlock(&dev->count_lock); } + unlock_kernel(); return retcode; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/drm/tdfx_drv.c linux/drivers/char/drm/tdfx_drv.c --- v2.4.0-test3/linux/drivers/char/drm/tdfx_drv.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/drm/tdfx_drv.c Wed Jul 12 21:58:42 2000 @@ -30,6 +30,8 @@ */ #include +#include +#include #include "drmP.h" #include "tdfx_drv.h" @@ -44,6 +46,7 @@ drm_ctx_t tdfx_res_ctx; static struct file_operations tdfx_fops = { + owner: THIS_MODULE, open: tdfx_open, flush: drm_flush, release: tdfx_release, @@ -343,7 +346,6 @@ DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_open_helper(inode, filp, dev))) { - MOD_INC_USE_COUNT; atomic_inc(&dev->total_open); spin_lock(&dev->count_lock); if (!dev->open_count++) { @@ -358,12 +360,13 @@ int tdfx_release(struct inode *inode, struct file *filp) { drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; + drm_device_t *dev; int retcode = 0; + lock_kernel(); + dev = priv->dev; DRM_DEBUG("open_count = %d\n", dev->open_count); if (!(retcode = drm_release(inode, filp))) { - MOD_DEC_USE_COUNT; atomic_inc(&dev->total_close); spin_lock(&dev->count_lock); if (!--dev->open_count) { @@ -372,13 +375,17 @@ atomic_read(&dev->ioctl_count), dev->blocked); spin_unlock(&dev->count_lock); + unlock_kernel(); return -EBUSY; } spin_unlock(&dev->count_lock); - return tdfx_takedown(dev); + retcode = tdfx_takedown(dev); + unlock_kernel(); + return retcode; } spin_unlock(&dev->count_lock); } + unlock_kernel(); return retcode; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/drm/vm.c linux/drivers/char/drm/vm.c --- v2.4.0-test3/linux/drivers/char/drm/vm.c Tue Mar 14 19:10:39 2000 +++ linux/drivers/char/drm/vm.c Wed Jul 12 21:58:42 2000 @@ -144,7 +144,6 @@ DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); atomic_inc(&dev->vma_count); - MOD_INC_USE_COUNT; #if DRM_DEBUG_CODE vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); @@ -169,7 +168,6 @@ DRM_DEBUG("0x%08lx,0x%08lx\n", vma->vm_start, vma->vm_end - vma->vm_start); - MOD_DEC_USE_COUNT; atomic_dec(&dev->vma_count); #if DRM_DEBUG_CODE diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/dsp56k.c linux/drivers/char/dsp56k.c --- v2.4.0-test3/linux/drivers/char/dsp56k.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/dsp56k.c Wed Jul 12 21:58:42 2000 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -483,7 +484,9 @@ { case DSP56K_DEV_56001: + lock_kernel(); dsp56k.in_use = 0; + unlock_kernel(); break; default: diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/dtlk.c linux/drivers/char/dtlk.c --- v2.4.0-test3/linux/drivers/char/dtlk.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/dtlk.c Wed Jul 12 21:58:42 2000 @@ -69,6 +69,7 @@ #include /* for POLLIN, etc. */ #include /* local header file for DoubleTalk values */ #include +#include #ifdef TRACING #define TRACE_TEXT(str) printk(str); @@ -333,7 +334,9 @@ } TRACE_RET; + lock_kernel(); del_timer(&dtlk_timer); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/ftape/zftape/zftape-init.c linux/drivers/char/ftape/zftape/zftape-init.c --- v2.4.0-test3/linux/drivers/char/ftape/zftape/zftape-init.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/ftape/zftape/zftape-init.c Wed Jul 12 21:58:42 2000 @@ -35,15 +35,11 @@ #endif #include #include +#include #include #include -#if LINUX_VERSION_CODE >=KERNEL_VER(2,1,16) #include -#else -#define __initdata -#define __initfunc(__arg) __arg -#endif #include "../zftape/zftape-init.h" #include "../zftape/zftape-read.h" @@ -56,7 +52,6 @@ char zft_rev[] __initdata = "$Revision: 1.8 $"; char zft_dat[] __initdata = "$Date: 1997/11/06 00:48:56 $"; -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,18) MODULE_AUTHOR("(c) 1996, 1997 Claus-Justus Heine " "(claus@momo.math.rwth-aachen.de)"); MODULE_DESCRIPTION(ZFTAPE_VERSION " - " @@ -64,7 +59,6 @@ "Support for QIC-113 compatible volume table " "and builtin compression (lzrw3 algorithm)"); MODULE_SUPPORTED_DEVICE("char-major-27"); -#endif /* Global vars. */ @@ -90,38 +84,18 @@ */ static int zft_open (struct inode *ino, struct file *filep); -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,31) static int zft_close(struct inode *ino, struct file *filep); -#else -static void zft_close(struct inode *ino, struct file *filep); -#endif static int zft_ioctl(struct inode *ino, struct file *filep, unsigned int command, unsigned long arg); -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,56) static int zft_mmap(struct file *filep, struct vm_area_struct *vma); -#else -static int zft_mmap(struct inode *ino, struct file *filep, - struct vm_area_struct *vma); -#endif -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60) static ssize_t zft_read (struct file *fp, char *buff, size_t req_len, loff_t *ppos); static ssize_t zft_write(struct file *fp, const char *buff, size_t req_len, loff_t *ppos); -#elif LINUX_VERSION_CODE >= KERNEL_VER(2,1,0) -static long zft_read (struct inode *ino, struct file *fp, char *buff, - unsigned long req_len); -static long zft_write(struct inode *ino, struct file *fp, const char *buff, - unsigned long req_len); -#else -static int zft_read (struct inode *ino, struct file *fp, char *buff, - int req_len); -static int zft_write(struct inode *ino, struct file *fp, const char *buff, - int req_len); -#endif static struct file_operations zft_cdev = { + owner: THIS_MODULE, read: zft_read, write: zft_write, ioctl: zft_ioctl, @@ -137,15 +111,6 @@ int result; TRACE_FUN(ft_t_flow); -#if LINUX_VERSION_CODE < KERNEL_VER(2,1,18) - if (!MOD_IN_USE) { - MOD_INC_USE_COUNT; /* lock module in memory */ - } -#else - MOD_INC_USE_COUNT; /* sets MOD_VISITED and MOD_USED_ONCE, - * locking is done with can_unload() - */ -#endif TRACE(ft_t_flow, "called for minor %d", MINOR(ino->i_rdev)); if (busy_flag) { TRACE_ABORT(-EBUSY, ft_t_warn, "failed: already busy"); @@ -155,11 +120,6 @@ > FTAPE_SEL_D) { busy_flag = 0; -#if defined(MODULE) && LINUX_VERSION_CODE < KERNEL_VER(2,1,18) - if (!zft_dirty()) { - MOD_DEC_USE_COUNT; /* unlock module in memory */ - } -#endif TRACE_ABORT(-ENXIO, ft_t_err, "failed: illegal unit nr"); } orig_sigmask = current->blocked; @@ -168,11 +128,6 @@ if (result < 0) { current->blocked = orig_sigmask; /* restore mask */ busy_flag = 0; -#if defined(MODULE) && LINUX_VERSION_CODE < KERNEL_VER(2,1,18) - if (!zft_dirty()) { - MOD_DEC_USE_COUNT; /* unlock module in memory */ - } -#endif TRACE_ABORT(result, ft_t_err, "_ftape_open failed"); } else { /* Mask signals that will disturb proper operation of the @@ -191,13 +146,11 @@ int result; TRACE_FUN(ft_t_flow); + lock_kernel(); if (!busy_flag || MINOR(ino->i_rdev) != zft_unit) { TRACE(ft_t_err, "failed: not busy or wrong unit"); -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,31) + unlock_kernel(); TRACE_EXIT 0; -#else - TRACE_EXIT; /* keep busy_flag !(?) */ -#endif } sigfillset(¤t->blocked); result = _zft_close(); @@ -206,16 +159,8 @@ } current->blocked = orig_sigmask; /* restore before open state */ busy_flag = 0; -#if defined(MODULE) && LINUX_VERSION_CODE < KERNEL_VER(2,1,18) - if (!zft_dirty()) { - MOD_DEC_USE_COUNT; /* unlock module in memory */ - } -#endif -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,31) + unlock_kernel(); TRACE_EXIT 0; -#else - TRACE_EXIT; -#endif } /* Ioctl for floppy tape device @@ -241,24 +186,14 @@ /* Ioctl for floppy tape device */ -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,56) static int zft_mmap(struct file *filep, struct vm_area_struct *vma) -#else -static int zft_mmap(struct inode *ino, - struct file *filep, - struct vm_area_struct *vma) -#endif { int result = -EIO; sigset_t old_sigmask; TRACE_FUN(ft_t_flow); if (!busy_flag || -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,56) MINOR(filep->f_dentry->d_inode->i_rdev) != zft_unit || -#else - MINOR(ino->i_rdev) != zft_unit || -#endif ft_failure) { TRACE_ABORT(-EIO, ft_t_err, @@ -266,34 +201,26 @@ } old_sigmask = current->blocked; /* save mask */ sigfillset(¤t->blocked); + lock_kernel(); if ((result = ftape_mmap(vma)) >= 0) { #ifndef MSYNC_BUG_WAS_FIXED static struct vm_operations_struct dummy = { NULL, }; vma->vm_ops = &dummy; #endif } + unlock_kernel(); current->blocked = old_sigmask; /* restore mask */ TRACE_EXIT result; } /* Read from floppy tape device */ -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60) static ssize_t zft_read(struct file *fp, char *buff, size_t req_len, loff_t *ppos) -#elif LINUX_VERSION_CODE >= KERNEL_VER(2,1,0) -static long zft_read(struct inode *ino, struct file *fp, char *buff, - unsigned long req_len) -#else -static int zft_read(struct inode *ino, struct file *fp, char *buff, - int req_len) -#endif { int result = -EIO; sigset_t old_sigmask; -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60) struct inode *ino = fp->f_dentry->d_inode; -#endif TRACE_FUN(ft_t_flow); TRACE(ft_t_data_flow, "called with count: %ld", (unsigned long)req_len); @@ -311,22 +238,12 @@ /* Write to tape device */ -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60) static ssize_t zft_write(struct file *fp, const char *buff, size_t req_len, loff_t *ppos) -#elif LINUX_VERSION_CODE >= KERNEL_VER(2,1,0) -static long zft_write(struct inode *ino, struct file *fp, const char *buff, - unsigned long req_len) -#else -static int zft_write(struct inode *ino, struct file *fp, const char *buff, - int req_len) -#endif { int result = -EIO; sigset_t old_sigmask; -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,60) struct inode *ino = fp->f_dentry->d_inode; -#endif TRACE_FUN(ft_t_flow); TRACE(ft_t_flow, "called with count: %ld", (unsigned long)req_len); @@ -470,9 +387,6 @@ &zft_cdev, NULL); } -#if LINUX_VERSION_CODE < KERNEL_VER(2,1,18) - register_symtab(&zft_symbol_table); /* add global zftape symbols */ -#endif #ifdef CONFIG_ZFT_COMPRESSOR (void)zft_compressor_init(); #endif @@ -484,24 +398,20 @@ #ifdef MODULE -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,18) /* Called by modules package before trying to unload the module */ static int can_unload(void) { - return (zft_dirty() || busy_flag) ? -EBUSY : 0; + return (GET_USE_COUNT(THIS_MODULE)||zft_dirty()||busy_flag)?-EBUSY:0; } -#endif /* Called by modules package when installing the driver */ int init_module(void) { -#if LINUX_VERSION_CODE >= KERNEL_VER(2,1,18) if (!mod_member_present(&__this_module, can_unload)) { return -EBUSY; } __this_module.can_unload = can_unload; -#endif return zft_init(); } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/h8.c linux/drivers/char/h8.c --- v2.4.0-test3/linux/drivers/char/h8.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/h8.c Wed Jul 12 21:58:42 2000 @@ -106,16 +106,6 @@ static char driver_version[] = "X0.0";/* no spaces */ -static struct file_operations h8_fops = { - /* twelve lines of crap^WNULLs were here */ -}; - -static struct miscdevice h8_device = { - H8_MINOR_DEV, - "h8", - &h8_fops -}; - union intr_buf intrbuf; int intr_buf_ptr; union intr_buf xx; @@ -297,7 +287,6 @@ static void __exit h8_cleanup (void) { remove_proc_entry("driver/h8", NULL); - misc_deregister(&h8_device); release_region(h8_base, 8); free_irq(h8_irq, NULL); } @@ -313,7 +302,6 @@ create_proc_info_entry("driver/h8", 0, NULL, h8_get_info); - misc_register(&h8_device); request_region(h8_base, 8, "h8"); h8_alloc_queues(); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/i2c-parport.c linux/drivers/char/i2c-parport.c --- v2.4.0-test3/linux/drivers/char/i2c-parport.c Mon Dec 20 18:48:21 1999 +++ linux/drivers/char/i2c-parport.c Wed Jul 12 16:24:33 2000 @@ -75,7 +75,7 @@ struct parport_i2c_bus *b = kmalloc(sizeof(struct parport_i2c_bus), GFP_KERNEL); b->i2c = parport_i2c_bus_template; - b->i2c.data = port; + b->i2c.data = parport_get_port (port); strncpy(b->i2c.name, port->name, 32); spin_lock(&bus_list_lock); b->next = bus_list; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/i810_rng.c linux/drivers/char/i810_rng.c --- v2.4.0-test3/linux/drivers/char/i810_rng.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/i810_rng.c Wed Jul 12 21:58:42 2000 @@ -165,6 +165,7 @@ #include #include #include +#include #include #include @@ -626,12 +627,16 @@ static int rng_dev_release (struct inode *inode, struct file *filp) { - if (rng_enable(0) != 0) + lock_kernel(); + if (rng_enable(0) != 0) { + unlock_kernel(); return -EIO; + } spin_lock_bh (&rng_lock); rng_open = 0; spin_unlock_bh (&rng_lock); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/joystick/Config.in linux/drivers/char/joystick/Config.in --- v2.4.0-test3/linux/drivers/char/joystick/Config.in Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/joystick/Config.in Thu Jul 13 12:16:07 2000 @@ -7,9 +7,7 @@ tristate 'Joystick support' CONFIG_JOYSTICK if [ "$CONFIG_JOYSTICK" != "n" ]; then - - define_tristate CONFIG_USB $CONFIG_JOYSTICK - define_tristate CONFIG_INPUT_JOYDEV $CONFIG_JOYSTICK + define_tristate CONFIG_INPUT_JOYDEV $CONFIG_JOYSTICK comment 'Game port support' dep_tristate ' ns558 gameports' CONFIG_INPUT_NS558 $CONFIG_JOYSTICK diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.4.0-test3/linux/drivers/char/lp.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/lp.c Wed Jul 12 21:58:42 2000 @@ -119,6 +119,7 @@ #include #include #include +#include #include #include #include @@ -407,9 +408,11 @@ { unsigned int minor = MINOR(inode->i_rdev); + lock_kernel(); kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE); lp_table[minor].lp_buffer = NULL; LP_F(minor) &= ~LP_BUSY; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/mixcomwd.c linux/drivers/char/mixcomwd.c --- v2.4.0-test3/linux/drivers/char/mixcomwd.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/mixcomwd.c Wed Jul 12 21:58:42 2000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -100,9 +101,11 @@ static int mixcomwd_release(struct inode *inode, struct file *file) { + lock_kernel(); #ifndef CONFIG_WATCHDOG_NOWAYOUT if(mixcomwd_timer_alive) { printk(KERN_ERR "mixcomwd: release called while internal timer alive"); + unlock_kernel(); return -EBUSY; } init_timer(&mixcomwd_timer); @@ -114,6 +117,7 @@ #endif clear_bit(0,&mixcomwd_opened); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/msp3400.c linux/drivers/char/msp3400.c --- v2.4.0-test3/linux/drivers/char/msp3400.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/msp3400.c Wed Jul 12 21:58:42 2000 @@ -1265,8 +1265,10 @@ { struct i2c_client *client = file->private_data; + lock_kernel(); if (client->adapter->dec_use) client->adapter->dec_use(client->adapter); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/nvram.c linux/drivers/char/nvram.c --- v2.4.0-test3/linux/drivers/char/nvram.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/nvram.c Wed Jul 12 21:58:42 2000 @@ -34,6 +34,8 @@ #include #include +#include +#include #define PC 1 #define ATARI 2 @@ -341,11 +343,13 @@ static int nvram_release( struct inode *inode, struct file *file ) { + lock_kernel(); nvram_open_cnt--; if (file->f_flags & O_EXCL) nvram_open_mode &= ~NVRAM_EXCL; if (file->f_mode & 2) nvram_open_mode &= ~NVRAM_WRITE; + unlock_kernel(); return( 0 ); } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c --- v2.4.0-test3/linux/drivers/char/pc110pad.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/pc110pad.c Wed Jul 12 21:58:42 2000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -583,10 +584,11 @@ static int close_pad(struct inode * inode, struct file * file) { + lock_kernel(); fasync_pad(-1, file, 0); - if (--active) - return 0; - outb(0x30, current_params.io+2); /* switch off digitiser */ + if (!--active) + outb(0x30, current_params.io+2); /* switch off digitiser */ + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.4.0-test3/linux/drivers/char/pc_keyb.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/pc_keyb.c Wed Jul 12 21:58:42 2000 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -872,12 +873,16 @@ static int release_aux(struct inode * inode, struct file * file) { + lock_kernel(); fasync_aux(-1, file, 0); - if (--aux_count) + if (--aux_count) { + unlock_kernel(); return 0; + } kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE); aux_free_irq(AUX_DEV); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/pcmcia/Config.in linux/drivers/char/pcmcia/Config.in --- v2.4.0-test3/linux/drivers/char/pcmcia/Config.in Fri Jan 21 18:19:16 2000 +++ linux/drivers/char/pcmcia/Config.in Tue Jul 11 19:02:37 2000 @@ -3,12 +3,12 @@ # if [ "$CONFIG_SERIAL" = "n" ]; then - define_bool CONFIG_PCMCIA_SERIAL n + define_tristate CONFIG_PCMCIA_SERIAL n else if [ "$CONFIG_SERIAL" = "m" -o "$CONFIG_PCMCIA" = "m" ]; then - define_bool CONFIG_PCMCIA_SERIAL m + define_tristate CONFIG_PCMCIA_SERIAL m else - define_bool CONFIG_PCMCIA_SERIAL y + define_tristate CONFIG_PCMCIA_SERIAL y fi fi diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c --- v2.4.0-test3/linux/drivers/char/pcwd.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/pcwd.c Wed Jul 12 21:58:42 2000 @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -451,6 +452,7 @@ { if (MINOR(ino->i_rdev)==WATCHDOG_MINOR) { + lock_kernel(); is_open = 0; #ifndef CONFIG_WATCHDOG_NOWAYOUT /* Disable the board */ @@ -460,6 +462,7 @@ outb_p(0xA5, current_readport + 3); spin_unlock(&io_lock); } + unlock_kernel(); #endif } return 0; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c --- v2.4.0-test3/linux/drivers/char/ppdev.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/ppdev.c Wed Jul 12 21:58:42 2000 @@ -52,6 +52,7 @@ #include #include #include +#include #define PP_VERSION "ppdev: user-space parallel port driver" #define CHRDEV "ppdev" @@ -83,64 +84,6 @@ /* ROUND_UP macro from fs/select.c */ #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) -struct pp_port_list_struct { - struct parport *port; - struct pp_port_list_struct *next; -}; -static struct pp_port_list_struct *pp_port_list; -static DECLARE_MUTEX(pp_port_list_lock); - -/* pp_attach and pp_detach are for keeping a list of currently - * available ports, held under a mutex. We do this rather than - * using parport_enumerate because it stops a load of races. - */ - -static void pp_attach (struct parport *port) -{ - struct pp_port_list_struct *add; - - add = kmalloc (sizeof (struct pp_port_list_struct), GFP_KERNEL); - if (!add) { - printk (KERN_WARNING CHRDEV ": memory squeeze\n"); - return; - } - - add->port = port; - down (&pp_port_list_lock); - add->next = pp_port_list; - pp_port_list = add; - up (&pp_port_list_lock); -} - -static void pp_detach (struct parport *port) -{ - struct pp_port_list_struct *del; - - down (&pp_port_list_lock); - del = pp_port_list; - if (del->port == port) - pp_port_list = del->next; - else { - struct pp_port_list_struct *prev; - do { - prev = del; - del = del->next; - } while (del && del->port != port); - if (del) - prev->next = del->next; - } - up (&pp_port_list_lock); - - if (del) - kfree (del); -} - -static struct parport_driver ppdev_driver = { - name: CHRDEV, - attach: pp_attach, - detach: pp_detach -}; - static inline void pp_enable_irq (struct pp_struct *pp) { struct parport *port = pp->pdev->port; @@ -274,7 +217,7 @@ static int register_device (int minor, struct pp_struct *pp) { - struct pp_port_list_struct *ports; + struct parport *port; struct pardevice * pdev = NULL; char *name; int fl; @@ -285,23 +228,17 @@ sprintf (name, CHRDEV "%x", minor); - down (&pp_port_list_lock); - ports = pp_port_list; - while (ports && ports->port->number != minor) - ports = ports->next; - if (ports->port) { - fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; - pdev = parport_register_device (ports->port, name, NULL, - NULL, pp_irq, fl, pp); - } - up (&pp_port_list_lock); - - if (!ports->port) { + port = parport_find_number (minor); + if (!port) { printk (KERN_WARNING "%s: no associated port!\n", name); kfree (name); return -ENXIO; } + fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; + pdev = parport_register_device (port, name, NULL, + NULL, pp_irq, fl, pp); + parport_put_port (port); if (!pdev) { printk (KERN_WARNING "%s: failed to register device!\n", name); @@ -595,6 +532,7 @@ unsigned int minor = MINOR (inode->i_rdev); struct pp_struct *pp = file->private_data; + lock_kernel(); if (pp->pdev && pp->pdev->port->ieee1284.mode != IEEE1284_MODE_COMPAT) { if (!(pp->flags & PP_CLAIMED)) { parport_claim_or_block (pp->pdev); @@ -620,6 +558,7 @@ printk (KERN_DEBUG CHRDEV "%x: unregistered pardevice\n", minor); } + unlock_kernel(); kfree (pp); @@ -654,10 +593,6 @@ static int __init ppdev_init (void) { - if (parport_register_driver (&ppdev_driver)) { - printk (KERN_WARNING CHRDEV ": unable to register driver\n"); - return -EIO; - } if (devfs_register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) { printk (KERN_WARNING CHRDEV ": unable to get major %d\n", PP_MAJOR); @@ -678,7 +613,6 @@ /* Clean up all parport stuff */ devfs_unregister (devfs_handle); devfs_unregister_chrdev (PP_MAJOR, CHRDEV); - parport_unregister_driver (&ppdev_driver); } module_init(ppdev_init); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/qpmouse.c linux/drivers/char/qpmouse.c --- v2.4.0-test3/linux/drivers/char/qpmouse.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/qpmouse.c Wed Jul 12 21:58:42 2000 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -141,6 +142,7 @@ { unsigned char status; + lock_kernel(); fasync_qp(-1, file, 0); if (!--qp_count) { if (!poll_qp_status()) @@ -151,6 +153,7 @@ printk("Warning: Mouse device busy in release_qp()\n"); free_irq(QP_IRQ, NULL); } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/raw.c linux/drivers/char/raw.c --- v2.4.0-test3/linux/drivers/char/raw.c Sun Mar 19 18:35:30 2000 +++ linux/drivers/char/raw.c Wed Jul 12 21:58:42 2000 @@ -14,6 +14,7 @@ #include #include #include +#include #include #define dprintk(x...) @@ -126,9 +127,11 @@ struct block_device *bdev; minor = MINOR(inode->i_rdev); + lock_kernel(); bdev = raw_device_bindings[minor]; blkdev_put(bdev, BDEV_RAW); raw_device_inuse[minor]--; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/rtc.c linux/drivers/char/rtc.c --- v2.4.0-test3/linux/drivers/char/rtc.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/rtc.c Thu Jul 13 09:50:52 2000 @@ -506,19 +506,24 @@ * up things on a close. */ +/* We use rtc_lock to protect against concurrent opens. So the BKL is not + * needed here. Or anywhere else in this driver. */ static int rtc_open(struct inode *inode, struct file *file) { - /* If someday somebody decides to remove the kernel_lock on open and - * close and ioctl this is gonna get open to races */ + spin_lock_irq (&rtc_lock); + if(rtc_status & RTC_IS_OPEN) - return -EBUSY; + goto out_busy; rtc_status |= RTC_IS_OPEN; - spin_lock_irq (&rtc_lock); rtc_irq_data = 0; spin_unlock_irq (&rtc_lock); return 0; + +out_busy: + spin_unlock_irq (&rtc_lock); + return -EBUSY; } static int rtc_fasync (int fd, struct file *filp, int on) @@ -554,13 +559,15 @@ if (file->f_flags & FASYNC) { rtc_fasync (-1, file, 0); } - #endif spin_lock_irq (&rtc_lock); rtc_irq_data = 0; spin_unlock_irq (&rtc_lock); - rtc_status = rtc_status & ~RTC_IS_OPEN; + + /* No need for locking -- nobody else can do anything until this rmw is + * committed, and no timer is running. */ + rtc_status &= ~RTC_IS_OPEN; return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/sbc60xxwdt.c linux/drivers/char/sbc60xxwdt.c --- v2.4.0-test3/linux/drivers/char/sbc60xxwdt.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/sbc60xxwdt.c Wed Jul 12 21:58:42 2000 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -207,6 +208,7 @@ static int fop_close(struct inode * inode, struct file * file) { + lock_kernel(); if(MINOR(inode->i_rdev) == WATCHDOG_MINOR) { if(wdt_expect_close) @@ -217,6 +219,7 @@ } } wdt_is_open = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/softdog.c linux/drivers/char/softdog.c --- v2.4.0-test3/linux/drivers/char/softdog.c Thu May 11 15:30:07 2000 +++ linux/drivers/char/softdog.c Wed Jul 12 21:58:42 2000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -79,7 +80,9 @@ { if(timer_alive) return -EBUSY; +#ifdef CONFIG_WATCHDOG_NOWAYOUT MOD_INC_USE_COUNT; +#endif /* * Activate timer */ @@ -94,11 +97,12 @@ * Shut off the timer. * Lock it in if it's a module and we defined ...NOWAYOUT */ + lock_kernel(); #ifndef CONFIG_WATCHDOG_NOWAYOUT del_timer(&watchdog_ticktock); - MOD_DEC_USE_COUNT; #endif timer_alive=0; + unlock_kernel(); return 0; } @@ -146,6 +150,7 @@ static struct file_operations softdog_fops= { + owner: THIS_MODULE, write: softdog_write, ioctl: softdog_ioctl, open: softdog_open, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/synclink.c linux/drivers/char/synclink.c --- v2.4.0-test3/linux/drivers/char/synclink.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/synclink.c Tue Jul 11 11:22:09 2000 @@ -1,7 +1,7 @@ /* * linux/drivers/char/synclink.c * - * ==FILEDATE 19991217== + * ==FILEDATE 20000707== * * Device driver for Microgate SyncLink ISA and PCI * high speed multiprotocol serial adapters. @@ -33,6 +33,13 @@ * This driver has been tested with a slightly modified ppp.c driver * for synchronous PPP. * + * 2000/02/16 + * Added interface for syncppp.c driver (an alternate synchronous PPP + * implementation that also supports Cisco HDLC). Each device instance + * registers as a tty device AND a network device (if dosyncppp option + * is set for the device). The functionality is determined by which + * device interface is opened. + * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -73,6 +80,8 @@ #include #include +#include + #if LINUX_VERSION_CODE >= VERSION(2,1,0) #include #include @@ -101,6 +110,23 @@ #define set_current_state(a) current->state = (a) #endif +#ifdef CONFIG_SYNCLINK_SYNCPPP_MODULE +#define CONFIG_SYNCLINK_SYNCPPP 1 +#endif + +#ifdef CONFIG_SYNCLINK_SYNCPPP +#if LINUX_VERSION_CODE < VERSION(2,3,43) +#include "../net/syncppp.h" +#define net_device device +#define netif_stop_queue(a) (a)->tbusy = 1 +#define netif_start_queue(a) (a)->tbusy = 0 +#define netif_wake_queue(a) (a)->tbusy = 0; mark_bh(NET_BH) +#define netif_queue_stopped(a) ((a)->tbusy) +#else +#include "../net/wan/syncppp.h" +#endif +#endif + #if LINUX_VERSION_CODE >= VERSION(2,1,4) #include #define GET_USER(error,value,addr) error = get_user(value,addr) @@ -208,22 +234,11 @@ /* The queue of BH actions to be performed */ -#define BH_TYPE_RECEIVE_DATA 1 -#define BH_TYPE_RECEIVE_STATUS 2 -#define BH_TYPE_RECEIVE_DMA 3 -#define BH_TYPE_TRANSMIT_DATA 4 -#define BH_TYPE_TRANSMIT_STATUS 5 -#define BH_TYPE_STATUS 6 - -typedef struct _BH_EVENT { - unsigned char type; /* Set by interrupt routines to reqst */ - u16 status; - struct _BH_EVENT *link; - -} BH_EVENT, *BH_QUEUE; /* Queue of BH actions to be done. */ +#define BH_RECEIVE 1 +#define BH_TRANSMIT 2 +#define BH_STATUS 4 -#define MAX_BH_QUEUE_ENTRIES 200 -#define IO_PIN_SHUTDOWN_LIMIT (MAX_BH_QUEUE_ENTRIES/4) +#define IO_PIN_SHUTDOWN_LIMIT 100 #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) @@ -243,6 +258,7 @@ */ struct mgsl_struct { + void *if_ptr; /* General purpose pointer (used by SPPP) */ int magic; int flags; int count; /* count of opens */ @@ -284,12 +300,8 @@ u32 max_frame_size; /* as set by device config */ - BH_EVENT bh_queue[MAX_BH_QUEUE_ENTRIES]; /* Pointer to alloc'ed block */ - BH_QUEUE bh_queue_head; /* Queue of BH actions */ - BH_QUEUE bh_queue_tail; /* Tail of above for perf. */ - BH_QUEUE free_bh_queue_head; /* Queue of Free BH */ - BH_QUEUE free_bh_queue_tail; /* Tail of above for perf. */ - BH_QUEUE bh_action; /* Action for BH */ + u32 pending_bh; + int bh_running; /* Protection from multiple */ int isr_overflow; int bh_requested; @@ -324,7 +336,8 @@ char device_name[25]; /* device instance name */ unsigned int bus_type; /* expansion bus type (ISA,EISA,PCI) */ - struct pci_dev *pdev; /* pointer to PCI device info */ + unsigned char bus; /* expansion bus number (zero based) */ + unsigned char function; /* PCI device number */ unsigned int io_base; /* base I/O address of adapter */ unsigned int io_addr_size; /* size of the I/O address range */ @@ -366,6 +379,20 @@ BOOLEAN loopmode_send_done_requested; struct _input_signal_events input_signal_events; + + /* SPPP/Cisco HDLC device parts */ + int netcount; + int dosyncppp; + spinlock_t netlock; +#ifdef CONFIG_SYNCLINK_SYNCPPP + struct ppp_device pppdev; + char netname[10]; + struct net_device *netdev; + struct net_device_stats netstats; +#if LINUX_VERSION_CODE >= VERSION(2,2,16) + struct net_device netdevice; +#endif +#endif }; #define MGSL_MAGIC 0x5401 @@ -373,8 +400,9 @@ /* * The size of the serial xmit buffer is 1 page, or 4096 bytes */ -/* #define SERIAL_XMIT_SIZE 4096 */ /* defined in include/linux/serial.h */ - +#ifndef SERIAL_XMIT_SIZE +#define SERIAL_XMIT_SIZE 4096 +#endif /* * These macros define the offsets used in calculating the @@ -767,6 +795,22 @@ void usc_loopmode_send_done( struct mgsl_struct * info ); int usc_loopmode_send_active( struct mgsl_struct * info ); +int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg); + +#ifdef CONFIG_SYNCLINK_SYNCPPP +/* SPPP/HDLC stuff */ +void mgsl_sppp_init(struct mgsl_struct *info); +void mgsl_sppp_delete(struct mgsl_struct *info); +int mgsl_sppp_open(struct net_device *d); +int mgsl_sppp_close(struct net_device *d); +void mgsl_sppp_tx_timeout(struct net_device *d); +int mgsl_sppp_tx(struct sk_buff *skb, struct net_device *d); +void mgsl_sppp_rx_done(struct mgsl_struct *info, char *buf, int size); +void mgsl_sppp_tx_done(struct mgsl_struct *info); +int mgsl_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +struct net_device_stats *mgsl_net_stats(struct net_device *dev); +#endif + /* * Defines a BUS descriptor value for the PCI adapter * local bus address ranges. @@ -828,14 +872,9 @@ * Bottom half interrupt handlers */ void mgsl_bh_handler(void* Context); -void mgsl_bh_receive_dma( struct mgsl_struct *info, unsigned short status ); -void mgsl_bh_transmit_data( struct mgsl_struct *info, unsigned short Datacount ); -void mgsl_bh_status_handler( struct mgsl_struct *info, unsigned short status ); - -void mgsl_format_bh_queue( struct mgsl_struct *info ); -void mgsl_bh_queue_put( struct mgsl_struct *info, unsigned char type, unsigned short status ); -int mgsl_bh_queue_get( struct mgsl_struct *info ); - +void mgsl_bh_receive(struct mgsl_struct *info); +void mgsl_bh_transmit(struct mgsl_struct *info); +void mgsl_bh_status(struct mgsl_struct *info); /* * Interrupt handler routines and dispatch table. @@ -911,7 +950,7 @@ static int dma[MAX_ISA_DEVICES] = {0,}; static int debug_level = 0; static int maxframe[MAX_TOTAL_DEVICES] = {0,}; - +static int dosyncppp[MAX_TOTAL_DEVICES] = {0,}; #if LINUX_VERSION_CODE >= VERSION(2,1,0) MODULE_PARM(break_on_load,"i"); @@ -922,10 +961,11 @@ MODULE_PARM(dma,"1-" __MODULE_STRING(MAX_ISA_DEVICES) "i"); MODULE_PARM(debug_level,"i"); MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i"); +MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i"); #endif static char *driver_name = "SyncLink serial driver"; -static char *driver_version = "1.16"; +static char *driver_version = "1.21"; static struct tty_driver serial_driver, callout_driver; static int serial_refcount; @@ -1037,152 +1077,46 @@ * Bottom half work queue access functions */ -/* mgsl_format_bh_queue() - * - * Initialize the bottom half processing queue - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -void mgsl_format_bh_queue( struct mgsl_struct *info ) -{ - BH_QUEUE bh_queue = info->bh_queue; - int i; - - /* go through sequentially tacking the little bits together */ - - for ( i=0; i < MAX_BH_QUEUE_ENTRIES; i++ ) { - if ( info->free_bh_queue_tail == NULL ) - info->free_bh_queue_head = bh_queue; - else - info->free_bh_queue_tail->link = bh_queue; - info->free_bh_queue_tail = bh_queue++; - } - - /* As a safety measure, mark the end of the chain with a NULL */ - info->free_bh_queue_tail->link = NULL; - info->isr_overflow=0; - -} /* end of mgsl_format_bh_queue() */ - -/* mgsl_bh_queue_put() - * - * Add a BH event to the BH queue - * - * Arguments: info pointer to device instance data - * type BH event type - * status BH event status - * - * Return Value: None +/* mgsl_bh_action() Return next bottom half action to perform. + * Return Value: BH action code or 0 if nothing to do. */ -void mgsl_bh_queue_put( struct mgsl_struct *info, unsigned char type, unsigned short status ) -{ - BH_EVENT *event = info->free_bh_queue_head; - - if ( event != NULL ) { - /* remove free element from head of free list */ - info->free_bh_queue_head = event->link; - event->link = NULL; - - /* file out new BH event */ - event->type = type; - event->status = status; - - /* add element to tail of pending list */ - if ( info->bh_queue_head != NULL ){ - /* BH queue is not empty, add current element to tail */ - info->bh_queue_tail->link = event; - } else { - /* the BH queue is empty so this element becomes the head of queue */ - info->bh_queue_head = event; - } - - /* the new element becomes tail of queue */ - info->bh_queue_tail = event; - } else { - /* No more free BH action elements in queue. */ - /* This happens when too many interrupts are occuring */ - /* for the mgsl_bh_handler to process so set a flag. */ - - info->isr_overflow = 1; - } - -} /* end of mgsl_bh_queue_put() */ - -/* mgsl_bh_queue_get() - * - * Free the current work item (if any) and get the - * next work item from the head of the pending work item queue. - * - * Effects: - * - * If a BH action element is available on the BH action queue - * then the head of the queue is removed and bh_action - * is set to point to the removed element. - * - * Arguments: info pointer to device instance data - * Return Value: 1 if BH action removed from queue - */ -int mgsl_bh_queue_get( struct mgsl_struct *info ) +int mgsl_bh_action(struct mgsl_struct *info) { unsigned long flags; + int rc = 0; spin_lock_irqsave(&info->irq_spinlock,flags); - if ( info->bh_action ) { - /* free the current work item */ - if ( info->free_bh_queue_head != NULL ){ - /* free queue is not empty, add current element to tail */ - info->free_bh_queue_tail->link = info->bh_action; - } else { - /* free queue is empty so this element becomes the head of queue */ - info->free_bh_queue_head = info->bh_action; - } - - /* add element to tail of free queue */ - info->free_bh_queue_tail = info->bh_action; - info->free_bh_queue_tail->link = NULL; + if (info->pending_bh & BH_RECEIVE) { + info->pending_bh &= ~BH_RECEIVE; + rc = BH_RECEIVE; + } else if (info->pending_bh & BH_TRANSMIT) { + info->pending_bh &= ~BH_TRANSMIT; + rc = BH_TRANSMIT; + } else if (info->pending_bh & BH_STATUS) { + info->pending_bh &= ~BH_STATUS; + rc = BH_STATUS; } - - /* attempt to remove element from head of queue */ - info->bh_action = info->bh_queue_head; - if ( info->bh_action != NULL ){ - /* BH queue is not empty, remove element from queue head */ - info->bh_queue_head = info->bh_action->link; - spin_unlock_irqrestore(&info->irq_spinlock,flags); - return 1; - } - - if ( info->isr_overflow ) { - if (debug_level >= DEBUG_LEVEL_BH) - printk("ISR overflow cleared.\n"); - info->isr_overflow=0; - usc_EnableMasterIrqBit(info); - usc_EnableDmaInterrupts(info,DICR_MASTER); + if (!rc) { + /* Mark BH routine as complete */ + info->bh_running = 0; + info->bh_requested = 0; } - - /* Mark BH routine as complete */ - info->bh_running = 0; - info->bh_requested = 0; spin_unlock_irqrestore(&info->irq_spinlock,flags); - return 0; - -} /* end of mgsl_bh_queue_get() */ + return rc; +} -/* mgsl_bh_handler() - * +/* * Perform bottom half processing of work items queued by ISR. - * - * Arguments: Context pointer to device instance data - * Return Value: None */ void mgsl_bh_handler(void* Context) { struct mgsl_struct *info = (struct mgsl_struct*)Context; - + int action; + if (!info) return; @@ -1192,34 +1126,27 @@ info->bh_running = 1; - /* Attempt to clear out the BH queue */ - - while( mgsl_bh_queue_get(info) ) { + while((action = mgsl_bh_action(info)) != 0) { /* Process work item */ if ( debug_level >= DEBUG_LEVEL_BH ) printk( "%s(%d):mgsl_bh_handler() work item action=%d\n", - __FILE__,__LINE__,info->bh_action->type); + __FILE__,__LINE__,action); - switch ( info->bh_action->type ) { + switch (action) { - case BH_TYPE_RECEIVE_DMA: - mgsl_bh_receive_dma( info, info->bh_action->status ); + case BH_RECEIVE: + mgsl_bh_receive(info); break; - - case BH_TYPE_TRANSMIT_STATUS: - case BH_TYPE_TRANSMIT_DATA: - mgsl_bh_transmit_data( info, info->bh_action->status ); + case BH_TRANSMIT: + mgsl_bh_transmit(info); break; - - case BH_TYPE_STATUS: - mgsl_bh_status_handler( info, info->bh_action->status ); + case BH_STATUS: + mgsl_bh_status(info); break; - default: /* unknown work item ID */ - printk("Unknown work item ID=%08X!\n", - info->bh_action->type ); + printk("Unknown work item ID=%08X!\n", action); break; } } @@ -1227,51 +1154,27 @@ if ( debug_level >= DEBUG_LEVEL_BH ) printk( "%s(%d):mgsl_bh_handler(%s) exit\n", __FILE__,__LINE__,info->device_name); - -} /* end of mgsl_bh_handler() */ +} -/* mgsl_bh_receive_dma() - * - * Perform bottom half processing for a receive DMA interrupt - * This occurs in HDLC mode after a DMA buffer has terminated - * or the DMA buffers have been exhausted. - * - * Arguments: - * - * info pointer to device instance data - * status status word - * - * Return Value: None - */ -void mgsl_bh_receive_dma( struct mgsl_struct *info, unsigned short status ) +void mgsl_bh_receive(struct mgsl_struct *info) { if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_receive_dma(%s)\n", + printk( "%s(%d):mgsl_bh_receive(%s)\n", __FILE__,__LINE__,info->device_name); while( mgsl_get_rx_frame(info) ); +} -} /* end of mgsl_bh_receive_dma() */ - -/* mgsl_bh_transmit_data() - * - * Process a transmit data interrupt event - * This occurs in asynchronous communications mode. - * - * Arguments: info pointer to device instance data - * Return Value: None - */ -void mgsl_bh_transmit_data( struct mgsl_struct *info, unsigned short Datacount ) +void mgsl_bh_transmit(struct mgsl_struct *info) { struct tty_struct *tty = info->tty; unsigned long flags; if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_transmit_data() entry on %s\n", + printk( "%s(%d):mgsl_bh_transmit() entry on %s\n", __FILE__,__LINE__,info->device_name); - - /* wakeup any waiting write requests */ - if (tty) { + + if (tty) { if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) { if ( debug_level >= DEBUG_LEVEL_BH ) @@ -1289,49 +1192,19 @@ if ( !info->tx_active && info->loopmode_send_done_requested ) usc_loopmode_send_done( info ); spin_unlock_irqrestore(&info->irq_spinlock,flags); +} -} /* End Of mgsl_bh_transmit_data() */ - -/* mgsl_bh_status_handler() - * - * Peform bottom half processing for a status interrupt - * - * This event is generated when a I/O pin (serial signal) - * has a transition. If there is a pending WaitEvent call - * and the status transition is identified in the EventMast - * of the pending call then complete the pending call. - * - * Arguments: - * - * info pointer to device instance data - * status status word - * - * Return Value: None - */ -void mgsl_bh_status_handler( struct mgsl_struct *info, unsigned short status ) +void mgsl_bh_status(struct mgsl_struct *info) { if ( debug_level >= DEBUG_LEVEL_BH ) - printk( "%s(%d):mgsl_bh_status_handler() entry on %s\n", + printk( "%s(%d):mgsl_bh_status() entry on %s\n", __FILE__,__LINE__,info->device_name); - if (status & MISCSTATUS_RI_LATCHED) { - if (info->ri_chkcount) - (info->ri_chkcount)--; - } - if (status & MISCSTATUS_DSR_LATCHED) { - if (info->dsr_chkcount) - (info->dsr_chkcount)--; - } - if (status & MISCSTATUS_DCD_LATCHED) { - if (info->dcd_chkcount) - (info->dcd_chkcount)--; - } - if (status & MISCSTATUS_CTS_LATCHED) { - if (info->cts_chkcount) - (info->cts_chkcount)--; - } - -} /* End Of mgsl_bh_status_handler() */ + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + info->dcd_chkcount = 0; + info->cts_chkcount = 0; +} /* mgsl_isr_receive_status() * @@ -1375,12 +1248,6 @@ } if (status & RXSTATUS_OVERRUN){ -// /* Purge receive FIFO to allow DMA buffer completion -// * with overrun status stored in the receive status block. -// */ -// usc_RCmd( info, RCmd_EnterHuntmode ); -// usc_RTCmd( info, RTCmd_PurgeRxFifo ); - info->icount.rxover++; usc_process_rxoverrun_sync( info ); } @@ -1443,13 +1310,19 @@ } info->drop_rts_on_tx_done = 0; } - - if (info->tty->stopped || info->tty->hw_stopped) { - usc_stop_transmitter(info); - return; + +#ifdef CONFIG_SYNCLINK_SYNCPPP + if (info->netcount) + mgsl_sppp_tx_done(info); + else +#endif + { + if (info->tty->stopped || info->tty->hw_stopped) { + usc_stop_transmitter(info); + return; + } + info->pending_bh |= BH_TRANSMIT; } - - mgsl_bh_queue_put(info, BH_TYPE_TRANSMIT_STATUS, status); } /* end of mgsl_isr_transmit_status() */ @@ -1499,9 +1372,13 @@ if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) usc_DisablestatusIrqs(info,SICR_DCD); icount->dcd++; - if ( status & MISCSTATUS_DCD ) + if (status & MISCSTATUS_DCD) { info->input_signal_events.dcd_up++; - else +#ifdef CONFIG_SYNCLINK_SYNCPPP + if (info->netcount) + sppp_reopen(info->netdev); +#endif + } else info->input_signal_events.dcd_down++; #ifdef CONFIG_HARD_PPS if ((info->flags & ASYNC_HARDPPS_CD) && @@ -1544,23 +1421,25 @@ if (status & MISCSTATUS_CTS) { if ( debug_level >= DEBUG_LEVEL_ISR ) printk("CTS tx start..."); - info->tty->hw_stopped = 0; + if (info->tty) + info->tty->hw_stopped = 0; usc_start_transmitter(info); - mgsl_bh_queue_put( info, BH_TYPE_TRANSMIT_DATA, status ); + info->pending_bh |= BH_TRANSMIT; return; } } else { if (!(status & MISCSTATUS_CTS)) { if ( debug_level >= DEBUG_LEVEL_ISR ) printk("CTS tx stop..."); - info->tty->hw_stopped = 1; + if (info->tty) + info->tty->hw_stopped = 1; usc_stop_transmitter(info); } } } } - mgsl_bh_queue_put(info, BH_TYPE_STATUS, status); + info->pending_bh |= BH_STATUS; /* for diagnostics set IRQ flag */ if ( status & MISCSTATUS_TXC_LATCHED ){ @@ -1598,7 +1477,7 @@ info->tx_active = 0; if (info->xmit_cnt < WAKEUP_CHARS) - mgsl_bh_queue_put(info, BH_TYPE_TRANSMIT_DATA, (unsigned short)(info->xmit_cnt)); + info->pending_bh |= BH_TRANSMIT; } /* end of mgsl_isr_transmit_data() */ @@ -1790,8 +1669,7 @@ printk("%s(%d):mgsl_isr_receive_dma(%s) status=%04X\n", __FILE__,__LINE__,info->device_name,status); - /* Post a receive event for BH processing. */ - mgsl_bh_queue_put( info, BH_TYPE_RECEIVE_DMA, status ); + info->pending_bh |= BH_RECEIVE; if ( status & BIT3 ) { info->rx_overflow = 1; @@ -1859,7 +1737,7 @@ * for it to do and the bh is not already running */ - if ( info->bh_queue_head && !info->bh_running && !info->bh_requested ) { + if ( info->pending_bh && !info->bh_running && !info->bh_requested ) { if ( debug_level >= DEBUG_LEVEL_ISR ) printk("%s(%d):%s queueing bh task.\n", __FILE__,__LINE__,info->device_name); @@ -1903,7 +1781,7 @@ } } - mgsl_format_bh_queue(info); + info->pending_bh = 0; init_timer(&info->tx_timer); info->tx_timer.data = (unsigned long)info; @@ -1962,6 +1840,8 @@ wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); + del_timer(&info->tx_timer); + if (info->xmit_buf) { free_page((unsigned long) info->xmit_buf); info->xmit_buf = 0; @@ -2001,17 +1881,43 @@ } /* end of shutdown() */ -/* mgsl_change_params() - * - * Reconfigure adapter based on new parameters - * - * Arguments: info pointer to device instance data - * Return Value: None +static void mgsl_program_hw(struct mgsl_struct *info) +{ + unsigned long flags; + + spin_lock_irqsave(&info->irq_spinlock,flags); + + usc_stop_receiver(info); + usc_stop_transmitter(info); + info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; + + if (info->params.mode == MGSL_MODE_HDLC || info->netcount) + usc_set_sync_mode(info); + else + usc_set_async_mode(info); + + usc_set_serial_signals(info); + + info->dcd_chkcount = 0; + info->cts_chkcount = 0; + info->ri_chkcount = 0; + info->dsr_chkcount = 0; + + usc_EnableStatusIrqs(info,SICR_CTS+SICR_DSR+SICR_DCD+SICR_RI); + usc_EnableInterrupts(info, IO_PIN); + usc_get_serial_signals(info); + + if (info->netcount || info->tty->termios->c_cflag & CREAD) + usc_start_receiver(info); + + spin_unlock_irqrestore(&info->irq_spinlock,flags); +} + +/* Reconfigure adapter based on new parameters */ static void mgsl_change_params(struct mgsl_struct *info) { unsigned cflag; - unsigned long flags; int bits_per_char; if (!info->tty || !info->tty->termios) @@ -2119,35 +2025,7 @@ info->ignore_status_mask |= RXSTATUS_OVERRUN; } - /* reprogram the hardware */ - - spin_lock_irqsave(&info->irq_spinlock,flags); - - usc_stop_receiver(info); - usc_stop_transmitter(info); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - if ( info->params.mode == MGSL_MODE_HDLC ) - usc_set_sync_mode(info); - else - usc_set_async_mode(info); - - usc_set_serial_signals(info); - - info->dcd_chkcount = 0; - info->cts_chkcount = 0; - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - - /* enable modem signal IRQs and read initial signal states */ - usc_EnableStatusIrqs(info,SICR_CTS+SICR_DSR+SICR_DCD+SICR_RI); - usc_EnableInterrupts(info, IO_PIN); - usc_get_serial_signals(info); - - if ( cflag & CREAD ) - usc_start_receiver(info); - - spin_unlock_irqrestore(&info->irq_spinlock,flags); + mgsl_program_hw(info); } /* end of mgsl_change_params() */ @@ -3115,11 +2993,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { - int error; struct mgsl_struct * info = (struct mgsl_struct *)tty->driver_data; - struct mgsl_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - unsigned long flags; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, @@ -3133,6 +3007,16 @@ if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; } + + return mgsl_ioctl_common(info, cmd, arg); +} + +int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) +{ + int error; + struct mgsl_icount cprev, cnow; /* kernel counter temps */ + struct serial_icounter_struct *p_cuser; /* user space */ + unsigned long flags; switch (cmd) { case TIOCMGET: @@ -3233,10 +3117,9 @@ if (error) return error; #endif return 0; - default: return -ENOIOCTLCMD; - } + } return 0; } @@ -3662,6 +3545,7 @@ struct mgsl_struct *info; int retval, line; unsigned long page; + unsigned long flags; /* verify range of specified line number */ line = MINOR(tty->device) - tty->driver.minor_start; @@ -3717,7 +3601,15 @@ info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; #endif + spin_lock_irqsave(&info->netlock, flags); + if (info->netcount) { + retval = -EBUSY; + spin_unlock_irqrestore(&info->netlock, flags); + goto cleanup; + } info->count++; + spin_unlock_irqrestore(&info->netlock, flags); + if (info->count == 1) { /* 1st open on this device, init hardware */ retval = startup(info); @@ -3833,9 +3725,9 @@ /* Append serial signal status to end */ ret += sprintf(buf+ret, " %s\n", stat_buf+1); - ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d bh_q=%p\n", + ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", info->tx_active,info->bh_requested,info->bh_running, - info->bh_queue_head); + info->pending_bh); spin_lock_irqsave(&info->irq_spinlock,flags); { @@ -4398,6 +4290,12 @@ info->line = mgsl_device_count; sprintf(info->device_name,"ttySL%d",info->line); + if (info->line < MAX_TOTAL_DEVICES) { + if (maxframe[info->line]) + info->max_frame_size = maxframe[info->line]; + info->dosyncppp = dosyncppp[info->line]; + } + mgsl_device_count++; if ( !mgsl_device_list ) @@ -4424,7 +4322,11 @@ info->device_name, info->io_base, info->irq_level, info->dma_level, info->max_frame_size ); } - + +#ifdef CONFIG_SYNCLINK_SYNCPPP + if (info->dosyncppp) + mgsl_sppp_init(info); +#endif } /* end of mgsl_add_device() */ /* mgsl_allocate_device() @@ -4457,6 +4359,7 @@ init_waitqueue_head(&info->status_event_wait_q); init_waitqueue_head(&info->event_wait_q); spin_lock_init(&info->irq_spinlock); + spin_lock_init(&info->netlock); memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); info->idle_mode = HDLC_TXIDLE_FLAGS; } @@ -4477,7 +4380,6 @@ { struct mgsl_struct *info; int i; - int num_devices = 0; /* Check for user specified ISA devices */ @@ -4508,39 +4410,57 @@ info->io_addr_size = 16; info->irq_flags = 0; - /* override default max frame size if arg available */ - if ( num_devices < MAX_TOTAL_DEVICES && - maxframe[num_devices] ) - info->max_frame_size = maxframe[num_devices]; - - /* add new device to device list */ mgsl_add_device( info ); - - ++num_devices; } #ifdef CONFIG_PCI /* Auto detect PCI adapters */ - { + if ( pcibios_present() ) { + unsigned char bus; + unsigned char func; unsigned int shared_mem_base; unsigned int lcr_mem_base; unsigned int io_base; unsigned char irq_line; - struct pci_dev *pdev = NULL; - while ((pdev = pci_find_device( - MICROGATE_VENDOR_ID, SYNCLINK_DEVICE_ID, pdev))) { + for(i=0;;i++){ + if ( PCIBIOS_SUCCESSFUL == pcibios_find_device( + MICROGATE_VENDOR_ID, SYNCLINK_DEVICE_ID, i, &bus, &func) ) { +#if LINUX_VERSION_CODE >= VERSION(2,1,0) + struct pci_dev *pdev = pci_find_slot(bus,func); irq_line = pdev->irq; +#else + if (pcibios_read_config_byte(bus,func, + PCI_INTERRUPT_LINE,&irq_line) ) { + printk( "%s(%d):USC I/O addr not set.\n", + __FILE__,__LINE__); + continue; + } +#endif - shared_mem_base = pci_resource_start (pdev, 3); - lcr_mem_base = pci_resource_start (pdev, 0); - io_base = pci_resource_start (pdev, 2); - - if (pci_enable_device (pdev)) + if (pcibios_read_config_dword(bus,func, + PCI_BASE_ADDRESS_3,&shared_mem_base) ) { + printk( "%s(%d):Shared mem addr not set.\n", + __FILE__,__LINE__); + continue; + } + + if (pcibios_read_config_dword(bus,func, + PCI_BASE_ADDRESS_0,&lcr_mem_base) ) { + printk( "%s(%d):LCR mem addr not set.\n", + __FILE__,__LINE__); + continue; + } + + if (pcibios_read_config_dword(bus,func, + PCI_BASE_ADDRESS_2,&io_base) ) { + printk( "%s(%d):USC I/O addr not set.\n", + __FILE__,__LINE__); continue; + } info = mgsl_allocate_device(); if ( !info ) { @@ -4552,29 +4472,30 @@ /* Copy user configuration info to device instance data */ - info->io_base = io_base; + info->io_base = io_base & PCI_BASE_ADDRESS_IO_MASK; info->irq_level = (unsigned int)irq_line; +#if LINUX_VERSION_CODE >= VERSION(2,1,0) info->irq_level = irq_cannonicalize(info->irq_level); - info->phys_memory_base = shared_mem_base; +#else + if (info->irq_level == 2) + info->irq_level = 9; +#endif + info->phys_memory_base = shared_mem_base & PCI_BASE_ADDRESS_MEM_MASK; /* Because veremap only works on page boundaries we must map * a larger area than is actually implemented for the LCR * memory range. We map a full page starting at the page boundary. */ - info->phys_lcr_base = lcr_mem_base; + info->phys_lcr_base = lcr_mem_base & PCI_BASE_ADDRESS_MEM_MASK; info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1); info->phys_lcr_base &= ~(PAGE_SIZE-1); info->bus_type = MGSL_BUS_TYPE_PCI; info->io_addr_size = 8; info->irq_flags = SA_SHIRQ; - info->pdev = pdev; + info->bus = bus; + info->function = func; - /* override default max frame size if arg available */ - if ( num_devices < MAX_TOTAL_DEVICES && - maxframe[num_devices] ) - info->max_frame_size = maxframe[num_devices]; - /* Store the PCI9050 misc control register value because a flaw * in the PCI9050 prevents LCR registers from being read if * BIOS assigns an LCR base address with bit 7 set. @@ -4588,6 +4509,9 @@ /* add new device to device list */ mgsl_add_device( info ); + } else { + break; + } } } #endif @@ -4757,6 +4681,10 @@ info = mgsl_device_list; while(info) { +#ifdef CONFIG_SYNCLINK_SYNCPPP + if (info->dosyncppp) + mgsl_sppp_delete(info); +#endif mgsl_release_resources(info); info = info->next_device; } @@ -6036,12 +5964,12 @@ { if ( info->bus_type == MGSL_BUS_TYPE_PCI ) { int i; - volatile u32 readval; + u32 readval; /* Set BIT30 of Misc Control Register */ /* (Local Control Register 0x50) to force reset of USC. */ - u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); + volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50); u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28); info->misc_ctrl_value |= BIT30; @@ -6769,6 +6697,10 @@ else info->icount.rxcrc++; framesize = 0; +#ifdef CONFIG_SYNCLINK_SYNCPPP + info->netstats.rx_errors++; + info->netstats.rx_frame_errors++; +#endif } else { /* receive frame has no errors, get frame size. * The frame size is the starting value of the RCC (which was @@ -6797,19 +6729,14 @@ if (framesize > info->max_frame_size) info->icount.rxlong++; else { -#if 1 - /* - * copy contents of dma frame buffer(s) to intermediate - * rxbuffer for presentation to line discipline - */ + /* copy dma buffer(s) to contiguous intermediate buffer */ int copy_count = framesize; int index = StartIndex; unsigned char *ptmp = info->intermediate_rxbuffer; info->icount.rxok++; - while( copy_count ) - { + while(copy_count) { int partial_count; if ( copy_count > DMABUFFERSIZE ) partial_count = DMABUFFERSIZE; @@ -6823,17 +6750,19 @@ if ( ++index == info->rx_buffer_count ) index = 0; - } - - /* Call the line discipline receive callback directly. */ - tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); -#else - info->icount.rxok++; - pBufEntry = &(info->rx_buffer_list[StartIndex]); - /* Call the line discipline receive callback directly. */ - tty->ldisc.receive_buf(tty, pBufEntry->virt_addr, info->flag_buf, framesize); + +#ifdef CONFIG_SYNCLINK_SYNCPPP + if (info->netcount) { + /* pass frame to syncppp device */ + mgsl_sppp_rx_done(info,info->intermediate_rxbuffer,framesize); + } + else #endif + { + /* Call the line discipline receive callback directly. */ + tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize); + } } } /* Free the buffers used by this frame. */ @@ -7056,8 +6985,8 @@ unsigned int i; char *TmpPtr; BOOLEAN rc = TRUE; - volatile unsigned short status; - volatile unsigned long EndTime; + unsigned short status; + unsigned long EndTime; unsigned long flags; MGSL_PARAMS tmp_params; @@ -7467,12 +7396,7 @@ void mgsl_load_pci_memory( char* TargetPtr, const char* SourcePtr, unsigned short count ) { - /*******************************************************/ - /* A load interval of 16 allows for 4 32-bit writes at */ - /* 60ns each for a maximum latency of 240ns on the */ - /* local bus. */ - /*******************************************************/ - + /* 16 32-bit writes @ 60ns each = 960ns max latency on local bus */ #define PCI_LOAD_INTERVAL 64 unsigned short Intervalcount = count / PCI_LOAD_INTERVAL; @@ -7551,7 +7475,12 @@ spin_unlock_irqrestore(&info->irq_spinlock,flags); - mgsl_bh_transmit_data(info,0); +#ifdef CONFIG_SYNCLINK_SYNCPPP + if (info->netcount) + mgsl_sppp_tx_done(info); + else +#endif + mgsl_bh_transmit(info); } /* end of mgsl_tx_timeout() */ @@ -7629,3 +7558,223 @@ return usc_InReg( info, CCSR ) & BIT6 ? 1 : 0 ; } +#ifdef CONFIG_SYNCLINK_SYNCPPP +/* syncppp net device routines + */ + +void mgsl_sppp_init(struct mgsl_struct *info) +{ + struct net_device *d; + + sprintf(info->netname,"mgsl%d",info->line); + +#if LINUX_VERSION_CODE < VERSION(2,2,16) + info->netdev = &info->pppdev.dev; +#else + info->if_ptr = &info->pppdev; + info->netdev = info->pppdev.dev = &info->netdevice; +#endif + sppp_attach(&info->pppdev); + + d = info->netdev; + strcpy(d->name, info->netname); + d->base_addr = info->io_base; + d->irq = info->irq_level; + d->dma = info->dma_level; + d->priv = info; + d->init = NULL; + d->open = mgsl_sppp_open; + d->stop = mgsl_sppp_close; + d->hard_start_xmit = mgsl_sppp_tx; + d->do_ioctl = mgsl_sppp_ioctl; + d->get_stats = mgsl_net_stats; +#if LINUX_VERSION_CODE >= VERSION(2,3,43) + d->tx_timeout = mgsl_sppp_tx_timeout; + d->watchdog_timeo = 10*HZ; +#endif + dev_init_buffers(d); + + if (register_netdev(d) == -1) { + printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); + sppp_detach(info->netdev); + return; + } + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_sppp_init()\n"); +} + +void mgsl_sppp_delete(struct mgsl_struct *info) +{ + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_sppp_delete(%s)\n",info->netname); + sppp_detach(info->netdev); + unregister_netdev(info->netdev); +} + +int mgsl_sppp_open(struct net_device *d) +{ + struct mgsl_struct *info = d->priv; + int err, flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_sppp_open(%s)\n",info->netname); + + spin_lock_irqsave(&info->netlock, flags); + if (info->count != 0 || info->netcount != 0) { + printk(KERN_WARNING "%s: sppp_open returning busy\n", info->netname); + spin_unlock_irqrestore(&info->netlock, flags); + return -EBUSY; + } + info->netcount=1; + MOD_INC_USE_COUNT; + spin_unlock_irqrestore(&info->netlock, flags); + + /* claim resources and init adapter */ + if ((err = startup(info)) != 0) + goto open_fail; + + /* allow syncppp module to do open processing */ + if ((err = sppp_open(d)) != 0) { + shutdown(info); + goto open_fail; + } + + info->serial_signals |= SerialSignal_RTS + SerialSignal_DTR; + mgsl_program_hw(info); + + d->trans_start = jiffies; + netif_start_queue(d); + return 0; + +open_fail: + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&info->netlock, flags); + return err; +} + +void mgsl_sppp_tx_timeout(struct net_device *dev) +{ + struct mgsl_struct *info = dev->priv; + int flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_sppp_tx_timeout(%s)\n",info->netname); + + info->netstats.tx_errors++; + info->netstats.tx_aborted_errors++; + + spin_lock_irqsave(&info->irq_spinlock,flags); + usc_stop_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + netif_wake_queue(dev); +} + +int mgsl_sppp_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct mgsl_struct *info = dev->priv; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_sppp_tx(%s)\n",info->netname); + +#if LINUX_VERSION_CODE < VERSION(2,3,43) + if (dev->tbusy) { + if (time_before(jiffies, dev->trans_start+10*HZ)) + return -EBUSY; /* 10 seconds timeout */ + mgsl_sppp_tx_timeout(dev); + } + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) + return -EBUSY; +#else + netif_stop_queue(dev); +#endif + + info->xmit_cnt = skb->len; + mgsl_load_tx_dma_buffer(info, skb->data, skb->len); + info->netstats.tx_packets++; + info->netstats.tx_bytes += skb->len; + dev_kfree_skb(skb); + + dev->trans_start = jiffies; + + spin_lock_irqsave(&info->irq_spinlock,flags); + if (!info->tx_active) + usc_start_transmitter(info); + spin_unlock_irqrestore(&info->irq_spinlock,flags); + + return 0; +} + +int mgsl_sppp_close(struct net_device *d) +{ + struct mgsl_struct *info = d->priv; + unsigned long flags; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_sppp_close(%s)\n",info->netname); + + /* shutdown adapter and release resources */ + shutdown(info); + + /* allow syncppp to do close processing */ + sppp_close(d); + netif_stop_queue(d); + + spin_lock_irqsave(&info->netlock, flags); + info->netcount=0; + MOD_DEC_USE_COUNT; + spin_unlock_irqrestore(&info->netlock, flags); + return 0; +} + +void mgsl_sppp_rx_done(struct mgsl_struct *info, char *buf, int size) +{ + struct sk_buff *skb = dev_alloc_skb(size); + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_sppp_rx_done(%s)\n",info->netname); + if (skb == NULL) { + printk(KERN_NOTICE "%s: cant alloc skb, dropping packet\n", + info->netname); + info->netstats.rx_dropped++; + return; + } + + memcpy(skb_put(skb, size),buf,size); + + skb->protocol = htons(ETH_P_WAN_PPP); + skb->dev = info->netdev; + skb->mac.raw = skb->data; + info->netstats.rx_packets++; + info->netstats.rx_bytes += size; + netif_rx(skb); + info->netdev->trans_start = jiffies; +} + +void mgsl_sppp_tx_done(struct mgsl_struct *info) +{ + if (netif_queue_stopped(info->netdev)) + netif_wake_queue(info->netdev); +} + +struct net_device_stats *mgsl_net_stats(struct net_device *dev) +{ + struct mgsl_struct *info = dev->priv; + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgsl_net_stats(%s)\n",info->netname); + return &info->netstats; +} + +int mgsl_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct mgsl_struct *info = (struct mgsl_struct *)dev->priv; + if (debug_level >= DEBUG_LEVEL_INFO) + printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, + info->netname, cmd ); + return sppp_do_ioctl(dev, ifr, cmd); +} + +#endif /* ifdef CONFIG_SYNCLINK_SYNCPPP */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c --- v2.4.0-test3/linux/drivers/char/tpqic02.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/tpqic02.c Wed Jul 12 21:58:42 2000 @@ -89,6 +89,7 @@ #include #include #include +#include #include #include @@ -2411,6 +2412,7 @@ { kdev_t dev = inode->i_rdev; + lock_kernel(); if (TP_DIAGS(dev)) { printk("qic02_tape_release: dev=%s\n", kdevname(dev)); @@ -2437,6 +2439,7 @@ (void) do_qic_cmd(QCMD_REWIND, TIM_R); } } + unlock_kernel(); return 0; } /* qic02_tape_release */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c --- v2.4.0-test3/linux/drivers/char/tty_io.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/tty_io.c Wed Jul 12 21:58:42 2000 @@ -1430,7 +1430,9 @@ static int tty_release(struct inode * inode, struct file * filp) { + lock_kernel(); release_dev(filp); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/tvmixer.c linux/drivers/char/tvmixer.c --- v2.4.0-test3/linux/drivers/char/tvmixer.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/tvmixer.c Wed Jul 12 21:58:42 2000 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -220,13 +221,18 @@ static int tvmixer_release(struct inode *inode, struct file *file) { struct TVMIXER *mix = file->private_data; - struct i2c_client *client = mix->dev; + struct i2c_client *client; - if (NULL == client) + lock_kernel(); + client = mix->dev; + if (NULL == client) { + unlock_kernel(); return -ENODEV; + } if (client->adapter->dec_use) client->adapter->dec_use(client->adapter); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/videodev.c linux/drivers/char/videodev.c --- v2.4.0-test3/linux/drivers/char/videodev.c Mon Jul 10 16:47:22 2000 +++ linux/drivers/char/videodev.c Wed Jul 12 21:58:42 2000 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -158,11 +159,9 @@ if(vfl==NULL) { char modname[20]; - MOD_INC_USE_COUNT; sprintf (modname, "char-major-%d-%d", VIDEO_MAJOR, minor); request_module(modname); vfl=video_device[minor]; - MOD_DEC_USE_COUNT; if (vfl==NULL) return -ENODEV; } @@ -188,10 +187,13 @@ static int video_release(struct inode *inode, struct file *file) { - struct video_device *vfl=video_device[MINOR(inode->i_rdev)]; + struct video_device *vfl; + lock_kernel(); + vfl=video_device[MINOR(inode->i_rdev)]; if(vfl->close) vfl->close(vfl); vfl->busy=0; + unlock_kernel(); return 0; } @@ -229,11 +231,15 @@ int video_mmap(struct file *file, struct vm_area_struct *vma) { + int ret = -EINVAL; struct video_device *vfl=video_device[MINOR(file->f_dentry->d_inode->i_rdev)]; - if(vfl->mmap) - return vfl->mmap(vfl, (char *)vma->vm_start, + if(vfl->mmap) { + lock_kernel(); + ret = vfl->mmap(vfl, (char *)vma->vm_start, (unsigned long)(vma->vm_end-vma->vm_start)); - return -EINVAL; + unlock_kernel(); + } + return ret; } /* @@ -515,6 +521,7 @@ static struct file_operations video_fops= { + owner: THIS_MODULE, llseek: video_lseek, read: video_read, write: video_write, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/wdt.c linux/drivers/char/wdt.c --- v2.4.0-test3/linux/drivers/char/wdt.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/wdt.c Wed Jul 12 21:58:42 2000 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include "wd501p.h" @@ -372,6 +373,7 @@ static int wdt_release(struct inode *inode, struct file *file) { + lock_kernel(); if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) { #ifndef CONFIG_WATCHDOG_NOWAYOUT @@ -380,6 +382,7 @@ #endif wdt_is_open=0; } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/wdt285.c linux/drivers/char/wdt285.c --- v2.4.0-test3/linux/drivers/char/wdt285.c Thu Mar 2 14:36:22 2000 +++ linux/drivers/char/wdt285.c Wed Jul 12 21:58:42 2000 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -74,7 +75,6 @@ { if(timer_alive) return -EBUSY; - MOD_INC_USE_COUNT; /* * Ahead watchdog factor ten, Mr Sulu */ @@ -86,6 +86,7 @@ request_irq(IRQ_TIMER4, watchdog_fire, 0, "watchdog", NULL); #else *CSR_SA110_CNTL |= 1 << 13; + MOD_INC_USE_COUNT; #endif timer_alive = 1; return 0; @@ -94,9 +95,10 @@ static int watchdog_release(struct inode *inode, struct file *file) { #ifdef ONLY_TESTING + lock_kernel(); free_irq(IRQ_TIMER4, NULL); timer_alive = 0; - MOD_DEC_USE_COUNT; + unlock_kernel(); #else /* * It's irreversible! @@ -153,6 +155,7 @@ static struct file_operations watchdog_fops= { + owner: THIS_MODULE, write: watchdog_write, ioctl: watchdog_ioctl, open: watchdog_open, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/wdt977.c linux/drivers/char/wdt977.c --- v2.4.0-test3/linux/drivers/char/wdt977.c Thu Mar 2 14:36:22 2000 +++ linux/drivers/char/wdt977.c Wed Jul 12 21:58:42 2000 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,9 @@ { if(timer_alive) return -EBUSY; +#ifdef CONFIG_WATCHDOG_NOWAYOUT MOD_INC_USE_COUNT; +#endif timer_alive++; //max timeout value = 255 minutes (0xFF). Write 0 to disable WatchDog. @@ -88,6 +91,7 @@ * Lock it in if it's a module and we defined ...NOWAYOUT */ #ifndef CONFIG_WATCHDOG_NOWAYOUT + lock_kernel(); // unlock the SuperIO chip outb(0x87,0x370); @@ -118,8 +122,8 @@ // lock the SuperIO chip outb(0xAA,0x370); - MOD_DEC_USE_COUNT; timer_alive=0; + unlock_kernel(); printk(KERN_INFO "Watchdog: shutdown.\n"); #endif @@ -162,6 +166,7 @@ static struct file_operations wdt977_fops= { + owner: THIS_MODULE, write: wdt977_write, open: wdt977_open, release: wdt977_release, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/char/wdt_pci.c linux/drivers/char/wdt_pci.c --- v2.4.0-test3/linux/drivers/char/wdt_pci.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/char/wdt_pci.c Wed Jul 12 21:58:42 2000 @@ -51,6 +51,7 @@ #include #include #include +#include #include @@ -358,7 +359,9 @@ case WATCHDOG_MINOR: if(wdt_is_open) return -EBUSY; +#ifdef CONFIG_WATCHDOG_NOWAYOUT MOD_INC_USE_COUNT; +#endif /* * Activate */ @@ -391,7 +394,6 @@ outb_p(0, WDT_DC); /* Enable */ return 0; case TEMP_MINOR: - MOD_INC_USE_COUNT; return 0; default: return -ENODEV; @@ -414,13 +416,14 @@ { if(MINOR(inode->i_rdev)==WATCHDOG_MINOR) { + lock_kernel(); #ifndef CONFIG_WATCHDOG_NOWAYOUT inb_p(WDT_DC); /* Disable counters */ wdtpci_ctr_load(2,0); /* 0 length reset pulses now */ #endif wdt_is_open=0; + unlock_kernel(); } - MOD_DEC_USE_COUNT; return 0; } @@ -454,6 +457,7 @@ static struct file_operations wdtpci_fops = { + owner: THIS_MODULE, llseek: wdtpci_llseek, read: wdtpci_read, write: wdtpci_write, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/i2c/i2c-dev.c linux/drivers/i2c/i2c-dev.c --- v2.4.0-test3/linux/drivers/i2c/i2c-dev.c Sun Mar 19 18:35:30 2000 +++ linux/drivers/i2c/i2c-dev.c Wed Jul 12 21:58:42 2000 @@ -32,6 +32,7 @@ #include #include #include +#include /* If you want debugging uncomment: */ /* #define DEBUG */ @@ -76,6 +77,7 @@ static int i2cdev_cleanup(void); static struct file_operations i2cdev_fops = { + owner: THIS_MODULE, llseek: i2cdev_lseek, read: i2cdev_read, write: i2cdev_write, @@ -374,7 +376,6 @@ if (i2cdev_adaps[minor]->inc_use) i2cdev_adaps[minor]->inc_use(i2cdev_adaps[minor]); - MOD_INC_USE_COUNT; #ifdef DEBUG printk("i2c-dev.o: opened i2c-%d\n",minor); @@ -390,9 +391,10 @@ #ifdef DEBUG printk("i2c-dev.o: Closed: i2c-%d\n", minor); #endif - MOD_DEC_USE_COUNT; + lock_kernel(); if (i2cdev_adaps[minor]->dec_use) i2cdev_adaps[minor]->dec_use(i2cdev_adaps[minor]); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/i2o/i2o_config.c linux/drivers/i2o/i2o_config.c --- v2.4.0-test3/linux/drivers/i2o/i2o_config.c Fri Jun 23 21:55:08 2000 +++ linux/drivers/i2o/i2o_config.c Wed Jul 12 21:58:42 2000 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -848,6 +849,7 @@ struct i2o_cfg_info *p1, *p2; unsigned int flags; + lock_kernel(); p1 = p2 = NULL; spin_lock_irqsave(&i2o_config_lock, flags); @@ -870,6 +872,7 @@ p1 = p1->next; } spin_unlock_irqrestore(&i2o_config_lock, flags); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c --- v2.4.0-test3/linux/drivers/ide/ide-tape.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/ide/ide-tape.c Wed Jul 12 21:58:42 2000 @@ -402,6 +402,7 @@ #include #include #include +#include #include #include @@ -5235,11 +5236,6 @@ if (test_and_set_bit (IDETAPE_BUSY, &tape->flags)) return -EBUSY; - MOD_INC_USE_COUNT; -#if ONSTREAM_DEBUG - if (tape->debug_level >= 6) - printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_chrdev_open-1\n"); -#endif if (!tape->onstream) { idetape_read_position(drive); if (!test_bit (IDETAPE_ADDRESS_VALID, &tape->flags)) @@ -5255,28 +5251,13 @@ } if (idetape_wait_ready(drive, 60 * HZ)) { clear_bit(IDETAPE_BUSY, &tape->flags); - MOD_DEC_USE_COUNT; -#if ONSTREAM_DEBUG - if (tape->debug_level >= 6) - printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_chrdev_open-1\n"); -#endif printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); return -EBUSY; } idetape_read_position(drive); - MOD_DEC_USE_COUNT; -#if ONSTREAM_DEBUG - if (tape->debug_level >= 6) - printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_chrdev_open-2\n"); -#endif clear_bit (IDETAPE_PIPELINE_ERROR, &tape->flags); if (tape->chrdev_direction == idetape_direction_none) { - MOD_INC_USE_COUNT; -#if ONSTREAM_DEBUG - if (tape->debug_level >= 6) - printk(KERN_INFO "ide-tape: MOD_INC_USE_COUNT in idetape_chrdev_open-2\n"); -#endif idetape_create_prevent_cmd(drive, &pc, 1); if (!idetape_queue_pc_tail (drive,&pc)) { if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) @@ -5296,10 +5277,12 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) { ide_drive_t *drive = get_drive_ptr (inode->i_rdev); - idetape_tape_t *tape = drive->driver_data; + idetape_tape_t *tape; idetape_pc_t pc; unsigned int minor=MINOR (inode->i_rdev); - + + lock_kernel(); + tape = drive->driver_data; #if IDETAPE_DEBUG_LOG if (tape->debug_level >= 3) printk (KERN_INFO "ide-tape: Reached idetape_chrdev_release\n"); @@ -5337,13 +5320,9 @@ if (!idetape_queue_pc_tail (drive,&pc)) tape->door_locked = DOOR_UNLOCKED; } - MOD_DEC_USE_COUNT; -#if ONSTREAM_DEBUG - if (tape->debug_level >= 6) - printk(KERN_INFO "ide-tape: MOD_DEC_USE_COUNT in idetape_chrdev_release\n"); -#endif } clear_bit (IDETAPE_BUSY, &tape->flags); + unlock_kernel(); return 0; } @@ -5919,6 +5898,7 @@ * Our character device supporting functions, passed to register_chrdev. */ static struct file_operations idetape_fops = { + owner: THIS_MODULE, read: idetape_chrdev_read, write: idetape_chrdev_write, ioctl: idetape_chrdev_ioctl, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c --- v2.4.0-test3/linux/drivers/ieee1394/raw1394.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/ieee1394/raw1394.c Wed Jul 12 21:58:42 2000 @@ -17,6 +17,7 @@ #include #include #include +#include #include #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) @@ -869,6 +870,7 @@ struct pending_request *req; int done = 0, i; + lock_kernel(); for (i = 0; i < 64; i++) { if (fi->listen_channels & (1ULL << i)) { hpsb_unlisten_channel(hl_handle, fi->host, i); @@ -913,6 +915,7 @@ kfree(fi); V22_COMPAT_MOD_DEC_USE_COUNT; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/ieee1394/video1394.c linux/drivers/ieee1394/video1394.c --- v2.4.0-test3/linux/drivers/ieee1394/video1394.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/ieee1394/video1394.c Wed Jul 12 21:58:42 2000 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1043,18 +1044,20 @@ { struct video_card *video = &video_cards[MINOR(file->f_dentry->d_inode->i_rdev)]; - struct ti_ohci *ohci= video->ohci; + struct ti_ohci *ohci; + int res = -EINVAL; + lock_kernel(); + ohci = video->ohci; PRINT(KERN_INFO, ohci->id, "mmap"); if (video->current_ctx == NULL) { PRINT(KERN_ERR, ohci->id, "current iso context not set"); - return -EINVAL; - } - - return do_iso_mmap(ohci, video->current_ctx, + } else + res = do_iso_mmap(ohci, video->current_ctx, (char *)vma->vm_start, (unsigned long)(vma->vm_end-vma->vm_start)); - return 0; + unlock_kernel(); + return res; } static int video1394_open(struct inode *inode, struct file *file) @@ -1079,6 +1082,7 @@ struct ti_ohci *ohci= video->ohci; int i; + lock_kernel(); for (i=0;inb_iso_rcv_ctx-1;i++) if (video->ir_context[i]) { if (!test_and_clear_bit( @@ -1115,6 +1119,7 @@ V22_COMPAT_MOD_DEC_USE_COUNT; PRINT(KERN_INFO, ohci->id, "release"); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c --- v2.4.0-test3/linux/drivers/isdn/avmb1/capi.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/isdn/avmb1/capi.c Wed Jul 12 21:58:42 2000 @@ -182,6 +182,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE @@ -379,10 +380,8 @@ struct capiminor *mp, **pp; unsigned int minor = 0; - MOD_INC_USE_COUNT; mp = (struct capiminor *)kmem_cache_alloc(capiminor_cachep, GFP_ATOMIC); if (!mp) { - MOD_DEC_USE_COUNT; printk(KERN_ERR "capi: can't alloc capiminor\n"); return 0; } @@ -434,7 +433,6 @@ kfree_skb(skb); capiminor_del_all_ack(mp); kmem_cache_free(capiminor_cachep, mp); - MOD_DEC_USE_COUNT; #ifdef _DEBUG_REFCOUNT printk(KERN_DEBUG "capiminor_free %d\n", GET_USE_COUNT(THIS_MODULE)); #endif @@ -1212,7 +1210,6 @@ if ((file->private_data = capidev_alloc(file)) == 0) return -ENOMEM; - MOD_INC_USE_COUNT; #ifdef _DEBUG_REFCOUNT printk(KERN_DEBUG "capi_open %d\n", GET_USE_COUNT(THIS_MODULE)); #endif @@ -1224,14 +1221,15 @@ { struct capidev *cdev = (struct capidev *)file->private_data; + lock_kernel(); capincci_free(cdev, 0xffffffff); capidev_free(cdev); file->private_data = NULL; - MOD_DEC_USE_COUNT; #ifdef _DEBUG_REFCOUNT printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(THIS_MODULE)); #endif + unlock_kernel(); return 0; } @@ -1414,11 +1412,13 @@ struct capiminor *mp = (struct capiminor *)file->private_data; if (mp) { + lock_kernel(); mp->file = 0; if (mp->nccip == 0) { capiminor_free(mp); file->private_data = NULL; } + unlock_kernel(); } #ifdef _DEBUG_REFCOUNT @@ -2050,8 +2050,6 @@ { char *p; - MOD_INC_USE_COUNT; - if ((p = strchr(revision, ':'))) { strcpy(rev, p + 2); p = strchr(rev, '$'); @@ -2061,7 +2059,6 @@ if (devfs_register_chrdev(capi_major, "capi20", &capi_fops)) { printk(KERN_ERR "capi20: unable to get major %d\n", capi_major); - MOD_DEC_USE_COUNT; return -EIO; } @@ -2069,7 +2066,6 @@ if (devfs_register_chrdev(capi_rawmajor, "capi/r%d", &capinc_raw_fops)) { devfs_unregister_chrdev(capi_major, "capi20"); printk(KERN_ERR "capi20: unable to get major %d\n", capi_rawmajor); - MOD_DEC_USE_COUNT; return -EIO; } devfs_register_series (NULL, "capi/r%u", CAPINC_NR_PORTS, @@ -2085,7 +2081,6 @@ if ((capifuncs = attach_capi_interface(&cuser)) == 0) { - MOD_DEC_USE_COUNT; devfs_unregister_chrdev(capi_major, "capi20"); #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE devfs_unregister_chrdev(capi_rawmajor, "capi/r%d"); @@ -2101,7 +2096,6 @@ (void) detach_capi_interface(&cuser); devfs_unregister_chrdev(capi_major, "capi20"); devfs_unregister_chrdev(capi_rawmajor, "capi/r%d"); - MOD_DEC_USE_COUNT; return -ENOMEM; } #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ @@ -2122,7 +2116,6 @@ devfs_unregister(devfs_find_handle(NULL, "capi20", capi_major, 0, DEVFS_SPECIAL_CHR, 0)); - MOD_DEC_USE_COUNT; return -ENOMEM; } @@ -2131,7 +2124,6 @@ printk(KERN_NOTICE "capi20: Rev%s: started up with major %d\n", rev, capi_major); - MOD_DEC_USE_COUNT; return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c --- v2.4.0-test3/linux/drivers/isdn/divert/divert_procfs.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/isdn/divert/divert_procfs.c Wed Jul 12 21:58:42 2000 @@ -199,6 +199,7 @@ struct divert_info *inf; int flags; + lock_kernel(); save_flags(flags); cli(); if_used--; @@ -214,6 +215,7 @@ divert_info_head = divert_info_head->next; kfree(inf); } + unlock_kernel(); return (0); } /* isdn_divert_close */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c --- v2.4.0-test3/linux/drivers/isdn/hysdn/hysdn_procconf.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/isdn/hysdn/hysdn_procconf.c Wed Jul 12 21:58:42 2000 @@ -372,6 +372,7 @@ int retval = 0; struct proc_dir_entry *pd; + lock_kernel(); /* search the addressed card */ card = card_root; while (card) { @@ -381,6 +382,7 @@ card = card->next; /* search next entry */ } if (!card) { + unlock_kernel(); return (-ENODEV); /* device is unknown/invalid */ } if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL)) @@ -403,6 +405,7 @@ if (filep->private_data) kfree(filep->private_data); /* release memory */ } + unlock_kernel(); return (retval); } /* hysdn_conf_close */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/isdn/hysdn/hysdn_procfs.c linux/drivers/isdn/hysdn/hysdn_procfs.c --- v2.4.0-test3/linux/drivers/isdn/hysdn/hysdn_procfs.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/isdn/hysdn/hysdn_procfs.c Wed Jul 12 21:58:42 2000 @@ -254,7 +254,7 @@ hysdn_card *card; int flags, retval = 0; - + lock_kernel(); if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { /* write only access -> write debug completely written */ retval = 0; /* success */ @@ -297,6 +297,7 @@ } } /* read access */ + unlock_kernel(); return (retval); } /* hysdn_log_close */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c --- v2.4.0-test3/linux/drivers/isdn/hysdn/hysdn_proclog.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/isdn/hysdn/hysdn_proclog.c Wed Jul 12 21:58:42 2000 @@ -345,6 +345,7 @@ int flags, retval = 0; + lock_kernel(); if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { /* write only access -> write debug level written */ retval = 0; /* success */ @@ -386,6 +387,7 @@ kfree(inf); } } /* read access */ + unlock_kernel(); return (retval); } /* hysdn_log_close */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- v2.4.0-test3/linux/drivers/isdn/isdn_common.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/isdn/isdn_common.c Wed Jul 12 21:58:42 2000 @@ -439,6 +439,7 @@ #include #include #include +#include #include "isdn_common.h" #include "isdn_tty.h" #include "isdn_net.h" @@ -485,11 +486,10 @@ static void isdn_unregister_devfs(int); void -isdn_MOD_INC_USE_COUNT(void) +isdn_lock_drivers(void) { int i; - MOD_INC_USE_COUNT; for (i = 0; i < dev->drivers; i++) { isdn_ctrl cmd; @@ -502,11 +502,17 @@ } void -isdn_MOD_DEC_USE_COUNT(void) +isdn_MOD_INC_USE_COUNT(void) +{ + MOD_INC_USE_COUNT; + isdn_lock_drivers(); +} + +void +isdn_unlock_drivers(void) { int i; - MOD_DEC_USE_COUNT; for (i = 0; i < dev->drivers; i++) if (dev->drv[i]->locks > 0) { isdn_ctrl cmd; @@ -519,6 +525,13 @@ } } +void +isdn_MOD_DEC_USE_COUNT(void) +{ + MOD_DEC_USE_COUNT; + isdn_unlock_drivers(); +} + #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP) void isdn_dumppkt(char *s, u_char * p, int len, int dumplen) @@ -1976,8 +1989,6 @@ /* * Open the device code. - * MOD_INC_USE_COUNT make sure that the driver memory is not freed - * while the device is in use. */ static int isdn_open(struct inode *ino, struct file *filep) @@ -1990,7 +2001,6 @@ infostruct *p; if ((p = (infostruct *) kmalloc(sizeof(infostruct), GFP_KERNEL))) { - MOD_INC_USE_COUNT; p->next = (char *) dev->infochain; p->private = (char *) &(filep->private_data); dev->infochain = p; @@ -2011,21 +2021,21 @@ return -ENODEV; if (!(dev->drv[drvidx]->online & (1 << chidx))) return -ENODEV; - isdn_MOD_INC_USE_COUNT(); + isdn_lock_drivers(); return 0; } if (minor <= ISDN_MINOR_CTRLMAX) { drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL); if (drvidx < 0) return -ENODEV; - isdn_MOD_INC_USE_COUNT(); + isdn_lock_drivers(); return 0; } #ifdef CONFIG_ISDN_PPP if (minor <= ISDN_MINOR_PPPMAX) { int ret; if (!(ret = isdn_ppp_open(minor - ISDN_MINOR_PPP, filep))) - isdn_MOD_INC_USE_COUNT(); + isdn_lock_drivers(); return ret; } #endif @@ -2037,11 +2047,11 @@ { uint minor = MINOR(ino->i_rdev); + lock_kernel(); if (minor == ISDN_MINOR_STATUS) { infostruct *p = dev->infochain; infostruct *q = NULL; - MOD_DEC_USE_COUNT; while (p) { if (p->private == (char *) &(filep->private_data)) { if (q) @@ -2049,31 +2059,38 @@ else dev->infochain = (infostruct *) (p->next); kfree(p); + unlock_kernel(); return 0; } q = p; p = (infostruct *) (p->next); } printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n"); + unlock_kernel(); return 0; } - isdn_MOD_DEC_USE_COUNT(); - if (minor < ISDN_MINOR_CTRL) + isdn_unlock_drivers(); + if (minor < ISDN_MINOR_CTRL) { + unlock_kernel(); return 0; + } if (minor <= ISDN_MINOR_CTRLMAX) { if (dev->profd == current) dev->profd = NULL; + unlock_kernel(); return 0; } #ifdef CONFIG_ISDN_PPP if (minor <= ISDN_MINOR_PPPMAX) isdn_ppp_release(minor - ISDN_MINOR_PPP, filep); #endif + unlock_kernel(); return 0; } static struct file_operations isdn_fops = { + owner: THIS_MODULE, llseek: isdn_lseek, read: isdn_read, write: isdn_write, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c --- v2.4.0-test3/linux/drivers/isdn/isdn_net.c Thu May 11 15:30:07 2000 +++ linux/drivers/isdn/isdn_net.c Tue Jul 11 11:12:23 2000 @@ -1820,7 +1820,7 @@ /* * Get statistics */ -static struct enet_statistics * +static struct net_device_stats * isdn_net_get_stats(struct net_device *dev) { isdn_net_local *lp = (isdn_net_local *) dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/macintosh/adb.c linux/drivers/macintosh/adb.c --- v2.4.0-test3/linux/drivers/macintosh/adb.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/macintosh/adb.c Wed Jul 12 21:58:42 2000 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -516,6 +517,7 @@ struct adbdev_state *state = file->private_data; unsigned long flags; + lock_kernel(); if (state) { file->private_data = NULL; spin_lock_irqsave(&state->lock, flags); @@ -528,6 +530,7 @@ spin_unlock_irqrestore(&state->lock, flags); } } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c --- v2.4.0-test3/linux/drivers/macintosh/via-pmu.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/macintosh/via-pmu.c Wed Jul 12 21:58:42 2000 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1031,12 +1032,12 @@ pmu_register_sleep_notifier(struct pmu_sleep_notifier *n) { struct list_head *list; - struct pmu_sleep_notifier *current; + struct pmu_sleep_notifier *notifier; for (list = sleep_notifiers.next; list != &sleep_notifiers; list = list->next) { - current = list_entry(list, struct pmu_sleep_notifier, list); - if (n->priority > current->priority) + notifier = list_entry(list, struct pmu_sleep_notifier, list); + if (n->priority > notifier->priority) break; } __list_add(&n->list, list->prev, list); @@ -1059,18 +1060,18 @@ { int ret = PBOOK_SLEEP_OK; struct list_head *list; - struct pmu_sleep_notifier *current; + struct pmu_sleep_notifier *notifier; for (list = sleep_notifiers.prev; list != &sleep_notifiers; list = list->prev) { - current = list_entry(list, struct pmu_sleep_notifier, list); - ret = current->notifier_call(current, when); + notifier = list_entry(list, struct pmu_sleep_notifier, list); + ret = notifier->notifier_call(notifier, when); if (ret != PBOOK_SLEEP_OK) { printk(KERN_DEBUG "sleep %d rejected by %p (%p)\n", - when, current, current->notifier_call); + when, notifier, notifier->notifier_call); for (; list != &sleep_notifiers; list = list->next) { - current = list_entry(list, struct pmu_sleep_notifier, list); - current->notifier_call(current, fallback); + notifier = list_entry(list, struct pmu_sleep_notifier, list); + notifier->notifier_call(notifier, fallback); } return ret; } @@ -1084,12 +1085,12 @@ { int ret = PBOOK_SLEEP_OK; struct list_head *list; - struct pmu_sleep_notifier *current; + struct pmu_sleep_notifier *notifier; for (list = sleep_notifiers.next; list != &sleep_notifiers; list = list->next) { - current = list_entry(list, struct pmu_sleep_notifier, list); - current->notifier_call(current, PBOOK_WAKE); + notifier = list_entry(list, struct pmu_sleep_notifier, list); + notifier->notifier_call(notifier, PBOOK_WAKE); } return ret; } @@ -1539,6 +1540,7 @@ struct pmu_private *pp = file->private_data; unsigned long flags; + lock_kernel(); if (pp != 0) { file->private_data = 0; spin_lock_irqsave(&all_pvt_lock, flags); @@ -1546,6 +1548,7 @@ spin_unlock_irqrestore(&all_pvt_lock, flags); kfree(pp); } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/Config.in linux/drivers/mtd/Config.in --- v2.4.0-test3/linux/drivers/mtd/Config.in Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/Config.in Thu Jul 13 10:19:55 2000 @@ -1,43 +1,67 @@ + +# $Id: Config.in,v 1.20 2000/07/13 12:40:46 scote1 Exp $ + mainmenu_option next_comment comment 'Memory Technology Devices (MTD)' tristate 'Memory Technology Device (MTD) support' CONFIG_MTD if [ "$CONFIG_MTD" != "n" ]; then - dep_tristate 'Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD - dep_tristate 'CFI support for Intel/Sharp Extended Command Set chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_CFI - dep_tristate 'CFI chips in virtual memory map' CONFIG_MTD_NORA $CONFIG_MTD_CFI - dep_tristate 'CFI chips in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI - dep_tristate 'CFI chips on RPXLite PPC board' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI - dep_tristate 'M-Systems Disk-On-Chip 1000 support' CONFIG_MTD_DOC1000 $CONFIG_MTD - dep_tristate 'M-Systems Disk-On-Chip 2000' CONFIG_MTD_DOC2000 $CONFIG_MTD - dep_tristate 'M-Systems Disk-On-Chip Millennium' CONFIG_MTD_DOC2001 $CONFIG_MTD - if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then - define_bool CONFIG_MTD_DOCPROBE y - else - if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then - define_bool CONFIG_MTD_DOCPROBE m - else - define_bool CONFIG_MTD_DOCPROBE n - fi - fi - dep_tristate 'Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD - dep_tristate 'Octagon 5066 SBC onboard flash support' CONFIG_MTD_OCTAGON $CONFIG_MTD - dep_tristate 'Tempustech VMAX SBC301 onboard flash support' CONFIG_MTD_VMAX $CONFIG_MTD - dep_tristate 'Mixcom piggyback flash card support' CONFIG_MTD_MIXMEM $CONFIG_MTD - dep_tristate 'Ramix PMC551 PCI Mezzanine ram card support' CONFIG_MTD_PMC551 $CONFIG_MTD - if [ "$CONFIG_MTD_PMC551" != "n" ]; then - bool 'PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX - fi - dep_tristate 'Debugging RAM test driver' CONFIG_MTD_MTDRAM $CONFIG_MTD - - dep_tristate 'FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD - dep_tristate 'NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD - if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_NFTL" != "n" ]; then - bool 'Write support for NFTL (EXPERIMENTAL)' CONFIG_NFTL_RW - fi - dep_tristate 'Direct blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD - dep_tristate 'Direct chardevice access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD + dep_tristate ' M-Systems Disk-On-Chip 1000 support' CONFIG_MTD_DOC1000 $CONFIG_MTD + dep_tristate ' M-Systems Disk-On-Chip 2000' CONFIG_MTD_DOC2000 $CONFIG_MTD + dep_tristate ' M-Systems Disk-On-Chip Millennium' CONFIG_MTD_DOC2001 $CONFIG_MTD + if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then + define_tristate CONFIG_MTD_DOCPROBE y + else + if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then + define_tristate CONFIG_MTD_DOCPROBE m + else + define_tristate CONFIG_MTD_DOCPROBE n + fi + fi + dep_tristate ' Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD + dep_tristate ' Ramix PMC551 PCI Mezzanine ram card support' CONFIG_MTD_PMC551 $CONFIG_MTD + if [ "$CONFIG_MTD_PMC551" != "n" ]; then + bool ' PMC551 256M DRAM Bugfix' CONFIG_MTD_PMC551_BUGFIX + fi + dep_tristate ' Debugging RAM test driver' CONFIG_MTD_MTDRAM $CONFIG_MTD + if [ "$CONFIG_MTD_MTDRAM" != "n" ]; then + int 'Device size in kB' CONFIG_MTDRAM_TOTAL_SIZE 4096 + int 'Size of the erase sectors in kB' CONFIG_MTDRAM_ERASE_SIZE 128 + fi + +comment 'MTD drivers for mapped chips' + dep_tristate ' Common Flash Interface (CFI) support' CONFIG_MTD_CFI $CONFIG_MTD + dep_tristate ' CFI support for Intel/Sharp Extended Command Set chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI + dep_tristate ' CFI support for AMD/Fujitsu Standard Command Set chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_CFI + +# These will later become config-options +define_bool CONFIG_MTD_JEDEC n +define_bool CONFIG_MTD_RAM n +define_bool CONFIG_MTD_ROM n + + dep_tristate ' Flash chip mapping in physical memory' CONFIG_MTD_PHYSMAP $CONFIG_MTD_CFI + if [ "$CONFIG_MTD_PHYSMAP" != "n" ]; then + hex 'Physical start location of flash chip mapping' CONFIG_MTD_PHYSMAP_START 0x8000000 + hex 'Physical length of flash chip mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000 + fi + +comment 'Drivers for chip mappings' + dep_tristate ' Flash chip mapping on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC + dep_tristate ' Flash chip mapping on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI + dep_tristate ' Flash chip mapping on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC + dep_tristate ' Flash chip mapping on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI + dep_tristate ' Flash chip mapping on RPXLite PPC board' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI + dep_tristate ' Flash chip mapping on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC + +comment 'User modules and translation layers for MTD devices' + dep_tristate ' Direct chardevice access to MTD devices' CONFIG_MTD_CHAR $CONFIG_MTD + dep_tristate ' Pseudo-blockdevice access to MTD devices' CONFIG_MTD_BLOCK $CONFIG_MTD + dep_tristate ' FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD + dep_tristate ' NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD + if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_NFTL" != "n" ]; then + bool ' Write support for NFTL (EXPERIMENTAL)' CONFIG_NFTL_RW + fi fi endmenu diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/Makefile linux/drivers/mtd/Makefile --- v2.4.0-test3/linux/drivers/mtd/Makefile Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/Makefile Thu Jul 13 10:19:55 2000 @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.20 2000/07/04 08:58:10 dwmw2 Exp $ +# $Id: Makefile,v 1.21 2000/07/13 10:42:55 dwmw2 Exp $ # Uncomment this to enable the DBG macro (see mtd.h) #CFLAGS+= -DZDBG @@ -68,6 +68,14 @@ endif endif +ifeq ($(CONFIG_MTD_CFI_AMDSTD),y) + OX_OBJS += cfi_cmdset_0002.o +else + ifeq ($(CONFIG_MTD_CFI_AMDSTD),m) + MX_OBJS += cfi_cmdset_0002.o + endif +endif + ifeq ($(CONFIG_MTD_DOC1000),y) O_OBJS += doc1000.o else @@ -149,6 +157,14 @@ else ifeq ($(CONFIG_MTD_MTDRAM),m) M_OBJS += mtdram.o + endif +endif + +ifeq ($(CONFIG_MTD_PNC2000),y) + O_OBJS += pnc2000.o +else + ifeq ($(CONFIG_MTD_PNC2000),m) + M_OBJS += pnc2000.o endif endif diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/cfi_cmdset_0001.c linux/drivers/mtd/cfi_cmdset_0001.c --- v2.4.0-test3/linux/drivers/mtd/cfi_cmdset_0001.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/cfi_cmdset_0001.c Thu Jul 13 10:19:55 2000 @@ -4,7 +4,7 @@ * * (C) 2000 Red Hat. GPL'd * - * $Id: cfi_cmdset_0001.c,v 1.20 2000/07/04 07:36:43 dwmw2 Exp $ + * $Id: cfi_cmdset_0001.c,v 1.21 2000/07/13 10:36:14 dwmw2 Exp $ */ #include @@ -455,13 +455,9 @@ chip->word_write_time--; if (!chip->word_write_time) chip->word_write_time++; - else - printk("decreasing word_write_time to %d µs\n", chip->word_write_time); } - if (z > 100) { + if (z > 1) chip->word_write_time++; - printk("increasing word_write_time to %d µs\n", chip->word_write_time); - } /* Done and happy. */ chip->state = FL_STATUS; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/cfi_cmdset_0002.c linux/drivers/mtd/cfi_cmdset_0002.c --- v2.4.0-test3/linux/drivers/mtd/cfi_cmdset_0002.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/mtd/cfi_cmdset_0002.c Thu Jul 13 10:19:55 2000 @@ -0,0 +1,610 @@ +/* + * Common Flash Interface support: + * AMD & Fujitsu Extended Vendor Command Set (ID 0x0002) + * + * Copyright (C) 2000 Crossnet Co. + * + * This code is GPL + * + * $Id: cfi_cmdset_0002.c,v 1.1 2000/07/11 12:32:09 dwmw2 Exp $ + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < 0x20300 +#define set_current_state(x) current->state = (x); +#endif + +static int cfi_amdext_read_2_by_16 (struct mtd_info *, loff_t, size_t, size_t *, u_char *); +static int cfi_amdext_write_2_by_16(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); +static int cfi_amdext_erase_2_by_16 (struct mtd_info *, struct erase_info *); +static void cfi_amdext_sync (struct mtd_info *); +static int cfi_amdext_suspend (struct mtd_info *); +static void cfi_amdext_resume (struct mtd_info *); + +static void cfi_amdext_destroy(struct mtd_info *); + +void cfi_cmdset_0002(struct map_info *, int, unsigned long); +EXPORT_SYMBOL(cfi_cmdset_0002); + +struct mtd_info *cfi_amdext_setup (struct map_info *); + +void cfi_cmdset_0002(struct map_info *map, int primary, unsigned long base) +{ + struct cfi_private *cfi = map->fldrv_priv; + int i; +// struct cfi_pri_intelext *extp; + + __u16 adr = primary?cfi->cfiq.P_ADR:cfi->cfiq.A_ADR; + + printk(" Amd/Fujitsu Extended Query Table at 0x%4.4X\n", adr); + + + /* If there was an old setup function, decrease its use count */ + if (cfi->cmdset_setup) + put_module_symbol((unsigned long)cfi->cmdset_setup); + if (cfi->cmdset_priv) + kfree(cfi->cmdset_priv); + + for (i=0; i< cfi->numchips; i++) { + cfi->chips[i].word_write_time = 128; + cfi->chips[i].buffer_write_time = 128; + cfi->chips[i].erase_time = 1024; + } + + + cfi->cmdset_setup = cfi_amdext_setup; +// cfi->cmdset_priv = extp; + MOD_INC_USE_COUNT; /* So the setup function is still there + * by the time it's called */ + + return; +} + +struct mtd_info *cfi_amdext_setup(struct map_info *map) +{ + struct cfi_private *cfi = map->fldrv_priv; + struct mtd_info *mtd; + + mtd = kmalloc(sizeof(*mtd), GFP_KERNEL); + printk("number of CFI chips: %d\n", cfi->numchips); + + if (!mtd) { + printk("Failed to allocate memory for MTD device\n"); + kfree(cfi->cmdset_priv); + return NULL; + } + + memset(mtd, 0, sizeof(*mtd)); + mtd->priv = map; + mtd->type = MTD_NORFLASH; + mtd->erasesize = 0x20000; /* FIXME */ + /* Also select the correct geometry setup too */ + mtd->size = (1 << cfi->cfiq.DevSize) * cfi->numchips * cfi->interleave; + mtd->erase = cfi_amdext_erase_2_by_16; + mtd->read = cfi_amdext_read_2_by_16; + mtd->write = cfi_amdext_write_2_by_16; + mtd->sync = cfi_amdext_sync; + mtd->suspend = cfi_amdext_suspend; + mtd->resume = cfi_amdext_resume; + mtd->flags = MTD_CAP_NORFLASH; + map->fldrv_destroy = cfi_amdext_destroy; + mtd->name = map->name; + return mtd; +} + +static inline int do_read_2_by_16_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long timeo = jiffies + HZ; + + retry: + spin_lock_bh(chip->mutex); + + if (chip->state != FL_READY){ +printk("Waiting for chip to read, status = %d\n", chip->state); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + + spin_unlock_bh(chip->mutex); + + schedule(); + remove_wait_queue(&chip->wq, &wait); + + if(signal_pending(current)) + return -EINTR; + + timeo = jiffies + HZ; + + goto retry; + } + + adr += chip->start; + +// map->write32(map, cpu_to_le32(0x00F000F0), adr); + + chip->state = FL_READY; + + map->copy_from(map, buf, adr, len); + + wake_up(&chip->wq); + spin_unlock_bh(chip->mutex); + + return 0; +} + +static int cfi_amdext_read_2_by_16 (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + unsigned long ofs; + int chipnum; + int ret = 0; + + /* ofs: offset within the first chip that the first read should start */ + + chipnum = (from >> cfi->chipshift); + chipnum /= (cfi->interleave); + ofs = from - (chipnum << cfi->chipshift) * (cfi->interleave); + + *retlen = 0; + + while (len) { + unsigned long thislen; + + if (chipnum >= cfi->numchips) + break; + + if (((len + ofs -1) >> cfi->chipshift) / (cfi->interleave)) + thislen = (1<chipshift) * (cfi->interleave) - ofs; + else + thislen = len; + + ret = do_read_2_by_16_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); + if (ret) + break; + + *retlen += thislen; + len -= thislen; + buf += thislen; + + ofs = 0; + chipnum++; + } + return ret; +} + +static inline int do_write_2_by_16_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum) +{ + unsigned long timeo = jiffies + HZ; + unsigned int Last[4]; + unsigned long Count = 0; + DECLARE_WAITQUEUE(wait, current); + int ret = 0; + + retry: + spin_lock_bh(chip->mutex); + + if (chip->state != FL_READY){ +printk("Waiting for chip to write, status = %d\n", chip->state); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + + spin_unlock_bh(chip->mutex); + + schedule(); + remove_wait_queue(&chip->wq, &wait); +printk("Wake up to write:\n"); + if(signal_pending(current)) + return -EINTR; + + timeo = jiffies + HZ; + + goto retry; + } + + chip->state = FL_WRITING; + + adr += chip->start; + + map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4); + map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4); + map->write32(map, cpu_to_le32(0x00A000A0), 0x555 *4); + map->write32(map, cpu_to_le32(datum), adr); + + spin_unlock_bh(chip->mutex); + udelay(chip->word_write_time); + spin_lock_bh(chip->mutex); + + Last[0] = map->read32(map, adr); + Last[1] = map->read32(map, adr); + Last[2] = map->read32(map, adr); + + for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && Count < 10000; Count++){ + udelay(10); + + Last[Count % 4] = map->read32(map, adr); + } + + if (Last[(Count - 1) % 4] != datum){ + map->write32(map, cpu_to_le32(0x00F000F0), adr); + ret = -EIO; + } + + chip->state = FL_READY; + wake_up(&chip->wq); + spin_unlock_bh(chip->mutex); + + return ret; +} + + +static int cfi_amdext_write_2_by_16 (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + int ret = 0; + int chipnum; + unsigned long ofs; + + *retlen = 0; + + chipnum = (to >> cfi->chipshift); + chipnum /= cfi->interleave; + ofs = to - (chipnum << cfi->chipshift) * cfi->interleave; + + while(len > 3) { + + ret = do_write_2_by_16_oneword(map, &cfi->chips[chipnum], + ofs, *(__u32 *)buf); + if (ret) + return ret; + + ofs += 4; + buf += 4; + (*retlen) += 4; + len -= 4; + + if ((ofs >> cfi->chipshift) / cfi->interleave) { + chipnum ++; + ofs = 0; + if (chipnum == cfi->numchips) + return 0; + } + } + + if (len) { + unsigned int tmp; + + /* Final byte to write */ +#if defined(__LITTLE_ENDIAN) + tmp = map->read32(map, ofs); + + tmp = 0xffffffff >> (len*8); + tmp = tmp << (len*8); + + tmp |= *(__u32 *)(buf); + + ret = do_write_2_by_16_oneword(map, &cfi->chips[chipnum], + ofs, tmp); + +#elif defined(__BIG_ENDIAN) +#error not support big endian yet +#else +#error define a sensible endianness +#endif + + if (ret) + return ret; + + (*retlen)+=len; + } + + return 0; +} + + +static inline int do_erase_2_by_16_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) +{ + unsigned int status; + unsigned long timeo = jiffies + HZ; + DECLARE_WAITQUEUE(wait, current); + + retry: + spin_lock_bh(chip->mutex); + + if (chip->state != FL_READY){ + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + + spin_unlock_bh(chip->mutex); + + schedule(); + remove_wait_queue(&chip->wq, &wait); + + if(signal_pending(current)) + return -EINTR; + + timeo = jiffies + HZ; + + goto retry; + } + + chip->state = FL_ERASING; + + adr += chip->start; + + map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4); + map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4); + map->write32(map, cpu_to_le32(0x00800080), 0x555 *4); + map->write32(map, cpu_to_le32(0x00AA00AA), 0x555 *4); + map->write32(map, cpu_to_le32(0x00550055), 0x2AA *4); + map->write32(map, cpu_to_le32(0x00300030), adr); + + + timeo = jiffies + (HZ*20); + + spin_unlock_bh(chip->mutex); + schedule_timeout(HZ); + spin_lock_bh(chip->mutex); + + /* FIXME. Use a timer to check this, and return immediately. */ + /* Once the state machine's known to be working I'll do that */ + + while ( ( (status = le32_to_cpu(map->read32(map, 0x00))) & 0x80808080 ) != 0x80808080 ) { + static int z=0; + + if (chip->state != FL_ERASING) { + /* Someone's suspended the erase. Sleep */ + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + + spin_unlock_bh(chip->mutex); + printk("erase suspended. Sleeping\n"); + + schedule(); + remove_wait_queue(&chip->wq, &wait); + + if (signal_pending(current)) + return -EINTR; + + timeo = jiffies + (HZ*2); /* FIXME */ + spin_lock_bh(chip->mutex); + continue; + } + + /* OK Still waiting */ + if (time_after(jiffies, timeo)) { + chip->state = FL_READY; + spin_unlock_bh(chip->mutex); + printk("waiting for erase to complete timed out."); + return -EIO; + } + + /* Latency issues. Drop the lock, wait a while and retry */ + spin_unlock_bh(chip->mutex); + + z++; + if ( 0 && !(z % 100 )) + printk("chip not ready yet after erase. looping\n"); + + udelay(1); + + spin_lock_bh(chip->mutex); + continue; + } + + /* Done and happy. */ + chip->state = FL_READY; + wake_up(&chip->wq); + spin_unlock_bh(chip->mutex); + printk("erase ret OK\n"); + return 0; +} + +static int cfi_amdext_erase_2_by_16 (struct mtd_info *mtd, struct erase_info *instr) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + unsigned long adr, len; + int chipnum, ret = 0; + +//printk("erase : 0x%x 0x%x 0x%x\n", instr->addr, instr->len, mtd->size); + + if (instr->addr & (mtd->erasesize - 1)) + return -EINVAL; + + if (instr->len & (mtd->erasesize -1)) + return -EINVAL; + + if ((instr->len + instr->addr) > mtd->size) + return -EINVAL; + + chipnum = instr->addr >> cfi->chipshift; + chipnum /= cfi->interleave; + adr = instr->addr - (chipnum << cfi->chipshift) * (cfi->interleave); + len = instr->len; + +printk("erase : 0x%x 0x%x 0x%x\n", adr, len, chipnum, mtd->size); + + while(len) { +//printk("erase : 0x%x 0x%x 0x%x 0x%x\n", chipnum, adr, len, cfi->chipshift); + ret = do_erase_2_by_16_oneblock(map, &cfi->chips[chipnum], adr); + + if (ret) + return ret; + + adr += mtd->erasesize; + len -= mtd->erasesize; + + if ((adr >> cfi->chipshift) / (cfi->interleave)) { + adr = 0; + chipnum++; + + if (chipnum >= cfi->numchips) + break; + } + } + + if (instr->callback) + instr->callback(instr); + + return 0; +} + + + +static void cfi_amdext_sync (struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + int i; + struct flchip *chip; + int ret = 0; + DECLARE_WAITQUEUE(wait, current); +printk("sync\n"); + + for (i=0; !ret && inumchips; i++) { + chip = &cfi->chips[i]; + + retry: + spin_lock_bh(chip->mutex); + + switch(chip->state) { + case FL_READY: + case FL_STATUS: + case FL_CFI_QUERY: + case FL_JEDEC_QUERY: + chip->oldstate = chip->state; + chip->state = FL_SYNCING; + /* No need to wake_up() on this state change - + * as the whole point is that nobody can do anything + * with the chip now anyway. + */ + spin_unlock_bh(chip->mutex); + break; + + default: + /* Not an idle state */ + add_wait_queue(&chip->wq, &wait); + + spin_unlock_bh(chip->mutex); + schedule(); + + goto retry; + } + } + + /* Unlock the chips again */ + + for (i--; i >=0; i--) { + chip = &cfi->chips[i]; + + spin_lock_bh(chip->mutex); + + if (chip->state == FL_SYNCING) { + chip->state = chip->oldstate; + wake_up(&chip->wq); + } + spin_unlock_bh(chip->mutex); + } +printk("sync end\n"); +} + + +static int cfi_amdext_suspend(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + int i; + struct flchip *chip; + int ret = 0; +//printk("suspend\n"); + + for (i=0; !ret && inumchips; i++) { + chip = &cfi->chips[i]; + + spin_lock_bh(chip->mutex); + + switch(chip->state) { + case FL_READY: + case FL_STATUS: + case FL_CFI_QUERY: + case FL_JEDEC_QUERY: + chip->oldstate = chip->state; + chip->state = FL_PM_SUSPENDED; + /* No need to wake_up() on this state change - + * as the whole point is that nobody can do anything + * with the chip now anyway. + */ + spin_unlock_bh(chip->mutex); + break; + + default: + ret = -EAGAIN; + break; + } + } + + /* Unlock the chips again */ + + for (i--; i >=0; i--) { + chip = &cfi->chips[i]; + + spin_lock_bh(chip->mutex); + + if (chip->state == FL_PM_SUSPENDED) { + chip->state = chip->oldstate; + wake_up(&chip->wq); + } + spin_unlock_bh(chip->mutex); + } + + return ret; +} + +static void cfi_amdext_resume(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + int i; + struct flchip *chip; +//printk("resume\n"); + + for (i=0; inumchips; i++) { + + chip = &cfi->chips[i]; + + spin_lock_bh(chip->mutex); + + if (chip->state == FL_PM_SUSPENDED) { + chip->state = chip->oldstate; + wake_up(&chip->wq); + } + else + printk("Argh. Chip not in PM_SUSPENDED state upon resume()\n"); + + spin_unlock_bh(chip->mutex); + } +} + +static void cfi_amdext_destroy(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + kfree(cfi->cmdset_priv); + kfree(cfi); +} + diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/doc2000.c linux/drivers/mtd/doc2000.c --- v2.4.0-test3/linux/drivers/mtd/doc2000.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/doc2000.c Thu Jul 13 10:19:55 2000 @@ -2,7 +2,7 @@ /* Linux driver for Disk-On-Chip 2000 */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ -/* $Id: doc2000.c,v 1.23 2000/07/03 10:01:38 dwmw2 Exp $ */ +/* $Id: doc2000.c,v 1.24 2000/07/13 10:03:31 dwmw2 Exp $ */ #include #include @@ -36,7 +36,7 @@ /* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ -int _DoC_WaitReady (unsigned long docptr) +static int _DoC_WaitReady (unsigned long docptr) { //long c=-1; short c=-1; @@ -148,7 +148,7 @@ /* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */ -int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip) +static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip) { int mfr, id, chipshift=0; char *mfrname=NULL, *idname=NULL; @@ -302,7 +302,7 @@ /* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */ -void DoC_ScanChips(struct DiskOnChip *this) +static void DoC_ScanChips(struct DiskOnChip *this) { int floor, chip; int numchips[MAX_FLOORS]; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/doc2001.c linux/drivers/mtd/doc2001.c --- v2.4.0-test3/linux/drivers/mtd/doc2001.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/doc2001.c Thu Jul 13 10:19:55 2000 @@ -1,8 +1,7 @@ - /* Linux driver for Disk-On-Chip Millennium */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ -/* $Id: doc2001.c,v 1.4 2000/07/03 10:01:38 dwmw2 Exp $ */ +/* $Id: doc2001.c,v 1.7 2000/07/13 10:41:39 dwmw2 Exp $ */ #include #include @@ -21,305 +20,238 @@ #include #include - - -//#define PRERELEASE -#if 0 -static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); -static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); -static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eecbuf); -static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf); -static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf); -static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, const u_char *buf); +static struct { + char * name; + int manufacture_id; + int model_id; + int chipshift; +} nand_flash_ids[] = { + {"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21}, + {"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22}, + {"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24}, + {"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25}, + {"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22}, + {"Toshiba TC58V64DC", NAND_MFR_TOSHIBA, 0xe6, 23}, + {"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21}, + {"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21}, + {"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24}, + {"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25}, + {"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22}, + {"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23}, + {"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21}, + {NULL,} +}; + +static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf); +static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf); +static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf, u_char *eecbuf); +static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf, u_char *eccbuf); +static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, + size_t *retlen, u_char *buf); +static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, + size_t *retlen, const u_char *buf); static int doc_erase (struct mtd_info *mtd, struct erase_info *instr); -#endif static struct mtd_info *docmillist = NULL; -/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ - -int _DoC_WaitReady (unsigned long docptr) +static void DoC_Delay(unsigned long docptr, unsigned short cycles) { - //long c=-1; - short c=-1; + volatile char dummy; + int i; - DEBUG(2,"_DoC_WaitReady called for out-of-line wait\n"); + for (i = 0; i < cycles; i++) + dummy = ReadDOC(docptr, NOP); +} + +/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ +static int _DoC_WaitReady(unsigned long docptr) +{ + unsigned short c = 0xffff; /* Out-of-line routine to wait for chip response */ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c) ; - if (c == 0) - DEBUG(2, "_DoC_WaitReady timed out.\n"); - - return (c==0); + return (c == 0); } -static inline int DoC_WaitReady(unsigned long docptr) +static __inline__ int DoC_WaitReady(unsigned long docptr) { /* This is inline, to optimise the common case, where it's ready instantly */ - volatile char dummy; int ret = 0; - /* Out-of-line routine to wait for chip response */ - /* TPW: Add 4 reads - see Software Requirement 2.3.2 */ - dummy = ReadDOC(docptr, CDSNControl); - dummy = ReadDOC(docptr, CDSNControl); - dummy = ReadDOC(docptr, CDSNControl); - dummy = ReadDOC(docptr, CDSNControl); - + /* 4 read form NOP register should be issued in prior to the read from CDSNControl + see Software Requirement 11.4 item 2. */ + DoC_Delay(docptr, 4); + if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) - ret = _DoC_WaitReady(docptr); /* Call the out-of-line routine to wait */ - - /* TPW: Add 2 reads - see Software Requirement 2.3.2 */ - dummy = ReadDOC(docptr, CDSNControl); - dummy = ReadDOC(docptr, CDSNControl); + /* Call the out-of-line routine to wait */ + ret = _DoC_WaitReady(docptr); + + /* issue 2 read from NOP register after reading from CDSNControl register + see Software Requirement 11.4 item 2. */ + DoC_Delay(docptr, 2); return ret; } - -/* DoC_Command: Send a flash command to the flash chip */ - -static inline int DoC_Command(unsigned long docptr, unsigned char command, unsigned char xtraflags) +/* DoC_Command: Send a flash command to the flash chip through the CDSN Slow IO register to bypass + the internal pipeline. Each of 4 delay cycles (read from the NOP register) is required after + writing to CDSN Control register, see Software Requirement 11.4 item 3. */ +static __inline__ void DoC_Command(unsigned long docptr, unsigned char command, + unsigned char xtraflags) { /* Assert the CLE (Command Latch Enable) line to the flash chip */ - WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, - docptr, CDSNControl); + WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl); + DoC_Delay(docptr, 4); /* Send the command */ - WriteDOC(command, docptr, 2k_CDSN_IO); + WriteDOC(command, docptr, CDSNSlowIO); + WriteDOC(command, docptr, Mil_CDSN_IO); /* Lower the CLE line */ - WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags | CDSN_CTRL_CE, docptr, CDSNControl); - - /* Wait for the chip to respond */ - return DoC_WaitReady(docptr); + WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl); + DoC_Delay(docptr, 4); } -/* DoC_Address: Set the current address for the flash chip */ - -static inline int DoC_Address (unsigned long docptr, int numbytes, unsigned long ofs, +/* DoC_Address: Set the current address for the flash chip through the CDSN Slow IO register to bypass + the internal pipeline. Each of 4 delay cycles (read from the NOP register) is required after + writing to CDSN Control register, see Software Requirement 11.4 item 3. */ +static __inline__ void DoC_Address (unsigned long docptr, int numbytes, unsigned long ofs, unsigned char xtraflags1, unsigned char xtraflags2) { /* Assert the ALE (Address Latch Enable line to the flash chip */ - WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, - docptr, CDSNControl); + WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl); + DoC_Delay(docptr, 4); /* Send the address */ - /* Three cases: - numbytes == 1: Send single byte, bits 0-7. - numbytes == 2: Send bits 9-16 followed by 17-23 - numbytes == 3: Send 0-7, 9-16, then 17-23 - */ - if (numbytes != 2) - WriteDOC(ofs & 0xff, docptr, 2k_CDSN_IO); - - if (numbytes != 1) { - WriteDOC((ofs >> 9) & 0xff, docptr, 2k_CDSN_IO); - WriteDOC((ofs >> 17) & 0xff, docptr, 2k_CDSN_IO); - } + switch (numbytes) + { + case 1: + /* Send single byte, bits 0-7. */ + WriteDOC(ofs & 0xff, docptr, CDSNSlowIO); + WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO); + break; + case 2: + /* Send bits 9-16 followed by 17-23 */ + WriteDOC((ofs >> 9) & 0xff, docptr, CDSNSlowIO); + WriteDOC((ofs >> 9) & 0xff, docptr, Mil_CDSN_IO); + WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO); + WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO); + break; + case 3: + /* Send 0-7, 9-16, then 17-23 */ + WriteDOC(ofs & 0xff, docptr, CDSNSlowIO); + WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO); + WriteDOC((ofs >> 9) & 0xff, docptr, CDSNSlowIO); + WriteDOC((ofs >> 9) & 0xff, docptr, Mil_CDSN_IO); + WriteDOC((ofs >> 17) & 0xff, docptr, CDSNSlowIO); + WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO); + break; + default: + return; + } + /* Lower the ALE line */ - WriteDOC( CDSN_CTRL_FLASH_IO | xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl); - - /* Wait for the chip to respond */ - return DoC_WaitReady(docptr); + WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl); + DoC_Delay(docptr, 4); } /* DoC_SelectChip: Select a given flash chip within the current floor */ - -static inline int DoC_SelectChip(unsigned long docptr, int chip) +static int DoC_SelectChip(unsigned long docptr, int chip) { /* Select the individual flash chip requested */ - WriteDOC( chip, docptr, CDSNDeviceSelect); - + WriteDOC(chip, docptr, CDSNDeviceSelect); + DoC_Delay(docptr, 4); + /* Wait for it to be ready */ return DoC_WaitReady(docptr); } /* DoC_SelectFloor: Select a given floor (bank of flash chips) */ - -static inline int DoC_SelectFloor(unsigned long docptr, int floor) +static int DoC_SelectFloor(unsigned long docptr, int floor) { /* Select the floor (bank) of chips required */ - WriteDOC( floor, docptr, FloorSelect); + WriteDOC(floor, docptr, FloorSelect); /* Wait for the chip to be ready */ return DoC_WaitReady(docptr); } - -/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */ -int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip) +/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */ +static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip) { - int mfr, id, chipshift=0; - char *mfrname=NULL, *idname=NULL; + int mfr, id, i; + volatile char dummy; - /* Page in the required floor/chip */ + /* Page in the required floor/chip + FIXME: is this supported by Millennium ?? */ DoC_SelectFloor(doc->virtadr, floor); DoC_SelectChip(doc->virtadr, chip); - /* Reset the chip */ - if (DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP)) { - DEBUG(2, "DoC_Command (reset) for %d,%d returned true\n", floor,chip); - return 0; - } - + /* Reset the chip, see Software Requirement 11.4 item 1. */ + DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP); + DoC_WaitReady(doc->virtadr); + /* Read the NAND chip ID: 1. Send ReadID command */ - if(DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP)) { - DEBUG(2,"DoC_Command (ReadID) for %d,%d returned true\n", floor,chip); - return 0; - } + DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP); + + /* Read the NAND chip ID: 2. Send address byte zero */ + DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00); + + /* Read the manufacturer and device id codes of the flash device through + CDSN Slow IO register see Software Requirement 11.4 item 5.*/ + dummy = ReadDOC(doc->virtadr, CDSNSlowIO); + DoC_Delay(doc->virtadr, 2); + mfr = ReadDOC(doc->virtadr, Mil_CDSN_IO); + + dummy = ReadDOC(doc->virtadr, CDSNSlowIO); + DoC_Delay(doc->virtadr, 2); + id = ReadDOC(doc->virtadr, Mil_CDSN_IO); - /* Read the NAND chip ID: 2. Send address byte zero - */ - DoC_Address(doc->virtadr, 1, 0, CDSN_CTRL_WP, 0); - - /* Read the manufacturer and device id codes from the device */ - mfr = ReadDOC(doc->virtadr, 2k_CDSN_IO); - id = ReadDOC(doc->virtadr, 2k_CDSN_IO); - /* No response - return failure */ if (mfr == 0xff || mfr == 0) return 0; - - /* Check it's the same as the first chip we identified. - * M-Systems say that any given DiskOnChip device should only - * contain _one_ type of flash part, although that's not a - * hardware restriction. */ - if (doc->mfr) { - if (doc->mfr == mfr && doc->id == id) - return 1; /* This is another the same the first */ - else - printk(KERN_WARNING "Flash chip at floor %d, chip %d is different:\n", - floor, chip); - } - - /* Print (and store if first time) the manufacturer and ID codes. */ - - switch(mfr) { - case NAND_MFR_TOSHIBA: /* Toshiba */ - mfrname = "Toshiba"; - - switch(id) { - case 0x64: - idname = "TC5816BDC"; - chipshift = 21; - break; - - case 0x6b: - idname = "TC5832DC"; - chipshift = 22; - break; - - case 0x73: - idname = "TH58V128DC"; - chipshift = 24; - break; - - case 0x75: - idname = "TC58256FT/DC"; - chipshift = 25; - break; - - case 0xe5: - idname = "TC58V32DC"; - chipshift = 22; - break; - - case 0xe6: - idname = "TC58V64DC"; - chipshift = 23; - break; - - case 0xea: - idname = "TC58V16BDC"; - chipshift = 21; - break; - } - break; /* End of Toshiba parts */ - - case NAND_MFR_SAMSUNG: /* Samsung */ - mfrname = "Samsung"; - - switch(id) { - case 0x64: - idname = "KM29N16000"; - chipshift = 21; - - case 0x73: - idname = "KM29U128T"; - chipshift = 24; - break; - - case 0x75: - idname = "KM29U256T"; - chipshift = 25; - break; - case 0xe3: - idname = "KM29W32000"; - chipshift = 22; - break; - - case 0xe6: - idname = "KM29U64000"; - chipshift = 23; - break; - - case 0xea: - idname = "KM29W16000"; - chipshift = 21; - break; - } - break; /* End of Samsung parts */ - } - - /* If we've identified it fully, print the full names */ - if (idname) { -#ifdef PRERELEASE - DEBUG(1, "Flash chip found: %2.2X %2.2X (%s %s)\n", - mfr,id,mfrname,idname); -#endif - /* If this is the first chip, store the id codes */ - if (!doc->mfr) { + /* FIXME: to deal with mulit-flash on multi-Millennium case more carefully */ + for (i = 0; nand_flash_ids[i].name != NULL; i++) { + if (mfr == nand_flash_ids[i].manufacture_id && + id == nand_flash_ids[i].model_id) { + printk(KERN_INFO "Flash chip found: Manufacture ID: %2.2X, " + "Chip ID: %2.2X (%s)\n", + mfr, id, nand_flash_ids[i].name); doc->mfr = mfr; doc->id = id; - doc->chipshift = chipshift; - return 1; + doc->chipshift = nand_flash_ids[i].chipshift; + break; } - return 0; } - /* We haven't fully identified the chip. Print as much as we know. */ - if (mfrname) - printk(KERN_WARNING "Unknown %s flash chip found: %2.2X %2.2X\n", mfrname, - id, mfr); + if (nand_flash_ids[i].name == NULL) + return 0; else - printk(KERN_WARNING "Unknown flash chip found: %2.2X %2.2X\n", id, mfr); - - printk(KERN_WARNING "Please report to David.Woodhouse@mvhi.com\n"); - return 0; + return 1; } /* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */ - -void DoC_ScanChips(struct DiskOnChip *this) +static void DoC_ScanChips(struct DiskOnChip *this) { int floor, chip; - int numchips[MAX_FLOORS]; - int ret = 1; + int numchips[MAX_FLOORS_MIL]; + int ret; this->numchips = 0; this->mfr = 0; this->id = 0; /* For each floor, find the number of valid chips it contains */ - for (floor = 0 ; floor < MAX_FLOORS ; floor++) { - ret = 1; - numchips[floor]=0; - for (chip = 0 ; chip < MAX_CHIPS && ret != 0; chip++ ) { - + for (floor = 0,ret = 1; floor < MAX_FLOORS_MIL; floor++) { + numchips[floor] = 0; + for (chip = 0; chip < MAX_CHIPS_MIL && ret != 0; chip++) { ret = DoC_IdentChip(this, floor, chip); if (ret) { numchips[floor]++; @@ -327,7 +259,6 @@ } } } - /* If there are none at all that we recognise, bail */ if (!this->numchips) { printk("No flash chips recognised.\n"); @@ -341,11 +272,9 @@ return; } - ret = 0; - /* Fill out the chip array with {floor, chipno} for each * detected chip in the device. */ - for (floor = 0; floor < MAX_FLOORS; floor++) { + for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) { for (chip = 0 ; chip < numchips[floor] ; chip++) { this->chips[ret].floor = floor; this->chips[ret].chip = chip; @@ -357,14 +286,14 @@ /* Calculate and print the total size of the device */ this->totlen = this->numchips * (1 << this->chipshift); - - printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld Mb\n", this->numchips , - this->totlen >> 20); + printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld Mbytes\n", + this->numchips ,this->totlen >> 20); } static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2) { int tmp1, tmp2, retval; + if (doc1->physadr == doc2->physadr) return 1; @@ -392,21 +321,19 @@ return retval; } - void DoCMil_init(struct mtd_info *mtd) { struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; struct DiskOnChip *old = NULL; /* We must avoid being called twice for the same device. */ - if (docmillist) old = (struct DiskOnChip *)docmillist->priv; while (old) { if (DoCMil_is_alias(this, old)) { - printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at 0x%lX - already configured\n", - this->physadr); + printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at " + "0x%lX - already configured\n", this->physadr); iounmap((void *)this->virtadr); kfree(mtd); return; @@ -418,14 +345,9 @@ } mtd->name = "DiskOnChip Millennium"; - printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n",this->physadr); + printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n", + this->physadr); -#if 1 - printk("Unfortunately, we don't have support for the DiskOnChip Millennium yet.\n"); - iounmap((void *)this->virtadr); - kfree(mtd); - return; -#else mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; mtd->size = 0; @@ -445,8 +367,7 @@ mtd->sync = NULL; this->totlen = 0; - this->numchips = 0; - + this->numchips = 0; this->curfloor = -1; this->curchip = -1; @@ -463,78 +384,90 @@ add_mtd_device(mtd); return; } -#endif } - EXPORT_SYMBOL(DoCMil_init); -#if 0 -static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) + +static int doc_read (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf) { /* Just a special case of doc_read_ecc */ return doc_read_ecc(mtd, from, len, retlen, buf, NULL); } -static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf) +static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, u_char *buf, u_char *eccbuf) { + int i; + volatile char dummy; struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; - int di=0; /* Yes, DI is a hangover from when I was disassembling the binary driver */ - unsigned long docptr; - struct Nand *mychip; - - docptr = this->virtadr; + unsigned long docptr = this->virtadr; + struct Nand *mychip = &this->chips[from >> (this->chipshift)]; /* Don't allow read past end of device */ if (from >= this->totlen) return -EINVAL; - + /* Don't allow a single read to cross a 512-byte block boundary */ - if (from + len > ( (from | 0x1ff) + 1)) + if (from + len > ((from | 0x1ff) + 1)) len = ((from | 0x1ff) + 1) - from; /* Find the chip which is to be used and select it */ - mychip = &this->chips[from >> (this->chipshift)]; - if (this->curfloor != mychip->floor) { DoC_SelectFloor(docptr, mychip->floor); DoC_SelectChip(docptr, mychip->chip); - } - else if (this->curchip != mychip->chip) { + } else if (this->curchip != mychip->chip) { DoC_SelectChip(docptr, mychip->chip); } - this->curfloor = mychip->floor; this->curchip = mychip->chip; - if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC ( DOC_ECC_RESET, docptr, ECCConf); - WriteDOC ( DOC_ECC_EN, docptr, ECCConf); + /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ + WriteDOC (DOC_ECC_RESET, docptr, ECCConf); + WriteDOC (DOC_ECC_EN, docptr, ECCConf); + } else { + /* disable the ECC engine, FIXME: is this correct ?? */ + WriteDOC (DOC_ECC_RESET, docptr, ECCConf); + WriteDOC (DOC_ECC_DIS, docptr, ECCConf); } + /* issue the Read0 or Read1 command depend on which half of the page + we are accessing. Polling the Flash Ready bit after issue 3 bytes + address in Sequence Read Mode, see Software Requirement 11.4 item 1.*/ DoC_Command(docptr, (from >> 8) & 1, CDSN_CTRL_WP); - DoC_Address(docptr, 3, from, CDSN_CTRL_WP , CDSN_CTRL_ECC_IO); + DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00); + DoC_WaitReady(docptr); - for (di=0; di < len ; di++) { - buf[di] = ReadDOC(docptr, 2k_CDSN_IO); + /* Read the data via the internal pipeline through CDSN IO register, + see Pipelined Read Operations 11.3 */ + dummy = ReadDOC(docptr, ReadPipeInit); + for (i = 0; i < len-1; i++) { + buf[i] = ReadDOC(docptr, Mil_CDSN_IO); } + buf[i] = ReadDOC(docptr, LastDataRead); /* Let the caller know we completed it */ *retlen = len; if (eccbuf) { - /* Read the ECC data through the DiskOnChip ECC logic */ - for (di=0; di<6; di++) { - eccbuf[di] = ReadDOC(docptr, 2k_CDSN_IO); + /* FIXME: are we reading the ECC from the ECC logic of DOC or + the spare data space on the flash chip i.e. How do we + control the Spare Area Enable bit of the flash ?? */ + /* Read the ECC data through the DiskOnChip ECC logic + see Reed-Solomon EDC/ECC 11.1 */ + dummy = ReadDOC(docptr, ReadPipeInit); + for (i = 0; i < 5; i++) { + eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO); } - + eccbuf[i] = ReadDOC(docptr, LastDataRead); + /* Flush the pipeline */ - (void) ReadDOC(docptr, 2k_ECCStatus); - (void) ReadDOC(docptr, 2k_ECCStatus); - + dummy = ReadDOC(docptr, ECCConf); + dummy = ReadDOC(docptr, ECCConf); + /* Check the ECC Status */ - if (ReadDOC(docptr, 2k_ECCStatus) & 0x80) { + if (ReadDOC(docptr, ECCConf) & 0x80) { /* There was an ECC error */ printk("DiskOnChip ECC Error: Read at %lx\n", (long)from); @@ -548,41 +481,40 @@ #ifdef PSYCHO_DEBUG else printk("ECC OK at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], eccbuf[4], - eccbuf[5]); + (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], + eccbuf[4], eccbuf[5]); #endif - /* Reset the ECC engine */ WriteDOC(DOC_ECC_RESV, docptr , ECCConf); - } return 0; } -static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) +static int doc_write (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf) { static char as[6]; return doc_write_ecc(mtd, to, len, retlen, buf, as); } -static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf) +static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const u_char *buf, u_char *eccbuf) { + int i; + volatile char dummy; struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; - int di=0; - unsigned long docptr; - struct Nand *mychip; - - docptr = this->virtadr; + unsigned long docptr = this->virtadr; + struct Nand *mychip = &this->chips[to >> (this->chipshift)]; /* Don't allow write past end of device */ if (to >= this->totlen) return -EINVAL; -#if 0 + +#if 0 /* Don't allow a single write to cross a 512-byte block boundary */ if (to + len > ( (to | 0x1ff) + 1)) len = ((to | 0x1ff) + 1) - to; - #else /* Don't allow writes which aren't exactly one block */ if (to & 0x1ff || len != 0x200) @@ -590,8 +522,6 @@ #endif /* Find the chip which is to be used and select it */ - mychip = &this->chips[to >> (this->chipshift)]; - if (this->curfloor != mychip->floor) { DoC_SelectFloor(docptr, mychip->floor); DoC_SelectChip(docptr, mychip->chip); @@ -599,61 +529,75 @@ else if (this->curchip != mychip->chip) { DoC_SelectChip(docptr, mychip->chip); } - this->curfloor = mychip->floor; this->curchip = mychip->chip; - - /* Set device to main plane of flash */ + + /* Reset the chip, see Software Requirement 11.4 item 1. */ DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP); + DoC_WaitReady(docptr); + /* Set device to main plane of flash */ DoC_Command(docptr, NAND_CMD_READ0, CDSN_CTRL_WP); if (eccbuf) { - /* Prime the ECC engine */ - WriteDOC ( DOC_ECC_RESET, docptr, ECCConf); - WriteDOC ( DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); + /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/ + WriteDOC (DOC_ECC_RESET, docptr, ECCConf); + WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf); + } else { + /* disable the ECC engine, FIXME: is this correct ?? */ + WriteDOC (DOC_ECC_RESET, docptr, ECCConf); + WriteDOC (DOC_ECC_DIS, docptr, ECCConf); } - DoC_Command(docptr, NAND_CMD_SEQIN, 0); - DoC_Address(docptr, 3, to, 0, CDSN_CTRL_ECC_IO); + /* issue the Serial Data In command to initial the Page Program process */ + DoC_Command(docptr, NAND_CMD_SEQIN, 0x00); + DoC_Address(docptr, 3, to, 0x00, 0x00); - for (di=0; di < len ; di++) { - WriteDOC(buf[di], docptr, 2k_CDSN_IO); + /* Write the data via the internal pipeline through CDSN IO register, + see Pipelined Write Operations 11.2 */ + for (i = 0; i < len; i++) { + WriteDOC(buf[i], docptr, Mil_CDSN_IO); } - + WriteDOC(0x00, docptr, WritePipeTerm); if (eccbuf) { - WriteDOC( CDSN_CTRL_ECC_IO | CDSN_CTRL_CE , docptr, CDSNControl ); - -#if 1 - /* eduardp@m-sys.com says this shouldn't be necessary, - * but it doesn't actually work without it, so I've - * left it in for now. dwmw2. - */ - - WriteDOC( 0, docptr, 2k_CDSN_IO); - WriteDOC( 0, docptr, 2k_CDSN_IO); - WriteDOC( 0, docptr, 2k_CDSN_IO); -#endif + /* Write ECC data to flash, the ECC info is generated by the DiskOnChip DECC logic + see Reed-Solomon EDC/ECC 11.1 */ + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + WriteDOC(0, docptr, NOP); + /* Read the ECC data through the DiskOnChip ECC logic */ - for (di=0; di<6; di++) { - eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); + for (i = 0; i < 6; i++) { + eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i); } + + /* Write the ECC data to flash */ + for (i = 0; i < 6; i++) { + WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO); + } + WriteDOC(0x00, docptr, WritePipeTerm); + #ifdef PSYCHO_DEBUG printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", - (long) to, eccbuf[0], eccbuf[1], eccbuf[2], - eccbuf[3], eccbuf[4], eccbuf[5] ); + (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3], + eccbuf[4], eccbuf[5]); #endif + /* Reset the ECC engine */ WriteDOC(DOC_ECC_RESV, docptr , ECCConf); - } - DoC_Command(docptr, NAND_CMD_PAGEPROG, 0); - - DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP); - /* There's an implicit DoC_WaitReady() in DoC_Command */ - - if (ReadDOC(docptr, 2k_CDSN_IO) & 1) { + /* Commit the Page Program command and wait for ready + see Software Requirement 11.4 item 1.*/ + DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00); + DoC_WaitReady(docptr); + + /* Read the status of the flash device through CDSN Slow IO register + see Software Requirement 11.4 item 5.*/ + DoC_Command(docptr, NAND_CMD_STATUS, 0x00); + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(docptr, 2); + if (ReadDOC(docptr, Mil_CDSN_IO) & 1) { printk("Error programming flash\n"); /* Error in programming */ *retlen = 0; @@ -666,19 +610,18 @@ return 0; } - - -static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, size_t *retlen, u_char *buf) +static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, + size_t *retlen, u_char *buf) { - struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; + volatile char dummy; int i; - unsigned long docptr; - struct Nand *mychip; - - docptr = this->virtadr; - - mychip = &this->chips[ofs >> this->chipshift]; - + struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; + unsigned long docptr = this->virtadr; + struct Nand *mychip = &this->chips[ofs >> this->chipshift]; + + /* FIXME: should we restrict the access between 512 to 527 ?? */ + + /* Find the chip which is to be used and select it */ if (this->curfloor != mychip->floor) { DoC_SelectFloor(docptr, mychip->floor); DoC_SelectChip(docptr, mychip->chip); @@ -688,35 +631,43 @@ } this->curfloor = mychip->floor; this->curchip = mychip->chip; - - - + + /* FIXME: should we disable ECC engine in this way ?? */ + /* disable the ECC engine, FIXME: is this correct ?? */ + WriteDOC (DOC_ECC_RESET, docptr, ECCConf); + WriteDOC (DOC_ECC_DIS, docptr, ECCConf); + + /* issue the Read2 command to read the Spare Data Area. + Polling the Flash Ready bit after issue 3 bytes address in + Sequence Read Mode, see Software Requirement 11.4 item 1.*/ DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP); - DoC_Address(docptr, 3, ofs, CDSN_CTRL_WP, 0); - - for (i=0; ipriv; int i; - unsigned long docptr; - struct Nand *mychip; - - // printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len, - // buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]); + volatile char dummy; + struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; + unsigned long docptr = this->virtadr; + struct Nand *mychip = &this->chips[ofs >> this->chipshift]; - docptr = this->virtadr; - - mychip = &this->chips[ofs >> this->chipshift]; - - if (this->curfloor != mychip->floor) { + /* Find the chip which is to be used and select it */ + if (this->curfloor != mychip->floor) { DoC_SelectFloor(docptr, mychip->floor); DoC_SelectChip(docptr, mychip->chip); } @@ -725,49 +676,63 @@ } this->curfloor = mychip->floor; this->curchip = mychip->chip; - - DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP); - DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP); - DoC_Command(docptr, NAND_CMD_SEQIN, 0); - DoC_Address(docptr, 3, ofs, 0, 0); - - for (i=0; ipriv; unsigned long ofs = instr->addr; unsigned long len = instr->len; - unsigned long docptr; - struct Nand *mychip; - - if(len != mtd->erasesize) - printk(KERN_WARNING "Erase not right size (%lx != %lx)n", len, mtd->erasesize); - + unsigned long docptr = this->virtadr; + struct Nand *mychip = &this->chips[ofs >> this->chipshift]; - docptr = this->virtadr; - - mychip = &this->chips[ofs >> this->chipshift]; - + if (len != mtd->erasesize) + printk(KERN_WARNING "Erase not right size (%lx != %lx)n", + len, mtd->erasesize); + + /* Find the chip which is to be used and select it */ if (this->curfloor != mychip->floor) { DoC_SelectFloor(docptr, mychip->floor); DoC_SelectChip(docptr, mychip->chip); @@ -780,31 +745,34 @@ instr->state = MTD_ERASE_PENDING; - DoC_Command(docptr, NAND_CMD_ERASE1, 0); - DoC_Address(docptr, 2, ofs, 0, 0); - DoC_Command(docptr, NAND_CMD_ERASE2, 0); + /* issue the Erase Setup command */ + DoC_Command(docptr, NAND_CMD_ERASE1, 0x00); + DoC_Address(docptr, 2, ofs, 0x00, 0x00); + + /* Commit the Erase Start command and wait for ready + see Software Requirement 11.4 item 1.*/ + DoC_Command(docptr, NAND_CMD_ERASE2, 0x00); + DoC_WaitReady(docptr); instr->state = MTD_ERASING; + /* Read the status of the flash device through CDSN Slow IO register + see Software Requirement 11.4 item 5.*/ DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP); - - if (ReadDOC(docptr, 2k_CDSN_IO) & 1) { - printk("Error writing\n"); + dummy = ReadDOC(docptr, CDSNSlowIO); + DoC_Delay(docptr, 2); + if (ReadDOC(docptr, Mil_CDSN_IO) & 1) { + printk("Error Erasing\n"); /* There was an error */ instr->state = MTD_ERASE_FAILED; - } - else + } else instr->state = MTD_ERASE_DONE; if (instr->callback) instr->callback(instr); - + return 0; } - - - -#endif /**************************************************************************** * diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/docprobe.c linux/drivers/mtd/docprobe.c --- v2.4.0-test3/linux/drivers/mtd/docprobe.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/docprobe.c Thu Jul 13 10:19:55 2000 @@ -3,7 +3,7 @@ /* Probe routines common to all DoC devices */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ -/* $Id: docprobe.c,v 1.8 2000/06/26 20:40:53 dwmw2 Exp $ */ +/* $Id: docprobe.c,v 1.10 2000/07/13 14:23:20 dwmw2 Exp $ */ @@ -206,7 +206,7 @@ case DOC_ChipID_DocMil: name="Millennium"; #ifdef CONFIG_MTD_DOC2001 - initroutine = &DocMil_init; + initroutine = &DoCMil_init; #elif CONFIG_MODULES initroutinedynamic=1; initroutine = (void *)get_module_symbol(NULL, "DoCMil_init"); @@ -252,7 +252,7 @@ printk(KERN_NOTICE "M-Systems DiskOnChip driver. (C) 1999 Machine Vision Holdings, Inc.\n"); #ifdef PRERELEASE - printk(KERN_INFO "$Id: docprobe.c,v 1.8 2000/06/26 20:40:53 dwmw2 Exp $\n"); + printk(KERN_INFO "$Id: docprobe.c,v 1.10 2000/07/13 14:23:20 dwmw2 Exp $\n"); #endif for (i=0; doc_locations[i]; i++) { diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c --- v2.4.0-test3/linux/drivers/mtd/mtdblock.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/mtdblock.c Thu Jul 13 10:19:55 2000 @@ -1,7 +1,7 @@ /* * Direct MTD block device access * - * $Id: mtdblock.c,v 1.16 2000/06/23 09:34:58 dwmw2 Exp $ + * $Id: mtdblock.c,v 1.17 2000/07/13 14:25:54 dwmw2 Exp $ */ #ifdef MTDBLOCK_DEBUG diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c --- v2.4.0-test3/linux/drivers/mtd/mtdchar.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/mtdchar.c Thu Jul 13 10:19:55 2000 @@ -63,21 +63,16 @@ if ((file->f_mode & 2) && (minor & 1)) return -EACCES; - MOD_INC_USE_COUNT; - mtd = get_mtd_device(NULL, devnum); - if (!mtd) { - MOD_DEC_USE_COUNT; + if (!mtd) return -ENODEV; - } file->private_data = mtd; /* You can't open it RW if it's not a writeable device */ if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { put_mtd_device(mtd); - MOD_DEC_USE_COUNT; return -EACCES; } @@ -100,7 +95,6 @@ put_mtd_device(mtd); - MOD_DEC_USE_COUNT; release_return(0); } /* mtd_close */ @@ -362,7 +356,7 @@ } /* memory_ioctl */ static struct file_operations mtd_fops = { - + owner: THIS_MODULE, llseek: mtd_lseek, /* lseek */ read: mtd_read, /* read */ write: mtd_write, /* write */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/mtdcore.c linux/drivers/mtd/mtdcore.c --- v2.4.0-test3/linux/drivers/mtd/mtdcore.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/mtdcore.c Thu Jul 13 10:19:55 2000 @@ -1,5 +1,5 @@ /* - * $Id: mtdcore.c,v 1.8 2000/06/27 13:40:05 dwmw2 Exp $ + * $Id: mtdcore.c,v 1.13 2000/07/13 14:27:37 dwmw2 Exp $ * * Core registration and callback routines for MTD * drivers and users. @@ -44,9 +44,18 @@ #ifdef CONFIG_MTD_DOCPROBE extern int init_doc(void); #endif +#ifdef CONFIG_MTD_PHYSMAP +extern int init_physmap(void); +#endif +#ifdef CONFIG_MTD_RPXLITE +extern int init_rpxlite(void); +#endif #ifdef CONFIG_MTD_OCTAGON extern int init_octagon5066(void); #endif +#ifdef CONFIG_MTD_PNC2000 +extern int init_pnc2000(void); +#endif #ifdef CONFIG_MTD_VMAX extern int init_vmax301(void); #endif @@ -76,11 +85,18 @@ static DECLARE_MUTEX(mtd_table_mutex); - static struct mtd_info *mtd_table[MAX_MTD_DEVICES]; - static struct mtd_notifier *mtd_notifiers = NULL; +/** + * add_mtd_device - register an MTD device + * @mtd: pointer to new MTD device info structure + * + * Add a device to the list of MTD devices present in the system, and + * notify each currently active MTD 'user' of its arrival. Returns + * zero on success or 1 on failure, which currently will only happen + * if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16) + */ int add_mtd_device(struct mtd_info *mtd) { @@ -109,6 +125,15 @@ return 1; } +/** + * del_mtd_device - unregister an MTD device + * @mtd: pointer to MTD device info structure + * + * Remove a device from the list of MTD devices present in the system, + * and notify each currently active MTD 'user' of its departure. + * Returns zero on success or 1 on failure, which currently will happen + * if the requested device does not appear to be present in the list. + */ int del_mtd_device (struct mtd_info *mtd) { @@ -137,7 +162,14 @@ return 1; } - +/** + * register_mtd_user - register a 'user' of MTD devices. + * @new: pointer to notifier info structure + * + * Registers a pair of callbacks function to be called upon addition + * or removal of MTD devices. Causes the 'add' callback to be immediately + * invoked for each MTD device currently present in the system. + */ void register_mtd_user (struct mtd_notifier *new) { @@ -157,7 +189,15 @@ up(&mtd_table_mutex); } - +/** + * register_mtd_user - unregister a 'user' of MTD devices. + * @new: pointer to notifier info structure + * + * Removes a callback function pair from the list of 'users' to be + * notified upon addition or removal of MTD devices. Causes the + * 'remove' callback to be immediately invoked for each MTD device + * currently present in the system. + */ int unregister_mtd_user (struct mtd_notifier *old) { @@ -187,13 +227,17 @@ } -/* get_mtd_device(): - * Prepare to use an MTD device referenced either by number or address. +/** + * __get_mtd_device - obtain a validated handle for an MTD device + * @mtd: last known address of the required MTD device + * @num: internal device number of the required MTD device * - * If == -1, search the table for an MTD device located at . - * If == NULL, return the MTD device with number . - * If both are set, return the MTD device with number _only_ if it - * is located at . + * Given a number and NULL address, return the num'th entry in the device + * table, if any. Given an address and num == -1, search the device table + * for a device with that address and return if it's still present. Given + * both, return the num'th driver only if its address matches. Return NULL + * if not. get_mtd_device() increases the use count, but + * __get_mtd_device() doesn't - you should generally use get_mtd_device(). */ struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num) @@ -224,12 +268,45 @@ EXPORT_SYMBOL(unregister_mtd_user); /*====================================================================*/ -/* /proc/mtd support */ +/* Power management code */ + +#ifdef CONFIG_PM + +#include + +static struct pm_dev *mtd_pm_dev = NULL; + +static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + int ret = 0, i; + + if (down_trylock(&mtd_table_mutex)) + return -EAGAIN; + if (rqst == PM_SUSPEND) { + for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) { + if (mtd_table[i] && mtd_table[i]->suspend) + ret = mtd_table[i]->suspend(mtd_table[i]); + } + } else i = MAX_MTD_DEVICES-1; + + if (rqst == PM_RESUME || ret) { + for ( ; i >= 0; i--) { + if (mtd_table[i] && mtd_table[i]->resume) + mtd_table[i]->resume(mtd_table[i]); + } + } + up(&mtd_table_mutex); + return ret; +} +#endif + +/*====================================================================*/ +/* Support for /proc/mtd */ #ifdef CONFIG_PROC_FS #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) -struct proc_dir_entry *proc_mtd; +static struct proc_dir_entry *proc_mtd; #endif static inline int mtd_proc_info (char *buf, int i) @@ -292,10 +369,10 @@ }; #endif -#endif +#endif /* CONFIG_PROC_FS */ /*====================================================================*/ - +/* Init code */ #if LINUX_VERSION_CODE < 0x20300 @@ -315,9 +392,18 @@ * Theoretically all other DiskOnChip * devices too. */ #endif +#ifdef CONFIG_MTD_PHYSMAP + init_physmap(); +#endif +#ifdef CONFIG_MTD_RPXLITE + init_rpxlite(); +#endif #ifdef CONFIG_MTD_OCTAGON init_octagon5066(); #endif +#ifdef CONFIG_MTD_PNC2000 + init_pnc2000(); +#endif #ifdef CONFIG_MTD_VMAX init_vmax301(); #endif @@ -374,13 +460,21 @@ #if LINUX_VERSION_CODE < 0x20300 init_others(); #endif - +#ifdef CONFIG_PM + mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback); +#endif return 0; } mod_exit_t cleanup_mtd(void) { unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); +#ifdef CONFIG_PM + if (mtd_pm_dev) { + pm_unregister(mtd_pm_dev); + mtd_pm_dev = NULL; + } +#endif #ifdef CONFIG_PROC_FS #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) if (proc_mtd) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/mtdram.c linux/drivers/mtd/mtdram.c --- v2.4.0-test3/linux/drivers/mtd/mtdram.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/mtdram.c Thu Jul 13 10:19:55 2000 @@ -1,6 +1,6 @@ /* * mtdram - a test mtd device - * $Id: mtdram.c,v 1.13 2000/07/03 10:01:38 dwmw2 Exp $ + * $Id: mtdram.c,v 1.15 2000/07/13 12:40:46 scote1 Exp $ * Author: Alexander Larsson * * Copyright (c) 1999 Alexander Larsson @@ -17,8 +17,8 @@ #include -#define MTDRAM_TOTAL_SIZE 1024*1024*8 -#define MTDRAM_ERASE_SIZE 4*1024 +#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024) +#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024) // We could store these in the mtd structure, but we only support 1 device.. diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/nftl.c linux/drivers/mtd/nftl.c --- v2.4.0-test3/linux/drivers/mtd/nftl.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/nftl.c Thu Jul 13 10:19:55 2000 @@ -2,7 +2,7 @@ /* Linux driver for NAND Flash Translation Layer */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ -/* $Id: nftl.c,v 1.35 2000/07/06 14:35:01 dwmw2 Exp $ */ +/* $Id: nftl.c,v 1.36 2000/07/13 14:14:20 dwmw2 Exp $ */ /* The contents of this file are distributed under the GNU Public @@ -1293,7 +1293,7 @@ printk(KERN_NOTICE "M-Systems NAND Flash Translation Layer driver. (C) 1999 MVHI\n"); #ifdef PRERELEASE - printk(KERN_INFO"$Id: nftl.c,v 1.35 2000/07/06 14:35:01 dwmw2 Exp $\n"); + printk(KERN_INFO"$Id: nftl.c,v 1.36 2000/07/13 14:14:20 dwmw2 Exp $\n"); #endif if (register_blkdev(NFTL_MAJOR, "nftl", &nftl_fops)){ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/nora.c linux/drivers/mtd/nora.c --- v2.4.0-test3/linux/drivers/mtd/nora.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/nora.c Thu Jul 13 10:19:55 2000 @@ -1,5 +1,5 @@ /* - * $Id: nora.c,v 1.11 2000/07/04 16:42:50 dwmw2 Exp $ + * $Id: nora.c,v 1.12 2000/07/13 10:32:33 dwmw2 Exp $ * * This is so simple I love it. */ @@ -125,7 +125,7 @@ { type: MTD_NORFLASH, flags: MTD_CAP_NORFLASH, - size: 0x1a0000, + size: 0x0a0000, erasesize: 0x20000, name: "NORA kernel", module: THIS_MODULE, @@ -140,9 +140,9 @@ { type: MTD_NORFLASH, flags: MTD_CAP_NORFLASH, - size: 0xe00000, + size: 0xf00000, erasesize: 0x20000, - name: "NORA ramdisk", + name: "NORA root filesystem", module: THIS_MODULE, erase: nora_mtd_erase, read: nora_mtd_read, @@ -150,14 +150,14 @@ suspend: nora_mtd_suspend, resume: nora_mtd_resume, sync: nora_mtd_sync, - priv: (void *)0x200000 + priv: (void *)0x100000 }, { type: MTD_NORFLASH, flags: MTD_CAP_NORFLASH, size: 0x1000000, erasesize: 0x20000, - name: "NORA filesystem", + name: "NORA main filesystem", module: THIS_MODULE, erase: nora_mtd_erase, read: nora_mtd_read, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/octagon-5066.c linux/drivers/mtd/octagon-5066.c --- v2.4.0-test3/linux/drivers/mtd/octagon-5066.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/octagon-5066.c Thu Jul 13 10:19:55 2000 @@ -1,4 +1,4 @@ -// $Id: octagon-5066.c,v 1.9 2000/07/03 10:01:38 dwmw2 Exp $ +// $Id: octagon-5066.c,v 1.10 2000/07/13 14:04:23 dwmw2 Exp $ /* ###################################################################### Octagon 5066 MTD Driver. @@ -56,8 +56,8 @@ { __u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT); - if (page_n_dev != byte); - __oct5066_page(map, byte); + if (page_n_dev != byte) + __oct5066_page(map, byte); } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/physmap.c linux/drivers/mtd/physmap.c --- v2.4.0-test3/linux/drivers/mtd/physmap.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/mtd/physmap.c Tue Jul 11 11:23:37 2000 @@ -1,5 +1,5 @@ /* - * $Id: physmap.c,v 1.1 2000/07/04 08:58:10 dwmw2 Exp $ + * $Id: physmap.c,v 1.2 2000/07/11 09:42:32 dwmw2 Exp $ * * Normal mappings of chips in physical memory */ @@ -10,10 +10,11 @@ #include #include #include +#include -#define WINDOW_ADDR 0x8000000 -#define WINDOW_SIZE 0x4000000 +#define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START +#define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN static struct mtd_info *mymtd; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/mtd/pnc2000.c linux/drivers/mtd/pnc2000.c --- v2.4.0-test3/linux/drivers/mtd/pnc2000.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/mtd/pnc2000.c Thu Jul 13 10:19:55 2000 @@ -0,0 +1,210 @@ +/* + * pnc2000.c - mapper for Photron PNC-2000 board. + * + * Copyright (C) 2000 Crossnet Co. + * + * This code is GPL + * + * $Id: pnc2000.c,v 1.1 2000/07/12 09:34:32 dwmw2 Exp $ + */ + +#include +#include +#include + +#include +#include + + +#define WINDOW_ADDR 0xbf000000 +#define WINDOW_SIZE 0x00400000 + +/* + * MAP DRIVER STUFF + */ + +__u8 pnc_read8(struct map_info *map, unsigned long ofs) +{ + return *(__u8 *)(WINDOW_ADDR + ofs); +} + +__u16 pnc_read16(struct map_info *map, unsigned long ofs) +{ + return *(__u16 *)(WINDOW_ADDR + ofs); +} + +__u32 pnc_read32(struct map_info *map, unsigned long ofs) +{ + return *(volatile unsigned int *)(WINDOW_ADDR + ofs); +} + +void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) +{ + memcpy(to, (void *)(WINDOW_ADDR + from), len); +} + +void pnc_write8(struct map_info *map, __u8 d, unsigned long adr) +{ + *(__u8 *)(WINDOW_ADDR + adr) = d; +} + +void pnc_write16(struct map_info *map, __u16 d, unsigned long adr) +{ + *(__u16 *)(WINDOW_ADDR + adr) = d; +} + +void pnc_write32(struct map_info *map, __u32 d, unsigned long adr) +{ + *(__u32 *)(WINDOW_ADDR + adr) = d; +} + +void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) +{ + memcpy((void *)(WINDOW_ADDR + to), from, len); +} + +struct map_info pnc_map = { + "PNC-2000", + WINDOW_SIZE, + 4, + pnc_read8, + pnc_read16, + pnc_read32, + pnc_copy_from, + pnc_write8, + pnc_write16, + pnc_write32, + pnc_copy_to, + 0, + 0 +}; + + +/* + * MTD 'PARTITIONING' STUFF + */ + +/* + * This is the _real_ MTD device for which all the others are just + * auto-relocating aliases. + */ +static struct mtd_info *mymtd; + +/* + * MTD methods which simply translate the effective address and pass through + * to the _real_ device. + */ + +static int pnc_mtd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) +{ + return mymtd->read(mymtd, from + (unsigned long)mtd->priv, len, retlen, buf); +} + +static int pnc_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) +{ + return mymtd->write(mymtd, to + (unsigned long)mtd->priv, len, retlen, buf); +} + +static int pnc_mtd_erase (struct mtd_info *mtd, struct erase_info *instr) +{ + instr->addr += (unsigned long)mtd->priv; + return mymtd->erase(mymtd, instr); +} + +static void pnc_mtd_sync (struct mtd_info *mtd) +{ + mymtd->sync(mymtd); +} + +static int pnc_mtd_suspend (struct mtd_info *mtd) +{ + return mymtd->suspend(mymtd); +} + +static void pnc_mtd_resume (struct mtd_info *mtd) +{ + mymtd->resume(mymtd); +} + + +static struct mtd_info pnc_mtds[3] = { /* boot, kernel, fs */ + { + type: MTD_NORFLASH, + flags: MTD_CAP_NORFLASH, + size: 0x20000, + erasesize: 0x20000, + name: "PNC-2000 boot firmware", + module: THIS_MODULE, + erase: pnc_mtd_erase, + read: pnc_mtd_read, + write: pnc_mtd_write, + suspend: pnc_mtd_suspend, + resume: pnc_mtd_resume, + sync: pnc_mtd_sync, + priv: (void *)0 + }, + { + type: MTD_NORFLASH, + flags: MTD_CAP_NORFLASH, + size: 0x1a0000, + erasesize: 0x20000, + name: "PNC-2000 kernel", + module: THIS_MODULE, + erase: pnc_mtd_erase, + read: pnc_mtd_read, + write: pnc_mtd_write, + suspend: pnc_mtd_suspend, + resume: pnc_mtd_resume, + sync: pnc_mtd_sync, + priv: (void *)0x20000 + }, + { + type: MTD_NORFLASH, + flags: MTD_CAP_NORFLASH, + size: 0x240000, + erasesize: 0x20000, + name: "PNC-2000 filesystem", + module: THIS_MODULE, + erase: pnc_mtd_erase, + read: pnc_mtd_read, + write: pnc_mtd_write, + suspend: pnc_mtd_suspend, + resume: pnc_mtd_resume, + sync: pnc_mtd_sync, + priv: (void *)0x1c0000 + } +}; + +#if LINUX_VERSION_CODE < 0x20300 +#ifdef MODULE +#define init_pnc init_module +#define cleanup_pnc cleanup_module +#endif +#endif + +int __init init_pnc(void) +{ + printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR); + + mymtd = do_cfi_probe(&pnc_map); + if (mymtd) { + mymtd->module = THIS_MODULE; + + add_mtd_device(&pnc_mtds[0]); /* boot */ + add_mtd_device(&pnc_mtds[1]); /* kernel */ + add_mtd_device(&pnc_mtds[2]); /* file system */ + return 0; + } + + return -ENXIO; +} + +static void __exit cleanup_pnc(void) +{ + if (mymtd) { + del_mtd_device(&pnc_mtds[2]); + del_mtd_device(&pnc_mtds[1]); + del_mtd_device(&pnc_mtds[0]); + map_destroy(mymtd); + } +} diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/3c509.c linux/drivers/net/3c509.c --- v2.4.0-test3/linux/drivers/net/3c509.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/net/3c509.c Tue Jul 11 11:12:23 2000 @@ -129,7 +129,7 @@ #define SKB_QUEUE_SIZE 64 struct el3_private { - struct enet_statistics stats; + struct net_device_stats stats; struct net_device *next_dev; spinlock_t lock; /* skb send-queue */ @@ -146,7 +146,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev); static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void update_stats(struct net_device *dev); -static struct enet_statistics *el3_get_stats(struct net_device *dev); +static struct net_device_stats *el3_get_stats(struct net_device *dev); static int el3_rx(struct net_device *dev); static int el3_close(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -789,7 +789,7 @@ } -static struct enet_statistics * +static struct net_device_stats * el3_get_stats(struct net_device *dev) { struct el3_private *lp = (struct el3_private *)dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/3c515.c linux/drivers/net/3c515.c --- v2.4.0-test3/linux/drivers/net/3c515.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/net/3c515.c Tue Jul 11 11:12:23 2000 @@ -310,7 +310,7 @@ struct sk_buff *tx_skbuff[TX_RING_SIZE]; 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 enet_statistics stats; + struct net_device_stats stats; struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ struct timer_list timer; /* Media selection timer. */ int capabilities ; /* Adapter capabilities word. */ @@ -384,7 +384,7 @@ struct pt_regs *regs); static int corkscrew_close(struct net_device *dev); static void update_stats(int addr, struct net_device *dev); -static struct enet_statistics *corkscrew_get_stats(struct net_device *dev); +static struct net_device_stats *corkscrew_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); @@ -1505,7 +1505,7 @@ return 0; } -static struct enet_statistics *corkscrew_get_stats(struct net_device *dev) +static struct net_device_stats *corkscrew_get_stats(struct net_device *dev) { struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/aironet4500.h linux/drivers/net/aironet4500.h --- v2.4.0-test3/linux/drivers/net/aironet4500.h Tue Mar 14 19:10:39 2000 +++ linux/drivers/net/aironet4500.h Tue Jul 11 11:12:23 2000 @@ -1522,7 +1522,7 @@ int full_stats; int debug; - struct enet_statistics stats; + struct net_device_stats stats; struct ctl_table * proc_table; @@ -1537,7 +1537,7 @@ extern void awc_tx_timeout(struct net_device *dev); extern int awc_start_xmit(struct sk_buff *, struct net_device *); extern void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs); -extern struct enet_statistics * awc_get_stats(struct net_device *dev); +extern struct net_device_stats * awc_get_stats(struct net_device *dev); extern int awc_rx(struct net_device *dev, struct awc_fid * rx_fid); extern void awc_set_multicast_list(struct net_device *dev); extern int awc_change_mtu(struct net_device *dev, int new_mtu); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/aironet4500_core.c linux/drivers/net/aironet4500_core.c --- v2.4.0-test3/linux/drivers/net/aironet4500_core.c Fri Mar 10 16:40:42 2000 +++ linux/drivers/net/aironet4500_core.c Tue Jul 11 11:12:23 2000 @@ -3118,7 +3118,7 @@ - struct enet_statistics *awc_get_stats(struct net_device *dev) + struct net_device_stats *awc_get_stats(struct net_device *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; // unsigned long flags; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/am79c961a.c linux/drivers/net/am79c961a.c --- v2.4.0-test3/linux/drivers/net/am79c961a.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/am79c961a.c Tue Jul 11 11:12:23 2000 @@ -322,7 +322,7 @@ * Get the current statistics. This may be called with the card open or * closed. */ -static struct enet_statistics *am79c961_getstats (struct net_device *dev) +static struct net_device_stats *am79c961_getstats (struct net_device *dev) { struct dev_priv *priv = (struct dev_priv *)dev->priv; return &priv->stats; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/am79c961a.h linux/drivers/net/am79c961a.h --- v2.4.0-test3/linux/drivers/net/am79c961a.h Mon Jul 10 16:47:23 2000 +++ linux/drivers/net/am79c961a.h Tue Jul 11 11:12:23 2000 @@ -109,7 +109,7 @@ #define TST_BUFF 0x8000 struct dev_priv { - struct enet_statistics stats; + struct net_device_stats stats; unsigned long rxbuffer[RX_BUFFERS]; unsigned long txbuffer[TX_BUFFERS]; unsigned char txhead; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/appletalk/ipddp.c linux/drivers/net/appletalk/ipddp.c --- v2.4.0-test3/linux/drivers/net/appletalk/ipddp.c Tue Mar 7 14:32:26 2000 +++ linux/drivers/net/appletalk/ipddp.c Tue Jul 11 11:12:23 2000 @@ -122,10 +122,10 @@ /* Initalize the device structure. */ dev->hard_start_xmit = ipddp_xmit; - dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL); + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); if(!dev->priv) return -ENOMEM; - memset(dev->priv,0,sizeof(struct enet_statistics)); + memset(dev->priv,0,sizeof(struct net_device_stats)); dev->open = ipddp_open; dev->stop = ipddp_close; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/arlan.c linux/drivers/net/arlan.c --- v2.4.0-test3/linux/drivers/net/arlan.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/arlan.c Tue Jul 11 11:12:23 2000 @@ -94,7 +94,7 @@ static int arlan_tx(struct sk_buff *skb, struct net_device *dev); static void arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int arlan_close(struct net_device *dev); -static struct enet_statistics * +static struct net_device_stats * arlan_statistics (struct net_device *dev); static void arlan_set_multicast (struct net_device *dev); static int arlan_hw_tx (struct net_device* dev, char *buf, int length ); @@ -1907,7 +1907,7 @@ * This may be called with the card open or closed. */ -static struct enet_statistics *arlan_statistics(struct net_device *dev) +static struct net_device_stats *arlan_statistics(struct net_device *dev) { struct arlan_private *priv = (struct arlan_private *) dev->priv; volatile struct arlan_shmem *arlan = ((struct arlan_private *) dev->priv)->card; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/arlan.h linux/drivers/net/arlan.h --- v2.4.0-test3/linux/drivers/net/arlan.h Mon Dec 20 18:48:21 1999 +++ linux/drivers/net/arlan.h Tue Jul 11 11:12:23 2000 @@ -343,7 +343,7 @@ #define TX_RING_SIZE 2 /* Information that need to be kept for each board. */ struct arlan_private { - struct enet_statistics stats; + struct net_device_stats stats; long open_time; /* Useless example local info. */ struct arlan_shmem * card; struct arlan_shmem * conf; @@ -574,4 +574,4 @@ #define ARLAN_DEBUG_INTERRUPT 0x00080 #define ARLAN_DEBUG_STARTUP 0x00100 #define ARLAN_DEBUG_SHUTDOWN 0x00200 - \ No newline at end of file + diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/at1700.c linux/drivers/net/at1700.c --- v2.4.0-test3/linux/drivers/net/at1700.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/at1700.c Tue Jul 11 11:12:23 2000 @@ -110,7 +110,7 @@ /* Information that need to be kept for each board. */ struct net_local { - struct enet_statistics stats; + struct net_device_stats stats; spinlock_t lock; unsigned char mc_filter[8]; uint jumpered:1; /* Set iff the board has jumper config. */ @@ -164,7 +164,7 @@ static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void net_rx(struct net_device *dev); static int net_close(struct net_device *dev); -static struct enet_statistics *net_get_stats(struct net_device *dev); +static struct net_device_stats *net_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static void net_tx_timeout (struct net_device *dev); @@ -796,7 +796,7 @@ This may be called with the card open or closed. There are no on-chip counters, so this function is trivial. */ -static struct enet_statistics * +static struct net_device_stats * net_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c --- v2.4.0-test3/linux/drivers/net/de4x5.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/de4x5.c Thu Jul 13 11:11:10 2000 @@ -3271,6 +3271,7 @@ case ANS: lp->media = ANS; + lp->fdx = lp->params.fdx; break; default: diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/dmfe.c linux/drivers/net/dmfe.c --- v2.4.0-test3/linux/drivers/net/dmfe.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/dmfe.c Tue Jul 11 11:12:23 2000 @@ -214,7 +214,7 @@ u8 rx_error_cnt; /* recievd abnormal case count */ u8 dm910x_chk_mode; /* Operating mode check */ struct timer_list timer; - struct enet_statistics stats; /* statistic counter */ + struct net_device_stats stats; /* statistic counter */ unsigned char srom[128]; }; @@ -313,7 +313,7 @@ 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 *); -static struct enet_statistics *dmfe_get_stats(struct net_device *); +static struct net_device_stats *dmfe_get_stats(struct net_device *); static void dmfe_set_filter_mode(struct net_device *); static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int); static u16 read_srom_word(long, int); @@ -849,7 +849,7 @@ /* Get statistics from driver. */ -static struct enet_statistics *dmfe_get_stats(struct net_device *dev) +static struct net_device_stats *dmfe_get_stats(struct net_device *dev) { struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/eepro.c linux/drivers/net/eepro.c --- v2.4.0-test3/linux/drivers/net/eepro.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/net/eepro.c Tue Jul 11 11:12:23 2000 @@ -181,7 +181,7 @@ /* Information that need to be kept for each board. */ struct eepro_local { - struct enet_statistics stats; + struct net_device_stats stats; unsigned rx_start; unsigned tx_start; /* start of the transmit chain */ int tx_last; /* pointer to last packet in the transmit chain */ @@ -293,7 +293,7 @@ static void eepro_rx(struct net_device *dev); static void eepro_transmit_interrupt(struct net_device *dev); static int eepro_close(struct net_device *dev); -static struct enet_statistics *eepro_get_stats(struct net_device *dev); +static struct net_device_stats *eepro_get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void eepro_tx_timeout (struct net_device *dev); @@ -1247,7 +1247,7 @@ /* Get the current statistics. This may be called with the card open or closed. */ -static struct enet_statistics * +static struct net_device_stats * eepro_get_stats(struct net_device *dev) { struct eepro_local *lp = (struct eepro_local *)dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c --- v2.4.0-test3/linux/drivers/net/eepro100.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/net/eepro100.c Tue Jul 11 11:12:23 2000 @@ -518,7 +518,7 @@ unsigned int cur_rx, dirty_rx; /* The next free ring entry */ long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ const char *product_name; - struct enet_statistics stats; + struct net_device_stats stats; struct speedo_stats *lstats; dma_addr_t lstats_dma; int chip_id; @@ -585,7 +585,7 @@ static void speedo_tx_buffer_gc(struct net_device *dev); static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int speedo_close(struct net_device *dev); -static struct enet_statistics *speedo_get_stats(struct net_device *dev); +static struct net_device_stats *speedo_get_stats(struct net_device *dev); static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static void set_rx_mode(struct net_device *dev); static void speedo_show_state(struct net_device *dev); @@ -1905,7 +1905,7 @@ Oh, and incoming frames are dropped while executing dump-stats! */ -static struct enet_statistics * +static struct net_device_stats * speedo_get_stats(struct net_device *dev) { struct speedo_private *sp = (struct speedo_private *)dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/ibmlana.c linux/drivers/net/ibmlana.c --- v2.4.0-test3/linux/drivers/net/ibmlana.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/ibmlana.c Tue Jul 11 11:12:23 2000 @@ -1001,7 +1001,7 @@ /* return pointer to Ethernet statistics */ -static struct enet_statistics *ibmlana_stats(struct IBMLANA_NETDEV *dev) +static struct net_device_stats *ibmlana_stats(struct IBMLANA_NETDEV *dev) { ibmlana_priv *priv = (ibmlana_priv *) dev->priv; @@ -1131,7 +1131,7 @@ priv->slot = slot; priv->realirq = irq; priv->medium = medium; - memset(&(priv->stat), 0, sizeof(struct enet_statistics)); + memset(&(priv->stat), 0, sizeof(struct net_device_stats)); /* set base + irq for this device (irq not allocated so far) */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/ibmlana.h linux/drivers/net/ibmlana.h --- v2.4.0-test3/linux/drivers/net/ibmlana.h Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/ibmlana.h Tue Jul 11 11:12:23 2000 @@ -41,7 +41,7 @@ typedef struct { unsigned int slot; /* MCA-Slot-# */ - struct enet_statistics stat; /* packet statistics */ + struct net_device_stats stat; /* packet statistics */ int realirq; /* memorizes actual IRQ, even when currently not allocated */ ibmlana_medium medium; /* physical cannector */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/pcmcia/netwave_cs.c linux/drivers/net/pcmcia/netwave_cs.c --- v2.4.0-test3/linux/drivers/net/pcmcia/netwave_cs.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/pcmcia/netwave_cs.c Tue Jul 11 11:12:24 2000 @@ -235,7 +235,7 @@ /* Statistics */ static void update_stats(struct net_device *dev); -static struct enet_statistics *netwave_get_stats(struct net_device *dev); +static struct net_device_stats *netwave_get_stats(struct net_device *dev); /* Wireless extensions */ #ifdef WIRELESS_EXT @@ -312,14 +312,14 @@ spinlock_t lock; struct timer_list watchdog; /* To avoid blocking state */ struct site_survey nss; - struct enet_statistics stats; + struct net_device_stats stats; #ifdef WIRELESS_EXT struct iw_statistics iw_stats; /* Wireless stats */ #endif } netwave_private; #ifdef NETWAVE_STATS -static struct enet_statistics *netwave_get_stats(struct net_device *dev); +static struct net_device_stats *netwave_get_stats(struct net_device *dev); #endif /* @@ -1434,7 +1434,7 @@ } /* netwave_watchdog */ -static struct enet_statistics *netwave_get_stats(struct net_device *dev) { +static struct net_device_stats *netwave_get_stats(struct net_device *dev) { netwave_private *priv = (netwave_private*)dev->priv; update_stats(dev); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c --- v2.4.0-test3/linux/drivers/net/pcmcia/ray_cs.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/pcmcia/ray_cs.c Tue Jul 11 11:12:24 2000 @@ -94,7 +94,7 @@ /***** Prototypes indicated by device structure ******************************/ static int ray_dev_close(struct net_device *dev); static int ray_dev_config(struct net_device *dev, struct ifmap *map); -static struct enet_statistics *ray_get_stats(struct net_device *dev); +static struct net_device_stats *ray_get_stats(struct net_device *dev); static int ray_dev_init(struct net_device *dev); static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static int ray_open(struct net_device *dev); @@ -1679,13 +1679,13 @@ return status; } /*===========================================================================*/ -static struct enet_statistics *ray_get_stats(struct net_device *dev) +static struct net_device_stats *ray_get_stats(struct net_device *dev) { ray_dev_t *local = (ray_dev_t *)dev->priv; dev_link_t *link = local->finder; struct status *p = (struct status *)(local->sram + STATUS_BASE); if (!(link->state & DEV_PRESENT)) { - DEBUG(2,"ray_cs enet_statistics - device not present\n"); + DEBUG(2,"ray_cs net_device_stats - device not present\n"); return &local->stats; } if (readb(&p->mrx_overflow_for_host)) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/pcmcia/ray_cs.h linux/drivers/net/pcmcia/ray_cs.h --- v2.4.0-test3/linux/drivers/net/pcmcia/ray_cs.h Wed Oct 27 16:34:12 1999 +++ linux/drivers/net/pcmcia/ray_cs.h Tue Jul 11 11:12:24 2000 @@ -50,7 +50,7 @@ UCHAR auth_id[6]; UCHAR net_default_tx_rate; UCHAR encryption; - struct enet_statistics stats; + struct net_device_stats stats; UCHAR net_type; UCHAR sta_type; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/pcmcia/xirc2ps_cs.c linux/drivers/net/pcmcia/xirc2ps_cs.c --- v2.4.0-test3/linux/drivers/net/pcmcia/xirc2ps_cs.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/pcmcia/xirc2ps_cs.c Tue Jul 11 11:12:24 2000 @@ -398,7 +398,7 @@ dev_link_t link; struct net_device dev; dev_node_t node; - struct enet_statistics stats; + struct net_device_stats stats; int card_type; int probe_port; int silicon; /* silicon revision. 0=old CE2, 1=Scipper, 4=Mohawk */ @@ -416,7 +416,7 @@ */ static int do_start_xmit(struct sk_buff *skb, struct net_device *dev); static void do_tx_timeout(struct net_device *dev); -static struct enet_statistics *do_get_stats(struct net_device *dev); +static struct net_device_stats *do_get_stats(struct net_device *dev); static void set_addresses(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static int set_card_type(dev_link_t *link, const void *s); @@ -1648,7 +1648,7 @@ return 0; } -static struct enet_statistics * +static struct net_device_stats * do_get_stats(struct net_device *dev) { local_info_t *lp = dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c --- v2.4.0-test3/linux/drivers/net/ppp_generic.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/ppp_generic.c Wed Jul 12 21:58:43 2000 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -319,6 +320,7 @@ { struct ppp_file *pf = (struct ppp_file *) file->private_data; + lock_kernel(); if (pf != 0) { file->private_data = 0; if (atomic_dec_and_test(&pf->refcnt)) { @@ -332,6 +334,7 @@ } } } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/ptifddi.c linux/drivers/net/ptifddi.c --- v2.4.0-test3/linux/drivers/net/ptifddi.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/ptifddi.c Tue Jul 11 15:46:08 2000 @@ -1,4 +1,4 @@ -/* $Id: ptifddi.c,v 1.12 2000/06/19 06:24:46 davem Exp $ +/* $Id: ptifddi.c,v 1.13 2000/07/11 22:35:22 davem Exp $ * ptifddi.c: Network driver for Performance Technologies single-attach * and dual-attach FDDI sbus cards. * @@ -142,7 +142,7 @@ struct ptifddi *pp = (struct ptifddi *) dev->priv; } -static struct enet_statistics *pti_get_stats(struct net_device *dev) +static struct net_device_stats *pti_get_stats(struct net_device *dev) { return &(((struct ptifddi *)dev->priv)->enet_stats); } static void pti_set_multicast(struct net_device *dev) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/rcpci45.c linux/drivers/net/rcpci45.c --- v2.4.0-test3/linux/drivers/net/rcpci45.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/rcpci45.c Tue Jul 11 11:12:24 2000 @@ -122,7 +122,7 @@ U32 bus; U32 function; struct timer_list timer; /* timer */ - struct enet_statistics stats; /* the statistics structure */ + struct net_device_stats stats; /* the statistics structure */ struct net_device *next; /* points to the next RC adapter */ unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/ unsigned char shutdown; @@ -152,7 +152,7 @@ static int RC_xmit_packet(struct sk_buff *, struct net_device *); static void RCinterrupt(int, void *, struct pt_regs *); static int RCclose(struct net_device *dev); -static struct enet_statistics *RCget_stats(struct net_device *); +static struct net_device_stats *RCget_stats(struct net_device *); static int RCioctl(struct net_device *, struct ifreq *, int); static int RCconfig(struct net_device *, struct ifmap *); static void RCxmit_callback(U32, U16, PU32, U16); @@ -936,7 +936,7 @@ return 0; } -static struct enet_statistics * +static struct net_device_stats * RCget_stats(struct net_device *dev) { RCLINKSTATS RCstats; @@ -1019,7 +1019,7 @@ pDpa->stats.tx_heartbeat_errors = 0; pDpa->stats.tx_window_errors = 0; - return ((struct enet_statistics *)&(pDpa->stats)); + return ((struct net_device_stats *)&(pDpa->stats)); } return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/rtl8129.c linux/drivers/net/rtl8129.c --- v2.4.0-test3/linux/drivers/net/rtl8129.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/rtl8129.c Tue Jul 11 11:12:24 2000 @@ -260,11 +260,7 @@ int chip_id; int chip_revision; unsigned char pci_bus, pci_devfn; -#if LINUX_VERSION_CODE > 0x20139 struct net_device_stats stats; -#else - struct enet_statistics stats; -#endif struct timer_list timer; /* Media selection timer. */ unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ unsigned int cur_tx, dirty_tx, tx_flag; @@ -306,7 +302,7 @@ static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int rtl8129_close(struct net_device *dev); static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static struct enet_statistics *rtl8129_get_stats(struct net_device *dev); +static struct net_device_stats *rtl8129_get_stats(struct net_device *dev); static inline u32 ether_crc(int length, unsigned char *data); static void set_rx_mode(struct net_device *dev); @@ -1365,7 +1361,7 @@ } } -static struct enet_statistics * +static struct net_device_stats * rtl8129_get_stats(struct net_device *dev) { struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sb1000.c linux/drivers/net/sb1000.c --- v2.4.0-test3/linux/drivers/net/sb1000.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/sb1000.c Tue Jul 11 11:12:24 2000 @@ -92,7 +92,7 @@ static int sb1000_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd); static int sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev); static void sb1000_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct enet_statistics *sb1000_stats(struct net_device *dev); +static struct net_device_stats *sb1000_stats(struct net_device *dev); static int sb1000_close(struct net_device *dev); @@ -760,7 +760,7 @@ unsigned int skbsize; struct sk_buff *skb; struct sb1000_private *lp = (struct sb1000_private *)dev->priv; - struct enet_statistics *stats = &lp->stats; + struct net_device_stats *stats = &lp->stats; /* SB1000 frame constants */ const int FrameSize = FRAMESIZE; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sgiseeq.c linux/drivers/net/sgiseeq.c --- v2.4.0-test3/linux/drivers/net/sgiseeq.c Mon Jul 10 16:47:23 2000 +++ linux/drivers/net/sgiseeq.c Tue Jul 11 11:12:24 2000 @@ -107,7 +107,7 @@ unsigned char control; unsigned char mode; - struct enet_statistics stats; + struct net_device_stats stats; }; static inline void hpc3_eth_reset(volatile struct hpc3_ethregs *hregs) @@ -552,7 +552,7 @@ netif_wake_queue(dev); } -static struct enet_statistics *sgiseeq_get_stats(struct net_device *dev) +static struct net_device_stats *sgiseeq_get_stats(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sis900.c linux/drivers/net/sis900.c --- v2.4.0-test3/linux/drivers/net/sis900.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/sis900.c Tue Jul 11 11:12:24 2000 @@ -161,7 +161,7 @@ static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int sis900_close(struct net_device *net_dev); static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd); -static struct enet_statistics *sis900_get_stats(struct net_device *net_dev); +static struct net_device_stats *sis900_get_stats(struct net_device *net_dev); static u16 sis900_compute_hashtable_index(u8 *addr); static void set_rx_mode(struct net_device *net_dev); static void sis900_reset(struct net_device *net_dev); @@ -1140,7 +1140,7 @@ } } -static struct enet_statistics * +static struct net_device_stats * sis900_get_stats(struct net_device *net_dev) { struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sk_mca.c linux/drivers/net/sk_mca.c --- v2.4.0-test3/linux/drivers/net/sk_mca.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/net/sk_mca.c Tue Jul 11 11:12:24 2000 @@ -1016,7 +1016,7 @@ /* return pointer to Ethernet statistics */ -static struct enet_statistics *skmca_stats(struct SKMCA_NETDEV *dev) +static struct net_device_stats *skmca_stats(struct SKMCA_NETDEV *dev) { skmca_priv *priv = (skmca_priv *) dev->priv; @@ -1164,7 +1164,7 @@ priv->ctrladdr = base + 0x3ff2; priv->cmdaddr = base + 0x3ff3; priv->medium = medium; - memset(&(priv->stat), 0, sizeof(struct enet_statistics)); + memset(&(priv->stat), 0, sizeof(struct net_device_stats)); /* set base + irq for this device (irq not allocated so far) */ dev->irq = 0; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sk_mca.h linux/drivers/net/sk_mca.h --- v2.4.0-test3/linux/drivers/net/sk_mca.h Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/sk_mca.h Tue Jul 11 11:12:24 2000 @@ -49,7 +49,7 @@ int nexttxdone; /* index of next TX descriptor to be finished */ int txbusy; /* # of busy TX descriptors */ - struct enet_statistics stat; /* packet statistics */ + struct net_device_stats stat; /* packet statistics */ int realirq; /* memorizes actual IRQ, even when currently not allocated */ skmca_medium medium; /* physical cannector */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/skfp/skfddi.c linux/drivers/net/skfp/skfddi.c --- v2.4.0-test3/linux/drivers/net/skfp/skfddi.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/skfp/skfddi.c Tue Jul 11 11:12:24 2000 @@ -121,7 +121,7 @@ static int skfp_open(struct net_device *dev); static int skfp_close(struct net_device *dev); static void skfp_interrupt(int irq, void *dev_id, struct pt_regs *regs); -static struct enet_statistics *skfp_ctl_get_stats(struct net_device *dev); +static struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev); static void skfp_ctl_set_multicast_list(struct net_device *dev); static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev); static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr); @@ -967,7 +967,7 @@ * independent. * */ -struct enet_statistics *skfp_ctl_get_stats(struct net_device *dev) +struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev) { struct s_smc *bp = (struct s_smc *) dev->priv; @@ -1090,7 +1090,7 @@ bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls; #endif - return ((struct enet_statistics *) &bp->os.MacStat); + return ((struct net_device_stats *) &bp->os.MacStat); } // ctl_get_stat diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sonic.c linux/drivers/net/sonic.c --- v2.4.0-test3/linux/drivers/net/sonic.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/sonic.c Tue Jul 11 11:12:24 2000 @@ -377,7 +377,7 @@ * Get the current statistics. * This may be called with the device open or closed. */ -static struct enet_statistics * +static struct net_device_stats * sonic_get_stats(struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sonic.h linux/drivers/net/sonic.h --- v2.4.0-test3/linux/drivers/net/sonic.h Wed Aug 18 11:36:45 1999 +++ linux/drivers/net/sonic.h Tue Jul 11 11:12:24 2000 @@ -460,7 +460,7 @@ unsigned int cur_tx; unsigned int dirty_tx; /* last unacked transmit packet */ char tx_full; - struct enet_statistics stats; + struct net_device_stats stats; }; /* Index to functions, as function prototypes. */ @@ -470,7 +470,7 @@ static void sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void sonic_rx(struct net_device *dev); static int sonic_close(struct net_device *dev); -static struct enet_statistics *sonic_get_stats(struct net_device *dev); +static struct net_device_stats *sonic_get_stats(struct net_device *dev); static void sonic_multicast_list(struct net_device *dev); static int sonic_init(struct net_device *dev); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/strip.c linux/drivers/net/strip.c --- v2.4.0-test3/linux/drivers/net/strip.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/strip.c Tue Jul 11 11:12:24 2000 @@ -2430,12 +2430,12 @@ return 0; } -static struct enet_statistics *strip_get_stats(struct net_device *dev) +static struct net_device_stats *strip_get_stats(struct net_device *dev) { - static struct enet_statistics stats; + static struct net_device_stats stats; struct strip *strip_info = (struct strip *)(dev->priv); - memset(&stats, 0, sizeof(struct enet_statistics)); + memset(&stats, 0, sizeof(struct net_device_stats)); stats.rx_packets = strip_info->rx_packets; stats.tx_packets = strip_info->tx_packets; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sunbmac.c linux/drivers/net/sunbmac.c --- v2.4.0-test3/linux/drivers/net/sunbmac.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/sunbmac.c Tue Jul 11 15:46:08 2000 @@ -1,4 +1,4 @@ -/* $Id: sunbmac.c,v 1.19 2000/06/19 06:24:46 davem Exp $ +/* $Id: sunbmac.c,v 1.20 2000/07/11 22:35:22 davem Exp $ * sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -164,7 +164,7 @@ static void bigmac_get_counters(struct bigmac *bp, unsigned long bregs) { - struct enet_statistics *stats = &bp->enet_stats; + struct net_device_stats *stats = &bp->enet_stats; stats->rx_crc_errors += sbus_readl(bregs + BMAC_RCRCECTR); sbus_writel(0, bregs + BMAC_RCRCECTR); @@ -974,7 +974,7 @@ return 0; } -static struct enet_statistics *bigmac_get_stats(struct net_device *dev) +static struct net_device_stats *bigmac_get_stats(struct net_device *dev) { struct bigmac *bp = (struct bigmac *) dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/sunbmac.h linux/drivers/net/sunbmac.h --- v2.4.0-test3/linux/drivers/net/sunbmac.h Thu Feb 10 17:11:11 2000 +++ linux/drivers/net/sunbmac.h Tue Jul 11 15:46:08 2000 @@ -1,4 +1,4 @@ -/* $Id: sunbmac.h,v 1.6 2000/02/09 11:15:36 davem Exp $ +/* $Id: sunbmac.h,v 1.7 2000/07/11 22:35:22 davem Exp $ * sunbmac.h: Defines for the Sun "Big MAC" 100baseT ethernet cards. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -328,7 +328,7 @@ enum bigmac_timer_state timer_state; unsigned int timer_ticks; - struct enet_statistics enet_stats; + struct net_device_stats enet_stats; struct sbus_dev *qec_sdev; struct sbus_dev *bigmac_sdev; struct net_device *dev; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/tokenring/smctr.c linux/drivers/net/tokenring/smctr.c --- v2.4.0-test3/linux/drivers/net/tokenring/smctr.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/tokenring/smctr.c Tue Jul 11 11:12:24 2000 @@ -124,7 +124,7 @@ static int smctr_get_physical_drop_number(struct net_device *dev); static __u8 *smctr_get_rx_pointer(struct net_device *dev, short queue); static int smctr_get_station_id(struct net_device *dev); -static struct enet_statistics *smctr_get_stats(struct net_device *dev); +static struct net_device_stats *smctr_get_stats(struct net_device *dev); static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, __u16 bytes_count); static int smctr_get_upstream_neighbor_addr(struct net_device *dev); @@ -1402,11 +1402,11 @@ * Get the current statistics. This may be called with the card open * or closed. */ -static struct enet_statistics *smctr_get_stats(struct net_device *dev) +static struct net_device_stats *smctr_get_stats(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; - return ((struct enet_statistics *)&tp->MacStat); + return ((struct net_device_stats *)&tp->MacStat); } static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/tokenring/tms380tr.c linux/drivers/net/tokenring/tms380tr.c --- v2.4.0-test3/linux/drivers/net/tokenring/tms380tr.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/tokenring/tms380tr.c Tue Jul 11 11:12:24 2000 @@ -143,7 +143,7 @@ static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue); /* "F" */ /* "G" */ -static struct enet_statistics *tms380tr_get_stats(struct net_device *dev); +static struct net_device_stats *tms380tr_get_stats(struct net_device *dev); /* "H" */ static void tms380tr_hardware_send_packet(struct net_device *dev, struct net_local* tp); @@ -1166,11 +1166,11 @@ * Get the current statistics. This may be called with the card open * or closed. */ -static struct enet_statistics *tms380tr_get_stats(struct net_device *dev) +static struct net_device_stats *tms380tr_get_stats(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; - return ((struct enet_statistics *)&tp->MacStat); + return ((struct net_device_stats *)&tp->MacStat); } /* diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c --- v2.4.0-test3/linux/drivers/net/tulip/tulip_core.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/net/tulip/tulip_core.c Tue Jul 11 11:12:24 2000 @@ -717,7 +717,7 @@ return 0; } -static struct enet_statistics *tulip_get_stats(struct net_device *dev) +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; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/Config.in linux/drivers/net/wan/Config.in --- v2.4.0-test3/linux/drivers/net/wan/Config.in Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/wan/Config.in Tue Jul 11 11:22:42 2000 @@ -45,6 +45,8 @@ dep_tristate 'Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m + dep_tristate 'SyncLink HDLC/SYNCPPP support' CONFIG_SYNCLINK_SYNCPPP m + tristate 'Frame relay DLCI support' CONFIG_DLCI if [ "$CONFIG_DLCI" != "n" ]; then int 'Max open DLCI' CONFIG_DLCI_COUNT 24 diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/Makefile linux/drivers/net/wan/Makefile --- v2.4.0-test3/linux/drivers/net/wan/Makefile Wed Apr 26 16:34:08 2000 +++ linux/drivers/net/wan/Makefile Thu Jul 13 14:49:57 2000 @@ -49,6 +49,14 @@ endif endif +ifeq ($(CONFIG_SYNCLINK_SYNCPPP),y) +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_SYNCLINK_SYNCPPP),m) + CONFIG_SYNCPPP_MODULE = y + endif +endif + ifeq ($(CONFIG_COMX),y) LX_OBJS += comx.o else @@ -167,6 +175,7 @@ else ifeq ($(CONFIG_SDLA),m) M_OBJS += sdla.o + endif endif ifeq ($(CONFIG_VENDOR_SANGOMA),y) @@ -184,8 +193,6 @@ ifeq ($(CONFIG_WANPIPE_PPP),y) L_OBJS += sdla_ppp.o endif -endif - endif ifeq ($(CONFIG_VENDOR_SANGOMA),m) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/cosa.c linux/drivers/net/wan/cosa.c --- v2.4.0-test3/linux/drivers/net/wan/cosa.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/net/wan/cosa.c Wed Jul 12 21:58:43 2000 @@ -93,6 +93,7 @@ #include #include #include +#include #undef COSA_SLOW_IO /* for testing purposes only */ #undef REALLY_SLOW_IO @@ -977,13 +978,16 @@ static int cosa_release(struct inode *inode, struct file *file) { struct channel_data *channel = (struct channel_data *)file->private_data; - struct cosa_data *cosa = channel->cosa; + struct cosa_data *cosa; unsigned long flags; + lock_kernel(); + cosa = channel->cosa; spin_lock_irqsave(&cosa->lock, flags); cosa->usage--; channel->usage--; spin_unlock_irqrestore(&cosa->lock, flags); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/hostess_sv11.c linux/drivers/net/wan/hostess_sv11.c --- v2.4.0-test3/linux/drivers/net/wan/hostess_sv11.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/net/wan/hostess_sv11.c Tue Jul 11 11:12:24 2000 @@ -166,7 +166,7 @@ return sppp_do_ioctl(d, ifr,cmd); } -static struct enet_statistics *hostess_get_stats(struct net_device *d) +static struct net_device_stats *hostess_get_stats(struct net_device *d) { struct sv11_device *sv11=d->priv; if(sv11) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/lmc/lmc_main.c linux/drivers/net/wan/lmc/lmc_main.c --- v2.4.0-test3/linux/drivers/net/wan/lmc/lmc_main.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/net/wan/lmc/lmc_main.c Tue Jul 11 11:12:24 2000 @@ -127,7 +127,7 @@ static int lmc_rx (struct net_device *dev); static int lmc_open(struct net_device *dev); static int lmc_close(struct net_device *dev); -static struct enet_statistics *lmc_get_stats(struct net_device *dev); +static struct net_device_stats *lmc_get_stats(struct net_device *dev); static void lmc_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int lmc_set_config(struct net_device *dev, struct ifmap *map); static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, size_t csr_size); @@ -1961,7 +1961,7 @@ return 0; } -static struct enet_statistics *lmc_get_stats (struct net_device *dev) /*fold00*/ +static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/ { lmc_softc_t *sc; LMC_SPIN_FLAGS; @@ -1978,7 +1978,7 @@ lmc_trace(dev, "lmc_get_stats out"); - return (struct enet_statistics *) &sc->stats; + return (struct net_device_stats *) &sc->stats; } #ifdef MODULE diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/lmc/lmc_var.h linux/drivers/net/wan/lmc/lmc_var.h --- v2.4.0-test3/linux/drivers/net/wan/lmc/lmc_var.h Wed Apr 26 16:34:08 2000 +++ linux/drivers/net/wan/lmc/lmc_var.h Tue Jul 11 11:12:24 2000 @@ -248,7 +248,7 @@ #define STATCHECK 0xBEEFCAFE /* Included in this structure are first - * - standard enet_statistics + * - standard net_device_stats * - some other counters used for debug and driver performance * evaluation -baz */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/sbni.c linux/drivers/net/wan/sbni.c --- v2.4.0-test3/linux/drivers/net/wan/sbni.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/net/wan/sbni.c Tue Jul 11 11:12:24 2000 @@ -100,7 +100,7 @@ static void sbni_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int sbni_close(struct net_device *dev); static void sbni_drop_tx_queue(struct net_device *dev); -static struct enet_statistics *sbni_get_stats(struct net_device *dev); +static struct net_device_stats *sbni_get_stats(struct net_device *dev); static void card_start(struct net_device *dev); static inline unsigned short sbni_recv(struct net_device *dev); void change_level(struct net_device *dev); @@ -952,7 +952,7 @@ spin_unlock(&lp->lock); } -static struct enet_statistics *sbni_get_stats(struct net_device *dev) +static struct net_device_stats *sbni_get_stats(struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; return &lp->stats; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/sbni.h linux/drivers/net/wan/sbni.h --- v2.4.0-test3/linux/drivers/net/wan/sbni.h Sun Feb 13 19:29:04 2000 +++ linux/drivers/net/wan/sbni.h Tue Jul 11 11:12:24 2000 @@ -106,7 +106,7 @@ * Board-specific info in dev->priv. */ struct net_local { - struct enet_statistics stats; + struct net_device_stats stats; struct timer_list watchdog; unsigned int realframelen; /* the current size of the SB-frame */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/sdla_chdlc.c linux/drivers/net/wan/sdla_chdlc.c --- v2.4.0-test3/linux/drivers/net/wan/sdla_chdlc.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/wan/sdla_chdlc.c Tue Jul 11 11:12:24 2000 @@ -143,7 +143,7 @@ struct sk_buff* skb); #endif static int if_send (struct sk_buff* skb, struct net_device* dev); -static struct enet_statistics* if_stats (struct net_device* dev); +static struct net_device_stats* if_stats (struct net_device* dev); /* CHDLC Firmware interface functions */ static int chdlc_configure (sdla_t* card, void* data); @@ -1169,7 +1169,7 @@ /*============================================================================ * Get ethernet-style interface statistics. - * Return a pointer to struct enet_statistics. + * Return a pointer to struct net_device_stats. */ #ifdef LINUX_2_1 static struct net_device_stats* if_stats (struct net_device* dev) @@ -1181,7 +1181,7 @@ return &my_card->wandev.stats; } #else -static struct enet_statistics* if_stats (struct net_device* dev) +static struct net_device_stats* if_stats (struct net_device* dev) { sdla_t *my_card; chdlc_private_area_t* chdlc_priv_area = dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/sdla_fr.c linux/drivers/net/wan/sdla_fr.c --- v2.4.0-test3/linux/drivers/net/wan/sdla_fr.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/wan/sdla_fr.c Tue Jul 11 11:12:24 2000 @@ -1588,9 +1588,9 @@ /*============================================================================ * Get ethernet-style interface statistics. - * Return a pointer to struct enet_statistics. + * Return a pointer to struct net_device_stats. */ -static struct enet_statistics* if_stats (struct net_device* dev) +static struct net_device_stats* if_stats (struct net_device* dev) { fr_channel_t* chan = dev->priv; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/net/wan/sealevel.c linux/drivers/net/wan/sealevel.c --- v2.4.0-test3/linux/drivers/net/wan/sealevel.c Thu May 11 15:30:07 2000 +++ linux/drivers/net/wan/sealevel.c Tue Jul 11 11:12:24 2000 @@ -164,7 +164,7 @@ return sppp_do_ioctl(d, ifr,cmd); } -static struct enet_statistics *sealevel_get_stats(struct net_device *d) +static struct net_device_stats *sealevel_get_stats(struct net_device *d) { struct slvl_device *slvl=d->priv; if(slvl) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog --- v2.4.0-test3/linux/drivers/parport/ChangeLog Mon Jul 10 16:47:24 2000 +++ linux/drivers/parport/ChangeLog Wed Jul 12 16:24:33 2000 @@ -1,3 +1,49 @@ +2000-07-12 Tim Waugh + + * share.c: Documentation for parport_{get,port}_port, + parport_find_{number,base}. + +2000-07-12 Tim Waugh + + * share.c (parport_unregister_device): Remove unneeded locking + (test cad==dev). + (parport_claim): Likewise. + (parport_find_number): New function. + +2000-07-12 Tim Waugh + + * share.c (parport_register_port): Hold the parportlist_lock while + looking for a free parport number. + (parport_register_driver): Make sure that attach can block. + (attach_driver_chain): Likewise. + +2000-07-12 Tim Waugh + + * share.c (call_driver_chain): Do reference counting things. + (parport_get_port): New function. + (parport_put_port): New function. + (parport_register_port): Initialise reference count to zero. + (parport_unregister_port): Check reference count rather than + driver list to see if we can free the port. + +2000-07-12 Tim Waugh + + * share.c: Clarifications in doc comments. + +2000-07-12 Tim Waugh + + * share.c (parport_unregister_port): Fix typo in comment. + +2000-07-11 Gunther Mayer + + * parport_pc.c: Support for the full range of Timedia cards. + +2000-07-08 Tim Waugh + + * daisy.c: License block comments as part of parportbook. + * ieee1284.c: Likewise. + * share.c: Likewise. + 2000-06-30 Petr Vandrovec * procfs.c (do_hardware_modes): Generated string can be up to 34 diff -u --recursive --new-file v2.4.0-test3/linux/drivers/parport/init.c linux/drivers/parport/init.c --- v2.4.0-test3/linux/drivers/parport/init.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/parport/init.c Wed Jul 12 16:24:33 2000 @@ -180,6 +180,10 @@ EXPORT_SYMBOL(parport_register_device); EXPORT_SYMBOL(parport_unregister_device); EXPORT_SYMBOL(parport_enumerate); +EXPORT_SYMBOL(parport_get_port); +EXPORT_SYMBOL(parport_put_port); +EXPORT_SYMBOL(parport_find_number); +EXPORT_SYMBOL(parport_find_base); EXPORT_SYMBOL(parport_negotiate); EXPORT_SYMBOL(parport_write); EXPORT_SYMBOL(parport_read); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c --- v2.4.0-test3/linux/drivers/parport/parport_pc.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/parport/parport_pc.c Tue Jul 11 10:44:57 2000 @@ -2307,8 +2307,31 @@ boca_ioppar, plx_9050, afavlab_tk9902, - timedia_1889, + timedia_4078a, + timedia_4079h, + timedia_4085h, + timedia_4088a, + timedia_4089a, + timedia_4095a, + timedia_4096a, + timedia_4078u, + timedia_4079a, + timedia_4085u, + timedia_4079r, + timedia_4079s, + timedia_4079d, + timedia_4079e, + timedia_4079f, + timedia_9079a, + timedia_9079b, + timedia_9079c, + timedia_4006a, + timedia_4014, + timedia_4008a, + timedia_4018, + timedia_9018a, syba_2p_epp, + syba_1p_ecp, }; @@ -2348,10 +2371,33 @@ /* boca_ioppar */ { 1, { { 0, -1 }, } }, /* plx_9050 */ { 2, { { 4, -1 }, { 5, -1 }, } }, /* afavlab_tk9902 */ { 1, { { 0, 1 }, } }, - /* timedia_1889 */ { 1, { { 2, -1 }, } }, + /* timedia_4078a */ { 1, { { 2, -1 }, } }, + /* timedia_4079h */ { 1, { { 2, 3 }, } }, + /* timedia_4085h */ { 2, { { 2, -1 }, { 4, -1 }, } }, + /* timedia_4088a */ { 2, { { 2, 3 }, { 4, 5 }, } }, + /* timedia_4089a */ { 2, { { 2, 3 }, { 4, 5 }, } }, + /* timedia_4095a */ { 2, { { 2, 3 }, { 4, 5 }, } }, + /* timedia_4096a */ { 2, { { 2, 3 }, { 4, 5 }, } }, + /* timedia_4078u */ { 1, { { 2, -1 }, } }, + /* timedia_4079a */ { 1, { { 2, 3 }, } }, + /* timedia_4085u */ { 2, { { 2, -1 }, { 4, -1 }, } }, + /* timedia_4079r */ { 1, { { 2, 3 }, } }, + /* timedia_4079s */ { 1, { { 2, 3 }, } }, + /* timedia_4079d */ { 1, { { 2, 3 }, } }, + /* timedia_4079e */ { 1, { { 2, 3 }, } }, + /* timedia_4079f */ { 1, { { 2, 3 }, } }, + /* timedia_9079a */ { 1, { { 2, 3 }, } }, + /* timedia_9079b */ { 1, { { 2, 3 }, } }, + /* timedia_9079c */ { 1, { { 2, 3 }, } }, + /* timedia_4006a */ { 1, { { 0, -1 }, } }, + /* timedia_4014 */ { 2, { { 0, -1 }, { 2, -1 }, } }, + /* timedia_4008a */ { 1, { { 0, 1 }, } }, + /* timedia_4018 */ { 2, { { 0, 1 }, { 2, 3 }, } }, + /* timedia_9018a */ { 2, { { 0, 1 }, { 2, 3 }, } }, /* SYBA uses fixed offsets in a 1K io window */ - /* syba_2p_epp */ { 2, { { 0, 0x078 }, { 0, 0x178 }, } }, + /* syba_2p_epp AP138B */ { 2, { { 0, 0x078 }, { 0, 0x178 }, } }, + /* syba_1p_ecp W83787 */ { 1, { { 0, 0x078 }, } }, }; static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = { @@ -2409,9 +2455,34 @@ PCI_SUBVENDOR_ID_EXSYS, PCI_SUBDEVICE_ID_EXSYS_4014, 0,0, plx_9050 }, { PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_TK9902, PCI_ANY_ID, PCI_ANY_ID, 0, 0, afavlab_tk9902 }, - { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, timedia_1889 }, - { 0x1592, 0x0782, PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_2p_epp }, + /* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/ + { 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a }, + { 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h }, + { 0x1409, 0x7168, 0x1409, 0x4085, 0, 0, timedia_4085h }, + { 0x1409, 0x7168, 0x1409, 0x4088, 0, 0, timedia_4088a }, + { 0x1409, 0x7168, 0x1409, 0x4089, 0, 0, timedia_4089a }, + { 0x1409, 0x7168, 0x1409, 0x4095, 0, 0, timedia_4095a }, + { 0x1409, 0x7168, 0x1409, 0x4096, 0, 0, timedia_4096a }, + { 0x1409, 0x7168, 0x1409, 0x5078, 0, 0, timedia_4078u }, + { 0x1409, 0x7168, 0x1409, 0x5079, 0, 0, timedia_4079a }, + { 0x1409, 0x7168, 0x1409, 0x5085, 0, 0, timedia_4085u }, + { 0x1409, 0x7168, 0x1409, 0x6079, 0, 0, timedia_4079r }, + { 0x1409, 0x7168, 0x1409, 0x7079, 0, 0, timedia_4079s }, + { 0x1409, 0x7168, 0x1409, 0x8079, 0, 0, timedia_4079d }, + { 0x1409, 0x7168, 0x1409, 0x9079, 0, 0, timedia_4079e }, + { 0x1409, 0x7168, 0x1409, 0xa079, 0, 0, timedia_4079f }, + { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, + { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, + { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, + { 0x1409, 0x7268, 0x1409, 0x0101, 0, 0, timedia_4006a }, + { 0x1409, 0x7268, 0x1409, 0x0102, 0, 0, timedia_4014 }, + { 0x1409, 0x7268, 0x1409, 0x0103, 0, 0, timedia_4008a }, + { 0x1409, 0x7268, 0x1409, 0x0104, 0, 0, timedia_4018 }, + { 0x1409, 0x7268, 0x1409, 0x9018, 0, 0, timedia_9018a }, + { PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_2P_EPP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_2p_epp }, + { PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_1P_ECP, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_1p_ecp }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/parport/share.c linux/drivers/parport/share.c --- v2.4.0-test3/linux/drivers/parport/share.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/parport/share.c Wed Jul 12 16:24:34 2000 @@ -88,17 +88,57 @@ dead_read /* byte */ }; -static void call_driver_chain(int attach, struct parport *port) +/* Call attach(port) for each registered driver. */ +static void attach_driver_chain(struct parport *port) { struct parport_driver *drv; + void (**attach) (struct parport *); + int count = 0, i; + + /* This is complicated because attach() must be able to block, + * but we can't let it do that while we're holding a + * spinlock. */ spin_lock (&driverlist_lock); - for (drv = driver_chain; drv; drv = drv->next) { - if (attach) - drv->attach (port); - else - drv->detach (port); + for (drv = driver_chain; drv; drv = drv->next) + count++; + spin_unlock (&driverlist_lock); + + /* Drivers can unregister here; that's okay. If they register + * they'll be given an attach during parport_register_driver, + * so that's okay too. The only worry is that someone might + * get given an attach twice if they registered just before + * this function gets called. */ + + /* Hmm, this could be fixed with a generation number.. + * FIXME */ + + attach = kmalloc (sizeof (void(*)(struct parport *)) * count, + GFP_KERNEL); + if (!attach) { + printk (KERN_WARNING "parport: not enough memory to attach\n"); + return; } + + spin_lock (&driverlist_lock); + for (i = 0, drv = driver_chain; drv && i < count; drv = drv->next) + attach[i] = drv->attach; + spin_unlock (&driverlist_lock); + + for (count = 0; count < i; count++) + (*attach[i]) (port); + + kfree (attach); +} + +/* Call detach(port) for each registered driver. */ +static void detach_driver_chain(struct parport *port) +{ + struct parport_driver *drv; + + spin_lock (&driverlist_lock); + for (drv = driver_chain; drv; drv = drv->next) + drv->detach (port); spin_unlock (&driverlist_lock); } @@ -121,28 +161,63 @@ * The @drv structure is allocated by the caller and must not be * deallocated until after calling parport_unregister_driver(). * + * The driver's attach() function may block. The port that + * attach() is given will be valid for the duration of the + * callback, but if the driver wants to take a copy of the + * pointer it must call parport_get_port() to do so. Calling + * parport_register_device() on that port will do this for you. + * + * The driver's detach() function may not block. The port that + * detach() is given will be valid for the duration of the + * callback, but if the driver wants to take a copy of the + * pointer it must call parport_get_port() to do so. + * * Returns 0 on success. Currently it always succeeds. **/ int parport_register_driver (struct parport_driver *drv) { struct parport *port; - - spin_lock (&driverlist_lock); - drv->next = driver_chain; - driver_chain = drv; - spin_unlock (&driverlist_lock); + struct parport **ports; + int count = 0, i; /* We have to take the portlist lock for this to be sure * that port is valid for the duration of the callback. */ + + /* This is complicated by the fact that attach must be allowed + * to block, so we can't be holding any spinlocks when we call + * it. But we need to hold a spinlock to iterate over the + * list of ports.. */ + spin_lock (&parportlist_lock); for (port = portlist; port; port = port->next) - drv->attach (port); + count++; spin_unlock (&parportlist_lock); + ports = kmalloc (sizeof (struct parport *) * count, GFP_KERNEL); + if (!ports) + printk (KERN_WARNING "parport: not enough memory to attach\n"); + else { + spin_lock (&parportlist_lock); + for (i = 0, port = portlist; port && i < count; + port = port->next) + ports[i] = port; + spin_unlock (&parportlist_lock); + + for (count = 0; count < i; count++) + drv->attach (ports[count]); + + kfree (ports); + } + if (!portlist) get_lowlevel_driver (); + spin_lock (&driverlist_lock); + drv->next = driver_chain; + driver_chain = drv; + spin_unlock (&driverlist_lock); + return 0; } @@ -162,6 +237,11 @@ * If the caller's attach() function can block, it is their * responsibility to make sure to wait for it to exit before * unloading. + * + * All the driver's detach() calls are guaranteed to have + * finished by the time this function returns. + * + * The driver's detach() call is not allowed to block. **/ void parport_unregister_driver (struct parport_driver *arg) @@ -194,6 +274,57 @@ } } +static void free_port (struct parport *port) +{ + int d; + for (d = 0; d < 5; d++) { + if (port->probe_info[d].class_name) + kfree (port->probe_info[d].class_name); + if (port->probe_info[d].mfr) + kfree (port->probe_info[d].mfr); + if (port->probe_info[d].model) + kfree (port->probe_info[d].model); + if (port->probe_info[d].cmdset) + kfree (port->probe_info[d].cmdset); + if (port->probe_info[d].description) + kfree (port->probe_info[d].description); + } + + kfree(port->name); + kfree(port); +} + +/** + * parport_get_port - increment a port's reference count + * @port: the port + * + * This ensure's that a struct parport pointer remains valid + * until the matching parport_put_port() call. + **/ + +struct parport *parport_get_port (struct parport *port) +{ + atomic_inc (&port->ref_count); + return port; +} + +/** + * parport_put_port - decrement a port's reference count + * @port: the port + * + * This should be called once for each call to parport_get_port(), + * once the port is no longer needed. + **/ + +void parport_put_port (struct parport *port) +{ + if (atomic_dec_and_test (&port->ref_count)) + /* Can destroy it now. */ + free_port (port); + + return; +} + /** * parport_enumerate - return a list of the system's parallel ports * @@ -260,6 +391,8 @@ } /* Search for the lowest free parport number. */ + + spin_lock_irq (&parportlist_lock); for (portnum = 0; ; portnum++) { struct parport *itr = portlist; while (itr) { @@ -274,6 +407,7 @@ /* Got to the end of the list. */ break; } + spin_unlock_irq (&parportlist_lock); /* Init our structure */ memset(tmp, 0, sizeof(struct parport)); @@ -296,6 +430,7 @@ tmp->ieee1284.phase = IEEE1284_PH_FWD_IDLE; init_MUTEX_LOCKED (&tmp->ieee1284.irq); /* actually a semaphore at 0 */ tmp->spintime = parport_default_spintime; + atomic_set (&tmp->ref_count, 1); name = kmalloc(15, GFP_KERNEL); if (!name) { @@ -372,27 +507,7 @@ #endif /* Let drivers know that a new port has arrived. */ - call_driver_chain (1, port); -} - -static void free_port (struct parport *port) -{ - int d; - for (d = 0; d < 5; d++) { - if (port->probe_info[d].class_name) - kfree (port->probe_info[d].class_name); - if (port->probe_info[d].mfr) - kfree (port->probe_info[d].mfr); - if (port->probe_info[d].model) - kfree (port->probe_info[d].model); - if (port->probe_info[d].cmdset) - kfree (port->probe_info[d].cmdset); - if (port->probe_info[d].description) - kfree (port->probe_info[d].description); - } - - kfree(port->name); - kfree(port); + attach_driver_chain (port); } /** @@ -421,7 +536,7 @@ port->ops = &dead_ops; /* Spread the word. */ - call_driver_chain (0, port); + detach_driver_chain (port); #ifdef CONFIG_PARPORT_1284 /* Forget the IEEE1284.3 topology of the port. */ @@ -431,7 +546,7 @@ spin_lock(&parportlist_lock); /* We are protected from other people changing the list, but - * they can see see it (using parport_enumerate). So be + * they can still see it (using parport_enumerate). So be * careful about the order of writes.. */ if (portlist == port) { if ((portlist = port->next) == NULL) @@ -449,8 +564,7 @@ spin_unlock(&parportlist_lock); /* Yes, parport_enumerate _is_ unsafe. Don't use it. */ - if (!port->devices) - free_port (port); + parport_put_port (port); } /** @@ -552,6 +666,7 @@ parport_register_device.. */ inc_parport_count(); port->ops->inc_use_count(); + parport_get_port (port); tmp = kmalloc(sizeof(struct pardevice), GFP_KERNEL); if (tmp == NULL) { @@ -623,6 +738,7 @@ out: dec_parport_count(); port->ops->dec_use_count(); + parport_put_port (port); return NULL; } @@ -636,7 +752,6 @@ void parport_unregister_device(struct pardevice *dev) { struct parport *port; - unsigned long flags; #ifdef PARPORT_PARANOID if (dev == NULL) { @@ -649,14 +764,11 @@ port = dev->port->physport; - read_lock_irqsave (&port->cad_lock, flags); if (port->cad == dev) { - read_unlock_irqrestore (&port->cad_lock, flags); printk(KERN_DEBUG "%s: %s forgot to release port\n", port->name, dev->name); parport_release (dev); } - read_unlock_irqrestore (&port->cad_lock, flags); spin_lock(&port->pardevice_lock); if (dev->next) @@ -676,11 +788,7 @@ dec_parport_count(); port->ops->dec_use_count(); - - /* If this was the last device on a port that's already gone away, - * free up the resources. */ - if (port->ops == &dead_ops && !port->devices) - free_port (port); + parport_put_port (port); /* Yes, that's right, someone _could_ still have a pointer to * port, if they used parport_enumerate. That's why they @@ -689,6 +797,56 @@ } /** + * parport_find_number - find a parallel port by number + * @number: parallel port number + * + * This returns the parallel port with the specified number, or + * %NULL if there is none. + * + * There is an implicit parport_get_port() done already; to throw + * away the reference to the port that parport_find_number() + * gives you, use parport_put_port(). + */ + +struct parport *parport_find_number (int number) +{ + struct parport *port, *result = NULL; + spin_lock (&parportlist_lock); + for (port = portlist; port; port = port->next) + if (port->number == number) { + result = parport_get_port (port); + break; + } + spin_unlock (&parportlist_lock); + return result; +} + +/** + * parport_find_base - find a parallel port by base address + * @base: base I/O address + * + * This returns the parallel port with the specified base + * address, or %NULL if there is none. + * + * There is an implicit parport_get_port() done already; to throw + * away the reference to the port that parport_find_base() + * gives you, use parport_put_port(). + */ + +struct parport *parport_find_base (unsigned long base) +{ + struct parport *port, *result = NULL; + spin_lock (&parportlist_lock); + for (port = portlist; port; port = port->next) + if (port->base == base) { + result = parport_get_port (port); + break; + } + spin_unlock (&parportlist_lock); + return result; +} + +/** * parport_claim - claim access to a parallel port device * @dev: pointer to structure representing a device on the port * @@ -706,14 +864,11 @@ struct parport *port = dev->port->physport; unsigned long flags; - read_lock_irqsave (&port->cad_lock, flags); if (port->cad == dev) { - read_unlock_irqrestore (&port->cad_lock, flags); printk(KERN_INFO "%s: %s already owner\n", dev->port->name,dev->name); return 0; } - read_unlock_irqrestore (&port->cad_lock, flags); /* Preempt any current device */ write_lock_irqsave (&port->cad_lock, flags); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c --- v2.4.0-test3/linux/drivers/pcmcia/ds.c Thu May 11 15:30:07 2000 +++ linux/drivers/pcmcia/ds.c Wed Jul 12 21:58:43 2000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -561,7 +562,6 @@ user = kmalloc(sizeof(user_info_t), GFP_KERNEL); if (!user) return -ENOMEM; - MOD_INC_USE_COUNT; user->event_tail = user->event_head = 0; user->next = s->user; user->user_magic = USER_MAGIC; @@ -584,10 +584,11 @@ DEBUG(0, "ds_release(socket %d)\n", i); if ((i >= sockets) || (sockets == 0)) return 0; + lock_kernel(); s = &socket_table[i]; user = file->private_data; if (CHECK_USER(user)) - return 0; + goto out; /* Unlink user data structure */ if ((file->f_flags & O_ACCMODE) != O_RDONLY) @@ -596,12 +597,12 @@ for (link = &s->user; *link; link = &(*link)->next) if (*link == user) break; if (link == NULL) - return 0; + goto out; *link = user->next; user->user_magic = 0; kfree(user); - - MOD_DEC_USE_COUNT; +out: + unlock_kernel(); return 0; } /* ds_release */ @@ -854,12 +855,13 @@ /*====================================================================*/ static struct file_operations ds_fops = { - open: ds_open, - release: ds_release, - ioctl: ds_ioctl, - read: ds_read, - write: ds_write, - poll: ds_poll, + owner: THIS_MODULE, + open: ds_open, + release: ds_release, + ioctl: ds_ioctl, + read: ds_read, + write: ds_write, + poll: ds_poll, }; EXPORT_SYMBOL(register_pccard_driver); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c --- v2.4.0-test3/linux/drivers/pnp/isapnp_proc.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/pnp/isapnp_proc.c Wed Jul 12 21:58:43 2000 @@ -187,10 +187,12 @@ if ((buffer = (isapnp_info_buffer_t *) file->private_data) == NULL) return -EINVAL; mode = file->f_flags & O_ACCMODE; + lock_kernel(); if (mode == O_WRONLY) isapnp_info_write(buffer); vfree(buffer->buffer); kfree(buffer); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/audio/audio.c linux/drivers/sbus/audio/audio.c --- v2.4.0-test3/linux/drivers/sbus/audio/audio.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sbus/audio/audio.c Wed Jul 12 21:58:43 2000 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1910,6 +1911,7 @@ struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >> SPARCAUDIO_DEVICE_SHIFT)]; + lock_kernel(); if (file->f_mode & FMODE_READ) { /* Stop input */ drv->ops->stop_input(drv); @@ -1951,11 +1953,13 @@ kill_procs(drv->sd_siglist,SIGPOLL,S_MSG); wake_up_interruptible(&drv->open_wait); + unlock_kernel(); return 0; } static struct file_operations sparcaudio_fops = { + owner: THIS_MODULE, llseek: sparcaudio_lseek, read: sparcaudio_read, write: sparcaudio_write, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/bpp.c linux/drivers/sbus/char/bpp.c --- v2.4.0-test3/linux/drivers/sbus/char/bpp.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sbus/char/bpp.c Wed Jul 12 21:58:43 2000 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -456,10 +457,13 @@ static int bpp_release(struct inode *inode, struct file *f) { unsigned minor = MINOR(inode->i_rdev); + + lock_kernel(); instances[minor].opened = 0; if (instances[minor].mode != COMPATIBILITY) terminate(minor); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/flash.c linux/drivers/sbus/char/flash.c --- v2.4.0-test3/linux/drivers/sbus/char/flash.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/sbus/char/flash.c Wed Jul 12 21:58:43 2000 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -37,23 +38,28 @@ unsigned long addr; unsigned long size; + lock_kernel(); if (flash.read_base == flash.write_base) { addr = flash.read_base; size = flash.read_size; } else { if ((vma->vm_flags & VM_READ) && - (vma->vm_flags & VM_WRITE)) + (vma->vm_flags & VM_WRITE)) { + unlock_kernel(); return -EINVAL; - + } if (vma->vm_flags & VM_READ) { addr = flash.read_base; size = flash.read_size; } else if (vma->vm_flags & VM_WRITE) { addr = flash.write_base; size = flash.write_size; - } else + } else { + unlock_kernel(); return -ENXIO; + } } + unlock_kernel(); if ((vma->vm_pgoff << PAGE_SHIFT) > size) return -ENXIO; @@ -121,7 +127,9 @@ static int flash_release(struct inode *inode, struct file *file) { + lock_kernel(); flash.busy = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/jsflash.c linux/drivers/sbus/char/jsflash.c --- v2.4.0-test3/linux/drivers/sbus/char/jsflash.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sbus/char/jsflash.c Wed Jul 12 21:58:43 2000 @@ -35,6 +35,7 @@ #include #include #include +#include /* * is controlled from the outside with these definitions. @@ -504,7 +505,9 @@ static int jsf_release(struct inode *inode, struct file *file) { + lock_kernel(); jsf0.busy = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c --- v2.4.0-test3/linux/drivers/sbus/char/pcikbd.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/sbus/char/pcikbd.c Wed Jul 12 21:58:43 2000 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -745,9 +746,10 @@ { unsigned long flags; + lock_kernel(); aux_fasync(-1, file, 0); if (--aux_count) - return 0; + goto out; spin_lock_irqsave(&pcikbd_lock, flags); @@ -760,6 +762,8 @@ poll_aux_status(); spin_unlock_irqrestore(&pcikbd_lock, flags); +out: + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/rtc.c linux/drivers/sbus/char/rtc.c --- v2.4.0-test3/linux/drivers/sbus/char/rtc.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/sbus/char/rtc.c Wed Jul 12 21:58:43 2000 @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -129,7 +130,9 @@ static int rtc_release(struct inode *inode, struct file *file) { + lock_kernel(); rtc_busy = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c --- v2.4.0-test3/linux/drivers/sbus/char/sunkbd.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/sbus/char/sunkbd.c Wed Jul 12 21:58:43 2000 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -1527,16 +1528,15 @@ static int kbd_close (struct inode *i, struct file *f) { - if (--kbd_active) - return 0; - - if (kbd_redirected) - kbd_table [kbd_redirected-1].kbdmode = VC_XLATE; - - kbd_redirected = 0; - kbd_opened = 0; - - kbd_fasync (-1, f, 0); + lock_kernel(); + if (!--kbd_active) { + if (kbd_redirected) + kbd_table [kbd_redirected-1].kbdmode = VC_XLATE; + kbd_redirected = 0; + kbd_opened = 0; + kbd_fasync (-1, f, 0); + } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/sunmouse.c linux/drivers/sbus/char/sunmouse.c --- v2.4.0-test3/linux/drivers/sbus/char/sunmouse.c Fri Jun 23 21:55:09 2000 +++ linux/drivers/sbus/char/sunmouse.c Wed Jul 12 21:58:43 2000 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -411,8 +412,10 @@ static int sun_mouse_close(struct inode *inode, struct file *file) { + lock_kernel(); sun_mouse_fasync (-1, file, 0); sunmouse.active--; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sbus/char/vfc_dev.c linux/drivers/sbus/char/vfc_dev.c --- v2.4.0-test3/linux/drivers/sbus/char/vfc_dev.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sbus/char/vfc_dev.c Wed Jul 12 21:58:43 2000 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -203,16 +204,19 @@ return 0; } -static void vfc_release(struct inode *inode,struct file *file) +static int vfc_release(struct inode *inode,struct file *file) { struct vfc_dev *dev; + lock_kernel(); dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); - if (dev == NULL) - return; - if (!dev->busy) - return; + if (!dev || !dev->busy) { + unlock_kernel(); + return -EINVAL; + } dev->busy = 0; + unlock_kernel(); + return 0; } static int vfc_debug(struct vfc_dev *dev, int cmd, unsigned long arg) @@ -606,10 +610,12 @@ unsigned int map_size, ret, map_offset; struct vfc_dev *dev; + lock_kernel(); dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); - if(dev == NULL) + if(dev == NULL) { + unlock_kernel(); return -ENODEV; - + } map_size = vma->vm_end - vma->vm_start; if(map_size > sizeof(struct vfc_regs)) map_size = sizeof(struct vfc_regs); @@ -619,6 +625,7 @@ map_offset = (unsigned int) (long)dev->phys_regs; ret = io_remap_page_range(vma->vm_start, map_offset, map_size, vma->vm_page_prot, dev->which_io); + unlock_kernel(); if(ret) return -EAGAIN; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c --- v2.4.0-test3/linux/drivers/scsi/hosts.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/scsi/hosts.c Tue Jul 11 11:17:45 2000 @@ -273,6 +273,10 @@ #include "esp.h" #endif +#ifdef CONFIG_SCSI_SGIWD93 +#include "sgiwd93.h" +#endif + #ifdef CONFIG_SCSI_QLOGICPTI #include "qlogicpti.h" #endif @@ -677,9 +681,15 @@ #ifdef CONFIG_SCSI_IMM IMM, #endif +#ifdef CONFIG_SCSI_SGIWD93 + SGIWD93_SCSI, +#endif +#ifdef CONFIG_JAZZ_ESP + SCSI_JAZZ_ESP, +#endif #ifdef CONFIG_SUN3X_ESP SCSI_SUN3X_ESP, -#endif +#endif #ifdef CONFIG_SCSI_DEBUG SCSI_DEBUG, #endif diff -u --recursive --new-file v2.4.0-test3/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c --- v2.4.0-test3/linux/drivers/scsi/scsi_scan.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/scsi/scsi_scan.c Wed Jul 12 16:31:15 2000 @@ -138,6 +138,10 @@ {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, {"TOSHIBA","CDROM","*", BLIST_ISROM}, {"MegaRAID", "LD", "*", BLIST_FORCELUN}, + {"DGC", "RAID", "*", BLIST_SPARSELUN}, // Dell PV 650F (tgt @ LUN 0) + {"DGC", "DISK", "*", BLIST_SPARSELUN}, // Dell PV 650F (no tgt @ LUN 0) + {"DELL", "PV530F", "*", BLIST_SPARSELUN}, // Dell PV 530F + {"SONY", "TSL", "*", BLIST_FORCELUN}, // DDS3 & DDS4 autoloaders /* * Must be at end of list... diff -u --recursive --new-file v2.4.0-test3/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c --- v2.4.0-test3/linux/drivers/scsi/sg.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/scsi/sg.c Wed Jul 12 21:58:43 2000 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -304,8 +305,6 @@ if (sdp->device->host->hostt->module) __MOD_INC_USE_COUNT(sdp->device->host->hostt->module); - if (sg_template.module) - __MOD_INC_USE_COUNT(sg_template.module); return 0; } @@ -315,8 +314,11 @@ Sg_device * sdp; Sg_fd * sfp; - if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp))) + lock_kernel(); + if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp))) { + unlock_kernel(); return -ENXIO; + } SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev))); sg_fasync(-1, filp, 0); /* remove filp from async notification list */ sg_remove_sfp(sdp, sfp); @@ -325,10 +327,9 @@ if (sdp->device->host->hostt->module) __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module); - if(sg_template.module) - __MOD_DEC_USE_COUNT(sg_template.module); sdp->exclude = 0; wake_up_interruptible(&sdp->o_excl_wait); + unlock_kernel(); return 0; } @@ -1094,13 +1095,14 @@ } static struct file_operations sg_fops = { - read: sg_read, - write: sg_write, - poll: sg_poll, - ioctl: sg_ioctl, - open: sg_open, - release: sg_release, - fasync: sg_fasync, + owner: THIS_MODULE, + read: sg_read, + write: sg_write, + poll: sg_poll, + ioctl: sg_ioctl, + open: sg_open, + release: sg_release, + fasync: sg_fasync, }; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/scsi/sgiwd93.c linux/drivers/scsi/sgiwd93.c --- v2.4.0-test3/linux/drivers/scsi/sgiwd93.c Sat Feb 26 22:31:48 2000 +++ linux/drivers/scsi/sgiwd93.c Tue Jul 11 11:17:45 2000 @@ -7,7 +7,7 @@ * * (In all truth, Jed Schimmel wrote all this code.) * - * $Id: sgiwd93.c,v 1.20 2000/02/21 15:05:48 ralf Exp $ + * $Id: sgiwd93.c,v 1.19 2000/02/04 07:40:47 ralf Exp $ */ #include #include @@ -234,7 +234,7 @@ #endif } -void sgiwd93_reset(uchar *base) +void sgiwd93_reset(unsigned long base) { struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) base; @@ -275,7 +275,7 @@ SGIblows->proc_name = "SGIWD93"; sgiwd93_host = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); - sgiwd93_host->base = (unsigned char *) hregs; + sgiwd93_host->base = (unsigned long) hregs; sgiwd93_host->irq = SGI_WD93_0_IRQ; buf = (uchar *) get_free_page(GFP_KERNEL); @@ -294,7 +294,7 @@ /* set up second controller on the Indigo2 */ if(!sgi_guiness) { sgiwd93_host1 = scsi_register(SGIblows, sizeof(struct WD33C93_hostdata)); - sgiwd93_host1->base = (unsigned char *) hregs1; + sgiwd93_host1->base = (unsigned long) hregs1; sgiwd93_host1->irq = SGI_WD93_1_IRQ; buf = (uchar *) get_free_page(GFP_KERNEL); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/scsi/sgiwd93.h linux/drivers/scsi/sgiwd93.h --- v2.4.0-test3/linux/drivers/scsi/sgiwd93.h Sat Feb 26 22:31:48 2000 +++ linux/drivers/scsi/sgiwd93.h Tue Jul 11 11:17:45 2000 @@ -1,4 +1,4 @@ -/* $Id: sgiwd93.h,v 1.6 2000/01/29 01:42:18 ralf Exp $ +/* $Id: sgiwd93.h,v 1.5 1998/08/25 09:18:50 ralf Exp $ * sgiwd93.h: SGI WD93 scsi definitions. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.4.0-test3/linux/drivers/scsi/st.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/scsi/st.c Wed Jul 12 21:58:43 2000 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -620,8 +621,6 @@ if (STp->device->host->hostt->module) __MOD_INC_USE_COUNT(STp->device->host->hostt->module); - if (st_template.module) - __MOD_INC_USE_COUNT(st_template.module); if (mode != STp->current_mode) { DEBC(printk(ST_DEB_MSG "st%d: Mode change from %d to %d.\n", @@ -859,8 +858,6 @@ STp->in_use = 0; if (STp->device->host->hostt->module) __MOD_DEC_USE_COUNT(STp->device->host->hostt->module); - if (st_template.module) - __MOD_DEC_USE_COUNT(st_template.module); return retval; } @@ -995,6 +992,7 @@ int dev; dev = TAPE_NR(devt); + lock_kernel(); read_lock(&st_dev_arr_lock); STp = scsi_tapes[dev]; read_unlock(&st_dev_arr_lock); @@ -1010,8 +1008,7 @@ STp->in_use = 0; if (STp->device->host->hostt->module) __MOD_DEC_USE_COUNT(STp->device->host->hostt->module); - if (st_template.module) - __MOD_DEC_USE_COUNT(st_template.module); + unlock_kernel(); return result; } @@ -3428,6 +3425,7 @@ static struct file_operations st_fops = { + owner: THIS_MODULE, read: st_read, write: st_write, ioctl: st_ioctl, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sgi/char/ds1286.c linux/drivers/sgi/char/ds1286.c --- v2.4.0-test3/linux/drivers/sgi/char/ds1286.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sgi/char/ds1286.c Wed Jul 12 21:58:43 2000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -354,7 +355,9 @@ static int ds1286_release(struct inode *inode, struct file *file) { + lock_kernel(); ds1286_status &= ~RTC_IS_OPEN; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c --- v2.4.0-test3/linux/drivers/sgi/char/graphics.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sgi/char/graphics.c Wed Jul 12 21:58:43 2000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "gconsole.h" #include "graphics.h" @@ -194,6 +195,7 @@ int board = GRAPHICS_CARD (inode->i_rdev); /* Tell the rendering manager that one client is going away */ + lock_kernel(); rrm_close (inode, file); /* Was this file handle from the board owner?, clear it */ @@ -203,6 +205,7 @@ (*cards [board].g_reset_console)(); enable_gconsole (); } + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c --- v2.4.0-test3/linux/drivers/sgi/char/shmiq.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sgi/char/shmiq.c Wed Jul 12 21:58:43 2000 @@ -329,9 +329,12 @@ size = vma->vm_end - vma->vm_start; start = vma->vm_start; + lock_kernel(); mem = (unsigned long) shmiqs [minor].shmiq_vaddr = vmalloc_uncached (size); - if (!mem) + if (!mem) { + unlock_kernel(); return -EINVAL; + } /* Prevent the swapper from considering these pages for swap and touching them */ vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO); @@ -345,6 +348,7 @@ shmiqs [minor].tail = 0; /* Init the shared memory input queue */ memset (shmiqs [minor].shmiq_vaddr, 0, size); + unlock_kernel(); return error; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sgi/char/streamable.c linux/drivers/sgi/char/streamable.c --- v2.4.0-test3/linux/drivers/sgi/char/streamable.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sgi/char/streamable.c Wed Jul 12 21:58:43 2000 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -50,20 +51,6 @@ /* /dev/gfx device */ static int -sgi_gfx_open (struct inode *inode, struct file *file) -{ - printk ("GFX: Opened by %d\n", current->pid); - return 0; -} - -static int -sgi_gfx_close (struct inode *inode, struct file *file) -{ - printk ("GFX: Closed by %d\n", current->pid); - return 0; -} - -static int sgi_gfx_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { printk ("GFX: ioctl 0x%x %ld called\n", cmd, arg); @@ -73,8 +60,6 @@ struct file_operations sgi_gfx_fops = { ioctl: sgi_gfx_ioctl, - open: sgi_gfx_open, - release: sgi_gfx_close, }; static struct miscdevice dev_gfx = { @@ -236,7 +221,9 @@ static int sgi_mouse_close (struct inode *inode, struct file *filp) { + lock_kernel(); mouse_opened = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sgi/char/usema.c linux/drivers/sgi/char/usema.c --- v2.4.0-test3/linux/drivers/sgi/char/usema.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sgi/char/usema.c Wed Jul 12 21:58:43 2000 @@ -163,17 +163,10 @@ return 0; } -static int -sgi_usemaclone_release(struct inode *inode, struct file *filp) -{ - return 0; -} - struct file_operations sgi_usemaclone_fops = { poll: sgi_usemaclone_poll, ioctl: sgi_usemaclone_ioctl, open: sgi_usemaclone_open, - release: sgi_usemaclone_release, }; static struct miscdevice dev_usemaclone = { diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/Makefile linux/drivers/sound/Makefile --- v2.4.0-test3/linux/drivers/sound/Makefile Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/Makefile Tue Jul 11 12:50:50 2000 @@ -47,7 +47,7 @@ obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_MAD16) += mad16.o ad1848.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_CS4232) += cs4232.o uart401.o -obj-$(CONFIG_SOUND_OPL3SA2) += opl3sa2.o ad1848.o uart401.o mpu401.o +obj-$(CONFIG_SOUND_OPL3SA2) += opl3sa2.o ad1848.o mpu401.o obj-$(CONFIG_SOUND_MSS) += ad1848.o obj-$(CONFIG_SOUND_PAS) += pas2.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c --- v2.4.0-test3/linux/drivers/sound/cmpci.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sound/cmpci.c Wed Jul 12 21:58:43 2000 @@ -114,6 +114,7 @@ #include #include #include +#include #include #include @@ -1397,29 +1398,35 @@ { struct cm_state *s = (struct cm_state *)file->private_data; struct dmabuf *db; - int ret; + int ret = -EINVAL; unsigned long size; VALIDATE_STATE(s); + lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf(s, 1)) != 0) - return ret; + goto out; db = &s->dma_dac; } else if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf(s, 0)) != 0) - return ret; + goto out; db = &s->dma_adc; } else - return -EINVAL; + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; db->mapped = 1; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int cm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -1771,6 +1778,7 @@ struct cm_state *s = (struct cm_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); @@ -1785,6 +1793,7 @@ s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); up(&s->open_sem); wake_up(&s->open_wait); + unlock_kernel(); return 0; } @@ -2021,6 +2030,7 @@ VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) { __set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->midi.owait, &wait); @@ -2058,6 +2068,7 @@ spin_unlock_irqrestore(&s->lock, flags); up(&s->open_sem); wake_up(&s->open_wait); + unlock_kernel(); return 0; } @@ -2212,6 +2223,7 @@ unsigned int regb; VALIDATE_STATE(s); + lock_kernel(); down(&s->open_sem); s->open_mode &= ~FMODE_DMFM; for (regb = 0xb0; regb < 0xb9; regb++) { @@ -2222,6 +2234,7 @@ } up(&s->open_sem); wake_up(&s->open_wait); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/dmasound/dmasound_core.c linux/drivers/sound/dmasound/dmasound_core.c --- v2.4.0-test3/linux/drivers/sound/dmasound/dmasound_core.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/dmasound/dmasound_core.c Wed Jul 12 21:58:43 2000 @@ -111,6 +111,7 @@ #include #include #include +#include #include @@ -501,8 +502,10 @@ static int mixer_release(struct inode *inode, struct file *file) { + lock_kernel(); mixer.busy = 0; dmasound.mach.release(); + unlock_kernel(); return 0; } static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, @@ -905,6 +908,7 @@ { int rc = 0; + lock_kernel(); if (write_sq.busy) rc = sq_fsync(file, file->f_dentry); dmasound.soft = dmasound.dsp; @@ -923,6 +927,7 @@ /* Wake up a process waiting for the queue being released. * Note: There may be several processes waiting for a call * to open() returning. */ + unlock_kernel(); return rc; } @@ -1141,8 +1146,10 @@ static int state_release(struct inode *inode, struct file *file) { + lock_kernel(); state.busy = 0; dmasound.mach.release(); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/emu10k1/audio.c linux/drivers/sound/emu10k1/audio.c --- v2.4.0-test3/linux/drivers/sound/emu10k1/audio.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/emu10k1/audio.c Wed Jul 12 21:58:43 2000 @@ -36,6 +36,8 @@ #include "cardwi.h" #include "recmgr.h" #include "audio.h" +#include +#include static void calculate_ofrag(struct woinst *); static void calculate_ifrag(struct wiinst *); @@ -890,6 +892,7 @@ if (vma_get_pgoff(vma) != 0) return -ENXIO; + lock_kernel(); if (vma->vm_flags & VM_WRITE) { struct woinst *woinst = wave_dev->woinst; struct wave_out *wave_out; @@ -907,6 +910,7 @@ if (emu10k1_waveout_open(wave_dev) != CTSTATUS_SUCCESS) { spin_unlock_irqrestore(&woinst->lock, flags); ERROR(); + unlock_kernel(); return -EINVAL; } @@ -921,12 +925,14 @@ if (size > (PAGE_SIZE * wave_out->wavexferbuf->numpages)) { spin_unlock_irqrestore(&woinst->lock, flags); + unlock_kernel(); return -EINVAL; } for (i = 0; i < wave_out->wavexferbuf->numpages; i++) { if (remap_page_range(vma->vm_start + (i * PAGE_SIZE), virt_to_phys(wave_out->pagetable[i]), PAGE_SIZE, vma->vm_page_prot)) { spin_unlock_irqrestore(&woinst->lock, flags); + unlock_kernel(); return -EAGAIN; } } @@ -944,6 +950,7 @@ wiinst->mapped = 1; spin_unlock_irqrestore(&wiinst->lock, flags); } + unlock_kernel(); return 0; } @@ -1098,9 +1105,11 @@ static int emu10k1_audio_release(struct inode *inode, struct file *file) { struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data; - struct emu10k1_card *card = wave_dev->card; + struct emu10k1_card *card; unsigned long flags; + lock_kernel(); + card = wave_dev->card; DPF(2, "emu10k1_audio_release()\n"); if (file->f_mode & FMODE_WRITE) { @@ -1171,6 +1180,7 @@ kfree(wave_dev); wake_up_interruptible(&card->open_wait); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/emu10k1/midi.c linux/drivers/sound/emu10k1/midi.c --- v2.4.0-test3/linux/drivers/sound/emu10k1/midi.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/emu10k1/midi.c Wed Jul 12 21:58:43 2000 @@ -32,6 +32,8 @@ #define __NO_VERSION__ #include +#include +#include #include #include "hwaccess.h" @@ -183,8 +185,10 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file) { struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data; - struct emu10k1_card *card = midi_dev->card; + struct emu10k1_card *card; + lock_kernel(); + card = midi_dev->card; DPF(2, "emu10k1_midi_release()\n"); if (file->f_mode & FMODE_WRITE) { @@ -227,6 +231,7 @@ card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE)); up(&card->open_sem); wake_up_interruptible(&card->open_wait); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c --- v2.4.0-test3/linux/drivers/sound/es1370.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/es1370.c Wed Jul 12 21:58:43 2000 @@ -149,6 +149,7 @@ #include #include #include +#include #include #include #include @@ -1306,24 +1307,38 @@ unsigned long size; VALIDATE_STATE(s); + lock_kernel(); if (vma->vm_flags & VM_WRITE) { - if ((ret = prog_dmabuf_dac2(s)) != 0) + if ((ret = prog_dmabuf_dac2(s)) != 0) { + unlock_kernel(); return ret; + } db = &s->dma_dac2; } else if (vma->vm_flags & VM_READ) { - if ((ret = prog_dmabuf_adc(s)) != 0) + if ((ret = prog_dmabuf_adc(s)) != 0) { + unlock_kernel(); return ret; + } db = &s->dma_adc; - } else + } else { + unlock_kernel(); return -EINVAL; - if (vma->vm_pgoff != 0) + } + if (vma->vm_pgoff != 0) { + unlock_kernel(); return -EINVAL; + } size = vma->vm_end - vma->vm_start; - if (size > (PAGE_SIZE << db->buforder)) + if (size > (PAGE_SIZE << db->buforder)) { + unlock_kernel(); return -EINVAL; - if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) + } + if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) { + unlock_kernel(); return -EAGAIN; + } db->mapped = 1; + unlock_kernel(); return 0; } @@ -1717,6 +1732,7 @@ struct es1370_state *s = (struct es1370_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac2(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); @@ -1733,6 +1749,7 @@ wake_up(&s->open_wait); up(&s->open_sem); return 0; + unlock_kernel(); } static /*const*/ struct file_operations es1370_audio_fops = { @@ -1850,17 +1867,23 @@ VALIDATE_STATE(s); if (!(vma->vm_flags & VM_WRITE)) return -EINVAL; + lock_kernel(); if ((ret = prog_dmabuf_dac1(s)) != 0) - return ret; + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << s->dma_dac1.buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; s->dma_dac1.mapped = 1; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -2122,6 +2145,7 @@ struct es1370_state *s = (struct es1370_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); drain_dac1(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); stop_dac1(s); @@ -2129,6 +2153,7 @@ s->open_mode &= ~FMODE_DAC; wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } @@ -2366,6 +2391,7 @@ VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) { add_wait_queue(&s->midi.owait, &wait); for (;;) { @@ -2399,6 +2425,7 @@ spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c --- v2.4.0-test3/linux/drivers/sound/es1371.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/es1371.c Wed Jul 12 21:58:43 2000 @@ -121,6 +121,7 @@ #include #include #include +#include #include #include #include @@ -1494,24 +1495,38 @@ unsigned long size; VALIDATE_STATE(s); + lock_kernel(); if (vma->vm_flags & VM_WRITE) { - if ((ret = prog_dmabuf_dac2(s)) != 0) + if ((ret = prog_dmabuf_dac2(s)) != 0) { + unlock_kernel(); return ret; + } db = &s->dma_dac2; } else if (vma->vm_flags & VM_READ) { - if ((ret = prog_dmabuf_adc(s)) != 0) + if ((ret = prog_dmabuf_adc(s)) != 0) { + unlock_kernel(); return ret; + } db = &s->dma_adc; - } else + } else { + unlock_kernel(); return -EINVAL; - if (vma->vm_pgoff != 0) + } + if (vma->vm_pgoff != 0) { + unlock_kernel(); return -EINVAL; + } size = vma->vm_end - vma->vm_start; - if (size > (PAGE_SIZE << db->buforder)) + if (size > (PAGE_SIZE << db->buforder)) { + unlock_kernel(); return -EINVAL; - if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) + } + if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) { + unlock_kernel(); return -EAGAIN; + } db->mapped = 1; + unlock_kernel(); return 0; } @@ -1903,6 +1918,7 @@ struct es1371_state *s = (struct es1371_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac2(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); @@ -1917,6 +1933,7 @@ s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); up(&s->open_sem); wake_up(&s->open_wait); + unlock_kernel(); return 0; } @@ -2035,17 +2052,23 @@ VALIDATE_STATE(s); if (!(vma->vm_flags & VM_WRITE)) return -EINVAL; + lock_kernel(); if ((ret = prog_dmabuf_dac1(s)) != 0) - return ret; + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << s->dma_dac1.buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(s->dma_dac1.rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; s->dma_dac1.mapped = 1; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -2297,6 +2320,7 @@ struct es1371_state *s = (struct es1371_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); drain_dac1(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); stop_dac1(s); @@ -2304,6 +2328,7 @@ s->open_mode &= ~FMODE_DAC; up(&s->open_sem); wake_up(&s->open_wait); + unlock_kernel(); return 0; } @@ -2540,6 +2565,7 @@ unsigned count, tmo; VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) { add_wait_queue(&s->midi.owait, &wait); for (;;) { @@ -2573,6 +2599,7 @@ spin_unlock_irqrestore(&s->lock, flags); up(&s->open_sem); wake_up(&s->open_wait); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c --- v2.4.0-test3/linux/drivers/sound/esssolo1.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sound/esssolo1.c Wed Jul 12 21:58:43 2000 @@ -90,6 +90,7 @@ #include #include #include +#include #include #include @@ -1192,29 +1193,35 @@ { struct solo1_state *s = (struct solo1_state *)file->private_data; struct dmabuf *db; - int ret; + int ret = -EINVAL; unsigned long size; VALIDATE_STATE(s); + lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf_dac(s)) != 0) - return ret; + goto out; db = &s->dma_dac; } else if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf_adc(s)) != 0) - return ret; + goto out; db = &s->dma_adc; } else - return -EINVAL; + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; db->mapped = 1; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int solo1_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -1510,6 +1517,7 @@ struct solo1_state *s = (struct solo1_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); @@ -1527,6 +1535,7 @@ s->open_mode &= ~(FMODE_READ | FMODE_WRITE); wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } @@ -1881,6 +1890,7 @@ VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) { add_wait_queue(&s->midi.owait, &wait); for (;;) { @@ -1914,6 +1924,7 @@ spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } @@ -2083,6 +2094,7 @@ unsigned int regb; VALIDATE_STATE(s); + lock_kernel(); down(&s->open_sem); s->open_mode &= ~FMODE_DMFM; for (regb = 0xb0; regb < 0xb9; regb++) { @@ -2094,6 +2106,7 @@ release_region(s->sbbase, FMSYNTH_EXTENT); wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c --- v2.4.0-test3/linux/drivers/sound/i810_audio.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sound/i810_audio.c Wed Jul 12 21:58:43 2000 @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -1227,29 +1228,34 @@ { struct i810_state *state = (struct i810_state *)file->private_data; struct dmabuf *dmabuf = &state->dmabuf; - int ret; + int ret = -EINVAL; unsigned long size; + lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf(state, 0)) != 0) - return ret; + goto out; } else if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf(state, 1)) != 0) - return ret; + goto out; } else - return -EINVAL; + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << dmabuf->buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; dmabuf->mapped = 1; - - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -1608,6 +1614,7 @@ struct i810_state *state = (struct i810_state *)file->private_data; struct dmabuf *dmabuf = &state->dmabuf; + lock_kernel(); if (file->f_mode & FMODE_WRITE) { i810_clear_tail(state); drain_dac(state, file->f_flags & O_NONBLOCK); @@ -1632,6 +1639,7 @@ kfree(state->card->states[state->virt]); state->card->states[state->virt] = NULL; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/maestro.c linux/drivers/sound/maestro.c --- v2.4.0-test3/linux/drivers/sound/maestro.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/maestro.c Wed Jul 12 21:58:43 2000 @@ -197,6 +197,8 @@ #include #include +#include +#include #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) @@ -2422,13 +2424,14 @@ { struct ess_state *s = (struct ess_state *)file->private_data; struct dmabuf *db; - int ret; + int ret = -EINVAL; unsigned long size; VALIDATE_STATE(s); + lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf(s, 1)) != 0) - return ret; + goto out; db = &s->dma_dac; } else #if 0 @@ -2436,20 +2439,25 @@ we can turn this back on. */ if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf(s, 0)) != 0) - return ret; + goto out; db = &s->dma_adc; } else #endif - return -EINVAL; + goto out; + ret = -EINVAL; if (SILLY_OFFSET(vma) != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; db->mapped = 1; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int ess_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -2985,6 +2993,7 @@ struct ess_state *s = (struct ess_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); @@ -3006,6 +3015,7 @@ } up(&s->open_sem); wake_up(&s->open_wait); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/msnd.h linux/drivers/sound/msnd.h --- v2.4.0-test3/linux/drivers/sound/msnd.h Fri Jan 21 18:19:17 2000 +++ linux/drivers/sound/msnd.h Wed Jul 12 21:58:43 2000 @@ -160,13 +160,6 @@ # define inb inb_p #endif -#ifdef LINUX20 -# define __initfunc(f) f -# define __initdata /* nothing */ -# define spin_lock_irqsave(junk,flags) do { save_flags(flags); cli(); } while (0) -# define spin_unlock_irqrestore(junk,flags) do { restore_flags(flags); } while (0) -#endif - /* JobQueueStruct */ #define JQS_wStart 0x00 #define JQS_wSize 0x02 @@ -236,9 +229,7 @@ wait_queue_head_t writeblock; wait_queue_head_t readblock; wait_queue_head_t writeflush; -#ifndef LINUX20 spinlock_t lock; -#endif int nresets; unsigned long recsrc; int left_levels[16]; @@ -250,8 +241,6 @@ int rec_sample_size, rec_sample_rate, rec_channels; int rec_ndelay; BYTE bCurrentMidiPatch; - void (*inc_ref)(void); - void (*dec_ref)(void); /* Digital audio FIFOs */ msnd_fifo DAPF, DARF; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c --- v2.4.0-test3/linux/drivers/sound/msnd_pinnacle.c Thu Feb 10 17:11:14 2000 +++ linux/drivers/sound/msnd_pinnacle.c Wed Jul 12 21:58:43 2000 @@ -35,16 +35,12 @@ #include #include -#if LINUX_VERSION_CODE < 0x020101 -# define LINUX20 -#endif #include #include #include #include -#ifndef LINUX20 -# include -#endif +#include +#include #include #include #include "sound_config.h" @@ -747,16 +743,6 @@ set_default_rec_audio_parameters(); } -static void mod_inc_ref(void) -{ - MOD_INC_USE_COUNT; -} - -static void mod_dec_ref(void) -{ - MOD_DEC_USE_COUNT; -} - static int dev_open(struct inode *inode, struct file *file) { int minor = MINOR(inode->i_rdev); @@ -789,43 +775,23 @@ } else err = -EINVAL; - if (err >= 0) - mod_inc_ref(); - return err; } -#ifdef LINUX20 -static void dev_release(struct inode *inode, struct file *file) -#else static int dev_release(struct inode *inode, struct file *file) -#endif { int minor = MINOR(inode->i_rdev); -#ifndef LINUX20 int err = 0; -#endif - if (minor == dev.dsp_minor) { -#ifndef LINUX20 - err = -#endif - dsp_release(file); - } + lock_kernel(); + if (minor == dev.dsp_minor) + err = dsp_release(file); else if (minor == dev.mixer_minor) { /* nothing */ - } -#ifndef LINUX20 - else + } else err = -EINVAL; - - if (err >= 0) -#endif - mod_dec_ref(); - -#ifndef LINUX20 + unlock_kernel(); return err; -#endif } static __inline__ int pack_DARQ_to_DARF(register int bank) @@ -1002,30 +968,18 @@ return len - count; } -#ifdef LINUX20 -static int dev_read(struct inode *inode, struct file *file, char *buf, int count) -{ - int minor = MINOR(inode->i_rdev); -#else static ssize_t dev_read(struct file *file, char *buf, size_t count, loff_t *off) { int minor = MINOR(file->f_dentry->d_inode->i_rdev); -#endif if (minor == dev.dsp_minor) return dsp_read(buf, count); else return -EINVAL; } -#ifdef LINUX20 -static int dev_write(struct inode *inode, struct file *file, const char *buf, int count) -{ - int minor = MINOR(inode->i_rdev); -#else static ssize_t dev_write(struct file *file, const char *buf, size_t count, loff_t *off) { int minor = MINOR(file->f_dentry->d_inode->i_rdev); -#endif if (minor == dev.dsp_minor) return dsp_write(buf, count); else @@ -1042,15 +996,8 @@ if (pack_DAPF_to_DAPQ(0) <= 0) { if (!test_bit(F_WRITEBLOCK, &dev.flags)) { -#ifdef LINUX20 - if (test_bit(F_WRITEFLUSH, &dev.flags)) { - clear_bit(F_WRITEFLUSH, &dev.flags); - wake_up_interruptible(&dev.writeflush); - } -#else if (test_and_clear_bit(F_WRITEFLUSH, &dev.flags)) wake_up_interruptible(&dev.writeflush); -#endif } clear_bit(F_WRITING, &dev.flags); } @@ -1122,6 +1069,7 @@ } static struct file_operations dev_fileops = { + owner: THIS_MODULE, read: dev_read, write: dev_write, ioctl: dev_ioctl, @@ -1881,8 +1829,6 @@ dev.recsrc = 0; dev.dspq_data_buff = DSPQ_DATA_BUFF; dev.dspq_buff_size = DSPQ_BUFF_SIZE; - dev.inc_ref = mod_inc_ref; - dev.dec_ref = mod_dec_ref; if (write_ndelay == -1) write_ndelay = CONFIG_MSND_WRITE_NDELAY; if (write_ndelay) @@ -1898,9 +1844,7 @@ init_waitqueue_head(&dev.writeflush); msnd_fifo_init(&dev.DAPF); msnd_fifo_init(&dev.DARF); -#ifndef LINUX20 spin_lock_init(&dev.lock); -#endif printk(KERN_INFO LOGNAME ": %u byte audio FIFOs (x2)\n", dev.fifosize); if ((err = msnd_fifo_alloc(&dev.DAPF, dev.fifosize)) < 0) { printk(KERN_ERR LOGNAME ": Couldn't allocate write FIFO\n"); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c --- v2.4.0-test3/linux/drivers/sound/sonicvibes.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sound/sonicvibes.c Wed Jul 12 21:58:43 2000 @@ -108,6 +108,7 @@ #include #include #include +#include #include #include @@ -1509,29 +1510,35 @@ { struct sv_state *s = (struct sv_state *)file->private_data; struct dmabuf *db; - int ret; + int ret = -EINVAL; unsigned long size; VALIDATE_STATE(s); + lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf(s, 1)) != 0) - return ret; + goto out; db = &s->dma_dac; } else if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf(s, 0)) != 0) - return ret; + goto out; db = &s->dma_adc; } else - return -EINVAL; + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << db->buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; db->mapped = 1; - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int sv_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -1907,6 +1914,7 @@ struct sv_state *s = (struct sv_state *)file->private_data; VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) drain_dac(s, file->f_flags & O_NONBLOCK); down(&s->open_sem); @@ -1921,6 +1929,7 @@ s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } @@ -2167,6 +2176,7 @@ VALIDATE_STATE(s); + lock_kernel(); if (file->f_mode & FMODE_WRITE) { add_wait_queue(&s->midi.owait, &wait); for (;;) { @@ -2200,6 +2210,7 @@ spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } @@ -2363,6 +2374,7 @@ unsigned int regb; VALIDATE_STATE(s); + lock_kernel(); down(&s->open_sem); s->open_mode &= ~FMODE_DMFM; for (regb = 0xb0; regb < 0xb9; regb++) { @@ -2373,6 +2385,7 @@ } wake_up(&s->open_wait); up(&s->open_sem); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c --- v2.4.0-test3/linux/drivers/sound/soundcard.c Mon Jul 10 16:47:24 2000 +++ linux/drivers/sound/soundcard.c Wed Jul 12 21:58:43 2000 @@ -270,6 +270,7 @@ { int dev = MINOR(inode->i_rdev); + lock_kernel(); DEB(printk("sound_release(dev=%d)\n", dev)); switch (dev & 0x0f) { case SND_DEV_CTL: @@ -297,6 +298,7 @@ notifier_call_chain(&sound_locker, 0, 0); lock_depth--; + unlock_kernel(); return 0; } @@ -449,29 +451,35 @@ printk(KERN_ERR "Sound: mmap() not supported for other than audio devices\n"); return -EINVAL; } + lock_kernel(); if (vma->vm_flags & VM_WRITE) /* Map write and read/write to the output buf */ dmap = audio_devs[dev]->dmap_out; else if (vma->vm_flags & VM_READ) dmap = audio_devs[dev]->dmap_in; else { printk(KERN_ERR "Sound: Undefined mmap() access\n"); + unlock_kernel(); return -EINVAL; } if (dmap == NULL) { printk(KERN_ERR "Sound: mmap() error. dmap == NULL\n"); + unlock_kernel(); return -EIO; } if (dmap->raw_buf == NULL) { printk(KERN_ERR "Sound: mmap() called when raw_buf == NULL\n"); + unlock_kernel(); return -EIO; } if (dmap->mapping_flags) { printk(KERN_ERR "Sound: mmap() called twice for the same DMA buffer\n"); + unlock_kernel(); return -EIO; } if (vma->vm_pgoff != 0) { printk(KERN_ERR "Sound: mmap() offset must be 0.\n"); + unlock_kernel(); return -EINVAL; } size = vma->vm_end - vma->vm_start; @@ -481,8 +489,10 @@ } if (remap_page_range(vma->vm_start, virt_to_phys(dmap->raw_buf), vma->vm_end - vma->vm_start, - vma->vm_page_prot)) + vma->vm_page_prot)) { + unlock_kernel(); return -EAGAIN; + } dmap->mapping_flags |= DMA_MAP_MAPPED; @@ -492,6 +502,7 @@ memset(dmap->raw_buf, dmap->neutral_byte, dmap->bytes_in_use); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/trident.c linux/drivers/sound/trident.c --- v2.4.0-test3/linux/drivers/sound/trident.c Mon Jul 10 16:47:25 2000 +++ linux/drivers/sound/trident.c Thu Jul 13 09:37:48 2000 @@ -107,6 +107,7 @@ #include #include #include +#include #include #include #include @@ -1560,30 +1561,35 @@ { struct trident_state *state = (struct trident_state *)file->private_data; struct dmabuf *dmabuf = &state->dmabuf; - int ret; + int ret = -EINVAL; unsigned long size; VALIDATE_STATE(state); + lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf(state, 0)) != 0) - return ret; + goto out; } else if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf(state, 1)) != 0) - return ret; - } else - return -EINVAL; + goto out; + } else + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; size = vma->vm_end - vma->vm_start; if (size > (PAGE_SIZE << dmabuf->buforder)) - return -EINVAL; + goto out; + ret = -EAGAIN; if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf), size, vma->vm_page_prot)) - return -EAGAIN; + goto out; dmabuf->mapped = 1; - - return 0; + ret = 0; +out: + unlock_kernel(); + return ret; } static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -2009,9 +2015,12 @@ static int trident_release(struct inode *inode, struct file *file) { struct trident_state *state = (struct trident_state *)file->private_data; - struct trident_card *card = state->card; - struct dmabuf *dmabuf = &state->dmabuf; + struct trident_card *card; + struct dmabuf *dmabuf; + lock_kernel(); + card = state->card; + dmabuf = &state->dmabuf; VALIDATE_STATE(state); if (file->f_mode & FMODE_WRITE) { @@ -2038,6 +2047,7 @@ /* we're covered by the open_sem */ up(&card->open_sem); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/via82cxxx_audio.c linux/drivers/sound/via82cxxx_audio.c --- v2.4.0-test3/linux/drivers/sound/via82cxxx_audio.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/via82cxxx_audio.c Wed Jul 12 21:58:43 2000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -2207,6 +2208,7 @@ card = file->private_data; assert (card != NULL); + lock_kernel(); if (file->f_mode & FMODE_READ) via_chan_free (card, &card->ch_in); @@ -2220,6 +2222,7 @@ spin_unlock_irqrestore (&card->lock, flags); wake_up (&card->open_wait); + unlock_kernel(); DPRINTK("EXIT, returning 0\n"); return 0; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/vwsnd.c linux/drivers/sound/vwsnd.c --- v2.4.0-test3/linux/drivers/sound/vwsnd.c Wed Apr 26 16:34:08 2000 +++ linux/drivers/sound/vwsnd.c Wed Jul 12 21:58:43 2000 @@ -84,10 +84,9 @@ * Locking Notes * * INC_USE_COUNT and DEC_USE_COUNT keep track of the number of - * open descriptors to this driver. When the driver is compiled - * as a module, they call MOD_{INC,DEC}_USE_COUNT; otherwise they - * bump vwsnd_use_count. The global device list, vwsnd_dev_list, - * is immutable when the IN_USE is true. + * open descriptors to this driver. They store it in vwsnd_use_count. + * The global device list, vwsnd_dev_list, is immutable when the IN_USE + * is true. * * devc->open_lock is a semaphore that is used to enforce the * single reader/single writer rule for /dev/audio. The rule is @@ -141,6 +140,7 @@ #include #include #include +#include #include #include #include @@ -1517,22 +1517,12 @@ static vwsnd_dev_t *vwsnd_dev_list; /* linked list of all devices */ -#ifdef MODULE - -# define INC_USE_COUNT MOD_INC_USE_COUNT -# define DEC_USE_COUNT MOD_DEC_USE_COUNT -# define IN_USE MOD_IN_USE - -#else - static atomic_t vwsnd_use_count = ATOMIC_INIT(0); # define INC_USE_COUNT (atomic_inc(&vwsnd_use_count)) # define DEC_USE_COUNT (atomic_dec(&vwsnd_use_count)) # define IN_USE (atomic_read(&vwsnd_use_count) != 0) -#endif - /* * Lithium can only DMA multiples of 32 bytes. Its DMA buffer may * be up to 8 Kb. This driver always uses 8 Kb. @@ -2998,6 +2988,7 @@ vwsnd_port_t *wport = NULL, *rport = NULL; int err = 0; + lock_kernel(); down(&devc->io_sema); { DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); @@ -3023,13 +3014,14 @@ } up(&devc->open_sema); wake_up(&devc->open_wait); - DBGDO(if (IN_USE)) /* see hack in vwsnd_mixer_release() */ - DEC_USE_COUNT; + DEC_USE_COUNT; DBGR(); + unlock_kernel(); return err; } static struct file_operations vwsnd_audio_fops = { + owner: THIS_MODULE, llseek: vwsnd_audio_llseek, read: vwsnd_audio_read, write: vwsnd_audio_write, @@ -3069,15 +3061,7 @@ static int vwsnd_mixer_release(struct inode *inode, struct file *file) { DBGEV("(inode=0x%p, file=0x%p)\n", inode, file); - - /* - * hack -- opening/closing the mixer device zeroes use count - * so driver can be unloaded. - * Use only while debugging module, and then use it carefully. - */ - - DBGDO(while (IN_USE)) - DEC_USE_COUNT; + DEC_USE_COUNT; return 0; } @@ -3234,6 +3218,7 @@ } static struct file_operations vwsnd_mixer_fops = { + owner: THIS_MODULE, llseek: vwsnd_mixer_llseek, ioctl: vwsnd_mixer_ioctl, open: vwsnd_mixer_open, @@ -3429,8 +3414,6 @@ DBGE("()\n"); - if (IN_USE) - return -EBUSY; devcp = &vwsnd_dev_list; while ((devc = *devcp)) { if (devc->audio_minor == hw_config->slots[0]) { diff -u --recursive --new-file v2.4.0-test3/linux/drivers/sound/wavfront.c linux/drivers/sound/wavfront.c --- v2.4.0-test3/linux/drivers/sound/wavfront.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/sound/wavfront.c Wed Jul 12 21:58:43 2000 @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -1959,8 +1960,10 @@ static int wavefront_release(struct inode *inode, struct file *file) { + lock_kernel(); dev.opened = 0; dev.debug = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/telephony/ixj.c linux/drivers/telephony/ixj.c --- v2.4.0-test3/linux/drivers/telephony/ixj.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/telephony/ixj.c Wed Jul 12 21:58:43 2000 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -1056,6 +1057,7 @@ if (ixjdebug > 0) printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev)); + lock_kernel(); daa_set_mode(board, SOP_PU_SLEEP); ixj_set_port(board, PORT_POTS); aec_stop(board); @@ -1189,6 +1191,7 @@ j->rec_frame_size = j->play_frame_size = 0; ixj_fasync(-1, file_p, 0); // remove from list of async notification + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/Config.in linux/drivers/usb/Config.in --- v2.4.0-test3/linux/drivers/usb/Config.in Mon Jul 10 16:47:25 2000 +++ linux/drivers/usb/Config.in Wed Jul 12 20:07:39 2000 @@ -28,6 +28,9 @@ comment 'USB Devices' dep_tristate ' USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB dep_tristate ' USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI + fi dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND dep_tristate ' USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB dep_tristate ' USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB @@ -68,7 +71,6 @@ dep_tristate ' USB ADMtek Pegasus-based device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB dep_tristate ' D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV - dep_tristate ' Microtek X6USB scanner support (EXPERIMENTAL)' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB fi diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/audio.c linux/drivers/usb/audio.c --- v2.4.0-test3/linux/drivers/usb/audio.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/audio.c Wed Jul 12 21:58:43 2000 @@ -171,6 +171,7 @@ #include #include #include +#include #include #include #include @@ -1944,10 +1945,13 @@ static int usb_audio_release_mixdev(struct inode *inode, struct file *file) { struct usb_mixerdev *ms = (struct usb_mixerdev *)file->private_data; - struct usb_audio_state *s = ms->state; + struct usb_audio_state *s; + lock_kernel(); + s = ms->state; down(&open_sem); release(s); + unlock_kernel(); return 0; } @@ -2283,23 +2287,28 @@ { struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; struct dmabuf *db; - int ret; + int ret = -EINVAL; + lock_kernel(); if (vma->vm_flags & VM_WRITE) { if ((ret = prog_dmabuf_out(as)) != 0) - return ret; + goto out; db = &as->usbout.dma; } else if (vma->vm_flags & VM_READ) { if ((ret = prog_dmabuf_in(as)) != 0) - return ret; + goto out; db = &as->usbin.dma; } else - return -EINVAL; + goto out; + ret = -EINVAL; if (vma->vm_pgoff != 0) - return -EINVAL; + goto out; - return dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot); + ret = dmabuf_mmap(db, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot); +out: + unlock_kernel(); + return ret; } static int usb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -2615,10 +2624,13 @@ static int usb_audio_release(struct inode *inode, struct file *file) { struct usb_audiodev *as = (struct usb_audiodev *)file->private_data; - struct usb_audio_state *s = as->state; - struct usb_device *dev = s->usbdev; + struct usb_audio_state *s; + struct usb_device *dev; struct usb_interface *iface; + lock_kernel(); + s = as->state; + dev = s->usbdev; if (file->f_mode & FMODE_WRITE) drain_out(as, file->f_flags & O_NONBLOCK); down(&open_sem); @@ -2643,6 +2655,7 @@ as->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); release(s); wake_up(&open_wait); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/bluetooth.c linux/drivers/usb/bluetooth.c --- v2.4.0-test3/linux/drivers/usb/bluetooth.c Mon Jul 10 16:47:25 2000 +++ linux/drivers/usb/bluetooth.c Tue Jul 11 19:03:13 2000 @@ -1,11 +1,15 @@ /* - * bluetooth.c Version 0.1 + * bluetooth.c Version 0.2 * * Copyright (c) 2000 Greg Kroah-Hartman * * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B * * + * (07/11/2000) Version 0.2 gkh + * Fixed a small bug found by Nils Faerber in the usb_bluetooth_probe + * function. + * * (07/09/2000) Version 0.1 gkh * Initial release. Has support for sending ACL data (which is really just * a HCI frame.) Raw HCI commands and HCI events are not supported. @@ -33,7 +37,6 @@ */ -#include #include #include #include @@ -620,6 +623,7 @@ memset(bluetooth, 0, sizeof(struct usb_bluetooth)); + bluetooth->magic = USB_BLUETOOTH_MAGIC; bluetooth->dev = dev; bluetooth->minor = minor; bluetooth->tqueue.routine = bluetooth_softint; @@ -676,6 +680,8 @@ /* initialize the devfs nodes for this device and let the user know what bluetooths we are bound to */ tty_register_devfs (&bluetooth_tty_driver, 0, minor); info("Bluetooth converter now attached to ttyBLUE%d (or usb/ttblue/%d for devfs)", minor, minor); + + bluetooth_table[minor] = bluetooth; return bluetooth; /* success */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/dabusb.c linux/drivers/usb/dabusb.c --- v2.4.0-test3/linux/drivers/usb/dabusb.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/dabusb.c Wed Jul 12 21:58:43 2000 @@ -38,6 +38,7 @@ #include #include #include +#include #include "dabusb.h" #include "dabfirmware.h" @@ -613,6 +614,7 @@ dbg("dabusb_release"); + lock_kernel(); down (&s->mutex); dabusb_stop (s); dabusb_free_buffers (s); @@ -626,6 +628,7 @@ wake_up (&s->remove_ok); s->opened = 0; + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c --- v2.4.0-test3/linux/drivers/usb/dc2xx.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/dc2xx.c Wed Jul 12 21:58:43 2000 @@ -60,6 +60,7 @@ #include #undef DEBUG #include +#include @@ -298,10 +299,12 @@ kfree (camera->buf); /* If camera was unplugged with open file ... */ + lock_kernel(); if (!camera->dev) { minor_data [camera->subminor] = NULL; kfree (camera); } + unlock_kernel(); dbg ("close"); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/devices.c linux/drivers/usb/devices.c --- v2.4.0-test3/linux/drivers/usb/devices.c Wed Apr 26 16:34:08 2000 +++ linux/drivers/usb/devices.c Wed Jul 12 17:27:36 2000 @@ -45,6 +45,9 @@ * up an eventual usbd * 2000-01-04: Thomas Sailer * Turned into its own filesystem + * 2000-07-05: Ashley Montanaro + * Converted file reading routine to dump to buffer once + * per device, not per bus * * $Id: devices.c,v 1.5 2000/01/11 13:58:21 tom Exp $ */ @@ -367,23 +370,40 @@ /*****************************************************************/ -static char *usb_device_dump(char *start, char *end, struct usb_device *usbdev, - struct usb_bus *bus, int level, int index, int count) +/* This is a recursive function. Parameters: + * buffer - the user-space buffer to write data into + * nbytes - the maximum number of bytes to write + * skip_bytes - the number of bytes to skip before writing anything + * file_offset - the offset into the devices file on completion + */ +static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset, + struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count) { int chix; - int cnt = 0; + int ret, cnt = 0; int parent_devnum = 0; - + char *pages_start, *data_end; + unsigned int length; + ssize_t total_written = 0; + + /* don't bother with anything else if we're not writing any data */ + if (*nbytes <= 0) + return 0; + if (level > MAX_TOPO_LEVEL) - return start; + return total_written; + /* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */ + if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1))) + return -ENOMEM; + if (usbdev->parent && usbdev->parent->devnum != -1) parent_devnum = usbdev->parent->devnum; /* * So the root hub's parent is 0 and any device that is * plugged into the root hub has a parent of 0. */ - start += sprintf(start, format_topo, bus->busnum, level, parent_devnum, index, count, - usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild); + data_end = pages_start + sprintf(pages_start, format_topo, bus->busnum, level, parent_devnum, index, count, + usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild); /* * level = topology-tier level; * parent_devnum = parent device number; @@ -392,30 +412,58 @@ */ /* If this is the root hub, display the bandwidth information */ if (level == 0) - start += sprintf(start, format_bandwidth, bus->bandwidth_allocated, + data_end += sprintf(data_end, format_bandwidth, bus->bandwidth_allocated, FRAME_TIME_MAX_USECS_ALLOC, (100 * bus->bandwidth_allocated + FRAME_TIME_MAX_USECS_ALLOC / 2) / FRAME_TIME_MAX_USECS_ALLOC, bus->bandwidth_int_reqs, bus->bandwidth_isoc_reqs); - start = usb_dump_desc(start, end, usbdev); - if (start > end) - return start + sprintf(start, "(truncated)\n"); + + data_end = usb_dump_desc(data_end, pages_start + (2 * PAGE_SIZE) - 256, usbdev); + + if (data_end > (pages_start + (2 * PAGE_SIZE) - 256)) + data_end += sprintf(data_end, "(truncated)\n"); + + length = data_end - pages_start; + /* if we can start copying some data to the user */ + if (length > *skip_bytes) { + length -= *skip_bytes; + if (length > *nbytes) + length = *nbytes; + if (copy_to_user(*buffer, pages_start + *skip_bytes, length)) { + free_pages((unsigned long)pages_start, 1); + + if (total_written == 0) + return -EFAULT; + return total_written; + } + *nbytes -= length; + *file_offset += length; + total_written += length; + *buffer += length; + *skip_bytes = 0; + } else + *skip_bytes -= length; + + free_pages((unsigned long)pages_start, 1); + /* Now look at all of this device's children. */ for (chix = 0; chix < usbdev->maxchild; chix++) { - if (start > end) - return start; - if (usbdev->children[chix]) - start = usb_device_dump(start, end, usbdev->children[chix], bus, level + 1, chix, ++cnt); + if (usbdev->children[chix]) { + ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, usbdev->children[chix], + bus, level + 1, chix, ++cnt); + if (ret == -EFAULT) + return total_written; + total_written += ret; + } } - return start; + return total_written; } static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos) { struct list_head *buslist; struct usb_bus *bus; - char *page, *end; - ssize_t ret = 0; - unsigned int pos, len; + ssize_t ret, total_written = 0; + loff_t skip_bytes = *ppos; if (*ppos < 0) return -EINVAL; @@ -423,34 +471,18 @@ return 0; if (!access_ok(VERIFY_WRITE, buf, nbytes)) return -EFAULT; - if (!(page = (char*) __get_free_pages(GFP_KERNEL,1))) - return -ENOMEM; - pos = *ppos; + /* enumerate busses */ for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) { /* print devices for this bus */ bus = list_entry(buslist, struct usb_bus, bus_list); - end = usb_device_dump(page, page + (2*PAGE_SIZE - 256), bus->root_hub, bus, 0, 0, 0); - len = end - page; - if (len > pos) { - len -= pos; - if (len > nbytes) - len = nbytes; - if (copy_to_user(buf, page + pos, len)) { - if (!ret) - ret = -EFAULT; - break; - } - nbytes -= len; - buf += len; - ret += len; - pos = 0; - *ppos += len; - } else - pos -= len; + /* recurse through all children of the root hub */ + ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0); + if (ret < 0) + return ret; + total_written += ret; } - free_pages((unsigned long)page, 1); - return ret; + return total_written; } /* Kernel lock for "lastev" protection */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/evdev.c linux/drivers/usb/evdev.c --- v2.4.0-test3/linux/drivers/usb/evdev.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/evdev.c Wed Jul 12 21:58:43 2000 @@ -37,6 +37,7 @@ #include #include #include +#include struct evdev { int exist; @@ -91,8 +92,10 @@ static int evdev_release(struct inode * inode, struct file * file) { struct evdev_list *list = file->private_data; - struct evdev_list **listptr = &list->evdev->list; + struct evdev_list **listptr; + lock_kernel(); + listptr = &list->evdev->list; evdev_fasync(-1, file, 0); while (*listptr && (*listptr != list)) @@ -110,6 +113,7 @@ } kfree(list); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/hub.c linux/drivers/usb/hub.c --- v2.4.0-test3/linux/drivers/usb/hub.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/hub.c Tue Jul 11 10:46:06 2000 @@ -588,6 +588,8 @@ * so get rid of all our resources */ exit_files(current); /* daemonize doesn't do exit_files */ + current->files = init_task.files; + atomic_inc(¤t->files->count); daemonize(); /* Setup a nice name */ diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/joydev.c linux/drivers/usb/joydev.c --- v2.4.0-test3/linux/drivers/usb/joydev.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/joydev.c Wed Jul 12 21:58:43 2000 @@ -44,6 +44,7 @@ #include #include #include +#include #define JOYDEV_MINOR_BASE 0 #define JOYDEV_MINORS 32 @@ -160,8 +161,10 @@ static int joydev_release(struct inode * inode, struct file * file) { struct joydev_list *list = file->private_data; - struct joydev_list **listptr = &list->joydev->list; + struct joydev_list **listptr; + lock_kernel(); + listptr = &list->joydev->list; joydev_fasync(-1, file, 0); while (*listptr && (*listptr != list)) @@ -179,6 +182,7 @@ } kfree(list); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/mdc800.c linux/drivers/usb/mdc800.c --- v2.4.0-test3/linux/drivers/usb/mdc800.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/mdc800.c Wed Jul 12 21:58:43 2000 @@ -76,6 +76,7 @@ #include #include #include +#include #include @@ -582,6 +583,7 @@ int retval=0; dbg ("Mustek MDC800 device closed."); + lock_kernel(); if (mdc800->open && (mdc800->state != NOT_CONNECTED)) { mdc800->open=0; @@ -593,6 +595,7 @@ { retval=-EIO; } + unlock_kernel(); return retval; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/mousedev.c linux/drivers/usb/mousedev.c --- v2.4.0-test3/linux/drivers/usb/mousedev.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/mousedev.c Wed Jul 12 21:58:43 2000 @@ -38,6 +38,7 @@ #include #include #include +#include #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024 @@ -159,8 +160,10 @@ static int mousedev_release(struct inode * inode, struct file * file) { struct mousedev_list *list = file->private_data; - struct mousedev_list **listptr = &list->mousedev->list; + struct mousedev_list **listptr; + lock_kernel(); + listptr = &list->mousedev->list; mousedev_fasync(-1, file, 0); while (*listptr && (*listptr != list)) @@ -197,6 +200,7 @@ } kfree(list); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/ov511.c linux/drivers/usb/ov511.c --- v2.4.0-test3/linux/drivers/usb/ov511.c Mon Jul 10 16:47:25 2000 +++ linux/drivers/usb/ov511.c Tue Jul 11 10:46:38 2000 @@ -30,7 +30,7 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -static const char version[] = "1.18"; +static const char version[] = "1.19"; #define __NO_VERSION__ @@ -98,6 +98,9 @@ * programs that expect RGB data (e.g. gqcam) to work with this driver. */ static int force_rgb = 0; +/* Number of seconds before inactive buffers are deallocated */ +static int buf_timeout = 5; + MODULE_PARM(autoadjust, "i"); MODULE_PARM(debug, "i"); MODULE_PARM(fix_rgb_offset, "i"); @@ -106,6 +109,7 @@ MODULE_PARM(i2c_detect_tries, "i"); MODULE_PARM(aperture, "i"); MODULE_PARM(force_rgb, "i"); +MODULE_PARM(buf_timeout, "i"); MODULE_AUTHOR("Mark McClelland & Bret Wallach & Orion Sky Lawlor & Kevin Moore & Charl P. Botha & Claudio Matsuoka "); MODULE_DESCRIPTION("OV511 USB Camera Driver"); @@ -132,6 +136,7 @@ { -1, NULL } }; +#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) static struct palette_list plist[] = { { VIDEO_PALETTE_GREY, "GREY" }, { VIDEO_PALETTE_HI240, "HI240" }, @@ -151,6 +156,7 @@ { VIDEO_PALETTE_YUV410P,"YUV410P" }, { -1, NULL } }; +#endif /********************************************************************** * @@ -432,7 +438,7 @@ PDEBUG(5, "reg write: 0x%02X:0x%02X, 0x%x", reg, value, rc); if (rc < 0) - err("ov511_reg_write: error %d", rc); + err("reg write: error %d", rc); return rc; } @@ -452,7 +458,7 @@ PDEBUG(5, "reg read: 0x%02X:0x%02X", reg, buffer[0]); if (rc < 0) { - err("ov511_reg_read: error %d", rc); + err("reg read: error %d", rc); return rc; } else { return buffer[0]; @@ -501,7 +507,7 @@ return 0; error: - err("ov511_i2c_write: error %d", rc); + err("i2c write: error %d", rc); return rc; } @@ -573,7 +579,7 @@ return value; error: - err("ov511_i2c_read: error %d", rc); + err("i2c read: error %d", rc); return rc; } @@ -601,7 +607,7 @@ return 0; error: - err("ov511_write_regvals: error %d", rc); + err("write regvals: error %d", rc); return rc; } @@ -699,11 +705,8 @@ if (ov511->bridge == BRG_OV511) { if (size == 0) alt = OV511_ALT_SIZE_0; else if (size == 257) alt = OV511_ALT_SIZE_257; -// else if (size == 512) alt = OV511_ALT_SIZE_512; else if (size == 513) alt = OV511_ALT_SIZE_513; -// else if (size == 768) alt = OV511_ALT_SIZE_768; else if (size == 769) alt = OV511_ALT_SIZE_769; -// else if (size == 992) alt = OV511_ALT_SIZE_992; else if (size == 993) alt = OV511_ALT_SIZE_993; else { err("Set packet size: invalid size (%d)", size); @@ -1673,7 +1676,7 @@ static int ov511_init_isoc(struct usb_ov511 *ov511) { urb_t *urb; - int fx, err; + int fx, err, n; PDEBUG(3, "*** Initializing capture ***"); @@ -1689,55 +1692,37 @@ else err("invalid bridge type"); - /* We double buffer the Iso lists */ - urb = usb_alloc_urb(FRAMES_PER_DESC); + for (n = 0; n < OV511_NUMSBUF; n++) { + urb = usb_alloc_urb(FRAMES_PER_DESC); - if (!urb) { - err("ov511_init_isoc: usb_alloc_urb ret. NULL"); - return -ENOMEM; - } - ov511->sbuf[0].urb = urb; - urb->dev = ov511->dev; - urb->context = ov511; - urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS); - urb->transfer_flags = USB_ISO_ASAP; - urb->transfer_buffer = ov511->sbuf[0].data; - urb->complete = ov511_isoc_irq; - urb->number_of_packets = FRAMES_PER_DESC; - urb->transfer_buffer_length = ov511->packet_size * FRAMES_PER_DESC; - for (fx = 0; fx < FRAMES_PER_DESC; fx++) { - urb->iso_frame_desc[fx].offset = ov511->packet_size * fx; - urb->iso_frame_desc[fx].length = ov511->packet_size; - } - - urb = usb_alloc_urb(FRAMES_PER_DESC); - if (!urb) { - err("ov511_init_isoc: usb_alloc_urb ret. NULL"); - return -ENOMEM; - } - ov511->sbuf[1].urb = urb; - urb->dev = ov511->dev; - urb->context = ov511; - urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS); - urb->transfer_flags = USB_ISO_ASAP; - urb->transfer_buffer = ov511->sbuf[1].data; - urb->complete = ov511_isoc_irq; - urb->number_of_packets = FRAMES_PER_DESC; - urb->transfer_buffer_length = ov511->packet_size * FRAMES_PER_DESC; - for (fx = 0; fx < FRAMES_PER_DESC; fx++) { - urb->iso_frame_desc[fx].offset = ov511->packet_size * fx; - urb->iso_frame_desc[fx].length = ov511->packet_size; + if (!urb) { + err("init isoc: usb_alloc_urb ret. NULL"); + return -ENOMEM; + } + ov511->sbuf[n].urb = urb; + urb->dev = ov511->dev; + urb->context = ov511; + urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS); + urb->transfer_flags = USB_ISO_ASAP; + urb->transfer_buffer = ov511->sbuf[n].data; + urb->complete = ov511_isoc_irq; + urb->number_of_packets = FRAMES_PER_DESC; + urb->transfer_buffer_length = ov511->packet_size * FRAMES_PER_DESC; + for (fx = 0; fx < FRAMES_PER_DESC; fx++) { + urb->iso_frame_desc[fx].offset = ov511->packet_size * fx; + urb->iso_frame_desc[fx].length = ov511->packet_size; + } } - ov511->sbuf[1].urb->next = ov511->sbuf[0].urb; - ov511->sbuf[0].urb->next = ov511->sbuf[1].urb; - - err = usb_submit_urb(ov511->sbuf[0].urb); - if (err) - err("ov511_init_isoc: usb_submit_urb(0) ret %d", err); - err = usb_submit_urb(ov511->sbuf[1].urb); - if (err) - err("ov511_init_isoc: usb_submit_urb(1) ret %d", err); + ov511->sbuf[OV511_NUMSBUF - 1].urb->next = ov511->sbuf[0].urb; + for (n = 0; n < OV511_NUMSBUF - 1; n++) + ov511->sbuf[n].urb->next = ov511->sbuf[n+1].urb; + + for (n = 0; n < OV511_NUMSBUF; n++) { + err = usb_submit_urb(ov511->sbuf[n].urb); + if (err) + err("init isoc: usb_submit_urb(%d) ret %d", n, err); + } ov511->streaming = 1; @@ -1746,6 +1731,8 @@ static void ov511_stop_isoc(struct usb_ov511 *ov511) { + int n; + if (!ov511->streaming || !ov511->dev) return; @@ -1756,17 +1743,13 @@ ov511->streaming = 0; /* Unschedule all of the iso td's */ - if (ov511->sbuf[1].urb) { - ov511->sbuf[1].urb->next = NULL; - usb_unlink_urb(ov511->sbuf[1].urb); - usb_free_urb(ov511->sbuf[1].urb); - ov511->sbuf[1].urb = NULL; - } - if (ov511->sbuf[0].urb) { - ov511->sbuf[0].urb->next = NULL; - usb_unlink_urb(ov511->sbuf[0].urb); - usb_free_urb(ov511->sbuf[0].urb); - ov511->sbuf[0].urb = NULL; + for (n = OV511_NUMSBUF - 1; n >= 0; n--) { + if (ov511->sbuf[n].urb) { + ov511->sbuf[n].urb->next = NULL; + usb_unlink_urb(ov511->sbuf[n].urb); + usb_free_urb(ov511->sbuf[n].urb); + ov511->sbuf[n].urb = NULL; + } } } @@ -1818,6 +1801,127 @@ /**************************************************************************** * + * Buffer management + * + ***************************************************************************/ +static int ov511_alloc(struct usb_ov511 *ov511) +{ + int i; + + PDEBUG(4, "entered"); + down(&ov511->buf_lock); + + if (ov511->buf_state == BUF_PEND_DEALLOC) { + ov511->buf_state = BUF_ALLOCATED; + del_timer(&ov511->buf_timer); + } + + if (ov511->buf_state == BUF_ALLOCATED) + goto out; + + ov511->fbuf = rvmalloc(OV511_NUMFRAMES * MAX_DATA_SIZE); + if (!ov511->fbuf) + goto error; + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov511->frame[i].grabstate = FRAME_UNUSED; + ov511->frame[i].data = ov511->fbuf + i * MAX_DATA_SIZE; + PDEBUG(4, "frame[%d] @ %p", i, ov511->frame[i].data); + + ov511->sbuf[i].data = kmalloc(FRAMES_PER_DESC * + MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL); + if (!ov511->sbuf[i].data) { + while (--i) { + kfree(ov511->sbuf[i].data); + ov511->sbuf[i].data = NULL; + } + rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE); + ov511->fbuf = NULL; + goto error; + } + PDEBUG(4, "sbuf[%d] @ %p", i, ov511->sbuf[i].data); + } + ov511->buf_state = BUF_ALLOCATED; +out: + up(&ov511->buf_lock); + PDEBUG(4, "leaving"); + return 0; +error: + ov511->buf_state = BUF_NOT_ALLOCATED; + up(&ov511->buf_lock); + PDEBUG(4, "errored"); + return -ENOMEM; +} + +/* + * - You must acquire buf_lock before entering this function. + * - Because this code will free any non-null pointer, you must be sure to null + * them if you explicitly free them somewhere else! + */ +static void ov511_do_dealloc(struct usb_ov511 *ov511) +{ + int i; + PDEBUG(4, "entered"); + + if (ov511->fbuf) { + rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE); + ov511->fbuf = NULL; + } + + for (i = 0; i < OV511_NUMFRAMES; i++) { + if (ov511->sbuf[i].data) { + kfree(ov511->sbuf[i].data); + ov511->sbuf[i].data = NULL; + } + } + + PDEBUG(4, "buffer memory deallocated"); + ov511->buf_state = BUF_NOT_ALLOCATED; + PDEBUG(4, "leaving"); +} + +static void ov511_buf_callback(unsigned long data) +{ + struct usb_ov511 *ov511 = (struct usb_ov511 *)data; + PDEBUG(4, "entered"); + down(&ov511->buf_lock); + + if (ov511->buf_state == BUF_PEND_DEALLOC) + ov511_do_dealloc(ov511); + + up(&ov511->buf_lock); + PDEBUG(4, "leaving"); +} + +static void ov511_dealloc(struct usb_ov511 *ov511, int now) +{ + struct timer_list *bt = &(ov511->buf_timer); + PDEBUG(4, "entered"); + down(&ov511->buf_lock); + + PDEBUG(4, "deallocating buffer memory %s", now ? "now" : "later"); + + if (ov511->buf_state == BUF_PEND_DEALLOC) { + ov511->buf_state = BUF_ALLOCATED; + del_timer(bt); + } + + if (now) + ov511_do_dealloc(ov511); + else { + ov511->buf_state = BUF_PEND_DEALLOC; + init_timer(bt); + bt->function = ov511_buf_callback; + bt->data = (unsigned long)ov511; + bt->expires = jiffies + buf_timeout * HZ; + add_timer(bt); + } + up(&ov511->buf_lock); + PDEBUG(4, "leaving"); +} + +/**************************************************************************** + * * V4L API * ***************************************************************************/ @@ -1825,7 +1929,7 @@ static int ov511_open(struct video_device *dev, int flags) { struct usb_ov511 *ov511 = (struct usb_ov511 *)dev; - int i, err = 0; + int err = 0; MOD_INC_USE_COUNT; PDEBUG(4, "opening"); @@ -1836,33 +1940,16 @@ goto out; err = -ENOMEM; - - /* Allocate memory for the frame buffers */ - ov511->fbuf = rvmalloc(OV511_NUMFRAMES * MAX_DATA_SIZE); - if (!ov511->fbuf) + if (ov511_alloc(ov511)) goto out; ov511->sub_flag = 0; - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov511->frame[i].grabstate = FRAME_UNUSED; - ov511->frame[i].data = ov511->fbuf + i * MAX_DATA_SIZE; - PDEBUG(4, "frame [%d] @ %p", i, ov511->frame[0].data); - - ov511->sbuf[i].data = kmalloc(FRAMES_PER_DESC * - MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL); - if (!ov511->sbuf[i].data) { -open_free_ret: - while (--i) kfree(ov511->sbuf[i].data); - rvfree(ov511->fbuf, 2 * MAX_DATA_SIZE); - goto out; - } - PDEBUG(4, "sbuf[%d] @ %p", i, ov511->sbuf[i].data); - } - err = ov511_init_isoc(ov511); - if (err) - goto open_free_ret; + if (err) { + ov511_dealloc(ov511, 0); + goto out; + } ov511->user++; @@ -1878,7 +1965,6 @@ static void ov511_close(struct video_device *dev) { struct usb_ov511 *ov511 = (struct usb_ov511 *)dev; - int i; PDEBUG(4, "ov511_close"); @@ -1887,15 +1973,13 @@ ov511_stop_isoc(ov511); - rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE); - for (i = 0; i < OV511_NUMFRAMES; i++) - kfree(ov511->sbuf[i].data); - + ov511_dealloc(ov511, 0); up(&ov511->lock); if (!ov511->dev) { video_unregister_device(&ov511->vdev); kfree(ov511); + ov511 = NULL; } MOD_DEC_USE_COUNT; @@ -2118,8 +2202,8 @@ struct video_mbuf vm; memset(&vm, 0, sizeof(vm)); - vm.size = 2 * MAX_DATA_SIZE; - vm.frames = 2; + vm.size = OV511_NUMFRAMES * MAX_DATA_SIZE; + vm.frames = OV511_NUMFRAMES; vm.offsets[0] = 0; vm.offsets[1] = MAX_FRAME_SIZE + sizeof (struct timeval); @@ -2329,7 +2413,7 @@ frame->bytes_read = 0; err("** ick! ** Errored frame %d", ov511->curframe); if (ov511_new_frame(ov511, frmx)) - err("ov511_read: ov511_new_frame error"); + err("read: ov511_new_frame error"); goto restart; } @@ -2531,15 +2615,24 @@ /* Reset the 76xx */ if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1; +#if 1 /* Maybe this will fix detection problems? MM */ + /* Wait for it to initialize */ + schedule_timeout (1 + 150 * HZ / 1000); +#endif + for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { if ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) == 0x7F) && - (ov511_i2c_read(dev, OV7610_REG_ID_LOW) == 0xA2)) + (ov511_i2c_read(dev, OV7610_REG_ID_LOW) == 0xA2)) { success = 1; + continue; + } - /* Dummy read to sync I2C */ - if (ov511_i2c_read(dev, 0x00) < 0) return -1; + /* Reset the 76xx */ + if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1; /* Wait for it to initialize */ schedule_timeout (1 + 150 * HZ / 1000); + /* Dummy read to sync I2C */ + if (ov511_i2c_read(dev, 0x00) < 0) return -1; } if (success) { @@ -2647,8 +2740,9 @@ memcpy(&ov511->vdev, &ov511_template, sizeof(ov511_template)); - init_waitqueue_head(&ov511->frame[0].wq); - init_waitqueue_head(&ov511->frame[1].wq); + for (i = 0; i < OV511_NUMFRAMES; i++) + init_waitqueue_head(&ov511->frame[i].wq); + init_waitqueue_head(&ov511->wq); if (video_register_device(&ov511->vdev, VFL_TYPE_GRABBER) == -1) { @@ -2790,6 +2884,8 @@ if (!ov511_configure(ov511)) { ov511->user = 0; init_MUTEX(&ov511->lock); /* to 1 == available */ + init_MUTEX(&ov511->buf_lock); + ov511->buf_state = BUF_NOT_ALLOCATED; } else { err("Failed to configure camera"); goto error; @@ -2812,6 +2908,7 @@ static void ov511_disconnect(struct usb_device *dev, void *ptr) { struct usb_ov511 *ov511 = (struct usb_ov511 *) ptr; + int n; MOD_INC_USE_COUNT; @@ -2823,38 +2920,37 @@ &ov511->dev->actconfig->interface[ov511->iface]); ov511->dev = NULL; - ov511->frame[0].grabstate = FRAME_ERROR; - ov511->frame[1].grabstate = FRAME_ERROR; + for (n = 0; n < OV511_NUMFRAMES; n++) + ov511->frame[n].grabstate = FRAME_ERROR; + ov511->curframe = -1; /* This will cause the process to request another frame */ - if (waitqueue_active(&ov511->frame[0].wq)) - wake_up_interruptible(&ov511->frame[0].wq); - if (waitqueue_active(&ov511->frame[1].wq)) - wake_up_interruptible(&ov511->frame[1].wq); + for (n = 0; n < OV511_NUMFRAMES; n++) + if (waitqueue_active(&ov511->frame[n].wq)) + wake_up_interruptible(&ov511->frame[n].wq); if (waitqueue_active(&ov511->wq)) wake_up_interruptible(&ov511->wq); ov511->streaming = 0; /* Unschedule all of the iso td's */ - if (ov511->sbuf[1].urb) { - ov511->sbuf[1].urb->next = NULL; - usb_unlink_urb(ov511->sbuf[1].urb); - usb_free_urb(ov511->sbuf[1].urb); - ov511->sbuf[1].urb = NULL; - } - if (ov511->sbuf[0].urb) { - ov511->sbuf[0].urb->next = NULL; - usb_unlink_urb(ov511->sbuf[0].urb); - usb_free_urb(ov511->sbuf[0].urb); - ov511->sbuf[0].urb = NULL; + for (n = OV511_NUMSBUF - 1; n >= 0; n--) { + if (ov511->sbuf[n].urb) { + ov511->sbuf[n].urb->next = NULL; + usb_unlink_urb(ov511->sbuf[n].urb); + usb_free_urb(ov511->sbuf[n].urb); + ov511->sbuf[n].urb = NULL; + } } #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) destroy_proc_ov511_cam(ov511); #endif + /* FIXME - is this correct/safe? Should we acquire ov511->lock? */ + ov511_dealloc(ov511, 1); + /* Free the memory */ if (ov511 && !ov511->user) { kfree(ov511); @@ -2895,7 +2991,7 @@ static void __exit usb_ov511_exit(void) { usb_deregister(&ov511_driver); - info("ov511 driver deregistered"); + info("driver deregistered"); #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) proc_ov511_destroy(); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/ov511.h linux/drivers/usb/ov511.h --- v2.4.0-test3/linux/drivers/usb/ov511.h Fri Jun 23 21:55:10 2000 +++ linux/drivers/usb/ov511.h Tue Jul 11 10:46:38 2000 @@ -171,9 +171,7 @@ #define OV7610_REG_COM_K 0x38 /* misc registers */ -#define STREAM_BUF_SIZE (PAGE_SIZE * 4) - -#define SCRATCH_BUF_SIZE 384 +#define SCRATCH_BUF_SIZE 512 #define FRAMES_PER_DESC 10 /* FIXME - What should this be? */ #define FRAME_SIZE_PER_DESC 993 /* FIXME - Deprecated */ @@ -213,6 +211,13 @@ STATE_LINES, /* Parsing lines */ }; +/* Buffer states */ +enum { + BUF_NOT_ALLOCATED, + BUF_ALLOCATED, + BUF_PEND_DEALLOC, /* ov511->buf_timer is set */ +}; + struct usb_device; struct ov511_sbuf { @@ -324,6 +329,11 @@ /* proc interface */ struct semaphore param_lock; /* params lock for this camera */ struct proc_dir_entry *proc_entry; /* /proc/ov511/videoX */ + + /* Framebuffer/sbuf management */ + int buf_state; + struct semaphore buf_lock; + struct timer_list buf_timer; }; struct cam_list { diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/printer.c linux/drivers/usb/printer.c --- v2.4.0-test3/linux/drivers/usb/printer.c Mon Jul 10 16:47:25 2000 +++ linux/drivers/usb/printer.c Wed Jul 12 21:58:43 2000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -167,17 +168,19 @@ if (minor < 0 || minor >= USBLP_MINORS) return -ENODEV; + lock_kernel(); usblp = usblp_table[minor]; + retval = -ENODEV; if (!usblp || !usblp->dev) - return -ENODEV; + goto out; + retval = -EBUSY; if (usblp->used) - return -EBUSY; + goto out; - if ((retval = usblp_check_status(usblp))) { - return retval; - } + if ((retval = usblp_check_status(usblp))) + goto out; usblp->used = 1; file->private_data = usblp; @@ -189,8 +192,9 @@ usblp->readcount = 0; usb_submit_urb(&usblp->readurb); } - - return 0; +out: + unlock_kernel(); + return retval; } static int usblp_release(struct inode *inode, struct file *file) diff -u --recursive --new-file v2.4.0-test3/linux/drivers/usb/usb.c linux/drivers/usb/usb.c --- v2.4.0-test3/linux/drivers/usb/usb.c Mon Jul 10 16:47:25 2000 +++ linux/drivers/usb/usb.c Thu Jul 13 10:40:20 2000 @@ -58,8 +58,6 @@ int usb_register(struct usb_driver *new_driver) { - struct list_head *tmp; - if (new_driver->fops != NULL) { if (usb_minors[new_driver->minor/16]) { err("error registering %s driver", new_driver->name); @@ -75,13 +73,22 @@ /* Add it to the list of known drivers */ list_add(&new_driver->driver_list, &usb_driver_list); - /* - * We go through all existing devices, and see if any of them would - * be acceptable to the new driver.. This is done using a depth-first - * search for devices without a registered driver already, then - * running 'probe' with each of the drivers registered on every one - * of these. - */ + usb_scan_devices(); + + return 0; +} + +/* + * We go through all existing devices, and see if any of them would + * be acceptable to the new driver.. This is done using a depth-first + * search for devices without a registered driver already, then + * running 'probe' with each of the drivers registered on every one + * of these. + */ +void usb_scan_devices(void) +{ + struct list_head *tmp; + tmp = usb_bus_list.next; while (tmp != &usb_bus_list) { struct usb_bus *bus = list_entry(tmp,struct usb_bus, bus_list); @@ -89,7 +96,6 @@ tmp = tmp->next; usb_check_support(bus->root_hub); } - return 0; } /* @@ -1772,6 +1778,7 @@ EXPORT_SYMBOL(usb_register); EXPORT_SYMBOL(usb_deregister); +EXPORT_SYMBOL(usb_scan_devices); EXPORT_SYMBOL(usb_alloc_bus); EXPORT_SYMBOL(usb_free_bus); EXPORT_SYMBOL(usb_register_bus); diff -u --recursive --new-file v2.4.0-test3/linux/drivers/video/Makefile linux/drivers/video/Makefile --- v2.4.0-test3/linux/drivers/video/Makefile Fri Jun 23 21:55:10 2000 +++ linux/drivers/video/Makefile Wed Jul 12 16:35:28 2000 @@ -33,7 +33,7 @@ # Each configuration option enables a list of files. obj-$(CONFIG_DUMMY_CONSOLE) += dummycon.o -obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o vga_font.o +obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o obj-$(CONFIG_VGA_CONSOLE) += vgacon.o obj-$(CONFIG_MDA_CONSOLE) += mdacon.o diff -u --recursive --new-file v2.4.0-test3/linux/drivers/video/fbcon-mac.c linux/drivers/video/fbcon-mac.c --- v2.4.0-test3/linux/drivers/video/fbcon-mac.c Sun Feb 13 19:29:04 2000 +++ linux/drivers/video/fbcon-mac.c Thu Jul 13 14:49:57 2000 @@ -100,8 +100,8 @@ err_buf[cnt] = 0x700 | err_str[cnt]; fbcon_mac_putcs(p->conp, p, err_buf, len, 0, 0); /* pause for the user */ - for(cnt = 0; cnt < 50000; cnt++) - udelay(100); + printk( "ERROR: shift algorithm...\n" ); + mdelay(5000); return; } } @@ -318,12 +318,25 @@ } } +static inline void plot_helper(u8 *dest, u8 bit, int bw) +{ + switch (bw) { + case PIXEL_BLACK_MAC: + fb_writeb( fb_readb(dest) | bit, dest ); + break; + case PIXEL_WHITE_MAC: + fb_writeb( fb_readb(dest) & (~bit), dest ); + break; + case PIXEL_INVERT_MAC: + fb_writeb( fb_readb(dest) ^ bit, dest ); + break; + default: + printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); + } +} + /* * plot_pixel_mac - * - * bw == 0 = black - * 1 = white - * 2 = invert */ static void plot_pixel_mac(struct display *p, int bw, int pixel_x, int pixel_y) { @@ -333,10 +346,8 @@ /* There *are* 68k Macs that support more than 832x624, you know :-) */ if (pixel_x < 0 || pixel_y < 0 || pixel_x >= p->var.xres || pixel_y >= p->var.yres) { - int cnt; printk ("ERROR: pixel_x == %d, pixel_y == %d", pixel_x, pixel_y); - for(cnt = 0; cnt < 100000; cnt++) - udelay(100); + mdelay(1000); return; } @@ -344,90 +355,36 @@ case 1: dest = (u8 *) ((pixel_x >> 3) + p->screen_base + pixel_y * p->next_line); bit = 0x80 >> (pixel_x & 7); - switch (bw) { - case PIXEL_BLACK_MAC: - *dest |= bit; - break; - case PIXEL_WHITE_MAC: - *dest &= ~bit; - break; - case PIXEL_INVERT_MAC: - *dest ^= bit; - break; - default: - printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); - } + plot_helper(dest, bit, bw); break; case 2: dest = (u8 *) ((pixel_x >> 2) + p->screen_base + pixel_y * p->next_line); bit = 0xC0 >> ((pixel_x & 3) << 1); - switch (bw) { - case PIXEL_BLACK_MAC: - *dest |= bit; - break; - case PIXEL_WHITE_MAC: - *dest &= ~bit; - break; - case PIXEL_INVERT_MAC: - *dest ^= bit; - break; - default: - printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); - } + plot_helper(dest, bit, bw); break; case 4: - dest = (u8 *) ((pixel_x / 2) + p->screen_base + pixel_y * p->next_line); + dest = (u8 *) ((pixel_x >> 1) + p->screen_base + pixel_y * p->next_line); bit = 0xF0 >> ((pixel_x & 1) << 2); - switch (bw) { - case PIXEL_BLACK_MAC: - *dest |= bit; - break; - case PIXEL_WHITE_MAC: - *dest &= ~bit; - break; - case PIXEL_INVERT_MAC: - *dest ^= bit; - break; - default: - printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); - } + plot_helper(dest, bit, bw); break; case 8: dest = (u8 *) (pixel_x + p->screen_base + pixel_y * p->next_line); bit = 0xFF; - switch (bw) { - case PIXEL_BLACK_MAC: - *dest |= bit; - break; - case PIXEL_WHITE_MAC: - *dest &= ~bit; - break; - case PIXEL_INVERT_MAC: - *dest ^= bit; - break; - default: - printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); - } + plot_helper(dest, bit, bw); break; +/* FIXME: You can't access framebuffer directly like this! */ case 16: dest16 = (u16 *) ((pixel_x *2) + p->screen_base + pixel_y * p->next_line); pix16 = 0xFFFF; switch (bw) { - case PIXEL_BLACK_MAC: - *dest16 = ~pix16; - break; - case PIXEL_WHITE_MAC: - *dest16 = pix16; - break; - case PIXEL_INVERT_MAC: - *dest16 ^= pix16; - break; - default: - printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); + case PIXEL_BLACK_MAC: *dest16 = ~pix16; break; + case PIXEL_WHITE_MAC: *dest16 = pix16; break; + case PIXEL_INVERT_MAC: *dest16 ^= pix16; break; + default: printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); } break; @@ -435,17 +392,10 @@ dest32 = (u32 *) ((pixel_x *4) + p->screen_base + pixel_y * p->next_line); pix32 = 0xFFFFFFFF; switch (bw) { - case PIXEL_BLACK_MAC: - *dest32 = ~pix32; - break; - case PIXEL_WHITE_MAC: - *dest32 = pix32; - break; - case PIXEL_INVERT_MAC: - *dest32 ^= pix32; - break; - default: - printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); + case PIXEL_BLACK_MAC: *dest32 = ~pix32; break; + case PIXEL_WHITE_MAC: *dest32 = pix32; break; + case PIXEL_INVERT_MAC: *dest32 ^= pix32; break; + default: printk( "ERROR: Unknown pixel value in plot_pixel_mac\n"); } break; } @@ -497,7 +447,7 @@ */ struct display_switch fbcon_mac = { - fbcon_mac_setup, fbcon_mac_bmove, fbcon_mac_clear, fbcon_mac_putc, + fbcon_mac_setup, fbcon_redraw_bmove, fbcon_redraw_clear, fbcon_mac_putc, fbcon_mac_putcs, fbcon_mac_revc, NULL, NULL, NULL, FONTWIDTHRANGE(1,8) }; diff -u --recursive --new-file v2.4.0-test3/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c --- v2.4.0-test3/linux/drivers/video/fbcon.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/video/fbcon.c Thu Jul 13 14:49:57 2000 @@ -1124,6 +1124,15 @@ } } +void fbcon_redraw_clear(struct vc_data *conp, struct display *p, int sy, int sx, + int height, int width) +{ + int x, y; + for (y=0; y #include #include +#include #include #include #include @@ -473,8 +474,13 @@ off = vma->vm_pgoff << PAGE_SHIFT; if (!fb) return -ENODEV; - if (fb->fb_mmap) - return fb->fb_mmap(info, file, vma); + if (fb->fb_mmap) { + int res; + lock_kernel(); + res = fb->fb_mmap(info, file, vma); + unlock_kernel(); + return res; + } #if defined(__sparc__) && !defined(__sparc_v9__) /* Should never get here, all fb drivers should have their own @@ -483,6 +489,7 @@ #else /* !sparc32... */ + lock_kernel(); fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); /* frame buffer memory */ @@ -497,6 +504,7 @@ start = fix.mmio_start; len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len); } + unlock_kernel(); start &= PAGE_MASK; if ((vma->vm_end - vma->vm_start + off) > len) return -EINVAL; @@ -612,12 +620,15 @@ fb_release(struct inode *inode, struct file *file) { int fbidx = GET_FB_IDX(inode->i_rdev); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info; + lock_kernel(); + info = registered_fb[fbidx]; if (info->fbops->fb_release) info->fbops->fb_release(info,1); if (info->fbops->owner) __MOD_DEC_USE_COUNT(info->fbops->owner); + unlock_kernel(); return 0; } diff -u --recursive --new-file v2.4.0-test3/linux/drivers/video/fonts.c linux/drivers/video/fonts.c --- v2.4.0-test3/linux/drivers/video/fonts.c Fri Nov 13 10:10:12 1998 +++ linux/drivers/video/fonts.c Tue Jul 11 15:35:51 2000 @@ -30,7 +30,7 @@ &font_vga_8x16, #endif #ifdef CONFIG_FONT_6x11 -#if defined(CONFIG_MAC) || defined(CONFIG_FB_SBUS) +#if defined(CONFIG_FBCON_MAC) || defined(CONFIG_FB_SBUS) #undef NO_FONTS #endif &font_vga_6x11, diff -u --recursive --new-file v2.4.0-test3/linux/drivers/video/vesafb.c linux/drivers/video/vesafb.c --- v2.4.0-test3/linux/drivers/video/vesafb.c Fri Jun 23 21:55:10 2000 +++ linux/drivers/video/vesafb.c Thu Jul 13 14:49:57 2000 @@ -30,6 +30,7 @@ #include