diff -u --recursive --new-file v2.3.48/linux/CREDITS linux/CREDITS --- v2.3.48/linux/CREDITS Sat Feb 26 22:31:37 2000 +++ linux/CREDITS Thu Mar 2 11:17:32 2000 @@ -701,6 +701,14 @@ S: 1131 Budapest S: Hungary +N: Ben Fennema +E: bfennema@falcon.csc.calpoly.edu +W: http://www.csc.calpoly.edu/~bfennema +D: UDF filesystem +S: 21760 Irma Lyle Drive +S: Los Gatos, CA 95033-8942 +S: USA + N: Jürgen Fischer E: fischer@norbit.de (=?iso-8859-1?q?J=FCrgen?= Fischer) D: Author of Adaptec AHA-152x SCSI driver @@ -1194,8 +1202,9 @@ S: USA N: Russell King -E: rmk@arm.uk.linux.org +E: rmk@arm.linux.org.uk D: Linux/arm integrator, maintainer & hacker +D: Acornfb, Cyber2000fb author S: Burgh Heath, Tadworth, Surrey. S: England diff -u --recursive --new-file v2.3.48/linux/Documentation/Configure.help linux/Documentation/Configure.help --- v2.3.48/linux/Documentation/Configure.help Sat Feb 26 22:31:37 2000 +++ linux/Documentation/Configure.help Thu Mar 2 10:10:24 2000 @@ -339,10 +339,6 @@ performance, look for the hdparm package at ftp://metalab.unc.edu/pub/Linux/kernel/patches/diskdrives/ . - To fine-tune ATA/IDE drive/interface parameters for improved - performance, look for the hdparm package at - ftp://metalab.unc.edu/pub/Linux/kernel/patches/diskdrives/ . - If you want 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 and read Documentation/modules.txt and @@ -8478,12 +8474,11 @@ USB mouse and prefer to use the mouse in its limited Boot Protocol mode. This driver is much smaller than the HID one. -Wacom Graphire tablet support -CONFIG_USB_GRAPHIRE +Wacom Intuos/Graphire tablet support +CONFIG_USB_WACOM Say Y here if you want to use the USB version of the Wacom - Graphire tablet. Make sure you select Mouse and Event support, - don't select HID support, because this driver collides with it. - Use HIDBP support for keyboards and mice instead if you need it. + Intuos or Graphire tablet. Make sure you select Mouse and Event + support as well. Logitech WingMan Force joystick support CONFIG_USB_WMFORCE @@ -8656,6 +8651,18 @@ The module will be called ov511.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. +USB ADMtek's Pegasus based ethernet devices support +CONFIG_USB_PEGASUS + Say Y if you want to use your usb ethernet device. Note that + the code is still experimental. If you have devices with other + vendor IDs than ADMtek's you should change/add them in the + driver code and send a message to me (petkan@spct.net) for + update. + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called ov511.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt. + USB Kodak DC-2xx Camera support CONFIG_USB_DC2XX Say Y here if you want to connect this type of still camera to @@ -8740,7 +8747,18 @@ 5Mbit/s. Configure this driver after connecting the USB cable via ifconfig plusb0 10.0.0.1 pointopoint 10.0.0.2 (and vice versa on the other host). - + +USB Diamond Rio500 support +CONFIG_USB_RIO500 + Say Y here if you want to connect a USB rio500 to your + computer's USB port. Please read Documentation/usb/rio.txt + for more information. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called rio500.o. If you want to compile it as + a module, say M here and read Documentation/modules.txt. + ACPI support CONFIG_ACPI Advanced Configuration and Power Interface (ACPI) is an interface @@ -11113,13 +11131,15 @@ Intel processors in P6 family, e.g. Pentium Pro, Pentium II, Pentium III, Xeon etc. You will obviously need the actual microcode binary data itself which is not shipped with the Linux kernel. - Contact Intel to obtain the latest revision of microcode for - your CPU(s). With this support compiled you can use dd(1) to write - microcode, for example: + With this support compiled you can use dd(1) to write microcode, + for example: + + # dd if=/etc/microcode of=/dev/cpu/microcode bs=98304 count=1 - # dd if=/etc/microcode of=/proc/driver/microcode bs=98304 count=1 + You need to be superuser to do that. For latest news and information + on obtaining all the required ingredients for this driver, check: - You need to be superuser to do that. + http://www.ocston.org/~tigran/patches/microcode This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). diff -u --recursive --new-file v2.3.48/linux/Documentation/filesystems/udf.txt linux/Documentation/filesystems/udf.txt --- v2.3.48/linux/Documentation/filesystems/udf.txt Fri Jan 28 15:09:06 2000 +++ linux/Documentation/filesystems/udf.txt Thu Mar 2 11:17:32 2000 @@ -1,7 +1,7 @@ * * ./Documentation/filesystems/udf.txt * -UDF Filesystem version 0.9.0 +UDF Filesystem version 0.9.1 If you encounter problems with reading UDF discs using this driver, please report them to linux_udf@hootie.lvld.hp.com, which is the @@ -16,13 +16,17 @@ gid= Set the default group. umask= Set the default umask. uid= Set the default user. + bs= Set the block size. unhide Show otherwise hidden files. undelete Show deleted files in lists. + adinicb Embed data in the inode (default) + noadinicb Don't embed data in the inode + shortad Use short ad's + longad Use long ad's (default) strict Set strict conformance (unused) The remaining are for debugging and disaster recovery: - bs= Set the block size. (may not work unless 2048) novrs Skip volume sequence recognition The following expect a offset from 0. @@ -46,7 +50,8 @@ http://www.trylinux.com/projects/udf/index.html For the latest version and toolset see: - http://www.csc.calpoly.edu/~bfennema/udf.html + http://www.csc.calpoly.edu/~bfennema/udf.html + http://linux-udf.sourceforge.net/ Documentation on UDF and ECMA 167 is available FREE from: http://www.osta.org/ diff -u --recursive --new-file v2.3.48/linux/Documentation/usb/ibmcam.txt linux/Documentation/usb/ibmcam.txt --- v2.3.48/linux/Documentation/usb/ibmcam.txt Thu Feb 10 17:11:02 2000 +++ linux/Documentation/usb/ibmcam.txt Mon Feb 28 14:21:15 2000 @@ -10,7 +10,12 @@ I did not have any input from Xirlink. Some people asked about data sheets, but nothing came out of that. I didn't try. -Video formats: 128x96, 176x144, 352x288 +Video formats: + 128x96 [model 1] + 176x144 + 320x240 [model 2] + 352x240 [model 2] + 352x288 Frame rate: 3 - 30 frames per second (FPS) External interface: USB Internal interface: Video For Linux (V4L) @@ -28,11 +33,11 @@ The Linux driver was developed with camera with following model number (or FCC ID): KSX-XVP510. This camera has three -interfaces, each with one endpoint (control, iso, iso). +interfaces, each with one endpoint (control, iso, iso). This +type of cameras is referred to as "model 1". It appears that Xirlink made some changes in their cameras recently. -In particular, following models [FCC ID] are suspect; one with -with FCC ID KSX-X9903 is known to be one of them: +In particular, following models [FCC ID] belong to that category: XVP300 [KSX-X9903] XVP600 [KSX-X9902] @@ -41,12 +46,57 @@ (see http://www.xirlink.com/ibmpccamera/ for updates, they refer to these new cameras by Windows driver dated 12-27-99, v3005 BETA) These cameras have two interfaces, one endpoint in each (iso, bulk). -Attempts to remotely debug one of these cameras weren't successful. -I'd need to have a camera to figure out how to use it. +Such type of cameras is referred to as "model 2". They are supported. + +Quirks of Model 2 cameras: +------------------------- + +These cameras apparently produce only 176x144 native video stream; +the 352x288 formats are produced from 176x144 RGB stream. In fact, +Xirlink broke perfectly good Model 1 (which used I420 on all sizes) +and instead switched to color-separated RGB which is a terrible waste +of bandwidth and resolution. However it probably allowed to simplify +the camera and use less RAM. Model 2 camera works visibly worse than +model 1 even using Xirlink's own driver on Windows. The image quality +is better on Linux than on Windows, partly thanks to _absence_ of +annoying automatic color corrections which Windows driver feeds into +the camera several times per second. + +Model 2 does not have hardware contrast control. Corresponding V4L +control is not used at the moment. It may be possible to implement +contrast control in software, at cost of extra processor cycles. + +The bandwidth demand imposed by RGB quasi-352x288 mode (800 Kbits per +frame) essentially limits this mode to 10 frames per second or less, in +ideal conditions on the bus (USB is shared, after all). The frame rate +has to be programmed very conservatively. Additional concern is that +frame rate depends on brightness setting; therefore the picture can +be good at one brightness and broken at another! I did not want to fix +the frame rate at slowest setting, but I had to move it pretty much down +the scale (so that framerate option barely matters). I also noticed that +camera after first powering up produces frames slightly faster than during +consecutive uses. All this means that if you use videosize=2 (which is +default), be warned - you may encounter broken picture on first connect; +try to adjust brightness - brighter image is slower, so USB will be able +to send all data. However if you regularly use Model 2 cameras you may +prefer videosize=1 which makes perfectly good I420, with no scaling and +lesser demands on USB (300 Kbits per second, or 26 frames per second). +Remember that model 2 cameras never produce images with resolution +better than "true" 176x144 - or so it seems. + +The camera that I had also has a hardware quirk: if disconnected, +it needs few minutes to "relax" before it can be plugged in again +(poorly designed USB processor reset circuit?) + +Finally, to say something good about Model 2: it is much simpler to program +than Model 1. Commands are few, and they all are straightforward. This camera +can be programmed for very high sensitivity (starlight may be enough), this +makes it convenient for tinkering with. The driver code has enough comments +to help a programmer to tweak the camera as s/he feels necessary. WHAT YOU NEED: -- A supported IBM PC (C-it) camera (see above) +- A supported IBM PC (C-it) camera (model 1 or 2) - A Linux box with USB support (2.3/2.4 or 2.2 w/backport) @@ -85,7 +135,7 @@ The driver can have options, though some defaults are provided. -Driver options: +Driver options: (* indicates that option is model-dependent) Name Type Range [default] Example -------------- -------------- -------------- ------------------ @@ -97,9 +147,18 @@ init_contrast Integer 0-255 [192] init_contrast=200 init_color Integer 0-255 [128] init_color=130 init_hue Integer 0-255 [128] init_hue=115 -lighting Integer 0-2 [1] lighting=2 -sharpness Integer 0-6 [4] sharpness=3 -videosize Integer 0-2 [2] videosize=1 +lighting Integer 0-2* [1] lighting=2 +sharpness Integer 0-6* [4] sharpness=3 +videosize Integer 0-2* [2] videosize=1 + +Options for Model 2 only: + +Name Type Range [default] Example +-------------- -------------- -------------- ------------------ +init_model2_rg Integer 0..255 [0x70] init_model2_rg=128 +init_model2_rg2 Integer 0..255 [0x2f] init_model2_rg2=50 +init_model2_sat Integer 0..255 [0x34] init_model2_sat=65 +init_model2_yb Integer 0..255 [0xa0] init_model2_yb=200 debug You don't need this option unless you are a developer. If you are a developer then you will see in the code @@ -145,49 +204,80 @@ preconfigure the camera when it gets connected, before any V4L application connects to it. Good for webcams. +init_model2_rg These initial settings alter color balance of the +init_model2_rg2 camera on hardware level. All four settings may be used +init_model2_sat to tune the camera to specific lighting conditions. These +init_model2_yb settings only apply to Model 2 cameras. + lighting This option selects one of three hardware-defined photosensitivity settings of the camera. 0=bright light, 1=Medium (default), 2=Low light. This setting affects frame rate: the dimmer the lighting the lower the frame - rate (because longer exposition time is needed). + rate (because longer exposition time is needed). The + Model 2 cameras allow values more than 2 for this option, + thus enabling extremely high sensitivity at cost of frame + rate, color saturation and imaging sensor noise. sharpness This option controls smoothing (noise reduction) made by camera. Setting 0 is most smooth, setting 6 is most sharp. Be aware that CMOS sensor used in the camera is pretty noisy, so if you choose 6 you will - be greeted with "snowy" image. Default is 4. + be greeted with "snowy" image. Default is 4. Model 2 + cameras do not support this feature. videosize This setting chooses one if three image sizes that are supported by this driver. Camera supports more, but it's difficult to reverse-engineer all formats. Following video sizes are supported: - videosize=0 128x96 + videosize=0 128x96 (Model 1 only) videosize=1 176x144 videosize=2 352x288 + videosize=3 320x240 (Model 2 only) + videosize=4 352x240 (Model 2 only) The last one (352x288) is the native size of the sensor - array, so it's the best resolution camera can yield. + array, so it's the best resolution camera (Model 1) can + yield. The best resolution of Model 2 is 176x144, and + larger images are produced by stretching the bitmap. Choose the image size you need. The smaller image can support faster frame rate. Default is 352x288. WHAT NEEDS TO BE DONE: - The box freezes if camera is unplugged after being used (OHCI). - Workaround: don't do that :) -- Some USB frames are lost on high frame rates, though they shouldn't -- ViCE compression (Xirlink proprietary) may improve frame rate -- On occasion camera does not start properly; xawtv reports errors. - Workaround: reload the driver module. Reason: [1]. -- On occasion camera produces negative image (funny colors.) + Workaround: remove usb-ohci module first. +- On occasion camera (model 1) does not start properly (xawtv reports + errors), or camera produces negative image (funny colors.) Workaround: reload the driver module. Reason: [1]. - The button on the camera is not used. I don't know how to get to it. + I know now how to read button on Model 2, but what to do with it? [1] - Camera reports its status back to the driver; however I don't know what returned data means. If camera fails at some initialization stage then something should be done, and I don't do that because - I don't even know that some command failed. + I don't even know that some command failed. This is mostly Model 1 + concern because Model 2 uses different commands which do not return + status (and seem to complete successfully every time). + +VIDEO SIZE AND IMAGE SIZE + +Camera produces picture X by Y pixels. This is camera-specific and can be +altered by programming the camera accordingly. This image is placed onto +larger (or equal) area W by H, this is V4L image. At this time the driver +uses V4L image size (W by H) 352x288 pixels because many programs (such +as xawtv) expect quite specific sizes and don't want to deal with arbitrary, +camera-specific sizes. However this approach "hides" real image size, and +application always sees the camera as producing only 352x288 image. It is +possible to change the V4L image size to 128x96, and then if camera is +switched to 128x96 mode then xawtv will correctly accept this image size. But +many other popular sizes (such as 176x144) will not be welcomed. This is the +reason why all camera images are at this time placed onto 352x288 "canvas", +and size of that canvas (V4L) is reported to applications. It will be easy +to add options to control the canvas size, but it will be application- +specific because not all applications are ready to work with variety of +camera-specific sizes. CREDITS: diff -u --recursive --new-file v2.3.48/linux/Documentation/usb/rio.txt linux/Documentation/usb/rio.txt --- v2.3.48/linux/Documentation/usb/rio.txt Wed Dec 31 16:00:00 1969 +++ linux/Documentation/usb/rio.txt Thu Mar 2 10:10:24 2000 @@ -0,0 +1,138 @@ +Copyright (C) 1999, 2000 Bruce Tenison +Portions Copyright (C) 1999, 2000 David Nelson +Thanks to David Nelson for guidance and the usage of the scanner.txt +and scanner.c files to model our driver and this informative file. + +Mar. 2, 2000 + +CHANGES + +- Initial Revision + + +OVERVIEW + +This README will address issues regarding how to configure the kernel +to access a RIO 500 mp3 player. +Before I explain how to use this to access the Rio500 please be warned: + +W A R N I N G: +-------------- + +Please note that this software is still under development. The authors +are in no way responsible for any damage that may occur, no matter how +inconsequential. + +It seems that the Rio has a problem when sending .mp3 with low batteries. +I suggest when the batteries are low and want to transfer stuff that you +replace it with a fresh one. In my case, what happened is I lost two 16kb +blocks (they are no longer usable to store information to it). But I don't +know if thats normal or not. It could simply be a problem with the flash +memory. + +In an extreme case, I left my Rio playing overnight and the batteries wore +down to nothing and appear to have corrupted the flash memory. My RIO +needed to be replaced as a result. Diamond tech support is aware of the +problem. Do NOT allow your batteries to wear down to nothing before +changing them. It appears RIO 500 firmware does not handle low battery +power well at all. + +On systems with OHCI controllers, the kernel OHCI code appears to have +power on problems with some chipsets. If you are having problems +connecting to your RIO 500, try turning it on first and then plugging it +into the USB cable. + +Contact information: +-------------------- + + The main page for the project is hosted at sourceforge.net in the following + address: http://rio500.sourceforge.net You can also go to the sourceforge + project page at: http://sourceforge.net/project/?group_id=1944 There is + also a mailing list: rio500-users@lists.sourceforge.net + +Authors: +------- + +Most of the code was written by Cesar Miquel . Keith +Clayton is incharge of the PPC port and making sure +things work there. Bruce Tenison is adding support +for .fon files and also does testing. The program will mostly sure be +re-written and Pete Ikusz along with the rest will re-design it. I would +also like to thank Tri Nguyen who provided use +with some important information regarding the communication with the Rio. + +ADDITIONAL INFORMATION and Userspace tools + +http://rio500.sourceforge.net/ + + +REQUIREMENTS + +A host with a USB port. Ideally, either a UHCI (Intel) or OHCI +(Compaq and others) hardware port should work. + +A Linux development kernel (2.3.x) with USB support enabled or a +backported version to linux-2.2.x. See http://www.linux-usb.org for +more information on accomplishing this. + +A Linux kernel with RIO 500 support enabled. + +'lspci' which is only needed to determine the type of USB hardware +available in your machine. + +CONFIGURATION + +Using `lspci -v`, determine the type of USB hardware available. + + If you see something like: + + USB Controller: ...... + Flags: ..... + I/O ports at .... + + Then you have a UHCI based controller. + + If you see something like: + + USB Controller: ..... + Flags: .... + Memory at ..... + + Then you have a OHCI based controller. + +Using `make menuconfig` or your preferred method for configuring the +kernel, select 'Support for USB', 'OHCI/UHCI' depending on your +hardware (determined from the steps above), 'USB Diamond Rio500 support', and +'Preliminary USB device filesystem'. Compile and install the modules +(you may need to execute `depmod -a` to update the module +dependencies). + +Add a device for the USB rio500: + `mknod /dev/usb/rio500 c 180 64` + +Set appropriate permissions for /dev/usb/rio500 (don't forget about +group and world permissions). Both read and write permissions are +required for proper operation. + +Load the appropriate modules (if compiled as modules): + + OHCI: + modprobe usbcore + modprobe usb-ohci + modprobe rio500 + + UHCI: + modprobe usbcore + modprobe usb-uhci (or uhci) + modprobe rio500 + +That's it. The Rio500 Utils at: http://rio500.sourceforge.net should +be able to access the rio500. + +BUGS + +If you encounter any problems feel free to drop me an email. + +Bruce Tenison +btenison@dibbs.net + diff -u --recursive --new-file v2.3.48/linux/MAINTAINERS linux/MAINTAINERS --- v2.3.48/linux/MAINTAINERS Sat Feb 26 22:31:38 2000 +++ linux/MAINTAINERS Thu Mar 2 10:10:24 2000 @@ -148,7 +148,7 @@ P: Russell King M: linux@arm.linux.org.uk L: linux-arm@vger.rutgers.edu -W: http://www.arm.linux.org.uk/~rmk/armlinux.html +W: http://www.arm.linux.org.uk/ S: Maintained ARPD SUPPORT @@ -234,6 +234,12 @@ M: jam@acm.org S: Maintained +CYBERPRO FB DRIVER +P: Russell King +M: linux@arm.linux.org.uk +W: http://www.arm.linux.org.uk/ +S: Maintained + CYCLADES 2X SYNC CARD DRIVER P: Arnaldo Carvalho de Melo M: acme@conectiva.com.br @@ -1125,6 +1131,13 @@ P: Jeff Garzik M: jgarzik@mandrakesoft.com L: linux-via@gtf.org +S: Maintained + +USB DIAMOND RIO500 DRIVER +P: Cesar Miquel +M: miquel@df.uba.ar +L: rio500-users@lists.sourceforge.net +W: http://rio500.sourceforge.net S: Maintained VIDEO FOR LINUX diff -u --recursive --new-file v2.3.48/linux/Makefile linux/Makefile --- v2.3.48/linux/Makefile Sat Feb 26 22:31:38 2000 +++ linux/Makefile Sat Feb 26 22:32:57 2000 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 48 +SUBLEVEL = 49 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile --- v2.3.48/linux/arch/alpha/kernel/Makefile Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/Makefile Mon Feb 28 14:52:42 2000 @@ -13,10 +13,21 @@ $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< O_TARGET := kernel.o -O_OBJS := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \ - ptrace.o time.o semaphore.o i8259.o +O_OBJS := entry.o traps.o process.o osf_sys.o irq.o irq_alpha.o \ + signal.o setup.o ptrace.o time.o semaphore.o OX_OBJS := alpha_ksyms.o +L_TARGET := rest.a +L_OBJS := irq_i8259.o irq_srm.o \ + es1888.o smc37c669.o smc37c93x.o ns87312.o + +ifdef CONFIG_SMP +O_OBJS += smp.o irq_smp.o +endif + +ifdef CONFIG_PCI +L_OBJS += pci.o pci_iommu.o +endif ifdef CONFIG_ALPHA_GENERIC @@ -25,13 +36,9 @@ sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \ sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \ sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \ - sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \ - es1888.o smc37c669.o smc37c93x.o ns87312.o pci.o pci_iommu.o -else + sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o -ifdef CONFIG_PCI -O_OBJS += pci.o pci_iommu.o -endif +else # Core logic support ifdef CONFIG_ALPHA_APECS @@ -67,10 +74,10 @@ O_OBJS += sys_alcor.o endif ifneq ($(CONFIG_ALPHA_CABRIOLET)$(CONFIG_ALPHA_EB164)$(CONFIG_ALPHA_EB66P)$(CONFIG_ALPHA_LX164)$(CONFIG_ALPHA_PC164),) -O_OBJS += sys_cabriolet.o ns87312.o +O_OBJS += sys_cabriolet.o endif ifdef CONFIG_ALPHA_DP264 -O_OBJS += sys_dp264.o es1888.o smc37c669.o +O_OBJS += sys_dp264.o endif ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),) O_OBJS += sys_eb64p.o @@ -82,7 +89,7 @@ O_OBJS += sys_jensen.o endif ifdef CONFIG_ALPHA_MIATA -O_OBJS += sys_miata.o es1888.o smc37c669.o +O_OBJS += sys_miata.o endif ifdef CONFIG_ALPHA_MIKASA O_OBJS += sys_mikasa.o @@ -106,25 +113,18 @@ O_OBJS += sys_sable.o endif ifneq ($(CONFIG_ALPHA_BOOK1)$(CONFIG_ALPHA_AVANTI)$(CONFIG_ALPHA_NONAME)$(CONFIG_ALPHA_P2K)$(CONFIG_ALPHA_XL),) -O_OBJS += sys_sio.o ns87312.o +O_OBJS += sys_sio.o endif ifdef CONFIG_ALPHA_SX164 -O_OBJS += sys_sx164.o smc37c669.o +O_OBJS += sys_sx164.o endif ifdef CONFIG_ALPHA_TAKARA -O_OBJS += sys_takara.o ns87312.o -endif - -# Device support -ifneq ($(CONFIG_ALPHA_PC164)$(CONFIG_ALPHA_LX164),) -O_OBJS += smc37c93x.o +O_OBJS += sys_takara.o endif endif # GENERIC -ifdef CONFIG_SMP -O_OBJS += smp.o -endif +O_OBJS += $(L_TARGET) all: kernel.o head.o diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/core_apecs.c linux/arch/alpha/kernel/core_apecs.c --- v2.3.48/linux/arch/alpha/kernel/core_apecs.c Thu Feb 10 17:11:02 2000 +++ linux/arch/alpha/kernel/core_apecs.c Thu Mar 2 11:35:12 2000 @@ -385,7 +385,7 @@ * Window 1 is direct access 1GB at 1GB * Window 2 is scatter-gather 8MB at 8MB (for isa) */ - hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, PAGE_SIZE); + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); hose->sg_pci = NULL; __direct_map_base = 0x40000000; __direct_map_size = 0x40000000; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c --- v2.3.48/linux/arch/alpha/kernel/core_cia.c Thu Feb 10 17:11:02 2000 +++ linux/arch/alpha/kernel/core_cia.c Thu Mar 2 11:35:12 2000 @@ -405,10 +405,12 @@ * ??? We ought to scale window 1 with memory. */ - /* NetBSD hints that page tables must be aligned to 32K due - to a hardware bug. No description of what models affected. */ - hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, 32768); - hose->sg_pci = iommu_arena_new(0x40000000, 0x08000000, 32768); + /* ??? NetBSD hints that page tables must be aligned to 32K, + possibly due to a hardware bug. This is over-aligned + from the 8K alignment one would expect for an 8MB window. + No description of what CIA revisions affected. */ + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0x8000); + hose->sg_pci = iommu_arena_new(hose, 0x40000000, 0x08000000, 0); __direct_map_base = 0x80000000; __direct_map_size = 0x80000000; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/core_lca.c linux/arch/alpha/kernel/core_lca.c --- v2.3.48/linux/arch/alpha/kernel/core_lca.c Thu Feb 10 17:11:02 2000 +++ linux/arch/alpha/kernel/core_lca.c Thu Mar 2 11:35:12 2000 @@ -307,7 +307,7 @@ * Window 0 is direct access 1GB at 1GB * Window 1 is scatter-gather 8MB at 8MB (for isa) */ - hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, PAGE_SIZE); + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); hose->sg_pci = NULL; __direct_map_base = 0x40000000; __direct_map_size = 0x40000000; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c --- v2.3.48/linux/arch/alpha/kernel/core_mcpcia.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/core_mcpcia.c Thu Mar 2 11:35:12 2000 @@ -404,8 +404,8 @@ * ??? We ought to scale window 1 with memory. */ - hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, PAGE_SIZE); - hose->sg_pci = iommu_arena_new(0x40000000, 0x08000000, PAGE_SIZE); + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); + hose->sg_pci = iommu_arena_new(hose, 0x40000000, 0x08000000, 0); __direct_map_base = 0x80000000; __direct_map_size = 0x80000000; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/core_pyxis.c linux/arch/alpha/kernel/core_pyxis.c --- v2.3.48/linux/arch/alpha/kernel/core_pyxis.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/core_pyxis.c Thu Mar 2 11:35:12 2000 @@ -36,7 +36,6 @@ */ #define DEBUG_CONFIG 0 - #if DEBUG_CONFIG # define DBG_CNF(args) printk args #else @@ -304,7 +303,7 @@ pyxis_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); } -static inline void +static void pyxis_disable_irq(unsigned int irq) { pyxis_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); @@ -318,6 +317,13 @@ } static void +pyxis_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + pyxis_enable_irq(irq); +} + +static void pyxis_mask_and_ack_irq(unsigned int irq) { unsigned long bit = 1UL << (irq - 16); @@ -340,7 +346,7 @@ enable: pyxis_enable_irq, disable: pyxis_disable_irq, ack: pyxis_mask_and_ack_irq, - end: pyxis_enable_irq, + end: pyxis_end_irq, }; void @@ -382,7 +388,7 @@ for (i = 16; i < 48; ++i) { if ((ignore_mask >> i) & 1) continue; - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &pyxis_irq_type; } @@ -427,6 +433,8 @@ ctrl = *(vuip)PYXIS_CTRL; *(vuip)PYXIS_CTRL = ctrl | 4; mb(); + *(vuip)PYXIS_CTRL; + mb(); /* Read from PCI dense memory space at TBI_ADDR, skipping 64k on each read. This forces SG TLB misses. It appears that @@ -441,6 +449,8 @@ mb(); *(vuip)PYXIS_CTRL = ctrl; mb(); + *(vuip)PYXIS_CTRL; + mb(); __restore_flags(flags); } @@ -473,31 +483,31 @@ struct pci_controler *hose; unsigned int temp; -#if 0 - printk("pyxis_init: PYXIS_ERR_MASK 0x%x\n", *(vuip)PYXIS_ERR_MASK); - printk("pyxis_init: PYXIS_ERR 0x%x\n", *(vuip)PYXIS_ERR); - printk("pyxis_init: PYXIS_INT_REQ 0x%lx\n", *(vulp)PYXIS_INT_REQ); - printk("pyxis_init: PYXIS_INT_MASK 0x%lx\n", *(vulp)PYXIS_INT_MASK); - printk("pyxis_init: PYXIS_INT_ROUTE 0x%lx\n", *(vulp)PYXIS_INT_ROUTE); - printk("pyxis_init: PYXIS_INT_HILO 0x%lx\n", *(vulp)PYXIS_INT_HILO); - printk("pyxis_init: PYXIS_INT_CNFG 0x%x\n", *(vuip)PYXIS_INT_CNFG); - printk("pyxis_init: PYXIS_RT_COUNT 0x%lx\n", *(vulp)PYXIS_RT_COUNT); -#endif - - /* - * Set up error reporting. Make sure CPU_PE is OFF in the mask. - */ + /* Set up error reporting. Make sure CPU_PE is OFF in the mask. */ temp = *(vuip)PYXIS_ERR_MASK; - temp &= ~4; - *(vuip)PYXIS_ERR_MASK = temp; - mb(); - *(vuip)PYXIS_ERR_MASK; /* re-read to force write */ + *(vuip)PYXIS_ERR_MASK = temp & ~4; + /* Enable master/target abort. */ temp = *(vuip)PYXIS_ERR; - temp |= 0x180; /* master/target abort */ - *(vuip)PYXIS_ERR = temp; + *(vuip)PYXIS_ERR = temp | 0x180; + + /* Clear the PYXIS_CFG register, which gets used for PCI Config + Space accesses. That is the way we want to use it, and we do + not want to depend on what ARC or SRM might have left behind. */ + *(vuip)PYXIS_CFG = 0; + + /* Zero the HAEs. */ + *(vuip)PYXIS_HAE_MEM = 0; + *(vuip)PYXIS_HAE_IO = 0; + + /* Finally, check that the PYXIS_CTRL1 has IOA_BEN set for + enabling byte/word PCI bus space(s) access. */ + temp = *(vuip)PYXIS_CTRL1; + *(vuip)PYXIS_CTRL1 = temp | 1; + + /* Syncronize with all previous changes. */ mb(); - *(vuip)PYXIS_ERR; /* re-read to force write */ + *(vuip)PYXIS_REV; /* * Create our single hose. @@ -524,10 +534,41 @@ * address range. */ - /* NetBSD hints that page tables must be aligned to 32K due - to a hardware bug. No description of what models affected. */ - hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, 32768); - hose->sg_pci = iommu_arena_new(0xc0000000, 0x08000000, 32768); +#if 1 + /* ??? There's some bit of syncronization wrt writing new tlb + entries that's missing. Sometimes it works, sometimes invalid + tlb machine checks, sometimes hard lockup. And this just within + the boot sequence. + + I've tried extra memory barriers, extra alignment, pyxis + register reads, tlb flushes, and loopback tlb accesses. + + I guess the pyxis revision in the sx164 is just too buggy... */ + + hose->sg_isa = hose->sg_pci = NULL; + __direct_map_base = 0x40000000; + __direct_map_size = 0x80000000; + + *(vuip)PYXIS_W0_BASE = 0x40000000 | 1; + *(vuip)PYXIS_W0_MASK = (0x40000000 - 1) & 0xfff00000; + *(vuip)PYXIS_T0_BASE = 0; + + *(vuip)PYXIS_W1_BASE = 0x80000000 | 1; + *(vuip)PYXIS_W1_MASK = (0x40000000 - 1) & 0xfff00000; + *(vuip)PYXIS_T1_BASE = 0; + + *(vuip)PYXIS_W2_BASE = 0; + *(vuip)PYXIS_W3_BASE = 0; + + alpha_mv.mv_pci_tbi = NULL; + mb(); +#else + /* ??? NetBSD hints that page tables must be aligned to 32K, + possibly due to a hardware bug. This is over-aligned + from the 8K alignment one would expect for an 8MB window. + No description of what CIA revisions affected. */ + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0x08000); + hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0x20000); __direct_map_base = 0x40000000; __direct_map_size = 0x80000000; @@ -553,36 +594,7 @@ pyxis_enable_broken_tbi(hose->sg_pci); alpha_mv.mv_pci_tbi(hose, 0, -1); - - /* - * Next, clear the PYXIS_CFG register, which gets used - * for PCI Config Space accesses. That is the way - * we want to use it, and we do not want to depend on - * what ARC or SRM might have left behind... - */ - temp = *(vuip)PYXIS_CFG; - if (temp != 0) { - *(vuip)PYXIS_CFG = 0; - mb(); - *(vuip)PYXIS_CFG; /* re-read to force write */ - } - - /* Zero the HAE. */ - *(vuip)PYXIS_HAE_MEM = 0U; mb(); - *(vuip)PYXIS_HAE_MEM; /* re-read to force write */ - *(vuip)PYXIS_HAE_IO = 0; mb(); - *(vuip)PYXIS_HAE_IO; /* re-read to force write */ - - /* - * Finally, check that the PYXIS_CTRL1 has IOA_BEN set for - * enabling byte/word PCI bus space(s) access. - */ - temp = *(vuip) PYXIS_CTRL1; - if (!(temp & 1)) { - *(vuip)PYXIS_CTRL1 = temp | 1; - mb(); - *(vuip)PYXIS_CTRL1; /* re-read */ - } +#endif } static inline void diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c --- v2.3.48/linux/arch/alpha/kernel/core_tsunami.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/core_tsunami.c Thu Mar 2 11:35:12 2000 @@ -343,13 +343,9 @@ * because of an idiot-syncrasy of the CYPRESS chip. It may * respond to a PCI bus address in the last 1MB of the 4GB * address range. - * - * Note that the TLB lookup logic uses bitwise concatenation, - * not addition, so the required arena alignment is based on - * the size of the window. */ - hose->sg_isa = iommu_arena_new(0x00800000, 0x00800000, 0x00800000>>10); - hose->sg_pci = iommu_arena_new(0xc0000000, 0x08000000, 0x08000000>>10); + hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); + hose->sg_pci = iommu_arena_new(hose, 0xc0000000, 0x08000000, 0); __direct_map_base = 0x40000000; __direct_map_size = 0x80000000; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/i8259.c linux/arch/alpha/kernel/i8259.c --- v2.3.48/linux/arch/alpha/kernel/i8259.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/i8259.c Wed Dec 31 16:00:00 1969 @@ -1,95 +0,0 @@ -/* - * linux/arch/alpha/kernel/i8259.c - * - * This is the 'legacy' 8259A Programmable Interrupt Controller, - * present in the majority of PC/AT boxes. - * - * Started hacking from linux-2.3.30pre6/arch/i386/kernel/i8259.c. - */ - -#include -#include -#include -#include -#include - -#include - -#include "proto.h" -#include "irq_impl.h" - - -/* Note mask bit is true for DISABLED irqs. */ -static unsigned int cached_irq_mask = 0xffff; - -static inline void -i8259_update_irq_hw(unsigned int irq, unsigned long mask) -{ - int port = 0x21; - if (irq & 8) mask >>= 8; - if (irq & 8) port = 0xA1; - outb(mask, port); -} - -inline void -i8259a_enable_irq(unsigned int irq) -{ - i8259_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq)); -} - -inline void -i8259a_disable_irq(unsigned int irq) -{ - i8259_update_irq_hw(irq, cached_irq_mask |= 1 << irq); -} - -void -i8259a_mask_and_ack_irq(unsigned int irq) -{ - i8259a_disable_irq(irq); - - /* Ack the interrupt making it the lowest priority. */ - if (irq >= 8) { - outb(0xE0 | (irq - 8), 0xa0); /* ack the slave */ - irq = 2; - } - outb(0xE0 | irq, 0x20); /* ack the master */ -} - -unsigned int -i8259a_startup_irq(unsigned int irq) -{ - i8259a_enable_irq(irq); - return 0; /* never anything pending */ -} - -struct hw_interrupt_type i8259a_irq_type = { - typename: "XT-PIC", - startup: i8259a_startup_irq, - shutdown: i8259a_disable_irq, - enable: i8259a_enable_irq, - disable: i8259a_disable_irq, - ack: i8259a_mask_and_ack_irq, - end: i8259a_enable_irq, -}; - -void __init -init_i8259a_irqs(void) -{ - static struct irqaction cascade = { - handler: no_action, - name: "cascade", - }; - - long i; - - outb(0xff, 0x21); /* mask all of 8259A-1 */ - outb(0xff, 0xA1); /* mask all of 8259A-2 */ - - for (i = 0; i < 16; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].handler = &i8259a_irq_type; - } - - setup_irq(2, &cascade); -} diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v2.3.48/linux/arch/alpha/kernel/irq.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/irq.c Mon Feb 28 14:54:30 2000 @@ -17,304 +17,85 @@ #include #include #include +#include #include #include #include -#include +#include +#include #include #include -#include #include -#include - -#include "proto.h" -#include "irq_impl.h" - -#define vulp volatile unsigned long * -#define vuip volatile unsigned int * - -/* Only uniprocessor needs this IRQ/BH locking depth, on SMP it lives - in the per-cpu structure for cache reasons. */ -#ifndef CONFIG_SMP -int __local_irq_count; -int __local_bh_count; -unsigned long __irq_attempt[NR_IRQS]; -#endif - -#ifdef CONFIG_ALPHA_GENERIC -#define ACTUAL_NR_IRQS alpha_mv.nr_irqs -#else -#define ACTUAL_NR_IRQS NR_IRQS -#endif - -/* Hack minimum IPL during interupt processing for broken hardware. */ - -#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK -int __min_ipl; -#endif +#include /* - * Performance counter hook. A module can override this to - * do something useful. + * Controller mappings for all interrupt sources: */ +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { + [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED} +}; -static void -dummy_perf(unsigned long vector, struct pt_regs *regs) -{ - printk(KERN_CRIT "Performance counter interrupt!\n"); -} - -void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf; - -/* - * Dispatch device interrupts. - */ - -/* - * Handle ISA interrupt via the PICs. - */ - -#if defined(CONFIG_ALPHA_GENERIC) -# define IACK_SC alpha_mv.iack_sc -#elif defined(CONFIG_ALPHA_APECS) -# define IACK_SC APECS_IACK_SC -#elif defined(CONFIG_ALPHA_LCA) -# define IACK_SC LCA_IACK_SC -#elif defined(CONFIG_ALPHA_CIA) -# define IACK_SC CIA_IACK_SC -#elif defined(CONFIG_ALPHA_PYXIS) -# define IACK_SC PYXIS_IACK_SC -#elif defined(CONFIG_ALPHA_TSUNAMI) -# define IACK_SC TSUNAMI_IACK_SC -#elif defined(CONFIG_ALPHA_POLARIS) -# define IACK_SC POLARIS_IACK_SC -#elif defined(CONFIG_ALPHA_IRONGATE) -# define IACK_SC IRONGATE_IACK_SC -#endif - -#if defined(IACK_SC) -void -isa_device_interrupt(unsigned long vector, struct pt_regs *regs) -{ - /* - * Generate a PCI interrupt acknowledge cycle. The PIC will - * respond with the interrupt vector of the highest priority - * interrupt that is pending. The PALcode sets up the - * interrupts vectors such that irq level L generates vector L. - */ - int j = *(vuip) IACK_SC; - j &= 0xff; - if (j == 7) { - if (!(inb(0x20) & 0x80)) { - /* It's only a passive release... */ - return; - } - } - handle_irq(j, regs); -} -#endif -#if defined(CONFIG_ALPHA_GENERIC) || !defined(IACK_SC) -void -isa_no_iack_sc_device_interrupt(unsigned long vector, struct pt_regs *regs) -{ - unsigned long pic; - - /* - * It seems to me that the probability of two or more *device* - * interrupts occurring at almost exactly the same time is - * pretty low. So why pay the price of checking for - * additional interrupts here if the common case can be - * handled so much easier? - */ - /* - * The first read of gives you *all* interrupting lines. - * Therefore, read the mask register and and out those lines - * not enabled. Note that some documentation has 21 and a1 - * write only. This is not true. - */ - pic = inb(0x20) | (inb(0xA0) << 8); /* read isr */ - pic &= 0xFFFB; /* mask out cascade & hibits */ +static void register_irq_proc(unsigned int irq); - while (pic) { - int j = ffz(~pic); - pic &= pic - 1; - handle_irq(j, regs); - } -} -#endif +unsigned long irq_err_count; /* - * Handle interrupts from the SRM, assuming no additional weirdness. + * Special irq handlers. */ -static inline void -srm_enable_irq(unsigned int irq) -{ - cserve_ena(irq - 16); -} - -static void -srm_disable_irq(unsigned int irq) -{ - cserve_dis(irq - 16); -} - -static unsigned int -srm_startup_irq(unsigned int irq) -{ - srm_enable_irq(irq); - return 0; -} - -static struct hw_interrupt_type srm_irq_type = { - typename: "SRM", - startup: srm_startup_irq, - shutdown: srm_disable_irq, - enable: srm_enable_irq, - disable: srm_disable_irq, - ack: srm_disable_irq, - end: srm_enable_irq, -}; - -void -srm_device_interrupt(unsigned long vector, struct pt_regs * regs) -{ - int irq = (vector - 0x800) >> 4; - handle_irq(irq, regs); -} - -void __init -init_srm_irqs(long max, unsigned long ignore_mask) -{ - long i; - - for (i = 16; i < max; ++i) { - if (i < 64 && ((ignore_mask >> i) & 1)) - continue; - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].handler = &srm_irq_type; - } -} +void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } /* - * The not-handled irq handler. + * Generic no controller code */ -static void -noirq_enable_disable(unsigned int irq) -{ -} - -static unsigned int -noirq_startup(unsigned int irq) -{ - return 0; -} +static void no_irq_enable_disable(unsigned int irq) { } +static unsigned int no_irq_startup(unsigned int irq) { return 0; } static void -noirq_ack(unsigned int irq) +no_irq_ack(unsigned int irq) { - printk(KERN_CRIT "Unexpected IRQ %u\n", irq); + irq_err_count++; + printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq); } -static struct hw_interrupt_type no_irq_type = { +struct hw_interrupt_type no_irq_type = { typename: "none", - startup: noirq_startup, - shutdown: noirq_enable_disable, - enable: noirq_enable_disable, - disable: noirq_enable_disable, - ack: noirq_ack, - end: noirq_enable_disable, -}; - -/* - * The special RTC interrupt type. The interrupt itself was - * processed by PALcode, and comes in via entInt vector 1. - */ - -static struct hw_interrupt_type rtc_irq_type = { - typename: "RTC", - startup: noirq_startup, - shutdown: noirq_enable_disable, - enable: noirq_enable_disable, - disable: noirq_enable_disable, - ack: noirq_enable_disable, - end: noirq_enable_disable, -}; - -void __init -init_rtc_irq(void) -{ - irq_desc[RTC_IRQ].status = IRQ_DISABLED; - irq_desc[RTC_IRQ].handler = &rtc_irq_type; -} - -/* - * Special irq handlers. - */ - -void -no_action(int cpl, void *dev_id, struct pt_regs *regs) -{ -} - -/* - * Common irq handlers. - */ - -struct irqaction isa_cascade_irqaction = { - handler: no_action, - name: "isa-cascade" -}; - -struct irqaction timer_cascade_irqaction = { - handler: no_action, - name: "timer-cascade" -}; - -struct irqaction halt_switch_irqaction = { - handler: no_action, - name: "halt-switch" -}; - - -spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED; -irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { - [0 ... NR_IRQS-1] = { 0, &no_irq_type, } + startup: no_irq_startup, + shutdown: no_irq_enable_disable, + enable: no_irq_enable_disable, + disable: no_irq_enable_disable, + ack: no_irq_ack, + end: no_irq_enable_disable, }; int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action) { - int status, cpu = smp_processor_id(); - int old_ipl, ipl; + int status; + int cpu = smp_processor_id(); kstat.irqs[cpu][irq]++; irq_enter(cpu, irq); status = 1; /* Force the "do bottom halves" bit */ - old_ipl = ipl = getipl(); do { - int new_ipl = IPL_MIN; - if (action->flags & SA_INTERRUPT) - new_ipl = IPL_MAX; - if (new_ipl != ipl) { - setipl(new_ipl); - ipl = new_ipl; - } + if (!(action->flags & SA_INTERRUPT)) + __sti(); + else + __cli(); status |= action->flags; action->handler(irq, action->dev_id, regs); action = action->next; } while (action); - if (ipl != old_ipl) - setipl(old_ipl); - if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); + __cli(); + irq_exit(cpu, irq); return status; @@ -326,17 +107,18 @@ * hardware disable after having gotten the irq * controller lock. */ -void +void inline disable_irq_nosync(unsigned int irq) { + irq_desc_t *desc = irq_desc + irq; unsigned long flags; - spin_lock_irqsave(&irq_controller_lock, flags); - if (!irq_desc[irq].depth++) { - irq_desc[irq].status |= IRQ_DISABLED | IRQ_MASKED; - irq_desc[irq].handler->disable(irq); + spin_lock_irqsave(&desc->lock, flags); + if (!desc->depth++) { + desc->status |= IRQ_DISABLED; + desc->handler->disable(irq); } - spin_unlock_irqrestore(&irq_controller_lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); } /* @@ -358,32 +140,29 @@ void enable_irq(unsigned int irq) { + irq_desc_t *desc = irq_desc + irq; unsigned long flags; - spin_lock_irqsave(&irq_controller_lock, flags); - switch (irq_desc[irq].depth) { - case 1: - { - unsigned int status = irq_desc[irq].status; - - status &= ~(IRQ_DISABLED | IRQ_MASKED); + spin_lock_irqsave(&desc->lock, flags); + switch (desc->depth) { + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + desc->status = status; if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { - status |= IRQ_REPLAY; - /* ??? We can't re-send on (most?) alpha hw. - hw_resend_irq(irq_desc[irq].handler,irq); */ + desc->status = status | IRQ_REPLAY; + hw_resend_irq(desc->handler,irq); } - irq_desc[irq].status = status; - irq_desc[irq].handler->enable(irq); + desc->handler->enable(irq); /* fall-through */ - } + } default: - irq_desc[irq].depth--; + desc->depth--; break; case 0: printk(KERN_ERR "enable_irq() unbalanced from %p\n", __builtin_return_address(0)); } - spin_unlock_irqrestore(&irq_controller_lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); } int @@ -392,6 +171,7 @@ int shared = 0; struct irqaction *old, **p; unsigned long flags; + irq_desc_t *desc = irq_desc + irq; /* * Some drivers like serial.c use request_irq() heavily, @@ -413,12 +193,12 @@ /* * The following block of code has to be executed atomically */ - spin_lock_irqsave(&irq_controller_lock,flags); - p = &irq_desc[irq].action; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; if ((old = *p) != NULL) { /* Can't share interrupts unless both agree to */ if (!(old->flags & new->flags & SA_SHIRQ)) { - spin_unlock_irqrestore(&irq_controller_lock,flags); + spin_unlock_irqrestore(&desc->lock,flags); return -EBUSY; } @@ -433,14 +213,181 @@ *p = new; if (!shared) { - irq_desc[irq].depth = 0; - irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_MASKED); - irq_desc[irq].handler->startup(irq); + desc->depth = 0; + desc->status &= ~IRQ_DISABLED; + desc->handler->startup(irq); } - spin_unlock_irqrestore(&irq_controller_lock,flags); + spin_unlock_irqrestore(&desc->lock,flags); + + register_irq_proc(irq); return 0; } +static struct proc_dir_entry * root_irq_dir; +static struct proc_dir_entry * irq_dir [NR_IRQS]; +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; + +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; + +#define HEX_DIGITS 16 + +static int +irq_affinity_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + if (count < HEX_DIGITS+1) + return -EINVAL; + return sprintf (page, "%016lx\n", irq_affinity[(long)data]); +} + +static unsigned int +parse_hex_value (const char *buffer, + unsigned long count, unsigned long *ret) +{ + unsigned char hexnum [HEX_DIGITS]; + unsigned long value; + int i; + + if (!count) + return -EINVAL; + if (count > HEX_DIGITS) + count = HEX_DIGITS; + if (copy_from_user(hexnum, buffer, count)) + return -EFAULT; + + /* + * Parse the first 8 characters as a hex string, any non-hex char + * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. + */ + value = 0; + + for (i = 0; i < count; i++) { + unsigned int c = hexnum[i]; + + switch (c) { + case '0' ... '9': c -= '0'; break; + case 'a' ... 'f': c -= 'a'-10; break; + case 'A' ... 'F': c -= 'A'-10; break; + default: + goto out; + } + value = (value << 4) | c; + } +out: + *ret = value; + return 0; +} + +static int +irq_affinity_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int irq = (long) data, full_count = count, err; + unsigned long new_value; + + if (!irq_desc[irq].handler->set_affinity) + return -EIO; + + err = parse_hex_value(buffer, count, &new_value); + +#if CONFIG_SMP + /* + * Do not allow disabling IRQs completely - it's a too easy + * way to make the system unusable accidentally :-) At least + * one online CPU still has to be targeted. + */ + if (!(new_value & cpu_present_mask)) + return -EINVAL; +#endif + + irq_affinity[irq] = new_value; + irq_desc[irq].handler->set_affinity(irq, new_value); + + return full_count; +} + +static int +prof_cpu_mask_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + unsigned long *mask = (unsigned long *) data; + if (count < HEX_DIGITS+1) + return -EINVAL; + return sprintf (page, "%08lx\n", *mask); +} + +static int +prof_cpu_mask_write_proc(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + unsigned long *mask = (unsigned long *) data, full_count = count, err; + unsigned long new_value; + + err = parse_hex_value(buffer, count, &new_value); + if (err) + return err; + + *mask = new_value; + return full_count; +} + +#define MAX_NAMELEN 10 + +static void +register_irq_proc (unsigned int irq) +{ + struct proc_dir_entry *entry; + char name [MAX_NAMELEN]; + + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type)) + return; + + memset(name, 0, MAX_NAMELEN); + sprintf(name, "%d", irq); + + /* create /proc/irq/1234 */ + irq_dir[irq] = proc_mkdir(name, root_irq_dir); + + /* create /proc/irq/1234/smp_affinity */ + entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]); + + entry->nlink = 1; + entry->data = (void *)(long)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; + + smp_affinity_entry[irq] = entry; +} + +unsigned long prof_cpu_mask = ~0UL; + +void +init_irq_proc (void) +{ + struct proc_dir_entry *entry; + int i; + + /* create /proc/irq */ + root_irq_dir = proc_mkdir("irq", 0); + + /* create /proc/irq/prof_cpu_mask */ + entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir); + + entry->nlink = 1; + entry->data = (void *)&prof_cpu_mask; + entry->read_proc = prof_cpu_mask_read_proc; + entry->write_proc = prof_cpu_mask_write_proc; + + /* + * Create entries for all existing IRQs. + */ + for (i = 0; i < NR_IRQS; i++) { + if (irq_desc[i].handler == &no_irq_type) + continue; + register_irq_proc(i); + } +} + int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) @@ -488,6 +435,7 @@ void free_irq(unsigned int irq, void *dev_id) { + irq_desc_t *desc; struct irqaction **p; unsigned long flags; @@ -496,8 +444,9 @@ return; } - spin_lock_irqsave(&irq_controller_lock,flags); - p = &irq_desc[irq].action; + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; for (;;) { struct irqaction * action = *p; if (action) { @@ -508,26 +457,29 @@ /* Found - now remove it from the list of entries. */ *pp = action->next; - if (!irq_desc[irq].action) { - irq_desc[irq].status |= IRQ_DISABLED|IRQ_MASKED; - irq_desc[irq].handler->shutdown(irq); + if (!desc->action) { + desc->status |= IRQ_DISABLED; + desc->handler->shutdown(irq); } - spin_unlock_irqrestore(&irq_controller_lock,flags); + spin_unlock_irqrestore(&desc->lock,flags); +#ifdef CONFIG_SMP /* Wait to make sure it's not being used on another CPU. */ - while (irq_desc[irq].status & IRQ_INPROGRESS) + while (desc->status & IRQ_INPROGRESS) barrier(); +#endif kfree(action); return; } printk(KERN_ERR "Trying to free free IRQ%d\n",irq); - spin_unlock_irqrestore(&irq_controller_lock,flags); + spin_unlock_irqrestore(&desc->lock,flags); return; } } -int get_irq_list(char *buf) +int +get_irq_list(char *buf) { int i, j; struct irqaction * action; @@ -576,246 +528,10 @@ cpu_data[cpu_logical_map(j)].smp_local_irq_count); p += sprintf(p, "\n"); #endif + p += sprintf(p, "ERR: %10lu\n", irq_err_count); return p - buf; } -#ifdef CONFIG_SMP -/* Who has global_irq_lock. */ -int global_irq_holder = NO_PROC_ID; - -/* This protects IRQ's. */ -spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; - -/* Global IRQ locking depth. */ -atomic_t global_irq_count = ATOMIC_INIT(0); - -static void *previous_irqholder = NULL; - -#define MAXCOUNT 100000000 - -static void show(char * str, void *where); - -static inline void -wait_on_irq(int cpu, void *where) -{ - int count = MAXCOUNT; - - for (;;) { - - /* - * Wait until all interrupts are gone. Wait - * for bottom half handlers unless we're - * already executing in one.. - */ - if (!atomic_read(&global_irq_count)) { - if (local_bh_count(cpu) - || !spin_is_locked(&global_bh_lock)) - break; - } - - /* Duh, we have to loop. Release the lock to avoid deadlocks */ - spin_unlock(&global_irq_lock); - - for (;;) { - if (!--count) { - show("wait_on_irq", where); - count = MAXCOUNT; - } - __sti(); - udelay(1); /* make sure to run pending irqs */ - __cli(); - - if (atomic_read(&global_irq_count)) - continue; - if (spin_is_locked(&global_irq_lock)) - continue; - if (!local_bh_count(cpu) - && spin_is_locked(&global_bh_lock)) - continue; - if (spin_trylock(&global_irq_lock)) - break; - } - } -} - -static inline void -get_irqlock(int cpu, void* where) -{ - if (!spin_trylock(&global_irq_lock)) { - /* Do we already hold the lock? */ - if (cpu == global_irq_holder) - return; - /* Uhhuh.. Somebody else got it. Wait. */ - spin_lock(&global_irq_lock); - } - - /* - * Ok, we got the lock bit. - * But that's actually just the easy part.. Now - * we need to make sure that nobody else is running - * in an interrupt context. - */ - wait_on_irq(cpu, where); - - /* - * Finally. - */ -#if DEBUG_SPINLOCK - global_irq_lock.task = current; - global_irq_lock.previous = where; -#endif - global_irq_holder = cpu; - previous_irqholder = where; -} - -void -__global_cli(void) -{ - int cpu = smp_processor_id(); - void *where = __builtin_return_address(0); - - /* - * Maximize ipl. If ipl was previously 0 and if this thread - * is not in an irq, then take global_irq_lock. - */ - if (swpipl(IPL_MAX) == IPL_MIN && !local_irq_count(cpu)) - get_irqlock(cpu, where); -} - -void -__global_sti(void) -{ - int cpu = smp_processor_id(); - - if (!local_irq_count(cpu)) - release_irqlock(cpu); - __sti(); -} - -/* - * SMP flags value to restore to: - * 0 - global cli - * 1 - global sti - * 2 - local cli - * 3 - local sti - */ -unsigned long -__global_save_flags(void) -{ - int retval; - int local_enabled; - unsigned long flags; - int cpu = smp_processor_id(); - - __save_flags(flags); - local_enabled = (!(flags & 7)); - /* default to local */ - retval = 2 + local_enabled; - - /* Check for global flags if we're not in an interrupt. */ - if (!local_irq_count(cpu)) { - if (local_enabled) - retval = 1; - if (global_irq_holder == cpu) - retval = 0; - } - return retval; -} - -void -__global_restore_flags(unsigned long flags) -{ - switch (flags) { - case 0: - __global_cli(); - break; - case 1: - __global_sti(); - break; - case 2: - __cli(); - break; - case 3: - __sti(); - break; - default: - printk(KERN_ERR "global_restore_flags: %08lx (%p)\n", - flags, __builtin_return_address(0)); - } -} - -static void -show(char * str, void *where) -{ -#if 0 - int i; - unsigned long *stack; -#endif - int cpu = smp_processor_id(); - - printk("\n%s, CPU %d: %p\n", str, cpu, where); - printk("irq: %d [%d %d]\n", - atomic_read(&global_irq_count), - cpu_data[0].irq_count, - cpu_data[1].irq_count); - - printk("bh: %d [%d %d]\n", - spin_is_locked(&global_bh_lock) ? 1 : 0, - cpu_data[0].bh_count, - cpu_data[1].bh_count); -#if 0 - stack = (unsigned long *) &str; - for (i = 40; i ; i--) { - unsigned long x = *++stack; - if (x > (unsigned long) &init_task_union && - x < (unsigned long) &vsprintf) { - printk("<[%08lx]> ", x); - } - } -#endif -} - -/* - * From its use, I infer that synchronize_irq() stalls a thread until - * the effects of a command to an external device are known to have - * taken hold. Typically, the command is to stop sending interrupts. - * The strategy here is wait until there is at most one processor - * (this one) in an irq. The memory barrier serializes the write to - * the device and the subsequent accesses of global_irq_count. - * --jmartin - */ -#define DEBUG_SYNCHRONIZE_IRQ 0 - -void -synchronize_irq(void) -{ -#if 0 - /* Joe's version. */ - int cpu = smp_processor_id(); - int local_count; - int global_count; - int countdown = 1<<24; - void *where = __builtin_return_address(0); - - mb(); - do { - local_count = local_irq_count(cpu); - global_count = atomic_read(&global_irq_count); - if (DEBUG_SYNCHRONIZE_IRQ && (--countdown == 0)) { - printk("%d:%d/%d\n", cpu, local_count, global_count); - show("synchronize_irq", where); - break; - } - } while (global_count != local_count); -#else - /* Jay's version. */ - if (atomic_read(&global_irq_count)) { - cli(); - sti(); - } -#endif -} -#endif /* CONFIG_SMP */ /* * do_IRQ handles all normal device IRQ's (the special @@ -836,39 +552,26 @@ * handled by some other CPU. (or is disabled) */ int cpu = smp_processor_id(); - irq_desc_t *desc; + irq_desc_t *desc = irq_desc + irq; struct irqaction * action; unsigned int status; if ((unsigned) irq > ACTUAL_NR_IRQS) { + irq_err_count++; printk(KERN_CRIT "device_interrupt: illegal interrupt %d\n", irq); return; } irq_attempt(cpu, irq)++; - desc = irq_desc + irq; - spin_lock_irq(&irq_controller_lock); /* mask also the RTC */ + spin_lock_irq(&desc->lock); /* mask also the higher prio events */ desc->handler->ack(irq); - status = desc->status; - -#ifndef CONFIG_SMP - /* Look for broken irq masking. */ - if (status & IRQ_MASKED) { - static unsigned long last_printed; - if (time_after(jiffies, last_printed+HZ)) { - printk(KERN_CRIT "Mask didn't work for irq %d!\n", irq); - last_printed = jiffies; - } - } -#endif - /* * REPLAY is when Linux resends an IRQ that was dropped earlier. * WAITING is used by probe to mark irqs that are being tested. */ - status &= ~(IRQ_REPLAY | IRQ_WAITING); - status |= IRQ_PENDING | IRQ_MASKED; /* we _want_ to handle it */ + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); + status |= IRQ_PENDING; /* we _want_ to handle it */ /* * If the IRQ is disabled for whatever reason, we cannot @@ -881,7 +584,6 @@ status |= IRQ_INPROGRESS; /* we are handling it */ } desc->status = status; - spin_unlock(&irq_controller_lock); /* * If there is no IRQ handler or it was disabled, exit early. @@ -890,7 +592,7 @@ * will take care of it. */ if (!action) - return; + goto out; /* * Edge triggered interrupts need to remember pending events. @@ -902,22 +604,23 @@ * SMP environment. */ for (;;) { + spin_unlock(&desc->lock); handle_IRQ_event(irq, regs, action); - spin_lock(&irq_controller_lock); + spin_lock(&desc->lock); if (!(desc->status & IRQ_PENDING) || (desc->status & IRQ_LEVEL)) break; desc->status &= ~IRQ_PENDING; - spin_unlock(&irq_controller_lock); - } - status = desc->status & ~IRQ_INPROGRESS; - if (!(status & IRQ_DISABLED)) { - status &= ~IRQ_MASKED; - desc->handler->end(irq); } - desc->status = status; - spin_unlock(&irq_controller_lock); + desc->status &= ~IRQ_INPROGRESS; +out: + /* + * The ->end() handler has to deal with interrupts which got + * disabled while the handler was running. + */ + desc->handler->end(irq); + spin_unlock(&desc->lock); } /* @@ -932,17 +635,20 @@ probe_irq_on(void) { int i; + irq_desc_t *desc; unsigned long delay; unsigned long val; /* Something may have generated an irq long ago and we want to flush such a longstanding irq before considering it as spurious. */ - spin_lock_irq(&irq_controller_lock); - for (i = NR_IRQS-1; i >= 0; i--) + for (i = NR_IRQS-1; i >= 0; i--) { + desc = irq_desc + i; + + spin_lock_irq(&desc->lock); if (!irq_desc[i].action) - if(irq_desc[i].handler->startup(i)) - irq_desc[i].status |= IRQ_PENDING; - spin_unlock_irq(&irq_controller_lock); + irq_desc[i].handler->startup(i); + spin_unlock_irq(&desc->lock); + } /* Wait for longstanding interrupts to trigger. */ for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) @@ -951,15 +657,17 @@ /* enable any unassigned irqs (we must startup again here because if a longstanding irq happened in the previous stage, it may have masked itself) first, enable any unassigned irqs. */ - spin_lock_irq(&irq_controller_lock); for (i = NR_IRQS-1; i >= 0; i--) { - if (!irq_desc[i].action) { - irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING; - if(irq_desc[i].handler->startup(i)) - irq_desc[i].status |= IRQ_PENDING; + desc = irq_desc + i; + + spin_lock_irq(&desc->lock); + if (!desc->action) { + desc->status |= IRQ_AUTODETECT | IRQ_WAITING; + if (desc->handler->startup(i)) + desc->status |= IRQ_PENDING; } + spin_unlock_irq(&desc->lock); } - spin_unlock_irq(&irq_controller_lock); /* * Wait for spurious interrupts to trigger @@ -971,24 +679,24 @@ * Now filter out any obviously spurious interrupts */ val = 0; - spin_lock_irq(&irq_controller_lock); for (i=0; ishutdown(i); - continue; - } + spin_lock_irq(&desc->lock); + status = desc->status; - if (i < 64) - val |= 1 << i; + if (status & IRQ_AUTODETECT) { + /* It triggered already - consider it spurious. */ + if (!(status & IRQ_WAITING)) { + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } else + if (i < 32) + val |= 1 << i; + } + spin_unlock_irq(&desc->lock); } - spin_unlock_irq(&irq_controller_lock); return val; } @@ -997,26 +705,29 @@ * Return a mask of triggered interrupts (this * can handle only legacy ISA interrupts). */ -unsigned int probe_irq_mask(unsigned long val) +unsigned int +probe_irq_mask(unsigned long val) { int i; unsigned int mask; mask = 0; - spin_lock_irq(&irq_controller_lock); for (i = 0; i < 16; i++) { - unsigned int status = irq_desc[i].status; + irq_desc_t *desc = irq_desc + i; + unsigned int status; - if (!(status & IRQ_AUTODETECT)) - continue; + spin_lock_irq(&desc->lock); + status = desc->status; - if (!(status & IRQ_WAITING)) - mask |= 1 << i; + if (status & IRQ_AUTODETECT) { + if (!(status & IRQ_WAITING)) + mask |= 1 << i; - irq_desc[i].status = status & ~IRQ_AUTODETECT; - irq_desc[i].handler->shutdown(i); + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } + spin_unlock_irq(&desc->lock); } - spin_unlock_irq(&irq_controller_lock); return mask & val; } @@ -1034,183 +745,26 @@ nr_irqs = 0; irq_found = 0; - spin_lock_irq(&irq_controller_lock); for (i=0; ilock); + status = desc->status; - if (!(status & IRQ_WAITING)) { - if (!nr_irqs) - irq_found = i; - nr_irqs++; + if (status & IRQ_AUTODETECT) { + if (!(status & IRQ_WAITING)) { + if (!nr_irqs) + irq_found = i; + nr_irqs++; + } + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); } - irq_desc[i].status = status & ~IRQ_AUTODETECT; - irq_desc[i].handler->shutdown(i); + spin_unlock_irq(&desc->lock); } - spin_unlock_irq(&irq_controller_lock); if (nr_irqs > 1) irq_found = -irq_found; return irq_found; -} - - -/* - * The main interrupt entry point. - */ - -asmlinkage void -do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, - unsigned long a3, unsigned long a4, unsigned long a5, - struct pt_regs regs) -{ - switch (type) { - case 0: -#ifdef CONFIG_SMP - handle_ipi(®s); - return; -#else - printk(KERN_CRIT "Interprocessor interrupt? " - "You must be kidding!\n"); -#endif - break; - case 1: -#ifdef CONFIG_SMP - cpu_data[smp_processor_id()].smp_local_irq_count++; - smp_percpu_timer_interrupt(®s); - if (smp_processor_id() == boot_cpuid) -#endif - handle_irq(RTC_IRQ, ®s); - return; - case 2: - alpha_mv.machine_check(vector, la_ptr, ®s); - return; - case 3: - alpha_mv.device_interrupt(vector, ®s); - return; - case 4: - perf_irq(vector, ®s); - return; - default: - printk(KERN_CRIT "Hardware intr %ld %lx? Huh?\n", - type, vector); - } - printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps); -} - -void __init -common_init_isa_dma(void) -{ - outb(0, DMA1_RESET_REG); - outb(0, DMA2_RESET_REG); - outb(0, DMA1_CLR_MASK_REG); - outb(0, DMA2_CLR_MASK_REG); -} - -void __init -init_IRQ(void) -{ - wrent(entInt, 0); - alpha_mv.init_irq(); -} - - -/* - */ -#define MCHK_K_TPERR 0x0080 -#define MCHK_K_TCPERR 0x0082 -#define MCHK_K_HERR 0x0084 -#define MCHK_K_ECC_C 0x0086 -#define MCHK_K_ECC_NC 0x0088 -#define MCHK_K_OS_BUGCHECK 0x008A -#define MCHK_K_PAL_BUGCHECK 0x0090 - -#ifndef CONFIG_SMP -struct mcheck_info __mcheck_info; -#endif - -void -process_mcheck_info(unsigned long vector, unsigned long la_ptr, - struct pt_regs *regs, const char *machine, - int expected) -{ - struct el_common *mchk_header; - const char *reason; - - /* - * See if the machine check is due to a badaddr() and if so, - * ignore it. - */ - -#if DEBUG_MCHECK > 0 - printk(KERN_CRIT "%s machine check %s\n", machine, - expected ? "expected." : "NOT expected!!!"); -#endif - - if (expected) { - int cpu = smp_processor_id(); - mcheck_expected(cpu) = 0; - mcheck_taken(cpu) = 1; - return; - } - - mchk_header = (struct el_common *)la_ptr; - - printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%lx\n", - machine, vector, regs->pc, mchk_header->code); - - switch ((unsigned int) mchk_header->code) { - /* Machine check reasons. Defined according to PALcode sources. */ - case 0x80: reason = "tag parity error"; break; - case 0x82: reason = "tag control parity error"; break; - case 0x84: reason = "generic hard error"; break; - case 0x86: reason = "correctable ECC error"; break; - case 0x88: reason = "uncorrectable ECC error"; break; - case 0x8A: reason = "OS-specific PAL bugcheck"; break; - case 0x90: reason = "callsys in kernel mode"; break; - case 0x96: reason = "i-cache read retryable error"; break; - case 0x98: reason = "processor detected hard error"; break; - - /* System specific (these are for Alcor, at least): */ - case 0x202: reason = "system detected hard error"; break; - case 0x203: reason = "system detected uncorrectable ECC error"; break; - case 0x204: reason = "SIO SERR occurred on PCI bus"; break; - case 0x205: reason = "parity error detected by CIA"; break; - case 0x206: reason = "SIO IOCHK occurred on ISA bus"; break; - case 0x207: reason = "non-existent memory error"; break; - case 0x208: reason = "MCHK_K_DCSR"; break; - case 0x209: reason = "PCI SERR detected"; break; - case 0x20b: reason = "PCI data parity error detected"; break; - case 0x20d: reason = "PCI address parity error detected"; break; - case 0x20f: reason = "PCI master abort error"; break; - case 0x211: reason = "PCI target abort error"; break; - case 0x213: reason = "scatter/gather PTE invalid error"; break; - case 0x215: reason = "flash ROM write error"; break; - case 0x217: reason = "IOA timeout detected"; break; - case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break; - case 0x21b: reason = "EISA fail-safe timer timeout"; break; - case 0x21d: reason = "EISA bus time-out"; break; - case 0x21f: reason = "EISA software generated NMI"; break; - case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break; - default: reason = "unknown"; break; - } - - printk(KERN_CRIT "machine check type: %s%s\n", - reason, mchk_header->retry ? " (retryable)" : ""); - - dik_show_regs(regs, NULL); - -#if DEBUG_MCHECK > 1 - { - /* Dump the logout area to give all info. */ - unsigned long *ptr = (unsigned long *)la_ptr; - long i; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(KERN_CRIT " +%8lx %016lx %016lx\n", - i*sizeof(long), ptr[i], ptr[i+1]); - } - } -#endif } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/irq_alpha.c linux/arch/alpha/kernel/irq_alpha.c --- v2.3.48/linux/arch/alpha/kernel/irq_alpha.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/irq_alpha.c Thu Mar 2 11:35:12 2000 @@ -0,0 +1,248 @@ +/* + * Alpha specific irq code. + */ + +#include +#include +#include +#include + +#include +#include + +#include "proto.h" +#include "irq_impl.h" + +/* Only uniprocessor needs this IRQ/BH locking depth, on SMP it lives + in the per-cpu structure for cache reasons. */ +#ifndef CONFIG_SMP +int __local_irq_count; +int __local_bh_count; +unsigned long __irq_attempt[NR_IRQS]; +#endif + +/* Hack minimum IPL during interupt processing for broken hardware. */ +#ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK +int __min_ipl; +#endif + +/* + * Performance counter hook. A module can override this to + * do something useful. + */ +static void +dummy_perf(unsigned long vector, struct pt_regs *regs) +{ + irq_err_count++; + printk(KERN_CRIT "Performance counter interrupt!\n"); +} + +void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf; + +/* + * The main interrupt entry point. + */ + +asmlinkage void +do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, + unsigned long a3, unsigned long a4, unsigned long a5, + struct pt_regs regs) +{ + switch (type) { + case 0: +#ifdef CONFIG_SMP + handle_ipi(®s); + return; +#else + irq_err_count++; + printk(KERN_CRIT "Interprocessor interrupt? " + "You must be kidding!\n"); +#endif + break; + case 1: +#ifdef CONFIG_SMP + cpu_data[smp_processor_id()].smp_local_irq_count++; + smp_percpu_timer_interrupt(®s); + if (smp_processor_id() == boot_cpuid) +#endif + handle_irq(RTC_IRQ, ®s); + return; + case 2: + irq_err_count++; + alpha_mv.machine_check(vector, la_ptr, ®s); + return; + case 3: + alpha_mv.device_interrupt(vector, ®s); + return; + case 4: + perf_irq(vector, ®s); + return; + default: + printk(KERN_CRIT "Hardware intr %ld %lx? Huh?\n", + type, vector); + } + printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps); +} + +void __init +common_init_isa_dma(void) +{ + outb(0, DMA1_RESET_REG); + outb(0, DMA2_RESET_REG); + outb(0, DMA1_CLR_MASK_REG); + outb(0, DMA2_CLR_MASK_REG); +} + +void __init +init_IRQ(void) +{ + alpha_mv.init_irq(); + wrent(entInt, 0); +} + +/* + * machine error checks + */ +#define MCHK_K_TPERR 0x0080 +#define MCHK_K_TCPERR 0x0082 +#define MCHK_K_HERR 0x0084 +#define MCHK_K_ECC_C 0x0086 +#define MCHK_K_ECC_NC 0x0088 +#define MCHK_K_OS_BUGCHECK 0x008A +#define MCHK_K_PAL_BUGCHECK 0x0090 + +#ifndef CONFIG_SMP +struct mcheck_info __mcheck_info; +#endif + +void +process_mcheck_info(unsigned long vector, unsigned long la_ptr, + struct pt_regs *regs, const char *machine, + int expected) +{ + struct el_common *mchk_header; + const char *reason; + + /* + * See if the machine check is due to a badaddr() and if so, + * ignore it. + */ + +#if DEBUG_MCHECK > 0 + printk(KERN_CRIT "%s machine check %s\n", machine, + expected ? "expected." : "NOT expected!!!"); +#endif + + if (expected) { + int cpu = smp_processor_id(); + mcheck_expected(cpu) = 0; + mcheck_taken(cpu) = 1; + return; + } + + mchk_header = (struct el_common *)la_ptr; + + printk(KERN_CRIT "%s machine check: vector=0x%lx pc=0x%lx code=0x%lx\n", + machine, vector, regs->pc, mchk_header->code); + + switch ((unsigned int) mchk_header->code) { + /* Machine check reasons. Defined according to PALcode sources. */ + case 0x80: reason = "tag parity error"; break; + case 0x82: reason = "tag control parity error"; break; + case 0x84: reason = "generic hard error"; break; + case 0x86: reason = "correctable ECC error"; break; + case 0x88: reason = "uncorrectable ECC error"; break; + case 0x8A: reason = "OS-specific PAL bugcheck"; break; + case 0x90: reason = "callsys in kernel mode"; break; + case 0x96: reason = "i-cache read retryable error"; break; + case 0x98: reason = "processor detected hard error"; break; + + /* System specific (these are for Alcor, at least): */ + case 0x202: reason = "system detected hard error"; break; + case 0x203: reason = "system detected uncorrectable ECC error"; break; + case 0x204: reason = "SIO SERR occurred on PCI bus"; break; + case 0x205: reason = "parity error detected by CIA"; break; + case 0x206: reason = "SIO IOCHK occurred on ISA bus"; break; + case 0x207: reason = "non-existent memory error"; break; + case 0x208: reason = "MCHK_K_DCSR"; break; + case 0x209: reason = "PCI SERR detected"; break; + case 0x20b: reason = "PCI data parity error detected"; break; + case 0x20d: reason = "PCI address parity error detected"; break; + case 0x20f: reason = "PCI master abort error"; break; + case 0x211: reason = "PCI target abort error"; break; + case 0x213: reason = "scatter/gather PTE invalid error"; break; + case 0x215: reason = "flash ROM write error"; break; + case 0x217: reason = "IOA timeout detected"; break; + case 0x219: reason = "IOCHK#, EISA add-in board parity or other catastrophic error"; break; + case 0x21b: reason = "EISA fail-safe timer timeout"; break; + case 0x21d: reason = "EISA bus time-out"; break; + case 0x21f: reason = "EISA software generated NMI"; break; + case 0x221: reason = "unexpected ev5 IRQ[3] interrupt"; break; + default: reason = "unknown"; break; + } + + printk(KERN_CRIT "machine check type: %s%s\n", + reason, mchk_header->retry ? " (retryable)" : ""); + + dik_show_regs(regs, NULL); + +#if DEBUG_MCHECK > 1 + { + /* Dump the logout area to give all info. */ + unsigned long *ptr = (unsigned long *)la_ptr; + long i; + for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { + printk(KERN_CRIT " +%8lx %016lx %016lx\n", + i*sizeof(long), ptr[i], ptr[i+1]); + } + } +#endif +} + +/* + * The special RTC interrupt type. The interrupt itself was + * processed by PALcode, and comes in via entInt vector 1. + */ + +static void rtc_enable_disable(unsigned int irq) { } +static unsigned int rtc_startup(unsigned int irq) { return 0; } + +struct irqaction timer_irqaction = { + handler: timer_interrupt, + flags: SA_INTERRUPT, + name: "timer", +}; + +static struct hw_interrupt_type rtc_irq_type = { + typename: "RTC", + startup: rtc_startup, + shutdown: rtc_enable_disable, + enable: rtc_enable_disable, + disable: rtc_enable_disable, + ack: rtc_enable_disable, + end: rtc_enable_disable, +}; + +void __init +init_rtc_irq(void) +{ + irq_desc[RTC_IRQ].status = IRQ_DISABLED; + irq_desc[RTC_IRQ].handler = &rtc_irq_type; + setup_irq(RTC_IRQ, &timer_irqaction); +} + +/* Dummy irqactions. */ +struct irqaction isa_cascade_irqaction = { + handler: no_action, + name: "isa-cascade" +}; + +struct irqaction timer_cascade_irqaction = { + handler: no_action, + name: "timer-cascade" +}; + +struct irqaction halt_switch_irqaction = { + handler: no_action, + name: "halt-switch" +}; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/irq_i8259.c linux/arch/alpha/kernel/irq_i8259.c --- v2.3.48/linux/arch/alpha/kernel/irq_i8259.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/irq_i8259.c Thu Mar 2 11:35:12 2000 @@ -0,0 +1,187 @@ +/* + * linux/arch/alpha/kernel/irq_i8259.c + * + * This is the 'legacy' 8259A Programmable Interrupt Controller, + * present in the majority of PC/AT boxes. + * + * Started hacking from linux-2.3.30pre6/arch/i386/kernel/i8259.c. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "proto.h" +#include "irq_impl.h" + + +/* Note mask bit is true for DISABLED irqs. */ +static unsigned int cached_irq_mask = 0xffff; +spinlock_t i8259_irq_lock = SPIN_LOCK_UNLOCKED; + +static inline void +i8259_update_irq_hw(unsigned int irq, unsigned long mask) +{ + int port = 0x21; + if (irq & 8) mask >>= 8; + if (irq & 8) port = 0xA1; + outb(mask, port); +} + +inline void +i8259a_enable_irq(unsigned int irq) +{ + spin_lock(&i8259_irq_lock); + i8259_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq)); + spin_unlock(&i8259_irq_lock); +} + +static inline void +__i8259a_disable_irq(unsigned int irq) +{ + i8259_update_irq_hw(irq, cached_irq_mask |= 1 << irq); +} + +void +i8259a_disable_irq(unsigned int irq) +{ + spin_lock(&i8259_irq_lock); + __i8259a_disable_irq(irq); + spin_unlock(&i8259_irq_lock); +} + +void +i8259a_mask_and_ack_irq(unsigned int irq) +{ + spin_lock(&i8259_irq_lock); + __i8259a_disable_irq(irq); + + /* Ack the interrupt making it the lowest priority. */ + if (irq >= 8) { + outb(0xE0 | (irq - 8), 0xa0); /* ack the slave */ + irq = 2; + } + outb(0xE0 | irq, 0x20); /* ack the master */ + spin_unlock(&i8259_irq_lock); +} + +unsigned int +i8259a_startup_irq(unsigned int irq) +{ + i8259a_enable_irq(irq); + return 0; /* never anything pending */ +} + +void +i8259a_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + i8259a_enable_irq(irq); +} + +struct hw_interrupt_type i8259a_irq_type = { + typename: "XT-PIC", + startup: i8259a_startup_irq, + shutdown: i8259a_disable_irq, + enable: i8259a_enable_irq, + disable: i8259a_disable_irq, + ack: i8259a_mask_and_ack_irq, + end: i8259a_end_irq, +}; + +void __init +init_i8259a_irqs(void) +{ + static struct irqaction cascade = { + handler: no_action, + name: "cascade", + }; + + long i; + + outb(0xff, 0x21); /* mask all of 8259A-1 */ + outb(0xff, 0xA1); /* mask all of 8259A-2 */ + + for (i = 0; i < 16; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].handler = &i8259a_irq_type; + } + + setup_irq(2, &cascade); +} + + +#if defined(CONFIG_ALPHA_GENERIC) +# define IACK_SC alpha_mv.iack_sc +#elif defined(CONFIG_ALPHA_APECS) +# define IACK_SC APECS_IACK_SC +#elif defined(CONFIG_ALPHA_LCA) +# define IACK_SC LCA_IACK_SC +#elif defined(CONFIG_ALPHA_CIA) +# define IACK_SC CIA_IACK_SC +#elif defined(CONFIG_ALPHA_PYXIS) +# define IACK_SC PYXIS_IACK_SC +#elif defined(CONFIG_ALPHA_TSUNAMI) +# define IACK_SC TSUNAMI_IACK_SC +#elif defined(CONFIG_ALPHA_POLARIS) +# define IACK_SC POLARIS_IACK_SC +#elif defined(CONFIG_ALPHA_IRONGATE) +# define IACK_SC IRONGATE_IACK_SC +#endif + +#if defined(IACK_SC) +void +isa_device_interrupt(unsigned long vector, struct pt_regs *regs) +{ + /* + * Generate a PCI interrupt acknowledge cycle. The PIC will + * respond with the interrupt vector of the highest priority + * interrupt that is pending. The PALcode sets up the + * interrupts vectors such that irq level L generates vector L. + */ + int j = *(vuip) IACK_SC; + j &= 0xff; + if (j == 7) { + if (!(inb(0x20) & 0x80)) { + /* It's only a passive release... */ + return; + } + } + handle_irq(j, regs); +} +#endif + +#if defined(CONFIG_ALPHA_GENERIC) || !defined(IACK_SC) +void +isa_no_iack_sc_device_interrupt(unsigned long vector, struct pt_regs *regs) +{ + unsigned long pic; + + /* + * It seems to me that the probability of two or more *device* + * interrupts occurring at almost exactly the same time is + * pretty low. So why pay the price of checking for + * additional interrupts here if the common case can be + * handled so much easier? + */ + /* + * The first read of gives you *all* interrupting lines. + * Therefore, read the mask register and and out those lines + * not enabled. Note that some documentation has 21 and a1 + * write only. This is not true. + */ + pic = inb(0x20) | (inb(0xA0) << 8); /* read isr */ + pic &= 0xFFFB; /* mask out cascade & hibits */ + + while (pic) { + int j = ffz(~pic); + pic &= pic - 1; + handle_irq(j, regs); + } +} +#endif diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/irq_impl.h linux/arch/alpha/kernel/irq_impl.h --- v2.3.48/linux/arch/alpha/kernel/irq_impl.h Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/irq_impl.h Sun Feb 27 13:28:01 2000 @@ -19,6 +19,7 @@ extern void srm_device_interrupt(unsigned long, struct pt_regs *); extern void pyxis_device_interrupt(unsigned long, struct pt_regs *); +extern struct irqaction timer_irqaction; extern struct irqaction isa_cascade_irqaction; extern struct irqaction timer_cascade_irqaction; extern struct irqaction halt_switch_irqaction; @@ -33,27 +34,37 @@ extern void i8259a_disable_irq(unsigned int); extern void i8259a_mask_and_ack_irq(unsigned int); extern unsigned int i8259a_startup_irq(unsigned int); +extern void i8259a_end_irq(unsigned int); extern struct hw_interrupt_type i8259a_irq_type; extern void init_i8259a_irqs(void); -extern void no_action(int cpl, void *dev_id, struct pt_regs *regs); extern void handle_irq(int irq, struct pt_regs * regs); +extern unsigned long prof_cpu_mask; + static inline void alpha_do_profile(unsigned long pc) { - if (prof_buffer && current->pid) { - extern char _stext; + extern char _stext; + + if (!prof_buffer) + return; - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - /* - * Don't 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]); - } + /* + * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. + * (default is all CPUs.) + */ + if (!((1<>= prof_shift; + /* + * Don't 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]); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/irq_smp.c linux/arch/alpha/kernel/irq_smp.c --- v2.3.48/linux/arch/alpha/kernel/irq_smp.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/irq_smp.c Mon Feb 28 14:54:30 2000 @@ -0,0 +1,250 @@ +/* + * linux/arch/alpha/kernel/irq_smp.c + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/* Who has global_irq_lock. */ +int global_irq_holder = NO_PROC_ID; + +/* This protects IRQ's. */ +spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; + +/* Global IRQ locking depth. */ +static void *previous_irqholder = NULL; + +#define MAXCOUNT 100000000 + + +static void +show(char * str, void *where) +{ +#if 0 + int i; + unsigned long *stack; +#endif + int cpu = smp_processor_id(); + + printk("\n%s, CPU %d: %p\n", str, cpu, where); + printk("irq: %d [%d %d]\n", + irqs_running(), + cpu_data[0].irq_count, + cpu_data[1].irq_count); + + printk("bh: %d [%d %d]\n", + spin_is_locked(&global_bh_lock) ? 1 : 0, + cpu_data[0].bh_count, + cpu_data[1].bh_count); +#if 0 + stack = (unsigned long *) &str; + for (i = 40; i ; i--) { + unsigned long x = *++stack; + if (x > (unsigned long) &init_task_union && + x < (unsigned long) &vsprintf) { + printk("<[%08lx]> ", x); + } + } +#endif +} + +static inline void +wait_on_irq(int cpu, void *where) +{ + int count = MAXCOUNT; + + for (;;) { + + /* + * Wait until all interrupts are gone. Wait + * for bottom half handlers unless we're + * already executing in one.. + */ + if (!irqs_running()) { + if (local_bh_count(cpu) + || !spin_is_locked(&global_bh_lock)) + break; + } + + /* Duh, we have to loop. Release the lock to avoid deadlocks */ + spin_unlock(&global_irq_lock); + + for (;;) { + if (!--count) { + show("wait_on_irq", where); + count = MAXCOUNT; + } + __sti(); + udelay(1); /* make sure to run pending irqs */ + __cli(); + + if (irqs_running()) + continue; + if (spin_is_locked(&global_irq_lock)) + continue; + if (!local_bh_count(cpu) + && spin_is_locked(&global_bh_lock)) + continue; + if (spin_trylock(&global_irq_lock)) + break; + } + } +} + +static inline void +get_irqlock(int cpu, void* where) +{ + if (!spin_trylock(&global_irq_lock)) { + /* Do we already hold the lock? */ + if (cpu == global_irq_holder) + return; + /* Uhhuh.. Somebody else got it. Wait. */ + spin_lock(&global_irq_lock); + } + + /* + * Ok, we got the lock bit. + * But that's actually just the easy part.. Now + * we need to make sure that nobody else is running + * in an interrupt context. + */ + wait_on_irq(cpu, where); + + /* + * Finally. + */ +#if DEBUG_SPINLOCK + global_irq_lock.task = current; + global_irq_lock.previous = where; +#endif + global_irq_holder = cpu; + previous_irqholder = where; +} + +void +__global_cli(void) +{ + int cpu = smp_processor_id(); + void *where = __builtin_return_address(0); + + /* + * Maximize ipl. If ipl was previously 0 and if this thread + * is not in an irq, then take global_irq_lock. + */ + if (swpipl(IPL_MAX) == IPL_MIN && !local_irq_count(cpu)) + get_irqlock(cpu, where); +} + +void +__global_sti(void) +{ + int cpu = smp_processor_id(); + + if (!local_irq_count(cpu)) + release_irqlock(cpu); + __sti(); +} + +/* + * SMP flags value to restore to: + * 0 - global cli + * 1 - global sti + * 2 - local cli + * 3 - local sti + */ +unsigned long +__global_save_flags(void) +{ + int retval; + int local_enabled; + unsigned long flags; + int cpu = smp_processor_id(); + + __save_flags(flags); + local_enabled = (!(flags & 7)); + /* default to local */ + retval = 2 + local_enabled; + + /* Check for global flags if we're not in an interrupt. */ + if (!local_irq_count(cpu)) { + if (local_enabled) + retval = 1; + if (global_irq_holder == cpu) + retval = 0; + } + return retval; +} + +void +__global_restore_flags(unsigned long flags) +{ + switch (flags) { + case 0: + __global_cli(); + break; + case 1: + __global_sti(); + break; + case 2: + __cli(); + break; + case 3: + __sti(); + break; + default: + printk(KERN_ERR "global_restore_flags: %08lx (%p)\n", + flags, __builtin_return_address(0)); + } +} + +/* + * From its use, I infer that synchronize_irq() stalls a thread until + * the effects of a command to an external device are known to have + * taken hold. Typically, the command is to stop sending interrupts. + * The strategy here is wait until there is at most one processor + * (this one) in an irq. The memory barrier serializes the write to + * the device and the subsequent accesses of global_irq_count. + * --jmartin + */ +#define DEBUG_SYNCHRONIZE_IRQ 0 + +void +synchronize_irq(void) +{ +#if 0 + /* Joe's version. */ + int cpu = smp_processor_id(); + int local_count; + int global_count; + int countdown = 1<<24; + void *where = __builtin_return_address(0); + + mb(); + do { + local_count = local_irq_count(cpu); + global_count = atomic_read(&global_irq_count); + if (DEBUG_SYNCHRONIZE_IRQ && (--countdown == 0)) { + printk("%d:%d/%d\n", cpu, local_count, global_count); + show("synchronize_irq", where); + break; + } + } while (global_count != local_count); +#else + /* Jay's version. */ + if (irqs_running()) { + cli(); + sti(); + } +#endif +} diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/irq_srm.c linux/arch/alpha/kernel/irq_srm.c --- v2.3.48/linux/arch/alpha/kernel/irq_srm.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/irq_srm.c Mon Feb 28 14:54:30 2000 @@ -0,0 +1,82 @@ +/* + * Handle interrupts from the SRM, assuming no additional weirdness. + */ + +#include +#include +#include + +#include +#include + +#include "proto.h" +#include "irq_impl.h" + + +/* + * Is the palcode SMP safe? In other words: can we call cserve_ena/dis + * at the same time in multiple CPUs? To be safe I added a spinlock + * but it can be removed trivially if the palcode is robust against smp. + */ +spinlock_t srm_irq_lock = SPIN_LOCK_UNLOCKED; + +static inline void +srm_enable_irq(unsigned int irq) +{ + spin_lock(&srm_irq_lock); + cserve_ena(irq - 16); + spin_unlock(&srm_irq_lock); +} + +static void +srm_disable_irq(unsigned int irq) +{ + spin_lock(&srm_irq_lock); + cserve_dis(irq - 16); + spin_unlock(&srm_irq_lock); +} + +static unsigned int +srm_startup_irq(unsigned int irq) +{ + srm_enable_irq(irq); + return 0; +} + +static void +srm_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + srm_enable_irq(irq); +} + +/* Handle interrupts from the SRM, assuming no additional weirdness. */ +static struct hw_interrupt_type srm_irq_type = { + typename: "SRM", + startup: srm_startup_irq, + shutdown: srm_disable_irq, + enable: srm_enable_irq, + disable: srm_disable_irq, + ack: srm_disable_irq, + end: srm_end_irq, +}; + +void __init +init_srm_irqs(long max, unsigned long ignore_mask) +{ + long i; + + for (i = 16; i < max; ++i) { + if (i < 64 && ((ignore_mask >> i) & 1)) + continue; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; + irq_desc[i].handler = &srm_irq_type; + } +} + +void +srm_device_interrupt(unsigned long vector, struct pt_regs * regs) +{ + int irq = (vector - 0x800) >> 4; + handle_irq(irq, regs); +} diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/machvec_impl.h linux/arch/alpha/kernel/machvec_impl.h --- v2.3.48/linux/arch/alpha/kernel/machvec_impl.h Thu Feb 10 17:11:02 2000 +++ linux/arch/alpha/kernel/machvec_impl.h Thu Mar 2 11:35:17 2000 @@ -44,7 +44,6 @@ mv_switch_mm: ev4_switch_mm, \ mv_activate_mm: ev4_activate_mm, \ mv_flush_tlb_current: ev4_flush_tlb_current, \ - mv_flush_tlb_other: ev4_flush_tlb_other, \ mv_flush_tlb_current_page: ev4_flush_tlb_current_page #define DO_EV5_MMU \ @@ -52,7 +51,6 @@ mv_switch_mm: ev5_switch_mm, \ mv_activate_mm: ev5_activate_mm, \ mv_flush_tlb_current: ev5_flush_tlb_current, \ - mv_flush_tlb_other: ev5_flush_tlb_other, \ mv_flush_tlb_current_page: ev5_flush_tlb_current_page #define DO_EV6_MMU \ @@ -60,7 +58,6 @@ mv_switch_mm: ev5_switch_mm, \ mv_activate_mm: ev5_activate_mm, \ mv_flush_tlb_current: ev5_flush_tlb_current, \ - mv_flush_tlb_other: ev5_flush_tlb_other, \ mv_flush_tlb_current_page: ev5_flush_tlb_current_page #define IO_LITE(UP,low) \ diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/pci_impl.h linux/arch/alpha/kernel/pci_impl.h --- v2.3.48/linux/arch/alpha/kernel/pci_impl.h Thu Feb 10 17:11:02 2000 +++ linux/arch/alpha/kernel/pci_impl.h Thu Mar 2 11:35:12 2000 @@ -123,6 +123,24 @@ _ctl_; }) +/* A PCI IOMMU allocation arena. There are typically two of these + regions per bus. */ +/* ??? The 8400 has a 32-byte pte entry, and the entire table apparently + lives directly on the host bridge (no tlb?). We don't support this + machine, but if we ever did, we'd need to parameterize all this quite + a bit further. Probably with per-bus operation tables. */ + +struct pci_iommu_arena +{ + spinlock_t lock; + struct pci_controler *hose; + unsigned long *ptes; + dma_addr_t dma_base; + unsigned int size; + unsigned int next_entry; +}; + + /* The hose list. */ extern struct pci_controler *hose_head, **hose_tail; extern struct pci_controler *pci_isa_hose; @@ -132,8 +150,9 @@ extern struct pci_controler *alloc_pci_controler(void); extern struct resource *alloc_resource(void); -extern struct pci_iommu_arena *iommu_arena_new(dma_addr_t, unsigned long, - unsigned long); +extern struct pci_iommu_arena *iommu_arena_new(struct pci_controler *, + dma_addr_t, unsigned long, + unsigned long); extern long iommu_arena_alloc(struct pci_iommu_arena *arena, long n); extern const char *const pci_io_names[]; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/pci_iommu.c linux/arch/alpha/kernel/pci_iommu.c --- v2.3.48/linux/arch/alpha/kernel/pci_iommu.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/pci_iommu.c Thu Mar 2 11:35:12 2000 @@ -27,6 +27,8 @@ # define DBGA2(args...) #endif +#define DEBUG_NODIRECT 0 + static inline unsigned long mk_iommu_pte(unsigned long paddr) @@ -41,23 +43,29 @@ } struct pci_iommu_arena * -iommu_arena_new(dma_addr_t base, unsigned long window_size, - unsigned long align) +iommu_arena_new(struct pci_controler *hose, dma_addr_t base, + unsigned long window_size, unsigned long align) { - unsigned long entries, mem_size, mem_pages; + unsigned long mem_size; struct pci_iommu_arena *arena; - entries = window_size >> PAGE_SHIFT; - mem_size = entries * sizeof(unsigned long); - mem_pages = calc_npages(mem_size); + mem_size = window_size / (PAGE_SIZE / sizeof(unsigned long)); + + /* Note that the TLB lookup logic uses bitwise concatenation, + not addition, so the required arena alignment is based on + the size of the window. Retain the align parameter so that + particular systems can over-align the arena. */ + if (align < mem_size) + align = mem_size; arena = alloc_bootmem(sizeof(*arena)); - arena->ptes = __alloc_bootmem(mem_pages * PAGE_SIZE, align, 0); + arena->ptes = __alloc_bootmem(mem_size, align, 0); spin_lock_init(&arena->lock); + arena->hose = hose; arena->dma_base = base; arena->size = window_size; - arena->alloc_hint = 0; + arena->next_entry = 0; return arena; } @@ -74,20 +82,22 @@ /* Search forward for the first sequence of N empty ptes. */ beg = arena->ptes; end = beg + (arena->size >> PAGE_SHIFT); - p = beg + arena->alloc_hint; + p = beg + arena->next_entry; i = 0; while (i < n && p < end) i = (*p++ == 0 ? i + 1 : 0); - if (p >= end) { - /* Failure. Assume the hint was wrong and go back to + if (i < n) { + /* Reached the end. Flush the TLB and restart the search from the beginning. */ + alpha_mv.mv_pci_tbi(arena->hose, 0, -1); + p = beg; i = 0; while (i < n && p < end) i = (*p++ == 0 ? i + 1 : 0); - if (p >= end) { + if (i < n) { spin_unlock_irqrestore(&arena->lock, flags); return -1; } @@ -100,7 +110,7 @@ for (p = p - n, i = 0; i < n; ++i) p[i] = ~1UL; - arena->alloc_hint = p - beg + n; + arena->next_entry = p - beg + n; spin_unlock_irqrestore(&arena->lock, flags); return p - beg; @@ -115,7 +125,6 @@ p = arena->ptes + ofs; for (i = 0; i < n; ++i) p[i] = 0; - arena->alloc_hint = ofs; } /* Map a single buffer of the indicate size for PCI DMA in streaming @@ -138,6 +147,7 @@ paddr = virt_to_phys(cpu_addr); +#if !DEBUG_NODIRECT /* First check to see if we can use the direct map window. */ if (paddr + size + __direct_map_base - 1 <= max_dma && paddr + size <= __direct_map_size) { @@ -148,6 +158,7 @@ return ret; } +#endif /* If the machine doesn't define a pci_tbi routine, we have to assume it doesn't support sg mapping. */ @@ -199,6 +210,7 @@ if (direction == PCI_DMA_NONE) BUG(); +#if !DEBUG_NODIRECT if (dma_addr >= __direct_map_base && dma_addr < __direct_map_base + __direct_map_size) { /* Nothing to do. */ @@ -208,6 +220,7 @@ return; } +#endif arena = hose->sg_pci; if (!arena || dma_addr < arena->dma_base) @@ -224,10 +237,9 @@ npages = calc_npages((dma_addr & ~PAGE_MASK) + size); iommu_arena_free(arena, dma_ofs, npages); - alpha_mv.mv_pci_tbi(hose, dma_addr, dma_addr + size - 1); - DBGA2("pci_unmap_single: sg [%x,%lx] np %ld from %p\n", - dma_addr, size, npages, __builtin_return_address(0)); + DBGA("pci_unmap_single: sg [%x,%lx] np %ld from %p\n", + dma_addr, size, npages, __builtin_return_address(0)); } @@ -347,6 +359,7 @@ unsigned long *ptes; long npages, dma_ofs, i; +#if !DEBUG_NODIRECT /* If everything is physically contiguous, and the addresses fall into the direct-map window, use it. */ if (leader->dma_address == 0 @@ -360,6 +373,7 @@ return 0; } +#endif /* Otherwise, we'll use the iommu to make the pages virtually contiguous. */ @@ -376,56 +390,38 @@ DBGA(" sg_fill: [%p,%lx] -> sg %x np %ld\n", leader->address, size, out->dma_address, npages); + /* All virtually contiguous. We need to find the length of each + physically contiguous subsegment to fill in the ptes. */ ptes = &arena->ptes[dma_ofs]; sg = leader; - if (0 && leader->dma_address == 0) { - /* All physically contiguous. We already have the - length, all we need is to fill in the ptes. */ + do { + struct scatterlist *last_sg = sg; + + size = sg->length; + paddr = virt_to_phys(sg->address); - paddr = virt_to_phys(sg->address) & PAGE_MASK; + while (sg+1 < end && (int) sg[1].dma_address == -1) { + size += sg[1].length; + sg++; + } + + npages = calc_npages((paddr & ~PAGE_MASK) + size); + + paddr &= PAGE_MASK; for (i = 0; i < npages; ++i, paddr += PAGE_SIZE) *ptes++ = mk_iommu_pte(paddr); #if DEBUG_ALLOC > 0 - DBGA(" (0) [%p,%x] np %ld\n", - sg->address, sg->length, npages); - for (++sg; sg < end && (int) sg->dma_address < 0; ++sg) + DBGA(" (%ld) [%p,%x] np %ld\n", + last_sg - leader, last_sg->address, + last_sg->length, npages); + while (++last_sg <= sg) { DBGA(" (%ld) [%p,%x] cont\n", - sg - leader, sg->address, sg->length); -#endif - } else { - /* All virtually contiguous. We need to find the - length of each physically contiguous subsegment - to fill in the ptes. */ - do { - struct scatterlist *last_sg = sg; - - size = sg->length; - paddr = virt_to_phys(sg->address); - - while (sg+1 < end && (int) sg[1].dma_address == -1) { - size += sg[1].length; - sg++; - } - - npages = calc_npages((paddr & ~PAGE_MASK) + size); - - paddr &= PAGE_MASK; - for (i = 0; i < npages; ++i, paddr += PAGE_SIZE) - *ptes++ = mk_iommu_pte(paddr); - -#if DEBUG_ALLOC > 0 - DBGA(" (%ld) [%p,%x] np %ld\n", last_sg - leader, last_sg->address, - last_sg->length, npages); - while (++last_sg <= sg) { - DBGA(" (%ld) [%p,%x] cont\n", - last_sg - leader, last_sg->address, - last_sg->length); - } + last_sg->length); + } #endif - } while (++sg < end && (int) sg->dma_address < 0); - } + } while (++sg < end && (int) sg->dma_address < 0); return 1; } @@ -472,13 +468,9 @@ /* Third, iterate over the scatterlist leaders and allocate dma space as needed. */ for (out = sg; sg < end; ++sg) { - int ret; - if ((int) sg->dma_address < 0) continue; - - ret = sg_fill(sg, end, out, arena, max_dma); - if (ret < 0) + if (sg_fill(sg, end, out, arena, max_dma) < 0) goto error; out++; } @@ -517,7 +509,6 @@ struct pci_iommu_arena *arena; struct scatterlist *end; dma_addr_t max_dma; - dma_addr_t fstart, fend; if (direction == PCI_DMA_NONE) BUG(); @@ -531,42 +522,32 @@ if (!arena || arena->dma_base + arena->size > max_dma) arena = hose->sg_isa; - fstart = -1; - fend = 0; for (end = sg + nents; sg < end; ++sg) { unsigned long addr, size; + long npages, ofs; addr = sg->dma_address; size = sg->dma_length; - if (!size) break; +#if !DEBUG_NODIRECT if (addr >= __direct_map_base && addr < __direct_map_base + __direct_map_size) { /* Nothing to do. */ DBGA(" (%ld) direct [%lx,%lx]\n", sg - end + nents, addr, size); - } else { - long npages, ofs; - dma_addr_t tend; + continue; + } +#endif - DBGA(" (%ld) sg [%lx,%lx]\n", - sg - end + nents, addr, size); + DBGA(" (%ld) sg [%lx,%lx]\n", + sg - end + nents, addr, size); - npages = calc_npages((addr & ~PAGE_MASK) + size); - ofs = (addr - arena->dma_base) >> PAGE_SHIFT; - iommu_arena_free(arena, ofs, npages); - - tend = addr + size - 1; - if (fstart > addr) - fstart = addr; - if (fend < tend) - fend = tend; - } + npages = calc_npages((addr & ~PAGE_MASK) + size); + ofs = (addr - arena->dma_base) >> PAGE_SHIFT; + iommu_arena_free(arena, ofs, npages); } - if (fend) - alpha_mv.mv_pci_tbi(hose, fstart, fend); DBGA("pci_unmap_sg: %d entries\n", nents - (end - sg)); } @@ -580,6 +561,7 @@ struct pci_controler *hose; struct pci_iommu_arena *arena; +#if !DEBUG_NODIRECT /* If there exists a direct map, and the mask fits either MAX_DMA_ADDRESS defined such that GFP_DMA does something useful, or the total system memory as shifted by the @@ -588,6 +570,7 @@ && (__direct_map_base + MAX_DMA_ADDRESS-IDENT_ADDR-1 <= mask || __direct_map_base + (max_low_pfn<sysdata : pci_isa_hose; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h --- v2.3.48/linux/arch/alpha/kernel/proto.h Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/proto.h Sun Feb 27 13:28:01 2000 @@ -10,7 +10,6 @@ struct task_struct; struct pci_dev; struct pci_controler; -struct irqaction; /* core_apecs.c */ extern struct pci_ops apecs_pci_ops; @@ -81,14 +80,13 @@ extern int smp_info(char *buffer); extern void handle_ipi(struct pt_regs *); extern void smp_percpu_timer_interrupt(struct pt_regs *); -extern unsigned long cpu_present_mask; /* bios32.c */ /* extern void reset_for_srm(void); */ /* time.c */ extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs); -extern void common_init_rtc(struct irqaction *); +extern void common_init_rtc(void); extern unsigned long est_cycle_freq; /* smc37c93x.c */ diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v2.3.48/linux/arch/alpha/kernel/setup.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/setup.c Sun Feb 27 13:28:01 2000 @@ -487,6 +487,7 @@ #ifdef __SMP__ setup_smp(); #endif + paging_init(); } static char sys_unknown[] = "Unknown"; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c --- v2.3.48/linux/arch/alpha/kernel/signal.c Tue Nov 23 22:42:20 1999 +++ linux/arch/alpha/kernel/signal.c Mon Feb 28 07:50:08 2000 @@ -437,6 +437,8 @@ err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); } + if (err) + goto give_sigsegv; /* Set up to return from userspace. If provided, use a stub already in userspace. */ @@ -499,6 +501,8 @@ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw, set->sig[0], oldsp); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + if (err) + goto give_sigsegv; /* Set up to return from userspace. If provided, use a stub already in userspace. */ diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c --- v2.3.48/linux/arch/alpha/kernel/smp.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/smp.c Thu Mar 2 11:35:17 2000 @@ -972,6 +972,33 @@ flush_tlb_mm(mm); } +static void +ipi_flush_icache_page(void *x) +{ + struct mm_struct *mm = (struct mm_struct *) x; + if (mm == current->active_mm) + __load_new_mm_context(mm); +} + +void +flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + struct mm_struct *mm = vma->vm_mm; + + if ((vma->vm_flags & VM_EXEC) == 0) + return; + + mm->context = 0; + if (mm == current->active_mm) { + __load_new_mm_context(mm); + if (atomic_read(&mm->mm_users) <= 1) + return; + } + + if (smp_call_function(ipi_flush_icache_page, mm, 1, 1)) { + printk(KERN_CRIT "flush_icache_page: timed out\n"); + } +} int smp_info(char *buffer) diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_alcor.c linux/arch/alpha/kernel/sys_alcor.c --- v2.3.48/linux/arch/alpha/kernel/sys_alcor.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_alcor.c Mon Feb 28 14:54:30 2000 @@ -48,7 +48,7 @@ alcor_update_irq_hw(cached_irq_mask |= 1UL << (irq - 16)); } -static inline void +static void alcor_disable_irq(unsigned int irq) { alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (irq - 16))); @@ -81,6 +81,13 @@ *(vuip)GRU_INT_CLEAR = 0; mb(); } +static void +alcor_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + alcor_enable_irq(irq); +} + static struct hw_interrupt_type alcor_irq_type = { typename: "ALCOR", startup: alcor_startup_irq, @@ -88,7 +95,7 @@ enable: alcor_enable_irq, disable: alcor_disable_irq, ack: alcor_mask_and_ack_irq, - end: alcor_enable_irq, + end: alcor_end_irq, }; static void @@ -134,13 +141,12 @@ on while IRQ probing. */ if (i >= 16+20 && i <= 16+30) continue; - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &alcor_irq_type; } i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; init_i8259a_irqs(); - init_rtc_irq(); common_init_isa_dma(); setup_irq(16+31, &isa_cascade_irqaction); diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c --- v2.3.48/linux/arch/alpha/kernel/sys_cabriolet.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/sys_cabriolet.c Mon Feb 28 14:54:30 2000 @@ -65,6 +65,13 @@ return 0; /* never anything pending */ } +static void +cabriolet_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + cabriolet_enable_irq(irq); +} + static struct hw_interrupt_type cabriolet_irq_type = { typename: "CABRIOLET", startup: cabriolet_startup_irq, @@ -72,7 +79,7 @@ enable: cabriolet_enable_irq, disable: cabriolet_disable_irq, ack: cabriolet_disable_irq, - end: cabriolet_enable_irq, + end: cabriolet_end_irq, }; static void @@ -103,7 +110,6 @@ cabriolet_init_irq(void) { init_i8259a_irqs(); - init_rtc_irq(); if (alpha_using_srm) { alpha_mv.device_interrupt = srm_device_interrupt; @@ -117,7 +123,7 @@ outb(0xff, 0x806); for (i = 16; i < 35; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &cabriolet_irq_type; } } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c --- v2.3.48/linux/arch/alpha/kernel/sys_dp264.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/sys_dp264.c Mon Feb 28 14:54:30 2000 @@ -35,6 +35,10 @@ /* Note mask bit is true for ENABLED irqs. */ static unsigned long cached_irq_mask; +/* dp264 boards handle at max four CPUs */ +static unsigned long cpu_irq_affinity[4]; + +spinlock_t dp264_irq_lock = SPIN_LOCK_UNLOCKED; static void tsunami_update_irq_hw(unsigned long mask, unsigned long isa_enable) @@ -50,9 +54,14 @@ mask0 = mask1 = mask2 = mask3 = mask; maskB = mask | isa_enable; if (bcpu == 0) mask0 = maskB; - if (bcpu == 1) mask1 = maskB; - if (bcpu == 2) mask2 = maskB; - if (bcpu == 3) mask3 = maskB; + else if (bcpu == 1) mask1 = maskB; + else if (bcpu == 2) mask2 = maskB; + else if (bcpu == 3) mask3 = maskB; + + mask0 &= cpu_irq_affinity[0]; + mask1 &= cpu_irq_affinity[1]; + mask2 &= cpu_irq_affinity[2]; + mask3 &= cpu_irq_affinity[3]; dim0 = &cchip->dim0.csr; dim1 = &cchip->dim1.csr; @@ -73,10 +82,12 @@ *dim2; *dim3; #else - volatile unsigned long *dimB = &cchip->dim1.csr; + volatile unsigned long *dimB; if (bcpu == 0) dimB = &cchip->dim0.csr; - if (bcpu == 2) dimB = &cchip->dim2.csr; - if (bcpu == 3) dimB = &cchip->dim3.csr; + else if (bcpu == 1) dimB = &cchip->dim1.csr; + else if (bcpu == 2) dimB = &cchip->dim2.csr; + else if (bcpu == 3) dimB = &cchip->dim3.csr; + *dimB = mask | isa_enable; mb(); *dimB; @@ -95,18 +106,22 @@ tsunami_update_irq_hw(mask, 1UL << 55); } -static inline void +static void dp264_enable_irq(unsigned int irq) { + spin_lock(&dp264_irq_lock); cached_irq_mask |= 1UL << irq; dp264_update_irq_hw(cached_irq_mask); + spin_unlock(&dp264_irq_lock); } static void dp264_disable_irq(unsigned int irq) { + spin_lock(&dp264_irq_lock); cached_irq_mask &= ~(1UL << irq); dp264_update_irq_hw(cached_irq_mask); + spin_unlock(&dp264_irq_lock); } static unsigned int @@ -116,18 +131,29 @@ return 0; /* never anything pending */ } -static inline void +static void +dp264_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + dp264_enable_irq(irq); +} + +static void clipper_enable_irq(unsigned int irq) { + spin_lock(&dp264_irq_lock); cached_irq_mask |= 1UL << irq; clipper_update_irq_hw(cached_irq_mask); + spin_unlock(&dp264_irq_lock); } static void clipper_disable_irq(unsigned int irq) { + spin_lock(&dp264_irq_lock); cached_irq_mask &= ~(1UL << irq); clipper_update_irq_hw(cached_irq_mask); + spin_unlock(&dp264_irq_lock); } static unsigned int @@ -137,6 +163,47 @@ return 0; /* never anything pending */ } +static void +clipper_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + clipper_enable_irq(irq); +} + +static void +cpu_set_irq_affinity(unsigned int irq, unsigned long affinity) +{ + int cpu; + + for (cpu = 0; cpu < 4; cpu++) { + unsigned long aff = cpu_irq_affinity[cpu]; + if (affinity & (1UL << cpu)) + aff |= 1UL << irq; + else + aff &= ~(1UL << irq); + cpu_irq_affinity[cpu] = aff; + } + +} + +static void +dp264_set_affinity(unsigned int irq, unsigned long affinity) +{ + spin_lock(&dp264_irq_lock); + cpu_set_irq_affinity(irq, affinity); + dp264_update_irq_hw(cached_irq_mask); + spin_unlock(&dp264_irq_lock); +} + +static void +clipper_set_affinity(unsigned int irq, unsigned long affinity) +{ + spin_lock(&dp264_irq_lock); + cpu_set_irq_affinity(irq, affinity); + clipper_update_irq_hw(cached_irq_mask); + spin_unlock(&dp264_irq_lock); +} + static struct hw_interrupt_type dp264_irq_type = { typename: "DP264", startup: dp264_startup_irq, @@ -144,7 +211,8 @@ enable: dp264_enable_irq, disable: dp264_disable_irq, ack: dp264_disable_irq, - end: dp264_enable_irq, + end: dp264_end_irq, + set_affinity: dp264_set_affinity, }; static struct hw_interrupt_type clipper_irq_type = { @@ -154,7 +222,8 @@ enable: clipper_enable_irq, disable: clipper_disable_irq, ack: clipper_disable_irq, - end: clipper_enable_irq, + end: clipper_end_irq, + set_affinity: clipper_set_affinity, }; static void @@ -249,6 +318,8 @@ static void __init dp264_init_irq(void) { + int cpu; + outb(0, DMA1_RESET_REG); outb(0, DMA2_RESET_REG); outb(DMA_MODE_CASCADE, DMA2_MODE_REG); @@ -257,10 +328,12 @@ if (alpha_using_srm) alpha_mv.device_interrupt = dp264_srm_device_interrupt; + /* this is single threaded by design so no need of any smp lock */ + for (cpu = 0; cpu < 4; cpu++) + cpu_irq_affinity[cpu] = ~0UL; dp264_update_irq_hw(0UL); init_i8259a_irqs(); - init_rtc_irq(); init_tsunami_irqs(&dp264_irq_type); } @@ -278,7 +351,6 @@ clipper_update_irq_hw(0UL); init_i8259a_irqs(); - init_rtc_irq(); init_tsunami_irqs(&clipper_irq_type); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_eb64p.c linux/arch/alpha/kernel/sys_eb64p.c --- v2.3.48/linux/arch/alpha/kernel/sys_eb64p.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_eb64p.c Mon Feb 28 14:54:30 2000 @@ -48,7 +48,7 @@ eb64p_update_irq_hw(irq, cached_irq_mask &= ~(1 << irq)); } -static inline void +static void eb64p_disable_irq(unsigned int irq) { eb64p_update_irq_hw(irq, cached_irq_mask |= 1 << irq); @@ -61,6 +61,13 @@ return 0; /* never anything pending */ } +static void +eb64p_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + eb64p_enable_irq(irq); +} + static struct hw_interrupt_type eb64p_irq_type = { typename: "EB64P", startup: eb64p_startup_irq, @@ -68,7 +75,7 @@ enable: eb64p_enable_irq, disable: eb64p_disable_irq, ack: eb64p_disable_irq, - end: eb64p_enable_irq, + end: eb64p_end_irq, }; static void @@ -119,10 +126,9 @@ outb(0xff, 0x27); init_i8259a_irqs(); - init_rtc_irq(); for (i = 16; i < 32; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &eb64p_irq_type; } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_eiger.c linux/arch/alpha/kernel/sys_eiger.c --- v2.3.48/linux/arch/alpha/kernel/sys_eiger.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_eiger.c Mon Feb 28 14:54:30 2000 @@ -76,6 +76,13 @@ return 0; /* never anything pending */ } +static void +eiger_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + eiger_enable_irq(irq); +} + static struct hw_interrupt_type eiger_irq_type = { typename: "EIGER", startup: eiger_startup_irq, @@ -83,7 +90,7 @@ enable: eiger_enable_irq, disable: eiger_disable_irq, ack: eiger_disable_irq, - end: eiger_enable_irq, + end: eiger_end_irq, }; static void @@ -147,10 +154,9 @@ eiger_update_irq_hw(i, -1); init_i8259a_irqs(); - init_rtc_irq(); for (i = 16; i < 128; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &eiger_irq_type; } } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_jensen.c linux/arch/alpha/kernel/sys_jensen.c --- v2.3.48/linux/arch/alpha/kernel/sys_jensen.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_jensen.c Sun Feb 27 13:28:01 2000 @@ -71,7 +71,7 @@ enable: i8259a_enable_irq, disable: i8259a_disable_irq, ack: jensen_local_ack, - end: i8259a_enable_irq, + end: i8259a_end_irq, }; static void @@ -110,7 +110,6 @@ jensen_init_irq(void) { init_i8259a_irqs(); - init_rtc_irq(); irq_desc[1].handler = &jensen_local_irq_type; irq_desc[4].handler = &jensen_local_irq_type; diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c --- v2.3.48/linux/arch/alpha/kernel/sys_miata.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_miata.c Sun Feb 27 13:28:01 2000 @@ -70,7 +70,6 @@ #endif init_i8259a_irqs(); - init_rtc_irq(); /* Not interested in the bogus interrupts (3,10), Fan Fault (0), NMI (1), or EIDE (9). diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_mikasa.c linux/arch/alpha/kernel/sys_mikasa.c --- v2.3.48/linux/arch/alpha/kernel/sys_mikasa.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_mikasa.c Mon Feb 28 14:54:30 2000 @@ -48,7 +48,7 @@ mikasa_update_irq_hw(cached_irq_mask |= 1 << (irq - 16)); } -static inline void +static void mikasa_disable_irq(unsigned int irq) { mikasa_update_irq_hw(cached_irq_mask &= ~(1 << (irq - 16))); @@ -61,6 +61,13 @@ return 0; } +static void +mikasa_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + mikasa_enable_irq(irq); +} + static struct hw_interrupt_type mikasa_irq_type = { typename: "MIKASA", startup: mikasa_startup_irq, @@ -68,7 +75,7 @@ enable: mikasa_enable_irq, disable: mikasa_disable_irq, ack: mikasa_disable_irq, - end: mikasa_enable_irq, + end: mikasa_end_irq, }; static void @@ -108,12 +115,11 @@ mikasa_update_irq_hw(0); for (i = 16; i < 32; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &mikasa_irq_type; } init_i8259a_irqs(); - init_rtc_irq(); common_init_isa_dma(); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_nautilus.c linux/arch/alpha/kernel/sys_nautilus.c --- v2.3.48/linux/arch/alpha/kernel/sys_nautilus.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_nautilus.c Sun Feb 27 13:28:01 2000 @@ -54,7 +54,6 @@ nautilus_init_irq(void) { init_i8259a_irqs(); - init_rtc_irq(); common_init_isa_dma(); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_noritake.c linux/arch/alpha/kernel/sys_noritake.c --- v2.3.48/linux/arch/alpha/kernel/sys_noritake.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_noritake.c Mon Feb 28 14:54:30 2000 @@ -45,13 +45,13 @@ outw(mask, port); } -static inline void +static void noritake_enable_irq(unsigned int irq) { noritake_update_irq_hw(irq, cached_irq_mask |= 1 << (irq - 16)); } -static inline void +static void noritake_disable_irq(unsigned int irq) { noritake_update_irq_hw(irq, cached_irq_mask &= ~(1 << (irq - 16))); @@ -135,12 +135,11 @@ outw(0, 0x54c); for (i = 16; i < 48; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &noritake_irq_type; } init_i8259a_irqs(); - init_rtc_irq(); common_init_isa_dma(); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_rawhide.c linux/arch/alpha/kernel/sys_rawhide.c --- v2.3.48/linux/arch/alpha/kernel/sys_rawhide.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_rawhide.c Mon Feb 28 14:54:30 2000 @@ -41,6 +41,7 @@ 0xff0000, 0xfe0000, 0xff0000, 0xff0000 }; static unsigned int cached_irq_masks[4]; +spinlock_t rawhide_irq_lock = SPIN_LOCK_UNLOCKED; static inline void rawhide_update_irq_hw(int hose, int mask) @@ -50,7 +51,7 @@ *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose)); } -static void +static inline void rawhide_enable_irq(unsigned int irq) { unsigned int mask, hose; @@ -59,9 +60,11 @@ hose = irq / 24; irq -= hose * 24; + spin_lock(&rawhide_irq_lock); mask = cached_irq_masks[hose] |= 1 << irq; mask |= hose_irq_masks[hose]; rawhide_update_irq_hw(hose, mask); + spin_unlock(&rawhide_irq_lock); } static void @@ -73,9 +76,11 @@ hose = irq / 24; irq -= hose * 24; + spin_lock(&rawhide_irq_lock); mask = cached_irq_masks[hose] &= ~(1 << irq); mask |= hose_irq_masks[hose]; rawhide_update_irq_hw(hose, mask); + spin_unlock(&rawhide_irq_lock); } @@ -86,6 +91,13 @@ return 0; } +static void +rawhide_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + rawhide_enable_irq(irq); +} + static struct hw_interrupt_type rawhide_irq_type = { typename: "RAWHIDE", startup: rawhide_startup_irq, @@ -93,7 +105,7 @@ enable: rawhide_enable_irq, disable: rawhide_disable_irq, ack: rawhide_disable_irq, - end: rawhide_enable_irq, + end: rawhide_end_irq, }; static void @@ -138,12 +150,11 @@ } for (i = 16; i < 128; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &rawhide_irq_type; } init_i8259a_irqs(); - init_rtc_irq(); common_init_isa_dma(); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c --- v2.3.48/linux/arch/alpha/kernel/sys_ruffian.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_ruffian.c Sun Feb 27 13:28:01 2000 @@ -64,7 +64,7 @@ } static void __init -ruffian_init_rtc(struct irqaction *action) +ruffian_init_rtc(void) { /* Ruffian does not have the RTC connected to the CPU timer interrupt. Instead, it uses the PIT connected to IRQ 0. */ @@ -78,7 +78,7 @@ outb(0x31, 0x42); outb(0x13, 0x42); - setup_irq(0, action); + setup_irq(0, &timer_irqaction); } static void diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_rx164.c linux/arch/alpha/kernel/sys_rx164.c --- v2.3.48/linux/arch/alpha/kernel/sys_rx164.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_rx164.c Mon Feb 28 14:54:30 2000 @@ -65,6 +65,13 @@ return 0; } +static void +rx164_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + rx164_enable_irq(irq); +} + static struct hw_interrupt_type rx164_irq_type = { typename: "RX164", startup: rx164_startup_irq, @@ -72,7 +79,7 @@ enable: rx164_enable_irq, disable: rx164_disable_irq, ack: rx164_disable_irq, - end: rx164_enable_irq, + end: rx164_end_irq, }; static void @@ -109,12 +116,11 @@ rx164_update_irq_hw(0); for (i = 16; i < 40; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &rx164_irq_type; } init_i8259a_irqs(); - init_rtc_irq(); common_init_isa_dma(); setup_irq(16+20, &isa_cascade_irqaction); diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_sable.c linux/arch/alpha/kernel/sys_sable.c --- v2.3.48/linux/arch/alpha/kernel/sys_sable.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_sable.c Mon Feb 28 14:54:30 2000 @@ -30,6 +30,7 @@ #include "pci_impl.h" #include "machvec_impl.h" +spinlock_t sable_irq_lock = SPIN_LOCK_UNLOCKED; /* * For SABLE, which is really baroque, we manage 40 IRQ's, but the @@ -137,8 +138,10 @@ unsigned long bit, mask; bit = sable_irq_swizzle.irq_to_mask[irq]; + spin_lock(&sable_irq_lock); mask = sable_irq_swizzle.shadow_mask &= ~(1UL << bit); sable_update_irq_hw(bit, mask); + spin_unlock(&sable_irq_lock); } static void @@ -147,8 +150,10 @@ unsigned long bit, mask; bit = sable_irq_swizzle.irq_to_mask[irq]; + spin_lock(&sable_irq_lock); mask = sable_irq_swizzle.shadow_mask |= 1UL << bit; sable_update_irq_hw(bit, mask); + spin_unlock(&sable_irq_lock); } static unsigned int @@ -159,14 +164,23 @@ } static void +sable_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + sable_enable_irq(irq); +} + +static void sable_mask_and_ack_irq(unsigned int irq) { unsigned long bit, mask; bit = sable_irq_swizzle.irq_to_mask[irq]; + spin_lock(&sable_irq_lock); mask = sable_irq_swizzle.shadow_mask |= 1UL << bit; sable_update_irq_hw(bit, mask); sable_ack_irq_hw(bit); + spin_unlock(&sable_irq_lock); } static struct hw_interrupt_type sable_irq_type = { @@ -176,7 +190,7 @@ enable: sable_enable_irq, disable: sable_disable_irq, ack: sable_mask_and_ack_irq, - end: sable_enable_irq, + end: sable_end_irq, }; static void @@ -204,11 +218,10 @@ outb(0x44, 0x535); /* enable cascades in master */ for (i = 0; i < 40; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &sable_irq_type; } - init_rtc_irq(); common_init_isa_dma(); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_sio.c linux/arch/alpha/kernel/sys_sio.c --- v2.3.48/linux/arch/alpha/kernel/sys_sio.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/sys_sio.c Sun Feb 27 13:28:01 2000 @@ -42,7 +42,6 @@ alpha_mv.device_interrupt = srm_device_interrupt; init_i8259a_irqs(); - init_rtc_irq(); common_init_isa_dma(); } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c --- v2.3.48/linux/arch/alpha/kernel/sys_sx164.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_sx164.c Sun Feb 27 13:28:01 2000 @@ -43,7 +43,6 @@ alpha_mv.device_interrupt = srm_device_interrupt; init_i8259a_irqs(); - init_rtc_irq(); /* Not interested in the bogus interrupts (0,3,4,5,40-47), NMI (1), or HALT (2). */ diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/sys_takara.c linux/arch/alpha/kernel/sys_takara.c --- v2.3.48/linux/arch/alpha/kernel/sys_takara.c Sun Feb 20 21:12:38 2000 +++ linux/arch/alpha/kernel/sys_takara.c Mon Feb 28 14:54:30 2000 @@ -66,6 +66,13 @@ return 0; /* never anything pending */ } +static void +takara_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + takara_enable_irq(irq); +} + static struct hw_interrupt_type takara_irq_type = { typename: "TAKARA", startup: takara_startup_irq, @@ -73,7 +80,7 @@ enable: takara_enable_irq, disable: takara_disable_irq, ack: takara_disable_irq, - end: takara_enable_irq, + end: takara_end_irq, }; static void @@ -126,7 +133,6 @@ long i; init_i8259a_irqs(); - init_rtc_irq(); if (alpha_using_srm) { alpha_mv.device_interrupt = takara_srm_device_interrupt; @@ -146,7 +152,7 @@ takara_update_irq_hw(i, -1); for (i = 16; i < 128; ++i) { - irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].handler = &takara_irq_type; } diff -u --recursive --new-file v2.3.48/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c --- v2.3.48/linux/arch/alpha/kernel/time.c Sat Feb 26 22:31:38 2000 +++ linux/arch/alpha/kernel/time.c Sun Feb 27 13:28:01 2000 @@ -163,7 +163,7 @@ } void -common_init_rtc(struct irqaction *action) +common_init_rtc() { unsigned char x; @@ -192,18 +192,12 @@ outb(0x31, 0x42); outb(0x13, 0x42); - setup_irq(RTC_IRQ, action); + init_rtc_irq(); } void time_init(void) { - static struct irqaction timer_irqaction = { - handler: timer_interrupt, - flags: SA_INTERRUPT, - name: "timer", - }; - unsigned int year, mon, day, hour, min, sec, cc1, cc2; unsigned long cycle_freq, one_percent; long diff; @@ -292,7 +286,9 @@ state.partial_tick = 0L; /* Startup the timer source. */ - alpha_mv.init_rtc(&timer_irqaction); + alpha_mv.init_rtc(); + + do_get_fast_time = do_gettimeofday; } /* diff -u --recursive --new-file v2.3.48/linux/arch/alpha/mm/fault.c linux/arch/alpha/mm/fault.c --- v2.3.48/linux/arch/alpha/mm/fault.c Tue Nov 23 22:42:20 1999 +++ linux/arch/alpha/mm/fault.c Thu Mar 2 11:35:17 2000 @@ -38,9 +38,18 @@ unsigned long last_asn = ASN_FIRST_VERSION; #endif -void ev5_flush_tlb_current(struct mm_struct *mm) +extern void +__load_new_mm_context(struct mm_struct *next_mm) { - ev5_activate_mm(NULL, mm, smp_processor_id()); + unsigned long mmc; + + mmc = __get_new_mm_context(next_mm, smp_processor_id()); + next_mm->context = mmc; + current->thread.asn = mmc & HARDWARE_ASN_MASK; + current->thread.ptbr + = ((unsigned long) next_mm->pgd - IDENT_ADDR) >> PAGE_SHIFT; + + __reload_thread(¤t->thread); } diff -u --recursive --new-file v2.3.48/linux/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile --- v2.3.48/linux/arch/arm/boot/compressed/Makefile Fri Jan 21 18:19:15 2000 +++ linux/arch/arm/boot/compressed/Makefile Mon Feb 28 14:16:37 2000 @@ -46,13 +46,12 @@ ifeq ($(CONFIG_ARCH_SA1100),y) OBJS += head-sa1100.o -ifeq ($(CONFIG_SA1100_VICTOR),y) -ZTEXTADDR = 0x00002000 -ZBSSADDR = 0xc0100000 -else ZTEXTADDR = 0xc0008000 -endif ZRELADDR = 0xc0008000 +ifeq ($(CONFIG_SA1100_VICTOR),y) + ZTEXTADDR = 0x00002000 + ZBSSADDR = 0xc0100000 +endif endif # diff -u --recursive --new-file v2.3.48/linux/arch/arm/boot/compressed/head-sa1100.S linux/arch/arm/boot/compressed/head-sa1100.S --- v2.3.48/linux/arch/arm/boot/compressed/head-sa1100.S Fri Jan 21 18:19:15 2000 +++ linux/arch/arm/boot/compressed/head-sa1100.S Mon Feb 28 14:16:37 2000 @@ -11,6 +11,8 @@ .section ".start", #alloc, #execinstr +__SA1100_start: + #ifndef CONFIG_ARCH_SA1100 #error What am I doing here... #endif @@ -57,6 +59,65 @@ bic r0, r0, #0x0d @ clear WB, DC, MMU orr r0, r0, #0x1000 @ set Icache mcr p15, 0, r0, c1, c0, 0 + +#ifdef CONFIG_SA1100_BRUTUS + @ Initialize UART1 for early serial communication + @ since UART3 is used by angelboot. It is routed to + @ alternate GPIO functions on Brutus. + b 1f + +GPIO_BASE: .long 0x90040000 +#define GPDR 0x04 +#define GAFR 0x1c + +PPC_BASE: .long 0x90060000 +#define PPAR 0x08 + +UART1_BASE: .long 0x80010000 +#define UTCR0 0x00 +#define UTCR1 0x04 +#define UTCR2 0x08 +#define UTCR3 0x0c +#define UTSR0 0x1c +#define UTSR1 0x20 + +#define BAUD_DIV_230400 0x000 +#define BAUD_DIV_115200 0x001 +#define BAUD_DIV_57600 0x003 +#define BAUD_DIV_38400 0x005 +#define BAUD_DIV_19200 0x00b +#define BAUD_DIV_9600 0x017 +#define BAUD_DIV BAUD_DIV_9600 + +1: ldr r0, GPIO_BASE + ldr r1, [r0, #GPDR] + bic r1, r1, #1<<15 + orr r1, r1, #1<<14 + str r1, [r0, #GPDR] + ldr r1, [r0, #GAFR] + orr r1, r1, #(1<<15)|(1<<14) + str r1, [r0, #GAFR] + ldr r0, PPC_BASE + ldr r1, [r0, #PPAR] + orr r1, r1, #1<<12 + str r1, [r0, #PPAR] + ldr r0, UART1_BASE +1: ldr r1, [r0, #UTSR1] + tst r1, #1<<0 @ TBY + bne 1b + mov r1, #0 + str r1, [r0, #UTCR3] + mov r1, #0x08 @ 8N1 + str r1, [r0, #UTCR0] + mov r1, #BAUD_DIV + str r1, [r0, #UTCR2] + mov r1, r1, lsr #8 + str r1, [r0, #UTCR1] + mov r1, #0x03 @ RXE + TXE + str r1, [r0, #UTCR3] + mov r1, #0xff @ flush status reg + str r1, [r0, #UTSR0] +#endif @ set registers for entry mov r0, #0 diff -u --recursive --new-file v2.3.48/linux/arch/arm/config.in linux/arch/arm/config.in --- v2.3.48/linux/arch/arm/config.in Fri Jan 21 18:19:15 2000 +++ linux/arch/arm/config.in Mon Feb 28 14:16:37 2000 @@ -92,6 +92,8 @@ if [ "$CONFIG_ARCH_EBSA110" = "y" -o \ "$CONFIG_ARCH_SA1100" = "y" -o \ "$CONFIG_FOOTBRIDGE" = "y" -o \ + "$CONFIG_ARCH_TBOX" = "y" -o \ + "$CONFIG_ARCH_SHARK" = "y" -o \ "$CONFIG_ARCH_NEXUSPCI" = "y" ]; then define_bool CONFIG_CPU_32v4 y if [ "$CONFIG_ARCH_SA1100" = "y" ]; then @@ -122,6 +124,7 @@ # These machines have ISA-DMA # if [ "$CONFIG_CATS" = "y" -o \ + "$CONFIG_ARCH_SHARK" = "y" -o \ "$CONFIG_ARCH_NETWINDER" = "y" ]; then define_bool CONFIG_ISA_DMA y else @@ -186,6 +189,8 @@ fi endmenu +source drivers/ieee1394/Config.in + source drivers/i2o/Config.in source drivers/pnp/Config.in @@ -209,6 +214,8 @@ source drivers/usb/Config.in +source drivers/misc/Config.in + if [ "$CONFIG_VT" = "y" ]; then mainmenu_option next_comment comment 'Console drivers' @@ -256,7 +263,10 @@ fi endmenu -if [ "$CONFIG_ARCH_ACORN" = "y" -o "$CONFIG_PCI" = "y" ]; then +if [ "$CONFIG_ARCH_ACORN" = "y" -o \ + "$CONFIG_ARCH_CLPS7500" = "y" -o \ + "$CONFIG_ARCH_SHARK" = "y" -o \ + "$CONFIG_PCI" = "y" ]; then mainmenu_option next_comment comment 'Sound' diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/arthur.c linux/arch/arm/kernel/arthur.c --- v2.3.48/linux/arch/arm/kernel/arthur.c Thu Jun 17 01:11:35 1999 +++ linux/arch/arm/kernel/arthur.c Mon Feb 28 14:16:37 2000 @@ -1,6 +1,6 @@ /* * Arthur personality - * Copyright (C) 1998 Philip Blundell + * Copyright (C) 1998-1999 Philip Blundell */ #include @@ -8,35 +8,36 @@ #include #include #include +#include #include -/* RISC OS doesn't have many signals, and a lot of those that it does +/* Arthur doesn't have many signals, and a lot of those that it does have don't map easily to any Linux equivalent. Never mind. */ -#define RISCOS_SIGABRT 1 -#define RISCOS_SIGFPE 2 -#define RISCOS_SIGILL 3 -#define RISCOS_SIGINT 4 -#define RISCOS_SIGSEGV 5 -#define RISCOS_SIGTERM 6 -#define RISCOS_SIGSTAK 7 -#define RISCOS_SIGUSR1 8 -#define RISCOS_SIGUSR2 9 -#define RISCOS_SIGOSERROR 10 +#define ARTHUR_SIGABRT 1 +#define ARTHUR_SIGFPE 2 +#define ARTHUR_SIGILL 3 +#define ARTHUR_SIGINT 4 +#define ARTHUR_SIGSEGV 5 +#define ARTHUR_SIGTERM 6 +#define ARTHUR_SIGSTAK 7 +#define ARTHUR_SIGUSR1 8 +#define ARTHUR_SIGUSR2 9 +#define ARTHUR_SIGOSERROR 10 -static unsigned long riscos_to_linux_signals[32] = { +static unsigned long arthur_to_linux_signals[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 }; -static unsigned long linux_to_riscos_signals[32] = { - 0, -1, RISCOS_SIGINT, -1, - RISCOS_SIGILL, 5, RISCOS_SIGABRT, 7, - RISCOS_SIGFPE, 9, RISCOS_SIGUSR1, RISCOS_SIGSEGV, - RISCOS_SIGUSR2, 13, 14, RISCOS_SIGTERM, +static unsigned long linux_to_arthur_signals[32] = { + 0, -1, ARTHUR_SIGINT, -1, + ARTHUR_SIGILL, 5, ARTHUR_SIGABRT, 7, + ARTHUR_SIGFPE, 9, ARTHUR_SIGUSR1, ARTHUR_SIGSEGV, + ARTHUR_SIGUSR2, 13, 14, ARTHUR_SIGTERM, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, @@ -52,12 +53,12 @@ send_sig_info(SIGSWI, &info, current); } -static struct exec_domain riscos_exec_domain = { +static struct exec_domain arthur_exec_domain = { "Arthur", /* name */ (lcall7_func)arthur_lcall7, PER_RISCOS, PER_RISCOS, - riscos_to_linux_signals, - linux_to_riscos_signals, + arthur_to_linux_signals, + linux_to_arthur_signals, #ifdef MODULE &__this_module, /* No usage counter. */ #else @@ -71,18 +72,15 @@ * processes are using it. */ -#ifdef MODULE -int init_module(void) -#else -int initialise_arthur(void) -#endif +int __init arthur_init(void) { - return register_exec_domain(&riscos_exec_domain); + return register_exec_domain(&arthur_exec_domain); } -#ifdef MODULE -void cleanup_module(void) +void __exit arthur_exit(void) { - unregister_exec_domain(&riscos_exec_domain); + unregister_exec_domain(&arthur_exec_domain); } -#endif + +module_init(arthur_init); +module_exit(arthur_exit); diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/entry-armo.S linux/arch/arm/kernel/entry-armo.S --- v2.3.48/linux/arch/arm/kernel/entry-armo.S Fri Jan 21 18:19:15 2000 +++ linux/arch/arm/kernel/entry-armo.S Mon Feb 28 14:16:37 2000 @@ -22,6 +22,7 @@ * adhering to the above criteria. */ #include +#include #include #include @@ -29,6 +30,12 @@ #include "../lib/constants.h" + .macro zero_fp +#ifdef CONFIG_FRAME_POINTER + mov fp, #0 +#endif + .endm + .text @ Offsets into task structure @@ -213,7 +220,7 @@ stmfd sp!, {r0 - r12} ;\ mov r0, #-1 ;\ str r0, [sp, #S_OLD_R0] ;\ - mov fp, #0 + zero_fp #define SVC_IRQ_SAVE_ALL \ str sp, [sp, #-16]! ;\ @@ -224,7 +231,7 @@ stmfd sp!, {r0 - r12} ;\ mov r0, #-1 ;\ str r0, [sp, #S_OLD_R0] ;\ - mov fp, #0 + zero_fp #define SVC_RESTORE_ALL \ ldmfd sp, {r0 - pc}^ @@ -261,7 +268,7 @@ tst lr,#3 bne __und_svc save_user_regs - mov fp, #0 + zero_fp teqp pc, #I_BIT | MODE_SVC .Lbug_undef: ldr r4, .LC2 @@ -283,6 +290,10 @@ bl SYMBOL_NAME(do_undefinstr) SVC_RESTORE_ALL +#ifdef CONFIG_NWFPE + /* The FPE is always present */ + .equ fpe_not_present, 0 +#else /* We get here if an undefined instruction happens and the floating * point emulator is not present. If the offending instruction was * a WFS, we just perform a normal return as if we had emulated the @@ -319,6 +330,7 @@ .word 0x0d0d0100 @ LDF [sp]/STF [sp] .word 0x0d0b0100 @ LDF [fp]/STF [fp] .word 0x0f0f0f00 +#endif .LC2: .word SYMBOL_NAME(fp_enter) @@ -686,7 +698,7 @@ /* * initialise the trap system */ -ENTRY(trap_init) +ENTRY(__trap_init) stmfd sp!, {r4 - r7, lr} adr r1, .Ljump_addresses ldmia r1, {r1 - r7, ip, lr} diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S --- v2.3.48/linux/arch/arm/kernel/entry-armv.S Fri Jan 21 18:19:15 2000 +++ linux/arch/arm/kernel/entry-armv.S Mon Feb 28 14:16:37 2000 @@ -24,6 +24,12 @@ #define MODE_SVC 0x13 #endif + .macro zero_fp +#ifdef CONFIG_FRAME_POINTER + mov fp, #0 +#endif + .endm + .text #define PF_TRACESYS 0x20 @@ -421,7 +427,7 @@ ldr r4, .LCund mov r1, #BAD_UNDEFINSTR @ int reason -1: mov fp, #0 +1: zero_fp ldmia r4, {r5 - r7} @ Get XXX pc, cpsr, old_r0 add r4, sp, #S_PC stmia r4, {r5 - r7} @ Save XXX pc, cpsr, old_r0 @@ -573,7 +579,7 @@ stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0 stmdb r3, {sp, lr}^ alignment_trap r4, r7, __temp_abt - mov fp, #0 + zero_fp #ifdef MULTI_CPU ldr r2, .LCprocfns mov lr, pc @@ -595,7 +601,7 @@ stmia r8, {r5 - r7} @ save pc, psr, old_r0 stmdb r8, {sp, lr}^ alignment_trap r4, r7, __temp_irq - mov fp, #0 + zero_fp 1: get_irqnr_and_base r0, r6, r5 movne r1, sp adrsvc ne, lr, 1b @@ -615,7 +621,7 @@ stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 stmdb r8, {sp, lr}^ @ Save user r0 - r12 alignment_trap r4, r7, __temp_und - mov fp, #0 + zero_fp adrsvc al, r9, ret_from_sys_call @ r9 = normal FP return adrsvc al, lr, fpundefinstr @ lr = undefined instr return @@ -641,7 +647,7 @@ stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr alignment_trap r4, r7, __temp_abt - mov fp, #0 + zero_fp msr cpsr_c, #MODE_SVC @ Enable interrupts mov r0, r5 @ address (pc) mov r1, sp @ regs @@ -688,11 +694,11 @@ ENTRY(__switch_to) stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack mrs ip, cpsr - stmfd sp!, {ip} @ Save cpsr_SVC + str ip, [sp, #-4]! @ Save cpsr_SVC str sp, [r0, #TSS_SAVE] @ Save sp_SVC ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC ldr r2, [r1, #TSS_DOMAIN] - ldmfd sp!, {ip} + ldr ip, [sp], #4 mcr p15, 0, r2, c3, c0 @ Set domain register msr spsr, ip @ Save tasks CPSR into SPSR for this return ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/entry-common.S linux/arch/arm/kernel/entry-common.S --- v2.3.48/linux/arch/arm/kernel/entry-common.S Sun Feb 13 19:29:03 2000 +++ linux/arch/arm/kernel/entry-common.S Mon Feb 28 14:16:37 2000 @@ -4,16 +4,6 @@ */ #define S_OFF 8 -#define SYSCALL_REGS r4, r5 - -/* - * Define to favour ARM8, ARM9 and StrongARM cpus. This says that it is - * cheaper to use two LDR instructions than a two-register LDM, if the - * latter would entail calculating an address specially. - */ -#if defined(CONFIG_CPU_SA110) -#define HARVARD_CACHE -#endif .macro get_softirq, rd #ifdef __SMP__ @@ -85,7 +75,7 @@ .align 5 vector_swi: save_user_regs mask_pc lr, lr - mov fp, #0 + zero_fp ldr scno, [lr, #-4] @ get SWI instruction arm700_bug_check scno, ip #ifdef CONFIG_ALIGNMENT_TRAP @@ -95,9 +85,7 @@ #endif enable_irqs ip - stmdb sp!, {SYSCALL_REGS} @ new style: (r0 = arg1, r4 = arg5, r5 = arg6) - @ Note that we dont have to handle - @ sys_syscalls arg7 here + str r4, [sp, #-S_OFF]! @ push fifth arg adrsvc al, lr, fast_syscall_return bic scno, scno, #0xff000000 @ mask off SWI op-code @@ -141,10 +129,11 @@ b SYMBOL_NAME(deferred) .align 5 - + .type __softirq_state, #object __softirq_state: .word SYMBOL_NAME(softirq_state) + .type sys_call_table, #object ENTRY(sys_call_table) #include "calls.S" @@ -153,15 +142,18 @@ */ @ r0 = syscall number @ r5 = syscall table + .type sys_syscall, #function SYMBOL_NAME(sys_syscall): eor scno, r0, #OS_NUMBER << 20 cmp scno, #NR_syscalls @ check range add ip, sp, #S_OFF - ldmleib ip, {r0 - r3, SYSCALL_REGS} @ get our args - stmleia sp, {SYSCALL_REGS} @ Put our arg on the stack + stmleia sp, {r5, r6} @ shuffle args + movle r0, r1 + movle r1, r2 + movle r2, r3 + movle r3, r4 ldrle pc, [tbl, scno, lsl #2] - mov r0, #-ENOSYS - RETINSTR(mov,pc,lr) + b sys_ni_syscall sys_fork_wrapper: add r0, sp, #S_OFF @@ -198,6 +190,23 @@ sys_sigaltstack_wrapper: ldr r2, [sp, #S_OFF + S_SP] b do_sigaltstack + +/* + * Note: off_4k (r5) is always units of 4K. If we can't do the requested + * offset, we return EINVAL. + */ +sys_mmap2: +#if PAGE_SHIFT > 12 + tst r5, #PGOFF_MASK + moveq r5, r5, lsr #PGOFF_SHIFT + streq r5, [sp, #4] + beq do_mmap2 + mov r0, #-EINVAL + RETINSTR(mov,pc, lr) +#else + str r5, [sp, #4] + b do_mmap2 +#endif .data diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/hw-footbridge.c linux/arch/arm/kernel/hw-footbridge.c --- v2.3.48/linux/arch/arm/kernel/hw-footbridge.c Tue Dec 14 01:27:23 1999 +++ linux/arch/arm/kernel/hw-footbridge.c Sun Feb 27 08:51:11 2000 @@ -68,13 +68,13 @@ /* * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE */ -spinlock_t __netwinder_data gpio_lock = SPIN_LOCK_UNLOCKED; +spinlock_t gpio_lock = SPIN_LOCK_UNLOCKED; -static unsigned int __netwinder_data current_gpio_op = 0; -static unsigned int __netwinder_data current_gpio_io = 0; -static unsigned int __netwinder_data current_cpld = 0; +static unsigned int current_gpio_op = 0; +static unsigned int current_gpio_io = 0; +static unsigned int current_cpld = 0; -void __netwinder_text gpio_modify_op(int mask, int set) +void gpio_modify_op(int mask, int set) { unsigned int new_gpio, changed; @@ -119,7 +119,7 @@ } } -void __netwinder_text gpio_modify_io(int mask, int in) +void gpio_modify_io(int mask, int in) { /* Open up the SuperIO chip */ wb977_open(); @@ -130,7 +130,7 @@ wb977_close(); } -int __netwinder_text gpio_read(void) +int gpio_read(void) { return inb(GP1_IO_BASE) | inb(GP2_IO_BASE) << 8; } @@ -360,7 +360,7 @@ wb977_close(); } -void __netwinder_text cpld_modify(int mask, int set) +void cpld_modify(int mask, int set) { int msk; diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c --- v2.3.48/linux/arch/arm/kernel/irq.c Sun Feb 13 19:29:03 2000 +++ linux/arch/arm/kernel/irq.c Sun Feb 27 08:51:11 2000 @@ -471,6 +471,10 @@ return irq_found; } +void __init init_irq_proc(void) +{ +} + void __init init_IRQ(void) { extern void init_dma(void); diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/leds-footbridge.c linux/arch/arm/kernel/leds-footbridge.c --- v2.3.48/linux/arch/arm/kernel/leds-footbridge.c Fri Oct 22 13:21:44 1999 +++ linux/arch/arm/kernel/leds-footbridge.c Sun Feb 27 08:51:11 2000 @@ -37,7 +37,7 @@ #ifdef CONFIG_FOOTBRIDGE -static void __ebsa285_text ebsa285_leds_event(led_event_t evt) +static void ebsa285_leds_event(led_event_t evt) { unsigned long flags; @@ -129,7 +129,7 @@ #ifdef CONFIG_ARCH_NETWINDER -static void __netwinder_text netwinder_leds_event(led_event_t evt) +static void netwinder_leds_event(led_event_t evt) { unsigned long flags; diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c --- v2.3.48/linux/arch/arm/kernel/setup.c Fri Jan 21 18:19:15 2000 +++ linux/arch/arm/kernel/setup.c Sun Feb 27 08:51:11 2000 @@ -767,6 +767,8 @@ setup_bootmem(); request_standard_resources(mdesc); + paging_init(); + #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) conswitchp = &vga_con; diff -u --recursive --new-file v2.3.48/linux/arch/arm/kernel/sys_arm.c linux/arch/arm/kernel/sys_arm.c --- v2.3.48/linux/arch/arm/kernel/sys_arm.c Fri Jan 28 15:09:06 2000 +++ linux/arch/arm/kernel/sys_arm.c Mon Feb 28 14:16:37 2000 @@ -50,7 +50,7 @@ } /* common code for old and new mmaps */ -static inline long do_mmap2( +inline long do_mmap2( unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) @@ -77,27 +77,6 @@ fput(file); out: return error; -} - -#define PGOFF_SHIFT (PAGE_SHIFT - 12) -#define PGOFF_MASK (~((1 << PGOFF_SHIFT) - 1)) - -/* - * Note: off_4k is always units of 4K. If we can't do the requested - * offset, we return EINVAL. - */ -asmlinkage long -sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, - unsigned long flags, unsigned long fd, unsigned long off_4k) -{ - unsigned long pgoff; - - if (off_4k & ~PGOFF_MASK) - return -EINVAL; - - pgoff = off_4k >> PGOFF_SHIFT; - - return do_mmap2(addr, len, prot, flags, fd, pgoff); } struct mmap_arg_struct { diff -u --recursive --new-file v2.3.48/linux/arch/arm/lib/findbit.S linux/arch/arm/lib/findbit.S --- v2.3.48/linux/arch/arm/lib/findbit.S Fri Jan 21 18:19:16 2000 +++ linux/arch/arm/lib/findbit.S Mon Feb 28 14:16:37 2000 @@ -53,10 +53,10 @@ beq Lfindzbit1lp @ If new byte, goto old routine ldrb r3, [r0, r2, lsr#3] orr r3, r3, #0xFF00 @ Set top bits so we wont get confused - stmfd sp!, {r4} + str r4, [sp, #-4]! and r4, r2, #7 mov r3, r3, lsr r4 @ Shift right by no. of bits - ldmfd sp!, {r4} + ldr r4, [sp], #4 and r3, r3, #0xFF teq r3, #0xFF orreq r2, r2, #7 diff -u --recursive --new-file v2.3.48/linux/arch/arm/lib/getconsdata.c linux/arch/arm/lib/getconsdata.c --- v2.3.48/linux/arch/arm/lib/getconsdata.c Fri Jan 21 18:19:16 2000 +++ linux/arch/arm/lib/getconsdata.c Mon Feb 28 14:16:37 2000 @@ -91,3 +91,5 @@ unsigned long KSWI_BASE = 0x900000; unsigned long KSWI_SYS_BASE = 0x9f0000; unsigned long SYS_ERROR0 = 0x9f0000; +unsigned long PGOFF_SHIFT = PAGE_SHIFT - 12; +unsigned long PGOFF_MASK = (1 << (PAGE_SHIFT - 12)) - 1; diff -u --recursive --new-file v2.3.48/linux/arch/arm/lib/strrchr.S linux/arch/arm/lib/strrchr.S --- v2.3.48/linux/arch/arm/lib/strrchr.S Fri Jan 21 18:19:16 2000 +++ linux/arch/arm/lib/strrchr.S Mon Feb 28 14:16:37 2000 @@ -12,7 +12,7 @@ .text ENTRY(strrchr) - stmfd sp!, {lr} + str lr, [sp, #-4]! mov r3, #0 1: ldrb r2, [r0], #1 teq r2, r1 diff -u --recursive --new-file v2.3.48/linux/arch/arm/mm/consistent.c linux/arch/arm/mm/consistent.c --- v2.3.48/linux/arch/arm/mm/consistent.c Sat Feb 26 22:31:38 2000 +++ linux/arch/arm/mm/consistent.c Mon Feb 28 14:16:37 2000 @@ -1,13 +1,14 @@ /* * Dynamic DMA mapping support. */ - +#include #include #include #include #include #include #include +#include #include #include @@ -47,6 +48,22 @@ no_page: BUG(); return NULL; +} + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *handle) +{ + void *__ret; + int __gfp = GFP_KERNEL; + +#ifdef CONFIG_PCI + if ((hwdev) == NULL || + (hwdev)->dma_mask != 0xffffffff) +#endif + __gfp |= GFP_DMA; + + __ret = consistent_alloc(__gfp, (size), + (handle)); + return __ret; } /* diff -u --recursive --new-file v2.3.48/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c --- v2.3.48/linux/arch/arm/mm/fault-armv.c Fri Jan 21 18:19:16 2000 +++ linux/arch/arm/mm/fault-armv.c Mon Feb 28 14:16:37 2000 @@ -351,7 +351,7 @@ #endif -static struct fsr_info { +static const struct fsr_info { int (*fn)(unsigned long addr, int error_code, struct pt_regs *regs); int sig; char *name; @@ -384,7 +384,7 @@ asmlinkage void do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs) { - struct fsr_info *inf; + const struct fsr_info *inf; if (user_mode(regs) && addr == regs->ARM_pc) { static int first = 1; diff -u --recursive --new-file v2.3.48/linux/arch/arm/mm/fault-common.c linux/arch/arm/mm/fault-common.c --- v2.3.48/linux/arch/arm/mm/fault-common.c Fri Jan 21 18:19:16 2000 +++ linux/arch/arm/mm/fault-common.c Mon Feb 28 14:16:37 2000 @@ -6,7 +6,7 @@ */ #include -extern void die(const char *msg, struct pt_regs *regs, unsigned int err); +extern void die(const char *msg, struct pt_regs *regs, int err); /* * This is useful to dump out the page tables associated with diff -u --recursive --new-file v2.3.48/linux/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c --- v2.3.48/linux/arch/arm/mm/mm-armv.c Thu Feb 10 17:11:03 2000 +++ linux/arch/arm/mm/mm-armv.c Sun Feb 27 08:51:11 2000 @@ -60,6 +60,8 @@ __setup("nocache", nocache_setup); __setup("nowb", nowrite_setup); +#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) + /* * need to get a 16k page for level 1 */ @@ -71,9 +73,9 @@ if (pgd) { pgd_t *init = pgd_offset_k(0); - memzero(pgd, USER_PTRS_PER_PGD * sizeof(pgd_t)); - memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + memzero(pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); + memcpy(pgd + FIRST_KERNEL_PGD_NR, init + FIRST_KERNEL_PGD_NR, + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); clean_cache_area(pgd, PTRS_PER_PGD * sizeof(pgd_t)); /* diff -u --recursive --new-file v2.3.48/linux/arch/arm/mm/mm-clps7500.c linux/arch/arm/mm/mm-clps7500.c --- v2.3.48/linux/arch/arm/mm/mm-clps7500.c Wed Dec 31 16:00:00 1969 +++ linux/arch/arm/mm/mm-clps7500.c Mon Feb 28 14:16:37 2000 @@ -0,0 +1,28 @@ +/* + * arch/arm/mm/mm-cl7500.c + * + * Extra MM routines for CL7500 architecture + * + * Copyright (C) 1998 Russell King + * Copyright (C) 1999 Nexus Electronics Ltd + */ + +#include + +#include +#include +#include +#include + +#include "map.h" + +#define SIZE(x) (sizeof(x) / sizeof(x[0])) + +struct map_desc io_desc[] __initdata = { + { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1 }, /* IO space */ + { ISA_BASE, ISA_START, ISA_SIZE , DOMAIN_IO, 0, 1 }, /* ISA space */ + { FLASH_BASE, FLASH_START, FLASH_SIZE, DOMAIN_IO, 0, 1 }, /* Flash */ + { LED_BASE, LED_START, LED_SIZE , DOMAIN_IO, 0, 1 } /* LED */ +}; + +unsigned int __initdata io_desc_size = SIZE(io_desc); diff -u --recursive --new-file v2.3.48/linux/arch/arm/mm/mm-nexuspci.c linux/arch/arm/mm/mm-nexuspci.c --- v2.3.48/linux/arch/arm/mm/mm-nexuspci.c Mon Nov 1 13:56:26 1999 +++ linux/arch/arm/mm/mm-nexuspci.c Mon Feb 28 14:16:37 2000 @@ -2,9 +2,9 @@ * arch/arm/mm/mm-nexuspci.c * from arch/arm/mm/mm-ebsa110.c * - * Extra MM routines for the NexusPCI architecture + * Extra MM routines for the FTV/PCI architecture * - * Copyright (C) 1998 Phil Blundell + * Copyright (C) 1998-1999 Phil Blundell * Copyright (C) 1998-1999 Russell King */ @@ -18,14 +18,14 @@ #include "map.h" -#define SIZE(x) (sizeof(x) / sizeof(x[0])) - -const struct map_desc io_desc[] __initdata = { - { 0xfff00000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffe00000, 0x20000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xffc00000, 0x60000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xfe000000, 0x80000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, - { 0xfd000000, 0x88000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 } +struct map_desc io_desc[] __initdata = { + { INTCONT_BASE, INTCONT_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, + { PLX_BASE, PLX_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, + { PCIO_BASE, PLX_IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, + { DUART_BASE, DUART_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, + { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 } }; + +#define SIZE(x) (sizeof(x) / sizeof(x[0])) unsigned int __initdata io_desc_size = SIZE(io_desc); diff -u --recursive --new-file v2.3.48/linux/arch/arm/vmlinux-armo.lds.in linux/arch/arm/vmlinux-armo.lds.in --- v2.3.48/linux/arch/arm/vmlinux-armo.lds.in Mon Nov 1 13:56:26 1999 +++ linux/arch/arm/vmlinux-armo.lds.in Mon Feb 28 14:16:37 2000 @@ -28,6 +28,11 @@ *(.init.task) } + /DISCARD/ : { /* Exit code and data */ + *(.text.exit) + *(.data.exit) + } + _text = .; /* Text and read-only data */ .text : { *(.text) diff -u --recursive --new-file v2.3.48/linux/arch/arm/vmlinux-armv.lds.in linux/arch/arm/vmlinux-armv.lds.in --- v2.3.48/linux/arch/arm/vmlinux-armv.lds.in Fri Jan 21 18:19:16 2000 +++ linux/arch/arm/vmlinux-armv.lds.in Sun Feb 27 08:51:11 2000 @@ -25,22 +25,6 @@ __init_end = .; } - .ebsa285 : { - __ebsa285_begin = .; - *(.text.ebsa285) - *(.data.ebsa285) - . = ALIGN(4096); - __ebsa285_end = .; - } - - .netwinder : { - __netwinder_begin = .; - *(.text.netwinder) - *(.data.netwinder) - . = ALIGN(4096); - __netwinder_end = .; - } - .text : { /* Real text segment */ _text = .; /* Text and read-only data */ *(.text) @@ -65,11 +49,26 @@ . = ALIGN(8192); - .data : { /* Data */ + .data : { + /* + * first, the init task union, aligned + * to an 8192 byte boundary. + */ *(.init.task) + + /* + * then the cacheline aligned data + */ + . = ALIGN(32); + *(.data.cacheline_aligned) + + /* + * and the usual data section + */ *(.data) CONSTRUCTORS - _edata = .; /* End of data section */ + + _edata = .; } .bss : { diff -u --recursive --new-file v2.3.48/linux/arch/i386/config.in linux/arch/i386/config.in --- v2.3.48/linux/arch/i386/config.in Sun Feb 20 21:12:38 2000 +++ linux/arch/i386/config.in Thu Mar 2 10:10:24 2000 @@ -49,8 +49,8 @@ define_bool CONFIG_X86_USE_3DNOW y fi -if [ "$CONFIG_PROC_FS" = "y" ]; then - tristate '/proc/driver/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE +if [ "$CONFIG_DEVFS_FS" = "y" ]; then + tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE fi choice 'High Memory Support' \ @@ -139,30 +139,31 @@ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC -source drivers/parport/Config.in +bool 'Power Management support' CONFIG_PM -bool 'ACPI support' CONFIG_ACPI +dep_bool ' ACPI support' CONFIG_ACPI $CONFIG_PM if [ "$CONFIG_ACPI" != "n" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP + bool ' Enter S1 for sleep (EXPERIMENTAL)' CONFIG_ACPI_S1_SLEEP fi fi -tristate 'Advanced Power Management BIOS support' CONFIG_APM +dep_tristate ' Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM if [ "$CONFIG_APM" != "n" ]; then - bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND - 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' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND - 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 + bool ' Ignore USER SUSPEND' CONFIG_APM_IGNORE_USER_SUSPEND + 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' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND + 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 fi endmenu +source drivers/parport/Config.in source drivers/pnp/Config.in diff -u --recursive --new-file v2.3.48/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.3.48/linux/arch/i386/defconfig Sat Feb 26 22:31:38 2000 +++ linux/arch/i386/defconfig Thu Mar 2 13:29:23 2000 @@ -27,7 +27,6 @@ CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_PGE=y -# CONFIG_MICROCODE is not set CONFIG_NOHIGHMEM=y # CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set @@ -74,9 +73,10 @@ CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y -# CONFIG_PARPORT is not set +CONFIG_PM=y CONFIG_ACPI=y # CONFIG_APM is not set +# CONFIG_PARPORT is not set # # Plug and Play configuration @@ -96,6 +96,7 @@ # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -264,6 +265,7 @@ # # CONFIG_ARCNET is not set CONFIG_DUMMY=m +# CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_NET_SB1000 is not set diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/Makefile linux/arch/i386/kernel/Makefile --- v2.3.48/linux/arch/i386/kernel/Makefile Wed Feb 16 17:03:51 2000 +++ linux/arch/i386/kernel/Makefile Thu Mar 2 10:10:24 2000 @@ -40,14 +40,12 @@ endif endif -ifeq ($(CONFIG_PROC_FS),y) ifeq ($(CONFIG_MICROCODE),y) OX_OBJS += microcode.o else ifeq ($(CONFIG_MICROCODE),m) MX_OBJS += microcode.o endif -endif endif ifeq ($(CONFIG_ACPI),y) diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/acpi.c linux/arch/i386/kernel/acpi.c --- v2.3.48/linux/arch/i386/kernel/acpi.c Sat Feb 26 22:31:38 2000 +++ linux/arch/i386/kernel/acpi.c Mon Feb 28 12:10:06 2000 @@ -977,11 +977,9 @@ typa = ((typa << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK); typb = ((typb << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK); - if (state != ACPI_S0) { - acpi_sleep_start = get_cmos_time(); - acpi_enter_dx(ACPI_D3); - acpi_sleep_state = state; - } + acpi_sleep_start = get_cmos_time(); + acpi_enter_dx(ACPI_D3); + acpi_sleep_state = state; // clear wake status acpi_write_pm1_status(acpi_facp, ACPI_WAK); @@ -996,17 +994,11 @@ outw(value | typb | ACPI_SLP_EN, acpi_facp->pm1b_cnt); } - if (state == ACPI_S0) { - acpi_sleep_state = state; - acpi_enter_dx(ACPI_D0); - acpi_sleep_start = 0; - } - else if (state == ACPI_S1) { - // wait until S1 is entered - while (!(acpi_read_pm1_status(acpi_facp) & ACPI_WAK)) ; - // finished sleeping, update system time - acpi_update_clock(); - } + // wait until S1 is entered + while (!(acpi_read_pm1_status(acpi_facp) & ACPI_WAK)) ; + // finished sleeping, update system time + acpi_update_clock(); + acpi_enter_dx(ACPI_D0); } } @@ -1292,7 +1284,6 @@ { #ifdef CONFIG_ACPI_S1_SLEEP acpi_enter_sx(ACPI_S1); - acpi_enter_sx(ACPI_S0); #endif } file->f_pos += *len; diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/i8259.c linux/arch/i386/kernel/i8259.c --- v2.3.48/linux/arch/i386/kernel/i8259.c Sat Feb 26 22:31:38 2000 +++ linux/arch/i386/kernel/i8259.c Sun Feb 27 13:28:01 2000 @@ -131,7 +131,7 @@ static void end_8259A_irq (unsigned int irq) { - if (!(irq_desc[irq].status & IRQ_DISABLED)) + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_8259A_irq(irq); } diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c --- v2.3.48/linux/arch/i386/kernel/io_apic.c Sat Feb 26 22:31:38 2000 +++ linux/arch/i386/kernel/io_apic.c Tue Feb 29 12:06:17 2000 @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -1160,7 +1161,7 @@ static void mask_and_ack_level_ioapic_irq (unsigned int i) { /* nothing */ } -static void set_ioapic_affinity (unsigned int irq, unsigned int mask) +static void set_ioapic_affinity (unsigned int irq, unsigned long mask) { unsigned long flags; /* diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.3.48/linux/arch/i386/kernel/irq.c Sat Feb 26 22:31:38 2000 +++ linux/arch/i386/kernel/irq.c Mon Feb 28 07:44:22 2000 @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -184,24 +183,43 @@ unsigned char global_irq_holder = NO_PROC_ID; unsigned volatile int global_irq_lock; +extern void show_stack(unsigned long* esp); + static void show(char * str) { int i; - unsigned long *stack; int cpu = smp_processor_id(); printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [%d %d]\n", - irqs_running(), local_irq_count(0), local_irq_count(1)); - printk("bh: %d [%d %d]\n", - spin_is_locked(&global_bh_lock) ? 1 : 0, local_bh_count(0), local_bh_count(1)); - stack = (unsigned long *) &stack; - for (i = 40; i ; i--) { - unsigned long x = *++stack; - if (x > (unsigned long) &get_option && x < (unsigned long) &vsprintf) { - printk("<[%08lx]> ", x); + printk("irq: %d [",irqs_running()); + for(i=0;i < smp_num_cpus;i++) + printk(" %d",local_irq_count(i)); + printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0); + for(i=0;i < smp_num_cpus;i++) + printk(" %d",local_bh_count(i)); + + printk(" ]\nStack dumps:"); + for(i=0;i< smp_num_cpus;i++) { + unsigned long esp; + if(i==cpu) + continue; + printk("\nCPU %d:",i); + esp = init_tss[i].esp0; + if(esp==NULL) { + /* tss->esp0 is set to NULL in cpu_init(), + * it's initialized when the cpu returns to user + * space. -- manfreds + */ + printk(" "); + continue; } - } + esp &= ~(THREAD_SIZE-1); + esp += sizeof(struct task_struct); + show_stack((void*)esp); + } + printk("\nCPU %d:",cpu); + show_stack(NULL); + printk("\n"); } #define MAXCOUNT 100000000 @@ -874,7 +892,7 @@ static struct proc_dir_entry * irq_dir [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff}; +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; #define HEX_DIGITS 8 @@ -883,7 +901,7 @@ { if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08x\n", irq_affinity[(int)data]); + return sprintf (page, "%08lx\n", irq_affinity[(long)data]); } static unsigned int parse_hex_value (const char *buffer, @@ -926,7 +944,7 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - int irq = (int) data, full_count = count, err; + int irq = (long) data, full_count = count, err; unsigned long new_value; if (!irq_desc[irq].handler->set_affinity) @@ -993,7 +1011,7 @@ entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]); entry->nlink = 1; - entry->data = (void *)irq; + entry->data = (void *)(long)irq; entry->read_proc = irq_affinity_read_proc; entry->write_proc = irq_affinity_write_proc; diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/microcode.c linux/arch/i386/kernel/microcode.c --- v2.3.48/linux/arch/i386/kernel/microcode.c Sat Feb 26 22:31:38 2000 +++ linux/arch/i386/kernel/microcode.c Thu Mar 2 10:10:24 2000 @@ -23,20 +23,23 @@ * 1.02 21 February 2000, Tigran Aivazian * Added 'device trimming' support. open(O_WRONLY) zeroes * and frees the saved copy of applied microcode. + * 1.03 29 February 2000, Tigran Aivazian + * Made to use devfs (/dev/cpu/microcode) + cleanups. */ #include +#include #include #include #include #include -#include +#include #include #include #include -#define MICROCODE_VERSION "1.02" +#define MICROCODE_VERSION "1.03" MODULE_DESCRIPTION("CPU (P6) microcode update driver"); MODULE_AUTHOR("Tigran Aivazian "); @@ -60,9 +63,10 @@ static unsigned long microcode_status = 0; /* the actual array of microcode blocks, each 2048 bytes */ -static struct microcode * microcode = NULL; +static struct microcode *microcode = NULL; static unsigned int microcode_num = 0; static char *mc_applied = NULL; /* holds an array of applied microcode blocks */ +static unsigned int mc_fsize; /* used often, so compute once at microcode_init() */ static struct file_operations microcode_fops = { read: microcode_read, @@ -71,23 +75,25 @@ release: microcode_release, }; -static struct proc_dir_entry *proc_microcode; +static devfs_handle_t devfs_handle; static int __init microcode_init(void) { - proc_microcode = create_proc_entry("microcode", S_IWUSR|S_IRUSR, proc_root_driver); - if (!proc_microcode) { - printk(KERN_ERR "microcode: can't create /proc/driver/microcode\n"); - return -ENOMEM; - } - proc_microcode->proc_fops = µcode_fops; + devfs_handle = devfs_register(NULL, "cpu/microcode", 0, DEVFS_FL_DEFAULT, 0, 0, + S_IFREG | S_IRUSR | S_IWUSR, 0, 0, µcode_fops, NULL); + if (!devfs_handle) { + printk(KERN_ERR "microcode: can't create /dev/cpu/microcode\n"); + return -ENOMEM; + } + /* XXX assume no hotplug CPUs so smp_num_cpus does not change */ + mc_fsize = smp_num_cpus * sizeof(struct microcode); printk(KERN_INFO "P6 Microcode Update Driver v%s registered\n", MICROCODE_VERSION); return 0; } static void __exit microcode_exit(void) { - remove_proc_entry("microcode", proc_root_driver); + devfs_unregister(devfs_handle); if (mc_applied) kfree(mc_applied); printk(KERN_INFO "P6 Microcode Update Driver v%s unregistered\n", MICROCODE_VERSION); @@ -108,25 +114,21 @@ if (test_and_set_bit(MICROCODE_IS_OPEN, µcode_status)) return -EBUSY; - if ((file->f_flags & O_ACCMODE) == O_WRONLY) { - proc_microcode->size = 0; - if (mc_applied) { - memset(mc_applied, 0, smp_num_cpus * sizeof(struct microcode)); - kfree(mc_applied); - mc_applied = NULL; - } + if ((file->f_flags & O_ACCMODE) == O_WRONLY && mc_applied) { + devfs_set_file_size(devfs_handle, 0); + memset(mc_applied, 0, mc_fsize); + kfree(mc_applied); + mc_applied = NULL; } MOD_INC_USE_COUNT; - return 0; } static int microcode_release(struct inode *inode, struct file *file) { - MOD_DEC_USE_COUNT; - clear_bit(MICROCODE_IS_OPEN, µcode_status); + MOD_DEC_USE_COUNT; return 0; } @@ -156,19 +158,17 @@ memcpy(m, µcode[update_req[i].slot], sizeof(struct microcode)); } } - return error ? -EIO : 0; + return error; } static void do_update_one(void *arg) { - struct update_req *req; - struct cpuinfo_x86 * c; + int cpu_num = smp_processor_id(); + struct cpuinfo_x86 *c = cpu_data + cpu_num; + struct update_req *req = (struct update_req *)arg + cpu_num; unsigned int pf = 0, val[2], rev, sig; - int i, cpu_num; + int i; - cpu_num = smp_processor_id(); - c = cpu_data + cpu_num; - req = (struct update_req *)arg + cpu_num; req->err = 1; /* be pessimistic */ if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6) @@ -210,8 +210,8 @@ req->err = 0; req->slot = i; - printk(KERN_ERR "microcode: CPU%d microcode updated " - "from revision %d to %d, date=%08x\n", + printk(KERN_ERR "microcode: CPU%d updated from revision " + "%d to %d, date=%08x\n", cpu_num, rev, val[1], m->date); } break; @@ -220,12 +220,10 @@ static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos) { - size_t fsize = smp_num_cpus * sizeof(struct microcode); - - if (!proc_microcode->size || *ppos >= fsize) - return 0; /* EOF */ - if (*ppos + len > fsize) - len = fsize - *ppos; + if (*ppos >= mc_fsize) + return 0; + if (*ppos + len > mc_fsize) + len = mc_fsize - *ppos; if (copy_to_user(buf, mc_applied + *ppos, len)) return -EFAULT; *ppos += len; @@ -242,33 +240,34 @@ return -EINVAL; } if (!mc_applied) { - int size = smp_num_cpus * sizeof(struct microcode); - mc_applied = kmalloc(size, GFP_KERNEL); + mc_applied = kmalloc(mc_fsize, GFP_KERNEL); if (!mc_applied) { - printk(KERN_ERR "microcode: can't allocate memory for saved microcode\n"); + printk(KERN_ERR "microcode: out of memory for saved microcode\n"); return -ENOMEM; } - memset(mc_applied, 0, size); + memset(mc_applied, 0, mc_fsize); } lock_kernel(); microcode_num = len/sizeof(struct microcode); microcode = vmalloc(len); if (!microcode) { - unlock_kernel(); - return -ENOMEM; + ret = -ENOMEM; + goto out_unlock; } if (copy_from_user(microcode, buf, len)) { - vfree(microcode); - unlock_kernel(); - return -EFAULT; - } - ret = do_microcode_update(); - if (!ret) { - proc_microcode->size = smp_num_cpus * sizeof(struct microcode); - ret = (ssize_t)len; + ret = -EFAULT; + goto out_vfree; } + if(do_microcode_update()) { + ret = -EIO; + goto out_vfree; + } + devfs_set_file_size(devfs_handle, mc_fsize); + ret = (ssize_t)len; +out_vfree: vfree(microcode); +out_unlock: unlock_kernel(); return ret; } diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c --- v2.3.48/linux/arch/i386/kernel/pci-pc.c Sun Feb 13 19:29:03 2000 +++ linux/arch/i386/kernel/pci-pc.c Mon Feb 28 14:06:08 2000 @@ -1044,6 +1044,45 @@ printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i); } +static void set_level_irq(unsigned irq) +{ + unsigned char mask = 1 << (irq & 7); + unsigned int port = 0x4d0 + (irq >> 3); + unsigned char val = inb(port); + + if (val & mask) { + printk("PCI irq %d was level\n", irq); + return; + } + printk("PCI irq %d was edge, turning into level-triggered\n", irq); + outb(val | mask, port); +} + +static int ali_set_irq(struct pci_dev *router, unsigned pirq, unsigned irq) +{ + if (irq < 15) { + static unsigned char irqmap[16] = { + 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 + }; + unsigned char val = irqmap[irq]; + if (val && pirq < 8) { + u8 byte; + unsigned offset = 0x48 + (pirq >> 1); + unsigned shift = (pirq & 1) << 2; + pci_read_config_byte(router, offset, &byte); + printk("ALI: old %04x=%02x\n", offset, byte); + byte &= ~(0xf << shift); + byte |= val << shift; + printk("ALI: new %04x=%02x\n", offset, byte); + pci_write_config_byte(router, offset, byte); + set_level_irq(irq); + return irq; + } + } + return 0; +} + + /* * In case BIOS forgets to tell us about IRQ, we try to look it up in the routing * table, but unfortunately we have to know the interrupt router chip. @@ -1135,6 +1174,10 @@ DBG(" -> [PIIX] sink\n"); break; case ID(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533): + newirq = ali_set_irq(router, pirq-1, newirq); + if (newirq) + msg = "ALI"; + break; default: DBG(" -> unknown router %04x/%04x\n", rt->rtr_vendor, rt->rtr_device); if (newirq && mask == (1 << newirq)) { diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c --- v2.3.48/linux/arch/i386/kernel/process.c Sat Feb 26 22:31:39 2000 +++ linux/arch/i386/kernel/process.c Tue Feb 29 11:13:27 2000 @@ -693,7 +693,6 @@ int error; char * filename; - lock_kernel(); filename = getname((char *) regs.ebx); error = PTR_ERR(filename); if (IS_ERR(filename)) @@ -703,7 +702,6 @@ current->flags &= ~PF_DTRACE; putname(filename); out: - unlock_kernel(); return error; } diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- v2.3.48/linux/arch/i386/kernel/signal.c Fri Jan 28 15:09:06 2000 +++ linux/arch/i386/kernel/signal.c Mon Feb 28 07:50:08 2000 @@ -419,13 +419,19 @@ ? current->exec_domain->signal_invmap[sig] : sig), &frame->sig); + if (err) + goto give_sigsegv; err |= setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]); + if (err) + goto give_sigsegv; if (_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); } + if (err) + goto give_sigsegv; /* Set up to return from userspace. If provided, use a stub already in userspace. */ @@ -486,6 +492,8 @@ err |= __put_user(&frame->info, &frame->pinfo); err |= __put_user(&frame->uc, &frame->puc); err |= __copy_to_user(&frame->info, info, sizeof(*info)); + if (err) + goto give_sigsegv; /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); @@ -497,6 +505,8 @@ err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + if (err) + goto give_sigsegv; /* Set up to return from userspace. If provided, use a stub already in userspace. */ diff -u --recursive --new-file v2.3.48/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.3.48/linux/arch/i386/kernel/traps.c Sat Feb 26 22:31:39 2000 +++ linux/arch/i386/kernel/traps.c Tue Feb 29 09:04:08 2000 @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_MCA #include diff -u --recursive --new-file v2.3.48/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c --- v2.3.48/linux/arch/i386/mm/init.c Sat Feb 26 22:31:39 2000 +++ linux/arch/i386/mm/init.c Sun Feb 27 08:47:51 2000 @@ -631,13 +631,14 @@ #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { + if (start < end) + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { ClearPageReserved(mem_map + MAP_NR(start)); set_page_count(mem_map+MAP_NR(start), 1); free_page(start); totalram_pages++; } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif diff -u --recursive --new-file v2.3.48/linux/arch/mips/arc/console.c linux/arch/mips/arc/console.c --- v2.3.48/linux/arch/mips/arc/console.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/arc/console.c Mon Feb 28 07:18:20 2000 @@ -6,6 +6,7 @@ * * $Id: console.c,v 1.3 1999/10/09 00:00:57 ralf Exp $ */ +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/arc/init.c linux/arch/mips/arc/init.c --- v2.3.48/linux/arch/mips/arc/init.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/arc/init.c Mon Feb 28 07:18:20 2000 @@ -9,7 +9,6 @@ */ #include #include -#include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/arc/memory.c linux/arch/mips/arc/memory.c --- v2.3.48/linux/arch/mips/arc/memory.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/arc/memory.c Mon Feb 28 07:18:20 2000 @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/arc/printf.c linux/arch/mips/arc/printf.c --- v2.3.48/linux/arch/mips/arc/printf.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/arc/printf.c Mon Feb 28 07:18:20 2000 @@ -6,6 +6,7 @@ * * $Id: printf.c,v 1.3 1999/10/09 00:00:57 ralf Exp $ */ +#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/baget/balo_supp.S linux/arch/mips/baget/balo_supp.S --- v2.3.48/linux/arch/mips/baget/balo_supp.S Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/baget/balo_supp.S Mon Feb 28 07:18:20 2000 @@ -4,7 +4,6 @@ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ -#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/baget/prom/init.c linux/arch/mips/baget/prom/init.c --- v2.3.48/linux/arch/mips/baget/prom/init.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/baget/prom/init.c Mon Feb 28 07:18:20 2000 @@ -6,7 +6,6 @@ * $Id: init.c,v 1.3 1999/10/09 00:00:57 ralf Exp $ */ #include -#include #include char arcs_cmdline[CL_SIZE]; diff -u --recursive --new-file v2.3.48/linux/arch/mips/baget/setup.c linux/arch/mips/baget/setup.c --- v2.3.48/linux/arch/mips/baget/setup.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/baget/setup.c Mon Feb 28 07:18:20 2000 @@ -5,7 +5,6 @@ * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov * */ -#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/ddb5074/irq.c linux/arch/mips/ddb5074/irq.c --- v2.3.48/linux/arch/mips/ddb5074/irq.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/ddb5074/irq.c Mon Feb 28 07:18:20 2000 @@ -7,6 +7,7 @@ * $Id: irq.c,v 1.1 2000/01/26 00:07:44 ralf Exp $ */ +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/ddb5074/pci.c linux/arch/mips/ddb5074/pci.c --- v2.3.48/linux/arch/mips/ddb5074/pci.c Sat Feb 26 22:31:39 2000 +++ linux/arch/mips/ddb5074/pci.c Mon Feb 28 07:18:20 2000 @@ -9,12 +9,10 @@ */ #include -#include #include #include #include #include -#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/dec/prom/cmdline.c linux/arch/mips/dec/prom/cmdline.c --- v2.3.48/linux/arch/mips/dec/prom/cmdline.c Sat Feb 26 22:31:40 2000 +++ linux/arch/mips/dec/prom/cmdline.c Mon Feb 28 07:18:20 2000 @@ -7,7 +7,6 @@ */ #include #include -#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/dec/prom/identify.c linux/arch/mips/dec/prom/identify.c --- v2.3.48/linux/arch/mips/dec/prom/identify.c Sat Feb 26 22:31:40 2000 +++ linux/arch/mips/dec/prom/identify.c Mon Feb 28 07:18:20 2000 @@ -6,7 +6,6 @@ * $Id: identify.c,v 1.2 1999/10/09 00:00:58 ralf Exp $ */ #include -#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/kernel/r2300_misc.S linux/arch/mips/kernel/r2300_misc.S --- v2.3.48/linux/arch/mips/kernel/r2300_misc.S Sat Feb 26 22:31:40 2000 +++ linux/arch/mips/kernel/r2300_misc.S Mon Feb 28 07:18:20 2000 @@ -10,8 +10,6 @@ * Copyright (c) 1998 Harald Koerfgen * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov */ -#include - #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c --- v2.3.48/linux/arch/mips/kernel/time.c Sat Feb 26 22:31:40 2000 +++ linux/arch/mips/kernel/time.c Mon Feb 28 07:18:20 2000 @@ -6,6 +6,7 @@ * This file contains the time handling details for PC-style clocks as * found in some MIPS systems. */ +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/mm/loadmmu.c linux/arch/mips/mm/loadmmu.c --- v2.3.48/linux/arch/mips/mm/loadmmu.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips/mm/loadmmu.c Mon Feb 28 07:18:20 2000 @@ -5,6 +5,7 @@ * * $Id: loadmmu.c,v 1.15 2000/02/24 00:12:40 ralf Exp $ */ +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips/sgi/kernel/indy_int.c linux/arch/mips/sgi/kernel/indy_int.c --- v2.3.48/linux/arch/mips/sgi/kernel/indy_int.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips/sgi/kernel/indy_int.c Mon Feb 28 07:18:20 2000 @@ -9,7 +9,6 @@ * - Indigo2 changes * - Interrupt handling fixes */ -#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips64/arc/init.c linux/arch/mips64/arc/init.c --- v2.3.48/linux/arch/mips64/arc/init.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/arc/init.c Mon Feb 28 07:18:20 2000 @@ -10,7 +10,6 @@ */ #include #include -#include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips64/arc/memory.c linux/arch/mips64/arc/memory.c --- v2.3.48/linux/arch/mips64/arc/memory.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/arc/memory.c Mon Feb 28 07:18:20 2000 @@ -13,7 +13,6 @@ * because on some machines like SGI IP27 the ARC memory configuration data * completly bogus and alternate easier to use mechanisms are available. */ -#include #include #include #include @@ -21,7 +20,6 @@ #include #include #include -#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips64/kernel/signal32.c linux/arch/mips64/kernel/signal32.c --- v2.3.48/linux/arch/mips64/kernel/signal32.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/kernel/signal32.c Mon Feb 28 07:18:20 2000 @@ -8,7 +8,6 @@ * Copyright (C) 1994 - 1999 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ -#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips64/kernel/syscall.c linux/arch/mips64/kernel/syscall.c --- v2.3.48/linux/arch/mips64/kernel/syscall.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/kernel/syscall.c Mon Feb 28 07:18:20 2000 @@ -7,7 +7,6 @@ * Copyright (C) 1995 - 1999 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ -#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips64/sgi-ip27/ip27-init.c linux/arch/mips64/sgi-ip27/ip27-init.c --- v2.3.48/linux/arch/mips64/sgi-ip27/ip27-init.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/sgi-ip27/ip27-init.c Mon Feb 28 07:18:20 2000 @@ -7,7 +7,6 @@ #include #include #include -#include #include typedef unsigned long cpumask_t; /* into asm/sn/types.h */ diff -u --recursive --new-file v2.3.48/linux/arch/mips64/sgi-ip27/ip27-irq.c linux/arch/mips64/sgi-ip27/ip27-irq.c --- v2.3.48/linux/arch/mips64/sgi-ip27/ip27-irq.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/sgi-ip27/ip27-irq.c Mon Feb 28 07:18:20 2000 @@ -5,7 +5,6 @@ * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. */ -#include #include #include diff -u --recursive --new-file v2.3.48/linux/arch/mips64/sgi-ip27/ip27-rtc.c linux/arch/mips64/sgi-ip27/ip27-rtc.c --- v2.3.48/linux/arch/mips64/sgi-ip27/ip27-rtc.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/sgi-ip27/ip27-rtc.c Tue Feb 29 11:08:16 2000 @@ -192,16 +192,9 @@ */ static struct file_operations rtc_fops = { - NULL, /* No llseek (yet) */ - NULL, /* No read (yet) */ - NULL, /* No write */ - NULL, /* No readdir */ - NULL, /* No poll (yet) */ - rtc_ioctl, - NULL, /* No mmap */ - rtc_open, - NULL, /* flush */ - rtc_release + ioctl: rtc_ioctl, + open: rtc_open, + release: rtc_release, }; static struct miscdevice rtc_dev= diff -u --recursive --new-file v2.3.48/linux/arch/mips64/sgi-ip27/ip27-setup.c linux/arch/mips64/sgi-ip27/ip27-setup.c --- v2.3.48/linux/arch/mips64/sgi-ip27/ip27-setup.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/sgi-ip27/ip27-setup.c Mon Feb 28 07:18:20 2000 @@ -19,7 +19,6 @@ #include #include #include -#include /* Check against user dumbness. */ #ifdef CONFIG_VT diff -u --recursive --new-file v2.3.48/linux/arch/mips64/sgi-ip27/ip27-timer.c linux/arch/mips64/sgi-ip27/ip27-timer.c --- v2.3.48/linux/arch/mips64/sgi-ip27/ip27-timer.c Sat Feb 26 22:31:41 2000 +++ linux/arch/mips64/sgi-ip27/ip27-timer.c Mon Feb 28 07:18:20 2000 @@ -148,13 +148,10 @@ } /* Includes for ioc3_init(). */ -#include #include #include #include #include -#include -#include #include /* Converts Gregorian date to seconds since 1970-01-01 00:00:00. diff -u --recursive --new-file v2.3.48/linux/arch/sparc/config.in linux/arch/sparc/config.in --- v2.3.48/linux/arch/sparc/config.in Thu Feb 10 17:11:05 2000 +++ linux/arch/sparc/config.in Sun Feb 27 18:45:10 2000 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.86 2000/02/10 02:51:10 davem Exp $ +# $Id: config.in,v 1.87 2000/02/27 19:34:12 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -163,6 +163,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then tristate ' Dummy net driver support' CONFIG_DUMMY + tristate ' Bonding driver support' CONFIG_BONDING tristate ' PPP (point-to-point) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP diff -u --recursive --new-file v2.3.48/linux/arch/sparc/defconfig linux/arch/sparc/defconfig --- v2.3.48/linux/arch/sparc/defconfig Sun Feb 20 21:12:38 2000 +++ linux/arch/sparc/defconfig Sun Feb 27 18:45:10 2000 @@ -218,6 +218,7 @@ # CONFIG_NETDEVICES=y CONFIG_DUMMY=m +CONFIG_BONDING=m CONFIG_PPP=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m @@ -240,7 +241,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # -# Filesystems +# File systems # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=m diff -u --recursive --new-file v2.3.48/linux/arch/sparc/kernel/ioport.c linux/arch/sparc/kernel/ioport.c --- v2.3.48/linux/arch/sparc/kernel/ioport.c Sat Feb 26 22:31:42 2000 +++ linux/arch/sparc/kernel/ioport.c Sun Feb 27 18:45:10 2000 @@ -1,4 +1,4 @@ -/* $Id: ioport.c,v 1.34 2000/02/18 13:48:48 davem Exp $ +/* $Id: ioport.c,v 1.35 2000/02/27 08:16:25 davem Exp $ * ioport.c: Simple io mapping allocator. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff -u --recursive --new-file v2.3.48/linux/arch/sparc/kernel/pcic.c linux/arch/sparc/kernel/pcic.c --- v2.3.48/linux/arch/sparc/kernel/pcic.c Sun Feb 13 19:29:03 2000 +++ linux/arch/sparc/kernel/pcic.c Thu Mar 2 11:36:42 2000 @@ -1,4 +1,4 @@ -/* $Id: pcic.c,v 1.13 2000/02/12 03:05:37 zaitcev Exp $ +/* $Id: pcic.c,v 1.14 2000/03/01 02:53:28 davem Exp $ * pcic.c: Sparc/PCI controller support * * Copyright (C) 1998 V. Roganov and G. Raiko @@ -883,13 +883,6 @@ void pcibios_align_resource(void *data, struct resource *res, unsigned long size) { } - -#if 0 -int pci_assign_resource(struct pci_dev *dev, int i) -{ - return -ENOSYS; /* :-)... actually implement this soon */ -} -#endif int pcibios_enable_device(struct pci_dev *pdev) { diff -u --recursive --new-file v2.3.48/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c --- v2.3.48/linux/arch/sparc/kernel/process.c Tue Feb 1 01:35:43 2000 +++ linux/arch/sparc/kernel/process.c Thu Mar 2 11:36:42 2000 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.145 2000/01/29 01:08:56 anton Exp $ +/* $Id: process.c,v 1.146 2000/03/01 02:53:27 davem Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -652,7 +652,6 @@ if(regs->u_regs[UREG_G1] == 0) base = 1; - lock_kernel(); filename = getname((char *)regs->u_regs[base + UREG_I0]); error = PTR_ERR(filename); if(IS_ERR(filename)) @@ -661,7 +660,6 @@ (char **) regs->u_regs[base + UREG_I2], regs); putname(filename); out: - unlock_kernel(); return error; } diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/config.in linux/arch/sparc64/config.in --- v2.3.48/linux/arch/sparc64/config.in Sun Feb 20 21:12:38 2000 +++ linux/arch/sparc64/config.in Sun Feb 27 18:45:10 2000 @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.95 2000/02/10 02:51:12 davem Exp $ +# $Id: config.in,v 1.99 2000/02/27 19:34:17 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -112,6 +112,7 @@ define_bool CONFIG_IDEDMA_NEW_DRIVE_LISTINGS y define_bool CONFIG_BLK_DEV_NS87415 y define_bool CONFIG_BLK_DEV_CMD64X y + define_bool CONFIG_BLK_DEV_IDE_MODES y fi fi @@ -200,6 +201,7 @@ bool 'Network device support' CONFIG_NETDEVICES if [ "$CONFIG_NETDEVICES" = "y" ]; then tristate ' Dummy net driver support' CONFIG_DUMMY + tristate ' Bonding driver support' CONFIG_BONDING tristate ' PPP (point-to-point) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig --- v2.3.48/linux/arch/sparc64/defconfig Sat Feb 26 22:31:42 2000 +++ linux/arch/sparc64/defconfig Sun Feb 27 18:45:10 2000 @@ -136,6 +136,7 @@ CONFIG_IDEDMA_NEW_DRIVE_LISTINGS=y CONFIG_BLK_DEV_NS87415=y CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_IDE_MODES=y # # Networking options @@ -254,6 +255,7 @@ # CONFIG_NETDEVICES=y CONFIG_DUMMY=m +CONFIG_BONDING=m CONFIG_PPP=m # CONFIG_PPP_ASYNC is not set # CONFIG_PPP_SYNC_TTY is not set diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c --- v2.3.48/linux/arch/sparc64/kernel/irq.c Sat Feb 26 22:31:42 2000 +++ linux/arch/sparc64/kernel/irq.c Thu Mar 2 10:13:16 2000 @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.84 2000/02/25 05:44:41 davem Exp $ +/* $Id: irq.c,v 1.85 2000/03/02 02:00:24 davem Exp $ * irq.c: UltraSparc IRQ handling/init/registry. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -955,7 +955,7 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *), unsigned long *clock) { - unsigned long flags; + unsigned long pstate; extern unsigned long timer_tick_offset; int node, err; #ifdef __SMP__ @@ -978,31 +978,57 @@ prom_halt(); } - save_and_cli(flags); + /* Guarentee that the following sequences execute + * uninterrupted. + */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); /* Set things up so user can access tick register for profiling - * purposes. + * purposes. Also workaround BB_ERRATA_1 by doing a dummy + * read back of %tick after writing it. */ __asm__ __volatile__(" sethi %%hi(0x80000000), %%g1 - sllx %%g1, 32, %%g1 - rd %%tick, %%g2 + ba,pt %%xcc, 1f + sllx %%g1, 32, %%g1 + .align 64 + 1: rd %%tick, %%g2 add %%g2, 6, %%g2 andn %%g2, %%g1, %%g2 wrpr %%g2, 0, %%tick -" : /* no outputs */ + rdpr %%tick, %%g0" + : /* no outputs */ : /* no inputs */ : "g1", "g2"); + /* Workaround for Spitfire Errata (#54 I think??), I discovered + * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch + * number 103640. + * + * On Blackbird writes to %tick_cmpr can fail, the + * workaround seems to be to execute the wr instruction + * at the start of an I-cache line, and perform a dummy + * read back from %tick_cmpr right after writing to it. -DaveM + */ __asm__ __volatile__(" rd %%tick, %%g1 - add %%g1, %0, %%g1 - wr %%g1, 0x0, %%tick_cmpr" + ba,pt %%xcc, 1f + add %%g1, %0, %%g1 + .align 64 + 1: wr %%g1, 0x0, %%tick_cmpr + rd %%tick_cmpr, %%g0" : /* no outputs */ : "r" (timer_tick_offset) : "g1"); - restore_flags(flags); + /* Restore PSTATE_IE. */ + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : /* no outputs */ + : "r" (pstate)); + sti(); } diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/kernel/pci.c linux/arch/sparc64/kernel/pci.c --- v2.3.48/linux/arch/sparc64/kernel/pci.c Thu Feb 10 17:11:06 2000 +++ linux/arch/sparc64/kernel/pci.c Thu Mar 2 11:36:42 2000 @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.15 2000/02/08 05:11:29 jj Exp $ +/* $Id: pci.c,v 1.16 2000/03/01 02:53:33 davem Exp $ * pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -216,11 +216,6 @@ void pcibios_align_resource(void *data, struct resource *res, unsigned long size) { -} - -int pci_assign_resource(struct pci_dev *dev, int i) -{ - return -ENOSYS; /* :-)... actually implement this soon */ } int pcibios_enable_device(struct pci_dev *pdev) diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c --- v2.3.48/linux/arch/sparc64/kernel/process.c Fri Jan 28 15:09:07 2000 +++ linux/arch/sparc64/kernel/process.c Thu Mar 2 11:36:42 2000 @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.103 2000/01/21 11:38:53 jj Exp $ +/* $Id: process.c,v 1.104 2000/03/01 02:53:32 davem Exp $ * arch/sparc64/kernel/process.c * * Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu) @@ -779,24 +779,22 @@ /* User register window flush is done by entry.S */ /* Check for indirect call. */ - if(regs->u_regs[UREG_G1] == 0) + if (regs->u_regs[UREG_G1] == 0) base = 1; - lock_kernel(); filename = getname((char *)regs->u_regs[base + UREG_I0]); error = PTR_ERR(filename); - if(IS_ERR(filename)) + if (IS_ERR(filename)) goto out; error = do_execve(filename, (char **) regs->u_regs[base + UREG_I1], (char **) regs->u_regs[base + UREG_I2], regs); putname(filename); - if(!error) { + if (!error) { fprs_write(0); current->thread.xfsr[0] = 0; current->thread.fpsaved[0] = 0; regs->tstate &= ~TSTATE_PEF; } out: - unlock_kernel(); return error; } diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/kernel/smp.c linux/arch/sparc64/kernel/smp.c --- v2.3.48/linux/arch/sparc64/kernel/smp.c Wed Feb 16 17:03:51 2000 +++ linux/arch/sparc64/kernel/smp.c Thu Mar 2 10:13:16 2000 @@ -119,6 +119,7 @@ void __init smp_callin(void) { int cpuid = hard_smp_processor_id(); + unsigned long pstate; inherit_locked_prom_mappings(0); @@ -127,18 +128,37 @@ cpu_probe(); - /* Master did this already, now is the time for us to do it. */ + /* Guarentee that the following sequences execute + * uninterrupted. + */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + /* Set things up so user can access tick register for profiling + * purposes. Also workaround BB_ERRATA_1 by doing a dummy + * read back of %tick after writing it. + */ __asm__ __volatile__(" sethi %%hi(0x80000000), %%g1 - sllx %%g1, 32, %%g1 - rd %%tick, %%g2 + ba,pt %%xcc, 1f + sllx %%g1, 32, %%g1 + .align 64 +1: rd %%tick, %%g2 add %%g2, 6, %%g2 andn %%g2, %%g1, %%g2 wrpr %%g2, 0, %%tick -" : /* no outputs */ + rdpr %%tick, %%g0" + : /* no outputs */ : /* no inputs */ : "g1", "g2"); + /* Restore PSTATE_IE. */ + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : /* no outputs */ + : "r" (pstate)); + smp_setup_percpu_timer(); __sti(); @@ -598,7 +618,7 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs) { - unsigned long compare, tick; + unsigned long compare, tick, pstate; int cpu = smp_processor_id(); int user = user_mode(regs); @@ -664,27 +684,87 @@ prof_counter(cpu) = prof_multiplier(cpu); } + /* Guarentee that the following sequences execute + * uninterrupted. + */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + /* Workaround for Spitfire Errata (#54 I think??), I discovered + * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch + * number 103640. + * + * On Blackbird writes to %tick_cmpr can fail, the + * workaround seems to be to execute the wr instruction + * at the start of an I-cache line, and perform a dummy + * read back from %tick_cmpr right after writing to it. -DaveM + * + * Just to be anal we add a workaround for Spitfire + * Errata 50 by preventing pipeline bypasses on the + * final read of the %tick register into a compare + * instruction. The Errata 50 description states + * that %tick is not prone to this bug, but I am not + * taking any chances. + */ __asm__ __volatile__("rd %%tick_cmpr, %0\n\t" - "add %0, %2, %0\n\t" - "wr %0, 0x0, %%tick_cmpr\n\t" - "rd %%tick, %1" + "ba,pt %%xcc, 1f\n\t" + " add %0, %2, %0\n\t" + ".align 64\n" + "1: wr %0, 0x0, %%tick_cmpr\n\t" + "rd %%tick_cmpr, %%g0\n\t" + "rd %%tick, %1\n\t" + "mov %1, %1" : "=&r" (compare), "=r" (tick) : "r" (current_tick_offset)); + + /* Restore PSTATE_IE. */ + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : /* no outputs */ + : "r" (pstate)); } while (tick >= compare); } static void __init smp_setup_percpu_timer(void) { int cpu = smp_processor_id(); + unsigned long pstate; prof_counter(cpu) = prof_multiplier(cpu) = 1; - __asm__ __volatile__("rd %%tick, %%g1\n\t" - "add %%g1, %0, %%g1\n\t" - "wr %%g1, 0x0, %%tick_cmpr" + /* Guarentee that the following sequences execute + * uninterrupted. + */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + /* Workaround for Spitfire Errata (#54 I think??), I discovered + * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch + * number 103640. + * + * On Blackbird writes to %tick_cmpr can fail, the + * workaround seems to be to execute the wr instruction + * at the start of an I-cache line, and perform a dummy + * read back from %tick_cmpr right after writing to it. -DaveM + */ + __asm__ __volatile__(" + rd %%tick, %%g1 + ba,pt %%xcc, 1f + add %%g1, %0, %%g1 + .align 64 + 1: wr %%g1, 0x0, %%tick_cmpr + rd %%tick_cmpr, %%g0" + : /* no outputs */ + : "r" (current_tick_offset) + : "g1"); + + /* Restore PSTATE_IE. */ + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : /* no outputs */ - : "r" (current_tick_offset) - : "g1"); + : "r" (pstate)); } void __init smp_tick_init(void) diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c --- v2.3.48/linux/arch/sparc64/kernel/sys_sparc32.c Sun Feb 20 21:12:38 2000 +++ linux/arch/sparc64/kernel/sys_sparc32.c Thu Mar 2 11:36:42 2000 @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.132 2000/02/16 07:31:35 davem Exp $ +/* $Id: sys_sparc32.c,v 1.133 2000/03/01 02:53:33 davem Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -3086,7 +3086,10 @@ bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0])); + lock_kernel(); dentry = open_namei(filename, 0, 0); + unlock_kernel(); + retval = PTR_ERR(dentry); if (IS_ERR(dentry)) return retval; @@ -3097,11 +3100,15 @@ bprm.loader = 0; bprm.exec = 0; if ((bprm.argc = count32(argv)) < 0) { + lock_kernel(); dput(dentry); + unlock_kernel(); return bprm.argc; } if ((bprm.envc = count32(envp)) < 0) { + lock_kernel(); dput(dentry); + unlock_kernel(); return bprm.envc; } @@ -3129,8 +3136,11 @@ out: /* Something went wrong, return the inode and free the argument pages*/ - if (bprm.dentry) + if (bprm.dentry) { + lock_kernel(); dput(bprm.dentry); + unlock_kernel(); + } for (i=0 ; iu_regs[UREG_G1] == 0) base = 1; - lock_kernel(); filename = getname32((char *)AA(regs->u_regs[base + UREG_I0])); error = PTR_ERR(filename); if(IS_ERR(filename)) @@ -3171,7 +3180,6 @@ regs->tstate &= ~TSTATE_PEF; } out: - unlock_kernel(); return error; } diff -u --recursive --new-file v2.3.48/linux/arch/sparc64/kernel/time.c linux/arch/sparc64/kernel/time.c --- v2.3.48/linux/arch/sparc64/kernel/time.c Wed Dec 29 13:13:14 1999 +++ linux/arch/sparc64/kernel/time.c Thu Mar 2 10:13:16 2000 @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.23 1999/09/21 14:35:27 davem Exp $ +/* $Id: time.c,v 1.24 2000/03/02 02:00:25 davem Exp $ * time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -69,20 +69,53 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { - unsigned long ticks; + unsigned long ticks, pstate; write_lock(&xtime_lock); do { do_timer(regs); + /* Guarentee that the following sequences execute + * uninterrupted. + */ + __asm__ __volatile__("rdpr %%pstate, %0\n\t" + "wrpr %0, %1, %%pstate" + : "=r" (pstate) + : "i" (PSTATE_IE)); + + /* Workaround for Spitfire Errata (#54 I think??), I discovered + * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch + * number 103640. + * + * On Blackbird writes to %tick_cmpr can fail, the + * workaround seems to be to execute the wr instruction + * at the start of an I-cache line, and perform a dummy + * read back from %tick_cmpr right after writing to it. -DaveM + * + * Just to be anal we add a workaround for Spitfire + * Errata 50 by preventing pipeline bypasses on the + * final read of the %tick register into a compare + * instruction. The Errata 50 description states + * that %tick is not prone to this bug, but I am not + * taking any chances. + */ __asm__ __volatile__(" rd %%tick_cmpr, %0 - add %0, %2, %0 - wr %0, 0, %%tick_cmpr - rd %%tick, %1" + ba,pt %%xcc, 1f + add %0, %2, %0 + .align 64 + 1: wr %0, 0, %%tick_cmpr + rd %%tick_cmpr, %%g0 + rd %%tick, %1 + mov %1, %1" : "=&r" (timer_tick_compare), "=r" (ticks) : "r" (timer_tick_offset)); + + /* Restore PSTATE_IE. */ + __asm__ __volatile__("wrpr %0, 0x0, %%pstate" + : /* no outputs */ + : "r" (pstate)); } while (ticks >= timer_tick_compare); timer_check_rtc(); diff -u --recursive --new-file v2.3.48/linux/drivers/acorn/block/Makefile linux/drivers/acorn/block/Makefile --- v2.3.48/linux/drivers/acorn/block/Makefile Fri Oct 22 13:21:47 1999 +++ linux/drivers/acorn/block/Makefile Mon Feb 28 14:16:37 2000 @@ -9,26 +9,45 @@ # parent makefile. # -L_TARGET := acorn-block.a -L_OBJS := -M_OBJS := -MOD_LIST_NAME := ACORN_BLOCK_MODULES - -ifeq ($(CONFIG_BLK_DEV_FD1772),y) - L_OBJS += fd1772.o fd1772dma.o -else - ifeq ($(CONFIG_BLK_DEV_FD1772),m) - M_OBJS += fd1772_mod.o - endif -endif - -ifeq ($(CONFIG_BLK_DEV_MFM),y) - L_OBJS += mfmhd.o mfm.o -else - ifeq ($(CONFIG_BLK_DEV_MFM),m) - M_OBJS += mfmhd_mod.o - endif -endif +L_TARGET := acorn-block.a +MOD_LIST_NAME := ACORN_BLOCK_MODULES + +obj-y := +obj-m := +obj-n := +obj- := + +export-objs := +list-multi := fd1772_mod.o mfmhd_mod.o +fd1772_mod-objs := fd1772.o fd1772dma.o +mfmhd_mod-objs := mfmhd.o mfm.o + +obj-$(CONFIG_BLK_DEV_FD1772) += fd1772_mod.o +obj-$(CONFIG_BLK_DEV_MFM) += mfmhd.o mfm.o + +# Extract lists of the multi-part drivers. +# The 'int-*' lists are intermediate files used to build the multi's. + +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) +int-m := $(filter-out $(int-y), $(int-m)) + +# Take multi-part drivers out of obj-y and put components in. + +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) + +# Translate to Rules.make lists. + +L_OBJS := $(filter-out $(export-objs), $(obj-y)) +LX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.48/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c --- v2.3.48/linux/drivers/acorn/block/mfmhd.c Wed Feb 16 17:03:51 2000 +++ linux/drivers/acorn/block/mfmhd.c Mon Feb 28 14:16:37 2000 @@ -1280,7 +1280,6 @@ * Set the CHS from the ADFS boot block if it is present. This is not ideal * since if there are any non-ADFS partitions on the disk, this won't work! * Hence, I want to get rid of this... - * Please, do. It does seriously sucking things. */ void xd_set_geometry(kdev_t dev, unsigned char secsptrack, unsigned char heads, unsigned long discsize, unsigned int secsize) diff -u --recursive --new-file v2.3.48/linux/drivers/acorn/char/Makefile linux/drivers/acorn/char/Makefile --- v2.3.48/linux/drivers/acorn/char/Makefile Thu Feb 10 17:11:06 2000 +++ linux/drivers/acorn/char/Makefile Mon Feb 28 14:16:37 2000 @@ -10,37 +10,35 @@ # O_TARGET := acorn-char.o -M_OBJS := -O_OBJS := i2c.o pcf8583.o -O_OBJS_arc := keyb_arc.o -O_OBJS_a5k := keyb_arc.o -O_OBJS_rpc := keyb_ps2.o - -ifeq ($(CONFIG_RPCMOUSE),y) - OX_OBJS += mouse_rpc.o -else - ifeq ($(CONFIG_RPCSMOUSE),m) - MX_OBJS += mouse_rpc.o - endif -endif - -ifeq ($(CONFIG_ATOMWIDE_SERIAL),y) - O_OBJS += serial-atomwide.o -else - ifeq ($(CONFIG_ATOMWIDE_SERIAL),m) - O_OBJS += serial-atomwide.o - endif -endif - -ifeq ($(CONFIG_DUALSP_SERIAL),y) - O_OBJS += serial-dualsp.o -else - ifeq ($(CONFIG_DUALSP_SERIAL),m) - M_OBJS += serial-dualsp.o - endif -endif +O_OBJS := +OX_OBJS := +M_OBJS := +MX_OBJS := -O_OBJS += $(O_OBJS_$(MACHINE)) +# Object file lists. + +obj-y := i2c.o pcf8583.o +obj-m := +obj-n := +obj- := + +# All the objects that export symbols. +export-objs := mouse_rpc.o + +obj-arc := keyb_arc.o +obj-a5k := keyb_arc.o +obj-rpc := keyb_ps2.o + +obj-$(CONFIG_RPCMOUSE) += mouse_rpc.o +obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o +obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o + +obj-y += $(obj-$(MACHINE)) + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.48/linux/drivers/acorn/net/Makefile linux/drivers/acorn/net/Makefile --- v2.3.48/linux/drivers/acorn/net/Makefile Sun Sep 6 10:46:07 1998 +++ linux/drivers/acorn/net/Makefile Mon Feb 28 14:16:37 2000 @@ -4,32 +4,18 @@ # L_TARGET := acorn-net.a -L_OBJS := -M_OBJS := MOD_LIST_NAME := ACORN_NET_MODULES -ifeq ($(CONFIG_ARM_ETHER1),y) - L_OBJS += ether1.o -else - ifeq ($(CONFIG_ARM_ETHER1),m) - M_OBJS += ether1.o - endif -endif +obj-y := +obj-m := +obj-n := +obj- := -ifeq ($(CONFIG_ARM_ETHER3),y) - L_OBJS += ether3.o -else - ifeq ($(CONFIG_ARM_ETHER3),m) - M_OBJS += ether3.o - endif -endif +obj-$(CONFIG_ARM_ETHER1) += ether1.o +obj-$(CONFIG_ARM_ETHER3) += ether3.o +obj-$(CONFIG_ARM_ETHERH) += etherh.o -ifeq ($(CONFIG_ARM_ETHERH),y) - L_OBJS += etherh.o -else - ifeq ($(CONFIG_ARM_ETHERH),m) - M_OBJS += etherh.o - endif -endif +L_OBJS := $(obj-y) +M_OBJS := $(obj-m) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.48/linux/drivers/acorn/scsi/Makefile linux/drivers/acorn/scsi/Makefile --- v2.3.48/linux/drivers/acorn/scsi/Makefile Fri Oct 22 13:21:47 1999 +++ linux/drivers/acorn/scsi/Makefile Mon Feb 28 14:16:37 2000 @@ -2,109 +2,50 @@ # Makefile for drivers/acorn/scsi # -L_TARGET := acorn-scsi.a -L_OBJS := -LX_OBJS := -M_OBJS := -MX_OBJS := -MOD_LIST_NAME := ACORN_SCSI_MODULES - -CONFIG_QUEUE_BUILTIN := -CONFIG_FAS216_BUILTIN := -CONFIG_QUEUE_MODULE := -CONFIG_FAS216_MODULE := - -ifeq ($(CONFIG_SCSI_ACORNSCSI_3),y) - L_OBJS += acornscsi.o acornscsi-io.o - CONFIG_QUEUE_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_ACORNSCSI_3),m) - M_OBJS += acornscsi_mod.o - CONFIG_QUEUE_MODULE=y - endif -endif - -ifeq ($(CONFIG_SCSI_ARXESCSI),y) - L_OBJS += arxescsi.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_ARXESCSI),m) - M_OBJS += arxescsi.o - CONFIG_FAS216_MODULE=y - endif -endif - -ifeq ($(CONFIG_SCSI_CUMANA_1),y) - L_OBJS += cumana_1.o -else - ifeq ($(CONFIG_SCSI_CUMANA_1),m) - M_OBJS += cumana_1.o - endif -endif - -ifeq ($(CONFIG_SCSI_CUMANA_2),y) - L_OBJS += cumana_2.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_CUMANA_2),m) - M_OBJS += cumana_2.o - CONFIG_FAS216_MODULE=y - endif -endif - -ifeq ($(CONFIG_SCSI_ECOSCSI),y) - L_OBJS += ecoscsi.o -else - ifeq ($(CONFIG_SCSI_ECOSCSI),m) - M_OBJS += ecoscsi.o - endif -endif - -ifeq ($(CONFIG_SCSI_OAK1),y) - L_OBJS += oak.o -else - ifeq ($(CONFIG_SCSI_OAK1),m) - M_OBJS += oak.o - endif -endif - -ifeq ($(CONFIG_SCSI_POWERTECSCSI),y) - L_OBJS += powertec.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_POWERTECSCSI),m) - M_OBJS += powertec.o - CONFIG_FAS216_MODULE=y - endif -endif - -ifeq ($(CONFIG_SCSI_EESOXSCSI),y) - L_OBJS += eesox.o - CONFIG_FAS216_BUILTIN=y -else - ifeq ($(CONFIG_SCSI_EESOXSCSI),m) - M_OBJS += eesox.o - CONFIG_FAS216_MODULE=y - endif -endif - -ifeq ($(CONFIG_FAS216_BUILTIN),y) - LX_OBJS += fas216.o - CONFIG_QUEUE_BUILTIN=y -else - ifeq ($(CONFIG_FAS216_MODULE),y) - MX_OBJS += fas216.o - CONFIG_QUEUE_MODULE=y - endif -endif - -ifeq ($(CONFIG_QUEUE_BUILTIN),y) - LX_OBJS += queue.o msgqueue.o -else - ifeq ($(CONFIG_QUEUE_MODULE),y) - MX_OBJS += queue.o msgqueue.o - endif -endif +L_TARGET := acorn-scsi.a +MOD_LIST_NAME := ACORN_SCSI_MODULES + +obj-y := +obj-m := +obj-n := +obj- := + +export-objs := fas216.o queue.o msgqueue.o +list-multi := acornscsi_mod.o +acornscsi_mod-objs := acornscsi.o acornscsi-io.o + +obj-$(CONFIG_SCSI_ACORNSCSI_3) += acornscsi_mod.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_ARXESCSI) += arxescsi.o fas216.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_CUMANA_1) += cumana_1.o +obj-$(CONFIG_SCSI_CUMANA_2) += cumana_2.o fas216.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_ECOSCSI) += ecoscsi.o +obj-$(CONFIG_SCSI_OAK1) += oak.o +obj-$(CONFIG_SCSI_POWERTECSCSI) += powertec.o fas216.o queue.o msgqueue.o +obj-$(CONFIG_SCSI_EESOXSCSI) += eesox.o fas216.o queue.o msgqueue.o + +# Extract lists of the multi-part drivers. +# The 'int-*' lists are intermediate files used to build the multi's. + +multi-y := $(filter $(list-multi), $(obj-y)) +multi-m := $(filter $(list-multi), $(obj-m)) +int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs))) +int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs))) + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) +int-m := $(filter-out $(int-y), $(int-m)) + +# Take multi-part drivers out of obj-y and put components in. + +obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y) + +# Translate to Rules.make lists. + +L_OBJS := $(filter-out $(export-objs), $(obj-y)) +LX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.3.48/linux/drivers/acorn/scsi/arxescsi.c linux/drivers/acorn/scsi/arxescsi.c --- v2.3.48/linux/drivers/acorn/scsi/arxescsi.c Thu Nov 11 20:11:32 1999 +++ linux/drivers/acorn/scsi/arxescsi.c Mon Feb 28 07:16:54 2000 @@ -24,8 +24,8 @@ #include #include #include +#include -#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/drivers/block/Config.in linux/drivers/block/Config.in --- v2.3.48/linux/drivers/block/Config.in Sat Feb 26 22:31:43 2000 +++ linux/drivers/block/Config.in Thu Mar 2 11:32:37 2000 @@ -27,6 +27,7 @@ if [ "$CONFIG_BLK_DEV_IDEDISK" != "n" ]; then bool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE fi + dep_tristate ' PCMCIA IDE support' CONFIG_BLK_DEV_IDECS $CONFIG_BLK_DEV_IDE $CONFIG_PCMCIA dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE diff -u --recursive --new-file v2.3.48/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c --- v2.3.48/linux/drivers/block/DAC960.c Sun Feb 20 21:12:38 2000 +++ linux/drivers/block/DAC960.c Mon Feb 28 07:16:54 2000 @@ -3583,7 +3583,7 @@ int init_module(void) { - int ControllerNumber, LogicalDriveNumber; + int ControllerNumber; DAC960_Initialize(); if (DAC960_ActiveControllerCount == 0) return -1; for (ControllerNumber = 0; diff -u --recursive --new-file v2.3.48/linux/drivers/block/Makefile linux/drivers/block/Makefile --- v2.3.48/linux/drivers/block/Makefile Sat Feb 26 22:31:43 2000 +++ linux/drivers/block/Makefile Thu Mar 2 11:32:37 2000 @@ -262,6 +262,14 @@ ############ +ifeq ($(CONFIG_BLK_DEV_IDECS),y) +L_OBJS += ide-cs.o +else + ifeq ($(CONFIG_BLK_DEV_IDECS),m) + M_OBJS += ide-cs.o + endif +endif + ifeq ($(CONFIG_BLK_DEV_IDEDISK),y) L_OBJS += ide-disk.o else diff -u --recursive --new-file v2.3.48/linux/drivers/block/amd7409.c linux/drivers/block/amd7409.c --- v2.3.48/linux/drivers/block/amd7409.c Sat Feb 26 22:31:43 2000 +++ linux/drivers/block/amd7409.c Mon Feb 28 07:18:20 2000 @@ -6,6 +6,7 @@ * */ +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/drivers/block/cmd64x.c linux/drivers/block/cmd64x.c --- v2.3.48/linux/drivers/block/cmd64x.c Sat Feb 26 22:31:43 2000 +++ linux/drivers/block/cmd64x.c Mon Feb 28 07:18:20 2000 @@ -11,6 +11,7 @@ * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) */ +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/drivers/block/cpqarray.h linux/drivers/block/cpqarray.h --- v2.3.48/linux/drivers/block/cpqarray.h Tue Jul 6 10:11:40 1999 +++ linux/drivers/block/cpqarray.h Tue Feb 29 11:46:16 2000 @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #endif diff -u --recursive --new-file v2.3.48/linux/drivers/block/cs5530.c linux/drivers/block/cs5530.c --- v2.3.48/linux/drivers/block/cs5530.c Sat Feb 26 22:31:43 2000 +++ linux/drivers/block/cs5530.c Mon Feb 28 07:18:20 2000 @@ -8,6 +8,7 @@ * by the nice folks at National Semiconductor. */ +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/drivers/block/ide-cs.c linux/drivers/block/ide-cs.c --- v2.3.48/linux/drivers/block/ide-cs.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/block/ide-cs.c Thu Mar 2 11:32:37 2000 @@ -0,0 +1,481 @@ +/*====================================================================== + + A driver for PCMCIA IDE/ATA disk cards + + ide_cs.c 1.26 1999/11/16 02:10:49 + + The contents of this file are subject to the Mozilla Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The initial developer of the original code is David A. Hinds + . Portions created by David A. Hinds + are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + + Alternatively, the contents of this file may be used under the + terms of the GNU Public License version 2 (the "GPL"), in which + case the provisions of the GPL are applicable instead of the + above. If you wish to allow the use of your version of this file + only under the terms of the GPL and not to allow others to use + your version of this file under the MPL, indicate your decision + by deleting the provisions above and replace them with the notice + and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this + file under either the MPL or the GPL. + +======================================================================*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) +static char *version = +"ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)"; +#else +#define DEBUG(n, args...) +#endif + +/*====================================================================*/ + +/* Parameters that can be set with 'insmod' */ + +/* Bit map of interrupts to choose from */ +static u_int irq_mask = 0xdeb8; +static int irq_list[4] = { -1 }; + +MODULE_PARM(irq_mask, "i"); +MODULE_PARM(irq_list, "1-4i"); + +/*====================================================================*/ + +static const char ide_major[] = { + IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, +#ifdef IDE4_MAJOR + IDE4_MAJOR, IDE5_MAJOR +#endif +}; + +typedef struct ide_info_t { + dev_link_t link; + int ndev; + dev_node_t node; + int hd; +} ide_info_t; + +static void ide_config(dev_link_t *link); +static void ide_release(u_long arg); +static int ide_event(event_t event, int priority, + event_callback_args_t *args); + +static dev_info_t dev_info = "ide_cs"; + +static dev_link_t *ide_attach(void); +static void ide_detach(dev_link_t *); + +static dev_link_t *dev_list = NULL; + +/*====================================================================*/ + +static void cs_error(client_handle_t handle, int func, int ret) +{ + error_info_t err = { func, ret }; + CardServices(ReportError, handle, &err); +} + +/*====================================================================== + + ide_attach() creates an "instance" of the driver, allocating + local data structures for one device. The device is registered + with Card Services. + +======================================================================*/ + +static dev_link_t *ide_attach(void) +{ + ide_info_t *info; + dev_link_t *link; + client_reg_t client_reg; + int i, ret; + + DEBUG(0, "ide_attach()\n"); + + /* Create new ide device */ + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) return NULL; + memset(info, 0, sizeof(*info)); + link = &info->link; link->priv = info; + + link->release.function = &ide_release; + link->release.data = (u_long)link; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; + link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = 3; + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < 4; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &ide_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices(RegisterClient, &link->handle, &client_reg); + if (ret != CS_SUCCESS) { + cs_error(link->handle, RegisterClient, ret); + ide_detach(link); + return NULL; + } + + return link; +} /* ide_attach */ + +/*====================================================================== + + This deletes a driver "instance". The device is de-registered + with Card Services. If it has been released, all local data + structures are freed. Otherwise, the structures will be freed + when the device is released. + +======================================================================*/ + +static void ide_detach(dev_link_t *link) +{ + dev_link_t **linkp; + long flags; + int ret; + + DEBUG(0, "ide_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) + if (*linkp == link) break; + if (*linkp == NULL) + return; + + save_flags(flags); + cli(); + if (link->state & DEV_RELEASE_PENDING) { + del_timer(&link->release); + link->state &= ~DEV_RELEASE_PENDING; + } + restore_flags(flags); + + if (link->state & DEV_CONFIG) + ide_release((u_long)link); + + if (link->handle) { + ret = CardServices(DeregisterClient, link->handle); + if (ret != CS_SUCCESS) + cs_error(link->handle, DeregisterClient, ret); + } + + /* Unlink, free device structure */ + *linkp = link->next; + kfree(link->priv); + +} /* ide_detach */ + +/*====================================================================== + + ide_config() is scheduled to run after a CARD_INSERTION event + is received, to configure the PCMCIA socket, and to make the + ide device available to the system. + +======================================================================*/ + +#define CS_CHECK(fn, args...) \ +while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed + +#define CFG_CHECK(fn, args...) \ +if (CardServices(fn, args) != 0) goto next_entry + +void ide_config(dev_link_t *link) +{ + client_handle_t handle = link->handle; + ide_info_t *info = link->priv; + tuple_t tuple; + u_short buf[128]; + cisparse_t parse; + config_info_t conf; + cistpl_cftable_entry_t *cfg = &parse.cftable_entry; + cistpl_cftable_entry_t dflt = { 0 }; + int i, pass, last_ret, last_fn, hd, io_base, ctl_base; + + DEBUG(0, "ide_config(0x%p)\n", link); + + tuple.TupleData = (cisdata_t *)buf; + tuple.TupleOffset = 0; tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CONFIG; + CS_CHECK(GetFirstTuple, handle, &tuple); + CS_CHECK(GetTupleData, handle, &tuple); + CS_CHECK(ParseTuple, handle, &tuple, &parse); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Not sure if this is right... look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, handle, &conf); + link->conf.Vcc = conf.Vcc; + + pass = io_base = ctl_base = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple.Attributes = 0; + CS_CHECK(GetFirstTuple, handle, &tuple); + while (1) { + CFG_CHECK(GetTupleData, handle, &tuple); + CFG_CHECK(ParseTuple, handle, &tuple, &parse); + + /* Check for matching Vcc, unless we're desperate */ + if (!pass) { + if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000) + goto next_entry; + } else if (dflt.vcc.present & (1<vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = + dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; + + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + link->conf.ConfigIndex = cfg->index; + link->io.BasePort1 = io->win[0].base; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + if (!(io->flags & CISTPL_IO_16BIT)) + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + if (io->nwin == 2) { + link->io.NumPorts1 = 8; + link->io.BasePort2 = io->win[1].base; + link->io.NumPorts2 = 1; + CFG_CHECK(RequestIO, link->handle, &link->io); + io_base = link->io.BasePort1; + ctl_base = link->io.BasePort2; + } else if ((io->nwin == 1) && (io->win[0].len >= 16)) { + link->io.NumPorts1 = io->win[0].len; + link->io.NumPorts2 = 0; + CFG_CHECK(RequestIO, link->handle, &link->io); + io_base = link->io.BasePort1; + ctl_base = link->io.BasePort1+0x0e; + } else goto next_entry; + /* If we've got this far, we're done */ + break; + } + + next_entry: + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; + if (pass) { + CS_CHECK(GetNextTuple, handle, &tuple); + } else if (CardServices(GetNextTuple, handle, &tuple) != 0) { + CS_CHECK(GetFirstTuple, handle, &tuple); + memset(&dflt, 0, sizeof(dflt)); + pass++; + } + } + + CS_CHECK(RequestIRQ, handle, &link->irq); + CS_CHECK(RequestConfiguration, handle, &link->conf); + + /* deal with brain dead IDE resource management */ + release_region(link->io.BasePort1, link->io.NumPorts1); + if (link->io.NumPorts2) + release_region(link->io.BasePort2, link->io.NumPorts2); + + /* retry registration in case device is still spinning up */ + for (i = 0; i < 10; i++) { + hd = ide_register(io_base, ctl_base, link->irq.AssignedIRQ); + if (hd >= 0) break; + if (link->io.NumPorts1 == 0x20) { + hd = ide_register(io_base+0x10, ctl_base+0x10, + link->irq.AssignedIRQ); + if (hd >= 0) { + io_base += 0x10; ctl_base += 0x10; + break; + } + } + __set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ/10); + } + + if (hd < 0) { + printk(KERN_NOTICE "ide_cs: ide_register() at 0x%3x & 0x%3x" + ", irq %u failed\n", io_base, ctl_base, + link->irq.AssignedIRQ); + goto failed; + } + + MOD_INC_USE_COUNT; + info->ndev = 1; + sprintf(info->node.dev_name, "hd%c", 'a'+(hd*2)); + info->node.major = ide_major[hd]; + info->node.minor = 0; + info->hd = hd; + link->dev = &info->node; + printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n", + info->node.dev_name, link->conf.Vcc/10, link->conf.Vcc%10, + link->conf.Vpp1/10, link->conf.Vpp1%10); + + link->state &= ~DEV_CONFIG_PENDING; + return; + +cs_failed: + cs_error(link->handle, last_fn, last_ret); +failed: + ide_release((u_long)link); + +} /* ide_config */ + +/*====================================================================== + + After a card is removed, ide_release() will unregister the net + device, and release the PCMCIA configuration. If the device is + still open, this will be postponed until it is closed. + +======================================================================*/ + +void ide_release(u_long arg) +{ + dev_link_t *link = (dev_link_t *)arg; + ide_info_t *info = link->priv; + + DEBUG(0, "ide_release(0x%p)\n", link); + + if (info->ndev) { + ide_unregister(info->hd); + MOD_DEC_USE_COUNT; + } + info->ndev = 0; + link->dev = NULL; + + CardServices(ReleaseConfiguration, link->handle); + CardServices(ReleaseIO, link->handle, &link->io); + CardServices(ReleaseIRQ, link->handle, &link->irq); + + link->state &= ~DEV_CONFIG; + +} /* ide_release */ + +/*====================================================================== + + The card status event handler. Mostly, this schedules other + stuff to run after an event is received. A CARD_REMOVAL event + also sets some flags to discourage the ide drivers from + talking to the ports. + +======================================================================*/ + +int ide_event(event_t event, int priority, + event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + + DEBUG(1, "ide_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) { + link->release.expires = jiffies + HZ/20; + link->state |= DEV_RELEASE_PENDING; + add_timer(&link->release); + } + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + ide_config(link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) + CardServices(ReleaseConfiguration, link->handle); + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (DEV_OK(link)) + CardServices(RequestConfiguration, link->handle, &link->conf); + break; + } + return 0; +} /* ide_event */ + +/*====================================================================*/ + +static int __init init_ide_cs(void) +{ + servinfo_t serv; + DEBUG(0, "%s\n", version); + CardServices(GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk(KERN_NOTICE "ide_cs: Card Services release " + "does not match!\n"); + return -1; + } + register_pccard_driver(&dev_info, &ide_attach, &ide_detach); + return 0; +} + +static void __exit exit_ide_cs(void) +{ + DEBUG(0, "ide_cs: unloading\n"); + unregister_pccard_driver(&dev_info); + while (dev_list != NULL) + ide_detach(dev_list); +} + +module_init(init_ide_cs); +module_exit(exit_ide_cs); diff -u --recursive --new-file v2.3.48/linux/drivers/block/ide-pci.c linux/drivers/block/ide-pci.c --- v2.3.48/linux/drivers/block/ide-pci.c Sat Feb 26 22:31:43 2000 +++ linux/drivers/block/ide-pci.c Mon Feb 28 07:20:23 2000 @@ -243,9 +243,12 @@ #ifdef CONFIG_BLK_DEV_SL82C105 extern void ide_init_sl82c105(ide_hwif_t *); +extern void ide_dmacapable_sl82c105(ide_hwif_t *, unsigned long); #define INIT_W82C105 &ide_init_sl82c105 +#define DMA_W82C105 &ide_dmacapable_sl82c105 #else #define INIT_W82C105 IDE_IGNORE +#define DMA_W82C105 NULL #endif #ifdef CONFIG_BLK_DEV_TRM290 @@ -316,7 +319,7 @@ {DEVID_TRM290, "TRM290", NULL, NULL, INIT_TRM290, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_NS87415, "NS87415", NULL, NULL, INIT_NS87415, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AEC6210, "AEC6210", PCI_AEC6210, NULL, INIT_AEC6210, DMA_AEC6210, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 }, - {DEVID_W82C105, "W82C105", NULL, NULL, INIT_W82C105, NULL, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, + {DEVID_W82C105, "W82C105", NULL, NULL, INIT_W82C105, DMA_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 }, {DEVID_UM8673F, "UM8673F", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, diff -u --recursive --new-file v2.3.48/linux/drivers/block/piix.c linux/drivers/block/piix.c --- v2.3.48/linux/drivers/block/piix.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/block/piix.c Mon Feb 28 07:16:54 2000 @@ -85,8 +85,8 @@ #include #include #include +#include -#include #include #include "ide_modes.h" diff -u --recursive --new-file v2.3.48/linux/drivers/block/rd.c linux/drivers/block/rd.c --- v2.3.48/linux/drivers/block/rd.c Wed Feb 16 17:03:51 2000 +++ linux/drivers/block/rd.c Thu Mar 2 11:33:45 2000 @@ -87,7 +87,7 @@ static int crd_load(struct file *fp, struct file *outfp); #ifdef CONFIG_BLK_DEV_INITRD -static int initrd_users = 0; +static int initrd_users; #endif #endif @@ -122,13 +122,13 @@ #ifndef MODULE -int rd_doload = 0; /* 1 = load RAM disk, 0 = don't load */ +int rd_doload; /* 1 = load RAM disk, 0 = don't load */ int rd_prompt = 1; /* 1 = prompt for RAM disk, 0 = don't prompt */ -int rd_image_start = 0; /* starting block # of image */ +int rd_image_start; /* starting block # of image */ #ifdef CONFIG_BLK_DEV_INITRD -unsigned long initrd_start,initrd_end; +unsigned long initrd_start, initrd_end; int mount_initrd = 1; /* zero if initrd should not be mounted */ -int initrd_below_start_ok = 0; +int initrd_below_start_ok; static int __init no_initrd(char *str) { @@ -293,11 +293,15 @@ switch (cmd) { case BLKFLSBUF: - if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; /* special: we want to release the ramdisk memory, it's not like with the other blockdevices where this ioctl only flushes away the buffer cache. */ + if ((atomic_read(&inode->i_bdev->bd_openers) > 2)) + return -EBUSY; destroy_buffers(inode->i_rdev); + rd_blocksizes[minor] = 0; break; case BLKGETSIZE: /* Return device size */ @@ -338,6 +342,8 @@ 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; return 0; @@ -366,7 +372,6 @@ if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS) return -ENXIO; - filp->f_op = &def_blk_fops; MOD_INC_USE_COUNT; return 0; @@ -389,12 +394,18 @@ { int i; - for (i = 0 ; i < NUM_RAMDISKS; i++) + for (i = 0 ; i < NUM_RAMDISKS; i++) { + struct block_device *bdev; + bdev = bdget(kdev_t_to_nr(MKDEV(MAJOR_NR,i))); + atomic_dec(&bdev->bd_openers); destroy_buffers(MKDEV(MAJOR_NR, i)); + } devfs_unregister (devfs_handle); unregister_blkdev( MAJOR_NR, "ramdisk" ); blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); + blksize_size[MAJOR_NR] = NULL; + blk_size[MAJOR_NR] = NULL; } /* This is the registration and initialization section of the RAM disk driver */ @@ -432,16 +443,21 @@ hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */ blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */ - blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */ - for (i = 0; i < NUM_RAMDISKS; i++) + for (i = 0; i < NUM_RAMDISKS; i++) { + struct block_device *bdev; register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &fd_fops, rd_size<<1); + bdev = bdget(kdev_t_to_nr(MKDEV(MAJOR_NR,i))); + atomic_inc(&bdev->bd_openers); /* avoid invalidate_buffers() */ + } #ifdef CONFIG_BLK_DEV_INITRD /* We ought to separate initrd operations here */ register_disk(NULL, MKDEV(MAJOR_NR,INITRD_MINOR), 1, &fd_fops, rd_size<<1); #endif + blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */ + /* rd_size is given in kB */ printk("RAMDISK driver initialized: " "%d RAM disks of %dK size %d blocksize\n", @@ -584,26 +600,28 @@ ram_device = MKDEV(MAJOR_NR, unit); + if ((inode = get_empty_inode()) == NULL) + return; memset(&infile, 0, sizeof(infile)); memset(&in_dentry, 0, sizeof(in_dentry)); - inode = get_empty_inode(); - inode->i_rdev = device; - inode->i_bdev = bdget(kdev_t_to_nr(device)); infile.f_mode = 1; /* read only */ infile.f_dentry = &in_dentry; in_dentry.d_inode = inode; + infile.f_op = &def_blk_fops; + init_special_inode(inode, S_IFBLK | S_IRUSR, kdev_t_to_nr(device)); + if ((out_inode = get_empty_inode()) == NULL) + goto free_inode; memset(&outfile, 0, sizeof(outfile)); memset(&out_dentry, 0, sizeof(out_dentry)); - out_inode = get_empty_inode(); - out_inode->i_rdev = ram_device; - out_inode->i_bdev = bdget(kdev_t_to_nr(ram_device)); outfile.f_mode = 3; /* read/write */ outfile.f_dentry = &out_dentry; out_dentry.d_inode = out_inode; + outfile.f_op = &def_blk_fops; + init_special_inode(out_inode, S_IFBLK | S_IRUSR | S_IWUSR, kdev_t_to_nr(ram_device)); if (blkdev_open(inode, &infile) != 0) - goto free_inodes; + goto free_inode; if (blkdev_open(out_inode, &outfile) != 0) goto free_inodes; @@ -697,9 +715,12 @@ if (infile.f_op->release) infile.f_op->release(inode, &infile); set_fs(fs); -free_inodes: - iput(inode); + return; +free_inodes: /* free inodes on error */ iput(out_inode); + blkdev_put(inode->i_bdev, BDEV_FILE); +free_inode: + iput(inode); } diff -u --recursive --new-file v2.3.48/linux/drivers/block/sl82c105.c linux/drivers/block/sl82c105.c --- v2.3.48/linux/drivers/block/sl82c105.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/block/sl82c105.c Mon Feb 28 07:20:23 2000 @@ -26,6 +26,8 @@ #include "ide_modes.h" +extern char *ide_xfer_verbose (byte xfer_rate); + #ifdef CONFIG_ARCH_NETWINDER /* * Convert a PIO mode and cycle time to the required on/off @@ -50,42 +52,7 @@ if (cmd_off == 0) cmd_off = 1; - return (cmd_on - 1) << 8 | (cmd_off - 1); -} - -/* - * Tell the drive to enable the specified PIO mode. - * This should be in ide.c, maybe as a special command - * (see do_special). - */ -static int ide_set_drive_pio_mode(ide_drive_t *drive, byte pio) -{ - ide_hwif_t *hwif = HWIF(drive); - ide_startstop_t startstop; - - if (pio > 2) { - /* FIXME: I don't believe that this SELECT_DRIVE is required, - * since ide.c only calls tuneproc from do_special, after - * the correct drive has been selected. - */ - SELECT_DRIVE(hwif, drive); - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); - OUT_BYTE(0x08 | pio, IDE_NSECTOR_REG); - OUT_BYTE(0x03, IDE_FEATURE_REG); - OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG); - - if (ide_wait_stat(&startstop, drive, DRIVE_READY, - BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD)) { - printk("%s: drive not ready for command\n", - drive->name); - return 1; /* return startstop; ?? */ - } - if (IDE_CONTROL_REG) - OUT_BYTE(drive->ctl, IDE_CONTROL_REG); - } - - return 0; /* return startstop; ?? */ + return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00); } /* @@ -97,26 +64,48 @@ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; ide_pio_data_t p; - unsigned int drv_ctrl = 0x909; + unsigned short drv_ctrl = 0x909; + unsigned int xfer_mode, reg; - pio = ide_get_best_pio_mode(drive, pio, 5, &p); + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - if (!ide_set_drive_pio_mode(drive, pio)) { - drv_ctrl = get_timing_sl82c105(&p); + pio = ide_get_best_pio_mode(drive, pio, 5, &p); - if (p.use_iordy) - drv_ctrl |= 0x40; + switch (pio) { + default: + case 0: xfer_mode = XFER_PIO_0; break; + case 1: xfer_mode = XFER_PIO_1; break; + case 2: xfer_mode = XFER_PIO_2; break; + case 3: xfer_mode = XFER_PIO_3; break; + case 4: xfer_mode = XFER_PIO_4; break; } - pci_write_config_word(dev, - (hwif->channel ? 0x4c : 0x44) - + (drive->select.b.unit ? 4 : 0), - drv_ctrl); + if (ide_config_drive_speed(drive, xfer_mode) == 0) + drv_ctrl = get_timing_sl82c105(&p); - printk("%s: selected PIO mode %d (%dns)\n", - drive->name, p.pio_mode, p.cycle_time); + pci_write_config_word(dev, reg, drv_ctrl); + pci_read_config_word(dev, reg, &drv_ctrl); + + printk("%s: selected %s (%dns) (%04X)\n", drive->name, + ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); } #endif + +void ide_dmacapable_sl82c105(ide_hwif_t *hwif, unsigned long dmabase) +{ + unsigned char rev; + + pci_read_config_byte(hwif->pci_dev, PCI_REVISION_ID, &rev); + + if (rev <= 5) { + hwif->autodma = 0; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + printk(" %s: revision %d, Bus-Master DMA disabled\n", + hwif->name, rev); + } + ide_setup_dma(hwif, dmabase, 8); +} void ide_init_sl82c105(ide_hwif_t *hwif) { diff -u --recursive --new-file v2.3.48/linux/drivers/char/Config.in linux/drivers/char/Config.in --- v2.3.48/linux/drivers/char/Config.in Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/Config.in Mon Feb 28 14:56:10 2000 @@ -11,6 +11,10 @@ tristate 'Standard/generic (dumb) serial support' CONFIG_SERIAL if [ "$CONFIG_SERIAL" = "y" ]; then bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE + if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL + tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL + fi fi bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then @@ -116,9 +120,23 @@ tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT tristate ' Mixcom Watchdog' CONFIG_MIXCOMWD + if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then + tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG + if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then + tristate ' NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG + fi + fi fi endmenu +if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then + tristate 'NetWinder thermometer support' CONFIG_DS1620 + tristate 'NetWinder Button' CONFIG_NWBUTTON + if [ "$CONFIG_NWBUTTON" != "n" ]; then + bool ' Reboot Using Button' CONFIG_NWBUTTON_REBOOT + fi + tristate 'NetWinder flash support' CONFIG_NWFLASH +fi tristate '/dev/nvram support' CONFIG_NVRAM tristate 'Enhanced Real Time Clock Support' CONFIG_RTC @@ -188,6 +206,7 @@ fi fi dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV + dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_SGI" = "y" ]; then dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_SGI diff -u --recursive --new-file v2.3.48/linux/drivers/char/Makefile linux/drivers/char/Makefile --- v2.3.48/linux/drivers/char/Makefile Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/Makefile Mon Feb 28 14:56:10 2000 @@ -251,6 +251,7 @@ obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o +obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_QIC02_TAPE) += tpqic02.o ifeq ($(CONFIG_FTAPE),y) diff -u --recursive --new-file v2.3.48/linux/drivers/char/README.epca linux/drivers/char/README.epca --- v2.3.48/linux/drivers/char/README.epca Tue Mar 16 14:21:35 1999 +++ linux/drivers/char/README.epca Mon Feb 28 07:16:54 2000 @@ -515,3 +515,11 @@ Files affected : epca.c Release version : 1.3.0-K ----------------------------------------------------------------------- +Programmer : Jeff Garzik +Date : February 26, 2000 +Description (Verbose) : Updated driver: + 1. Use new kernel PCI interfaces. + 2. Updated list of includes. +Files affected : epca.c +Release version : 1.3.0.1-LK +----------------------------------------------------------------------- diff -u --recursive --new-file v2.3.48/linux/drivers/char/c-qcam.c linux/drivers/char/c-qcam.c --- v2.3.48/linux/drivers/char/c-qcam.c Sun Nov 7 16:37:34 1999 +++ linux/drivers/char/c-qcam.c Sun Feb 27 09:00:17 2000 @@ -1,7 +1,20 @@ /* * Video4Linux Colour QuickCam driver - * Copyright 1997-1999 Philip Blundell + * Copyright 1997-2000 Philip Blundell * + * Module parameters: + * + * parport=auto -- probe all parports (default) + * parport=0 -- parport0 becomes qcam1 + * parport=2,0,1 -- parports 2,0,1 are tried in that order + * + * probe=0 -- do no probing, assume camera is present + * probe=1 -- use IEEE-1284 autoprobe data only (default) + * probe=2 -- probe aggressively for cameras + * + * The parport parameter controls which parports will be scanned. + * Scanning all parports causes some printers to print a garbage page. + * -- March 14, 1999 Billy Donahue */ #include @@ -32,6 +45,9 @@ struct semaphore lock; }; +/* cameras maximum */ +#define MAX_CAMS 4 + /* The three possible QuickCam modes */ #define QC_MILLIONS 0x18 #define QC_BILLIONS 0x10 @@ -42,6 +58,11 @@ #define QC_DECIMATION_2 2 #define QC_DECIMATION_4 4 +#define BANNER "Colour QuickCam for Video4Linux v0.05" + +static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 }; +static int probe = 2; + static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i) { /* note: the QC specs refer to the PCAck pin by voltage, not @@ -159,6 +180,22 @@ { unsigned int stat, ostat, i, count = 0; + /* The probe routine below is not very reliable. The IEEE-1284 + probe takes precedence. */ + /* XXX Currently parport provides no way to distinguish between + "the IEEE probe was not done" and "the probe was done, but + no device was found". Fix this one day. */ + if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA + && qcam->pport->probe_info[0].model + && !strcmp(qcam->pdev->port->probe_info[0].model, + "Color QuickCam 2.0")) { + printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n"); + return 1; + } + + if (probe < 2) + return 0; + parport_write_control(qcam->pport, 0xc); /* look for a heartbeat */ @@ -174,6 +211,26 @@ } } + /* Reset the camera and try again */ + parport_write_control(qcam->pport, 0xc); + parport_write_control(qcam->pport, 0x8); + mdelay(1); + parport_write_control(qcam->pport, 0xc); + mdelay(1); + count = 0; + + ostat = stat = parport_read_status(qcam->pport); + for (i=0; i<250; i++) + { + mdelay(1); + stat = parport_read_status(qcam->pport); + if (ostat != stat) + { + if (++count >= 3) return 1; + ostat = stat; + } + } + /* no (or flatline) camera, give up */ return 0; } @@ -627,7 +684,7 @@ /* video device template */ static struct video_device qcam_template= { - "Colour Quickcam", + "Colour QuickCam", VID_TYPE_CAPTURE, VID_HARDWARE_QCAM_C, qcam_open, @@ -681,7 +738,6 @@ return q; } -#define MAX_CAMS 4 static struct qcam_device *qcams[MAX_CAMS]; static unsigned int num_cams = 0; @@ -689,6 +745,19 @@ { struct qcam_device *qcam; + if (parport[0] != -1) + { + /* The user gave specific instructions */ + int i, found = 0; + for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) + { + if (parport[0] == port->number) + found = 1; + } + if (!found) + return -ENODEV; + } + if (num_cams == MAX_CAMS) return -ENOSPC; @@ -700,7 +769,7 @@ qc_reset(qcam); - if (qc_detect(qcam)==0) + if (probe && qc_detect(qcam)==0) { parport_release(qcam->pdev); parport_unregister_device(qcam->pdev); @@ -712,16 +781,18 @@ parport_release(qcam->pdev); - printk(KERN_INFO "Colour Quickcam found on %s\n", - qcam->pport->name); - if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1) { + printk(KERN_ERR "Unable to register Colour QuickCam on %s\n", + qcam->pport->name); parport_unregister_device(qcam->pdev); kfree(qcam); return -ENODEV; } + printk(KERN_INFO "video%d: Colour QuickCam found on %s\n", + qcam->vdev.minor, qcam->pport->name); + qcams[num_cams++] = qcam; return 0; @@ -734,8 +805,6 @@ kfree(qcam); } -#define BANNER "Connectix Colour Quickcam driver v0.03" - static void cq_attach(struct parport *port) { init_cqcam(port); @@ -756,11 +825,16 @@ static int __init cqcam_init (void) { printk(BANNER "\n"); + return parport_register_driver(&cqcam_driver); } MODULE_AUTHOR("Philip Blundell "); MODULE_DESCRIPTION(BANNER); +MODULE_PARM_DESC(parport ,"parport= for port detection method \n\ +probe=<0|1|2> # for camera detection method"); +MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i"); +MODULE_PARM(probe, "i"); static void __exit cqcam_cleanup (void) { diff -u --recursive --new-file v2.3.48/linux/drivers/char/digi1.h linux/drivers/char/digi1.h --- v2.3.48/linux/drivers/char/digi1.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/digi1.h Mon Feb 28 07:16:54 2000 @@ -0,0 +1,100 @@ +/* Definitions for DigiBoard ditty(1) command. */ + +#if !defined(TIOCMODG) +#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */ +#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */ +#endif + +#if !defined(TIOCMSET) +#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */ +#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */ +#endif + +#if !defined(TIOCMBIC) +#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */ +#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */ +#endif + +#if !defined(TIOCSDTR) +#define TIOCSDTR ('e'<<8) | 0 /* set DTR */ +#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */ +#endif + +/************************************************************************ + * Ioctl command arguments for DIGI parameters. + ************************************************************************/ +#define DIGI_GETA ('e'<<8) | 94 /* Read params */ + +#define DIGI_SETA ('e'<<8) | 95 /* Set params */ +#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */ +#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */ + +#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */ + /* control characters */ +#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */ + /* control characters */ +#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */ + /* flow control chars */ +#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */ + /* flow control chars */ + +#define DIGI_GETINFO ('e'<<8) | 103 /* Fill in digi_info */ +#define DIGI_POLLER ('e'<<8) | 104 /* Turn on/off poller */ +#define DIGI_INIT ('e'<<8) | 105 /* Allow things to run. */ + +struct digiflow_struct +{ + unsigned char startc; /* flow cntl start char */ + unsigned char stopc; /* flow cntl stop char */ +}; + +typedef struct digiflow_struct digiflow_t; + + +/************************************************************************ + * Values for digi_flags + ************************************************************************/ +#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ +#define DIGI_FAST 0x0002 /* Fast baud rates */ +#define RTSPACE 0x0004 /* RTS input flow control */ +#define CTSPACE 0x0008 /* CTS output flow control */ +#define DSRPACE 0x0010 /* DSR output flow control */ +#define DCDPACE 0x0020 /* DCD output flow control */ +#define DTRPACE 0x0040 /* DTR input flow control */ +#define DIGI_FORCEDCD 0x0100 /* Force carrier */ +#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ +#define DIGI_AIXON 0x0400 /* Aux flow control in fep */ + + +/************************************************************************ + * Values for digiDload + ************************************************************************/ +#define NORMAL 0 +#define PCI_CTL 1 + +#define SIZE8 0 +#define SIZE16 1 +#define SIZE32 2 + +/************************************************************************ + * Structure used with ioctl commands for DIGI parameters. + ************************************************************************/ +struct digi_struct +{ + unsigned short digi_flags; /* Flags (see above) */ +}; + +typedef struct digi_struct digi_t; + +struct digi_info +{ + unsigned long board; /* Which board is this ? */ + unsigned char status; /* Alive or dead */ + unsigned char type; /* see epca.h */ + unsigned char subtype; /* For future XEM, XR, etc ... */ + unsigned short numports; /* Number of ports configured */ + unsigned char *port; /* I/O Address */ + unsigned char *membase; /* DPR Address */ + unsigned char *version; /* For future ... */ + unsigned short windowData; /* For future ... */ +} ; diff -u --recursive --new-file v2.3.48/linux/drivers/char/digiFep1.h linux/drivers/char/digiFep1.h --- v2.3.48/linux/drivers/char/digiFep1.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/digiFep1.h Mon Feb 28 07:16:54 2000 @@ -0,0 +1,136 @@ + +#define CSTART 0x400L +#define CMAX 0x800L +#define ISTART 0x800L +#define IMAX 0xC00L +#define CIN 0xD10L +#define GLOBAL 0xD10L +#define EIN 0xD18L +#define FEPSTAT 0xD20L +#define CHANSTRUCT 0x1000L +#define RXTXBUF 0x4000L + + +struct global_data +{ + volatile ushort cin; + volatile ushort cout; + volatile ushort cstart; + volatile ushort cmax; + volatile ushort ein; + volatile ushort eout; + volatile ushort istart; + volatile ushort imax; +}; + + +struct board_chan +{ + int filler1; + int filler2; + volatile ushort tseg; + volatile ushort tin; + volatile ushort tout; + volatile ushort tmax; + + volatile ushort rseg; + volatile ushort rin; + volatile ushort rout; + volatile ushort rmax; + + volatile ushort tlow; + volatile ushort rlow; + volatile ushort rhigh; + volatile ushort incr; + + volatile ushort etime; + volatile ushort edelay; + volatile unchar *dev; + + volatile ushort iflag; + volatile ushort oflag; + volatile ushort cflag; + volatile ushort gmask; + + volatile ushort col; + volatile ushort delay; + volatile ushort imask; + volatile ushort tflush; + + int filler3; + int filler4; + int filler5; + int filler6; + + volatile unchar num; + volatile unchar ract; + volatile unchar bstat; + volatile unchar tbusy; + volatile unchar iempty; + volatile unchar ilow; + volatile unchar idata; + volatile unchar eflag; + + volatile unchar tflag; + volatile unchar rflag; + volatile unchar xmask; + volatile unchar xval; + volatile unchar mstat; + volatile unchar mchange; + volatile unchar mint; + volatile unchar lstat; + + volatile unchar mtran; + volatile unchar orun; + volatile unchar startca; + volatile unchar stopca; + volatile unchar startc; + volatile unchar stopc; + volatile unchar vnext; + volatile unchar hflow; + + volatile unchar fillc; + volatile unchar ochar; + volatile unchar omask; + + unchar filler7; + unchar filler8[28]; +}; + + +#define SRXLWATER 0xE0 +#define SRXHWATER 0xE1 +#define STOUT 0xE2 +#define PAUSETX 0xE3 +#define RESUMETX 0xE4 +#define SAUXONOFFC 0xE6 +#define SENDBREAK 0xE8 +#define SETMODEM 0xE9 +#define SETIFLAGS 0xEA +#define SONOFFC 0xEB +#define STXLWATER 0xEC +#define PAUSERX 0xEE +#define RESUMERX 0xEF +#define SETBUFFER 0xF2 +#define SETCOOKED 0xF3 +#define SETHFLOW 0xF4 +#define SETCTRLFLAGS 0xF5 +#define SETVNEXT 0xF6 + + + +#define BREAK_IND 0x01 +#define LOWTX_IND 0x02 +#define EMPTYTX_IND 0x04 +#define DATA_IND 0x08 +#define MODEMCHG_IND 0x20 + +#define FEP_HUPCL 0002000 +#if 0 +#define RTS 0x02 +#define CD 0x08 +#define DSR 0x10 +#define CTS 0x20 +#define RI 0x40 +#define DTR 0x80 +#endif diff -u --recursive --new-file v2.3.48/linux/drivers/char/digiPCI.h linux/drivers/char/digiPCI.h --- v2.3.48/linux/drivers/char/digiPCI.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/digiPCI.h Mon Feb 28 07:16:54 2000 @@ -0,0 +1,42 @@ +/************************************************************************* + * Defines and structure definitions for PCI BIOS Interface + *************************************************************************/ +#define PCIMAX 32 /* maximum number of PCI boards */ + + +#define PCI_VENDOR_DIGI 0x114F +#define PCI_DEVICE_EPC 0x0002 +#define PCI_DEVICE_RIGHTSWITCH 0x0003 /* For testing */ +#define PCI_DEVICE_XEM 0x0004 +#define PCI_DEVICE_XR 0x0005 +#define PCI_DEVICE_CX 0x0006 +#define PCI_DEVICE_XRJ 0x0009 /* Jupiter boards with */ +#define PCI_DEVICE_EPCJ 0x000a /* PLX 9060 chip for PCI */ + + +/* + * On the PCI boards, there is no IO space allocated + * The I/O registers will be in the first 3 bytes of the + * upper 2MB of the 4MB memory space. The board memory + * will be mapped into the low 2MB of the 4MB memory space + */ + +/* Potential location of PCI Bios from E0000 to FFFFF*/ +#define PCI_BIOS_SIZE 0x00020000 + +/* Size of Memory and I/O for PCI (4MB) */ +#define PCI_RAM_SIZE 0x00400000 + +/* Size of Memory (2MB) */ +#define PCI_MEM_SIZE 0x00200000 + +/* Offset of I/0 in Memory (2MB) */ +#define PCI_IO_OFFSET 0x00200000 + +#define MEMOUTB(basemem, pnum, setmemval) *(caddr_t)((basemem) + ( PCI_IO_OFFSET | pnum << 4 | pnum )) = (setmemval) +#define MEMINB(basemem, pnum) *(caddr_t)((basemem) + (PCI_IO_OFFSET | pnum << 4 | pnum )) /* for PCI I/O */ + + + + + diff -u --recursive --new-file v2.3.48/linux/drivers/char/ds1620.c linux/drivers/char/ds1620.c --- v2.3.48/linux/drivers/char/ds1620.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/ds1620.c Tue Feb 29 11:08:16 2000 @@ -352,18 +352,10 @@ #endif static struct file_operations ds1620_fops = { - NULL, /* lseek */ - ds1620_read, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - ds1620_ioctl, /* ioctl */ - NULL, /* mmap */ - ds1620_open, /* open */ - NULL, /* flush */ - ds1620_release, /* release */ - NULL, /* fsync */ - NULL, /* fasync */ + read: ds1620_read, + ioctl: ds1620_ioctl, + open: ds1620_open, + release: ds1620_release, }; static struct miscdevice ds1620_miscdev = { diff -u --recursive --new-file v2.3.48/linux/drivers/char/dz.c linux/drivers/char/dz.c --- v2.3.48/linux/drivers/char/dz.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/dz.c Mon Feb 28 07:18:20 2000 @@ -29,6 +29,7 @@ #define MOD_DEC_USE_COUNT #endif +#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/drivers/char/epca.c linux/drivers/char/epca.c --- v2.3.48/linux/drivers/char/epca.c Tue Aug 31 17:29:13 1999 +++ linux/drivers/char/epca.c Mon Feb 28 07:16:54 2000 @@ -28,95 +28,38 @@ /* See README.epca for change history --DAT*/ -#ifdef MODVERSIONS -#ifndef MODULE -#define MODULE -#endif -#endif - -/* ----------------------------------------------------------------------- - This way modules should work regardless if they defined MODULE or - MODVERSIONS. (MODVERSIONS is for the newer kernels ... --------------------------------------------------------------------------- */ - -#ifdef MODULE #include -#endif /* MODULE */ - -#include - -#define NEW_MODULES - -#ifdef NEW_MODULES -#ifdef MODVERSIONS -#include -#endif /* MODVERSIONS */ -#endif /* NEW_MODULES */ - -#ifdef MODULE #include -#endif /* MODULE */ - - -#include -#include -#include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include +#include #include -#include -#include -#include - - -#include - -#include -#include -#include +#include #include -#include -#include -#include -#include - -#ifdef MODULE -#ifndef NEW_MODULES -char kernel_version[]=UTS_RELEASE; -#endif /* NEW_MODULE */ -#endif /* MODULE */ - +#include #ifdef CONFIG_PCI #define ENABLE_PCI #endif /* CONFIG_PCI */ - - -#include #define putUser(arg1, arg2) put_user(arg1, (unsigned long *)arg2) #define getUser(arg1, arg2) get_user(arg1, (unsigned int *)arg2) - - #ifdef ENABLE_PCI #include -#include +#include "digiPCI.h" #endif /* ENABLE_PCI */ -#include -#include -#include -#include +#include "digi1.h" +#include "digiFep1.h" +#include "epca.h" +#include "epcaconfig.h" /* ---------------------- Begin defines ------------------------ */ -#define VERSION "1.3.0-K" +#define VERSION "1.3.0.1-LK" /* This major needs to be submitted to Linux to join the majors list */ @@ -127,6 +70,8 @@ #define MAXCARDS 7 #define epcaassert(x, msg) if (!(x)) epca_error(__LINE__, msg) +#define PFX "epca: " + /* ----------------- Begin global definitions ------------------- */ static char mesg[100]; @@ -140,7 +85,7 @@ MAXBOARDS is typically 12, but ISA and EISA cards are restricted to 7 below. --------------------------------------------------------------------------*/ -static struct board_info boards[7]; +static struct board_info boards[MAXBOARDS]; /* ------------- Begin structures used for driver registeration ---------- */ @@ -284,11 +229,7 @@ int pc_init(void); #ifdef ENABLE_PCI -static int init_PCI(int); -static int get_PCI_configuration(unsigned char, unsigned char, - unsigned int *, unsigned int *, - unsigned int *, unsigned int *, - unsigned int *, unsigned int *); +static int init_PCI(void); #endif /* ENABLE_PCI */ @@ -1588,7 +1529,7 @@ #ifdef MODULE /* -------------------- Begin init_module ---------------------- */ -int init_module() +int __init init_module() { /* Begin init_module */ unsigned long flags; @@ -1606,6 +1547,11 @@ #endif #ifdef MODULE /* -------------------- Begin cleanup_module ---------------------- */ + +#ifdef ENABLE_PCI +static struct pci_driver epca_driver; +#endif + void cleanup_module() { /* Begin cleanup_module */ @@ -1654,6 +1600,9 @@ } /* End for each port */ } /* End for each card */ +#ifdef ENABLE_PCI + pci_unregister_driver (&epca_driver); +#endif restore_flags(flags); @@ -1662,7 +1611,7 @@ /* ------------------ Begin pc_init ---------------------- */ -int pc_init(void) +int __init pc_init(void) { /* Begin pc_init */ /* ---------------------------------------------------------------- @@ -1748,7 +1697,7 @@ if (pci_present()) { if(num_cards < MAXBOARDS) - pci_boards_found += init_PCI(num_cards); + pci_boards_found += init_PCI(); num_cards += pci_boards_found; } else @@ -2039,10 +1988,7 @@ epcaassert(ch <= &digi_channels[nbdevs - 1], "ch out of range"); - if (bd->membase < (unsigned char *)0x100000) - memaddr = (unchar *) bd->membase; - else /* Else get special mapped memory above RAM */ - memaddr = (unchar *)bd->re_map_membase; + memaddr = (unchar *)bd->re_map_membase; /* The below command is necessary because newer kernels (2.1.x and @@ -2356,12 +2302,7 @@ assertgwinon(chan0); - if (bd->membase < (unsigned char *)0x100000) - eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->membase + tail + ISTART)); - else - { - eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->re_map_membase + tail + ISTART)); - } + eventbuf = (volatile unchar *)bus_to_virt((ulong)(bd->re_map_membase + tail + ISTART)); /* Get the channel the event occurred on */ channel = eventbuf[0]; @@ -2522,10 +2463,7 @@ cmdMax = (cmdStart + 4 + (ch->mailbox->cmax)); - if (ch->board->membase < (unsigned char *)0x100000) - memaddr = ch->board->membase; - else - memaddr = ch->board->re_map_membase; + memaddr = ch->board->re_map_membase; /* The below command is necessary because newer kernels (2.1.x and @@ -4036,231 +3974,128 @@ #ifdef ENABLE_PCI -/* --------------------- Begin get_PCI_configuration ---------------------- */ - -int get_PCI_configuration(unsigned char bus, unsigned char device_fn, - unsigned int *base_addr0, unsigned int *base_addr1, - unsigned int *base_addr2, unsigned int *base_addr3, - unsigned int *base_addr4, unsigned int *base_addr5) -{ /* Begin get_PCI_configuration */ - - struct pci_dev *dev = pci_find_slot(bus, device_fn); - - if (!dev) - return(0); - - *base_addr0 = dev->resource[0].start; - *base_addr1 = dev->resource[1].start; - *base_addr2 = dev->resource[2].start; - *base_addr3 = dev->resource[3].start; - *base_addr4 = dev->resource[4].start; - *base_addr5 = dev->resource[5].start; - - /* ------------------------------------------------------------------------ - NOTE - The code below mask out either the 2 or 4 bits dependent on the - space being addressed. (base_addr value reflecting io space, have their - first 2 bits mask out, while base_addr value reflecting mem space, have - their first 4 bits mask out.) These bits are flag bits and should always - be 0 when used as an address. - ---------------------------------------------------------------------------- */ - - return(1); -} /* End get_PCI_configuration */ - /* ------------------------ Begin init_PCI --------------------------- */ -int init_PCI(int boards_found) -{ /* Begin init_PCI */ - - unsigned char bus, device_fn; - int i, pci_count = 0; - unsigned int base_addr0, base_addr1, base_addr2, - base_addr3, base_addr4, base_addr5; - - base_addr0 = base_addr1 = base_addr2 = 0; - base_addr3 = base_addr4 = base_addr5 = 0; - - for(i = 0; i < (MAXBOARDS - boards_found); i++) - { /* Begin for each POSSIBLE remaining board */ - - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XR, - i, &bus, &device_fn)) - { /* Begin found XR */ - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Store a PCI/XR into the boards structure */ - - - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCIXR; - - boards[boards_found + pci_count].numports = 0x0; - - boards[boards_found + pci_count].port = (unsigned char *)((char *)base_addr0 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; - - if (base_addr0 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - ioremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); - } - - pci_count++; - - /* -------------------------------------------------------------- - I don't know what the below does, but the hardware guys say - its required on everything except PLX (In this case XRJ). - ---------------------------------------------------------------- */ - pcibios_write_config_byte(bus, device_fn, 0x40, 0); - pcibios_write_config_byte(bus, device_fn, 0x46, 0); - - } /* End store a PCI/XR into the board structure */ - - } /* End found XR */ - - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XEM, - i, &bus, &device_fn)) - { /* Begin found XEM */ - - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Begin store a PCI/XEM into the boards structure */ - - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCIXEM; - - boards[boards_found + pci_count].numports = 0x0; - boards[boards_found + pci_count].port = (char *)((char *)base_addr0 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; - - if (base_addr0 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - vremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); - } - - pci_count++; - /* -------------------------------------------------------------- - I don't know what the below does, but the hardware guys say - its required on everything except PLX (In this case XRJ). - ---------------------------------------------------------------- */ - pcibios_write_config_byte(bus, device_fn, 0x40, 0); - pcibios_write_config_byte(bus, device_fn, 0x46, 0); - - } /* End store a PCI/XEM into the boards structure */ - - } /* End found XEM */ - - - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_CX, - i, &bus, &device_fn)) - { /* Begin found CX */ - - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Begin store a PCI/CX into the boards structure */ - - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCICX; - - boards[boards_found + pci_count].numports = 0x0; - boards[boards_found + pci_count].port = (char *)((char *)base_addr0 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr0; - - if (base_addr0 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - vremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr0 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr0, 0x200000); - } - - pci_count++; - /* -------------------------------------------------------------- - I don't know what the below does, but the hardware guys say - its required on everything except PLX (In this case XRJ). - ---------------------------------------------------------------- */ - pcibios_write_config_byte(bus, device_fn, 0x40, 0); - pcibios_write_config_byte(bus, device_fn, 0x46, 0); - - } /* End store a PCI/CX into the boards structure */ - - } /* End found CX */ - - if (!pcibios_find_device(PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, - i, &bus, &device_fn)) - { /* Begin found XRJ */ - - if (get_PCI_configuration(bus, device_fn, &base_addr0, &base_addr1, - &base_addr2, &base_addr3, - &base_addr4, &base_addr5)) - { /* Begin store a PCI/XRJ into the boards structure */ - - boards[boards_found + pci_count].status = ENABLED; - boards[boards_found + pci_count].type = PCIXRJ; - - boards[boards_found + pci_count].numports = 0x0; - boards[boards_found + pci_count].port = (unsigned char *)(base_addr2 + PCI_IO_OFFSET); - /* Most cards use base_addr0, but some use base_addr2 */ - boards[boards_found + pci_count].membase = (unsigned char *)base_addr2; +enum epic_board_types { + brd_xr = 0, + brd_xem, + brd_cx, + brd_xrj, +}; + + +/* indexed directly by epic_board_types enum */ +static struct { + unsigned char board_type; + unsigned bar_idx; /* PCI base address region */ +} epca_info_tbl[] = { + { PCIXR, 0, }, + { PCIXEM, 0, }, + { PCICX, 0, }, + { PCIXRJ, 2, }, +}; + + +static int __init epca_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static int board_num = -1; + int board_idx, info_idx = ent->driver_data; + unsigned long addr; + + board_num++; + board_idx = board_num + num_cards; + if (board_idx >= MAXBOARDS) + goto err_out; + + addr = pci_resource_start (pdev, epca_info_tbl[info_idx].bar_idx); + if (!addr) { + printk (KERN_ERR PFX "PCI region #%d not available (size 0)\n", + epca_info_tbl[info_idx].bar_idx); + goto err_out; + } + + boards[board_idx].status = ENABLED; + boards[board_idx].type = epca_info_tbl[info_idx].board_type; + boards[board_idx].numports = 0x0; + boards[board_idx].port = + (unsigned char *)((char *) addr + PCI_IO_OFFSET); + boards[board_idx].membase = + (unsigned char *)((char *) addr); + + if (!request_mem_region (addr + PCI_IO_OFFSET, 0x200000, "epca")) { + printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out; + } + + boards[board_idx].re_map_port = ioremap(addr + PCI_IO_OFFSET, 0x200000); + if (!boards[board_idx].re_map_port) { + printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out_free_pciio; + } + + if (!request_mem_region (addr, 0x200000, "epca")) { + printk (KERN_ERR PFX "resource 0x%x @ 0x%lx unavailable\n", + 0x200000, addr); + goto err_out_free_iounmap; + } + + boards[board_idx].re_map_membase = ioremap(addr, 0x200000); + if (!boards[board_idx].re_map_membase) { + printk (KERN_ERR PFX "cannot map 0x%x @ 0x%lx\n", + 0x200000, addr + PCI_IO_OFFSET); + goto err_out_free_memregion; + } + + /* -------------------------------------------------------------- + I don't know what the below does, but the hardware guys say + its required on everything except PLX (In this case XRJ). + ---------------------------------------------------------------- */ + if (info_idx != brd_xrj) { + pci_write_config_byte(pdev, 0x40, 0); + pci_write_config_byte(pdev, 0x46, 0); + } + + return 0; - if (base_addr2 >= 0x100000) - { - /* ------------------------------------------------------------ - Standard physical addresses are valid to the kernel as long - as they aren't above RAM. Higher addresses (Such as are - typical of a PCI system) need to be mapped in with the - ioremap command. For boards using such high addresses the - driver will store both addresses. One address (The physical) - will be held for the apps use (And mmap) and the other (The - vremapped address) will be used in the kernel. - - ---------------------------------------------------------------- */ - boards[boards_found + pci_count].re_map_port = ioremap((base_addr2 + PCI_IO_OFFSET),0x200000); - boards[boards_found + pci_count].re_map_membase = ioremap(base_addr2, 0x200000); - } +err_out_free_memregion: + release_mem_region (addr, 0x200000); +err_out_free_iounmap: + iounmap (boards[board_idx].re_map_port); +err_out_free_pciio: + release_mem_region (addr + PCI_IO_OFFSET, 0x200000); +err_out: + return -ENODEV; +} - pci_count++; - } /* End store a PCI/XRJ into the boards structure */ +static struct pci_device_id epca_pci_tbl[] __initdata = { + { PCI_VENDOR_DIGI, PCI_DEVICE_XR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xr }, + { PCI_VENDOR_DIGI, PCI_DEVICE_XEM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xem }, + { PCI_VENDOR_DIGI, PCI_DEVICE_CX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_cx }, + { PCI_VENDOR_DIGI, PCI_DEVICE_XRJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, brd_xrj }, + { 0, }, /* terminate list */ +}; - } /* End found XRJ */ - } /* End for each POSSIBLE remaining board */ +int __init init_PCI (void) +{ /* Begin init_PCI */ + + int pci_count; + + memset (&epca_driver, 0, sizeof (epca_driver)); + epca_driver.name = "epca"; + epca_driver.id_table = epca_pci_tbl; + epca_driver.probe = epca_init_one; + + pci_count = pci_register_driver (&epca_driver); + + if (pci_count <= 0) { + pci_unregister_driver (&epca_driver); + pci_count = 0; + } return(pci_count); diff -u --recursive --new-file v2.3.48/linux/drivers/char/epca.h linux/drivers/char/epca.h --- v2.3.48/linux/drivers/char/epca.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/epca.h Mon Feb 28 07:16:54 2000 @@ -0,0 +1,170 @@ +#define XEMPORTS 0xC02 +#define XEPORTS 0xC22 + +#define MAX_ALLOC 0x100 + +#define MAXBOARDS 12 +#define FEPCODESEG 0x0200L +#define FEPCODE 0x2000L +#define BIOSCODE 0xf800L + +#define MISCGLOBAL 0x0C00L +#define NPORT 0x0C22L +#define MBOX 0x0C40L +#define PORTBASE 0x0C90L + +/* Begin code defines used for epca_setup */ + +#define INVALID_BOARD_TYPE 0x1 +#define INVALID_NUM_PORTS 0x2 +#define INVALID_MEM_BASE 0x4 +#define INVALID_PORT_BASE 0x8 +#define INVALID_BOARD_STATUS 0x10 +#define INVALID_ALTPIN 0x20 + +/* End code defines used for epca_setup */ + + +#define FEPCLR 0x00 +#define FEPMEM 0x02 +#define FEPRST 0x04 +#define FEPINT 0x08 +#define FEPMASK 0x0e +#define FEPWIN 0x80 + +#define PCXE 0 +#define PCXEVE 1 +#define PCXEM 2 +#define EISAXEM 3 +#define PC64XE 4 +#define PCXI 5 +#define PCIXEM 7 +#define PCICX 8 +#define PCIXR 9 +#define PCIXRJ 10 +#define EPCA_NUM_TYPES 6 + + +static char *board_desc[] = +{ + "PC/Xe", + "PC/Xeve", + "PC/Xem", + "EISA/Xem", + "PC/64Xe", + "PC/Xi", + "unknown", + "PCI/Xem", + "PCI/CX", + "PCI/Xr", + "PCI/Xrj", +}; + +#define STARTC 021 +#define STOPC 023 +#define IAIXON 0x2000 + + +#define TXSTOPPED 0x1 +#define LOWWAIT 0x2 +#define EMPTYWAIT 0x4 +#define RXSTOPPED 0x8 +#define TXBUSY 0x10 + +#define DISABLED 0 +#define ENABLED 1 +#define OFF 0 +#define ON 1 + +#define FEPTIMEOUT 200000 +#define SERIAL_TYPE_NORMAL 1 +#define SERIAL_TYPE_CALLOUT 2 +#define SERIAL_TYPE_INFO 3 +#define EPCA_EVENT_HANGUP 1 +#define EPCA_MAGIC 0x5c6df104L + +struct channel +{ + long magic; + unchar boardnum; + unchar channelnum; + unchar omodem; /* FEP output modem status */ + unchar imodem; /* FEP input modem status */ + unchar modemfake; /* Modem values to be forced */ + unchar modem; /* Force values */ + unchar hflow; + unchar dsr; + unchar dcd; + unchar m_rts ; /* The bits used in whatever FEP */ + unchar m_dcd ; /* is indiginous to this board to */ + unchar m_dsr ; /* represent each of the physical */ + unchar m_cts ; /* handshake lines */ + unchar m_ri ; + unchar m_dtr ; + unchar stopc; + unchar startc; + unchar stopca; + unchar startca; + unchar fepstopc; + unchar fepstartc; + unchar fepstopca; + unchar fepstartca; + unchar txwin; + unchar rxwin; + ushort fepiflag; + ushort fepcflag; + ushort fepoflag; + ushort txbufhead; + ushort txbufsize; + ushort rxbufhead; + ushort rxbufsize; + int close_delay; + int count; + int blocked_open; + int event; + int asyncflags; + uint dev; + long session; + long pgrp; + ulong statusflags; + ulong c_iflag; + ulong c_cflag; + ulong c_lflag; + ulong c_oflag; + unchar *txptr; + unchar *rxptr; + unchar *tmp_buf; + struct board_info *board; + volatile struct board_chan *brdchan; + struct digi_struct digiext; + struct tty_struct *tty; + struct termios normal_termios; + struct termios callout_termios; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + struct tq_struct tqueue; + volatile struct global_data *mailbox; +}; + +struct board_info +{ + unchar status; + unchar type; + unchar altpin; + ushort numports; + unchar *port; + unchar *membase; + unchar *re_map_port; + unchar *re_map_membase; + ulong memory_seg; + void ( * memwinon ) (struct board_info *, unsigned int) ; + void ( * memwinoff ) (struct board_info *, unsigned int) ; + void ( * globalwinon ) (struct channel *) ; + void ( * txwinon ) (struct channel *) ; + void ( * rxwinon ) (struct channel *) ; + void ( * memoff ) (struct channel *) ; + void ( * assertgwinon ) (struct channel *) ; + void ( * assertmemoff ) (struct channel *) ; + unchar poller_inhibited ; +}; + diff -u --recursive --new-file v2.3.48/linux/drivers/char/epcaconfig.h linux/drivers/char/epcaconfig.h --- v2.3.48/linux/drivers/char/epcaconfig.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/epcaconfig.h Mon Feb 28 07:16:54 2000 @@ -0,0 +1,7 @@ +#define NUMCARDS 0 +#define NBDEVS 0 + +struct board_info static_boards[NUMCARDS]={ +}; + +/* DO NOT HAND EDIT THIS FILE! */ diff -u --recursive --new-file v2.3.48/linux/drivers/char/mem.c linux/drivers/char/mem.c --- v2.3.48/linux/drivers/char/mem.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/mem.c Sun Feb 27 08:52:18 2000 @@ -84,7 +84,7 @@ written+=sz; } #endif - if (copy_from_user(p, buf, count)) + if (copy_from_user(p, buf, count)) return -EFAULT; written += count; *ppos += written; @@ -634,12 +634,12 @@ misc_init(); #ifdef CONFIG_SOUND soundcore_init(); -#ifdef CONFIG_SOUND_OSS +#ifdef CONFIG_SOUND_OSS soundcard_init(); -#endif +#endif #ifdef CONFIG_DMASOUND dmasound_init(); -#endif +#endif #endif #ifdef CONFIG_SPARCAUDIO sparcaudio_init(); diff -u --recursive --new-file v2.3.48/linux/drivers/char/nwbutton.c linux/drivers/char/nwbutton.c --- v2.3.48/linux/drivers/char/nwbutton.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/nwbutton.c Tue Feb 29 11:08:16 2000 @@ -207,16 +207,9 @@ */ static struct file_operations button_fops = { - NULL, /* lseek */ - button_read, - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* mmap */ - button_open, - NULL, /* flush */ - button_release, + read: button_read, + open: button_open, + release: button_release, }; /* diff -u --recursive --new-file v2.3.48/linux/drivers/char/nwflash.c linux/drivers/char/nwflash.c --- v2.3.48/linux/drivers/char/nwflash.c Sat Feb 26 22:31:44 2000 +++ linux/drivers/char/nwflash.c Tue Feb 29 11:08:16 2000 @@ -60,20 +60,12 @@ static struct file_operations flash_fops = { - flash_llseek, /* llseek */ - flash_read, /* read */ - flash_write, /* write */ - NULL, /* no special readdir */ - NULL, /* no special select */ - flash_ioctl, - NULL, /* no special mmap */ - open_flash, - NULL, /* no special flush */ - release_flash, - NULL, /* no special fsync */ - NULL, /* no special fasync */ - NULL, /* no special check_media_change */ - NULL /* no special revaldate */ + llseek: flash_llseek, + read: flash_read, + write: flash_write, + ioctl: flash_ioctl, + open: open_flash, + release: release_flash, }; static struct miscdevice flash_miscdev = diff -u --recursive --new-file v2.3.48/linux/drivers/char/specialix.c linux/drivers/char/specialix.c --- v2.3.48/linux/drivers/char/specialix.c Mon Nov 1 13:56:26 1999 +++ linux/drivers/char/specialix.c Thu Mar 2 10:16:45 2000 @@ -59,11 +59,14 @@ * Revision 1.8: Jul 1 1997 * port to linux-2.1.43 kernel. * Revision 1.9: Oct 9 1998 - * Added stuff for the IO8+/PCI version. . + * Added stuff for the IO8+/PCI version. + * Revision 1.10: Oct 22 1999 / Jan 21 2000. + * Added stuff for setserial. + * Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr) * */ -#define VERSION "1.8" +#define VERSION "1.10" /* @@ -1070,10 +1073,17 @@ /* * Now we must calculate some speed depended things */ - + /* Set baud rate for port */ - tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] + - CD186x_TPC/2) / CD186x_TPC); + tmp = port->custom_divisor ; + if ( tmp ) + printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. \n" + "This is an untested option, please be carefull.\n", + port_No (port), tmp); + else + tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] + + CD186x_TPC/2) / CD186x_TPC); + if ((tmp < 0x10) && time_before(again, jiffies)) { again = jiffies + HZ * 60; /* Page 48 of version 2.0 of the CL-CD1865 databook */ @@ -1095,9 +1105,13 @@ sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); sx_out(bp, CD186x_RBPRL, tmp & 0xff); sx_out(bp, CD186x_TBPRL, tmp & 0xff); - - baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ - + + if (port->custom_divisor) { + baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor; + baud = ( baud + 5 ) / 10; + } else + baud = (baud_table[baud] + 5) / 10; /* Estimated CPS */ + /* Two timer ticks seems enough to wakeup something like SLIP driver */ tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO; port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ? @@ -1860,7 +1874,8 @@ if (error) return error; - copy_from_user(&tmp, newinfo, sizeof(tmp)); + if (copy_from_user(&tmp, newinfo, sizeof(tmp))) + return -EFAULT; #if 0 if ((tmp.irq != bp->irq) || @@ -1875,6 +1890,7 @@ change_speed = ((port->flags & ASYNC_SPD_MASK) != (tmp.flags & ASYNC_SPD_MASK)); + change_speed |= (tmp.custom_divisor != port->custom_divisor); if (!capable(CAP_SYS_ADMIN)) { if ((tmp.close_delay != port->close_delay) || @@ -1884,11 +1900,13 @@ return -EPERM; port->flags = ((port->flags & ~ASYNC_USR_MASK) | (tmp.flags & ASYNC_USR_MASK)); + port->custom_divisor = tmp.custom_divisor; } else { port->flags = ((port->flags & ~ASYNC_FLAGS) | (tmp.flags & ASYNC_FLAGS)); port->close_delay = tmp.close_delay; port->closing_wait = tmp.closing_wait; + port->custom_divisor = tmp.custom_divisor; } if (change_speed) { save_flags(flags); cli(); @@ -1919,8 +1937,10 @@ tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC; tmp.close_delay = port->close_delay * HZ/100; tmp.closing_wait = port->closing_wait * HZ/100; + tmp.custom_divisor = port->custom_divisor; tmp.xmit_fifo_size = CD186x_NFIFO; - copy_to_user(retinfo, &tmp, sizeof(tmp)); + if (copy_to_user(retinfo, &tmp, sizeof(tmp))) + return -EFAULT; return 0; } diff -u --recursive --new-file v2.3.48/linux/drivers/char/tuner-3036.c linux/drivers/char/tuner-3036.c --- v2.3.48/linux/drivers/char/tuner-3036.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/char/tuner-3036.c Mon Feb 28 14:56:10 2000 @@ -0,0 +1,227 @@ +/* + * Driver for Philips SAB3036 "CITAC" tuner control chip. + * + * Author: Phil Blundell + * + * The SAB3036 is just about different enough from the chips that + * tuner.c copes with to make it not worth the effort to crowbar + * the support into that file. So instead we have a separate driver. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "tuner.h" + +static int debug; /* insmod parameter */ +static int this_adap; + +static struct i2c_client client_template; + +/* Addresses to scan */ +static unsigned short normal_i2c[] = {I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {0x60, 0x61, I2C_CLIENT_END}; +static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; +static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + normal_i2c, normal_i2c_range, + probe, probe_range, + ignore, ignore_range, + force +}; + +/* ---------------------------------------------------------------------- */ + +static unsigned char +tuner_getstatus (struct i2c_client *c) +{ + unsigned char byte; + if (i2c_master_recv(c, &byte, 1) != 1) + printk(KERN_ERR "tuner-3036: I/O error.\n"); + return byte; +} + +#define TUNER_FL 0x80 + +static int +tuner_islocked (struct i2c_client *c) +{ + return (tuner_getstatus(c) & TUNER_FL); +} + +/* ---------------------------------------------------------------------- */ + +static void +set_tv_freq(struct i2c_client *c, int freq) +{ + u16 div = ((freq * 20) / 16); + unsigned long give_up = jiffies + HZ; + unsigned char buffer[2]; + + if (debug) + printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div); + + /* Select high tuning current */ + buffer[0] = 0x29; + buffer[1] = 0x3e; + + if (i2c_master_send(c, buffer, 2) != 2) + printk("tuner: i2c i/o error 1\n"); + + buffer[0] = 0x80 | ((div>>8) & 0x7f); + buffer[1] = div & 0xff; + + if (i2c_master_send(c, buffer, 2) != 2) + printk("tuner: i2c i/o error 2\n"); + + while (!tuner_islocked(c) && time_before(jiffies, give_up)) + schedule(); + + if (!tuner_islocked(c)) + printk(KERN_WARNING "tuner: failed to achieve PLL lock\n"); + + /* Select low tuning current and engage AFC */ + buffer[0] = 0x29; + buffer[1] = 0xb2; + + if (i2c_master_send(c, buffer, 2) != 2) + printk("tuner: i2c i/o error 3\n"); + + if (debug) + printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c)); +} + +/* ---------------------------------------------------------------------- */ + +static int +tuner_attach(struct i2c_adapter *adap, int addr, + unsigned short flags, int kind) +{ + static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 }; + + struct i2c_client *client; + + if (this_adap > 0) + return -1; + this_adap++; + + client_template.adapter = adap; + client_template.addr = addr; + + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + memcpy(client, &client_template, sizeof(struct i2c_client)); + + printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client)); + + i2c_attach_client(client); + MOD_INC_USE_COUNT; + + if (i2c_master_send(client, buffer, 2) != 2) + printk("tuner: i2c i/o error 1\n"); + if (i2c_master_send(client, buffer+2, 2) != 2) + printk("tuner: i2c i/o error 2\n"); + if (i2c_master_send(client, buffer+4, 2) != 2) + printk("tuner: i2c i/o error 3\n"); + return 0; +} + +static int +tuner_detach(struct i2c_client *c) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +static int +tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + int *iarg = (int*)arg; + + switch (cmd) + { + case TUNER_SET_TVFREQ: + set_tv_freq(client, *iarg); + break; + + default: + return -EINVAL; + } + return 0; +} + +static int +tuner_probe(struct i2c_adapter *adap) +{ + this_adap = 0; + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_LP)) + return i2c_probe(adap, &addr_data, tuner_attach); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static struct i2c_driver +i2c_driver_tuner = +{ + "sab3036", /* name */ + I2C_DRIVERID_SAB3036, /* ID */ + I2C_DF_NOTIFY, + tuner_probe, + tuner_detach, + tuner_command +}; + +static struct i2c_client client_template = +{ + "SAB3036", /* name */ + -1, + 0, + 0, + NULL, + &i2c_driver_tuner +}; + +EXPORT_NO_SYMBOLS; + +int __init +tuner3036_init(void) +{ + i2c_add_driver(&i2c_driver_tuner); + return 0; +} + +void __exit +tuner3036_exit(void) +{ + i2c_del_driver(&i2c_driver_tuner); +} + +MODULE_DESCRIPTION("SAB3036 tuner driver"); +MODULE_AUTHOR("Philip Blundell "); +MODULE_PARM(debug,"i"); +MODULE_PARM_DESC(debug,"Enable debugging output"); + +module_init(tuner3036_init); +module_exit(tuner3036_exit); diff -u --recursive --new-file v2.3.48/linux/drivers/char/vc_screen.c linux/drivers/char/vc_screen.c --- v2.3.48/linux/drivers/char/vc_screen.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/char/vc_screen.c Sun Feb 27 08:52:18 2000 @@ -49,7 +49,7 @@ vcs_size(struct inode *inode) { int size; - int currcons = MINOR(inode->i_rdev) & 127; + int currcons = MINOR(inode->i_rdev) & 127; if (currcons == 0) currcons = fg_console; else diff -u --recursive --new-file v2.3.48/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.3.48/linux/drivers/char/vt.c Sat Feb 26 22:31:45 2000 +++ linux/drivers/char/vt.c Sun Feb 27 08:52:18 2000 @@ -203,7 +203,7 @@ if (!(key_map = key_maps[s])) { int j; - if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && + if (keymap_count >= MAX_NR_OF_USER_KEYMAPS && !capable(CAP_SYS_RESOURCE)) return -EPERM; diff -u --recursive --new-file v2.3.48/linux/drivers/char/wdt285.c linux/drivers/char/wdt285.c --- v2.3.48/linux/drivers/char/wdt285.c Sat Feb 26 22:31:45 2000 +++ linux/drivers/char/wdt285.c Tue Feb 29 11:08:16 2000 @@ -153,18 +153,10 @@ static struct file_operations watchdog_fops= { - NULL, /* Seek */ - NULL, /* Read */ - watchdog_write, /* Write */ - NULL, /* Readdir */ - NULL, /* Select */ - watchdog_ioctl, /* Ioctl */ - NULL, /* MMap */ - watchdog_open, - NULL, /* flush */ - watchdog_release, - NULL, - NULL /* Fasync */ + write: watchdog_write, + ioctl: watchdog_ioctl, + open: watchdog_open, + release: watchdog_release, }; static struct miscdevice watchdog_miscdev= diff -u --recursive --new-file v2.3.48/linux/drivers/char/wdt977.c linux/drivers/char/wdt977.c --- v2.3.48/linux/drivers/char/wdt977.c Sat Feb 26 22:31:45 2000 +++ linux/drivers/char/wdt977.c Tue Feb 29 11:08:16 2000 @@ -162,18 +162,9 @@ static struct file_operations wdt977_fops= { - NULL, /* Seek */ - NULL, /* Read */ - wdt977_write, /* Write */ - NULL, /* Readdir */ - NULL, /* Select */ - NULL, /* Ioctl */ - NULL, /* MMap */ - wdt977_open, - NULL, /* flush */ - wdt977_release, - NULL, - NULL /* Fasync */ + write: wdt977_write, + open: wdt977_open, + release: wdt977_release, }; static struct miscdevice wdt977_miscdev= diff -u --recursive --new-file v2.3.48/linux/drivers/i2o/i2o_lan.c linux/drivers/i2o/i2o_lan.c --- v2.3.48/linux/drivers/i2o/i2o_lan.c Tue Jan 11 22:31:40 2000 +++ linux/drivers/i2o/i2o_lan.c Mon Feb 28 07:16:54 2000 @@ -131,7 +131,7 @@ switch (msg[1] >> 24) { case LAN_RECEIVE_POST: { - if (dev->start) { + if (netif_running(dev)) { if (!(msg[4]>>24)) { i2o_lan_receive_post_reply(dev,msg); break; @@ -162,10 +162,8 @@ trl_count--; } - if (dev->tbusy) { - clear_bit(0,(void*)&dev->tbusy); - mark_bh(NET_BH); /* inform upper layers */ - } + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); break; } @@ -536,8 +534,7 @@ return -ENOMEM; priv->i2o_fbl_tail = -1; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); i2o_set_batch_mode(dev); i2o_lan_receive_post(dev); @@ -562,8 +559,7 @@ printk(KERN_WARNING "%s: Unable to clear the event mask.\n", #endif dev->name); - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); i2o_lan_suspend(dev); if (i2o_release_device(i2o_dev, &i2o_lan_handler, I2O_CLAIM_PRIMARY)) @@ -617,15 +613,6 @@ u32 m, *msg; u32 *sgl_elem; - /* - * Keep interrupt from changing dev->tbusy from underneath us - * (Do we really need to do this?) - */ - - if (test_and_set_bit(0,(void*)&dev->tbusy) != 0) { - return 1; - } - priv->tx_count++; priv->tx_out++; @@ -673,8 +660,8 @@ /* If HDMs TxMaxPktOut reached, stay busy (don't clean tbusy) */ - if (priv->tx_out < priv->tx_max_out) - clear_bit(0, (void *)&dev->tbusy); + if (priv->tx_out >= priv->tx_max_out) + netif_stop_queue(dev); return 0; } diff -u --recursive --new-file v2.3.48/linux/drivers/ieee1394/aic5800.c linux/drivers/ieee1394/aic5800.c --- v2.3.48/linux/drivers/ieee1394/aic5800.c Fri Jan 21 18:19:16 2000 +++ linux/drivers/ieee1394/aic5800.c Mon Feb 28 07:16:54 2000 @@ -26,11 +26,11 @@ #include #include #include +#include #include #include #include #include -#include #include "ieee1394_types.h" #include "hosts.h" diff -u --recursive --new-file v2.3.48/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c --- v2.3.48/linux/drivers/isdn/avmb1/capi.c Sat Feb 26 22:31:45 2000 +++ linux/drivers/isdn/avmb1/capi.c Tue Feb 29 11:08:16 2000 @@ -515,18 +515,13 @@ static struct file_operations capi_fops = { - capi_llseek, - capi_read, - capi_write, - NULL, /* capi_readdir */ - capi_poll, - capi_ioctl, - NULL, /* capi_mmap */ - capi_open, - NULL, /* capi_flush */ - capi_release, - NULL, /* capi_fsync */ - NULL, /* capi_fasync */ + llseek: capi_llseek, + read: capi_read, + write: capi_write, + poll: capi_poll, + ioctl: capi_ioctl, + open: capi_open, + release: capi_release, }; /* -------- /proc functions ----------------------------------- */ diff -u --recursive --new-file v2.3.48/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c --- v2.3.48/linux/drivers/isdn/divert/divert_procfs.c Sat Feb 26 22:31:45 2000 +++ linux/drivers/isdn/divert/divert_procfs.c Tue Feb 29 11:08:16 2000 @@ -302,17 +302,13 @@ static struct file_operations isdn_fops = { - isdn_divert_lseek, - isdn_divert_read, - isdn_divert_write, - NULL, /* isdn_readdir */ - isdn_divert_poll, /* isdn_poll */ - isdn_divert_ioctl, /* isdn_ioctl */ - NULL, /* isdn_mmap */ - isdn_divert_open, - NULL, /* flush */ - isdn_divert_close, - NULL /* fsync */ + llseek: isdn_divert_lseek, + read: isdn_divert_read, + write: isdn_divert_write, + poll: isdn_divert_poll, + ioctl: isdn_divert_ioctl, + open: isdn_divert_open, + release: isdn_divert_close, }; /****************************/ diff -u --recursive --new-file v2.3.48/linux/drivers/isdn/hisax/hfc_sx.c linux/drivers/isdn/hisax/hfc_sx.c --- v2.3.48/linux/drivers/isdn/hisax/hfc_sx.c Sat Feb 26 22:31:45 2000 +++ linux/drivers/isdn/hisax/hfc_sx.c Mon Feb 28 07:18:20 2000 @@ -41,7 +41,6 @@ * */ -#include #define __NO_VERSION__ #include "hisax.h" #include "hfc_sx.h" diff -u --recursive --new-file v2.3.48/linux/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c --- v2.3.48/linux/drivers/isdn/hysdn/hysdn_procconf.c Sat Feb 26 22:31:46 2000 +++ linux/drivers/isdn/hysdn/hysdn_procconf.c Tue Feb 29 11:08:16 2000 @@ -403,17 +403,11 @@ /******************************************************/ static struct file_operations conf_fops = { - hysdn_dummy_lseek, - hysdn_conf_read, - hysdn_conf_write, - NULL, /* readdir */ - NULL, /* poll */ - NULL, /* ioctl */ - NULL, /* mmap */ - hysdn_conf_open, - NULL, /* flush */ - hysdn_conf_close, - NULL /* fsync */ + llseek: hysdn_dummy_lseek, + read: hysdn_conf_read, + write: hysdn_conf_write, + open: hysdn_conf_open, + release: hysdn_conf_close, }; /*****************************/ diff -u --recursive --new-file v2.3.48/linux/drivers/isdn/hysdn/hysdn_procfs.c linux/drivers/isdn/hysdn/hysdn_procfs.c --- v2.3.48/linux/drivers/isdn/hysdn/hysdn_procfs.c Sat Feb 26 22:31:46 2000 +++ linux/drivers/isdn/hysdn/hysdn_procfs.c Tue Feb 29 11:08:16 2000 @@ -338,17 +338,12 @@ /**************************************************/ static struct file_operations log_fops = { - hysdn_dummy_lseek, - hysdn_log_read, - hysdn_log_write, - NULL, /* readdir */ - hysdn_log_poll, /* poll */ - NULL, /*hysdn_log_ioctl, *//* ioctl */ - NULL, /* mmap */ - hysdn_log_open, - NULL, /* flush */ - hysdn_log_close, - NULL /* fsync */ + llseek: hysdn_dummy_lseek, + read: hysdn_log_read, + write: hysdn_log_write, + poll: hysdn_log_poll, + open: hysdn_log_open, + release: hysdn_log_close, }; /*****************************************/ diff -u --recursive --new-file v2.3.48/linux/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c --- v2.3.48/linux/drivers/isdn/hysdn/hysdn_proclog.c Sat Feb 26 22:31:46 2000 +++ linux/drivers/isdn/hysdn/hysdn_proclog.c Tue Feb 29 11:08:16 2000 @@ -420,17 +420,12 @@ /**************************************************/ static struct file_operations log_fops = { - hysdn_dummy_lseek, - hysdn_log_read, - hysdn_log_write, - NULL, /* readdir */ - hysdn_log_poll, /* poll */ - NULL, - NULL, /* mmap */ - hysdn_log_open, - NULL, /* flush */ - hysdn_log_close, - NULL /* fsync */ + llseek: hysdn_dummy_lseek, + read: hysdn_log_read, + write: hysdn_log_write, + poll: hysdn_log_poll, + open: hysdn_log_open, + release: hysdn_log_close, }; /***********************************************************************************/ diff -u --recursive --new-file v2.3.48/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c --- v2.3.48/linux/drivers/isdn/isdn_common.c Sat Feb 26 22:31:46 2000 +++ linux/drivers/isdn/isdn_common.c Tue Feb 29 11:08:16 2000 @@ -2070,17 +2070,13 @@ static struct file_operations isdn_fops = { - isdn_lseek, - isdn_read, - isdn_write, - NULL, /* isdn_readdir */ - isdn_poll, /* isdn_poll */ - isdn_ioctl, /* isdn_ioctl */ - NULL, /* isdn_mmap */ - isdn_open, - NULL, /* flush */ - isdn_close, - NULL /* fsync */ + llseek: isdn_lseek, + read: isdn_read, + write: isdn_write, + poll: isdn_poll, + ioctl: isdn_ioctl, + open: isdn_open, + release: isdn_close, }; char * diff -u --recursive --new-file v2.3.48/linux/drivers/macintosh/via-pmu68k.c linux/drivers/macintosh/via-pmu68k.c --- v2.3.48/linux/drivers/macintosh/via-pmu68k.c Wed Feb 16 17:03:52 2000 +++ linux/drivers/macintosh/via-pmu68k.c Tue Feb 29 11:08:16 2000 @@ -1038,16 +1038,10 @@ } static struct file_operations pmu_device_fops = { - NULL, /* no seek */ - pmu_read, - pmu_write, - NULL, /* no readdir */ - NULL, /* no poll yet */ - pmu_ioctl, - NULL, /* no mmap */ - pmu_open, - NULL, /* flush */ - NULL /* no release */ + read: pmu_read, + write: pmu_write, + ioctl: pmu_ioctl, + open: pmu_open, }; static struct miscdevice pmu_device = { diff -u --recursive --new-file v2.3.48/linux/drivers/net/3c505.c linux/drivers/net/3c505.c --- v2.3.48/linux/drivers/net/3c505.c Sat Feb 26 22:31:46 2000 +++ linux/drivers/net/3c505.c Mon Feb 28 07:16:54 2000 @@ -1242,12 +1242,12 @@ adapter->got[CMD_CONFIGURE_82586] = 0; if (!send_pcb(dev, &adapter->tx_pcb)) { - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); printk("%s: couldn't send 82586 configure command\n", dev->name); } else { int timeout = jiffies + TIMEOUT; - spin_unlock_irqrestore(&lp->lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); if (time_after_eq(jiffies, timeout)) TIMEOUT_MSG(__LINE__); diff -u --recursive --new-file v2.3.48/linux/drivers/net/3c515.c linux/drivers/net/3c515.c --- v2.3.48/linux/drivers/net/3c515.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/net/3c515.c Thu Mar 2 10:17:41 2000 @@ -11,6 +11,8 @@ Center of Excellence in Space Data and Information Sciences Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 + 2/2/00- Added support for kernel-level ISAPnP + by Stephen Frost and Alessandro Zummo Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox. */ @@ -46,6 +48,7 @@ #include #include +#include #include #include @@ -349,6 +352,21 @@ { "Default", 0, 0xFF, XCVR_10baseT, 10000}, }; +#ifdef CONFIG_ISAPNP +struct corkscrew_isapnp_adapters_struct { + unsigned short vendor, function; + char *name; +}; +struct corkscrew_isapnp_adapters_struct corkscrew_isapnp_adapters[] = { + {ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051), "3Com Fast EtherLink ISA"}, + {0, } +}; +int corkscrew_isapnp_phys_addr[3] = { + 0, 0, 0 +}; +#endif +static int nopnp = 0; + static int corkscrew_scan(struct net_device *dev); static struct net_device *corkscrew_found_device(struct net_device *dev, int ioaddr, int irq, @@ -422,11 +440,79 @@ static int corkscrew_scan(struct net_device *dev) { int cards_found = 0; - static int ioaddr = 0x100; + short i; + static int ioaddr; + static int pnp_cards = 0; + +#ifdef CONFIG_ISAPNP + if(nopnp == 1) + goto no_pnp; + for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) { + struct pci_dev *idev = NULL; + int irq, j; + while((idev = isapnp_find_dev(NULL, + corkscrew_isapnp_adapters[i].vendor, + corkscrew_isapnp_adapters[i].function, + idev))) { + + if(idev->active) idev->deactivate(idev); + + if(idev->prepare(idev)<0) + continue; + if (!(idev->resource[0].flags & IORESOURCE_IO)) + continue; + if(idev->activate(idev)<0) { + printk("isapnp configure failed (out of resources?)\n"); + return -ENOMEM; + } + if (!idev->resource[0].start || check_region(idev->resource[0].start,16)) + continue; + ioaddr = idev->resource[0].start; + irq = idev->irq_resource[0].start; + if(corkscrew_debug) + printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n", + corkscrew_isapnp_adapters[i].name,ioaddr, irq); + + if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) + continue; + /* Verify by reading the device ID from the EEPROM. */ + { + int timer; + outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd); + /* Pause for at least 162 us. for the read to take place. */ + for (timer = 4; timer >= 0; timer--) { + udelay(162); + if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) + == 0) + break; + } + if (inw(ioaddr + Wn0EepromData) != 0x6d50) + continue; + } + printk(KERN_INFO "3c515 Resource configuraiton register %#4.4x, DCR %4.4x.\n", + inl(ioaddr + 0x2002), inw(ioaddr + 0x2000)); + /* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */ + corkscrew_isapnp_phys_addr[pnp_cards] = ioaddr; + corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev + && dev->mem_start ? dev-> + mem_start : options[cards_found]); + dev = 0; + pnp_cards++; + cards_found++; + } + } +no_pnp: +#endif /* not CONFIG_ISAPNP */ /* Check all locations on the ISA bus -- evil! */ - for (; ioaddr < 0x400; ioaddr += 0x20) { + for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) { int irq; +#ifdef CONFIG_ISAPNP + /* Make sure this was not already picked up by isapnp */ + if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue; + if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue; + if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue; +#endif if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE)) continue; /* Check the resource configuration for a matching ioaddr. */ @@ -455,7 +541,6 @@ dev = 0; cards_found++; } - if (corkscrew_debug) printk(KERN_INFO "%d 3c515 cards found.\n", cards_found); return cards_found; diff -u --recursive --new-file v2.3.48/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.3.48/linux/drivers/net/Config.in Sat Feb 26 22:31:46 2000 +++ linux/drivers/net/Config.in Sun Feb 27 18:45:10 2000 @@ -5,6 +5,7 @@ source drivers/net/arcnet/Config.in tristate 'Dummy net driver support' CONFIG_DUMMY +tristate 'Bonding driver support' CONFIG_BONDING tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then if [ "$CONFIG_NETLINK" = "y" ]; then diff -u --recursive --new-file v2.3.48/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.3.48/linux/drivers/net/Makefile Sat Feb 26 22:31:46 2000 +++ linux/drivers/net/Makefile Sun Feb 27 18:45:10 2000 @@ -228,6 +228,7 @@ obj-$(CONFIG_DE650) += de650.o 8390.o obj-$(CONFIG_3C589) += 3c589.o obj-$(CONFIG_DUMMY) += dummy.o +obj-$(CONFIG_BONDING) += bonding.o obj-$(CONFIG_DE600) += de600.o obj-$(CONFIG_DE620) += de620.o obj-$(CONFIG_AT1500) += lance.o diff -u --recursive --new-file v2.3.48/linux/drivers/net/Space.c linux/drivers/net/Space.c --- v2.3.48/linux/drivers/net/Space.c Sat Feb 26 22:31:46 2000 +++ linux/drivers/net/Space.c Sun Feb 27 18:45:10 2000 @@ -685,6 +685,15 @@ -struct net_device *dev_base = NEXT_DEV; +/* + * The loopback device is global so it can be directly referenced + * by the network code. Also, it must be first on device list. + */ + +extern int loopback_init(struct net_device *dev); +struct net_device loopback_dev = + {"lo", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, loopback_init}; + +struct net_device *dev_base = &loopback_dev; rwlock_t dev_base_lock = RW_LOCK_UNLOCKED; diff -u --recursive --new-file v2.3.48/linux/drivers/net/aironet4500.h linux/drivers/net/aironet4500.h --- v2.3.48/linux/drivers/net/aironet4500.h Mon Dec 20 18:48:21 1999 +++ linux/drivers/net/aironet4500.h Mon Feb 28 07:16:54 2000 @@ -19,17 +19,7 @@ /*#include #include */ -#if LINUX_VERSION_CODE < 0x2030E -#define NET_DEVICE device -#error bad kernel version code - -#else -#define NET_DEVICE net_device -#endif -#if LINUX_VERSION_CODE < 0x20300 -#define init_MUTEX(a) *(a) = MUTEX; -#endif /* #include #include @@ -63,11 +53,6 @@ #define my_spin_unlock_irqrestore(a,b) spin_unlock_irqrestore(a,b) -#if LINUX_VERSION_CODE <= 0x20100 -#define in_interrupt() intr_count -#endif - - #define AWC_ERROR -1 #define AWC_SUCCESS 0 @@ -81,6 +66,10 @@ }; +/* timeout for transmit watchdog timer */ +#define TX_TIMEOUT (HZ * 3) + + /*************************** REGISTER OFFSETS *********************/ #define awc_Command_register 0x00 @@ -137,7 +126,7 @@ struct awc_command { volatile int state; volatile int lock_state; - struct NET_DEVICE * dev; + struct net_device * dev; struct awc_private * priv; u16 port; struct awc_bap * bap; @@ -1293,7 +1282,7 @@ /***************************** R I D ***************/ #define AWC_NOF_RIDS 18 -extern int awc_rid_setup(struct NET_DEVICE * dev); +extern int awc_rid_setup(struct net_device * dev); struct aironet4500_rid_selector{ const u16 selector; @@ -1427,7 +1416,7 @@ const struct aironet4500_rid_selector * selector; const int size; const struct aironet4500_RID * rids; - struct NET_DEVICE * dev ; + struct net_device * dev ; void * buff; int bufflen; // just checking }; @@ -1490,8 +1479,6 @@ int large_buff_mem; int small_buff_no; - int tx_timeout; - volatile int mac_enabled; u16 link_status; u8 link_status_changed; @@ -1533,60 +1520,59 @@ int card_type; }; -extern int awc_init(struct NET_DEVICE * dev); -extern void awc_reset(struct NET_DEVICE *dev); -extern int awc_config(struct NET_DEVICE *dev); -extern int awc_open(struct NET_DEVICE *dev); -extern void awc_tx_timeout(struct NET_DEVICE *dev); -extern int awc_tx_done(struct awc_fid * rx_fid); -extern int awc_start_xmit(struct sk_buff *, struct NET_DEVICE *); +extern int awc_init(struct net_device * dev); +extern void awc_reset(struct net_device *dev); +extern int awc_config(struct net_device *dev); +extern int awc_open(struct net_device *dev); +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 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); -extern int awc_close(struct NET_DEVICE *dev); -extern int awc_private_init(struct NET_DEVICE * dev); +extern struct enet_statistics * 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); +extern int awc_close(struct net_device *dev); +extern int awc_private_init(struct net_device * dev); extern int awc_register_proc(int (*awc_proc_set_device) (int),int (*awc_proc_unset_device)(int)); extern int awc_unregister_proc(void); extern int (* awc_proc_set_fun) (int) ; extern int (* awc_proc_unset_fun) (int) ; -extern int awc_interrupt_process(struct NET_DEVICE * dev); -extern int awc_readrid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf ); -extern int awc_writerid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf); -extern int awc_readrid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid ); -extern int awc_writerid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid); -extern int awc_tx_alloc(struct NET_DEVICE * dev) ; -extern int awc_tx_dealloc(struct NET_DEVICE * dev); -extern struct awc_fid *awc_tx_fid_lookup(struct NET_DEVICE * dev, u16 fid); -extern int awc_issue_soft_reset(struct NET_DEVICE * dev); -extern int awc_issue_noop(struct NET_DEVICE * dev); -extern int awc_dump_registers(struct NET_DEVICE * dev); +extern int awc_interrupt_process(struct net_device * dev); +extern int awc_readrid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf ); +extern int awc_writerid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf); +extern int awc_readrid_dir(struct net_device * dev, struct awc_rid_dir * rid ); +extern int awc_writerid_dir(struct net_device * dev, struct awc_rid_dir * rid); +extern int awc_tx_alloc(struct net_device * dev) ; +extern int awc_tx_dealloc(struct net_device * dev); +extern struct awc_fid *awc_tx_fid_lookup(struct net_device * dev, u16 fid); +extern int awc_issue_soft_reset(struct net_device * dev); +extern int awc_issue_noop(struct net_device * dev); +extern int awc_dump_registers(struct net_device * dev); extern unsigned short awc_issue_command_and_block(struct awc_command * cmd); -extern int awc_enable_MAC(struct NET_DEVICE * dev); -extern int awc_disable_MAC(struct NET_DEVICE * dev); -extern int awc_read_all_rids(struct NET_DEVICE * dev); -extern int awc_write_all_rids(struct NET_DEVICE * dev); -extern int awc_receive_packet(struct NET_DEVICE * dev); -extern int awc_transmit_packet(struct NET_DEVICE * dev, struct awc_fid * tx_buff) ; -extern int awc_tx_complete_check(struct NET_DEVICE * dev); -extern int awc_interrupt_process(struct NET_DEVICE * dev); -extern void awc_bh(struct NET_DEVICE *dev); -extern int awc_802_11_find_copy_path(struct NET_DEVICE * dev, struct awc_fid * rx_buff); -extern void awc_802_11_router_rx(struct NET_DEVICE * dev,struct awc_fid * rx_buff); -extern int awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, struct sk_buff * skb); -extern void awc_802_11_after_tx_packet_to_card_write(struct NET_DEVICE * dev, struct awc_fid * tx_buff); -extern void awc_802_11_after_failed_tx_packet_to_card_write(struct NET_DEVICE * dev,struct awc_fid * tx_buff); -extern void awc_802_11_after_tx_complete(struct NET_DEVICE * dev, struct awc_fid * tx_buff); -extern void awc_802_11_failed_rx_copy(struct NET_DEVICE * dev,struct awc_fid * rx_buff); -extern int awc_tx_alloc(struct NET_DEVICE * dev) ; -extern int awc_tx_dealloc_fid(struct NET_DEVICE * dev,struct awc_fid * fid); -extern int awc_tx_dealloc(struct NET_DEVICE * dev); +extern int awc_enable_MAC(struct net_device * dev); +extern int awc_disable_MAC(struct net_device * dev); +extern int awc_read_all_rids(struct net_device * dev); +extern int awc_write_all_rids(struct net_device * dev); +extern int awc_receive_packet(struct net_device * dev); +extern int awc_transmit_packet(struct net_device * dev, struct awc_fid * tx_buff) ; +extern int awc_tx_complete_check(struct net_device * dev); +extern int awc_interrupt_process(struct net_device * dev); +extern void awc_bh(struct net_device *dev); +extern int awc_802_11_find_copy_path(struct net_device * dev, struct awc_fid * rx_buff); +extern void awc_802_11_router_rx(struct net_device * dev,struct awc_fid * rx_buff); +extern int awc_802_11_tx_find_path_and_post(struct net_device * dev, struct sk_buff * skb); +extern void awc_802_11_after_tx_packet_to_card_write(struct net_device * dev, struct awc_fid * tx_buff); +extern void awc_802_11_after_failed_tx_packet_to_card_write(struct net_device * dev,struct awc_fid * tx_buff); +extern void awc_802_11_after_tx_complete(struct net_device * dev, struct awc_fid * tx_buff); +extern void awc_802_11_failed_rx_copy(struct net_device * dev,struct awc_fid * rx_buff); +extern int awc_tx_alloc(struct net_device * dev) ; +extern int awc_tx_dealloc_fid(struct net_device * dev,struct awc_fid * fid); +extern int awc_tx_dealloc(struct net_device * dev); extern struct awc_fid * - awc_tx_fid_lookup_and_remove(struct NET_DEVICE * dev, u16 fid_handle); -extern int awc_queues_init(struct NET_DEVICE * dev); -extern int awc_queues_destroy(struct NET_DEVICE * dev); -extern int awc_rids_setup(struct NET_DEVICE * dev); + awc_tx_fid_lookup_and_remove(struct net_device * dev, u16 fid_handle); +extern int awc_queues_init(struct net_device * dev); +extern int awc_queues_destroy(struct net_device * dev); +extern int awc_rids_setup(struct net_device * dev); @@ -1603,7 +1589,7 @@ extern int awc_full_stats; #define MAX_AWCS 4 -extern struct NET_DEVICE * aironet4500_devices[MAX_AWCS]; +extern struct net_device * aironet4500_devices[MAX_AWCS]; #define AWC_DEBUG 1 @@ -1613,18 +1599,6 @@ #else #define DEBUG(a, args...) #define AWC_ENTRY_EXIT_DEBUG(a) -#endif - -#if LINUX_VERSION_CODE < 0x20100 -#ifndef test_and_set_bit - #define test_and_set_bit(a,b) set_bit(a,b) -#endif -#endif - -#if LINUX_VERSION_CODE < 0x20100 - #define FREE_SKB(a) dev_kfree_skb(a, FREE_WRITE) -#else - #define FREE_SKB(a) dev_kfree_skb(a) #endif #endif /* AIRONET4500_H */ diff -u --recursive --new-file v2.3.48/linux/drivers/net/aironet4500_card.c linux/drivers/net/aironet4500_card.c --- v2.3.48/linux/drivers/net/aironet4500_card.c Mon Dec 20 18:48:21 1999 +++ linux/drivers/net/aironet4500_card.c Mon Feb 28 07:16:54 2000 @@ -7,11 +7,13 @@ * * Revision 0.1 ,started 30.12.1998 * + * Revision 0.2, Feb 27, 2000 + * Jeff Garzik - softnet, cleanups * */ #ifdef MODULE static const char *awc_version = -"aironet4500_cards.c v0.1 28/03/99 Elmer Joandi, elmer@ylenurme.ee.\n"; +"aironet4500_cards.c v0.2 Feb 27, 2000 Elmer Joandi, elmer@ylenurme.ee.\n"; #endif #include @@ -36,9 +38,6 @@ #include #include #include -#if LINUX_VERSION_CODE < 0x20100 -#include -#endif #include "aironet4500.h" @@ -64,11 +63,11 @@ static int reverse_probe =0 ; -static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr, +static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, int ioaddr, int cis_addr, int mem_addr,u8 pci_irq_line) ; -int awc4500_pci_probe(struct NET_DEVICE *dev) +int awc4500_pci_probe(struct net_device *dev) { int cards_found = 0; static int pci_index = 0; /* Static, for multiple probe calls. */ @@ -77,7 +76,7 @@ unsigned char awc_pci_dev, awc_pci_bus; - if (!pcibios_present()) + if (!pci_present()) return -1; for (;pci_index < 0xff; pci_index++) { @@ -85,10 +84,8 @@ u32 pci_memaddr; u32 pci_ioaddr; u32 pci_cisaddr; -#if LINUX_VERSION_CODE < 0x20100 - u16 pci_caps =0; - u8 pci_caps_ptr =0; -#endif + struct pci_dev *pdev; + if (pcibios_find_class (PCI_CLASS_NETWORK_OTHER << 8, reverse_probe ? 0xfe - pci_index : pci_index, &awc_pci_bus, &awc_pci_dev) != PCIBIOS_SUCCESSFUL){ @@ -98,31 +95,16 @@ break; } } - pcibios_read_config_word(awc_pci_bus, awc_pci_dev, - PCI_VENDOR_ID, &vendor); - pcibios_read_config_word(awc_pci_bus, awc_pci_dev, - PCI_DEVICE_ID, &device); -#if LINUX_VERSION_CODE >= 0x20300 - pci_irq_line = pci_find_slot(awc_pci_bus, awc_pci_dev)->irq; - pci_memaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[0].start; - pci_cisaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[1].start; - pci_ioaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->resource[2].start; -#else -#if LINUX_VERSION_CODE >= 0x20155 - pci_irq_line = pci_find_slot(awc_pci_bus, awc_pci_dev)->irq; - pci_memaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[0]; - pci_cisaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[1]; - pci_ioaddr = pci_find_slot(awc_pci_bus, awc_pci_dev)->base_address[2]; -#else - pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_0, &pci_memaddr); - pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_1, &pci_cisaddr); - pcibios_read_config_dword(awc_pci_bus, awc_pci_dev,PCI_BASE_ADDRESS_2, &pci_ioaddr); - pcibios_read_config_byte(awc_pci_bus, awc_pci_dev, PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_word(awc_pci_bus, awc_pci_dev,PCI_STATUS, &pci_caps); - pcibios_read_config_byte(awc_pci_bus, awc_pci_dev, 0x34, &pci_caps_ptr); + pdev = pci_find_slot(awc_pci_bus, awc_pci_dev); + if (!pdev) + continue; + vendor = pdev->vendor; + device = pdev->device; + pci_irq_line = pdev->irq; + pci_memaddr = pci_resource_start (pdev, 0); + pci_cisaddr = pci_resource_start (pdev, 1); + pci_ioaddr = pci_resource_start (pdev, 2); -#endif // 2.2 -#endif // 2.3 // printk("\n pci capabilities %x and ptr %x \n",pci_caps,pci_caps_ptr); /* Remove I/O space marker in bit 0. */ @@ -132,17 +114,7 @@ device != PCI_DEVICE_AIRONET_4800 && device != PCI_DEVICE_AIRONET_4500 ) continue; -#if LINUX_VERSION_CODE < 0x20300 - if (!(pci_ioaddr & 1)){ - printk("awc4X00 ioaddr location mismatch \n"); - return -1; - }; - - pci_ioaddr &= ~3; - pci_cisaddr &= ~0xf; - pci_memaddr &= ~0xf; -#endif // if (check_region(pci_ioaddr, AIRONET4X00_IO_SIZE) || // check_region(pci_cisaddr, AIRONET4X00_CIS_SIZE) || // check_region(pci_memaddr, AIRONET4X00_MEM_SIZE)) { @@ -153,33 +125,28 @@ // request_region(pci_cisaddr, AIRONET4X00_CIS_SIZE, "aironet4x00 cis"); // request_region(pci_memaddr, AIRONET4X00_MEM_SIZE, "aironet4x00 mem"); -// pcibios_write_config_word(awc_pci_bus, awc_pci_dev, -// PCI_COMMAND, 0); +// pci_write_config_word(pdev, PCI_COMMAND, 0); udelay(10000); - pcibios_read_config_word(awc_pci_bus, awc_pci_dev, - PCI_COMMAND, &pci_command); + pci_read_config_word(pdev, PCI_COMMAND, &pci_command); new_command = pci_command |0x100 | PCI_COMMAND_MEMORY|PCI_COMMAND_IO; if (pci_command != new_command) { printk(KERN_INFO " The PCI BIOS has not enabled this" " device! Updating PCI command %4.4x->%4.4x.\n", pci_command, new_command); - pcibios_write_config_word(awc_pci_bus, awc_pci_dev, - PCI_COMMAND, new_command); + pci_write_config_word(pdev, PCI_COMMAND, new_command); } /* if (device == PCI_DEVICE_AIRONET_4800) - pcibios_write_config_dword(awc_pci_bus, awc_pci_dev, - 0x40, 0x00000000); + pci_write_config_dword(pdev, 0x40, 0x00000000); udelay(1000); */ if (device == PCI_DEVICE_AIRONET_4800) - pcibios_write_config_dword(awc_pci_bus, awc_pci_dev, - 0x40, 0x40000000); + pci_write_config_dword(pdev, 0x40, 0x40000000); - if (awc_pci_init(dev, awc_pci_bus, awc_pci_dev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){ + if (awc_pci_init(dev, pdev, pci_ioaddr,pci_cisaddr,pci_memaddr,pci_irq_line)){ printk(KERN_ERR "awc4800 pci init failed \n"); break; } @@ -191,7 +158,7 @@ } -static int awc_pci_init(struct NET_DEVICE * dev, int pci_bus, int device_nr, +static int awc_pci_init(struct net_device * dev, struct pci_dev *pdev, int ioaddr, int cis_addr, int mem_addr, u8 pci_irq_line) { int i; @@ -218,18 +185,15 @@ dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; - dev->base_addr = ioaddr; - - dev->irq = pci_irq_line; -#if LINUX_VERSION_CODE > 0x20100 - request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev); -#else + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + netif_start_queue (dev); + request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev); -#endif + awc_private_init( dev); awc_init(dev); @@ -244,17 +208,11 @@ awc_proc_set_fun(i); } - dev->tbusy = 1; - dev->start = 0; - - // if (register_netdev(dev) != 0) { // printk(KERN_NOTICE "awc_cs: register_netdev() failed\n"); // goto failed; // } - - return 0; // failed: // return -1; @@ -285,7 +243,7 @@ unregister_netdev(aironet4500_devices[i]); free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]); kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; @@ -304,14 +262,9 @@ #ifdef CONFIG_AIRONET4500_PNP -#if LINUX_VERSION_CODE > 0x20300 #include -#else -#include "isapnp.h" -#endif #define AIRONET4X00_IO_SIZE 0x40 -#if LINUX_VERSION_CODE > 0x20300 #define isapnp_logdev pci_dev #define isapnp_dev pci_bus #define isapnp_find_device isapnp_find_card @@ -319,17 +272,11 @@ #define PNP_BUS bus #define PNP_BUS_NUMBER number #define PNP_DEV_NUMBER devfn -#else -#define PNP_BUS dev -#define PNP_BUS_NUMBER csn -#define PNP_DEV_NUMBER number -#endif -int awc4500_pnp_hw_reset(struct NET_DEVICE *dev){ + +int awc4500_pnp_hw_reset(struct net_device *dev){ struct isapnp_logdev *logdev; -#if LINUX_VERSION_CODE < 0x20300 - struct isapnp_config cfg; -#endif + DEBUG(0, "awc_pnp_reset \n"); if (!dev->priv ) { @@ -357,30 +304,14 @@ dev->name, logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER); return -EAGAIN; } -#if LINUX_VERSION_CODE < 0x20300 - if (isapnp_config_init(&cfg, logdev)<0) { - printk("cfg init failed \n"); - isapnp_cfg_end(); - return -EAGAIN; - } - cfg.port[0] = dev->base_addr; - cfg.irq[0] = dev->irq; - if (isapnp_configure(&cfg)<0) { - printk("%s hw_reset, isapnp configure failed (out of resources?)\n",dev->name); - isapnp_cfg_end(); - return -ENOMEM; - } -#else - -#endif isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */ isapnp_cfg_end(); return 0; } -int awc4500_pnp_probe(struct NET_DEVICE *dev) +int awc4500_pnp_probe(struct net_device *dev) { int isa_index = 0; int isa_irq_line = 0; @@ -389,21 +320,13 @@ int i=0; struct isapnp_dev * pnp_dev ; struct isapnp_logdev *logdev; -#if LINUX_VERSION_CODE < 0x20300 - struct isapnp_config cfg; -#endif while (1) { pnp_dev = isapnp_find_device( ISAPNP_VENDOR('A','W','L'), ISAPNP_DEVICE(1), -#if LINUX_VERSION_CODE < 0x20300 - isa_index -#else - 0 -#endif - ); + 0); if (!pnp_dev) break; @@ -421,28 +344,11 @@ logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER); return -EAGAIN; } -#if LINUX_VERSION_CODE < 0x20300 - if (isapnp_config_init(&cfg, logdev)<0) { - printk("cfg init failed \n"); - isapnp_cfg_end(); - return -EAGAIN; - } - if (isapnp_configure(&cfg)<0) { - printk("isapnp configure failed (out of resources?)\n"); - isapnp_cfg_end(); - return -ENOMEM; - } -#endif isapnp_activate(logdev->PNP_DEV_NUMBER); /* activate device */ isapnp_cfg_end(); -#if LINUX_VERSION_CODE < 0x20300 - isa_ioaddr = cfg.port[0]; - isa_irq_line = cfg.irq[0]; -#else isa_irq_line = logdev->irq; isa_ioaddr = logdev->resource[0].start; -#endif request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"); if (!dev) { @@ -468,18 +374,14 @@ dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; - dev->base_addr = isa_ioaddr; - - dev->irq = isa_irq_line; -#if LINUX_VERSION_CODE > 0x20100 + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + netif_start_queue (dev); + request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev); -#else - request_irq(dev->irq,awc_interrupt, SA_SHIRQ ,"Aironet 4X00",dev); -#endif awc_private_init( dev); @@ -512,9 +414,6 @@ return -1; } - dev->tbusy = 1; - dev->start = 0; - card++; } @@ -557,7 +456,7 @@ unregister_netdev(aironet4500_devices[i]); free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]); kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; @@ -580,16 +479,14 @@ EXPORT_SYMBOL(irq); EXPORT_SYMBOL(io); */ -#if LINUX_VERSION_CODE >= 0x20100 MODULE_PARM(irq,"i"); MODULE_PARM_DESC(irq,"Aironet 4x00 ISA non-PNP irqs,required"); MODULE_PARM(io,"i"); MODULE_PARM_DESC(io,"Aironet 4x00 ISA non-PNP ioports,required"); -#endif -int awc4500_isa_probe(struct NET_DEVICE *dev) +int awc4500_isa_probe(struct net_device *dev) { // int cards_found = 0; // static int isa_index = 0; /* Static, for multiple probe calls. */ @@ -638,19 +535,14 @@ dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; - dev->base_addr = isa_ioaddr; - - dev->irq = isa_irq_line; + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + + netif_start_queue (dev); -#if LINUX_VERSION_CODE > 0x20100 request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev); -#else - request_irq(dev->irq,awc_interrupt ,0 ,"Aironet 4X00",dev); -#endif awc_private_init( dev); if ( awc_init(dev) ){ @@ -671,9 +563,6 @@ awc_proc_set_fun(i); } - dev->tbusy = 1; - dev->start = 0; - card++; } if (card == 0 ) { @@ -707,7 +596,7 @@ unregister_netdev(aironet4500_devices[i]); free_irq(aironet4500_devices[i]->irq,aironet4500_devices[i]); kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; @@ -906,7 +795,7 @@ static int awc_i365_init(struct i365_socket * s) { - struct NET_DEVICE * dev; + struct net_device * dev; int i; @@ -923,11 +812,12 @@ dev->init = &awc_init; dev->open = &awc_open; dev->stop = &awc_close; - dev->tbusy = 1; - dev->start = 0; dev->irq = s->irq; dev->base_addr = s->io; + dev->tx_timeout = &awc_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; + netif_start_queue (dev); awc_private_init( dev); @@ -943,24 +833,18 @@ awc_proc_set_fun(i); } - dev->tbusy = 1; - dev->start = 0; - - if (register_netdev(dev) != 0) { printk(KERN_NOTICE "awc_cs: register_netdev() failed\n"); goto failed; } - - return 0; failed: return -1; - } + static void awc_i365_release(void) { // long flags; @@ -983,7 +867,7 @@ unregister_netdev(aironet4500_devices[i]); //kfree_s(aironet4500_devices[i]->priv, sizeof(struct awc_private)); - kfree_s(aironet4500_devices[i], sizeof(struct NET_DEVICE)); + kfree_s(aironet4500_devices[i], sizeof(struct net_device)); aironet4500_devices[i]=0; diff -u --recursive --new-file v2.3.48/linux/drivers/net/aironet4500_core.c linux/drivers/net/aironet4500_core.c --- v2.3.48/linux/drivers/net/aironet4500_core.c Tue Jan 4 13:57:17 2000 +++ linux/drivers/net/aironet4500_core.c Mon Feb 28 07:16:54 2000 @@ -72,7 +72,7 @@ return "UNKNOWN"; }; -int awc_dump_registers(struct NET_DEVICE * dev){ +int awc_dump_registers(struct net_device * dev){ #ifdef AWC_DEBUG int i; @@ -108,7 +108,7 @@ inline -int awc_command_busy_clear_wait(struct NET_DEVICE * dev){ +int awc_command_busy_clear_wait(struct net_device * dev){ // long long jiff = jiffies; u16 active_interrupts; int cnt= 0; @@ -319,7 +319,7 @@ inline unsigned short -awc_issue_command_no_ack(struct NET_DEVICE * dev, +awc_issue_command_no_ack(struct net_device * dev, u16 com, u16 par1, u16 par2, u16 par3){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -695,7 +695,7 @@ int -awc_readrid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf ){ +awc_readrid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf ){ struct awc_command cmd; int sleep_state ; @@ -728,7 +728,7 @@ } int -awc_writerid(struct NET_DEVICE * dev, struct aironet4500_RID * rid, void *pBuf){ +awc_writerid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf){ struct awc_command cmd; int sleep_state ; @@ -765,7 +765,7 @@ } int -awc_readrid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid ){ +awc_readrid_dir(struct net_device * dev, struct awc_rid_dir * rid ){ struct awc_command cmd; int sleep_state; @@ -798,7 +798,7 @@ } int -awc_writerid_dir(struct NET_DEVICE * dev, struct awc_rid_dir * rid){ +awc_writerid_dir(struct net_device * dev, struct awc_rid_dir * rid){ struct awc_command cmd; int sleep_state ; @@ -847,7 +847,7 @@ inline int -awc_issue_blocking_command(struct NET_DEVICE * dev,u16 comm){ +awc_issue_blocking_command(struct net_device * dev,u16 comm){ struct awc_command cmd; // struct awc_private * priv = (struct awc_private *)dev->priv; @@ -872,7 +872,7 @@ }; int -awc_issue_soft_reset(struct NET_DEVICE * dev){ +awc_issue_soft_reset(struct net_device * dev){ u16 status ; // int i= 0; @@ -912,7 +912,7 @@ }; int -awc_issue_noop(struct NET_DEVICE * dev){ +awc_issue_noop(struct net_device * dev){ int retval; AWC_OUT(dev->base_addr + 0x28, 0); AWC_OUT(dev->base_addr + 0x2A, 0); @@ -925,7 +925,7 @@ EXPORT_SYMBOL(awc_enable_MAC); int -awc_enable_MAC(struct NET_DEVICE * dev){ +awc_enable_MAC(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; AWC_ENTRY_EXIT_DEBUG(" entry awc_enable_MAC "); @@ -950,7 +950,7 @@ EXPORT_SYMBOL(awc_disable_MAC); int -awc_disable_MAC(struct NET_DEVICE * dev){ +awc_disable_MAC(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; AWC_ENTRY_EXIT_DEBUG(" entry awc_disable_MAC "); @@ -973,7 +973,7 @@ int -awc_read_all_rids(struct NET_DEVICE * dev){ +awc_read_all_rids(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int status,i; @@ -992,7 +992,7 @@ } int -awc_write_all_rids(struct NET_DEVICE * dev){ +awc_write_all_rids(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int i,status ; @@ -1012,7 +1012,7 @@ -int awc_tx_alloc(struct NET_DEVICE * dev) { +int awc_tx_alloc(struct net_device * dev) { struct awc_command cmd; int k=0; @@ -1116,7 +1116,7 @@ }; int -awc_tx_dealloc_fid(struct NET_DEVICE * dev,struct awc_fid * fid){ +awc_tx_dealloc_fid(struct net_device * dev,struct awc_fid * fid){ struct awc_command cmd; int fid_handle = 0; @@ -1150,7 +1150,7 @@ }; int -awc_tx_dealloc(struct NET_DEVICE * dev){ +awc_tx_dealloc(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -1177,7 +1177,7 @@ inline struct awc_fid * -awc_tx_fid_lookup_and_remove(struct NET_DEVICE * dev, u16 fid_handle){ +awc_tx_fid_lookup_and_remove(struct net_device * dev, u16 fid_handle){ struct awc_private * priv = (struct awc_private *)dev->priv; // int k = 0; @@ -1272,7 +1272,7 @@ int -awc_queues_init(struct NET_DEVICE * dev){ +awc_queues_init(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; struct awc_fid * fid = NULL; int retv =0; @@ -1302,7 +1302,7 @@ int -awc_queues_destroy(struct NET_DEVICE * dev){ +awc_queues_destroy(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; struct awc_fid * fid = NULL; int retv =0; @@ -1325,7 +1325,7 @@ /****************************** 802.11router ******************/ inline int -awc_802_11_copy_path_skb(struct NET_DEVICE * dev, struct awc_fid * rx_buff){ +awc_802_11_copy_path_skb(struct net_device * dev, struct awc_fid * rx_buff){ struct awc_private * priv = (struct awc_private * )dev->priv; @@ -1360,7 +1360,7 @@ int -awc_802_11_find_copy_path(struct NET_DEVICE * dev, struct awc_fid * rx_buff){ +awc_802_11_find_copy_path(struct net_device * dev, struct awc_fid * rx_buff){ // struct awc_private * priv = (struct awc_private * )dev->priv; // u8 is_802_3 = 0; @@ -1386,7 +1386,7 @@ int parse_not_8023= 0; void -awc_802_11_router_rx(struct NET_DEVICE * dev,struct awc_fid * rx_buff){ +awc_802_11_router_rx(struct net_device * dev,struct awc_fid * rx_buff){ struct awc_private * priv = (struct awc_private * )dev->priv; struct sk_buff * skb = rx_buff->skb; @@ -1531,7 +1531,7 @@ DEBUG(0x200,"%s packet dropped in packet hdr parse \n ",dev->name); if (rx_buff->skb && (rx_buff->type & p80211copy_path_skb)){ - FREE_SKB(rx_buff->skb); + dev_kfree_skb_irq(rx_buff->skb); rx_buff->skb = NULL; rx_buff->u.rx.payload = NULL; }; @@ -1541,13 +1541,13 @@ }; void -awc_802_11_failed_rx_copy(struct NET_DEVICE * dev,struct awc_fid * rx_buff){ +awc_802_11_failed_rx_copy(struct net_device * dev,struct awc_fid * rx_buff){ struct awc_private * priv = (struct awc_private * )dev->priv; AWC_ENTRY_EXIT_DEBUG("awc_802_11_failed_rx_copy"); if (rx_buff->skb) - FREE_SKB(rx_buff->skb); + dev_kfree_skb_irq(rx_buff->skb); rx_buff->skb = NULL; rx_buff->u.rx.payload = NULL; priv->stats.rx_errors++; @@ -1566,7 +1566,7 @@ int -awc_802_11_tx_find_path_and_post(struct NET_DEVICE * dev, +awc_802_11_tx_find_path_and_post(struct net_device * dev, struct sk_buff * skb){ @@ -1750,10 +1750,6 @@ udelay(1); awc_transmit_packet(dev,fid); UP(&priv->tx_buff_semaphore); - if (priv->tx_large_ready.size > 0 ){ - dev->tbusy = 0; - mark_bh(NET_BH); - } AWC_ENTRY_EXIT_DEBUG("exit\n"); return 0; @@ -1763,7 +1759,7 @@ #ifdef AWC_DEBUG // printk("s"); #endif - dev->tbusy = 1; //weell, here it must be set anyway and before + netif_stop_queue (dev); //weell, here it must be set anyway and before //priv->stats.tx_fifo_errors++; UP(&priv->tx_buff_semaphore); AWC_ENTRY_EXIT_DEBUG("NoSpaceExit\n"); @@ -1771,9 +1767,7 @@ final: priv->stats.tx_errors++; UP(&priv->tx_buff_semaphore); - dev->tbusy = 0; - FREE_SKB(skb); - mark_bh(NET_BH); + dev_kfree_skb(skb); AWC_ENTRY_EXIT_DEBUG("BADExit\n"); return -1; @@ -1788,7 +1782,7 @@ void -awc_802_11_after_tx_packet_to_card_write(struct NET_DEVICE * dev, +awc_802_11_after_tx_packet_to_card_write(struct net_device * dev, struct awc_fid * tx_buff){ @@ -1799,10 +1793,10 @@ }; if(tx_buff->skb){ - FREE_SKB(tx_buff->skb); + dev_kfree_skb(tx_buff->skb); tx_buff->skb = NULL; } - mark_bh(NET_BH); + netif_wake_queue (dev); AWC_ENTRY_EXIT_DEBUG("exit\n"); }; @@ -1815,7 +1809,7 @@ */ void -awc_802_11_after_failed_tx_packet_to_card_write(struct NET_DEVICE * dev, +awc_802_11_after_failed_tx_packet_to_card_write(struct net_device * dev, struct awc_fid * tx_buff){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -1827,7 +1821,7 @@ }; if(tx_buff->skb){ - FREE_SKB(tx_buff->skb); + dev_kfree_skb(tx_buff->skb); tx_buff->skb = NULL; tx_buff->busy =0; printk(KERN_ERR "%s packet to card write failed \n",dev->name); @@ -1845,7 +1839,7 @@ }; void -awc_802_11_after_tx_complete(struct NET_DEVICE * dev, struct awc_fid * tx_buff){ +awc_802_11_after_tx_complete(struct net_device * dev, struct awc_fid * tx_buff){ struct awc_private * priv = (struct awc_private *)dev->priv; @@ -1866,8 +1860,7 @@ } tx_buff->busy = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); AWC_ENTRY_EXIT_DEBUG("exit\n"); }; @@ -1880,7 +1873,7 @@ inline int -awc_receive_packet(struct NET_DEVICE * dev){ +awc_receive_packet(struct net_device * dev){ struct awc_command cmd; u16 Fid; @@ -2010,7 +2003,7 @@ int -awc_transmit_packet(struct NET_DEVICE * dev, struct awc_fid * tx_buff) { +awc_transmit_packet(struct net_device * dev, struct awc_fid * tx_buff) { struct awc_command cmd; u16 size ; @@ -2143,7 +2136,7 @@ inline int -awc_tx_complete_check(struct NET_DEVICE * dev){ +awc_tx_complete_check(struct net_device * dev){ struct awc_fid * fid; struct awc_command cmd; @@ -2197,7 +2190,7 @@ void -awc_bh(struct NET_DEVICE *dev){ +awc_bh(struct net_device *dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int active_interrupts; @@ -2226,8 +2219,7 @@ if (active_interrupts == 0xffff){ printk(KERN_CRIT "%s device ejected in interrupt, disabling\n",dev->name); - dev->tbusy = 1; - dev->start = 0; + netif_device_detach (dev); if (priv->command_semaphore_on){ priv->command_semaphore_on--; AWC_UNLOCK_COMMAND_ISSUING(priv); @@ -2286,7 +2278,7 @@ inline int -awc_interrupt_process(struct NET_DEVICE * dev){ +awc_interrupt_process(struct net_device * dev){ struct awc_private * priv ; int active_interrupts; @@ -2327,10 +2319,6 @@ // printk("ikka interruptis\n"); - if (test_and_set_bit( 0, (void *) &dev->interrupt) ) { - printk("RI\n"); - goto reenter_end_here; - } priv->interrupt_count++; if (priv->interrupt_count > 1 ) printk(" interrupt count on\n "); @@ -2354,12 +2342,10 @@ printk(KERN_CRIT "%s device ejected, got interrupt, disabling\n",dev->name); //priv-> - dev->tbusy = 1; - dev->start = 0; + netif_device_detach (dev); priv->ejected = 1; if (priv->bh_active || priv->bh_running){ priv->interrupt_count--; - dev->interrupt = 0; goto bad_end; } else if (priv->command_semaphore_on){ @@ -2368,7 +2354,6 @@ AWC_QUEUE_BH; } priv->interrupt_count--; - dev->interrupt = 0; goto bad_end; } @@ -2458,8 +2443,7 @@ awc_fid_queue_push_tail(&priv->tx_small_ready,fid); else awc_fid_queue_push_tail(&priv->tx_large_ready,fid); - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } } else printk(KERN_ERR "awc fid %x not found\n",tx_fid); @@ -2502,7 +2486,6 @@ priv->interrupt_count--; - dev->interrupt = 0; awc_ints_enable(dev->base_addr, 0x0000); @@ -2523,15 +2506,8 @@ // restore_flags(flags); return 0; -reenter_end_here: - - AWC_ENTRY_EXIT_DEBUG(" reenter-bad end exit \n"); -// enable_irq(dev->irq); -// restore_flags(flags); - return 0; bad_end: - dev->interrupt = 0; AWC_ENTRY_EXIT_DEBUG(" bad_end exit \n"); // enable_irq(dev->irq); // restore_flags(flags); @@ -2543,7 +2519,7 @@ static const char *aironet4500_core_version = "aironet4500.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n"; -struct NET_DEVICE * aironet4500_devices[MAX_AWCS] = {NULL,NULL,NULL,NULL}; +struct net_device * aironet4500_devices[MAX_AWCS] = {NULL,NULL,NULL,NULL}; static int awc_debug = 0; // 0xffffff; static int p802_11_send = 0; // 1 @@ -2595,7 +2571,6 @@ EXPORT_SYMBOL(awc_private_init); EXPORT_SYMBOL(awc_tx_timeout); EXPORT_SYMBOL(awc_start_xmit); -EXPORT_SYMBOL(awc_tx_done); EXPORT_SYMBOL(awc_rx); EXPORT_SYMBOL(awc_interrupt); EXPORT_SYMBOL(awc_get_stats); @@ -2611,7 +2586,7 @@ /*************************** RESET INIT CONFIG ***********************/ - void awc_reset(struct NET_DEVICE *dev) + void awc_reset(struct net_device *dev) { long long jiff; @@ -2633,7 +2608,7 @@ } - int awc_config(struct NET_DEVICE *dev) + int awc_config(struct net_device *dev) { // struct awc_private *priv = (struct awc_private *)dev->priv; @@ -2654,7 +2629,7 @@ char name[] = "ElmerLinux"; - int awc_init(struct NET_DEVICE *dev){ + int awc_init(struct net_device *dev){ struct awc_private *priv = (struct awc_private *)dev->priv; int i; const char * radioType; @@ -2785,8 +2760,6 @@ // here we go, bad aironet memset(&priv->SSIDs,0,sizeof(priv->SSIDs)); - my_spin_lock_init(&priv->queues_lock); - priv->SSIDs.ridLen =0; if (!SSID) { priv->SSIDs.SSID[0].SSID[0] ='a'; @@ -2834,7 +2807,7 @@ }; -int awc_private_init(struct NET_DEVICE * dev){ +int awc_private_init(struct net_device * dev){ struct awc_private * priv = (struct awc_private *) dev->priv; int i = 0; @@ -2906,7 +2879,6 @@ priv->ejected =0; - dev->interrupt =0; priv->interrupt_count =0; return 0; @@ -2916,7 +2888,7 @@ /**************************** OPEN CLOSE **********************/ - int awc_open(struct NET_DEVICE *dev) + int awc_open(struct net_device *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; @@ -2924,9 +2896,6 @@ DEBUG(2, "%s: awc_open \n", dev->name); - dev->interrupt = 0; dev->tbusy = 1; dev->start = 0; - - if( awc_queues_init(dev) ) goto final; if( awc_config(dev) ) goto final; @@ -2945,24 +2914,23 @@ MOD_INC_USE_COUNT; // kernel_thread(awc_thread,dev,0); - dev->tbusy = 0; dev->start = 1; + netif_start_queue (dev); return 0; /* Always succeed */ final: - dev->tbusy = 0; dev->start = 0; + netif_device_detach (dev); printk(KERN_ERR "aironet open failed \n"); return -1; } - int awc_close(struct NET_DEVICE *dev) + int awc_close(struct net_device *dev) { struct awc_private * priv = (struct awc_private *) dev->priv; DEBUG(2, "%s: closing device.\n", dev->name); - dev->start = 0; - dev->tbusy=1; + netif_stop_queue (dev); awc_disable_MAC(dev); awc_queues_destroy(dev); @@ -2986,32 +2954,58 @@ - void awc_tx_timeout(struct NET_DEVICE *dev) +void awc_tx_timeout (struct net_device *dev) { - struct awc_private *priv = (struct awc_private *)dev->priv; + struct awc_private *priv = (struct awc_private *) dev->priv; + struct awc_fid * fid; + int cnt; + + DEBUG (2, "%s: awc_tx_timeout \n", dev->name); + + printk (KERN_NOTICE "%s: Transmit timed out , buffs %d %d, queues tx %d pp %d lrg %d sm %d \n ", + dev->name, priv->tx_small_buffs_total, priv->tx_buffs_total, + priv->tx_in_transmit.size, priv->tx_post_process.size, + priv->tx_large_ready.size, priv->tx_small_ready.size); + priv->stats.tx_errors++; - DEBUG(2, "%s: awc_tx_timeout \n", dev->name); + // save_flags(flags); + // cli(); + fid = priv->tx_in_transmit.head; + cnt = 0; + while (fid) { + if (jiffies - fid->transmit_start_time > (HZ)) { + // printk(KERN_ERR "%s staled tx_buff found, age %uld jiffies\n",dev->name, + // jiffies - fid->transmit_start_time ); + awc_fid_queue_remove (&priv->tx_in_transmit, fid); + if (fid->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE) + awc_fid_queue_push_tail (&priv->tx_small_ready, fid); + else + awc_fid_queue_push_tail (&priv->tx_large_ready, fid); + } + fid = fid->next; + if (cnt++ > 200) { + printk ("bbb in awc_fid_queue\n"); + // restore_flags(flags); + return; + }; - printk(KERN_NOTICE "%s: Transmit timed out , buffs %d %d, queues tx %d pp %d lrg %d sm %d \n ", - dev->name,priv->tx_small_buffs_total ,priv->tx_buffs_total, - priv->tx_in_transmit.size,priv->tx_post_process.size, - priv->tx_large_ready.size,priv->tx_small_ready.size); - priv->stats.tx_errors++; + } + //restore_flags(flags); + //debug =0x8; dev->trans_start = jiffies; - dev->tbusy = 0; + netif_start_queue (dev); } + long long last_tx_q_hack = 0; int direction = 1; - int awc_start_xmit(struct sk_buff *skb, struct NET_DEVICE *dev) { + int awc_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; int retval = 0; // unsigned long flags; - struct awc_fid * fid = NULL; - int cnt=0; DEBUG(2, "%s: awc_start_xmit \n", dev->name); @@ -3021,48 +3015,13 @@ return -1; }; - /* Transmitter timeout, serious problems. */ - if (test_and_set_bit( 0, (void *) &dev->tbusy) ) { - if (jiffies - dev->trans_start > 3* HZ ){ - // save_flags(flags); - // cli(); - fid = priv->tx_in_transmit.head; - cnt = 0; - while (fid){ - if (jiffies - fid->transmit_start_time > (HZ)){ - // printk(KERN_ERR "%s staled tx_buff found, age %uld jiffies\n",dev->name, - // jiffies - fid->transmit_start_time ); - awc_fid_queue_remove(&priv->tx_in_transmit, fid); - if (fid->u.tx.fid_size <= AWC_TX_ALLOC_SMALL_SIZE) - awc_fid_queue_push_tail(&priv->tx_small_ready,fid); - else - awc_fid_queue_push_tail(&priv->tx_large_ready,fid); - dev->tbusy = 0; - } - fid = fid->next; - if (cnt++ > 200) { - printk("bbb in awc_fid_queue\n"); - // restore_flags(flags); - return -1; - }; - - } - //restore_flags(flags); - //debug =0x8; - }; - if (jiffies - dev->trans_start >= (5* HZ) ) { - awc_tx_timeout(dev); - } - return 1; - } - if (!skb) { DEBUG(1, " xmit skb=NULL, jiffie %ld \n",jiffies); return -1; }; if (test_and_set_bit( 0, (void *) &priv->tx_chain_active) ) { - dev->tbusy=0; + netif_start_queue (dev); return 1; } @@ -3075,15 +3034,7 @@ return retval; } -int awc_tx_done(struct awc_fid * rx_fid){ - -// dev->tbusy = 0; - mark_bh(NET_BH); - - return 0; -}; - -int awc_rx(struct NET_DEVICE *dev, struct awc_fid * rx_fid) { +int awc_rx(struct net_device *dev, struct awc_fid * rx_fid) { // struct awc_private *lp = (struct awc_private *)dev->priv; @@ -3109,7 +3060,7 @@ void awc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct NET_DEVICE *dev = (struct NET_DEVICE *)dev_id; + struct net_device *dev = (struct net_device *)dev_id; // struct awc_private *lp; // unsigned long flags; @@ -3133,7 +3084,7 @@ - struct enet_statistics *awc_get_stats(struct NET_DEVICE *dev) + struct enet_statistics *awc_get_stats(struct net_device *dev) { struct awc_private *priv = (struct awc_private *)dev->priv; // unsigned long flags; @@ -3142,7 +3093,7 @@ DEBUG(2, "%s: awc_get_stats \n", dev->name); - if (!dev->start) { + if (!netif_running(dev)) { return 0; } // save_flags(flags); @@ -3175,7 +3126,7 @@ } -int awc_change_mtu(struct NET_DEVICE *dev, int new_mtu){ +int awc_change_mtu(struct net_device *dev, int new_mtu){ // struct awc_private *priv = (struct awc_private *)dev->priv; // unsigned long flags; @@ -3183,7 +3134,7 @@ if ((new_mtu < 256 ) || (new_mtu > 2312) || (max_mtu && new_mtu > max_mtu) ) return -EINVAL; - if (dev->start) { + if (netif_running(dev)) { printk("PLEASE, ifconfig %s down for mtu change\n",dev->name); }; @@ -3207,7 +3158,7 @@ void -awc_set_multicast_list(struct NET_DEVICE *dev) { +awc_set_multicast_list(struct net_device *dev) { // int ioaddr = dev->base_addr; /* if (dev->flags & IFF_PROMISC) diff -u --recursive --new-file v2.3.48/linux/drivers/net/aironet4500_proc.c linux/drivers/net/aironet4500_proc.c --- v2.3.48/linux/drivers/net/aironet4500_proc.c Mon Dec 20 18:48:21 1999 +++ linux/drivers/net/aironet4500_proc.c Mon Feb 28 07:16:54 2000 @@ -264,7 +264,7 @@ struct awc_rid_dir * rid_dir; - struct NET_DEVICE * dev= NULL; + struct net_device * dev= NULL; struct aironet4500_RID * rid = (struct aironet4500_RID * ) ctl->extra2; diff -u --recursive --new-file v2.3.48/linux/drivers/net/aironet4500_rid.c linux/drivers/net/aironet4500_rid.c --- v2.3.48/linux/drivers/net/aironet4500_rid.c Wed Dec 8 14:11:26 1999 +++ linux/drivers/net/aironet4500_rid.c Mon Feb 28 07:16:54 2000 @@ -2134,7 +2134,7 @@ int awc_nof_rids = (sizeof(awc_rids) / sizeof(struct awc_rid_dir)) -1; -int awc_rids_setup(struct NET_DEVICE * dev){ +int awc_rids_setup(struct net_device * dev){ struct awc_private * priv = (struct awc_private *) dev->priv; int i=0; diff -u --recursive --new-file v2.3.48/linux/drivers/net/am79c961a.c linux/drivers/net/am79c961a.c --- v2.3.48/linux/drivers/net/am79c961a.c Wed Aug 18 11:36:41 1999 +++ linux/drivers/net/am79c961a.c Mon Feb 28 07:16:54 2000 @@ -20,13 +20,13 @@ #include #include #include +#include #include #include #include #include #include -#include #define TX_BUFFERS 15 #define RX_BUFFERS 25 diff -u --recursive --new-file v2.3.48/linux/drivers/net/arlan.c linux/drivers/net/arlan.c --- v2.3.48/linux/drivers/net/arlan.c Mon Dec 20 18:48:21 1999 +++ linux/drivers/net/arlan.c Mon Feb 28 07:16:54 2000 @@ -102,6 +102,7 @@ static void arlan_tx_done_interrupt (struct net_device * dev, int status); static void arlan_rx_interrupt (struct net_device * dev, u_char rxStatus, u_short, u_short); static void arlan_process_interrupt (struct net_device * dev); +static void arlan_tx_timeout (struct net_device *dev); int arlan_command(struct net_device * dev, int command); EXPORT_SYMBOL(arlan_command); @@ -182,10 +183,7 @@ priv->txOffset = 0; priv->bad = 0; if (!priv->under_reset && !priv->under_config) - { - dev->tbusy = 0; - mark_bh(NET_BH); - } + netif_wake_queue (dev); } return 1; }; @@ -288,15 +286,9 @@ } } if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) - { priv->under_reset = 1; - dev->start = 0; - } if (priv->waiting_command_mask & ARLAN_COMMAND_CONF) - { priv->under_config = 1; - dev->start = 0; - } /* Issuing command */ arlan_lock_card_access(dev); @@ -341,14 +333,14 @@ else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET) { priv->under_reset=1; - dev->tbusy = 1; + netif_stop_queue (dev); arlan_drop_tx(dev); if (priv->tx_command_given || priv->rx_command_given) { printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); }; - dev->tbusy = 1; + netif_stop_queue (dev); if (arlan_debug & ARLAN_DEBUG_RESET) printk(KERN_ERR "%s: Doing chip reset\n", dev->name); priv->lastReset = jiffies; @@ -388,7 +380,6 @@ { printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name); } - dev->start = 0; arlan_drop_tx(dev); setInterruptEnable(dev); arlan_hw_config(dev); @@ -437,13 +428,11 @@ } else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR) { - if ( !registrationBad(dev) && (dev->tbusy || !dev->start) ) + if ( !registrationBad(dev) && + (netif_queue_stopped(dev) || !netif_running(dev)) ) { priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR; - - dev->tbusy = 0; - dev->start = 1; - mark_bh(NET_BH); + netif_wake_queue (dev); }; } else if (priv->waiting_command_mask & ARLAN_COMMAND_TX) @@ -587,8 +576,7 @@ else IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty"); priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); return; } @@ -650,11 +638,8 @@ priv->registrationLastSeen = jiffies; priv->registrationLostCount = 0; priv->reRegisterExp = 1; - if (dev->start == 0) - { - dev->start = 1; - mark_bh(NET_BH); - } + if (!netif_running(dev)) + netif_wake_queue(dev); } @@ -682,8 +667,7 @@ if (!(TXHEAD(dev).offset && TXTAIL(dev).offset)) { priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } priv->tx_done_delayed = 0; bh_mark_needed = 1; @@ -691,8 +675,7 @@ if (bh_mark_needed) { priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } arlan_process_interrupt(dev); @@ -788,7 +771,7 @@ } else { - dev->tbusy = 1; + netif_stop_queue (dev); return -1; IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds); @@ -811,11 +794,11 @@ } if (TXHEAD(dev).offset && TXTAIL(dev).offset) { - dev->tbusy = 1; + netif_stop_queue (dev); return 0; } else - dev->tbusy = 0; + netif_start_queue (dev); IFDEBUG(ARLAN_DEBUG_HEADER_DUMP) @@ -1161,7 +1144,7 @@ ARLAN_DEBUG_ENTRY("arlan_mac_addr"); return -EINVAL; - if (dev->start) + if (!netif_running(dev)) return -EBUSY; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); @@ -1223,8 +1206,8 @@ dev->set_multicast_list = arlan_set_multicast; dev->change_mtu = arlan_change_mtu; dev->set_mac_address = arlan_mac_addr; - dev->tbusy = 1; - dev->start = 0; + dev->tx_timeout = arlan_tx_timeout; + dev->watchdog_timeo = 3*HZ; ((struct arlan_private *) dev->priv)->irq_test_done = 0; arlan_device[num] = dev; @@ -1302,14 +1285,13 @@ priv->open_time = jiffies; memcpy_fromio(dev->dev_addr, arlan->lanCardNodeId, 6); memset(dev->broadcast, 0xff, 6); - dev->tbusy = 1; priv->txOffset = 0; - dev->interrupt = 0; - dev->start = 0; dev->tx_queue_len = tx_queue_len; priv->interrupt_processing_active = 0; priv->command_lock = 0; + netif_start_queue (dev); + init_MUTEX(&priv->card_lock); myATOMIC_INIT(priv->card_users, 1); /* damn 2.0.33 */ priv->registrationLostCount = 0; @@ -1327,7 +1309,6 @@ priv->Conf->writeEEPROM = 0; priv->Conf->registrationInterrupts = 1; - dev->tbusy = 0; init_timer(&priv->timer); priv->timer.expires = jiffies + HZ / 10; priv->timer.data = (unsigned long) dev; @@ -1335,8 +1316,6 @@ arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW); udelay(200000); - dev->tbusy = 0; - dev->start = 1; add_timer(&priv->timer); MOD_INC_USE_COUNT; @@ -1351,69 +1330,43 @@ } +static void arlan_tx_timeout (struct net_device *dev) +{ + printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name); + /* Try to restart the adaptor. */ + arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); + dev->trans_start = jiffies; + netif_start_queue (dev); +} static int arlan_tx(struct sk_buff *skb, struct net_device *dev) { struct arlan_private *priv = ((struct arlan_private *) dev->priv); - struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf; + short length; + unsigned char *buf; ARLAN_DEBUG_ENTRY("arlan_tx"); - - if (dev->tbusy) - { - /* - * If we get here, some higher level has decided we are broken. - * There should really be a "kick me" function call instead. - */ - int tickssofar = jiffies - dev->trans_start; - - if (((tickssofar * 1000) / HZ) * 2 > conf->txTimeoutMs) - arlan_command(dev, ARLAN_COMMAND_TX_ABORT); - - if (((tickssofar * 1000) / HZ) < conf->txTimeoutMs) - { - // up(&priv->card_lock); - goto bad_end; - } - printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name); - /* Try to restart the adaptor. */ - arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET); - dev->trans_start = jiffies; - goto bad_end; - - } + /* - * Block a timer-based transmit from overlapping. This could better be - * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. + * If some higher layer thinks we've missed an tx-done interrupt + * we are passed NULL. Caution: dev_tint() handles the cli()/sti() + * itself. */ - if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) - { - printk(KERN_ERR "%s: Transmitter access conflict.\n", - dev->name); + + length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + buf = skb->data; + + if (priv->txOffset + length + 0x12 > 0x800) { + printk(KERN_ERR "TX RING overflow \n"); + netif_stop_queue (dev); } - else - { - short length; - unsigned char *buf; - - /* - * If some higher layer thinks we've missed an tx-done interrupt - * we are passed NULL. Caution: dev_tint() handles the cli()/sti() - * itself. - */ - - length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - buf = skb->data; - if (priv->txOffset + length + 0x12 > 0x800) - printk(KERN_ERR "TX RING overflow \n"); + if (arlan_hw_tx(dev, buf, length) == -1) + goto bad_end; - if (arlan_hw_tx(dev, buf, length) == -1) - goto bad_end; + dev->trans_start = jiffies; - dev->trans_start = jiffies; - } dev_kfree_skb(skb); arlan_process_interrupt(dev); @@ -1424,6 +1377,7 @@ bad_end: arlan_process_interrupt(dev); priv->tx_chain_active = 0; + netif_stop_queue (dev); ARLAN_DEBUG_EXIT("arlan_tx"); return 1; } @@ -1522,8 +1476,7 @@ if (!TXHEAD(dev).offset || !TXTAIL(dev).offset) { priv->txOffset = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } } } @@ -1852,15 +1805,12 @@ WRITESHMB(arlan->rxStatus, 0x00); arlan_command(dev, ARLAN_COMMAND_RX); if (registrationBad(dev)) - dev->start = 0; + netif_device_detach(dev); if (!registrationBad(dev)) { priv->registrationLastSeen = jiffies; - if (!dev->tbusy && !priv->under_reset && !priv->under_config) - { - mark_bh(NET_BH); - dev->start = 1; - } + if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config) + netif_wake_queue (dev); } goto ends; } @@ -1900,12 +1850,10 @@ if (!rxStatus && !txStatus) priv->interrupt_ack_requested++; - dev->interrupt++; arlan_process_interrupt(dev); priv->irq_test_done = 1; - dev->interrupt--; ARLAN_DEBUG_EXIT("arlan_interrupt"); return; @@ -1938,8 +1886,7 @@ printk(KERN_NOTICE "%s: Closing device\n", dev->name); priv->open_time = 0; - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); free_irq(dev->irq, dev); MOD_DEC_USE_COUNT; diff -u --recursive --new-file v2.3.48/linux/drivers/net/bonding.c linux/drivers/net/bonding.c --- v2.3.48/linux/drivers/net/bonding.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/bonding.c Mon Feb 28 07:18:20 2000 @@ -0,0 +1,350 @@ +/* + * originally based on the dummy device. + * + * Copyright 1999, Thomas Davis, tadavis@lbl.gov. + * Licensed under the GPL. Based on dummy.c, and eql.c devices. + * + * bond.c: a bonding/etherchannel/sun trunking net driver + * + * This is useful to talk to a Cisco 5500, running Etherchannel, aka: + * Linux Channel Bonding + * Sun Trunking (Solaris) + * + * How it works: + * ifconfig bond0 ipaddress netmask up + * will setup a network device, with an ip address. No mac address + * will be assigned at this time. The hw mac address will come from + * the first slave bonded to the channel. All slaves will then use + * this hw mac address. + * + * ifconfig bond0 down + * will release all slaves, marking them as down. + * + * ifenslave bond0 eth0 + * will attache eth0 to bond0 as a slave. eth0 hw mac address will either + * a: be used as initial mac address + * b: if a hw mac address already is there, eth0's hw mac address + * will then be set from bond0. + * + * v0.1 - first working version. + * v0.2 - changed stats to be calculated by summing slaves stats. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +typedef struct slave +{ + struct slave *next; + struct slave *prev; + struct net_device *dev; +} slave_t; + +typedef struct bonding +{ + slave_t *next; + slave_t *prev; + struct net_device *master; + + slave_t *current_slave; + struct net_device_stats stats; +} bonding_t; + + +static int bond_xmit(struct sk_buff *skb, struct net_device *dev); +static struct net_device_stats *bond_get_stats(struct net_device *dev); + +static struct net_device *this_bond; + +static int bond_open(struct net_device *dev) +{ + MOD_INC_USE_COUNT; + return 0; +} + +static int bond_close(struct net_device *master) +{ + bonding_t *bond = master->priv; + slave_t *slave; + + while ((slave = bond->next) != (slave_t*)bond) { + + spin_lock_bh(&master->xmit_lock); + slave->next->prev = slave->prev; + slave->prev->next = slave->next; + bond->current_slave = (slave_t*)bond; + spin_unlock_bh(&master->xmit_lock); + + netdev_set_master(slave->dev, NULL); + + kfree(slave); + } + + MOD_DEC_USE_COUNT; + return 0; +} + +/* Fake multicast ability. + + NB. It is possible and necessary to make it true one, otherwise + the device is not functional. + */ +static void bond_set_multicast_list(struct net_device *dev) +{ +} + +static int bond_enslave(struct net_device *master, struct net_device *dev) +{ + int err; + bonding_t *bond = master->priv; + slave_t *slave; + + if (dev->type != master->type) + return -ENODEV; + + if ((slave = kmalloc(sizeof(slave_t), GFP_KERNEL)) == NULL) + return -ENOMEM; + + memset(slave, 0, sizeof(slave_t)); + + err = netdev_set_master(dev, master); + if (err) { + kfree(slave); + return err; + } + + slave->dev = dev; + + spin_lock_bh(&master->xmit_lock); + + dev_hold(dev); + + slave->prev = bond->prev; + slave->next = (slave_t*)bond; + slave->prev->next = slave; + slave->next->prev = slave; + + spin_unlock_bh(&master->xmit_lock); + + MOD_INC_USE_COUNT; + return 0; +} + +static int bond_release(struct net_device *master, struct net_device *dev) +{ + bonding_t *bond = master->priv; + slave_t *slave; + + if (dev->master != master) + return -EINVAL; + + netdev_set_master(dev, NULL); + + for (slave = bond->next; slave != (slave_t*)bond; slave = slave->next) { + if (slave->dev == dev) { + spin_lock_bh(&master->xmit_lock); + if (bond->current_slave == slave) + bond->current_slave = slave->next; + slave->next->prev = slave->prev; + slave->prev->next = slave->next; + spin_unlock_bh(&master->xmit_lock); + + kfree(slave); + dev_put(dev); + MOD_DEC_USE_COUNT; + break; + } + } + + return 0; +} + +/* It is pretty silly, SIOCSIFHWADDR exists to make this. */ + +static int bond_sethwaddr(struct net_device *master, struct net_device *slave) +{ + memcpy(master->dev_addr, slave->dev_addr, slave->addr_len); + return 0; +} + +static int bond_ioctl(struct net_device *master, struct ifreq *ifr, int cmd) +{ + struct net_device *slave = __dev_get_by_name(ifr->ifr_slave); + + if (slave == NULL) + return -ENODEV; + + switch (cmd) { + case BOND_ENSLAVE: + return bond_enslave(master, slave); + case BOND_RELEASE: + return bond_release(master, slave); + case BOND_SETHWADDR: + return bond_sethwaddr(master, slave); + default: + return -EOPNOTSUPP; + } +} + +static int bond_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + struct net_device *slave = ptr; + + if (this_bond == NULL || + this_bond == slave || + this_bond != slave->master) + return NOTIFY_DONE; + + switch (event) { + case NETDEV_UNREGISTER: + bond_release(this_bond, slave); + break; + } + + return NOTIFY_DONE; +} + +struct notifier_block bond_netdev_notifier={ + bond_event, + NULL, + 0 +}; + +int __init bond_init(struct net_device *dev) +{ + bonding_t *bond; + + bond = kmalloc(sizeof(struct bonding), GFP_KERNEL); + if (bond == NULL) + return -ENOMEM; + + memset(bond, 0, sizeof(struct bonding)); + bond->next = (slave_t*)bond; + bond->prev = (slave_t*)bond; + bond->master = dev; + bond->current_slave = (slave_t*)bond; + dev->priv = bond; + + /* Initialize the device structure. */ + dev->hard_start_xmit = bond_xmit; + dev->get_stats = bond_get_stats; + dev->open = bond_open; + dev->stop = bond_close; + dev->set_multicast_list = bond_set_multicast_list; + dev->do_ioctl = bond_ioctl; + + /* Fill in the fields of the device structure with ethernet-generic + values. */ + ether_setup(dev); + dev->tx_queue_len = 0; + dev->flags |= IFF_MASTER; + + this_bond = dev; + + register_netdevice_notifier(&bond_netdev_notifier); + + return 0; +} + +static int bond_xmit(struct sk_buff *skb, struct net_device *dev) +{ + bonding_t *bond = dev->priv; + slave_t *slave, *start_at; + int pkt_len = skb->len; + + slave = start_at = bond->current_slave; + + do { + if (slave == (slave_t*)bond) + continue; + + if (netif_running(slave->dev) && netif_carrier_ok(dev)) { + bond->current_slave = slave->next; + skb->dev = slave->dev; + + if (dev_queue_xmit(skb)) { + bond->stats.tx_dropped++; + } else { + bond->stats.tx_packets++; + bond->stats.tx_bytes += pkt_len; + } + return 0; + } + } while ((slave = slave->next) != start_at); + + bond->stats.tx_dropped++; + kfree_skb(skb); + return 0; +} + +static struct net_device_stats *bond_get_stats(struct net_device *dev) +{ + bonding_t *bond = dev->priv; + + return &bond->stats; +} + +#ifdef MODULE + +static char bond_name[16]; + +static struct net_device dev_bond = { + bond_name, /* Needs to be writeable */ + 0, 0, 0, 0, + 0x0, 0, + 0, 0, 0, NULL, bond_init }; + +int init_module(void) +{ + /* Find a name for this unit */ + int err=dev_alloc_name(&dev_bond,"bond%d"); + + if (err<0) + return err; + + if (register_netdev(&dev_bond) != 0) + return -EIO; + + return 0; +} + +void cleanup_module(void) +{ + unregister_netdevice_notifier(&bond_netdev_notifier); + + unregister_netdev(&dev_bond); + + kfree(dev_bond.priv); +} +#endif /* MODULE */ + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -u --recursive --new-file v2.3.48/linux/drivers/net/fc/iph5526.c linux/drivers/net/fc/iph5526.c --- v2.3.48/linux/drivers/net/fc/iph5526.c Sun Feb 13 19:29:04 2000 +++ linux/drivers/net/fc/iph5526.c Mon Feb 28 07:16:54 2000 @@ -218,6 +218,7 @@ Scsi_Host_Template driver_template = IPH5526_SCSI_FC; +static void iph5526_timeout(struct net_device *dev); #ifdef CONFIG_PCI static int iph5526_probe_pci(struct net_device *dev); @@ -286,6 +287,8 @@ dev->get_stats = iph5526_get_stats; dev->set_multicast_list = NULL; dev->change_mtu = iph5526_change_mtu; + dev->tx_timeout = iph5526_timeout; + dev->watchdog_timeo = 5*HZ; #ifndef MODULE fc_setup(dev); #endif diff -u --recursive --new-file v2.3.48/linux/drivers/net/hamradio/mkiss.c linux/drivers/net/hamradio/mkiss.c --- v2.3.48/linux/drivers/net/hamradio/mkiss.c Thu Nov 11 20:11:41 1999 +++ linux/drivers/net/hamradio/mkiss.c Mon Feb 28 07:16:54 2000 @@ -320,16 +320,14 @@ /* Set the "sending" flag. This must be atomic, hence the ASM. */ static inline void ax_lock(struct ax_disp *ax) { - if (test_and_set_bit(0, (void *)&ax->dev->tbusy)) - printk(KERN_ERR "mkiss: %s: trying to lock already locked device!\n", ax->dev->name); + netif_stop_queue(ax->dev); } /* Clear the "sending" flag. This must be atomic, hence the ASM. */ static inline void ax_unlock(struct ax_disp *ax) { - if (!test_and_clear_bit(0, (void *)&ax->dev->tbusy)) - printk(KERN_ERR "mkiss: %s: trying to unlock already unlocked device!\n", ax->dev->name); + netif_start_queue(ax->dev); } /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ @@ -435,7 +433,7 @@ struct mkiss_channel *mkiss; /* First make sure we're connected. */ - if (ax == NULL || ax->magic != AX25_MAGIC || !ax->dev->start) + if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) return; if (ax->xleft <= 0) { /* Now serial buffer is almost free & we can start @@ -449,8 +447,7 @@ ax_unlock(ax->mkiss); } - ax_unlock(ax); - mark_bh(NET_BH); + netif_wake_queue(ax->dev); return; } @@ -474,22 +471,22 @@ tmp_ax = ax->mkiss; } - if (!dev->start) { + if (!netif_running(dev)) { printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); return 1; } if (tmp_ax != NULL) - if (tmp_ax->dev->tbusy) + if (netif_queue_stopped(tmp_ax->dev)) return 1; if (tmp_ax != NULL) - if (dev->tbusy) { + if (netif_queue_stopped(dev)) { printk(KERN_ERR "mkiss: dev busy while serial dev is free\n"); ax_unlock(ax); } - if (dev->tbusy) { + if (netif_queue_stopped(dev)) { /* * May be we must check transmitter timeout here ? * 14 Oct 1994 Dmitry Gorodchanin. @@ -583,9 +580,8 @@ ax->xleft = 0; ax->flags &= (1 << AXF_INUSE); /* Clear ESCAPE & ERROR flags */ - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); return 0; /* Cleanup */ @@ -609,8 +605,7 @@ ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); - dev->tbusy = 1; - dev->start = 0; + netif_stop_queue(dev); return 0; } @@ -630,7 +625,7 @@ { struct ax_disp *ax = (struct ax_disp *)tty->disc_data; - if (ax == NULL || ax->magic != AX25_MAGIC || !ax->dev->start) + if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) return; /* @@ -691,7 +686,7 @@ if (mkiss->magic == MKISS_DRIVER_MAGIC) { for (cnt = 1; cnt < ax25_maxdev; cnt++) { if (ax25_ctrls[cnt]) { - if (ax25_ctrls[cnt]->dev.start) { + if (netif_running(&ax25_ctrls[cnt]->dev)) { if (ax == &ax25_ctrls[cnt]->ctrl) { cnt--; tmp_ax = &ax25_ctrls[cnt]->ctrl; @@ -802,7 +797,7 @@ static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len) { unsigned char *ptr = d; - unsigned char c; + unsigned char c=0; *ptr++ = END; while (len > 0) { @@ -1221,7 +1216,7 @@ * VSV = if dev->start==0, then device * unregistred while close proc. */ - if (ax25_ctrls[i]->dev.start) + if (netif_running(&ax25_ctrls[i]->dev)) unregister_netdev(&(ax25_ctrls[i]->dev)); kfree(ax25_ctrls[i]); diff -u --recursive --new-file v2.3.48/linux/drivers/net/ioc3-eth.c linux/drivers/net/ioc3-eth.c --- v2.3.48/linux/drivers/net/ioc3-eth.c Sat Feb 26 22:31:47 2000 +++ linux/drivers/net/ioc3-eth.c Mon Feb 28 07:18:20 2000 @@ -48,7 +48,6 @@ * - Use hardware checksums. * - Convert to using the PCI infrastructure / IOC3 meta driver. */ -#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/drivers/net/irda/nsc-ircc.c linux/drivers/net/irda/nsc-ircc.c --- v2.3.48/linux/drivers/net/irda/nsc-ircc.c Sat Feb 26 22:31:47 2000 +++ linux/drivers/net/irda/nsc-ircc.c Thu Mar 2 11:41:11 2000 @@ -6,7 +6,7 @@ * Status: Stable. * Author: Dag Brattli * Created at: Sat Nov 7 21:43:15 1998 - * Modified at: Fri Feb 18 01:48:51 2000 + * Modified at: Wed Mar 1 11:29:34 2000 * Modified by: Dag Brattli * * Copyright (c) 1998-2000 Dag Brattli @@ -715,9 +715,9 @@ switch_bank(iobase, BANK2); outb(EXCR2_RFSIZ|EXCR2_TFSIZ, iobase+EXCR2); - /* IRCR2: FEND_MD is set */ + /* IRCR2: FEND_MD is not set */ switch_bank(iobase, BANK5); - outb(0x2a, iobase+4); + outb(0x02, iobase+4); /* Make sure that some defaults are OK */ switch_bank(iobase, BANK6); diff -u --recursive --new-file v2.3.48/linux/drivers/net/pcmcia/aironet4500_cs.c linux/drivers/net/pcmcia/aironet4500_cs.c --- v2.3.48/linux/drivers/net/pcmcia/aironet4500_cs.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/net/pcmcia/aironet4500_cs.c Mon Feb 28 07:16:54 2000 @@ -112,13 +112,13 @@ by the net software, because we only register already-found cards. */ -static int awc_pcmcia_init(struct NET_DEVICE *dev) +static int awc_pcmcia_init(struct net_device *dev) { return awc_init(dev); } -static int awc_pcmcia_open(struct NET_DEVICE *dev) +static int awc_pcmcia_open(struct net_device *dev) { dev_link_t *link; int status; @@ -136,7 +136,7 @@ return status; } -static int awc_pcmcia_close(struct NET_DEVICE *dev) +static int awc_pcmcia_close(struct net_device *dev) { // int ioaddr = dev->base_addr; dev_link_t *link; @@ -170,7 +170,7 @@ { client_reg_t client_reg; dev_link_t *link = NULL; - struct NET_DEVICE *dev = NULL; + struct net_device *dev = NULL; int ret; PC_DEBUG(0, "awc_attach()\n"); @@ -199,8 +199,8 @@ /* Create the network device object. */ - dev = kmalloc(sizeof(struct NET_DEVICE ), GFP_KERNEL); - memset(dev,0,sizeof(struct NET_DEVICE)); + dev = kmalloc(sizeof(struct net_device ), GFP_KERNEL); + memset(dev,0,sizeof(struct net_device)); // dev = init_etherdev(0, sizeof(struct awc_private) ); if (!dev ) { printk(KERN_CRIT "out of mem on dev alloc \n"); @@ -321,10 +321,10 @@ } if (link->priv) { - //struct NET_DEVICE *dev = link->priv; + //struct net_device *dev = link->priv; // dam dam damn mif (dev->priv) // kfree_s(dev->priv, sizeof(struct awc_private)); - kfree_s(link->priv, sizeof(struct NET_DEVICE)); + kfree_s(link->priv, sizeof(struct net_device)); } kfree_s(link->dev, sizeof(struct dev_node_t)); kfree_s(link, sizeof(struct dev_link_t)); @@ -345,7 +345,7 @@ static void awc_pcmcia_config(dev_link_t *link) { client_handle_t handle; - struct NET_DEVICE *dev; + struct net_device *dev; struct awc_private *lp; tuple_t tuple; int ii; @@ -520,7 +520,7 @@ static void awc_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; - struct NET_DEVICE *dev = link->priv; + struct net_device *dev = link->priv; DEBUG(0, "awc_release(0x%p)\n", link); @@ -558,7 +558,7 @@ event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct NET_DEVICE *dev = link->priv; + struct net_device *dev = link->priv; PC_DEBUG(1, "awc_event(0x%06x)\n", event); diff -u --recursive --new-file v2.3.48/linux/drivers/net/pcmcia/com20020_cs.c linux/drivers/net/pcmcia/com20020_cs.c --- v2.3.48/linux/drivers/net/pcmcia/com20020_cs.c Tue Jan 4 13:57:17 2000 +++ linux/drivers/net/pcmcia/com20020_cs.c Mon Feb 28 07:16:54 2000 @@ -309,7 +309,7 @@ { DEBUG(1,"unregister...\n"); - if (dev->start) + if (netif_running(dev)) dev->stop(dev); /* @@ -501,7 +501,7 @@ case CS_EVENT_CARD_REMOVAL: link->state &= ~DEV_PRESENT; if (link->state & DEV_CONFIG) { - dev->tbusy = 1; dev->start = 0; + netif_device_detach(dev); link->release.expires = jiffies + HZ/20; link->state |= DEV_RELEASE_PENDING; add_timer(&link->release); @@ -517,7 +517,7 @@ case CS_EVENT_RESET_PHYSICAL: if (link->state & DEV_CONFIG) { if (link->open) { - dev->tbusy = 1; dev->start = 0; + netif_device_detach(dev); } CardServices(ReleaseConfiguration, link->handle); } diff -u --recursive --new-file v2.3.48/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c --- v2.3.48/linux/drivers/net/rrunner.c Tue Dec 7 09:32:43 1999 +++ linux/drivers/net/rrunner.c Thu Mar 2 11:42:31 2000 @@ -1,7 +1,7 @@ /* * rrunner.c: Linux driver for the Essential RoadRunner HIPPI board. * - * Written 1998 by Jes Sorensen, . + * Copyright (C) 1998-2000 by Jes Sorensen, . * * Thanks to Essential Communication for providing us with hardware * and very comprehensive documentation without which I would not have @@ -13,6 +13,12 @@ * 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. + * + * Thanks to Jayaram Bhat from ODS/Essential for fixing some of the + * stupid bugs in my code. + * + * Softnet support and various other patches from Val Henson of + * ODS/Essential. */ #define DEBUG 1 @@ -20,7 +26,7 @@ #define PKT_COPY_THRESHOLD 512 #include - +#include #include #include #include @@ -32,17 +38,53 @@ #include #include #include -#include #include #include +#include #include #include #include #include +#if (LINUX_VERSION_CODE < 0x02030e) +#define net_device device +#endif + +#if (LINUX_VERSION_CODE >= 0x02031b) +#define NEW_NETINIT +#endif + +#if (LINUX_VERSION_CODE < 0x02032b) +/* + * SoftNet changes + */ +#define dev_kfree_skb_irq(a) dev_kfree_skb(a) +#define netif_wake_queue(dev) clear_bit(0, &dev->tbusy) +#define netif_stop_queue(dev) set_bit(0, &dev->tbusy) + +static inline void netif_start_queue(struct net_device *dev) +{ + dev->tbusy = 0; + dev->start = 1; +} + +#define rr_mark_net_bh(foo) mark_bh(foo) +#define rr_if_busy(dev) dev->tbusy +#define rr_if_running(dev) dev->start /* Currently unused. */ +#define rr_if_down(dev) {do{dev->start = 0;}while (0);} +#else +#define NET_BH 0 +#define rr_mark_net_bh(foo) {do{} while(0);} +#define rr_if_busy(dev) test_bit(LINK_STATE_XOFF, &dev->state) +#define rr_if_running(dev) test_bit(LINK_STATE_START, &dev->state) +#define rr_if_down(dev) {do{} while(0);} +#endif + #include "rrunner.h" +#define RUN_AT(x) (jiffies + (x)) + /* * Implementation notes: @@ -59,7 +101,9 @@ * stack will need to know about I/O vectors or something similar. */ -static const char __initdata *version = "rrunner.c: v0.17 03/09/99 Jes Sorensen (Jes.Sorensen@cern.ch)\n"; +static const char __initdata *version = "rrunner.c: v0.22 03/01/2000 Jes Sorensen (Jes.Sorensen@cern.ch)\n"; + +static struct net_device *root_dev = NULL; /* @@ -72,11 +116,17 @@ static int probed __initdata = 0; +#ifdef NEW_NETINIT int __init rr_hippi_probe (void) +#else +int __init rr_hippi_probe (struct net_device *dev) +#endif { +#ifdef NEW_NETINIT + struct net_device *dev; +#endif int boards_found = 0; int version_disp; /* was version info already displayed? */ - struct net_device *dev; struct pci_dev *pdev = NULL; struct pci_dev *opdev = NULL; u8 pci_latency; @@ -128,10 +178,11 @@ dev->get_stats = &rr_get_stats; dev->do_ioctl = &rr_ioctl; - /* - * Dummy value. - */ - dev->base_addr = 42; +#if (LINUX_VERSION_CODE < 0x02030d) + dev->base_addr = pdev->base_address[0]; +#else + dev->base_addr = pdev->resource[0].start; +#endif /* display version info if adapter is found */ if (!version_disp) @@ -153,14 +204,14 @@ printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI " "at 0x%08lx, irq %i, PCI latency %i\n", dev->name, - pdev->resource[0].start, dev->irq, pci_latency); + dev->base_addr, dev->irq, pci_latency); /* * Remap the regs into kernel space. */ rrpriv->regs = (struct rr_regs *) - ioremap(pdev->resource[0].start, 0x1000); + ioremap(dev->base_addr, 0x1000); if (!rrpriv->regs){ printk(KERN_ERR "%s: Unable to map I/O register, " @@ -193,10 +244,16 @@ * 1 or more boards. Otherwise, return failure (-ENODEV). */ +#ifdef MODULE return boards_found; +#else + if (boards_found > 0) + return 0; + else + return -ENODEV; +#endif } -static struct net_device *root_dev = NULL; #ifdef MODULE #if LINUX_VERSION_CODE > 0x20118 @@ -204,10 +261,18 @@ MODULE_DESCRIPTION("Essential RoadRunner HIPPI driver"); #endif - int init_module(void) { - return rr_hippi_probe()? 0 : -ENODEV; + int cards; + + root_dev = NULL; + +#ifdef NEW_NETINIT + cards = rr_hippi_probe(); +#else + cards = rr_hippi_probe(NULL); +#endif + return cards ? 0 : -ENODEV; } void cleanup_module(void) @@ -260,11 +325,11 @@ idx = rrpriv->info->cmd_ctrl.pi; writel(*(u32*)(cmd), ®s->CmdRing[idx]); - mb(); + wmb(); idx = (idx - 1) % CMD_RING_ENTRIES; rrpriv->info->cmd_ctrl.pi = idx; - mb(); + wmb(); if (readl(®s->Mode) & FATAL_ERR) printk("error code %02x\n", readl(®s->Fail1)); @@ -363,8 +428,8 @@ /* * Why 32 ? is this not cache line size dependant? */ - writel(WBURST_32, ®s->PciState); - mb(); + writel(RBURST_64|WBURST_64, ®s->PciState); + wmb(); start_pc = rr_read_eeprom_word(rrpriv, &hw->rncd_info.FwStart); @@ -374,11 +439,11 @@ #endif writel(start_pc + 0x800, ®s->Pc); - mb(); + wmb(); udelay(5); writel(start_pc, ®s->Pc); - mb(); + wmb(); return 0; } @@ -495,7 +560,9 @@ { struct rr_private *rrpriv; struct rr_regs *regs; + struct eeprom *hw = NULL; u32 sram_size, rev; + int i; rrpriv = (struct rr_private *)dev->priv; regs = rrpriv->regs; @@ -519,6 +586,26 @@ printk(" Maximum receive rings %i\n", readl(®s->MaxRxRng)); #endif + /* + * Read the hardware address from the eeprom. The HW address + * is not really necessary for HIPPI but awfully convenient. + * The pointer arithmetic to put it in dev_addr is ugly, but + * Donald Becker does it this way for the GigE version of this + * card and it's shorter and more portable than any + * other method I've seen. -VAL + */ + + *(u16 *)(dev->dev_addr) = + htons(rr_read_eeprom_word(rrpriv, &hw->manf.BoardULA)); + *(u32 *)(dev->dev_addr+2) = + htonl(rr_read_eeprom_word(rrpriv, &hw->manf.BoardULA[4])); + + printk(" MAC: "); + + for (i = 0; i < 5; i++) + printk("%2.2x:", dev->dev_addr[i]); + printk("%2.2x\n", dev->dev_addr[i]); + sram_size = rr_read_eeprom_word(rrpriv, (void *)8); printk(" SRAM size 0x%06x\n", sram_size); @@ -545,9 +632,10 @@ { struct rr_private *rrpriv; struct rr_regs *regs; - u32 hostctrl; unsigned long myjif, flags; struct cmd cmd; + u32 hostctrl; + int ecode = 0; short i; rrpriv = (struct rr_private *)dev->priv; @@ -557,13 +645,14 @@ hostctrl = readl(®s->HostCtrl); writel(hostctrl | HALT_NIC | RR_CLEAR_INT, ®s->HostCtrl); - mb(); + wmb(); if (hostctrl & PARITY_ERR){ printk("%s: Parity error halting NIC - this is serious!\n", dev->name); spin_unlock_irqrestore(&rrpriv->lock, flags); - return -EFAULT; + ecode = -EFAULT; + goto error; } set_rxaddr(regs, rrpriv->rx_ctrl); @@ -607,45 +696,36 @@ rr_reset(dev); - writel(0x60, ®s->IntrTmr); - /* - * These seem to have no real effect as the Firmware sets - * it's own default values - */ - writel(0x10, ®s->WriteDmaThresh); - writel(0x20, ®s->ReadDmaThresh); + /* Tuning values */ + writel(0x5000, ®s->ConRetry); + writel(0x100, ®s->ConRetryTmr); + writel(0x500000, ®s->ConTmout); + writel(0x60, ®s->IntrTmr); + writel(0x500000, ®s->TxDataMvTimeout); + writel(0x200000, ®s->RxDataMvTimeout); + writel(0x80, ®s->WriteDmaThresh); + writel(0x80, ®s->ReadDmaThresh); rrpriv->fw_running = 0; - mb(); + wmb(); hostctrl &= ~(HALT_NIC | INVALID_INST_B | PARITY_ERR); writel(hostctrl, ®s->HostCtrl); - mb(); + wmb(); spin_unlock_irqrestore(&rrpriv->lock, flags); - udelay(1000); - - /* - * Now start the FirmWare. - */ - cmd.code = C_START_FW; - cmd.ring = 0; - cmd.index = 0; - - rr_issue_cmd(rrpriv, &cmd); - - /* - * Give the FirmWare time to chew on the `get running' command. - */ - myjif = jiffies + 5 * HZ; - while ((jiffies < myjif) && !rrpriv->fw_running); - for (i = 0; i < RX_RING_ENTRIES; i++) { struct sk_buff *skb; rrpriv->rx_ring[i].mode = 0; skb = alloc_skb(dev->mtu + HIPPI_HLEN, GFP_ATOMIC); + if (!skb) { + printk(KERN_WARNING "%s: Unable to allocate memory " + "for receive ring - halting NIC\n", dev->name); + ecode = -ENOMEM; + goto error; + } rrpriv->rx_skbuff[i] = skb; /* * Sanity test to see if we conflict with the DMA @@ -662,28 +742,43 @@ rrpriv->rx_ctrl[4].entries = RX_RING_ENTRIES; rrpriv->rx_ctrl[4].mode = 8; rrpriv->rx_ctrl[4].pi = 0; - mb(); + wmb(); set_rraddr(&rrpriv->rx_ctrl[4].rngptr, rrpriv->rx_ring); - cmd.code = C_NEW_RNG; - cmd.ring = 4; + udelay(1000); + + /* + * Now start the FirmWare. + */ + cmd.code = C_START_FW; + cmd.ring = 0; cmd.index = 0; + rr_issue_cmd(rrpriv, &cmd); -#if 0 -{ - u32 tmp; - tmp = readl(®s->ExtIo); - writel(0x80, ®s->ExtIo); - - i = jiffies + 1 * HZ; - while (jiffies < i); - writel(tmp, ®s->ExtIo); -} -#endif - dev->tbusy = 0; - dev->start = 1; - return 0; + /* + * Give the FirmWare time to chew on the `get running' command. + */ + myjif = jiffies + 5 * HZ; + while ((jiffies < myjif) && !rrpriv->fw_running); + + netif_start_queue(dev); + + return ecode; + + error: + /* + * We might have gotten here because we are out of memory, + * make sure we release everything we allocated before failing + */ + for (i = 0; i < RX_RING_ENTRIES; i++) { + if (rrpriv->rx_skbuff[i]) { + rrpriv->rx_ring[i].size = 0; + set_rraddr(&rrpriv->rx_ring[i].addr, 0); + dev_kfree_skb(rrpriv->rx_skbuff[i]); + } + } + return ecode; } @@ -705,81 +800,147 @@ switch (rrpriv->evt_ring[eidx].code){ case E_NIC_UP: tmp = readl(®s->FwRev); - printk("%s: Firmware revision %i.%i.%i up and running\n", - dev->name, (tmp >> 16), ((tmp >> 8) & 0xff), - (tmp & 0xff)); + printk(KERN_INFO "%s: Firmware revision %i.%i.%i " + "up and running\n", dev->name, + (tmp >> 16), ((tmp >> 8) & 0xff), (tmp & 0xff)); rrpriv->fw_running = 1; - mb(); + writel(RX_RING_ENTRIES - 1, ®s->IpRxPi); + wmb(); break; case E_LINK_ON: - printk("%s: Optical link ON\n", dev->name); + printk(KERN_INFO "%s: Optical link ON\n", dev->name); break; case E_LINK_OFF: - printk("%s: Optical link OFF\n", dev->name); + printk(KERN_INFO "%s: Optical link OFF\n", dev->name); break; case E_RX_IDLE: - printk("%s: RX data not moving\n", dev->name); + printk(KERN_WARNING "%s: RX data not moving\n", + dev->name); break; case E_WATCHDOG: - printk("%s: The watchdog is here to see us\n", + printk(KERN_INFO "%s: The watchdog is here to see " + "us\n", dev->name); + break; + case E_INTERN_ERR: + printk(KERN_ERR "%s: HIPPI Internal NIC error\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_HOST_ERR: + printk(KERN_ERR "%s: Host software error\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); break; /* * TX events. */ case E_CON_REJ: - printk("%s: Connection rejected\n", dev->name); + printk(KERN_WARNING "%s: Connection rejected\n", + dev->name); rrpriv->stats.tx_aborted_errors++; break; case E_CON_TMOUT: - printk("%s: Connection timeout\n", dev->name); + printk(KERN_WARNING "%s: Connection timeout\n", + dev->name); break; case E_DISC_ERR: - printk("%s: HIPPI disconnect error\n", dev->name); + printk(KERN_WARNING "%s: HIPPI disconnect error\n", + dev->name); rrpriv->stats.tx_aborted_errors++; break; + case E_INT_PRTY: + printk(KERN_ERR "%s: HIPPI Internal Parity error\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; case E_TX_IDLE: - printk("%s: Transmitter idle\n", dev->name); + printk(KERN_WARNING "%s: Transmitter idle\n", + dev->name); break; case E_TX_LINK_DROP: - printk("%s: Link lost during transmit\n", dev->name); + printk(KERN_WARNING "%s: Link lost during transmit\n", + dev->name); rrpriv->stats.tx_aborted_errors++; + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_TX_INV_RNG: + printk(KERN_ERR "%s: Invalid send ring block\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_TX_INV_BUF: + printk(KERN_ERR "%s: Invalid send buffer address\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_TX_INV_DSC: + printk(KERN_ERR "%s: Invalid descriptor address\n", + dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); break; /* * RX events. */ - case E_VAL_RNG: /* Should be ignored */ -#if (DEBUG > 2) - printk("%s: RX ring valid event\n", dev->name); -#endif - writel(RX_RING_ENTRIES - 1, ®s->IpRxPi); - break; - case E_INV_RNG: - printk("%s: RX ring invalid event\n", dev->name); - break; case E_RX_RNG_OUT: - printk("%s: Receive ring full\n", dev->name); + printk(KERN_INFO "%s: Receive ring full\n", dev->name); break; case E_RX_PAR_ERR: - printk("%s: Receive parity error.\n", dev->name); + printk(KERN_WARNING "%s: Receive parity error\n", + dev->name); break; case E_RX_LLRC_ERR: - printk("%s: Receive LLRC error.\n", dev->name); + printk(KERN_WARNING "%s: Receive LLRC error\n", + dev->name); break; case E_PKT_LN_ERR: - printk("%s: Receive packet length error.\n", + printk(KERN_WARNING "%s: Receive packet length " + "error\n", dev->name); + break; + case E_RX_INV_BUF: + printk(KERN_ERR "%s: Invalid receive buffer " + "address\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_RX_INV_DSC: + printk(KERN_ERR "%s: Invalid receive descriptor " + "address\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); + break; + case E_RNG_BLK: + printk(KERN_ERR "%s: Invalid ring block\n", dev->name); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + wmb(); break; default: - printk("%s: Unhandled event 0x%02x\n", + printk(KERN_WARNING "%s: Unhandled event 0x%02x\n", dev->name, rrpriv->evt_ring[eidx].code); } eidx = (eidx + 1) % EVT_RING_ENTRIES; } rrpriv->info->evt_ctrl.pi = eidx; - mb(); + wmb(); return eidx; } @@ -787,10 +948,10 @@ static void rx_int(struct net_device *dev, u32 rxlimit, u32 index) { struct rr_private *rrpriv = (struct rr_private *)dev->priv; - u32 pkt_len; struct rr_regs *regs = rrpriv->regs; do { + u32 pkt_len; pkt_len = rrpriv->rx_ring[index].size; #if (DEBUG > 2) printk("index %i, rxlimit %i\n", index, rxlimit); @@ -803,8 +964,7 @@ if (pkt_len < PKT_COPY_THRESHOLD) { skb = alloc_skb(pkt_len, GFP_ATOMIC); if (skb == NULL){ - printk("%s: Out of memory deferring " - "packet\n", dev->name); + printk(KERN_WARNING "%s: Unable to allocate skb (%i bytes), deferring packet\n", dev->name, pkt_len); rrpriv->stats.rx_dropped++; goto defer; }else @@ -847,7 +1007,7 @@ } while(index != rxlimit); rrpriv->cur_rx = index; - mb(); + wmb(); } @@ -857,7 +1017,6 @@ struct rr_regs *regs; struct net_device *dev = (struct net_device *)dev_id; u32 prodidx, rxindex, eidx, txcsmr, rxlimit, txcon; - unsigned long flags; rrpriv = (struct rr_private *)dev->priv; regs = rrpriv->regs; @@ -865,7 +1024,7 @@ if (!(readl(®s->HostCtrl) & RR_INT)) return; - spin_lock_irqsave(&rrpriv->lock, flags); + spin_lock(&rrpriv->lock); prodidx = readl(®s->EvtPrd); txcsmr = (prodidx >> 8) & 0xff; @@ -886,7 +1045,7 @@ do { rrpriv->stats.tx_packets++; rrpriv->stats.tx_bytes +=rrpriv->tx_skbuff[txcon]->len; - dev_kfree_skb(rrpriv->tx_skbuff[txcon]); + dev_kfree_skb_irq(rrpriv->tx_skbuff[txcon]); rrpriv->tx_skbuff[txcon] = NULL; rrpriv->tx_ring[txcon].size = 0; @@ -895,15 +1054,15 @@ txcon = (txcon + 1) % TX_RING_ENTRIES; } while (txcsmr != txcon); - mb(); + wmb(); rrpriv->dirty_tx = txcon; - if (rrpriv->tx_full && dev->tbusy && + if (rrpriv->tx_full && rr_if_busy(dev) && (((rrpriv->info->tx_ctrl.pi + 1) % TX_RING_ENTRIES) != rrpriv->dirty_tx)){ rrpriv->tx_full = 0; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue(dev); + rr_mark_net_bh(NET_BH); } } @@ -913,9 +1072,51 @@ eidx |= ((txcsmr << 8) | (rxlimit << 16)); writel(eidx, ®s->EvtCon); - mb(); + wmb(); - spin_unlock_irqrestore(&rrpriv->lock, flags); + spin_unlock(&rrpriv->lock); +} + + +static void rr_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct rr_private *rrpriv = (struct rr_private *)dev->priv; + struct rr_regs *regs = rrpriv->regs; + unsigned long flags; + int i; + + if (readl(®s->HostCtrl) & NIC_HALTED){ + printk("%s: Restarting nic\n", dev->name); + memset(rrpriv->rx_ctrl, 0, 256 * sizeof(struct ring_ctrl)); + memset(rrpriv->info, 0, sizeof(struct rr_info)); + wmb(); + for (i = 0; i < TX_RING_ENTRIES; i++) { + if (rrpriv->tx_skbuff[i]) { + rrpriv->tx_ring[i].size = 0; + set_rraddr(&rrpriv->tx_ring[i].addr, 0); + dev_kfree_skb(rrpriv->tx_skbuff[i]); + rrpriv->tx_skbuff[i] = NULL; + } + } + + for (i = 0; i < RX_RING_ENTRIES; i++) { + if (rrpriv->rx_skbuff[i]) { + rrpriv->rx_ring[i].size = 0; + set_rraddr(&rrpriv->rx_ring[i].addr, 0); + dev_kfree_skb(rrpriv->rx_skbuff[i]); + rrpriv->rx_skbuff[i] = NULL; + } + } + if (rr_init1(dev)) { + spin_lock_irqsave(&rrpriv->lock, flags); + writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, + ®s->HostCtrl); + spin_unlock_irqrestore(&rrpriv->lock, flags); + } + } + rrpriv->timer.expires = RUN_AT(5*HZ); + add_timer(&rrpriv->timer); } @@ -936,22 +1137,21 @@ goto error; } - rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl), - GFP_KERNEL | GFP_DMA); + rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl), GFP_KERNEL); if (!rrpriv->rx_ctrl) { ecode = -ENOMEM; goto error; } - rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL | GFP_DMA); + rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL); if (!rrpriv->info){ - kfree(rrpriv->rx_ctrl); + rrpriv->rx_ctrl = NULL; ecode = -ENOMEM; goto error; } memset(rrpriv->rx_ctrl, 0, 256 * sizeof(struct ring_ctrl)); memset(rrpriv->info, 0, sizeof(struct rr_info)); - mb(); + wmb(); spin_lock_irqsave(&rrpriv->lock, flags); writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, ®s->HostCtrl); @@ -965,22 +1165,40 @@ goto error; } - rr_init1(dev); + if ((ecode = rr_init1(dev))) + goto error; - dev->tbusy = 0; - dev->start = 1; + /* Set the timer to switch to check for link beat and perhaps switch + to an alternate media type. */ + init_timer(&rrpriv->timer); + rrpriv->timer.expires = RUN_AT(5*HZ); /* 5 sec. watchdog */ + rrpriv->timer.data = (unsigned long)dev; + rrpriv->timer.function = &rr_timer; /* timer handler */ + add_timer(&rrpriv->timer); + + netif_start_queue(dev); MOD_INC_USE_COUNT; - return 0; + return ecode; error: spin_lock_irqsave(&rrpriv->lock, flags); writel(readl(®s->HostCtrl)|HALT_NIC|RR_CLEAR_INT, ®s->HostCtrl); spin_unlock_irqrestore(&rrpriv->lock, flags); - dev->tbusy = 1; - dev->start = 0; - return -ENOMEM; + if (rrpriv->info) { + kfree(rrpriv->info); + rrpriv->info = NULL; + } + if (rrpriv->rx_ctrl) { + kfree(rrpriv->rx_ctrl); + rrpriv->rx_ctrl = NULL; + } + + netif_stop_queue(dev); + rr_if_down(dev); + + return ecode; } @@ -1055,9 +1273,9 @@ u32 tmp; short i; - dev->start = 0; - set_bit(0, (void*)&dev->tbusy); - + netif_stop_queue(dev); + rr_if_down(dev); + rrpriv = (struct rr_private *)dev->priv; regs = rrpriv->regs; @@ -1074,11 +1292,13 @@ }else{ tmp |= HALT_NIC | RR_CLEAR_INT; writel(tmp, ®s->HostCtrl); - mb(); + wmb(); } rrpriv->fw_running = 0; + del_timer(&rrpriv->timer); + writel(0, ®s->TxPi); writel(0, ®s->IpRxPi); @@ -1098,6 +1318,7 @@ rrpriv->tx_ring[i].size = 0; set_rraddr(&rrpriv->tx_ring[i].addr, 0); dev_kfree_skb(rrpriv->tx_skbuff[i]); + rrpriv->tx_skbuff[i] = NULL; } } @@ -1106,11 +1327,18 @@ rrpriv->rx_ring[i].size = 0; set_rraddr(&rrpriv->rx_ring[i].addr, 0); dev_kfree_skb(rrpriv->rx_skbuff[i]); + rrpriv->rx_skbuff[i] = NULL; } } - kfree(rrpriv->rx_ctrl); - kfree(rrpriv->info); + if (rrpriv->rx_ctrl) { + kfree(rrpriv->rx_ctrl); + rrpriv->rx_ctrl = NULL; + } + if (rrpriv->info) { + kfree(rrpriv->info); + rrpriv->info = NULL; + } free_irq(dev->irq, dev); spin_unlock(&rrpriv->lock); @@ -1142,7 +1370,7 @@ printk("incoming skb too small - reallocating\n"); if (!(new_skb = dev_alloc_skb(len + 8))) { dev_kfree_skb(skb); - dev->tbusy = 0; + netif_wake_queue(dev); return -EBUSY; } skb_reserve(new_skb, 8); @@ -1172,11 +1400,12 @@ rrpriv->tx_ring[index].size = len + 8; /* include IFIELD */ rrpriv->tx_ring[index].mode = PACKET_START | PACKET_END; txctrl->pi = (index + 1) % TX_RING_ENTRIES; + wmb(); writel(txctrl->pi, ®s->TxPi); if (txctrl->pi == rrpriv->dirty_tx){ rrpriv->tx_full = 1; - set_bit(0, (void*)&dev->tbusy); + netif_stop_queue(dev); } spin_unlock_irqrestore(&rrpriv->lock, flags); diff -u --recursive --new-file v2.3.48/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c --- v2.3.48/linux/drivers/net/seeq8005.c Sun Feb 13 19:29:04 2000 +++ linux/drivers/net/seeq8005.c Mon Feb 28 07:16:54 2000 @@ -42,9 +42,9 @@ #include #include #include +#include #include #include -#include #include #include #include diff -u --recursive --new-file v2.3.48/linux/drivers/net/setup.c linux/drivers/net/setup.c --- v2.3.48/linux/drivers/net/setup.c Wed Feb 16 17:03:52 2000 +++ linux/drivers/net/setup.c Sun Feb 27 18:45:10 2000 @@ -185,27 +185,6 @@ #endif /* CONFIG_IPDDP */ } - -/* - * The loopback device is global so it can be directly referenced - * by the network code. - */ - -extern int loopback_init(struct net_device *dev); -struct net_device loopback_dev = -{ - "lo" __PAD2, /* Software Loopback interface */ - 0x0, /* recv memory end */ - 0x0, /* recv memory start */ - 0x0, /* memory end */ - 0x0, /* memory start */ - 0, /* base I/O address */ - 0, /* IRQ */ - 0, 0, 0, /* flags */ - NULL, /* next device */ - loopback_init /* loopback_init should set up the rest */ -}; - static void special_device_init(void) { #ifdef CONFIG_DUMMY @@ -248,12 +227,20 @@ extern int sb1000_probe(struct net_device *dev); static struct net_device sb1000_dev = { - "cm0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, sb1000_probe + "cm0 __PAD3", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, sb1000_probe }; register_netdev(&sb1000_dev); } #endif - register_netdev(&loopback_dev); +#ifdef CONFIG_BONDING + { + extern int bond_init(struct net_device *dev); + static struct net_device bond_dev = { + "bond" __PAD4, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, bond_init, + }; + register_netdev(&bond_dev); + } +#endif } /* diff -u --recursive --new-file v2.3.48/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c --- v2.3.48/linux/drivers/net/sunlance.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/net/sunlance.c Sun Feb 27 18:45:10 2000 @@ -1,4 +1,4 @@ -/* $Id: sunlance.c,v 1.99 2000/02/16 10:36:14 davem Exp $ +/* $Id: sunlance.c,v 1.100 2000/02/27 09:38:12 anton Exp $ * lance.c: Linux/Sparc/Lance driver * * Written 1995, 1996 by Miguel de Icaza @@ -1287,8 +1287,10 @@ static void lance_set_multicast_retry(unsigned long _opaque) { struct net_device *dev = (struct net_device *) _opaque; + struct lance_private *lp = (struct lance_private *) dev->priv; lance_set_multicast(dev); + timer_exit(&lp->multicast_timer); } static void lance_free_hwresources(struct lance_private *lp) diff -u --recursive --new-file v2.3.48/linux/drivers/net/tokenring/ibmtr.c linux/drivers/net/tokenring/ibmtr.c --- v2.3.48/linux/drivers/net/tokenring/ibmtr.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/net/tokenring/ibmtr.c Thu Mar 2 10:15:30 2000 @@ -83,6 +83,11 @@ * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting * i.e. using functional address C0 00 00 04 00 00 to transmit and * receive multicast packets. + * + * Changes by Mike Sullivan (based on original sram patch by Dave Grothe + * to support windowing into on adapter shared ram. + * i.e. Use LANAID to setup a PnP configuration with 16K RAM. Paging + * will shift this 16K window over the entire available shared RAM. */ /* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value @@ -102,7 +107,8 @@ #define NO_AUTODETECT 1 #undef NO_AUTODETECT -#undef ENABLE_PAGING +/* #undef ENABLE_PAGING */ +#define ENABLE_PAGING 1 #define FALSE 0 @@ -119,7 +125,8 @@ static char *version = "ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n" " v2.1.125 10/20/98 Paul Norton \n" -" v2.2.0 12/30/98 Joel Sloan \n"; +" v2.2.0 12/30/98 Joel Sloan \n" +" v2.2.1 02/08/00 Mike Sullivan \n"; static char pcchannelid[] = { 0x05, 0x00, 0x04, 0x09, @@ -570,7 +577,7 @@ ti->mapped_ram_size = ti->avail_shared_ram; } else { #ifdef ENABLE_PAGING - unsigned char pg_size; + unsigned char pg_size=0; #endif #if !TR_NEWFORMAT @@ -590,15 +597,16 @@ pg_size=64; /* 32KB page size */ break; case 0xc: - ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0; - ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0; - DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n"); - /* nb/dwm: I did this because RRR (3,2) bits are documented as - R/O and I can't find how to select which page size - Also, the above conditional statement sequence is invalid - as page_mask will always be set by the second stmt */ - kfree_s(ti, sizeof(struct tok_info)); - return -ENODEV; + switch (ti->mapped_ram_size) { + case 32: + ti->page_mask=0xc0; + pg_size=32; + break; + case 64: + ti->page_mask=0x80; + pg_size=64; + break; + } break; default: DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging); @@ -606,16 +614,22 @@ return -ENODEV; break; } + + if (ibmtr_debug_trace & TRC_INIT) + DPRINTK("Shared RAM paging code: " + "%02X mapped RAM size: %dK shared RAM size: %dK page mask: %0xX\n:", + ti->shared_ram_paging, ti->mapped_ram_size/2, ti->avail_shared_ram/2, ti->page_mask); + if (ti->page_mask) { if (pg_size > ti->mapped_ram_size) { DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", - pg_size, ti->mapped_ram_size); + pg_size/2, ti->mapped_ram_size/2); ti->page_mask = 0; /* reset paging */ - } else { - ti->mapped_ram_size=ti->avail_shared_ram; - DPRINTK("Shared RAM paging enabled. Page size : %uK\n", - ((ti->page_mask^ 0xff)+1)>>2); - } + } + } else if (pg_size > ti->mapped_ram_size) { + DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n", + pg_size/2, ti->mapped_ram_size/2); + } #endif } /* finish figuring the shared RAM address */ @@ -673,9 +687,17 @@ DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n", dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + if (ti->page_mask) + DPRINTK("Shared RAM paging enabled. Page size: %uK Shared Ram size %dK\n", + ((ti->page_mask ^ 0xff)+1)>>2,ti->avail_shared_ram/2); + else + DPRINTK("Shared RAM paging disabled. ti->page_mask %x\n",ti->page_mask); #endif /* Calculate the maximum DHB we can use */ - switch (ti->mapped_ram_size) { + if (!ti->page_mask) { + ti->avail_shared_ram=ti->mapped_ram_size; + } + switch (ti->avail_shared_ram) { case 16 : /* 8KB shared RAM */ ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; @@ -685,34 +707,34 @@ ti->rbuf_cnt16 = 2; break; case 32 : /* 16KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 520; ti->rbuf_cnt4 = 9; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 4096); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; /* 1024 usable */ ti->rbuf_cnt16 = 4; break; case 64 : /* 32KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; ti->rbuf_cnt4 = 6; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 10240); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; ti->rbuf_cnt16 = 10; break; case 127 : /* 63KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; ti->rbuf_cnt4 = 6; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 16384); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; ti->rbuf_cnt16 = 16; break; case 128 : /* 64KB shared RAM */ - ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464); + ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048); ti->rbuf_len4 = 1032; ti->rbuf_cnt4 = 6; - ti->dhb_size16mb = MIN(ti->dhb_size16mb, 17960); + ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048); ti->rbuf_len16 = 1032; ti->rbuf_cnt16 = 18; break; @@ -764,6 +786,7 @@ { struct tok_info *ti=(struct tok_info *)dev->priv; + SET_PAGE(ti->srb_page); ti->open_status = CLOSED; dev->init = tok_init_card; @@ -802,7 +825,7 @@ address[3] |= mclist->dmi_addr[5]; mclist = mclist->next; } - SET_PAGE(ti->srb); + SET_PAGE(ti->srb_page); for (i=0; isrb+i); @@ -848,7 +871,7 @@ struct tok_info *ti=(struct tok_info *) dev->priv; netif_stop_queue(dev); - + SET_PAGE(ti->srb_page); isa_writeb(DIR_CLOSE_ADAPTER, ti->srb + offsetof(struct srb_close_adapter, command)); isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); @@ -857,6 +880,7 @@ sleep_on(&ti->wait_for_tok_int); + SET_PAGE(ti->srb_page); if (isa_readb(ti->srb + offsetof(struct srb_close_adapter, ret_code))) DPRINTK("close adapter failed: %02X\n", (int)isa_readb(ti->srb + offsetof(struct srb_close_adapter, ret_code))); @@ -875,6 +899,9 @@ unsigned char status; struct tok_info *ti; struct net_device *dev; +#ifdef ENABLE_PAGING + unsigned char save_srpr; +#endif dev = dev_id; #if TR_VERBOSE @@ -882,6 +909,9 @@ #endif ti = (struct tok_info *) dev->priv; spin_lock(&(ti->lock)); +#ifdef ENABLE_PAGING + save_srpr=isa_readb(ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN); +#endif /* Disable interrupts till processing is finished */ isa_writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); @@ -907,17 +937,15 @@ if (status == 0xFF) { DPRINTK("PCMCIA card removed.\n"); - spin_unlock(&(ti->lock)); - return; + goto return_point ; } /* Check ISRP EVEN too. */ if ( isa_readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) == 0xFF) { DPRINTK("PCMCIA card removed.\n"); - spin_unlock(&(ti->lock)); - return; - } + goto return_point ; + } #endif @@ -925,8 +953,15 @@ int i; __u32 check_reason; + __u8 check_reason_page=0; - check_reason=ti->mmio + ntohs(isa_readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN)); + check_reason=ntohs(isa_readw(ti->sram + ACA_OFFSET + ACA_RW +WWCR_EVEN)); + if (ti->page_mask) { + check_reason_page=(check_reason>>8) & ti->page_mask; + check_reason &= ~(ti->page_mask << 8); + } + check_reason += ti->sram; + SET_PAGE(check_reason_page); DPRINTK("Adapter check interrupt\n"); DPRINTK("8 reason bytes follow: "); @@ -951,6 +986,12 @@ /* SRB, ASB, ARB or SSB response */ if (status & SRB_RESP_INT) { /* SRB response */ + SET_PAGE(ti->srb_page); +#if TR_VERBOSE + DPRINTK("SRB resp: cmd=%02X rsp=%02X\n", + isa_readb(ti->srb), + isa_readb(ti->srb + offsetof(struct srb_xmit, ret_code))); +#endif switch(isa_readb(ti->srb)) { /* SRB command check */ @@ -962,7 +1003,7 @@ DPRINTK("error on xmit_dir_frame request: %02X\n", xmit_ret_code); if (ti->current_skb) { - dev_kfree_skb(ti->current_skb); + dev_kfree_skb_irq(ti->current_skb); ti->current_skb=NULL; } netif_wake_queue(dev); @@ -979,7 +1020,7 @@ DPRINTK("error on xmit_ui_frame request: %02X\n", xmit_ret_code); if (ti->current_skb) { - dev_kfree_skb(ti->current_skb); + dev_kfree_skb_irq(ti->current_skb); ti->current_skb=NULL; } netif_wake_queue(dev); @@ -993,10 +1034,25 @@ unsigned char open_ret_code; __u16 open_error_code; - ti->srb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr))); - ti->ssb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr))); - ti->arb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr))); - ti->asb=ti->sram+ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr))); + ti->srb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr))); + ti->ssb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr))); + ti->arb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr))); + ti->asb=ntohs(isa_readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr))); + if (ti->page_mask) { + ti->srb_page=(ti->srb>>8) & ti->page_mask; + ti->srb &= ~(ti->page_mask<<8); + ti->ssb_page=(ti->ssb>>8) & ti->page_mask; + ti->ssb &= ~(ti->page_mask<<8); + ti->arb_page=(ti->arb>>8) & ti->page_mask; + ti->arb &= ~(ti->page_mask<<8); + ti->asb_page=(ti->asb>>8) & ti->page_mask; + ti->asb &= ~(ti->page_mask<<8); + } + ti->srb+=ti->sram; + ti->ssb+=ti->sram; + ti->arb+=ti->sram; + ti->asb+=ti->sram; + ti->current_skb=NULL; open_ret_code = isa_readb(ti->init_srb +offsetof(struct srb_open_response, ret_code)); @@ -1125,6 +1181,10 @@ } /* SRB response */ if (status & ASB_FREE_INT) { /* ASB response */ + SET_PAGE(ti->asb_page); +#if TR_VERBOSE + DPRINTK("ASB resp: cmd=%02X\n", isa_readb(ti->asb)); + #endif switch(isa_readb(ti->asb)) { /* ASB command check */ @@ -1147,6 +1207,12 @@ } /* ASB response */ if (status & ARB_CMD_INT) { /* ARB response */ + SET_PAGE(ti->arb_page); +#if TR_VERBOSE + DPRINTK("ARB resp: cmd=%02X rsp=%02X\n", + isa_readb(ti->arb), + isa_readb(ti->arb + offsetof(struct arb_dlc_status, status))); +#endif switch (isa_readb(ti->arb)) { /* ARB command check */ @@ -1203,6 +1269,11 @@ if (status & SSB_RESP_INT) { /* SSB response */ unsigned char retcode; + SET_PAGE(ti->ssb_page); +#if TR_VERBOSE + DPRINTK("SSB resp: cmd=%02X rsp=%02X\n", + isa_readb(ti->ssb), isa_readb(ti->ssb+2)); +#endif switch (isa_readb(ti->ssb)) { /* SSB command check */ case XMIT_DIR_FRAME: @@ -1216,6 +1287,7 @@ case XMIT_XID_CMD: DPRINTK("xmit xid ret_code: %02X\n", (int)isa_readb(ti->ssb+2)); + break; default: DPRINTK("Unknown command %02X in ssb\n", (int)isa_readb(ti->ssb)); @@ -1240,6 +1312,13 @@ DPRINTK("Unexpected interrupt from tr adapter\n"); } +#ifdef PCMCIA + return_point: +#endif +#ifdef ENABLE_PAGING + isa_writeb(save_srpr, ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN); +#endif + spin_unlock(&(ti->lock)); } @@ -1262,9 +1341,26 @@ isa_writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN); ti->sram=((__u32)ti->sram_base << 12); } - ti->init_srb=ti->sram - +ntohs((unsigned short)isa_readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN)); - SET_PAGE(ntohs((unsigned short)isa_readw(ti->mmio+ACA_OFFSET + WRBR_EVEN))); + ti->init_srb=ntohs((unsigned short)isa_readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN)); + if (ti->page_mask) { + ti->init_srb_page=(ti->init_srb>>8)&ti->page_mask; + ti->init_srb &= ~(ti->page_mask<<8); + } + ti->init_srb+=ti->sram; + + if (ti->avail_shared_ram == 127) { + int i; + int last_512=0xfe00; + if (ti->page_mask) { + last_512 &= ~(ti->page_mask<<8); + } + /* initialize high section of ram (if necessary) */ + SET_PAGE(0xc0); + for (i=0; i<512; i++) { + isa_writeb(0,ti->sram+last_512+i); + } + } + SET_PAGE(ti->init_srb_page); dev->mem_start = ti->sram; dev->mem_end = ti->sram + (ti->mapped_ram_size<<9) - 1; @@ -1272,7 +1368,7 @@ #if TR_VERBOSE { int i; - DPRINTK("init_srb(%p):", ti->init_srb); + DPRINTK("init_srb(%lx):", (long)ti->init_srb); for (i=0;i<17;i++) printk("%02X ", (int)isa_readb(ti->init_srb+i)); printk("\n"); } @@ -1325,11 +1421,6 @@ /* Reset adapter */ netif_stop_queue(dev); -#ifdef ENABLE_PAGING - if(ti->page_mask) - isa_writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); -#endif - isa_writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); #if !TR_NEWFORMAT @@ -1339,6 +1430,10 @@ outb(0, PIOaddr+ADAPTRESET); for (i=jiffies+TR_RESET_INTERVAL; time_before_eq(jiffies, i);); /* wait 50ms */ outb(0,PIOaddr+ADAPTRESETREL); +#ifdef ENABLE_PAGING + if(ti->page_mask) + isa_writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN); +#endif #if !TR_NEWFORMAT DPRINTK("card reset\n"); @@ -1354,7 +1449,7 @@ int i; struct tok_info *ti=(struct tok_info *) dev->priv; - SET_PAGE(ti->srb); + SET_PAGE(ti->srb_page); for (i=0; isrb+i); @@ -1417,6 +1512,12 @@ ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta)); ti->srb=ti->init_srb; /* We use this one in the interrupt handler */ + ti->srb_page=ti->init_srb_page; + DPRINTK("Opend adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n", + isa_readb(ti->init_srb+offsetof(struct dir_open_adapter,num_dhb)), + ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,dhb_length))), + ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,num_rcv_buf))), + ntohs(isa_readw(ti->init_srb+offsetof(struct dir_open_adapter,rcv_buf_len))) ); isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); @@ -1432,7 +1533,11 @@ unsigned char xmit_command; int i; struct trllc *llc; + struct srb_xmit xsrb; + __u8 dhb_page=0; + __u8 llc_ssap; + SET_PAGE(ti->asb_page); if (isa_readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF) DPRINTK("ASB not free !!!\n"); @@ -1441,8 +1546,13 @@ providing a shared memory address for us to stuff with data. Here we compute the effective address where we will place data.*/ - dhb=ti->sram - +ntohs(isa_readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address))); + SET_PAGE(ti->arb_page); + dhb=ntohs(isa_readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address))); + if (ti->page_mask) { + dhb_page=(dhb >> 8) & ti->page_mask; + dhb &= ~(ti->page_mask << 8); + } + dhb+=ti->sram; /* Figure out the size of the 802.5 header */ if (!(trhdr->saddr[0] & 0x80)) /* RIF present? */ @@ -1453,13 +1563,17 @@ llc = (struct trllc *)(ti->current_skb->data + hdr_len); - xmit_command = isa_readb(ti->srb + offsetof(struct srb_xmit, command)); - + llc_ssap=llc->ssap; + SET_PAGE(ti->srb_page); + isa_memcpy_fromio(&xsrb, ti->srb, sizeof(xsrb)); + SET_PAGE(ti->asb_page); + xmit_command=xsrb.command; + isa_writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command)); - isa_writew(isa_readb(ti->srb + offsetof(struct srb_xmit, station_id)), + isa_writew(xsrb.station_id, ti->asb + offsetof(struct asb_xmit_resp, station_id)); - isa_writeb(llc->ssap, ti->asb + offsetof(struct asb_xmit_resp, rsap_value)); - isa_writeb(isa_readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)), + isa_writeb(llc_ssap, ti->asb + offsetof(struct asb_xmit_resp, rsap_value)); + isa_writeb(xsrb.cmd_corr, ti->asb + offsetof(struct asb_xmit_resp, cmd_corr)); isa_writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code)); @@ -1468,6 +1582,7 @@ isa_writew(htons(0x11), ti->asb + offsetof(struct asb_xmit_resp, frame_length)); isa_writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length)); + SET_PAGE(dhb_page); isa_writeb(AC, dhb); isa_writeb(LLC_FRAME, dhb+1); @@ -1487,11 +1602,12 @@ isa_writew(htons(ti->current_skb->len), ti->asb + offsetof(struct asb_xmit_resp, frame_length)); + SET_PAGE(dhb_page); isa_memcpy_toio(dhb, ti->current_skb->data, ti->current_skb->len); isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); ti->tr_stats.tx_bytes+=ti->current_skb->len; - dev_kfree_skb(ti->current_skb); + dev_kfree_skb_irq(ti->current_skb); ti->current_skb=NULL; netif_wake_queue(dev); if (ti->readlog_pending) ibmtr_readlog(dev); @@ -1501,6 +1617,7 @@ { struct tok_info *ti=(struct tok_info *) dev->priv; __u32 rbuffer, rbufdata; + __u8 rbuffer_page=0; __u32 llc; unsigned char *data; unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length; @@ -1509,31 +1626,40 @@ int IPv4_p = 0; unsigned int chksum = 0; struct iphdr *iph; + struct arb_rec_req rarb; - rbuffer=(ti->sram - +ntohs(isa_readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))))+2; - + SET_PAGE(ti->arb_page); + isa_memcpy_fromio(&rarb, ti->arb, sizeof(rarb)); + rbuffer=ntohs(rarb.rec_buf_addr)+2; + if (ti->page_mask) { + rbuffer_page=(rbuffer >> 8) & ti->page_mask; + rbuffer &= ~(ti->page_mask<<8); + } + rbuffer += ti->sram; + + SET_PAGE(ti->asb_page); if(isa_readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF) DPRINTK("ASB not free !!!\n"); isa_writeb(REC_DATA, ti->asb + offsetof(struct asb_rec, command)); - isa_writew(isa_readw(ti->arb + offsetof(struct arb_rec_req, station_id)), + isa_writew(rarb.station_id, ti->asb + offsetof(struct asb_rec, station_id)); - isa_writew(isa_readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)), + isa_writew(rarb.rec_buf_addr, ti->asb + offsetof(struct asb_rec, rec_buf_addr)); - lan_hdr_len=isa_readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len)); + lan_hdr_len=rarb.lan_hdr_len; hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr); - + + SET_PAGE(rbuffer_page); llc=(rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len); #if TR_VERBOSE DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n", (unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len); - DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc, - ntohs(isa_readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))), - ti->sram); + DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %lx\n", llc, + ntohs(rarb.rec_buf_addr), + (long)ti->sram); DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, " "ethertype: %04X\n", (int)isa_readb(llc + offsetof(struct trllc, dsap)), @@ -1545,14 +1671,15 @@ (int)isa_readw(llc + offsetof(struct trllc, ethertype))); #endif if (isa_readb(llc + offsetof(struct trllc, llc))!=UI_CMD) { + SET_PAGE(ti->asb_page); isa_writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); ti->tr_stats.rx_dropped++; isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); return; } - length = ntohs(isa_readw(ti->arb+offsetof(struct arb_rec_req, frame_len))); - if ((isa_readb(llc + offsetof(struct trllc, dsap))==EXTENDED_SAP) && + length = ntohs(rarb.frame_len); + if ((isa_readb(llc + offsetof(struct trllc, dsap))==EXTENDED_SAP) && (isa_readb(llc + offsetof(struct trllc, ssap))==EXTENDED_SAP) && (length>=hdr_len)) { IPv4_p = 1; @@ -1585,11 +1712,12 @@ } #endif - skb_size = length-lan_hdr_len+sizeof(struct trh_hdr)+sizeof(struct trllc); + skb_size = length; if (!(skb=dev_alloc_skb(skb_size))) { DPRINTK("out of memory. frame dropped.\n"); ti->tr_stats.rx_dropped++; + SET_PAGE(ti->asb_page); isa_writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code)); isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); return; @@ -1630,11 +1758,17 @@ break; length -= rbuffer_len; data += rbuffer_len; + if (ti->page_mask) { + rbuffer_page=(rbuffer>>8) & ti->page_mask; + rbuffer &= ~(ti->page_mask << 8); + } rbuffer += ti->sram; + SET_PAGE(rbuffer_page); rbuffer_len = ntohs(isa_readw(rbuffer + offsetof(struct rec_buf, buf_len))); rbufdata = rbuffer + offsetof(struct rec_buf, data); } + SET_PAGE(ti->asb_page); isa_writeb(0, ti->asb + offsetof(struct asb_rec, ret_code)); isa_writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); @@ -1663,6 +1797,7 @@ /* Save skb; we'll need it when the adapter asks for the data */ ti->current_skb=skb; + SET_PAGE(ti->srb_page); isa_writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command)); isa_writew(ti->exsap_station_id, ti->srb +offsetof(struct srb_xmit, station_id)); @@ -1685,6 +1820,7 @@ ti=(struct tok_info *) dev->priv; ti->readlog_pending = 0; + SET_PAGE(ti->srb_page); isa_writeb(DIR_READ_LOG, ti->srb); isa_writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); isa_writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); diff -u --recursive --new-file v2.3.48/linux/drivers/net/tokenring/ibmtr.h linux/drivers/net/tokenring/ibmtr.h --- v2.3.48/linux/drivers/net/tokenring/ibmtr.h Tue Dec 14 01:27:24 1999 +++ linux/drivers/net/tokenring/ibmtr.h Thu Mar 2 10:15:30 2000 @@ -133,9 +133,9 @@ #define TCR_ODD 0x0D #define TVR_EVEN 0x0E /* Timer value registers - even and odd */ #define TVR_ODD 0x0F -#define SRPR_EVEN 0x10 /* Shared RAM paging registers - even and odd */ +#define SRPR_EVEN 0x18 /* Shared RAM paging registers - even and odd */ #define SRPR_ENABLE_PAGING 0xc0 -#define SRPR_ODD 0x11 /* Not used. */ +#define SRPR_ODD 0x19 /* Not used. */ #define TOKREAD 0x60 #define TOKOR 0x40 #define TOKAND 0x20 @@ -162,7 +162,7 @@ #define ACA_RW 0x00 #ifdef ENABLE_PAGING -#define SET_PAGE(x) (isa_writeb(((x>>8)&ti.page_mask), \ +#define SET_PAGE(x) (isa_writeb((x), \ ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)) #else #define SET_PAGE(x) @@ -205,6 +205,11 @@ __u32 ssb; /* System Status Block address */ __u32 arb; /* Adapter Request Block address */ __u32 asb; /* Adapter Status Block address */ + __u8 init_srb_page; + __u8 srb_page; + __u8 ssb_page; + __u8 arb_page; + __u8 asb_page; unsigned short exsap_station_id; unsigned short global_int_enable; struct sk_buff *current_skb; diff -u --recursive --new-file v2.3.48/linux/drivers/net/tulip/eeprom.c linux/drivers/net/tulip/eeprom.c --- v2.3.48/linux/drivers/net/tulip/eeprom.c Sat Feb 26 22:31:47 2000 +++ linux/drivers/net/tulip/eeprom.c Mon Feb 28 07:16:55 2000 @@ -56,6 +56,12 @@ 0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */ 0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */ }}, + {"NetWinder", 0x00, 0x10, 0x57, + /* Default media = MII + * MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1 + */ + { 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 } + }, {0, 0, 0, 0, {}}}; diff -u --recursive --new-file v2.3.48/linux/drivers/net/tulip/tulip.h linux/drivers/net/tulip/tulip.h --- v2.3.48/linux/drivers/net/tulip/tulip.h Sat Feb 26 22:31:47 2000 +++ linux/drivers/net/tulip/tulip.h Mon Feb 28 07:16:55 2000 @@ -50,7 +50,6 @@ DC21140 = 2, DC21142 = 3, DC21143 = 3, LC82C168, - NGMC169, MX98713, MX98715, MX98725, @@ -242,8 +241,10 @@ struct tulip_private { const char *product_name; struct net_device *next_module; - struct tulip_rx_desc rx_ring[RX_RING_SIZE]; - struct tulip_tx_desc tx_ring[TX_RING_SIZE]; + struct tulip_rx_desc *rx_ring; + struct tulip_tx_desc *tx_ring; + dma_addr_t rx_ring_dma; + dma_addr_t tx_ring_dma; /* The saved address of a sent-in-place packet/buffer, for skfree(). */ struct sk_buff *tx_skbuff[TX_RING_SIZE]; /* The addresses of receive-in-place skbuffs. */ diff -u --recursive --new-file v2.3.48/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c --- v2.3.48/linux/drivers/net/tulip/tulip_core.c Sat Feb 26 22:31:47 2000 +++ linux/drivers/net/tulip/tulip_core.c Mon Feb 28 07:16:55 2000 @@ -19,7 +19,7 @@ */ -static const char version[] = "Linux Tulip driver version 0.9.3 (Feb 23, 2000)\n"; +static const char version[] = "Linux Tulip driver version 0.9.4 (Feb 28, 2000)\n"; #include #include "tulip.h" @@ -51,7 +51,7 @@ }; /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */ -#ifdef __alpha__ +#if defined(__alpha__) || defined(__arm__) static int rx_copybreak = 1518; #else static int rx_copybreak = 100; @@ -74,6 +74,8 @@ static int csr0 = 0x01A00000 | 0xE000; #elif defined(__i386__) || defined(__powerpc__) || defined(__sparc__) static int csr0 = 0x01A00000 | 0x8000; +#elif defined(__arm__) +static int csr0 = 0x01A00000 | 0x4800; #else #warning Processor architecture undefined! static int csr0 = 0x00A00000 | 0x4800; @@ -123,8 +125,6 @@ t21142_timer }, { "Lite-On 82c168 PNIC", 256, 0x0001ebef, HAS_MII | HAS_PNICNWAY, pnic_timer }, - { "NETGEAR NGMC169 MAC", 256, 0x0001ebef, - HAS_MII | HAS_PNICNWAY, pnic_timer }, { "Macronix 98713 PMAC", 128, 0x0001ebef, HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer }, { "Macronix 98715 PMAC", 256, 0x0001ebef, @@ -155,7 +155,6 @@ { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 }, { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 }, { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 }, - { 0x1385, 0xf004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NGMC169 }, { 0x10d9, 0x0512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98713 }, { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x10d9, 0x0531, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98725 }, @@ -301,8 +300,8 @@ tp->cur_tx++; } - outl(virt_to_bus(tp->rx_ring), ioaddr + CSR3); - outl(virt_to_bus(tp->tx_ring), ioaddr + CSR4); + outl(tp->rx_ring_dma, ioaddr + CSR3); + outl(tp->tx_ring_dma, ioaddr + CSR4); tp->saved_if_port = dev->if_port; if (dev->if_port == 0) @@ -569,12 +568,12 @@ for (i = 0; i < RX_RING_SIZE; i++) { tp->rx_ring[i].status = 0x00000000; tp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ); - tp->rx_ring[i].buffer2 = virt_to_le32desc(&tp->rx_ring[i+1]); + tp->rx_ring[i].buffer2 = cpu_to_le32(tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * (i + 1)); tp->rx_skbuff[i] = NULL; } /* Mark the last entry as wrapping the ring. */ tp->rx_ring[i-1].length = cpu_to_le32(PKT_BUF_SZ | DESC_RING_WRAP); - tp->rx_ring[i-1].buffer2 = virt_to_le32desc(&tp->rx_ring[0]); + tp->rx_ring[i-1].buffer2 = cpu_to_le32(tp->rx_ring_dma); for (i = 0; i < RX_RING_SIZE; i++) { /* Note the receive buffer must be longword aligned. @@ -595,9 +594,9 @@ for (i = 0; i < TX_RING_SIZE; i++) { tp->tx_skbuff[i] = 0; tp->tx_ring[i].status = 0x00000000; - tp->tx_ring[i].buffer2 = virt_to_le32desc(&tp->tx_ring[i+1]); + tp->tx_ring[i].buffer2 = cpu_to_le32(tp->tx_ring_dma + sizeof(struct tulip_tx_desc) * (i + 1)); } - tp->tx_ring[i-1].buffer2 = virt_to_le32desc(&tp->tx_ring[0]); + tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma); } static int @@ -1033,6 +1032,13 @@ */ tp = dev->priv; + tp->rx_ring = pci_alloc_consistent(pdev, + sizeof(struct tulip_rx_desc) * RX_RING_SIZE + + sizeof(struct tulip_tx_desc) * TX_RING_SIZE, + &tp->rx_ring_dma); + tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE); + tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE; + tp->chip_id = chip_idx; tp->flags = tulip_tbl[chip_idx].flags; tp->pdev = pdev; @@ -1352,6 +1358,11 @@ if (dev) { struct tulip_private *tp = (struct tulip_private *)dev->priv; + pci_free_consistent(pdev, + sizeof(struct tulip_rx_desc) * RX_RING_SIZE + + sizeof(struct tulip_tx_desc) * TX_RING_SIZE, + tp->rx_ring, + tp->rx_ring_dma); unregister_netdev(dev); release_region(dev->base_addr, tulip_tbl[tp->chip_id].io_size); diff -u --recursive --new-file v2.3.48/linux/drivers/net/wan/sdla.c linux/drivers/net/wan/sdla.c --- v2.3.48/linux/drivers/net/wan/sdla.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/net/wan/sdla.c Mon Feb 28 07:16:54 2000 @@ -565,7 +565,7 @@ flp->dlci[i] = -*(short *)(master->dev_addr); master->mtu = slave->mtu; - if (netif_running(dev)) { + if (netif_running(slave)) { if (flp->config.station == FRAD_STATION_CPE) sdla_reconfig(slave); else diff -u --recursive --new-file v2.3.48/linux/drivers/net/wan/sdla_chdlc.c linux/drivers/net/wan/sdla_chdlc.c --- v2.3.48/linux/drivers/net/wan/sdla_chdlc.c Sun Feb 13 19:29:04 2000 +++ linux/drivers/net/wan/sdla_chdlc.c Mon Feb 28 07:16:54 2000 @@ -11,6 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* Feb 28, 2000 Jeff Garzik softnet updates * Nov 20, 1999 Nenad Corbic Fixed zero length API bug. * Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup. * Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing @@ -64,6 +65,7 @@ #define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" ) +#define TX_TIMEOUT (5*HZ) /******Data Structures*****************************************************/ @@ -130,6 +132,7 @@ static int if_init (struct net_device* dev); static int if_open (struct net_device* dev); static int if_close (struct net_device* dev); +static void if_tx_timeout (struct net_device *dev); static int if_header (struct sk_buff* skb, struct net_device* dev, unsigned short type, void* daddr, void* saddr, unsigned len); #ifdef LINUX_2_1 @@ -441,7 +444,7 @@ if(test_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; - if(!dev->start) + if(!netif_running(dev)) return -ENODEV; flags = card->u.c.flags; @@ -652,6 +655,8 @@ dev->rebuild_header = &if_rebuild_hdr; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; /* Initialize media-specific parameters */ dev->flags |= IFF_POINTTOPOINT; @@ -709,7 +714,7 @@ /* Only one open per interface is allowed */ - if(dev->start) + if(netif_running(dev)) return -EBUSY; if(test_and_set_bit(1, (void*)&card->wandev.critical)) { @@ -774,9 +779,7 @@ do_gettimeofday(&tv); chdlc_priv_area->router_start_time = tv.tv_sec; - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); dev->flags |= IFF_POINTTOPOINT; wanpipe_open(card); @@ -796,7 +799,7 @@ if(test_and_set_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; - dev->start = 0; + netif_stop_queue(dev); wanpipe_close(card); port_set_state(card, WAN_DISCONNECTED); chdlc_set_intr_mode(card, 0); @@ -843,6 +846,30 @@ } #endif + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout (struct net_device *dev) +{ + chdlc_private_area_t *chdlc_priv_area = dev->priv; + sdla_t *card = chdlc_priv_area->card; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + ++card->wandev.stats.collisions; + + printk (KERN_INFO "%s: Transmit timeout !\n", + card->devname); + + /* unbusy the interface */ + netif_start_queue (dev); +} + + /*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based @@ -875,30 +902,10 @@ */ printk(KERN_INFO "%s: interface %s got kicked!\n", card->devname, dev->name); - mark_bh(NET_BH); + netif_wake_queue(dev); return 0; } - if(dev->tbusy) { - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - ++card->wandev.stats.collisions; - - if((jiffies - chdlc_priv_area->tick_counter) < (5 * HZ)) { - return 1; - } - - printk (KERN_INFO "%s: Transmit timeout !\n", - card->devname); - - /* unbusy the interface */ - dev->tbusy = 0; - } - if(ntohs(skb->protocol) != 0x16) { /* check the udp packet type */ @@ -977,31 +984,24 @@ } if(chdlc_send(card, data, len)) { - dev->tbusy = 1; + netif_stop_queue(dev); chdlc_priv_area->tick_counter = jiffies; chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME; } else { ++card->wandev.stats.tx_packets; -#ifdef LINUX_2_1 card->wandev.stats.tx_bytes += len; -#endif } } - if (!dev->tbusy) { -#ifdef LINUX_2_1 + if (!netif_queue_stopped(dev)) dev_kfree_skb(skb); -#else - dev_kfree_skb(skb, FREE_WRITE); -#endif - } clear_bit(0, (void*)&card->wandev.critical); if(card->hw.type != SDLA_S514){ s508_unlock(card,&smp_flags); } - return dev->tbusy; + return netif_queue_stopped(dev); } @@ -1521,8 +1521,7 @@ ~APP_INT_ON_TX_FRAME; chdlc_priv_area = dev->priv; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue(dev); break; case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */ @@ -1606,7 +1605,7 @@ dev = card->wandev.dev; chdlc_priv_area = dev->priv; - if(dev && dev->start) { + if(dev && netif_running(dev)) { len = rxbuf->frame_length; diff -u --recursive --new-file v2.3.48/linux/drivers/net/wan/sdla_fr.c linux/drivers/net/wan/sdla_fr.c --- v2.3.48/linux/drivers/net/wan/sdla_fr.c Sun Feb 13 19:29:04 2000 +++ linux/drivers/net/wan/sdla_fr.c Mon Feb 28 07:16:55 2000 @@ -11,6 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * ============================================================================ +* Feb 28, 2000 Jeff Garzik o softnet updates * Nov 08, 1999 Nenad Corbic o Combined all debug UDP calls into one function * o Removed the ARP support. This has to be done * in the next version. @@ -108,7 +109,6 @@ * Jan 02, 1997 Gene Kozin Initial version. *****************************************************************************/ -#include #include /* printk(), and other useful stuff */ #include /* offsetof(), etc. */ #include /* return codes */ @@ -129,9 +129,6 @@ #include #include /* frame relay firmware API definitions */ -#if LINUX_VERSION_CODE < 0x020125 -#define test_and_set_bit set_bit -#endif /****** Defines & Macros ****************************************************/ @@ -157,6 +154,8 @@ #define API 0x01 #define FRAME_RELAY_API 1 +#define TX_TIMEOUT (5*HZ) + /* For handle_IPXWAN() */ #define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b))) @@ -273,6 +272,7 @@ static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); static int if_send(struct sk_buff *skb, struct net_device *dev); +static void if_tx_timeout (struct net_device *dev); static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev, struct sk_buff *skb); static struct net_device_stats *if_stats(struct net_device *dev); @@ -939,6 +939,8 @@ dev->rebuild_header = &if_rebuild_hdr; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; /* Initialize media-specific parameters */ dev->type = ARPHRD_DLCI; /* ARP h/w type */ @@ -993,7 +995,7 @@ int err = 0; struct timeval tv; - if (dev->start) + if (netif_running(dev)) return -EBUSY; /* only one open is allowed */ if (test_and_set_bit(1, (void*)&card->wandev.critical)) @@ -1034,9 +1036,7 @@ fr_activate_dlci(card, chan->dlci); } - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); wanpipe_open(card); update_chan_state(dev); do_gettimeofday( &tv ); @@ -1058,7 +1058,7 @@ if (test_and_set_bit(1, (void*)&card->wandev.critical)) return -EAGAIN; - dev->start = 0; + netif_stop_queue(dev); wanpipe_close(card); if (card->wandev.station == WANOPT_NODE) { fr_delete_dlci (card,chan->dlci); @@ -1113,6 +1113,30 @@ return 1; } + +/*============================================================================ + * Handle transmit timeout event from netif watchdog + */ +static void if_tx_timeout (struct net_device *dev) +{ + fr_channel_t* chan = dev->priv; + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + chan->drvstats_if_send.if_send_tbusy++; + ++chan->ifstats.collisions; + + printk (KERN_INFO "%s: Transmit timed out\n", chan->name); + chan->drvstats_if_send.if_send_tbusy_timeout++; + netif_start_queue (dev); + +} + + /*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based @@ -1153,7 +1177,7 @@ printk(KERN_INFO "%s: interface %s got kicked!\n", card->devname, dev->name); chan->drvstats_if_send.if_send_skb_null ++; - mark_bh(NET_BH); + netif_wake_queue(dev); return 0; } @@ -1164,33 +1188,13 @@ */ set_bit(2, (void*)&card->wandev.critical); if(chan->transmit_length) { - dev->tbusy = 1; + netif_stop_queue(dev); chan->tick_counter = jiffies; clear_bit(2, (void*)&card->wandev.critical); return 1; } clear_bit(2, (void*)&card->wandev.critical); - if (dev->tbusy) { - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - - chan->drvstats_if_send.if_send_tbusy++; - ++chan->ifstats.collisions; - - if ((jiffies - chan->tick_counter) < (5 * HZ)) { - return 1; - } - - printk(KERN_INFO "%s: Transmit timed out\n", chan->name); - chan->drvstats_if_send.if_send_tbusy_timeout ++; - dev->tbusy = 0; - } - data = skb->data; sendpacket = skb->data; len = skb->len; @@ -1318,15 +1322,14 @@ } } - if (!dev->tbusy) { + if (!netif_queue_stopped(dev)) dev_kfree_skb(skb); - } clear_bit(0, (void*)&card->wandev.critical); s508_s514_unlock(card,&smp_flags); - return (dev->tbusy); + return (netif_queue_stopped(dev)); } @@ -1743,10 +1746,10 @@ skb = dev_alloc_skb(len); - if (!dev->start || (skb == NULL)) { + if (!netif_running(dev) || (skb == NULL)) { ++chan->ifstats.rx_dropped; - if(dev->start) { + if(netif_running(dev)) { printk(KERN_INFO "%s: no socket buffers available!\n", @@ -1920,8 +1923,7 @@ if(!(-- card->u.f.tx_interrupts_pending)) flags->imask &= ~FR_INTR_TXRDY; - dev->tbusy = 0; - mark_bh(NET_BH); + netif_wake_queue (dev); } } @@ -2704,7 +2706,7 @@ "%s: DLCI %u is inactive!\n", card->devname, dlci); - if (dev && dev->start) + if (dev && netif_running(dev)) set_chan_state(dev, WAN_DISCONNECTED); } @@ -2714,7 +2716,7 @@ "%s: DLCI %u has been deleted!\n", card->devname, dlci); - if (dev && dev->start) { + if (dev && netif_running(dev)) { fr_channel_t *chan = dev->priv; if (chan->route_flag == ROUTE_ADDED) { @@ -2738,7 +2740,7 @@ */ chan->dlci_configured = DLCI_CONFIG_PENDING; - if (dev && dev->start) + if (dev && netif_running(dev)) set_chan_state(dev, WAN_CONNECTED); } @@ -3004,7 +3006,7 @@ test_bit(2, (void*)&card->wandev.critical)) { return 0; } - if((dev->tbusy) || (card->u.f.tx_interrupts_pending)) { + if((netif_queue_stopped(dev)) || (card->u.f.tx_interrupts_pending)) { return 0; } } diff -u --recursive --new-file v2.3.48/linux/drivers/net/wan/sdla_ppp.c linux/drivers/net/wan/sdla_ppp.c --- v2.3.48/linux/drivers/net/wan/sdla_ppp.c Sun Feb 13 19:29:04 2000 +++ linux/drivers/net/wan/sdla_ppp.c Mon Feb 28 07:16:55 2000 @@ -142,9 +142,8 @@ #define NUM_AUTH_REQ_WITHOUT_REPLY 10 #define END_OFFSET 0x1F0 -#if LINUX_VERSION_CODE < 0x020125 -#define test_and_set_bit set_bit -#endif + +#define TX_TIMEOUT (5*HZ) /******Data Structures*****************************************************/ @@ -213,6 +212,7 @@ static int if_init(struct net_device *dev); static int if_open(struct net_device *dev); static int if_close(struct net_device *dev); +static void if_tx_timeout (struct net_device *dev); static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); static int if_rebuild_hdr(struct sk_buff *skb); @@ -585,7 +585,8 @@ dev->rebuild_header = &if_rebuild_hdr; dev->hard_start_xmit = &if_send; dev->get_stats = &if_stats; - + dev->tx_timeout = &if_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; /* Initialize media-specific parameters */ dev->type = ARPHRD_PPP; /* ARP h/w type */ @@ -632,7 +633,7 @@ struct timeval tv; int err = 0; - if (dev->start) + if (netif_running(dev)) return -EBUSY; /* only one open is allowed */ if (test_and_set_bit(0, (void*)&card->wandev.critical)) @@ -714,13 +715,10 @@ return err; } - wanpipe_set_state(card, WAN_CONNECTING); wanpipe_open(card); dev->mtu = min(dev->mtu, card->wandev.mtu); - dev->interrupt = 0; - dev->tbusy = 0; - dev->start = 1; + netif_start_queue(dev); do_gettimeofday( &tv ); ppp_priv_area->router_start_time = tv.tv_sec; card->wandev.critical = 0; @@ -741,7 +739,7 @@ if (test_and_set_bit(0, (void*)&card->wandev.critical)) return -EAGAIN; - dev->start = 0; + netif_stop_queue(dev); wanpipe_close(card); wanpipe_set_state(card, WAN_DISCONNECTED); ppp_set_intr_mode(card, 0); @@ -795,6 +793,35 @@ return 1; } + +/*============================================================================ + * Handle transmit timeout from netif watchdog + */ +static void if_tx_timeout (struct net_device *dev) +{ + ppp_private_area_t *ppp_priv_area = dev->priv; + sdla_t *card = ppp_priv_area->card; + + + /* If our device stays busy for at least 5 seconds then we will + * kick start the device by making dev->tbusy = 0. We expect + * that our device never stays busy more than 5 seconds. So this + * is only used as a last resort. + */ + + ++ppp_priv_area->if_send_stat.if_send_tbusy; + ++card->wandev.stats.collisions; + + printk (KERN_INFO "%s: Transmit times out\n", card->devname); + + ++ppp_priv_area->if_send_stat.if_send_tbusy_timeout; + ++card->wandev.stats.collisions; + + /* unbusy the card (because only one interface per card) */ + netif_start_queue(dev); +} + + /*============================================================================ * Send a packet on a network interface. * o set tbusy flag (marks start of the transmission) to block a timer-based @@ -835,34 +862,11 @@ ++ppp_priv_area->if_send_stat.if_send_skb_null; - mark_bh(NET_BH); + netif_wake_queue(dev); return 0; } - if (dev->tbusy) { - - /* If our device stays busy for at least 5 seconds then we will - * kick start the device by making dev->tbusy = 0. We expect - * that our device never stays busy more than 5 seconds. So this - * is only used as a last resort. - */ - - ++ppp_priv_area->if_send_stat.if_send_tbusy; - ++card->wandev.stats.collisions; - - if ((jiffies - ppp_priv_area->tick_counter) < (5*HZ)) { - return 1; - } - - printk (KERN_INFO "%s: Transmit times out\n",card->devname); - - ++ppp_priv_area->if_send_stat.if_send_tbusy_timeout; - ++card->wandev.stats.collisions; - - /* unbusy the card (because only one interface per card)*/ - dev->tbusy = 0; - } sendpacket = skb->data; udp_type = udp_pkt_type( skb, card ); @@ -930,7 +934,7 @@ if (ppp_send(card, skb->data, skb->len, skb->protocol)) { retry = 1; - dev->tbusy = 1; + netif_stop_queue(dev); ++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full; ++ppp_priv_area->if_send_stat.if_send_tx_int_enabled; ppp_priv_area->tick_counter = jiffies; @@ -1530,7 +1534,7 @@ case PPP_INTR_TXRDY: /* transmit interrupt 0x02 (bit 1)*/ ++card->statistics.isr_tx; flags->imask &= ~PPP_INTR_TXRDY; - dev->tbusy = 0; + netif_wake_queue (dev); card->buff_int_mode_unbusy = 1; break; @@ -1564,9 +1568,8 @@ flags->iflag = 0; card->wandev.critical = 0; - if(card->buff_int_mode_unbusy) { - mark_bh(NET_BH); - } + if(card->buff_int_mode_unbusy) + netif_wake_queue(dev); } /*============================================================================ @@ -1603,7 +1606,7 @@ } - if (dev && dev->start) { + if (dev && netif_running(dev)) { len = rxbuf->length; ppp_priv_area = dev->priv; @@ -2006,7 +2009,7 @@ { struct net_device *dev = card->wandev.dev; - if (dev && dev->start && + if (dev && netif_running(dev) && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { wanpipe_set_state(card, WAN_CONNECTING); diff -u --recursive --new-file v2.3.48/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c --- v2.3.48/linux/drivers/net/wavelan.c Sat Feb 26 22:31:47 2000 +++ linux/drivers/net/wavelan.c Mon Feb 28 07:18:20 2000 @@ -3726,7 +3726,7 @@ } /* Release spinlock here so that wv_hw_reset() can grab it */ - spin_unlock (&lp->lock); + spin_unlock (&lp->spinlock); /* Check the state of the command unit. */ if (((status & SCB_ST_CNA) == SCB_ST_CNA) || @@ -4006,7 +4006,7 @@ lp->mc_count = 0; /* Init spinlock */ - spin_lock_init(&lp->lock); + spin_lock_init(&lp->spinlock); /* * Fill in the fields of the device structure diff -u --recursive --new-file v2.3.48/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c --- v2.3.48/linux/drivers/net/yellowfin.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/net/yellowfin.c Tue Feb 29 11:09:10 2000 @@ -103,6 +103,22 @@ #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) +#ifdef USE_IO_OPS +#define YF_INB inb +#define YF_INW inw +#define YF_INL inl +#define YF_OUTB outb +#define YF_OUTW outw +#define YF_OUTL outl +#else +#define YF_INB readb +#define YF_INW readw +#define YF_INL readl +#define YF_OUTB writeb +#define YF_OUTW writew +#define YF_OUTL writel +#endif + /* Theory of Operation @@ -357,11 +373,11 @@ { int bogus_cnt = 10000; /* Typical 33Mhz: 1050 ticks */ - outb(location, ioaddr + EEAddr); - outb(0x30 | ((location >> 8) & 7), ioaddr + EECtrl); - while ((inb(ioaddr + EEStatus) & 0x80) && --bogus_cnt > 0) + YF_OUTB(location, ioaddr + EEAddr); + YF_OUTB(0x30 | ((location >> 8) & 7), ioaddr + EECtrl); + while ((YF_INB(ioaddr + EEStatus) & 0x80) && --bogus_cnt > 0) ; - return inb(ioaddr + EERead); + return YF_INB(ioaddr + EERead); } /* MII Managemen Data I/O accesses. @@ -372,24 +388,24 @@ { int i; - outw((phy_id<<8) + location, ioaddr + MII_Addr); - outw(1, ioaddr + MII_Cmd); + YF_OUTW((phy_id<<8) + location, ioaddr + MII_Addr); + YF_OUTW(1, ioaddr + MII_Cmd); for (i = 10000; i >= 0; i--) - if ((inw(ioaddr + MII_Status) & 1) == 0) + if ((YF_INW(ioaddr + MII_Status) & 1) == 0) break; - return inw(ioaddr + MII_Rd_Data); + return YF_INW(ioaddr + MII_Rd_Data); } static void mdio_write(long ioaddr, int phy_id, int location, int value) { int i; - outw((phy_id<<8) + location, ioaddr + MII_Addr); - outw(value, ioaddr + MII_Wr_Data); + YF_OUTW((phy_id<<8) + location, ioaddr + MII_Addr); + YF_OUTW(value, ioaddr + MII_Wr_Data); /* Wait for the command to finish. */ for (i = 10000; i >= 0; i--) - if ((inw(ioaddr + MII_Status) & 1) == 0) + if ((YF_INW(ioaddr + MII_Status) & 1) == 0) break; return; } @@ -402,7 +418,7 @@ int i; /* Reset the chip. */ - outl(0x80000000, ioaddr + DMACtrl); + YF_OUTL(0x80000000, ioaddr + DMACtrl); if (request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, dev->name, dev)) return -EAGAIN; @@ -415,30 +431,30 @@ yellowfin_init_ring(dev); - outl(virt_to_bus(yp->rx_ring), ioaddr + RxPtr); - outl(virt_to_bus(yp->tx_ring), ioaddr + TxPtr); + YF_OUTL(virt_to_bus(yp->rx_ring), ioaddr + RxPtr); + YF_OUTL(virt_to_bus(yp->tx_ring), ioaddr + TxPtr); for (i = 0; i < 6; i++) - outb(dev->dev_addr[i], ioaddr + StnAddr + i); + YF_OUTB(dev->dev_addr[i], ioaddr + StnAddr + i); /* Set up various condition 'select' registers. There are no options here. */ - outl(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */ - outl(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */ - outl(0x00400040, ioaddr + TxWaitSel); /* Wait on Tx status */ - outl(0x00400040, ioaddr + RxIntrSel); /* Interrupt on Rx done */ - outl(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */ - outl(0x00400040, ioaddr + RxWaitSel); /* Wait on Rx done */ + YF_OUTL(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */ + YF_OUTL(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */ + YF_OUTL(0x00400040, ioaddr + TxWaitSel); /* Wait on Tx status */ + YF_OUTL(0x00400040, ioaddr + RxIntrSel); /* Interrupt on Rx done */ + YF_OUTL(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */ + YF_OUTL(0x00400040, ioaddr + RxWaitSel); /* Wait on Rx done */ /* Initialize other registers: with so many this eventually this will converted to an offset/value list. */ - outl(dma_ctrl, ioaddr + DMACtrl); - outw(fifo_cfg, ioaddr + FIFOcfg); + YF_OUTL(dma_ctrl, ioaddr + DMACtrl); + YF_OUTW(fifo_cfg, ioaddr + FIFOcfg); /* Enable automatic generation of flow control frames, period 0xffff. */ - outl(0x0030FFFF, ioaddr + FlowCtrl); + YF_OUTL(0x0030FFFF, ioaddr + FlowCtrl); yp->tx_threshold = 32; - outl(yp->tx_threshold, ioaddr + TxThreshold); + YF_OUTL(yp->tx_threshold, ioaddr + TxThreshold); if (dev->if_port == 0) dev->if_port = yp->default_port; @@ -449,19 +465,19 @@ if (yp->flags & IsGigabit) { /* We are always in full-duplex mode with gigabit! */ yp->full_duplex = 1; - outw(0x01CF, ioaddr + Cnfg); + YF_OUTW(0x01CF, ioaddr + Cnfg); } else { - outw(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */ - outw(0x1018, ioaddr + FrameGap1); - outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); + YF_OUTW(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */ + YF_OUTW(0x1018, ioaddr + FrameGap1); + YF_OUTW(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); } set_rx_mode(dev); /* Enable interrupts by setting the interrupt mask. */ - outw(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */ - outw(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */ - outl(0x80008000, ioaddr + RxCtrl); /* Start Rx and Tx channels. */ - outl(0x80008000, ioaddr + TxCtrl); + YF_OUTW(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */ + YF_OUTW(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */ + YF_OUTL(0x80008000, ioaddr + RxCtrl); /* Start Rx and Tx channels. */ + YF_OUTL(0x80008000, ioaddr + TxCtrl); if (yellowfin_debug > 2) { printk(KERN_DEBUG "%s: Done yellowfin_open().\n", @@ -486,7 +502,7 @@ if (yellowfin_debug > 3) { printk(KERN_DEBUG "%s: Yellowfin timer tick, status %8.8x.\n", - dev->name, inw(ioaddr + IntrStatus)); + dev->name, YF_INW(ioaddr + IntrStatus)); } if (yp->mii_cnt) { @@ -503,7 +519,7 @@ || (negotiated & 0x00C0) == 0x0040)) { yp->full_duplex = 1; } - outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); + YF_OUTW(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg); if (mii_reg1 & 0x0004) next_tick = 60*HZ; @@ -523,7 +539,7 @@ printk(KERN_WARNING "%s: Yellowfin transmit timed out at %d/%d Tx " "status %4.4x, Rx status %4.4x, resetting...\n", dev->name, yp->cur_tx, yp->dirty_tx, - inl(ioaddr + TxStatus), inl(ioaddr + RxStatus)); + YF_INL(ioaddr + TxStatus), YF_INL(ioaddr + RxStatus)); /* Note: these should be KERN_DEBUG. */ if (yellowfin_debug) { @@ -543,7 +559,7 @@ dev->if_port = 0; /* Wake the potentially-idle transmit channel. */ - outl(0x10001000, dev->base_addr + TxCtrl); + YF_OUTL(0x10001000, dev->base_addr + TxCtrl); if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE) netif_wake_queue (dev); /* Typical path */ @@ -681,7 +697,7 @@ /* Non-x86 Todo: explicitly flush cache lines here. */ /* Wake the potentially-idle transmit channel. */ - outl(0x10001000, dev->base_addr + TxCtrl); + YF_OUTL(0x10001000, dev->base_addr + TxCtrl); if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE) netif_start_queue (dev); /* Typical path */ @@ -717,7 +733,7 @@ spin_lock (&yp->lock); do { - u16 intr_status = inw(ioaddr + IntrClear); + u16 intr_status = YF_INW(ioaddr + IntrClear); if (yellowfin_debug > 4) printk(KERN_DEBUG "%s: Yellowfin interrupt, status %4.4x.\n", @@ -728,7 +744,7 @@ if (intr_status & (IntrRxDone | IntrEarlyRx)) { yellowfin_rx(dev); - outl(0x10001000, ioaddr + RxCtrl); /* Wake Rx engine. */ + YF_OUTL(0x10001000, ioaddr + RxCtrl); /* Wake Rx engine. */ } #ifdef NO_TXSTATS @@ -845,7 +861,7 @@ if (yellowfin_debug > 3) printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n", - dev->name, inw(ioaddr + IntrStatus)); + dev->name, YF_INW(ioaddr + IntrStatus)); /* Code that should never be run! Perhaps remove after testing.. */ { @@ -1023,18 +1039,19 @@ if (yellowfin_debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n", - dev->name, inw(ioaddr + TxStatus), - inw(ioaddr + RxStatus), inw(ioaddr + IntrStatus)); + dev->name, YF_INW(ioaddr + TxStatus), + YF_INW(ioaddr + RxStatus), + YF_INW(ioaddr + IntrStatus)); printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n", dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx); } /* Disable interrupts by clearing the interrupt mask. */ - outw(0x0000, ioaddr + IntrEnb); + YF_OUTW(0x0000, ioaddr + IntrEnb); /* Stop the chip's Tx and Rx processes. */ - outl(0x80000000, ioaddr + RxCtrl); - outl(0x80000000, ioaddr + TxCtrl); + YF_OUTL(0x80000000, ioaddr + RxCtrl); + YF_OUTL(0x80000000, ioaddr + TxCtrl); del_timer(&yp->timer); @@ -1043,7 +1060,7 @@ printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", (int)virt_to_bus(yp->tx_ring)); for (i = 0; i < TX_RING_SIZE*2; i++) printk(" %c #%d desc. %8.8x %8.8x %8.8x %8.8x.\n", - inl(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ', + YF_INL(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ', i, yp->tx_ring[i].dbdma_cmd, yp->tx_ring[i].addr, yp->tx_ring[i].branch_addr, yp->tx_ring[i].result_status); printk(KERN_DEBUG " Tx status %p:\n", yp->tx_status); @@ -1055,7 +1072,7 @@ printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", (int)virt_to_bus(yp->rx_ring)); for (i = 0; i < RX_RING_SIZE; i++) { printk(KERN_DEBUG " %c #%d desc. %8.8x %8.8x %8.8x\n", - inl(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ', + YF_INL(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ', i, yp->rx_ring[i].dbdma_cmd, yp->rx_ring[i].addr, yp->rx_ring[i].result_status); if (yellowfin_debug > 6) { @@ -1134,17 +1151,17 @@ { struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv; long ioaddr = dev->base_addr; - u16 cfg_value = inw(ioaddr + Cnfg); + u16 cfg_value = YF_INW(ioaddr + Cnfg); /* Stop the Rx process to change any value. */ - outw(cfg_value & ~0x1000, ioaddr + Cnfg); + YF_OUTW(cfg_value & ~0x1000, ioaddr + Cnfg); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ /* Unconditionally log net taps. */ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); - outw(0x000F, ioaddr + AddrMode); + YF_OUTW(0x000F, ioaddr + AddrMode); } else if ((dev->mc_count > 64) || (dev->flags & IFF_ALLMULTI)) { /* Too many to filter well, or accept all multicasts. */ - outw(0x000B, ioaddr + AddrMode); + YF_OUTW(0x000B, ioaddr + AddrMode); } else if (dev->mc_count > 0) { /* Must use the multicast hash table. */ struct dev_mc_list *mclist; u16 hash_table[4]; @@ -1167,13 +1184,13 @@ } /* Copy the hash table to the chip. */ for (i = 0; i < 4; i++) - outw(hash_table[i], ioaddr + HashTbl + i*2); - outw(0x0003, ioaddr + AddrMode); + YF_OUTW(hash_table[i], ioaddr + HashTbl + i*2); + YF_OUTW(0x0003, ioaddr + AddrMode); } else { /* Normal, unicast/broadcast-only mode. */ - outw(0x0001, ioaddr + AddrMode); + YF_OUTW(0x0001, ioaddr + AddrMode); } /* Restart the Rx process. */ - outw(cfg_value | 0x1000, ioaddr + Cnfg); + YF_OUTW(cfg_value | 0x1000, ioaddr + Cnfg); } #ifdef HAVE_PRIVATE_IOCTL @@ -1209,7 +1226,7 @@ int option, i, irq; int flags, chip_idx; static int find_cnt = 0; - long ioaddr; + long ioaddr, real_ioaddr; chip_idx = ent->driver_data; flags = chip_info[chip_idx].flags; @@ -1243,18 +1260,20 @@ pci_set_master (pdev); #ifdef USE_IO_OPS - ioaddr = pci_resource_start (pdev, 0); + real_ioaddr = ioaddr = pci_resource_start (pdev, 0); #else - ioaddr = pci_resource_start (pdev, 1); + real_ioaddr = ioaddr = pci_resource_start (pdev, 1); + ioaddr = ioremap(ioaddr, YELLOWFIN_SIZE); #endif irq = pdev->irq; printk(KERN_INFO "%s: %s type %8x at 0x%lx, ", - dev->name, chip_info[chip_idx].name, inl(ioaddr + ChipRev), ioaddr); + dev->name, chip_info[chip_idx].name, + YF_INL(ioaddr + ChipRev), real_ioaddr); if (flags & IsGigabit) for (i = 0; i < 6; i++) - dev->dev_addr[i] = inb(ioaddr + StnAddr + i); + dev->dev_addr[i] = YF_INB(ioaddr + StnAddr + i); else { int ee_offset = (read_eeprom(ioaddr, 6) == 0xff ? 0x100 : 0); for (i = 0; i < 6; i++) @@ -1265,7 +1284,7 @@ printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq); /* Reset the chip. */ - outl(0x80000000, ioaddr + DMACtrl); + YF_OUTL(0x80000000, ioaddr + DMACtrl); dev->base_addr = ioaddr; dev->irq = irq; diff -u --recursive --new-file v2.3.48/linux/drivers/parport/daisy.c linux/drivers/parport/daisy.c --- v2.3.48/linux/drivers/parport/daisy.c Sat Feb 26 22:31:47 2000 +++ linux/drivers/parport/daisy.c Mon Feb 28 07:16:49 2000 @@ -160,10 +160,10 @@ while (prev) { dev = prev->next; - if (dev && dev->port == port) + if (dev && dev->port == port) { prev->next = dev->next; - - kfree (dev); + kfree (dev); + } prev = prev->next; } diff -u --recursive --new-file v2.3.48/linux/drivers/parport/ieee1284.c linux/drivers/parport/ieee1284.c --- v2.3.48/linux/drivers/parport/ieee1284.c Thu Nov 11 20:11:42 1999 +++ linux/drivers/parport/ieee1284.c Mon Feb 28 07:19:18 2000 @@ -165,6 +165,7 @@ /* Terminate a negotiated mode. */ static void parport_ieee1284_terminate (struct parport *port) { + int r; port = port->physport; /* EPP terminates differently. */ @@ -199,9 +200,12 @@ | PARPORT_CONTROL_AUTOFD); /* Event 49: PError goes high */ - parport_wait_peripheral (port, - PARPORT_STATUS_PAPEROUT, - PARPORT_STATUS_PAPEROUT); + r = parport_wait_peripheral (port, + PARPORT_STATUS_PAPEROUT, + PARPORT_STATUS_PAPEROUT); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 49\n", + port->name); parport_data_forward (port); DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", @@ -221,7 +225,10 @@ PARPORT_CONTROL_SELECT); /* Event 24: nAck goes low */ - parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); + r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 24\n", + port->name); /* Event 25: Set nAutoFd low */ parport_frob_control (port, @@ -229,9 +236,12 @@ PARPORT_CONTROL_AUTOFD); /* Event 27: nAck goes high */ - parport_wait_peripheral (port, - PARPORT_STATUS_ACK, - PARPORT_STATUS_ACK); + r = parport_wait_peripheral (port, + PARPORT_STATUS_ACK, + PARPORT_STATUS_ACK); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 27\n", + port->name); /* Event 29: Set nAutoFd high */ parport_frob_control (port, PARPORT_CONTROL_AUTOFD, 0); @@ -260,6 +270,7 @@ return -1; #else int m = mode & ~IEEE1284_ADDR; + int r; unsigned char xflag; port = port->physport; @@ -367,7 +378,7 @@ /* xflag should be high for all modes other than nibble (0). */ if (mode && !xflag) { /* Mode not supported. */ - DPRINTK (KERN_DEBUG "%s: Mode 0x%02x not supported\n", + DPRINTK (KERN_DEBUG "%s: Mode 0x%02x rejected by peripheral\n", port->name, mode); parport_ieee1284_terminate (port); return 1; @@ -434,7 +445,7 @@ port->ieee1284.mode = mode; /* But ECP is special */ - if (!(mode & IEEE1284_EXT_LINK) && (mode & IEEE1284_MODE_ECP)) { + if (!(mode & IEEE1284_EXT_LINK) && (m & IEEE1284_MODE_ECP)) { port->ieee1284.phase = IEEE1284_PH_ECP_SETUP; /* Event 30: Set nAutoFd low */ @@ -443,10 +454,11 @@ PARPORT_CONTROL_AUTOFD); /* Event 31: PError goes high. */ - parport_wait_peripheral (port, - PARPORT_STATUS_PAPEROUT, - PARPORT_STATUS_PAPEROUT); - /* (Should check that this works..) */ + r = parport_wait_peripheral (port, + PARPORT_STATUS_PAPEROUT, + PARPORT_STATUS_PAPEROUT); + if (r) + DPRINTK (KERN_INFO "%s: Timeout at event 31\n"); port->ieee1284.phase = IEEE1284_PH_FWD_IDLE; DPRINTK (KERN_DEBUG "%s: ECP direction: forward\n", diff -u --recursive --new-file v2.3.48/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c --- v2.3.48/linux/drivers/parport/parport_pc.c Sat Feb 26 22:31:47 2000 +++ linux/drivers/parport/parport_pc.c Mon Feb 28 07:19:18 2000 @@ -1503,7 +1503,7 @@ /* --- DMA detection -------------------------------------- */ -/* Only if supports ECP mode */ +/* Only if chipset conforms to ECP ISA Interface Standard */ static int __devinit programmable_dma_support (struct parport *p) { unsigned char oecr = inb (ECONTROL (p)); @@ -1511,8 +1511,10 @@ frob_econtrol (p, 0xe0, ECR_CNF << 5); - dma = inb (CONFIGB(p)) & 0x03; - if (!dma) + dma = inb (CONFIGB(p)) & 0x07; + /* 000: Indicates jumpered 8-bit DMA if read-only. + 100: Indicates jumpered 16-bit DMA if read-only. */ + if ((dma & 0x03) == 0) dma = PARPORT_DMA_NONE; outb (oecr, ECONTROL (p)); @@ -1722,6 +1724,7 @@ } +/* Via support maintained by Jeff Garzik */ static int __devinit sio_via_686a_probe (struct pci_dev *pdev) { u8 dma, irq, tmp; @@ -1835,6 +1838,7 @@ static int __devinit parport_pc_init_superio(void) { +#ifdef CONFIG_PCI const struct pci_device_id *id; struct pci_dev *pdev; @@ -1845,11 +1849,11 @@ return parport_pc_superio_info[id->driver_data].probe (pdev); } +#endif /* CONFIG_PCI */ return 0; /* zero devices found */ } - /* Look for PCI parallel port cards. */ static int __init parport_pc_init_pci (int irq, int dma) { @@ -1991,6 +1995,7 @@ } } +#ifdef CONFIG_PCI /* Look for parallel controllers that we don't know about. */ pci_for_each_dev(pcidev) { const int class_noprogif = pcidev->class & ~0xff; @@ -2011,6 +2016,7 @@ "tim@cyberelk.demon.co.uk\n", pcidev->vendor, pcidev->device); } +#endif return count; } @@ -2034,9 +2040,16 @@ static int irqval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_IRQ_PROBEONLY }; static const char *irq[PARPORT_PC_MAX_PORTS] = { NULL, }; static const char *dma[PARPORT_PC_MAX_PORTS] = { NULL, }; + +MODULE_AUTHOR("Phil Blundell, Tim Waugh, others"); +MODULE_DESCRIPTION("PC-style parallel port driver"); +MODULE_PARM_DESC(io, "Base I/O address (SPP regs)"); MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i"); +MODULE_PARM_DESC(io_hi, "Base I/O address (ECR)"); MODULE_PARM(io_hi, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i"); +MODULE_PARM_DESC(irq, "IRQ line"); MODULE_PARM(irq, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s"); +MODULE_PARM_DESC(dma, "DMA channel"); MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s"); int init_module(void) diff -u --recursive --new-file v2.3.48/linux/drivers/pci/Makefile linux/drivers/pci/Makefile --- v2.3.48/linux/drivers/pci/Makefile Fri Jan 21 18:19:16 2000 +++ linux/drivers/pci/Makefile Mon Feb 28 07:16:54 2000 @@ -14,11 +14,8 @@ # Nasty trick as we need to link files with no references from the outside. O_TARGET := pci_core.o L_OBJS := pci_core.o -O_OBJS := pci.o quirks.o - -ifdef CONFIG_MODULES -OX_OBJS += pcisyms.o -endif +O_OBJS := quirks.o +OX_OBJS := pci.o ifdef CONFIG_PROC_FS O_OBJS += proc.o diff -u --recursive --new-file v2.3.48/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.3.48/linux/drivers/pci/pci.c Thu Feb 10 17:11:12 2000 +++ linux/drivers/pci/pci.c Mon Feb 28 07:16:54 2000 @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -19,6 +20,7 @@ #include #include +#include /* isa_dma_bridge_buggy */ #undef DEBUG @@ -987,3 +989,50 @@ } __setup("pci=", pci_setup); + + +EXPORT_SYMBOL(pci_read_config_byte); +EXPORT_SYMBOL(pci_read_config_word); +EXPORT_SYMBOL(pci_read_config_dword); +EXPORT_SYMBOL(pci_write_config_byte); +EXPORT_SYMBOL(pci_write_config_word); +EXPORT_SYMBOL(pci_write_config_dword); +EXPORT_SYMBOL(pci_devices); +EXPORT_SYMBOL(pci_root_buses); +EXPORT_SYMBOL(pci_enable_device); +EXPORT_SYMBOL(pci_find_capability); +EXPORT_SYMBOL(pci_find_class); +EXPORT_SYMBOL(pci_find_device); +EXPORT_SYMBOL(pci_find_slot); +EXPORT_SYMBOL(pci_find_subsys); +EXPORT_SYMBOL(pci_set_master); +EXPORT_SYMBOL(pci_set_power_state); +EXPORT_SYMBOL(pci_assign_resource); +EXPORT_SYMBOL(pci_register_driver); +EXPORT_SYMBOL(pci_unregister_driver); +EXPORT_SYMBOL(pci_match_device); +EXPORT_SYMBOL(pci_find_parent_resource); + +#ifdef CONFIG_HOTPLUG +EXPORT_SYMBOL(pci_setup_device); +EXPORT_SYMBOL(pci_insert_device); +EXPORT_SYMBOL(pci_remove_device); +#endif + +/* Obsolete functions */ + +EXPORT_SYMBOL(pcibios_present); +EXPORT_SYMBOL(pcibios_read_config_byte); +EXPORT_SYMBOL(pcibios_read_config_word); +EXPORT_SYMBOL(pcibios_read_config_dword); +EXPORT_SYMBOL(pcibios_write_config_byte); +EXPORT_SYMBOL(pcibios_write_config_word); +EXPORT_SYMBOL(pcibios_write_config_dword); +EXPORT_SYMBOL(pcibios_find_class); +EXPORT_SYMBOL(pcibios_find_device); + +/* Quirk info */ + +EXPORT_SYMBOL(isa_dma_bridge_buggy); +EXPORT_SYMBOL(pci_pci_problems); + diff -u --recursive --new-file v2.3.48/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids --- v2.3.48/linux/drivers/pci/pci.ids Sat Feb 26 22:31:47 2000 +++ linux/drivers/pci/pci.ids Tue Feb 29 14:53:08 2000 @@ -2225,6 +2225,7 @@ 1277 Comstream 1278 Transtech Parallel Systems Ltd. 1279 Transmeta Corporation + 0295 Virtual Northbridge 127a Rockwell International 1002 HCF 56k V90 FaxModem 1003 HCF 56k V90 FaxModem diff -u --recursive --new-file v2.3.48/linux/drivers/pci/pcisyms.c linux/drivers/pci/pcisyms.c --- v2.3.48/linux/drivers/pci/pcisyms.c Wed Feb 16 17:03:52 2000 +++ linux/drivers/pci/pcisyms.c Wed Dec 31 16:00:00 1969 @@ -1,58 +0,0 @@ -/* - * $Id: pcisyms.c,v 1.8 1998/05/12 07:36:04 mj Exp $ - * - * PCI Bus Services -- Exported Symbols - * - * Copyright 1998--2000 Martin Mares - */ - -#include -#include -#include -#include /* isa_dma_bridge_buggy */ - -EXPORT_SYMBOL(pci_read_config_byte); -EXPORT_SYMBOL(pci_read_config_word); -EXPORT_SYMBOL(pci_read_config_dword); -EXPORT_SYMBOL(pci_write_config_byte); -EXPORT_SYMBOL(pci_write_config_word); -EXPORT_SYMBOL(pci_write_config_dword); -EXPORT_SYMBOL(pci_devices); -EXPORT_SYMBOL(pci_root_buses); -EXPORT_SYMBOL(pci_enable_device); -EXPORT_SYMBOL(pci_find_capability); -EXPORT_SYMBOL(pci_find_class); -EXPORT_SYMBOL(pci_find_device); -EXPORT_SYMBOL(pci_find_slot); -EXPORT_SYMBOL(pci_find_subsys); -EXPORT_SYMBOL(pci_set_master); -EXPORT_SYMBOL(pci_set_power_state); -EXPORT_SYMBOL(pci_assign_resource); -EXPORT_SYMBOL(pci_register_driver); -EXPORT_SYMBOL(pci_unregister_driver); -EXPORT_SYMBOL(pci_match_device); -EXPORT_SYMBOL(pci_find_parent_resource); - -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pci_setup_device); -EXPORT_SYMBOL(pci_insert_device); -EXPORT_SYMBOL(pci_remove_device); -#endif - -/* Obsolete functions */ - -EXPORT_SYMBOL(pcibios_present); -EXPORT_SYMBOL(pcibios_read_config_byte); -EXPORT_SYMBOL(pcibios_read_config_word); -EXPORT_SYMBOL(pcibios_read_config_dword); -EXPORT_SYMBOL(pcibios_write_config_byte); -EXPORT_SYMBOL(pcibios_write_config_word); -EXPORT_SYMBOL(pcibios_write_config_dword); -EXPORT_SYMBOL(pcibios_find_class); -EXPORT_SYMBOL(pcibios_find_device); - -/* Quirk info */ - -EXPORT_SYMBOL(isa_dma_bridge_buggy); -EXPORT_SYMBOL(pci_pci_problems); - diff -u --recursive --new-file v2.3.48/linux/drivers/pci/quirks.c linux/drivers/pci/quirks.c --- v2.3.48/linux/drivers/pci/quirks.c Tue Dec 7 09:32:44 1999 +++ linux/drivers/pci/quirks.c Tue Feb 29 14:53:08 2000 @@ -113,6 +113,55 @@ } } +static void __init quirk_io_region(struct pci_dev *dev, unsigned region, unsigned size, int nr) +{ + region &= ~(size-1); + if (region) { + struct resource *res = dev->resource + nr; + + res->name = dev->name; + res->start = region; + res->end = region + size - 1; + res->flags = IORESOURCE_IO; + pci_claim_resource(dev, nr); + } +} + +/* + * Let's make the southbridge information explicit instead + * of having to worry about people probing the ACPI areas, + * for example.. (Yes, it happens, and if you read the wrong + * ACPI register it will put the machine to sleep with no + * way of waking it up again. Bummer). + * + * ALI M7101: Two IO regions pointed to by words at + * 0xE0 (64 bytes of ACPI registers) + * 0xE2 (32 bytes of SMB registers) + */ +static void __init quirk_ali7101(struct pci_dev *dev) +{ + u16 region; + + pci_read_config_word(dev, 0xE0, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES); + pci_read_config_word(dev, 0xE2, ®ion); + quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1); +} + +/* + * PIIX4 ACPI: Two IO regions pointed to by longwords at + * 0x40 (64 bytes of ACPI registers) + * 0x90 (32 bytes of SMB registers) + */ +static void __init quirk_piix4acpi(struct pci_dev *dev) +{ + u32 region; + + pci_read_config_dword(dev, 0x40, ®ion); + quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES); + pci_read_config_dword(dev, 0x90, ®ion); + quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1); +} /* * The main table of quirks. @@ -143,6 +192,8 @@ { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443BX_2, quirk_natoma }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5597, quirk_nopcipci }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, quirk_nopcipci }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, quirk_piix4acpi }, + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, quirk_ali7101 }, { 0 } }; diff -u --recursive --new-file v2.3.48/linux/drivers/pcmcia/cardbus.c linux/drivers/pcmcia/cardbus.c --- v2.3.48/linux/drivers/pcmcia/cardbus.c Fri Jan 21 18:19:16 2000 +++ linux/drivers/pcmcia/cardbus.c Wed Mar 1 15:30:07 2000 @@ -186,6 +186,9 @@ DEBUG(3, "cs: read_cb_mem(%d, %#x, %u)\n", space, addr, len); + if (!s->cb_config) + goto fail; + dev = &s->cb_config[fn].dev; /* Config space? */ diff -u --recursive --new-file v2.3.48/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c --- v2.3.48/linux/drivers/pcmcia/cs.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/pcmcia/cs.c Mon Feb 28 07:16:54 2000 @@ -82,14 +82,12 @@ #else #define CB_OPT "" #endif -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) || defined(CONFIG_ACPI) -#define APM_OPT " [apm]" +#ifdef CONFIG_PM +#define APM_OPT " [pm]" #else #define APM_OPT "" #endif -#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && \ - !defined(CONFIG_APM) && !defined(CONFIG_APM_MODULE) && \ - !defined(CONFIG_ACPI) +#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM) #define OPTIONS " none" #else #define OPTIONS PCI_OPT CB_OPT APM_OPT @@ -125,7 +123,7 @@ static int io_speed = 0; /* ns */ /* Optional features */ -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) || defined(CONFIG_ACPI) +#ifdef CONFIG_PM static int do_apm = 1; MODULE_PARM(do_apm, "i"); #else diff -u --recursive --new-file v2.3.48/linux/drivers/pcmcia/rsrc_mgr.c linux/drivers/pcmcia/rsrc_mgr.c --- v2.3.48/linux/drivers/pcmcia/rsrc_mgr.c Fri Jan 21 18:19:16 2000 +++ linux/drivers/pcmcia/rsrc_mgr.c Tue Feb 29 15:28:46 2000 @@ -102,10 +102,11 @@ /*====================================================================== Linux resource management extensions - + ======================================================================*/ -#define check_io_region(b,n) (0) +#define check_io_resource(b,n) check_resource(&ioport_resource, (b), (n)) +#define check_mem_resource(b,n) check_resource(&iomem_resource, (b), (n)) /*====================================================================== @@ -191,7 +192,7 @@ b = kmalloc(256, GFP_KERNEL); memset(b, 0, 256); for (i = base, most = 0; i < base+num; i += 8) { - if (check_region(i, 8) || check_io_region(i, 8)) + if (check_io_resource(i, 8)) continue; hole = inb(i); for (j = 1; j < 8; j++) @@ -204,7 +205,7 @@ bad = any = 0; for (i = base; i < base+num; i += 8) { - if (check_region(i, 8) || check_io_region(i, 8)) + if (check_io_resource(i, 8)) continue; for (j = 0; j < 8; j++) if (inb(i+j) != most) break; @@ -255,13 +256,13 @@ for (i = base; i < base+num; i = j + step) { if (!fail) { for (j = i; j < base+num; j += step) - if ((check_mem_region(j, step) == 0) && is_valid(j)) + if ((check_mem_resource(j, step) == 0) && is_valid(j)) break; fail = ((i == base) && (j == base+num)); } if (fail) { for (j = i; j < base+num; j += 2*step) - if ((check_mem_region(j, 2*step) == 0) && + if ((check_mem_resource(j, 2*step) == 0) && do_cksum(j) && do_cksum(j+step)) break; } @@ -375,8 +376,7 @@ for (try = (try >= m->base) ? try : try+align; (try >= m->base) && (try+num <= m->base+m->num); try += align) { - if ((check_region(try, num) == 0) && - (check_io_region(try, num) == 0)) { + if (check_io_resource(try, num) == 0) { *base = try; request_region(try, num, name); return 0; @@ -401,7 +401,7 @@ for (try = (try >= m->base) ? try : try+align; (try >= m->base) && (try+num <= m->base+m->num); try += align) { - if (check_mem_region(try, num) == 0) { + if (check_mem_resource(try, num) == 0) { request_mem_region(try, num, name); *base = try; return 0; diff -u --recursive --new-file v2.3.48/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c --- v2.3.48/linux/drivers/pcmcia/yenta.c Sat Feb 26 22:31:48 2000 +++ linux/drivers/pcmcia/yenta.c Mon Feb 28 14:06:08 2000 @@ -235,16 +235,18 @@ socket->io_irq = state->io_irq; bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR); if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { + u8 intr; bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0; /* ISA interrupt control? */ + intr = exca_readb(socket, I365_INTCTL); + intr = (intr & ~0xf); if (!socket->cb_irq) { - u8 intr = exca_readb(socket, I365_INTCTL); - intr = (intr & ~0xf) | state->io_irq; - exca_writeb(socket, I365_INTCTL, intr); + intr |= state->io_irq; bridge |= CB_BRIDGE_INTR; } - } else { + exca_writeb(socket, I365_INTCTL, intr); + } else { u8 reg; bridge |= CB_BRIDGE_INTR; diff -u --recursive --new-file v2.3.48/linux/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c --- v2.3.48/linux/drivers/scsi/pci2000.c Sat Feb 26 22:31:48 2000 +++ linux/drivers/scsi/pci2000.c Mon Feb 28 07:16:54 2000 @@ -660,7 +660,7 @@ padapter = HOSTDATA(pshost); #if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) - padapter->basePort = pdev->base_address[1] & 0xFFFE; + padapter->basePort = pci_resource_start (pdev, 1); #else pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &padapter->basePort); padapter->basePort &= 0xFFFE; diff -u --recursive --new-file v2.3.48/linux/drivers/scsi/pci2220i.c linux/drivers/scsi/pci2220i.c --- v2.3.48/linux/drivers/scsi/pci2220i.c Sat Feb 26 22:31:48 2000 +++ linux/drivers/scsi/pci2220i.c Mon Feb 28 07:16:54 2000 @@ -2448,15 +2448,9 @@ memset (&DaleSetup, 0, sizeof (DaleSetup)); memset (DiskMirror, 0, sizeof (DiskMirror)); -#if LINUX_VERSION_CODE > LINUXVERSION(2,1,92) - zr = pcidev->base_address[1] & 0xFFFE; - zl = pcidev->base_address[2] & 0xFFFE; -#else - pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &zr); - zr &= 0xFFFE; - pcibios_read_config_word (pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &zl); - zl &= 0xFFFE; -#endif + zr = pci_resource_start (pcidev, 1); + zl = pci_resource_start (pcidev, 2); + padapter->basePort = zr; padapter->regRemap = zr + RTR_LOCAL_REMAP; // 32 bit local space remap padapter->regDesc = zr + RTR_REGIONS; // 32 bit local region descriptor diff -u --recursive --new-file v2.3.48/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c --- v2.3.48/linux/drivers/scsi/scsi_scan.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/scsi/scsi_scan.c Sun Feb 27 08:56:37 2000 @@ -108,6 +108,7 @@ {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 * extra reset */ + {"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */ {"RELISYS", "Scorpio", "*", BLIST_NOLUN}, /* responds to all LUN */ {"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */ diff -u --recursive --new-file v2.3.48/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c --- v2.3.48/linux/drivers/scsi/seagate.c Fri Jan 21 18:19:17 2000 +++ linux/drivers/scsi/seagate.c Mon Feb 28 07:16:54 2000 @@ -89,7 +89,7 @@ #include #include #include - +#include #include #include "scsi.h" #include "hosts.h" @@ -99,7 +99,6 @@ #include #include "sd.h" #include -#include #ifdef DEBUG #define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0) diff -u --recursive --new-file v2.3.48/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.3.48/linux/drivers/scsi/st.c Sun Feb 20 21:12:39 2000 +++ linux/drivers/scsi/st.c Tue Feb 29 12:11:35 2000 @@ -11,7 +11,7 @@ Copyright 1992 - 2000 Kai Makisara email Kai.Makisara@metla.fi - Last modified: Sat Feb 19 17:22:34 2000 by makisara@kai.makisara.local + Last modified: Tue Feb 29 20:47:03 2000 by makisara@kai.makisara.local Some small formal changes - aeb, 950809 Last modified: 18-JAN-1998 Richard Gooch Devfs support @@ -172,21 +172,22 @@ /* Convert the result to success code */ static int st_chk_result(Scsi_Request * SRpnt) { - int dev = TAPE_NR(SRpnt->sr_request.rq_dev); + int dev; int result = SRpnt->sr_result; unsigned char *sense = SRpnt->sr_sense_buffer, scode; DEB(const char *stp;) - if (!result) + if (!result) { + sense[0] = 0; /* We don't have sense data if this byte is zero */ return 0; + } if (driver_byte(result) & DRIVER_SENSE) scode = sense[2] & 0x0f; - else { - sense[0] = 0; /* We don't have sense data if this byte is zero */ + else scode = 0; - } + dev = TAPE_NR(SRpnt->sr_request.rq_dev); DEB( if (debugging) { printk(ST_DEB_MSG "st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", @@ -294,7 +295,7 @@ { unsigned char *bp; - if (SRpnt == NULL) + if (SRpnt == NULL) { SRpnt = scsi_allocate_request(STp->device); if (SRpnt == NULL) { DEBC( printk(KERN_ERR "st%d: Can't get SCSI request.\n", @@ -305,6 +306,7 @@ (STp->buffer)->syscall_result = (-EBUSY); return NULL; } + } cmd[1] |= (SRpnt->sr_device->lun << 5) & 0xe0; init_MUTEX_LOCKED(&STp->sem); diff -u --recursive --new-file v2.3.48/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c --- v2.3.48/linux/drivers/scsi/u14-34f.c Thu Feb 10 17:11:13 2000 +++ linux/drivers/scsi/u14-34f.c Mon Feb 28 07:16:55 2000 @@ -1948,7 +1948,7 @@ if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n", driver_name); - if( sh[j]->block != NULL ) { + if( sh[j]->unchecked_isa_dma ) { scsi_deregister_blocked_host(sh[j]); } diff -u --recursive --new-file v2.3.48/linux/drivers/sgi/char/graphics_syms.c linux/drivers/sgi/char/graphics_syms.c --- v2.3.48/linux/drivers/sgi/char/graphics_syms.c Sat Feb 26 22:31:48 2000 +++ linux/drivers/sgi/char/graphics_syms.c Mon Feb 28 07:18:20 2000 @@ -8,7 +8,6 @@ */ #define __NO_VERSION__ -#include #include /* extern int rrm_command (unsigned int cmd, void *arg); diff -u --recursive --new-file v2.3.48/linux/drivers/sgi/char/newport.c linux/drivers/sgi/char/newport.c --- v2.3.48/linux/drivers/sgi/char/newport.c Sat Feb 26 22:31:48 2000 +++ linux/drivers/sgi/char/newport.c Mon Feb 28 07:18:20 2000 @@ -12,7 +12,6 @@ #include #include #include