From d26708baa4f5afe00b03ffef2dbddc5b70fea56b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:10:38 -0500 Subject: [PATCH] Import 1.3.70 --- CREDITS | 14 +- Documentation/Configure.help | 363 ++++++++++++------------ Documentation/devices.tex | 42 ++- Documentation/devices.txt | 31 ++- Documentation/isdn/README.teles | 2 +- MAINTAINERS | 8 +- Makefile | 2 +- Rules.make | 2 +- arch/alpha/config.in | 7 + arch/alpha/defconfig | 30 +- arch/alpha/kernel/Makefile | 2 +- arch/alpha/kernel/alcor.c | 472 ++++++++++++++++++++++++++++++++ arch/alpha/kernel/bios32.c | 4 +- arch/alpha/kernel/irq.c | 169 +++++++++--- arch/alpha/kernel/setup.c | 2 + arch/i386/boot/bootsect.S | 4 - arch/i386/kernel/irq.c | 193 +++++++++---- arch/i386/kernel/smp.c | 320 +++++++++++++--------- arch/i386/kernel/time.c | 10 +- arch/mips/kernel/irq.c | 162 +++++++---- arch/ppc/kernel/irq.c | 171 ++++++++---- arch/sparc/kernel/irq.c | 190 +++++++++---- drivers/block/Config.in | 10 +- drivers/block/README.hd | 2 +- drivers/block/README.ide | 26 +- drivers/block/cmd640.c | 1 + drivers/block/dtc2278.c | 12 +- drivers/block/floppy.c | 3 +- drivers/block/genhd.c | 48 ++-- drivers/block/hd.c | 6 +- drivers/block/ide.c | 94 ++++--- drivers/block/ide.h | 2 + drivers/block/ide_modes.h | 1 + drivers/block/ll_rw_blk.c | 2 + drivers/block/md.c | 10 +- drivers/block/rz1000.c | 2 +- drivers/block/triton.c | 6 +- drivers/block/xd.c | 6 +- drivers/cdrom/cdu31a.c | 4 +- drivers/cdrom/cm206.c | 6 +- drivers/cdrom/mcd.c | 6 +- drivers/cdrom/mcdx.c | 8 +- drivers/cdrom/sonycd535.c | 4 +- drivers/char/atixlmouse.c | 6 +- drivers/char/busmouse.c | 6 +- drivers/char/console.c | 2 +- drivers/char/cyclades.c | 14 +- drivers/char/keyboard.c | 4 +- drivers/char/lp.c | 12 +- drivers/char/msbusmouse.c | 6 +- drivers/char/psaux.c | 14 +- drivers/char/scc.c | 8 +- drivers/char/serial.c | 38 +-- drivers/char/stallion.c | 8 +- drivers/char/tpqic02.c | 12 +- drivers/char/wdt.c | 8 +- drivers/isdn/teles/card.c | 9 + drivers/net/3c501.c | 9 +- drivers/net/3c503.c | 210 +++++++++----- drivers/net/3c505.c | 6 +- drivers/net/3c507.c | 8 +- drivers/net/3c509.c | 8 +- drivers/net/3c59x.c | 10 +- drivers/net/8390.c | 2 +- drivers/net/8390.h | 2 +- drivers/net/ac3200.c | 10 +- drivers/net/apricot.c | 10 +- drivers/net/arcnet.c | 8 +- drivers/net/at1700.c | 8 +- drivers/net/atp.c | 8 +- drivers/net/auto_irq.c | 8 +- drivers/net/de4x5.c | 10 +- drivers/net/de600.c | 8 +- drivers/net/de620.c | 8 +- drivers/net/depca.c | 8 +- drivers/net/e2100.c | 6 +- drivers/net/eepro.c | 12 +- drivers/net/eexpress.c | 8 +- drivers/net/eth16i.c | 8 +- drivers/net/ewrk3.c | 32 +-- drivers/net/hp-plus.c | 4 +- drivers/net/hp.c | 10 +- drivers/net/hp100.c | 8 +- drivers/net/ibmtr.c | 8 +- drivers/net/lance.c | 8 +- drivers/net/ne.c | 6 +- drivers/net/ni52.c | 8 +- drivers/net/ni65.c | 12 +- drivers/net/pi2.c | 8 +- drivers/net/plip.c | 8 +- drivers/net/pt.c | 8 +- drivers/net/seeq8005.c | 10 +- drivers/net/sk_g16.c | 15 +- drivers/net/skeleton.c | 14 +- drivers/net/slip.c | 13 +- drivers/net/smc-ultra.c | 4 +- drivers/net/sunlance.c | 6 +- drivers/net/tulip.c | 10 +- drivers/net/wavelan.c | 10 +- drivers/net/wd.c | 6 +- drivers/net/znet.c | 8 +- drivers/scsi/53c7,8xx.c | 12 +- drivers/scsi/AM53C974.c | 24 +- drivers/scsi/BusLogic.c | 4 +- drivers/scsi/NCR5380.c | 8 +- drivers/scsi/NCR5380.h | 2 +- drivers/scsi/NCR53c406a.c | 8 +- drivers/scsi/advansys.c | 10 +- drivers/scsi/aha152x.c | 6 +- drivers/scsi/aha1542.c | 6 +- drivers/scsi/aha1740.c | 4 +- drivers/scsi/aic7xxx.c | 4 +- drivers/scsi/eata.c | 10 +- drivers/scsi/eata_dma.c | 18 +- drivers/scsi/eata_pio.c | 8 +- drivers/scsi/fdomain.c | 6 +- drivers/scsi/g_NCR5380.c | 4 +- drivers/scsi/in2000.c | 4 +- drivers/scsi/pas16.c | 2 +- drivers/scsi/qlogic.c | 4 +- drivers/scsi/scsi.c | 15 +- drivers/scsi/sd_ioctl.c | 14 +- drivers/scsi/seagate.c | 6 +- drivers/scsi/t128.c | 2 +- drivers/scsi/u14-34f.c | 10 +- drivers/scsi/ultrastor.c | 10 +- drivers/scsi/wd7000.c | 10 +- drivers/sound/ad1848.c | 15 +- drivers/sound/dev_table.h | 5 +- drivers/sound/gus_card.c | 6 +- drivers/sound/gus_wave.c | 2 +- drivers/sound/mad16_sb_midi.c | 2 +- drivers/sound/maui.c | 2 +- drivers/sound/mpu401.c | 2 +- drivers/sound/pas2_card.c | 2 +- drivers/sound/sb16_midi.c | 2 +- drivers/sound/sb_dsp.c | 2 +- drivers/sound/sound_calls.h | 10 +- drivers/sound/soundcard.c | 6 +- drivers/sound/sscape.c | 4 +- drivers/sound/uart6850.c | 2 +- fs/ncpfs/sock.c | 4 +- include/asm-alpha/alcor.h | 407 +++++++++++++++++++++++++++ include/asm-alpha/floppy.h | 4 +- include/asm-alpha/io.h | 2 + include/asm-alpha/irq.h | 2 +- include/asm-alpha/mmu_context.h | 34 +-- include/asm-alpha/signal.h | 2 + include/asm-alpha/system.h | 4 +- include/asm-i386/floppy.h | 4 +- include/asm-i386/signal.h | 2 + include/asm-i386/smp.h | 6 +- include/asm-mips/floppy.h | 4 +- include/asm-mips/signal.h | 2 + include/asm-ppc/signal.h | 2 + include/asm-sparc/floppy.h | 4 +- include/asm-sparc/signal.h | 2 + include/linux/atalk.h | 4 +- include/linux/genhd.h | 8 + include/linux/if_arp.h | 1 + include/linux/if_ether.h | 6 + include/linux/interrupt.h | 10 + include/linux/sched.h | 9 +- include/linux/xd.h | 2 +- init/main.c | 25 +- kernel/sys.c | 2 +- net/appletalk/aarp.c | 41 +++ net/appletalk/ddp.c | 119 +++++++- net/ethernet/eth.c | 5 +- net/ipv4/af_inet.c | 2 +- net/ipv4/icmp.c | 4 +- net/ipv4/route.c | 2 +- net/ipx/af_ipx.c | 2 +- scripts/lxdialog/checklist.c | 3 +- scripts/tkgen.c | 4 +- 175 files changed, 2932 insertions(+), 1272 deletions(-) create mode 100644 arch/alpha/kernel/alcor.c create mode 100644 include/asm-alpha/alcor.h diff --git a/CREDITS b/CREDITS index 8c5649256a67..637c6fe41fd4 100644 --- a/CREDITS +++ b/CREDITS @@ -348,8 +348,8 @@ N: Nigel Gamble E: nigel@nrg.org E: nigel@sgi.com D: Interrupt-driven printer driver -S: 765 N Rengstorff Ave, Apartment 7 -S: Mountain View, California 94043-2420 +S: 120 Alley Way +S: Mountain View, California 94040 S: USA N: Jacques Gelinas @@ -610,7 +610,7 @@ S: D53424 Remagen S: Germany N: Mark Lord -E: mlord@bnr.ca +E: mlord@pobox.com D: Author of IDE driver (ide.c), hd.c support D: Triton Bus Master IDE driver D: Hard Disk Parameter (hdparm) utility @@ -1040,6 +1040,14 @@ S: 3 Ballow Crescent S: MacGregor A.C.T S: 2615 Australia +N: Winfried Trümper +E: truemper@MI.Uni-Koeln.DE +D: German HOWTO, Enhanced German HOWTO, Crash-Kurs Linux (German) +D: 1- or 5-days tutorials on Linux twice a year (free of charge) +D: Linux-Workshop Köln (aka LUUG cologne, germany) +S: Tacitusstr. 6 +S: D-50968 Köln + N: Theodore Ts'o E: tytso@mit.edu D: Random Linux hacker diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 2459f237f689..978023bb820d 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -66,16 +66,17 @@ CONFIG_BLK_DEV_FD RAM disk support CONFIG_BLK_DEV_RAM - Enabling this option will allow you to use a portion of your RAM memory - as a block device, so that you can make filesystems on it, read and - write to it and do all the other things that normal block devices can do. - It is usually used to load and store a copy of a minimal root file - system off of a floppy into RAM during the initial install of Linux. - Note that the kernel command line option "ramdisk=XX" is now obsolete. - For details, read Documentation/ramdisk.txt. If you want to compile this - as a module ( = code which can be inserted in and removed from the - running kernel whenever you want), say M and read Documentation/modules.txt. - Most normal users won't need the RAM disk functionality, and can thus say + Enabling this option will allow you to use a portion of your RAM + memory as a block device, so that you can make filesystems on it, + read and write to it and do all the other things that normal block + devices (such as harddrives) can do. It is usually used to load and + store a copy of a minimal root file system off of a floppy into RAM + during the initial install of Linux. Note that the kernel command + line option "ramdisk=XX" is now obsolete. For details, read + Documentation/ramdisk.txt. If you want to compile this as a module ( + = code which can be inserted in and removed from the running kernel + whenever you want), say M and read Documentation/modules.txt. Most + normal users won't need the RAM disk functionality, and can thus say N here. Loop device support @@ -85,61 +86,69 @@ CONFIG_BLK_DEV_LOOP burning the CD, or want to use floppy images without first writing them to floppy. This option also allows one to mount a filesystem with encryption. + To use these features, you will need the program losetup, available + via ftp (user: anonymous) from sunsite.unc.edu in the package + lo.X.Y.tar.gz. + Note that this loop device has nothing to do with the loopback + device used for network connections from the machine to itself. Most users will answer N here. Enhanced IDE/MFM/RLL disk/cdrom/tape support CONFIG_BLK_DEV_IDE This will use the full-featured IDE driver to control up to four IDE - interfaces, for a combination of up to eight IDE disk/cdrom/tape drives. - Useful information about large (>540MB) IDE disks, soundcard IDE ports, - and other topics, is all contained in drivers/block/README.ide. - If you have one or more IDE drives, say Y here. - If your system has no IDE drives, or if memory requirements are really tight, - you could say N here, and select the Old harddisk driver instead to save - about 13kB of memory in the kernel. - To fine-tune IDE drive/interface parameters for improved performance, + interfaces, for a combination of up to eight IDE disk/cdrom/tape + drives. Useful information about large (>540MB) IDE disks, + soundcard IDE ports, and other topics, is all contained in + drivers/block/README.ide. If you have one or more IDE drives, say Y + here. If your system has no IDE drives, or if memory requirements + are really tight, you could say N here, and select the Old harddisk + driver instead to save about 13kB of memory in the kernel. To + fine-tune IDE drive/interface parameters for improved performance, look for the hdparm package at sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/ Old harddisk (MFM/RLL/IDE) driver CONFIG_BLK_DEV_HD_ONLY There are two drivers for MFM/RLL/IDE disks. Most people use the - newer enhanced driver, but the old one is still around for two reasons. - Some older systems have strange timing problems and seem to work only - with the old driver (which itself does not work with some newer systems). - The other reason is that the old driver is smaller, since it lacks the - enhanced functionality of the new one. This makes it a good choice - for systems with very tight memory restrictions, or for systems with - only older MFM/RLL/ESDI drives. Choosing the old driver can save 13kB - or so of kernel memory. If you are unsure, then just choose the - Enhanced IDE/MFM/RLL driver instead of this one. + newer enhanced driver, but the old one is still around for two + reasons. Some older systems have strange timing problems and seem + to work only with the old driver (which itself does not work with + some newer systems). The other reason is that the old driver is + smaller, since it lacks the enhanced functionality of the new one. + This makes it a good choice for systems with very tight memory + restrictions, or for systems with only older MFM/RLL/ESDI drives. + Choosing the old driver can save 13kB or so of kernel memory. If + you are unsure, then just choose the Enhanced IDE/MFM/RLL driver + instead of this one. Use old disk-only driver on primary interface CONFIG_BLK_DEV_HD_IDE - There are two drivers for MFM/RLL/IDE disks. Most people use just the - new enhanced driver by itself. This option installs the old harddisk - driver to control the primary IDE/disk interface in the system, - leaving the new enhanced IDE driver take care of only the 2nd/3rd/4th - IDE interfaces. Choosing this option may be useful for older systems - which have MFM/RLL/ESDI controller+drives at the primary port address - (0x1f0), along with IDE drives at the secondary/3rd/4th port addresses. - Normally, just say N here. + There are two drivers for MFM/RLL/IDE disks. Most people use just + the new enhanced driver by itself. This option installs the old + harddisk driver to control the primary IDE/disk interface in the + system, leaving the new enhanced IDE driver take care of only the + 2nd/3rd/4th IDE interfaces. Choosing this option may be useful for + older systems which have MFM/RLL/ESDI controller+drives at the + primary port address (0x1f0), along with IDE drives at the + secondary/3rd/4th port addresses. Normally, just say N here; you + will then use the new driver for all 4 interfaces. Include IDE/ATAPI CDROM support CONFIG_BLK_DEV_IDECD - If you have a CDROM drive using the ATAPI protocol, say Y. - ATAPI is a new protocol used by IDE CDROM and TAPE drives, - similar to the SCSI protocol. Most new CDROM drives use ATAPI, - including the NEC-260, Mitsumi FX400, Sony 55E, and just about - all non-SCSI double(2X), quad(4X), and six(6X) speed drives. - At boot time, the TAPE drive will be identified along with other IDE devices, - as "hdb" or "hdc", or something similar. - If this is your only CDROM drive, you can say N to all other CDROM options, - but be sure to say Y to the ISO9660 filesystem. Read the CDROM-HOWTO, - available via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO. - Note that older versions of lilo (the linux boot loader) cannot properly - deal with IDE/ATAPI CDROMs, so install lilo-16 or higher, available - from sunsite.unc.edu:/pub/Linux/system/Linux-boot/lilo. + If you have a CDROM drive using the ATAPI protocol, say Y. ATAPI is + a new protocol used by IDE CDROM and TAPE drives, similar to the + SCSI protocol. Most new CDROM drives use ATAPI, including the + NEC-260, Mitsumi FX400, Sony 55E, and just about all non-SCSI + double(2X), quad(4X), and six(6X) speed drives. At boot time, the + TAPE drive will be identified along with other IDE devices, as "hdb" + or "hdc", or something similar. + If this is your only CDROM drive, you can say N to all other CDROM + options, but be sure to say Y to the ISO9660 filesystem. Read the + CDROM-HOWTO, available via ftp (user: anonymous) in + sunsite.unc.edu:/pub/Linux/docs/HOWTO. Note that older versions of + lilo (the linux boot loader) cannot properly deal with IDE/ATAPI + CDROMs, so install lilo-16 or higher, available from + sunsite.unc.edu:/pub/Linux/system/Linux-boot/lilo. Include IDE/ATAPI TAPE support CONFIG_BLK_DEV_IDETAPE @@ -188,34 +197,34 @@ CONFIG_IDE_CHIPSETS chipsets. Most of these also require special kernel boot parameters to actually turn on the support at runtime. -DTC-2278 chipset support +DTC-2278 support CONFIG_BLK_DEV_DTC2278 This driver is enabled at runtime using the "ide0=dtc2278" kernel boot parameter. It enables support for the secondary IDE interface of the DTC-2278 card, and permits faster I/O speeds to be set as well. See the README.ide and dtc2278.c files for more info. -Holtek HT6560B chipset support +Holtek HT6560B support CONFIG_BLK_DEV_HT6560B This driver is enabled at runtime using the "ide0=ht6560b" kernel boot parameter. It enables support for the secondary IDE interface of the Holtek card, and permits faster I/O speeds to be set as well. See the README.ide and ht6560b.c files for more info. -QDI QD6580 chipset support +QDI QD6580 support CONFIG_BLK_DEV_QD6580 This driver is enabled at runtime using the "ide0=qd6580" kernel boot parameter. It permits faster I/O speeds to be set. See the README.ide and qd6580.c files for more info. -UMC 8672 chipset support +UMC 8672 support CONFIG_BLK_DEV_UMC8672 This driver is enabled at runtime using the "ide0=umc8672" kernel boot parameter. It enables support for the secondary IDE interface of the UMC-8672, and permits faster I/O speeds to be set as well. See the README.ide and umc8672.c files for more info. -ALI M1439/M1445 chipset support +ALI M1439/M1445 support CONFIG_BLK_DEV_ALI14XX This driver is enabled at runtime using the "ide0=ali14xx" kernel boot parameter. It enables support for the secondary IDE interface @@ -548,7 +557,7 @@ CONFIG_CPU_LITTLE_ENDIAN If your compiler is mipsel-linux-gcc or mipsel-linuxelf-gcc (as opposed to mips-linux-gcc or mips-linuxelf-gcc), say Y here, otherwise N. Most MIPS machines use little-endian code, but it might - be necessary to run older Mips sytems, such as the Sony News and + be necessary to run older Mips systems, such as the Sony News and MIPS RC3xxx in big endian mode. Enable loadable module support @@ -650,6 +659,7 @@ CONFIG_IP_MULTICAST drivers/net/README.multicast. For most people, it's safe to say N. IP: optimize as router not host +CONFIG_IP_ROUTER Some Linux network drivers use a technique called copy and checksum to optimize host performance. For a machine which is forwarding most packets to another host this is however a loss. This parameter turns @@ -848,12 +858,12 @@ CONFIG_IPX sunsite.unc.edu:/pub/Linux/docs/HOWTO). In order to do the former, you'll also have to say Y to "NCP filesystem support", below. To turn your Linux box into a fully featured Netware file server and - IPX router, say Y here and fetch lwared from - sunsite.unc.edu:/pub/Linux/system/Network/daemons/. For more - information, read the IPX-HOWTO in - sunsite.unc.edu:/pub/Linux/docs/howto. The IPX driver would enlarge - your kernel by about 5 kB. Unless you want to integrate your Linux - box with a local Novell network, say N. + IPX router, say Y here and fetch either lwared from + sunsite.unc.edu:/pub/Linux/system/Network/daemons/ or mars_nwe from + linux01.gwdg.de:/pub/ncpfs. For more information, read the IPX-HOWTO + in sunsite.unc.edu:/pub/Linux/docs/howto. The IPX driver would + enlarge your kernel by about 5 kB. Unless you want to integrate your + Linux box with a local Novell network, say N. Full internal IPX network CONFIG_IPX_INTERN @@ -1759,14 +1769,9 @@ NI5210 support CONFIG_NI52 If you have a network (ethernet) card of this type, say Y and read the Ethernet-HOWTO, available via ftp (user: anonymous) in - sunsite.unc.edu:/pub/Linux/docs/HOWTO. This driver is also available - as a module ( = code which can be inserted in and removed from the - running kernel whenever you want). If you want to compile it as a - module, say M here and read Documentation/modules.txt as well as - Documentation/networking/net-modules.txt. If you plan to use more - than one network card under linux, read the - Multiple-Ethernet-mini-HOWTO, available from - sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. + sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you plan to use more than + one network card under linux, read the Multiple-Ethernet-mini-HOWTO, + available from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini. NI6510 support CONFIG_NI65 @@ -2261,27 +2266,28 @@ CONFIG_FAT_FS msdos fs support CONFIG_MSDOS_FS This allows you to mount MSDOS partitions of your harddrive (unless - they are compressed; the only way to access compressed MSDOS - partitions under Linux is with the DOS emulator DOSEMU, described in - the DOSEMU-HOWTO, available via ftp (user: anonymous) at - sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you intend to use dosemu - with a non-compressed MSDOS partition, say Y here) and MSDOS - floppies. This means that file access becomes transparent, i.e. the - MSDOS files look and behave just like all other Unix files. Another - way to read and write MSDOS floppies from within Linux (but not - transparently) is with the mtools ("man mtools") program suite, + they are compressed; to access compressed MSDOS partitions under + Linux, you can either use the DOS emulator DOSEMU, described in the + DOSEMU-HOWTO, available via ftp (user: anonymous) at + sunsite.unc.edu:/pub/Linux/docs/HOWTO, or try dmsdosfs in + sunsite.unc.edu:/pub/Linux/system/Filesystems/dosfs. If you intend + to use dosemu with a non-compressed MSDOS partition, say Y here) and + MSDOS floppies. This means that file access becomes transparent, + i.e. the MSDOS files look and behave just like all other Unix files. + Another way to read and write MSDOS floppies from within Linux (but + not transparently) is with the mtools ("man mtools") program suite, which doesn't require the msdos filesystem support. If you want to use umsdos, the Unix-like filesystem on top of DOS, which allows you to run Linux from within a DOS partition without repartitioning, - you'll have to say Y or M here. If your have Windows'95 or Windows NT - installed on your MSDOS partitions, you should use the VFAT - filesystem instead, or you will not be able to see the long filenames - generated by Windows'95 / Windows NT. This option will enlarge your - kernel by about 7 kB. If unsure, say Y. If you want to compile this - as a module however ( = code which can be inserted in and removed from - the running kernel whenever you want), say M here and read - Documentation/modules.txt. Note that the filesystem of your root - partition cannot be a module. + you'll have to say Y or M here. If your have Windows'95 or Windows + NT installed on your MSDOS partitions, you should use the VFAT + filesystem instead, or you will not be able to see the long + filenames generated by Windows'95 / Windows NT. This option will + enlarge your kernel by about 7 kB. If unsure, say Y. If you want to + compile this as a module however ( = code which can be inserted in + and removed from the running kernel whenever you want), say M here + and read Documentation/modules.txt. Note that the filesystem of your + root partition cannot be a module. vfat fs support CONFIG_VFAT_FS @@ -2320,9 +2326,9 @@ CONFIG_PROC_FS This is a virtual filesystem providing information about the status of the system. "Virtual" means that it doesn't take any space on your harddisk: the files are created on the fly when you access - them. Also, you cannot read the files with less or more: you need to - use cat. The filesystem is explained in the Kernel Hacker's Guide, - available via ftp (user: anonymous) in + them. Also, you cannot read the files with less: you need to use + more or cat. The filesystem is explained in the Kernel Hacker's + Guide, available via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/LDP and also on the proc(8) manpage ("man 8 proc"). This option will enlarge your kernel by about 18 kB. It's totally cool; for example, "cat /proc/interrupts" gives @@ -2445,12 +2451,12 @@ CONFIG_NCP_FS used by NetWare clients to talk to file servers. It is to IPX what nfs is to tcp/ip, if that helps. Enabling this option allows you to mount NetWare file server volumes and to access them just like any - other Unix directory. To actually mount the filesystem, you need a - special mount program, as described in the IPX-HOWTO on - sunsite.unc.edu:/pub/Linux/docs/howto. If you want to compile this - 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. + other Unix directory. For details, please read the file + Documentation/filesystems/ncpfs.txt in the kernel source and the + IPX-HOWTO on sunsite.unc.edu:/pub/Linux/docs/howto. If you want to + compile this 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. Standard/generic serial support CONFIG_SERIAL @@ -2492,7 +2498,8 @@ CONFIG_STALLION n running kernel whenever you want), say M here and read Documentation/modules.txt. -CONFIG_ISTALLION n +Stallion EC8/64, ONboard, Brumby support +CONFIG_ISTALLION If you have an EasyConnection 8/64, ONboard, Brumby or Stallion serial multiport card, say Y here. Make sure to read drivers/char/README.stallion. To compile it as a module ( = code @@ -2585,20 +2592,6 @@ CONFIG_ATIXL_BUSMOUSE plugging in a COM port (9 or 25 pins) which is supported automatically. -Selection (cut and paste for virtual consoles) -CONFIG_SELECTION - This allows you to use your mouse for moving text on a Linux console - or even between several virtual consoles. Read about it with "man - selection". You also need it to run gpm ("general purpose mouse") - which is a superset of selection. This is explained in the - Busmouse-HOWTO, available via ftp (user: anonymous) in - sunsite.unc.edu:/pub/Linux/docs/HOWTO, although selection works fine - with serial mice, too. Most people say Y unless they run mainly the - X Window System, which has its own cut-and-paste mechanism. Enabling - this option enlarges your kernel by about 1 kB. Newer kernels - contain this code by default and don't have this config option - anymore. - QIC-02 tape support CONFIG_QIC02_TAPE If you have a non-SCSI tape drive like that, say Y. @@ -2652,45 +2645,58 @@ CONFIG_APM_IGNORE_USER_SUSPEND Enable APM features CONFIG_APM_DO_ENABLE Enable APM features at boot time. From page 36 of the APM BIOS - specification: "When disabled, the APM BIOS does not automatically power - manage devices, enter the Standby State, enter the Suspend State, or take - power saving steps in response to CPU Idle calls." This driver will make - CPU Idle calls when Linux is idle (unless this feature is turned off -- - see below). This should always save battery power, but more complicated - APM features will be dependent on your BIOS implementation. You may need - to turn this option off if your computer hangs at boot time when using - APM support, or if it beeps continuously instead of suspending. Turn - this off if you have a NEC UltraLite Versa 33/C or a Toshiba T400CDT. - This is off by default since most machines do fine without this feature. + specification: "When disabled, the APM BIOS does not automatically + power manage devices, enter the Standby State, enter the Suspend + State, or take power saving steps in response to CPU Idle calls." + This driver will make CPU Idle calls when Linux is idle (unless this + feature is turned off -- see below). This should always save + battery power, but more complicated APM features will be dependent + on your BIOS implementation. You may need to turn this option off + if your computer hangs at boot time when using APM support, or if it + beeps continuously instead of suspending. Turn this off if you have + a NEC UltraLite Versa 33/C or a Toshiba T400CDT. This is off by + default since most machines do fine without this feature. Watchdog Timer Support CONFIG_WATCHDOG If you enable this option and create a character special file /dev/watchdog with major number 10 and minor number 130 using mknod - ("man mknod"), you will get a software watchdog, i.e.: subsequently - opening the file and failing to write to it for longer than 1 minute - will result in rebooting the machine. This could be useful for a + ("man mknod"), you will get a watchdog, i.e.: subsequently opening + the file and failing to write to it for longer than 1 minute will + result in rebooting the machine. This could be useful for a networked machine that needs to come back online as fast as possible - after a lock-up. For details, read Documentation/watchdog.txt in the - kernel source. If unsure, say N. + after a lock-up. There's a watchdog implementation entirely in + software (which sometimes fail to reboot the machine) and a driver + for hardware watchdog boards, which are more robust and can also + keep track of the temperature inside your computer. For details, + read Documentation/watchdog.txt in the kernel source. If unsure, say + N. Disable watchdog shutdown on close CONFIG_WATCHDOG_NOWAYOUT The default watchdog behaviour is to stop the timer if the process - managing it closes the file. Its always remotely possible that this - process might get killed. In NOWAYOUT mode you cannot stop the watchdog - once its begun. + managing it closes the file /dev/watchdog. It's always remotely + possible that this process might get killed. If you enable this + option, the watchdog cannot be stopped once it has been started. WDT Watchdog timer CONFIG_WDT - Drivers for the WDT watchdog timer cards. These are hardware timer boards - that physically pull the power on and off to recover crashed machines. - Brutal but _very_ effective. + If you have a WDT500P or WDT501P watchdog board, say Y here, + otherwise N. It is not possible to probe for this board, which means + that you have to set the IO port and IRQ it uses in the kernel + source at the top of drivers/char/wdt.c. If you want to compile this + 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. WDT501 features CONFIG_WDT_501 - Enable the onboard thermometer and voltage monitors on the extended (501) - card. + Saying Y here and creating a character special file /dev/temperature + with major number 10 and minor number 131 ("man mknod") will give + you a thermometer inside your computer: reading from + /dev/temperature yields one byte, the temperature in degrees + Fahrenheit. This works only if you have a WDT501P watchdog board + installed. Fan Tachometer CONFIG_WDT_501_FAN @@ -2698,26 +2704,27 @@ CONFIG_WDT_501_FAN tachometer actually set up. Software Watchdog -CONFIG_SOFT_WATDHDOG - A software monitoring watchdog. This will fail to reboot your system from - some situations that the hardware watchdog will recover from. Equally its - a lot cheaper to install. +CONFIG_SOFT_WATCHDOG + A software monitoring watchdog. This will fail to reboot your system + from some situations that the hardware watchdog will recover + from. Equally it's a lot cheaper to install. Do CPU IDLE calls CONFIG_APM_CPU_IDLE - Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop. On - some machines, this can activate improved power savings, such as a slowed - CPU clock rate, when the machine is idle. These idle call is made after - the idle loop has run for some length of time (e.g., 333 mS). On some - machines, this will cause a hang at boot time or whenever the CPU becomes - idle. (On machines with more than one CPU, this option does nothing.) + Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop. + On some machines, this can activate improved power savings, such as + a slowed CPU clock rate, when the machine is idle. These idle call + is made after the idle loop has run for some length of time (e.g., + 333 mS). On some machines, this will cause a hang at boot time or + whenever the CPU becomes idle. (On machines with more than one CPU, + this option does nothing.) Black display CONFIG_APM_DISPLAY_BLANK - Enable console blanking using the APM. Some laptops can use this to turn - off the LCD backlight when the VC screen blanker blanks the screen. Note - that this is only used by the VC screen blanker, and won't turn off the - backlight when using X11. + Enable console blanking using the APM. Some laptops can use this to + turn off the LCD backlight when the VC screen blanker blanks the + screen. Note that this is only used by the VC screen blanker, and + won't turn off the backlight when using X11. Sound card support CONFIG_SOUND @@ -2762,48 +2769,50 @@ CONFIG_PROFILE_SHIFT ISDN subsystem CONFIG_ISDN - This allows you to use an ISDN-card for networking connections and as - dialin/out device. The isdn-tty's have a builtin AT-compatible modem - emulator. Network devices support autodial, channel-bundling, callback - and caller-authentication without having a daemon running. A reduced T.70 - protocol is supported with tty's suitable for german BTX. Currently Cards - by Teles and compatibles and ICN are supported. On D-Channel, the protocols - EDSS1 and 1TR6 are supported. See Documentation/isdn/README for more - information. + This allows you to use an ISDN-card for networking connections and + as dialin/out device. The isdn-tty's have a built in AT-compatible + modem emulator. Network devices support autodial, channel-bundling, + callback and caller-authentication without having a daemon + running. A reduced T.70 protocol is supported with tty's suitable + for German BTX. Currently Cards by Teles and compatibles and ICN are + supported. On D-Channel, the protocols EDSS1 and 1TR6 are + supported. See Documentation/isdn/README for more information. Support synchronous PPP CONFIG_ISDN_PPP - This enables synchronous PPP via ISDN. This protocol is used by Cisco - or Sun for example. You will need a special version of pppd (called ipppd) - for using this feature. See Documentation/isdn/README.syncppp for more - information. + This enables synchronous PPP via ISDN. This protocol is used by + Cisco or Sun for example. You will need a special version of pppd + (called ipppd) for using this feature. See + Documentation/isdn/README.syncppp for more information. -Sypport generic MP (RFC 1717) +Support generic MP (RFC 1717) CONFIG_ISDN_MPP - With synchronous PPP enabled, it is possible to increase throughput by - bundling several ISDN-connections, using this protocol. See + With synchronous PPP enabled, it is possible to increase throughput + by bundling several ISDN-connections, using this protocol. See Documentation/isdn/README.syncppp for more information. Use VJ-compression with synchronous PPP CONFIG_ISDN_PPP_VJ - This enables Van Jacobson headercompression for synchronous PPP. + This enables Van Jacobson header compression for synchronous PPP. ICN B1 and B2 support CONFIG_ISDN_DRV_ICN - This enables support for two kinds of ISDN-cards made by a german company - called ICN. 1B is the standard version for a single ISDN line with two - B-channels, 2B supports two ISDN lines. For running this card, additional - firmware is necessary, which has to be downloaded into the card using - a utility which is distributed separately. - See Documentation/isdn/README and README.icn for more information. + This enables support for two kinds of ISDN-cards made by a German + company called ICN. 1B is the standard version for a single ISDN + line with two B-channels, 2B supports two ISDN lines. For running + this card, additional firmware is necessary, which has to be + downloaded into the card using a utility which is distributed + separately. See Documentation/isdn/README and README.icn for more + information. Teles, NICCY1016PC, Creatix support CONFIG_ISDN_DRV_TELES - This enables support for the Teles ISDN-cards S0-16.0, S0-16.3, S0-8 and - many compatibles. By default, the driver is configured to support - a 16.0-type using EDSS1-protocol. See Documentation/isdn/README - on how to configure it using 16.3, a different D-channel protocol, or - non-standard irq/port/shmem settings. + This enables support for the Teles ISDN-cards S0-16.0, S0-16.3, S0-8 + and many compatibles. By default, the driver is configured to + support a 16.0-type using EDSS1-protocol. See + Documentation/isdn/README on how to configure it using 16.3, a + different D-channel protocol, or non-standard irq/port/shmem + settings. # need an empty line after last entry, for sed script in Configure. @@ -2862,6 +2871,8 @@ CONFIG_ISDN_DRV_TELES # LocalWords: wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI # LocalWords: QD qd UMC umc ALI ali lena fnet fr homepage azstarnet axplinux # LocalWords: Avanti XL AlphaStations Jensen DECpc AXPpci UDB Cabriolet MCA RC -# LocalWords: AlphaPC uwaterloo cpbeaure mca AOUT OUTput PPro sipx gwdg +# LocalWords: AlphaPC uwaterloo cpbeaure mca AOUT OUTput PPro sipx gwdg lo nwe # LocalWords: Keepalive linefill RELCOM keepalive analogue CDR conf CDI INIT -# LocalWords: OPTi isp irq noisp VFAT vfat NTFS +# LocalWords: OPTi isp irq noisp VFAT vfat NTFS losetup dmsdosfs dosfs ISDN MP +# LocalWords: NOWAYOUT behaviour dialin isdn callback BTX Teles ICN EDSS Cisco +# LocalWords: ipppd syncppp RFC MPP VJ downloaded icn NICCY Creatix shmem diff --git a/Documentation/devices.tex b/Documentation/devices.tex index ecd257ceba40..13062aa4f4af 100644 --- a/Documentation/devices.tex +++ b/Documentation/devices.tex @@ -42,7 +42,7 @@ foo \kill}% % \title{{\bf Linux Allocated Devices}} \author{Maintained by H. Peter Anvin $<$hpa@storm.net$>$} -\date{Last revised: February 17, 1996} +\date{Last revised: February 24, 1996} \maketitle % \noindent @@ -88,6 +88,7 @@ an unreasonable effort. \major{ 5}{}{char }{Alternate TTY devices} \major{ 6}{}{char }{Parallel printer devices} \major{ 7}{}{char }{Virtual console access devices} +\major{ }{}{block}{Loopback devices} \major{ 8}{}{block}{SCSI disk devices} \major{ 9}{}{char }{SCSI tape devices} \major{ }{}{block}{Metadisk (RAID) devices} @@ -147,8 +148,9 @@ an unreasonable effort. \major{37}{}{char }{IDE tape} \major{ }{}{block}{Zorro II ramdisk} \major{38}{}{char }{Myricom PCI Myrinet board} -\major{39}{--40}{}{Unallocated} -\major{41}{}{char}{Yet Another Micro Monitor} +\major{39}{}{char }{ML-16P experimental I/O board} +\major{40}{}{}{Unallocated} +\major{41}{}{char }{Yet Another Micro Monitor} \major{42}{}{}{Demo/sample use} \major{43}{}{char }{isdn4linux virtual modem} \major{44}{}{char }{isdn4linux virtual modem -- alternate devices} @@ -350,6 +352,17 @@ Not all computers have the {\hex 0x3bc} parallel port, hence the \noindent NOTE: These devices permit both read and write access. +\major{ }{}{block}{Loopback devices} + \minor{0}{/dev/loop0}{First loopback device} + \minor{1}{/dev/loop1}{Second loopback device} + \minordots +\end{devicelist} + +\noindent +The loopback devices are used to mount filesystems not associated with +block devices. The binding to the loopback devices is usually handled +by mount(1). + \begin{devicelist} \major{ 8}{}{block}{SCSI disk devices} \minor{0}{/dev/sda}{First SCSI disk whole disk} @@ -870,7 +883,28 @@ packet I/O''. The board is also accessible as a regular {\file eth} networking device. \begin{devicelist} -\major{39}{--40}{}{Unallocated} +\major{39}{}{char }{ML-16P experimental I/O board} + \minor{0}{/dev/ml16pa-a0}{First card, first analog channel} + \minor{1}{/dev/ml16pa-a1}{First card, second analog channel} + \minordots + \minor{15}{/dev/ml16pa-a15}{First card, 16th analog channel} + \minor{16}{/dev/ml16pa-d}{First card, digital lines} + \minor{17}{/dev/ml16pa-c0}{First card, first counter/timer} + \minor{18}{/dev/ml16pa-c1}{First card, second counter/timer} + \minor{19}{/dev/ml16pa-c2}{First card, third counter/timer} + \minor{32}{/dev/ml16pb-a0}{Second card, first analog channel} + \minor{33}{/dev/ml16pb-a1}{Second card, second analog channel} + \minordots + \minor{47}{/dev/ml16pb-a15}{Second card, 16th analog channel} + \minor{48}{/dev/ml16pb-d}{Second card, digital lines} + \minor{49}{/dev/ml16pb-c0}{Second card, first counter/timer} + \minor{50}{/dev/ml16pb-c1}{Second card, second counter/timer} + \minor{51}{/dev/ml16pb-c2}{Second card, third counter/timer} + \minordots +\end{devicelist} + +\begin{devicelist} +\major{40}{}{}{Unallocated} \end{devicelist} \begin{devicelist} diff --git a/Documentation/devices.txt b/Documentation/devices.txt index cc880eafc561..0932f2fe82c0 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -2,7 +2,7 @@ Maintained by H. Peter Anvin - Last revised: February 17, 1996 + Last revised: February 24, 1996 This list is the successor to Rick Miller's Linux Device List, which he stopped maintaining when he got busy with other things in 1993. It @@ -187,6 +187,15 @@ an unreasonable effort. NOTE: These devices permit both read and write access. + block Loopback devices + 0 = /dev/loop0 First loopback device + 1 = /dev/loop1 Second loopback device + ... + + The loopback devices are used to mount filesystems not + associated with block devices. The binding to the + loopback devices is usually handled by mount(1). + 8 block SCSI disk devices 0 = /dev/sda First SCSI disk whole disk 16 = /dev/sdb Second SCSI disk whole disk @@ -589,7 +598,25 @@ an unreasonable effort. and "user level packet I/O." This board is also accessible as a standard networking "eth" device. - 39-40 UNALLOCATED + 39 char ML-16P experimental I/O board + 0 = /dev/ml16pa-a0 First card, first analog channel + 1 = /dev/ml16pa-a1 First card, second analog channel + ... + 15 = /dev/ml16pa-a15 First card, 16th analog channel + 16 = /dev/ml16pa-d First card, digital lines + 17 = /dev/ml16pa-c0 First card, first counter/timer + 18 = /dev/ml16pa-c1 First card, second counter/timer + 19 = /dev/ml16pa-c2 First card, third counter/timer + 32 = /dev/ml16pb-a0 Second card, first analog channel + 33 = /dev/ml16pb-a1 Second card, second analog channel + ... + 47 = /dev/ml16pb-a15 Second card, 16th analog channel + 48 = /dev/ml16pb-d Second card, digital lines + 49 = /dev/ml16pb-c0 Second card, first counter/timer + 50 = /dev/ml16pb-c1 Second card, second counter/timer + 51 = /dev/ml16pb-c2 Second card, third counter/timer + + 40 UNALLOCATED 41 Yet Another Micro Monitor 0 = /dev/yamm Yet Another Micro Monitor diff --git a/Documentation/isdn/README.teles b/Documentation/isdn/README.teles index 19d8da3d1d93..e718c9fd213e 100644 --- a/Documentation/isdn/README.teles +++ b/Documentation/isdn/README.teles @@ -27,7 +27,7 @@ Oct 11 16:53:31 jedi kernel: Teles module installed Remember, that according to the new strategy for accessing Low-level-drivers from within isdn4linux you should also define a driver-id while doing -insmod: Simply append id= to the insmod-commandline. This +insmod: Simply append teles_id= to the insmod-commandline. This string MUST NOT start with a digit or a small 'x'! At this point you can run a 'cat /dev/isdnctrl0' and view debugging diff --git a/MAINTAINERS b/MAINTAINERS index c3ffb8e7fd13..f37619910c9a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -55,7 +55,7 @@ S: Status Odd Fixes: It has a maintainer but they don't have time to do much other than throw the odd patch in. See below.. Orphan: No current maintainer [but maybe you could take the - role as you write your new driver]. + role as you write your new code]. Obsolete: Ex code. Something tagged obsolete generally means its been replaced by a better system and you should be using that. @@ -84,6 +84,12 @@ M: net-patches@lxorguk.ukuu.org.uk L: linux-ipx@vger.rutgers.edu [will change] S: Maintained +ISDN SUBSYSTEM +P: Fritz Elfert +M: fritz@wuemaus.franken.de +L: isdn4linux@hub-wue.franken.de +S: Maintained + NETROM NETWORK LAYER P: Jon Naylor M: jsn@cs.nott.ac.uk diff --git a/Makefile b/Makefile index d22d9dfc35bd..666a48372328 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 3 -SUBLEVEL = 69 +SUBLEVEL = 70 ARCH = i386 diff --git a/Rules.make b/Rules.make index c29c6c7b3b61..5a2c36e0f70a 100644 --- a/Rules.make +++ b/Rules.make @@ -101,7 +101,7 @@ endif # ALL_MOBJS = $(MX_OBJS) $(M_OBJS) ifneq "$(strip $(ALL_MOBJS))" "" -PDWN=$(shell /bin/sh $(TOPDIR)/scripts/pathdown.sh) +PDWN=$(shell $(CONFIG_SHELL) $(TOPDIR)/scripts/pathdown.sh) endif modules: $(ALL_MOBJS) dummy ifdef MOD_SUB_DIRS diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 94ece7c10112..1b597abe897f 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -33,6 +33,7 @@ choice 'Alpha system type' \ EB66 CONFIG_ALPHA_EB66 \ EB66+ CONFIG_ALPHA_EB66P \ EB64+ CONFIG_ALPHA_EB64P \ + EB164 CONFIG_ALPHA_EB164 \ Jensen CONFIG_ALPHA_JENSEN \ Noname CONFIG_ALPHA_NONAME \ Platform2000 CONFIG_ALPHA_P2K" Cabriolet @@ -49,6 +50,12 @@ then define_bool CONFIG_PCI y define_bool CONFIG_ALPHA_APECS y fi +if [ "$CONFIG_ALPHA_EB164" = "y" ] +then + define_bool CONFIG_PCI y + define_bool CONFIG_ALPHA_EV5 y + define_bool CONFIG_ALPHA_ALCOR y +fi # This needs to be defined for all EV4 and EV45 CPUs: define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y bool 'Echo console messages on /dev/ttyS1' CONFIG_SERIAL_ECHO diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index f58ad9f9a8fc..6d35ca726a35 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -13,16 +13,17 @@ CONFIG_MODULES=y # CONFIG_NATIVE=y # CONFIG_ALPHA_AVANTI is not set -# CONFIG_ALPHA_JENSEN is not set -# CONFIG_ALPHA_NONAME is not set # CONFIG_ALPHA_CABRIOLET is not set -# CONFIG_ALPHA_P2K is not set # CONFIG_ALPHA_EB66 is not set # CONFIG_ALPHA_EB66P is not set -CONFIG_ALPHA_EB64P=y -# CONFIG_ALPHA_SRM is not set +# CONFIG_ALPHA_EB64P is not set +CONFIG_ALPHA_EB164=y +# CONFIG_ALPHA_JENSEN is not set +# CONFIG_ALPHA_NONAME is not set +# CONFIG_ALPHA_P2K is not set CONFIG_PCI=y -CONFIG_ALPHA_APECS=y +CONFIG_ALPHA_EV5=y +CONFIG_ALPHA_ALCOR=y CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y # CONFIG_SERIAL_ECHO is not set # CONFIG_TGA_CONSOLE is not set @@ -33,24 +34,19 @@ CONFIG_BINFMT_AOUT=y # CONFIG_BINFMT_ELF is not set # -# Block devices +# Floppy, IDE, and other block devices # CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_RAM is not set -CONFIG_ST506=y +# CONFIG_BLK_DEV_IDE is not set # # Please see drivers/block/README.ide for help/info on IDE drives # -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_RZ1000 is not set -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_TRITON is not set -# CONFIG_IDE_CHIPSETS is not set +# CONFIG_BLK_DEV_HD_ONLY is not set +CONFIG_BLK_DEV_RAM=y +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_MD is not set # # Networking options diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 72170729cf92..f5bb0925c309 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -16,7 +16,7 @@ all: kernel.o head.o O_TARGET := kernel.o O_OBJS := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \ - bios32.o ptrace.o time.o apecs.o lca.o ksyms.o + bios32.o ptrace.o time.o apecs.o lca.o alcor.o ksyms.o all: kernel.o head.o diff --git a/arch/alpha/kernel/alcor.c b/arch/alpha/kernel/alcor.c new file mode 100644 index 000000000000..1ad0ae858aff --- /dev/null +++ b/arch/alpha/kernel/alcor.c @@ -0,0 +1,472 @@ +/* + * Code common to all ALCOR chips. + * + * Written by David A Rusling (david.rusling@reo.mts.dec.com). + * December 1995. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern struct hwrpb_struct *hwrpb; +extern asmlinkage void wrmces(unsigned long mces); +extern int alpha_sys_type; +/* + * BIOS32-style PCI interface: + */ + +#ifdef CONFIG_ALPHA_ALCOR + +#ifdef DEBUG +# define DBG(args) printk args +#else +# define DBG(args) +#endif + +#define vulp volatile unsigned long * +#define vuip volatile unsigned int * + +static volatile unsigned int ALCOR_mcheck_expected = 0; +static volatile unsigned int ALCOR_mcheck_taken = 0; +static unsigned long ALCOR_jd, ALCOR_jd1, ALCOR_jd2; + + +/* + * Given a bus, device, and function number, compute resulting + * configuration space address and setup the ALCOR_HAXR2 register + * accordingly. It is therefore not safe to have concurrent + * invocations to configuration space access routines, but there + * really shouldn't be any need for this. + * + * Type 0: + * + * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 31:11 Device select bit. + * 10:8 Function number + * 7:2 Register number + * + * Type 1: + * + * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 31:24 reserved + * 23:16 bus number (8 bits = 128 possible buses) + * 15:11 Device number (5 bits) + * 10:8 function number + * 7:2 register number + * + * Notes: + * The function number selects which function of a multi-function device + * (e.g., scsi and ethernet). + * + * The register selects a DWORD (32 bit) register offset. Hence it + * doesn't get shifted by 2 bits as we want to "drop" the bottom two + * bits. + */ +static int mk_conf_addr(unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned long *pci_addr, + unsigned char *type1) +{ + unsigned long addr; + + DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p, type1=0x%p)\n", + bus, device_fn, where, pci_addr, type1)); + + if (bus == 0) { + int device = device_fn >> 3; + + /* type 0 configuration cycle: */ + + if (device > 20) { + DBG(("mk_conf_addr: device (%d) > 20, returning -1\n", device)); + return -1; + } + + *type1 = 0; + addr = (device_fn << 8) | (where); + } else { + /* type 1 configuration cycle: */ + *type1 = 1; + addr = (bus << 16) | (device_fn << 8) | (where); + } + *pci_addr = addr; + DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); + return 0; +} + + +static unsigned int conf_read(unsigned long addr, unsigned char type1) +{ + unsigned long flags; + unsigned int stat0, value; + unsigned int cia_cfg = 0; /* to keep gcc quiet */ + + save_flags(flags); /* avoid getting hit by machine check */ + cli(); + + DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); + + /* reset status register to avoid losing errors: */ + stat0 = *((volatile unsigned int *)ALCOR_IOC_CIA_ERR); + *((volatile unsigned int *)ALCOR_IOC_CIA_ERR) = stat0; + mb(); + DBG(("conf_read: ALCOR CIA ERR was 0x%x\n", stat0)); + /* if Type1 access, must set CIA CFG */ + if (type1) { + cia_cfg = *((unsigned int *)ALCOR_IOC_CFG); + mb(); + *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg | 1; + DBG(("conf_read: TYPE1 access\n")); + } + + draina(); + ALCOR_mcheck_expected = 1; + ALCOR_mcheck_taken = 0; + mb(); + /* access configuration space: */ + value = *((volatile unsigned int *)addr); + mb(); + mb(); + if (ALCOR_mcheck_taken) { + ALCOR_mcheck_taken = 0; + value = 0xffffffffU; + mb(); + } + ALCOR_mcheck_expected = 0; + mb(); + /* + * david.rusling@reo.mts.dec.com. This code is needed for the + * EB64+ as it does not generate a machine check (why I don't + * know). When we build kernels for one particular platform + * then we can make this conditional on the type. + */ +#if 1 + draina(); + + /* now look for any errors */ + stat0 = *((unsigned int *)ALCOR_IOC_CIA_ERR); + DBG(("conf_read: ALCOR CIA ERR after read 0x%x\n", stat0)); + if (stat0 & 0x8280U) { /* is any error bit set? */ + /* if not NDEV, print status */ + if (!(stat0 & 0x0080)) { + printk("ALCOR.c:conf_read: got stat0=%x\n", stat0); + } + + /* reset error status: */ + *((volatile unsigned long *)ALCOR_IOC_CIA_ERR) = stat0; + mb(); + wrmces(0x7); /* reset machine check */ + value = 0xffffffff; + } +#endif + + /* if Type1 access, must reset IOC CFG so normal IO space ops work */ + if (type1) { + *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg & ~1; + mb(); + } + + DBG(("conf_read(): finished\n")); + + restore_flags(flags); + return value; +} + + +static void conf_write(unsigned long addr, unsigned int value, unsigned char type1) +{ + unsigned long flags; + unsigned int stat0; + unsigned int cia_cfg = 0; /* to keep gcc quiet */ + + save_flags(flags); /* avoid getting hit by machine check */ + cli(); + + /* reset status register to avoid losing errors: */ + stat0 = *((volatile unsigned int *)ALCOR_IOC_CIA_ERR); + *((volatile unsigned int *)ALCOR_IOC_CIA_ERR) = stat0; + mb(); + DBG(("conf_write: ALCOR CIA ERR was 0x%x\n", stat0)); + /* if Type1 access, must set CIA CFG */ + if (type1) { + cia_cfg = *((unsigned int *)ALCOR_IOC_CFG); + mb(); + *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg | 1; + DBG(("conf_read: TYPE1 access\n")); + } + + draina(); + ALCOR_mcheck_expected = 1; + mb(); + /* access configuration space: */ + *((volatile unsigned int *)addr) = value; + mb(); + mb(); + ALCOR_mcheck_expected = 0; + mb(); + /* + * david.rusling@reo.mts.dec.com. This code is needed for the + * EB64+ as it does not generate a machine check (why I don't + * know). When we build kernels for one particular platform + * then we can make this conditional on the type. + */ +#if 1 + draina(); + + /* now look for any errors */ + stat0 = *((unsigned int *)ALCOR_IOC_CIA_ERR); + DBG(("conf_write: ALCOR CIA ERR after write 0x%x\n", stat0)); + if (stat0 & 0x8280U) { /* is any error bit set? */ + /* if not NDEV, print status */ + if (!(stat0 & 0x0080)) { + printk("ALCOR.c:conf_read: got stat0=%x\n", stat0); + } + + /* reset error status: */ + *((volatile unsigned long *)ALCOR_IOC_CIA_ERR) = stat0; + mb(); + wrmces(0x7); /* reset machine check */ + value = 0xffffffff; + } +#endif + + /* if Type1 access, must reset IOC CFG so normal IO space ops work */ + if (type1) { + *((unsigned int *)ALCOR_IOC_CFG) = cia_cfg & ~1; + mb(); + } + + DBG(("conf_write(): finished\n")); + restore_flags(flags); +} + + +int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned char *value) +{ + unsigned long addr = ALCOR_CONF; + unsigned long pci_addr; + unsigned char type1; + + *value = 0xff; + + if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) { + return PCIBIOS_SUCCESSFUL; + } + + addr |= (pci_addr << 5) + 0x00; + + *value = conf_read(addr, type1) >> ((where & 3) * 8); + + return PCIBIOS_SUCCESSFUL; +} + + +int pcibios_read_config_word (unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned short *value) +{ + unsigned long addr = ALCOR_CONF; + unsigned long pci_addr; + unsigned char type1; + + *value = 0xffff; + + if (where & 0x1) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) { + return PCIBIOS_SUCCESSFUL; + } + + addr |= (pci_addr << 5) + 0x08; + + *value = conf_read(addr, type1) >> ((where & 3) * 8); + return PCIBIOS_SUCCESSFUL; +} + + +int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned int *value) +{ + unsigned long addr = ALCOR_CONF; + unsigned long pci_addr; + unsigned char type1; + + *value = 0xffffffff; + if (where & 0x3) { + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) { + return PCIBIOS_SUCCESSFUL; + } + addr |= (pci_addr << 5) + 0x18; + *value = conf_read(addr, type1); + return PCIBIOS_SUCCESSFUL; +} + + +int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned char value) +{ + unsigned long addr = ALCOR_CONF; + unsigned long pci_addr; + unsigned char type1; + + if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) { + return PCIBIOS_SUCCESSFUL; + } + addr |= (pci_addr << 5) + 0x00; + conf_write(addr, value << ((where & 3) * 8), type1); + return PCIBIOS_SUCCESSFUL; +} + + +int pcibios_write_config_word (unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned short value) +{ + unsigned long addr = ALCOR_CONF; + unsigned long pci_addr; + unsigned char type1; + + if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) { + return PCIBIOS_SUCCESSFUL; + } + addr |= (pci_addr << 5) + 0x08; + conf_write(addr, value << ((where & 3) * 8), type1); + return PCIBIOS_SUCCESSFUL; +} + + +int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn, + unsigned char where, unsigned int value) +{ + unsigned long addr = ALCOR_CONF; + unsigned long pci_addr; + unsigned char type1; + + if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) { + return PCIBIOS_SUCCESSFUL; + } + addr |= (pci_addr << 5) + 0x18; + conf_write(addr, value << ((where & 3) * 8), type1); + return PCIBIOS_SUCCESSFUL; +} + + +unsigned long alcor_init(unsigned long mem_start, unsigned long mem_end) +{ + unsigned int cia_err ; + + /* + * Set up error reporting. + */ + cia_err = *(vuip)ALCOR_IOC_CIA_ERR ; + cia_err |= (0x1 << 7) ; /* master abort */ + *(vuip)ALCOR_IOC_CIA_ERR = cia_err ; + mb() ; + + /* + * Set up the PCI->physical memory translation windows. + * For now, windows 1,2 and 3 are disabled. In the future, we may + * want to use them to do scatter/gather DMA. Window 0 + * goes at 1 GB and is 1 GB large. + */ + + *(vuip)ALCOR_IOC_PCI_W0_BASE = 1U | (ALCOR_DMA_WIN_BASE & 0xfff00000U); + *(vuip)ALCOR_IOC_PCI_W0_MASK = (ALCOR_DMA_WIN_SIZE - 1) & 0xfff00000U; + *(vuip)ALCOR_IOC_PCI_T0_BASE = 0; + + *(vuip)ALCOR_IOC_PCI_W1_BASE = 0x0 ; + *(vuip)ALCOR_IOC_PCI_W2_BASE = 0x0 ; + *(vuip)ALCOR_IOC_PCI_W3_BASE = 0x0 ; + + /* + * check ASN in HWRPB for validity, report if bad + */ + if (hwrpb->max_asn != MAX_ASN) { + printk("alcor_init: max ASN from HWRPB is bad (0x%lx)\n", + hwrpb->max_asn); + hwrpb->max_asn = MAX_ASN; + } + + return mem_start; +} + +int ALCOR_pci_clr_err(void) +{ + ALCOR_jd = *((unsigned int *)ALCOR_IOC_CIA_ERR); + DBG(("ALCOR_pci_clr_err: ALCOR CIA ERR after read 0x%x\n", ALCOR_jd)); + *((unsigned long *)ALCOR_IOC_CIA_ERR) = 0x0080; + mb(); + return 0; +} + +void alcor_machine_check(unsigned long vector, unsigned long la_ptr, + struct pt_regs * regs) +{ +#if 1 + printk("ALCOR machine check\n") ; +#else + struct el_common *mchk_header; + struct el_ALCOR_sysdata_mcheck *mchk_sysdata; + + mchk_header = (struct el_common *)la_ptr; + + mchk_sysdata = + (struct el_ALCOR_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset); + + DBG(("ALCOR_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr)); + DBG((" pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n", + regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset)); + DBG(("ALCOR_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n", + ALCOR_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear)); +#ifdef DEBUG + { + unsigned long *ptr; + int i; + + ptr = (unsigned long *)la_ptr; + for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { + printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); + } + } +#endif /* DEBUG */ + /* + * Check if machine check is due to a badaddr() and if so, + * ignore the machine check. + */ + if (ALCOR_mcheck_expected && (mchk_sysdata->epic_dcsr && 0x0c00UL)) { + ALCOR_mcheck_expected = 0; + ALCOR_mcheck_taken = 1; + mb(); + mb(); + ALCOR_pci_clr_err(); + wrmces(0x7); + mb(); + draina(); + } +#endif +} + +#endif /* CONFIG_ALPHA_ALCOR */ diff --git a/arch/alpha/kernel/bios32.c b/arch/alpha/kernel/bios32.c index f69f5c98cec1..6d5c36cbf0ef 100644 --- a/arch/alpha/kernel/bios32.c +++ b/arch/alpha/kernel/bios32.c @@ -76,7 +76,6 @@ int pcibios_present(void) */ #define PCI_MODIFY 1 - extern struct hwrpb_struct *hwrpb; @@ -656,7 +655,7 @@ static inline void sio_fixup(void) /* * Go through all devices, fixing up irqs as we see fit: */ - level_bits = 0; + level_bits = inb(0x4d0) | (inb(0x4d1) << 8); for (dev = pci_devices; dev; dev = dev->next) { dev->irq = 0; if (dev->bus->number != 0) { @@ -678,6 +677,7 @@ static inline void sio_fixup(void) if (pirq < 0) { continue; } + /* * if its a VGA, enable its BIOS ROM at C0000 */ diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 652a57ecf1e7..aa8e44c1f4de 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -116,27 +117,27 @@ void enable_irq(unsigned int irq_nr) /* * Initial irq handlers. */ -struct irqaction { - void (*handler)(int, struct pt_regs *); - unsigned long flags; - unsigned long mask; - const char *name; -}; - -static struct irqaction irq_action[NR_IRQS]; +static struct irqaction *irq_action[NR_IRQS]; int get_irq_list(char *buf) { int i, len = 0; - struct irqaction * action = irq_action; + struct irqaction * action; - for (i = 0 ; i < NR_IRQS ; i++, action++) { - if (!action->handler) - continue; - len += sprintf(buf+len, "%2d: %8d %c %s\n", + for (i = 0 ; i < NR_IRQS ; i++) { + action = *(i + irq_action); + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.interrupts[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); } return len; } @@ -218,10 +219,13 @@ static inline void unmask_irq(unsigned long irq) } } -int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), - unsigned long irqflags, const char * devname) +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) { - struct irqaction * action; + struct irqaction *action, *tmp = NULL; unsigned long flags; if (irq >= NR_IRQS) @@ -229,28 +233,53 @@ int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), /* don't accept requests for irq #0 */ if (!irq) return -EINVAL; - action = irq + irq_action; - if (action->handler) - return -EBUSY; if (!handler) - return -EINVAL; + return -EINVAL; + action = *(irq + irq_action); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next); + } else { + return -EBUSY; + } + if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { + printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + return -EBUSY; + } + } save_flags(flags); cli(); + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + if (!action) { + restore_flags(flags); + return -ENOMEM; + } + action->handler = handler; action->flags = irqflags; action->mask = 0; action->name = devname; - enable_irq(irq); - if (irq >= 8 && irq < 16) { + action->next = NULL; + action->dev_id = dev_id; + + if (tmp) { + tmp->next = action; + } else { + *(irq + irq_action) = action; + enable_irq(irq); + if (irq >= 8 && irq < 16) { enable_irq(2); /* ensure cascade is enabled too */ + } } + restore_flags(flags); return 0; } -void free_irq(unsigned int irq) +void free_irq(unsigned int irq, void *dev_id) { - struct irqaction * action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); + struct irqaction * tmp = NULL; unsigned long flags; if (irq >= NR_IRQS) { @@ -261,13 +290,32 @@ void free_irq(unsigned int irq) printk("Trying to free free IRQ%d\n", irq); return; } + if (dev_id) { + for (; action; action = action->next) { + if (action->dev_id == dev_id) break; + tmp = action; + } + if (!action) { + printk("Trying to free free shared IRQ%d\n",irq); + return; + } + } else if (action->flags & SA_SHIRQ) { + printk("Trying to free shared IRQ%d with NULL device ID\n", irq); + return; + } save_flags(flags); cli(); - mask_irq(irq); - action->handler = NULL; - action->flags = 0; - action->mask = 0; - action->name = NULL; + if (action && tmp) { + tmp->next = action->next; + } else { + *(irq + irq_action) = action->next; + } + kfree_s(action, sizeof(struct irqaction)); + + if (!(*(irq + irq_action))) { + mask_irq(irq); + } + restore_flags(flags); } @@ -277,16 +325,20 @@ static inline void handle_nmi(struct pt_regs * regs) printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461)); } -static void unexpected_irq(int irq, struct pt_regs * regs) +static void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs) { + struct irqaction *action; int i; printk("IO device interrupt, irq = %d\n", irq); printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps); printk("Expecting: "); for (i = 0; i < 16; i++) - if (irq_action[i].handler) - printk("[%s:%d] ", irq_action[i].name, i); + if ((action = *(i + irq_action))) + while (action->handler) { + printk("[%s:%d] ", action->name, i); + action = action->next; + } printk("\n"); #if defined(CONFIG_ALPHA_JENSEN) printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n", @@ -298,16 +350,19 @@ static void unexpected_irq(int irq, struct pt_regs * regs) #endif } -static inline void handle_irq(int irq, struct pt_regs * regs) +static inline void handle_irq(int irq, void *dev_id, struct pt_regs * regs) { - struct irqaction * action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); kstat.interrupts[irq]++; - if (!action->handler) { - unexpected_irq(irq, regs); - return; + if (!action) { + unexpected_irq(irq, action->dev_id, regs); + return; + } + while (action) { + action->handler(irq, action->dev_id, regs); + action = action->next; } - action->handler(irq, regs); } static inline void device_interrupt(int irq, int ack, struct pt_regs * regs) @@ -320,12 +375,15 @@ static inline void device_interrupt(int irq, int ack, struct pt_regs * regs) } kstat.interrupts[irq]++; - action = irq_action + irq; + action = *(irq_action + irq); if (action->flags & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); /* quick interrupts get executed with no extra overhead */ if (action->flags & SA_INTERRUPT) { - action->handler(irq, regs); + while (action) { + action->handler(irq, action->dev_id, regs); + action = action->next; + } ack_irq(ack); return; } @@ -340,9 +398,12 @@ static inline void device_interrupt(int irq, int ack, struct pt_regs * regs) */ mask_irq(ack); ack_irq(ack); - if (!action->handler) + if (!action) return; - action->handler(irq, regs); + while (action) { + action->handler(irq, action->dev_id, regs); + action = action->next; + } unmask_irq(ack); } @@ -356,6 +417,8 @@ static inline void isa_device_interrupt(unsigned long vector, # define IACK_SC APECS_IACK_SC #elif defined(CONFIG_ALPHA_LCA) # define IACK_SC LCA_IACK_SC +#elif defined(CONFIG_ALPHA_ALCOR) +# define IACK_SC ALCOR_IACK_SC #else /* * This is bogus but necessary to get it to compile @@ -367,6 +430,7 @@ static inline void isa_device_interrupt(unsigned long vector, #endif int j; +#if 1 /* * Generate a PCI interrupt acknowledge cycle. The PIC will * respond with the interrupt vector of the highest priority @@ -383,7 +447,7 @@ static inline void isa_device_interrupt(unsigned long vector, } } device_interrupt(j, j, regs); -#if 0 +#else unsigned long pic; /* @@ -424,6 +488,10 @@ static inline void cabriolet_and_eb66p_device_interrupt(unsigned long vector, /* read the interrupt summary registers */ pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16); +#if 0 + printk("[0x%04X/0x%04X]", pld, inb(0x20) | (inb(0xA0) << 8)); +#endif + /* * Now for every possible bit set, work through them and call * the appropriate interrupt handler. @@ -495,6 +563,11 @@ static inline void eb66_and_eb64p_device_interrupt(unsigned long vector, static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq, ack; + unsigned long flags; + + save_flags(flags); + cli(); + ack = irq = (vector - 0x800) >> 4; @@ -517,6 +590,8 @@ static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * r #endif /* CONFIG_ALPHA_JENSEN */ device_interrupt(irq, ack, regs); + + restore_flags(flags) ; } #if NR_IRQS > 64 @@ -528,12 +603,14 @@ static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * r */ unsigned long probe_irq_on(void) { + struct irqaction * action; unsigned long irqs = 0, irqmask; unsigned long delay; unsigned int i; for (i = NR_IRQS - 1; i > 0; i--) { - if (!irq_action[i].handler) { + action = *(i + irq_action); + if (!action->handler) { enable_irq(i); irqs |= (1 << i); } @@ -598,6 +675,10 @@ static void machine_check(unsigned long vector, unsigned long la, struct pt_regs extern void apecs_machine_check(unsigned long vector, unsigned long la, struct pt_regs * regs); apecs_machine_check(vector, la, regs); +#elif defined(CONFIG_ALPHA_ALCOR) + extern void alcor_machine_check(unsigned long vector, unsigned long la, + struct pt_regs * regs); + alcor_machine_check(vector, la, regs); #else printk("Machine check\n"); #endif diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 97d753b91952..fe40ee5c68ee 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -139,6 +139,8 @@ void setup_arch(char **cmdline_p, *memory_start_p = lca_init(*memory_start_p, *memory_end_p); #elif defined(CONFIG_ALPHA_APECS) *memory_start_p = apecs_init(*memory_start_p, *memory_end_p); +#elif defined(CONFIG_ALPHA_ALCOR) + *memory_start_p = alcor_init(*memory_start_p, *memory_end_p); #endif } diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S index 0d65535df642..6ed9a6607452 100644 --- a/arch/i386/boot/bootsect.S +++ b/arch/i386/boot/bootsect.S @@ -53,10 +53,6 @@ SWAP_DEV = 0 ! ld86 requires an entry symbol. This may as well be the usual one. .globl _main _main: - nop - jmp over_magic - .byte 0xF0 -over_magic: #if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */ int 3 #endif diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index a82335757b80..5306f69955a4 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ #include #define CR0_NE 32 +#define TIMER_IRQ 0 /* Keep this in sync with time.c */ static unsigned char cache_21 = 0xff; static unsigned char cache_A1 = 0xff; @@ -158,36 +160,34 @@ static void (*bad_interrupt[16])(void) = { /* * Initial irq handlers. */ -struct irqaction { - void (*handler)(int, struct pt_regs *); - unsigned long flags; - unsigned long mask; - const char *name; -}; +static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL}; -static struct irqaction irq_action[16] = { - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL } +static struct irqaction *irq_action[16] = { + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL }; int get_irq_list(char *buf) { int i, len = 0; - struct irqaction * action = irq_action; + struct irqaction * action; - for (i = 0 ; i < 16 ; i++, action++) { - if (!action->handler) - continue; - len += sprintf(buf+len, "%3d: %8d %c %s\n", + for (i = 0 ; i < 16 ; i++) { + action = *(i + irq_action); + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.interrupts[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); } /* * Linus - should you add NMI counts here ????? @@ -203,7 +203,7 @@ int get_irq_list(char *buf) int get_smp_prof_list(char *buf) { int i,j, len = 0; - struct irqaction * action = irq_action; + struct irqaction * action; unsigned long sum_spins = 0; unsigned long sum_spins_syscall = 0; unsigned long sum_spins_sys_idle = 0; @@ -222,7 +222,8 @@ int get_smp_prof_list(char *buf) { for (i=0;ihandler) continue; len += sprintf(buf+len, "%3d: %10d ", @@ -232,6 +233,11 @@ int get_smp_prof_list(char *buf) { len += sprintf(buf+len, "%c %s\n", (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } } len+=sprintf(buf+len, "LCK: %10lu", sum_spins); @@ -273,7 +279,8 @@ int get_smp_prof_list(char *buf) { */ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { - struct irqaction * action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); + #ifdef __SMP__ if(smp_threads_ready && active_kernel_processor!=smp_processor_id()) panic("IRQ %d: active processor set wrongly(%d not %d).\n", irq, active_kernel_processor, smp_processor_id()); @@ -283,9 +290,13 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) #ifdef __SMP_PROF__ int_count[smp_processor_id()][irq]++; #endif - if (action->flags & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - action->handler(irq, regs); + while (action) { + if (action->flags & SA_SAMPLE_RANDOM) { + add_interrupt_randomness(irq); + } + action->handler(irq, action->dev_id, regs); + action = action->next; + } } /* @@ -295,7 +306,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) */ asmlinkage void do_fast_IRQ(int irq) { - struct irqaction * action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); #ifdef __SMP__ /* IRQ 13 is allowed - thats an invalidate */ if(smp_threads_ready && active_kernel_processor!=smp_processor_id() && irq!=13) @@ -306,56 +317,95 @@ asmlinkage void do_fast_IRQ(int irq) #ifdef __SMP_PROF__ int_count[smp_processor_id()][irq]++; #endif - if (action->flags & SA_SAMPLE_RANDOM) + while (action) { + if (action->flags & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); - action->handler(irq, NULL); + action->handler(irq, action->dev_id, NULL); + action = action->next; + } } #define SA_PROBE SA_ONESHOT -int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), - unsigned long irqflags, const char * devname) +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) { - struct irqaction * action; + struct irqaction * action, *tmp = NULL; unsigned long flags; if (irq > 15) - return -EINVAL; - action = irq + irq_action; - if (action->handler) - return -EBUSY; + return -EINVAL; if (!handler) - return -EINVAL; + return -EINVAL; + action = *(irq + irq_action); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next); + } else { + return -EBUSY; + } + if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { + printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + return -EBUSY; + } + } if (irqflags & SA_SAMPLE_RANDOM) rand_initialize_irq(irq); save_flags(flags); cli(); + if (irq == 2) + action = &cascade_irq; + else if (irq == 13) + action = &math_irq; + else if (irq == TIMER_IRQ) + action = &timer_irq; + else + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + + if (!action) { + restore_flags(flags); + return -ENOMEM; + } + action->handler = handler; action->flags = irqflags; action->mask = 0; action->name = devname; - if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */ + action->next = NULL; + action->dev_id = dev_id; + + if (tmp) { + tmp->next = action; + } else { + *(irq + irq_action) = action; + if (!(action->flags & SA_PROBE)) {/* SA_ONESHOT used by probing */ if (action->flags & SA_INTERRUPT) - set_intr_gate(0x20+irq,fast_interrupt[irq]); + set_intr_gate(0x20+irq,fast_interrupt[irq]); else - set_intr_gate(0x20+irq,interrupt[irq]); - } - if (irq < 8) { + set_intr_gate(0x20+irq,interrupt[irq]); + } + if (irq < 8) { cache_21 &= ~(1< 15) { @@ -366,20 +416,43 @@ void free_irq(unsigned int irq) printk("Trying to free free IRQ%d\n",irq); return; } + if (dev_id) { + for (; action; action = action->next) { + if (action->dev_id == dev_id) break; + tmp = action; + } + if (!action) { + printk("Trying to free free shared IRQ%d\n",irq); + return; + } + } else if (action->flags & SA_SHIRQ) { + printk("Trying to free shared IRQ%d with NULL device ID\n", irq); + return; + } save_flags(flags); cli(); - if (irq < 8) { + if (action && tmp) { + tmp->next = action->next; + } else { + *(irq + irq_action) = action->next; + } + + if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ)) + memset(action, 0, sizeof(struct irqaction)); + else + kfree_s(action, sizeof(struct irqaction)); + + if (!(*(irq + irq_action))) { + if (irq < 8) { cache_21 |= 1 << irq; outb(cache_21,0x21); - } else { + } else { cache_A1 |= 1 << (irq-8); outb(cache_A1,0xA1); + } + set_intr_gate(0x20+irq,bad_interrupt[irq]); } - set_intr_gate(0x20+irq,bad_interrupt[irq]); - action->handler = NULL; - action->flags = 0; - action->mask = 0; - action->name = NULL; + restore_flags(flags); } @@ -398,7 +471,7 @@ void free_irq(unsigned int irq) */ -static void math_error_irq(int cpl, struct pt_regs *regs) +static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs) { outb(0,0xF0); if (ignore_irq13 || !hard_math) @@ -408,7 +481,7 @@ static void math_error_irq(int cpl, struct pt_regs *regs) #endif -static void no_action(int cpl, struct pt_regs * regs) { } +static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } unsigned long probe_irq_on (void) { @@ -417,7 +490,7 @@ unsigned long probe_irq_on (void) /* first, snaffle up any unassigned irqs */ for (i = 15; i > 0; i--) { - if (!request_irq(i, no_action, SA_PROBE, "probe")) { + if (!request_irq(i, no_action, SA_PROBE, "probe", NULL)) { enable_irq(i); irqs |= (1 << i); } @@ -431,7 +504,7 @@ unsigned long probe_irq_on (void) for (i = 15; i > 0; i--) { if (irqs & (1 << i) & irqmask) { irqs ^= (1 << i); - free_irq(i); + free_irq(i, NULL); } } #ifdef DEBUG @@ -447,7 +520,7 @@ int probe_irq_off (unsigned long irqs) irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; for (i = 15; i > 0; i--) { if (irqs & (1 << i)) { - free_irq(i); + free_irq(i, NULL); } } #ifdef DEBUG @@ -481,13 +554,13 @@ void init_IRQ(void) #ifdef __SMP__ set_intr_gate(0x20+i, interrupt[i]); /* IRQ '16' - IPI for rescheduling */ #endif - if (request_irq(2, no_action, SA_INTERRUPT, "cascade")) + if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL)) printk("Unable to get IRQ2 for cascade.\n"); #ifndef __SMP__ - if (request_irq(13,math_error_irq, 0, "math error")) + if (request_irq(13, math_error_irq, 0, "math error", NULL)) printk("Unable to get IRQ13 for math-error handler.\n"); #else - if (request_irq(13, smp_message_irq, SA_INTERRUPT, "IPI")) + if (request_irq(13, smp_message_irq, SA_INTERRUPT, "IPI", NULL)) printk("Unable to get IRQ13 for IPI.\n"); #endif request_region(0x20,0x20,"pic1"); diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 7754853407d5..3ac62a6e8770 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -7,6 +7,8 @@ * Much of the core SMP work is based on previous work by Thomas Radke, to * whom a great many thanks are extended. * + * Thanks to Intel for testing against several Pentium and Pentium Pro + * MP machines. * * This code is released under the GNU public license version 2 or * later. @@ -35,12 +37,12 @@ #include #include -static int smp_found_config=0; /* Have we found an SMP box */ +int smp_found_config=0; /* Have we found an SMP box */ unsigned long cpu_present_map = 0; /* Bitmask of existing CPU's */ int smp_num_cpus; /* Total count of live CPU's */ int smp_threads_ready=0; /* Set when the idlers are all forked */ -volatile unsigned long cpu_number_map[NR_CPUS]; /* which CPU maps to which logical number */ +volatile int cpu_number_map[NR_CPUS]; /* which CPU maps to which logical number */ volatile unsigned long cpu_callin_map[NR_CPUS] = {0,}; /* We always use 0 the rest is ready for parallel delivery */ volatile unsigned long smp_invalidate_needed; /* Used for the invalidate map thats also checked in the spinlock */ struct cpuinfo_x86 cpu_data[NR_CPUS]; /* Per cpu bogomips and other parameters */ @@ -49,6 +51,7 @@ static unsigned long io_apic_addr = 0; /* Address of the I/O apic (not yet use unsigned char boot_cpu_id = 0; /* Processor that is doing the boot up */ static unsigned char *kstack_base,*kstack_end; /* Kernel stack list pointers */ static int smp_activated = 0; /* Tripped once we need to start cross invalidating */ +int apic_version[NR_CPUS]; /* APIC version number */ static volatile int smp_commenced=0; /* Tripped when we start scheduling */ unsigned long apic_addr=0xFEE00000; /* Address of APIC (defaults to 0xFEE00000) */ unsigned long nlong = 0; /* dummy used for apic_reg address + 0x20 */ @@ -114,6 +117,8 @@ static char *mpc_family(int family,int model) "Unknown","Unknown", "80486DX/4" }; + if(family==0x6) + return("Pentium(tm) Pro"); if(family==0x5) return("Pentium(tm)"); if(family==0x0F && model==0x0F) @@ -208,7 +213,10 @@ static int smp_read_mpc(struct mp_config_table *mpc) if(m->mpc_apicid>NR_CPUS) printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS); else + { cpu_present_map|=(1<mpc_apicid); + apic_version[m->mpc_apicid]=m->mpc_apicver; + } } mpt+=sizeof(*m); count+=sizeof(*m); @@ -345,6 +353,10 @@ void smp_scan_config(unsigned long base, unsigned long length) else cpu_present_map=3; printk("Processors: %d\n", num_processors); + /* + * Only use the first one found. + */ + return; } } bp+=4; @@ -494,19 +506,44 @@ void smp_callin(void) void smp_boot_cpus(void) { - int i=0; + int i,j; int cpucount=0; + unsigned long cfg; void *stack; extern unsigned long init_user_stack[]; + /* + * Initialize the logical to physical cpu number mapping + */ + + for (i = 0; i < NR_CPUS; i++) + cpu_number_map[i] = -1; + + /* + * Setup boot CPU information + */ + + kernel_stacks[boot_cpu_id]=(void *)init_user_stack; /* Set up for boot processor first */ + + smp_store_cpu_info(boot_cpu_id); /* Final full version of the data */ + + cpu_present_map |= (1 << smp_processor_id()); + cpu_number_map[boot_cpu_id] = 0; + active_kernel_processor=boot_cpu_id; + + /* + * If we don't conform to the Intel MPS standard, get out + * of here now! + */ + + if (!smp_found_config) + return; + /* * Map the local APIC into kernel space */ - /* Mapping on non-Intel conforming platforms is a bad move. */ - if (1>4; *((volatile unsigned short *) 0x469) = 0; + + /* + * Protect it again + */ + pg0[0]= pte_val(mk_pte(0, PAGE_READONLY)); + local_invalidate(); /* - * Clean up the errors + * Be paranoid about clearing APIC errors. */ apic_write(APIC_ESR, 0); @@ -597,9 +662,13 @@ void smp_boot_cpus(void) * Status is now clean */ - send_status = 0; + send_status = 0; accept_status = 0; + /* + * Starting actual IPI sequence... + */ + SMP_PRINTK(("Asserting INIT.\n")); /* @@ -611,123 +680,76 @@ void smp_boot_cpus(void) apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ cfg=apic_read(APIC_ICR); cfg&=~0xCDFFF; /* Clear bits */ - cfg|=0x0000c500; /* Urgh.. fix for constants */ + cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG + | APIC_DEST_ASSERT | APIC_DEST_DM_INIT); apic_write(APIC_ICR, cfg); /* Send IPI */ - timeout = 0; - do { - udelay(1000); - if ((send_status = (!(apic_read(APIC_ICR) & 0x00001000)))) - break; - } while (timeout++ < 1000); - -#ifdef EEK2 - if (send_status) { - apic_write(APIC_ESR, 0); - accept_status = (apic_read(APIC_ESR) & 0xEF); - } -#endif + udelay(200); + SMP_PRINTK(("Deasserting INIT.\n")); + cfg=apic_read(APIC_ICR2); + cfg&=0x00FFFFFF; + apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ + cfg=apic_read(APIC_ICR); + cfg&=~0xCDFFF; /* Clear bits */ + cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG + | APIC_DEST_DM_INIT); + apic_write(APIC_ICR, cfg); /* Send IPI */ + /* - * And off again + * Should we send STARTUP IPIs ? + * + * Determine this based on the APIC version. + * If we don't have an integrated APIC, don't + * send the STARTUP IPIs. */ - - if (send_status && !accept_status) - { - SMP_PRINTK(("Deasserting INIT.\n")); - - cfg=apic_read(APIC_ICR2); - cfg&=0x00FFFFFF; - apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ - cfg=apic_read(APIC_ICR); - cfg&=~0xCDFFF; /* Clear bits */ - cfg|=0x00008500; - apic_write(APIC_ICR, cfg); /* Send IPI */ - - timeout = 0; - do { - udelay(1000); - if ((send_status = !(apic_read(APIC_ICR) & 0x00001000) )) - break; - } while (timeout++ < 1000); - if (send_status) { - udelay(1000000); - apic_write(APIC_ESR, 0); - accept_status = (apic_read(APIC_ESR) & 0xEF); - } - } + if ( apic_version[i] & 0xF0 ) + num_starts = 2; + else + num_starts = 0; /* - * We currently assume an integrated - * APIC only, so STARTUP IPIs must be - * sent as well. + * Run STARTUP IPI loop. */ - if (send_status && !accept_status) + for (j = 0; !(send_status || accept_status) + && (j < num_starts) ; j++) { - SMP_PRINTK(("Sending first STARTUP.\n")); - - /* - * First STARTUP IPI - */ - - cfg=apic_read(APIC_ICR2); - cfg&=0x00FFFFFF; - apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ - cfg=apic_read(APIC_ICR); - cfg&=~0xCDFFF ; /* Clear bits */ - cfg|=APIC_DEST_FIELD|APIC_DEST_DM_STARTUP|(((unsigned long)stack)>>12); /* Boot on the stack */ - apic_write(APIC_ICR, cfg); /* Kick the second */ + SMP_PRINTK(("Sending STARTUP #%d.\n",j)); - timeout = 0; - do { - udelay(1000); - if ((send_status = !(apic_read(APIC_ICR) & 0x00001000)) ) - break; - } while (timeout++ < 1000); - - if (send_status) { - udelay(1000000); - apic_write(APIC_ESR, 0); - accept_status = (apic_read(APIC_ESR) & 0xEF); - } - } - - if (send_status && !accept_status) - { - SMP_PRINTK(("Sending second STARTUP.\n")); + apic_write(APIC_ESR, 0); /* - * Second STARTUP IPI + * STARTUP IPI */ cfg=apic_read(APIC_ICR2); cfg&=0x00FFFFFF; apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); /* Target chip */ cfg=apic_read(APIC_ICR); - cfg&=~0xCDFFF ; /* Clear bits */ - cfg|=APIC_DEST_FIELD|APIC_DEST_DM_STARTUP|(((unsigned long)stack)>>12); /* Boot on the stack */ + cfg&=~0xCDFFF; /* Clear bits */ + cfg |= (APIC_DEST_FIELD + | APIC_DEST_DM_STARTUP + | (((int) stack) >> 12) ); /* Boot on the stack */ apic_write(APIC_ICR, cfg); /* Kick the second */ timeout = 0; do { - udelay(1000); - if ((send_status = !(apic_read(APIC_ICR) & 0x00001000))) - break; - } while (timeout++ < 1000); + udelay(10); + } while ( (send_status = (apic_read(APIC_ICR) & 0x1000)) + && (timeout++ < 1000)); + udelay(200); - if (send_status) { - udelay(1000000); - apic_write(APIC_ESR, 0); - accept_status = (apic_read(APIC_ESR) & 0xEF); - } + accept_status = (apic_read(APIC_ESR) & 0xEF); } - if (!send_status) /* APIC never delivered?? */ + if (send_status) /* APIC never delivered?? */ printk("APIC never delivered???\n"); - else if (accept_status) /* Send accept error */ + if (accept_status) /* Send accept error */ printk("APIC delivery error (%lx).\n", accept_status); + + if( !(send_status || accept_status) ) { for(timeout=0;timeout<50000;timeout++) { @@ -746,28 +768,54 @@ void smp_boot_cpus(void) if(*((volatile unsigned char *)8192)==0xA5) printk("Stuck ??\n"); else - printk("Not responding val=(%lx).\n", *((unsigned long *) stack)); - cpu_present_map&=~(1< #include #include +#include #include #include @@ -42,6 +43,8 @@ #include #include +#define TIMER_IRQ 0 /* Keep this in sync with time.c */ + unsigned char cache_21 = 0xff; unsigned char cache_A1 = 0xff; @@ -98,36 +101,34 @@ extern void bad_interrupt(void); /* * Initial irq handlers. */ -struct irqaction { - void (*handler)(int, struct pt_regs *); - unsigned long flags; - unsigned long mask; - const char *name; -}; +static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL}; -static struct irqaction irq_action[16] = { - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL } +static struct irqaction *irq_action[16] = { + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL }; int get_irq_list(char *buf) { int i, len = 0; - struct irqaction * action = irq_action; + struct irqaction * action; - for (i = 0 ; i < 16 ; i++, action++) { - if (!action->handler) - continue; - len += sprintf(buf+len, "%3d: %8d %c %s\n", + for (i = 0 ; i < 16 ; i++) { + action = *(i + irq_action); + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.interrupts[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); } return len; } @@ -141,12 +142,15 @@ int get_irq_list(char *buf) */ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { - struct irqaction * action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); kstat.interrupts[irq]++; if (action->flags & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); - action->handler(irq, regs); + while (action) { + action->handler(irq, action->dev_id, regs); + action = action->next; + } } /* @@ -156,38 +160,74 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) */ asmlinkage void do_fast_IRQ(int irq) { - struct irqaction * action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); kstat.interrupts[irq]++; if (action->flags & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); - action->handler(irq, NULL); + while (action) { + action->handler(irq, action->dev_id, NULL); + action = action->next; + } } #define SA_PROBE SA_ONESHOT -int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), - unsigned long irqflags, const char * devname) +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) { - struct irqaction * action; + struct irqaction * action, *tmp = NULL; unsigned long flags; if (irq > 15) return -EINVAL; - action = irq + irq_action; - if (action->handler) - return -EBUSY; if (!handler) - return -EINVAL; + return -EINVAL; + action = *(irq + irq_action); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next); + } else { + return -EBUSY; + } + if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { + printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + return -EBUSY; + } + } if (irqflags & SA_SAMPLE_RANDOM) rand_initialize_irq(irq); save_flags(flags); cli(); + if (irq == 2) + action = &cascade_irq; + else if (irq == 13) + action = &math_irq; + else if (irq == TIMER_IRQ) + action = &timer_irq; + else + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + + if (!action) { + restore_flags(flags); + return -ENOMEM; + } + action->handler = handler; action->flags = irqflags; action->mask = 0; action->name = devname; - if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */ + action->next = NULL; + action->dev_id = dev_id; + + if (tmp) { + tmp->next = action; + } else { + *(irq + irq_action) = action; + if (!(action->flags & SA_PROBE)) {/* SA_ONESHOT used by probing */ /* * FIXME: Does the SA_INTERRUPT flag make any sense on MIPS??? */ @@ -195,23 +235,25 @@ int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), set_int_vector(irq,fast_interrupt); else set_int_vector(irq,interrupt); - } - if (irq < 8) { + } + if (irq < 8) { cache_21 &= ~(1< 15) { @@ -222,24 +264,46 @@ void free_irq(unsigned int irq) printk("Trying to free free IRQ%d\n",irq); return; } + if (dev_id) { + for (; action; action = action->next) { + if (action->dev_id == dev_id) break; + tmp = action; + } + if (!action) { + printk("Trying to free free shared IRQ%d\n",irq); + return; + } + } else if (action->flags & SA_SHIRQ) { + printk("Trying to free shared IRQ%d with NULL device ID\n", irq); + return; + } save_flags(flags); cli(); - if (irq < 8) { + if (action && tmp) { + tmp->next = action->next; + } else { + *(irq + irq_action) = action->next; + } + + if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ)) + memset(action, 0, sizeof(struct irqaction)); + else + kfree_s(action, sizeof(struct irqaction)); + + if (!(*(irq + irq_action))) { + if (irq < 8) { cache_21 |= 1 << irq; outb(cache_21,0x21); - } else { + } else { cache_A1 |= 1 << (irq-8); outb(cache_A1,0xA1); + } + set_int_vector(irq,bad_interrupt); } - set_int_vector(irq,bad_interrupt); - action->handler = NULL; - action->flags = 0; - action->mask = 0; - action->name = NULL; restore_flags(flags); } -static void no_action(int cpl, struct pt_regs * regs) { } +static void no_action(int cpl, void *dev_id, struct pt_regs * regs) { } unsigned long probe_irq_on (void) { @@ -248,7 +312,7 @@ unsigned long probe_irq_on (void) /* first, snaffle up any unassigned irqs */ for (i = 15; i > 0; i--) { - if (!request_irq(i, no_action, SA_PROBE, "probe")) { + if (!request_irq(i, no_action, SA_PROBE, "probe", NULL)) { enable_irq(i); irqs |= (1 << i); } @@ -262,7 +326,7 @@ unsigned long probe_irq_on (void) for (i = 15; i > 0; i--) { if (irqs & (1 << i) & irqmask) { irqs ^= (1 << i); - free_irq(i); + free_irq(i, NULL); } } #ifdef DEBUG @@ -278,7 +342,7 @@ int probe_irq_off (unsigned long irqs) irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; for (i = 15; i > 0; i--) { if (irqs & (1 << i)) { - free_irq(i); + free_irq(i, NULL); } } #ifdef DEBUG @@ -317,7 +381,7 @@ void init_IRQ(void) outb_p(LATCH & 0xff , 0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ - if (request_irq(2, no_action, SA_INTERRUPT, "cascade")) + if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL)) printk("Unable to get IRQ2 for cascade\n"); break; default: diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 84e5d243913b..1670a5db06c0 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -72,37 +73,34 @@ void enable_irq(unsigned int irq_nr) /* * Irq handlers. */ -struct irqaction { - void (*handler)(int, struct pt_regs *); - unsigned long flags; - unsigned long mask; - const char *name; - int notified; -}; +static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL}; -static struct irqaction irq_action[16] = { - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL } +static struct irqaction *irq_action[16] = { + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL }; int get_irq_list(char *buf) { int i, len = 0; - struct irqaction * action = irq_action; + struct irqaction * action; - for (i = 0 ; i < 16 ; i++, action++) { - if (!action->handler) - continue; - len += sprintf(buf+len, "%2d: %8d %c %s\n", + for (i = 0 ; i < 16 ; i++) { + action = *(i + irq_action); + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat.interrupts[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); } return len; } @@ -110,7 +108,7 @@ int get_irq_list(char *buf) asmlinkage void handle_IRQ(struct pt_regs *regs) { int irq, s; - struct irqaction *action; + struct irqaction * action; intr_count++; /* Figure out IRQ#, etc. */ outb(0x0C, 0x20); /* Poll interrupt controller */ @@ -134,14 +132,17 @@ asmlinkage void handle_IRQ(struct pt_regs *regs) outb(cache_21 | (1<handler) - { - action->handler(irq, regs); - } else - { + while (action) { + if (action->handler) + { + action->handler(irq, action->dev_id, regs); + } else + { _printk("Bogus interrupt #%d\n", irq); + } + action = action->next; } if (_disable_interrupts() && !action->notified) { @@ -202,10 +203,13 @@ void check_irq(void ) #define SA_PROBE SA_ONESHOT -int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), - unsigned long irqflags, const char * devname) +int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) { - struct irqaction * action; + struct irqaction * action, *tmp = NULL; unsigned long flags; #if 0 @@ -214,41 +218,73 @@ cnpause(); #endif if (irq > 15) return -EINVAL; - action = irq + irq_action; - if (action->handler) - return -EBUSY; if (!handler) - return -EINVAL; + return -EINVAL; + action = *(irq + irq_action); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next); + } else { + return -EBUSY; + } + if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { + printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + return -EBUSY; + } + } save_flags(flags); cli(); + if (irq == 2) + action = &cascade_irq; + else if (irq == 13) + action = &math_irq; + else if (irq == TIMER_IRQ) + action = &timer_irq; + else + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + + if (!action) { + restore_flags(flags); + return -ENOMEM; + } + action->handler = handler; action->flags = irqflags; action->mask = 0; action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + if (tmp) { + tmp->next = action; + } else { + *(irq + irq_action) = action; #if 0 - if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */ + if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */ if (action->flags & SA_INTERRUPT) - set_intr_gate(0x20+irq,fast_interrupt[irq]); + set_intr_gate(0x20+irq,fast_interrupt[irq]); else - set_intr_gate(0x20+irq,interrupt[irq]); - } + set_intr_gate(0x20+irq,interrupt[irq]); + } #endif - if (irq < 8) { + if (irq < 8) { cache_21 &= ~(1< 15) { @@ -259,26 +295,49 @@ void free_irq(unsigned int irq) printk("Trying to free free IRQ%d\n",irq); return; } + if (dev_id) { + for (; action; action = action->next) { + if (action->dev_id == dev_id) break; + tmp = action; + } + if (!action) { + printk("Trying to free free shared IRQ%d\n",irq); + return; + } + } else if (action->flags & SA_SHIRQ) { + printk("Trying to free shared IRQ%d with NULL device ID\n", irq); + return; + } save_flags(flags); cli(); - if (irq < 8) { + if (action && tmp) { + tmp->next = action->next; + } else { + *(irq + irq_action) = action->next; + } + + if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ)) + memset(action, 0, sizeof(struct irqaction)); + else + kfree_s(action, sizeof(struct irqaction)); + + if (!(*(irq + irq_action))) { + if (irq < 8) { cache_21 |= 1 << irq; outb(cache_21,0x21); - } else { + } else { cache_A1 |= 1 << (irq-8); outb(cache_A1,0xA1); - } + } #if 0 - set_intr_gate(0x20+irq,bad_interrupt[irq]); + set_intr_gate(0x20+irq,bad_interrupt[irq]); #endif - action->handler = NULL; - action->flags = 0; - action->mask = 0; - action->name = NULL; + } + restore_flags(flags); } -static void no_action(int cpl, struct pt_regs * regs) { } +static void no_action(int cpl, void *dev_id, struct pt_regs * regs) { } unsigned /*int*/ long probe_irq_on (void) { @@ -287,7 +346,7 @@ unsigned /*int*/ long probe_irq_on (void) /* first, snaffle up any unassigned irqs */ for (i = 15; i > 0; i--) { - if (!request_irq(i, no_action, SA_PROBE, "probe")) { + if (!request_irq(i, no_action, SA_PROBE, "probe", NULL)) { enable_irq(i); irqs |= (1 << i); } @@ -301,7 +360,7 @@ unsigned /*int*/ long probe_irq_on (void) for (i = 15; i > 0; i--) { if (irqs & (1 << i) & irqmask) { irqs ^= (1 << i); - free_irq(i); + free_irq(i, NULL); } } #ifdef DEBUG @@ -317,7 +376,7 @@ int probe_irq_off (unsigned /*int*/ long irqs) irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21; for (i = 15; i > 0; i--) { if (irqs & (1 << i)) { - free_irq(i); + free_irq(i, NULL); } } #ifdef DEBUG @@ -347,7 +406,7 @@ void init_IRQ(void) outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ outb_p(LATCH & 0xff , 0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ - if (request_irq(2, no_action, SA_INTERRUPT, "cascade")) + if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL)) printk("Unable to get IRQ2 for cascade\n"); request_region(0x20,0x20,"pic1"); request_region(0xa0,0x20,"pic2"); diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index 06bac2bc27dc..9fb9e32376be 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -143,62 +144,79 @@ enable_irq(unsigned int irq_nr) /* * Initial irq handlers. */ -struct irqaction { - void (*handler)(int, struct pt_regs *); - unsigned long flags; - unsigned long mask; - const char *name; -}; +static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL}; +static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL}; -static struct irqaction irq_action[16] = { - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }, - { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL } +static struct irqaction *irq_action[16] = { + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL }; - int get_irq_list(char *buf) { int i, len = 0; - struct irqaction * action = irq_action; - - for (i = 0 ; i < 16 ; i++, action++) { - if (!action->handler) - continue; - len += sprintf(buf+len, "%2d: %8d %c %s\n", - i, kstat.interrupts[i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); + struct irqaction * action; + + for (i = 0 ; i < 16 ; i++) { + action = *(i + irq_action); + if (!action) + continue; + len += sprintf(buf+len, "%2d: %8d %c %s", + i, kstat.interrupts[i], + (action->flags & SA_INTERRUPT) ? '+' : ' ', + action->name); + for (action=action->next; action; action = action->next) { + len += sprintf(buf+len, ",%s %s", + (action->flags & SA_INTERRUPT) ? " +" : "", + action->name); + } + len += sprintf(buf+len, "\n"); } return len; } void -free_irq(unsigned int irq) +free_irq(unsigned int irq, void *dev_id) { - struct irqaction * action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); + struct irqaction * tmp = NULL; unsigned long flags; if (irq > 14) { /* 14 irq levels on the sparc */ printk("Trying to free bogus IRQ %d\n", irq); return; } - if (!action->handler) { - printk("Trying to free free IRQ%d\n", irq); - return; - } + if (!action->handler) { + printk("Trying to free free IRQ%d\n",irq); + return; + } + if (dev_id) { + for (; action; action = action->next) { + if (action->dev_id == dev_id) break; + tmp = action; + } + if (!action) { + printk("Trying to free free shared IRQ%d\n",irq); + return; + } + } else if (action->flags & SA_SHIRQ) { + printk("Trying to free shared IRQ%d with NULL device ID\n", irq); + return; + } save_flags(flags); cli(); - disable_irq(irq); - action->handler = NULL; - action->flags = 0; - action->mask = 0; - action->name = NULL; + if (action && tmp) { + tmp->next = action->next; + } else { + *(irq + irq_action) = action->next; + } + kfree_s(action, sizeof(struct irqaction)); + + if (!(*(irq + irq_action))) { + disable_irq(irq); + } + restore_flags(flags); } @@ -206,15 +224,16 @@ void unexpected_irq(int irq, struct pt_regs * regs) { int i; + struct irqaction * action = *(irq + irq_action); printk("IO device interrupt, irq = %d\n", irq); printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, regs->npc, regs->u_regs[14]); printk("Expecting: "); for (i = 0; i < 16; i++) - if (irq_action[i].handler) - prom_printf("[%s:%d:0x%x] ", irq_action[i].name, (int) i, - (unsigned int) irq_action[i].handler); + if (action->handler) + prom_printf("[%s:%d:0x%x] ", action->name, (int) i, + (unsigned int) action->handler); printk("AIEEE\n"); panic("bogus interrupt received"); } @@ -222,13 +241,16 @@ unexpected_irq(int irq, struct pt_regs * regs) void handler_irq(int irq, struct pt_regs * regs) { - struct irqaction * action = irq_action + irq; + struct irqaction * action = *(irq + irq_action); kstat.interrupts[irq]++; - if (!action->handler) - unexpected_irq(irq, regs); - else - action->handler(irq, regs); + while (action) { + if (!action->handler) + unexpected_irq(irq, action->dev_id, regs); + else + action->handler(irq, action->dev_id, regs); + action = action->next; + } } /* @@ -241,10 +263,13 @@ handler_irq(int irq, struct pt_regs * regs) asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { - struct irqaction *action = irq + irq_action; + struct irqaction * action = *(irq + irq_action); kstat.interrupts[irq]++; - action->handler(irq, regs); + while (action) { + action->handler(irq, action->dev_id, regs); + action = action->next; + } return; } @@ -263,21 +288,38 @@ do_fast_IRQ(int irq) int request_fast_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), - unsigned long irqflags, const char *devname) + unsigned long irqflags, const char *devname, void *dev_id) +) { - struct irqaction *action; + struct irqaction * action, *tmp = NULL; unsigned long flags; if(irq > 14) return -EINVAL; - action = irq + irq_action; - if(action->handler) + if (!handler) + return -EINVAL; + action = *(irq + irq_action); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next); + } else { return -EBUSY; - if(!handler) - return -EINVAL; + } + if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { + printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + return -EBUSY; + } + } save_flags(flags); cli(); + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + + if (!action) { + restore_flags(flags); + return -ENOMEM; + } + /* Dork with trap table if we get this far. */ sparc_ttable[SP_TRAP_IRQ1+(irq-1)].inst_one = SPARC_BRANCH((unsigned long) handler, @@ -290,6 +332,13 @@ request_fast_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), action->flags = irqflags; action->mask = 0; action->name = devname; + action->dev_id = dev_id; + + if (tmp) { + tmp->next = action; + } else { + *(irq + irq_action) = action; + } restore_flags(flags); return 0; @@ -299,25 +348,48 @@ extern void probe_clock(void); int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *), - unsigned long irqflags, const char * devname) + unsigned long irqflags, const char * devname, void *dev_id) { - struct irqaction *action; + struct irqaction * action, *tmp = NULL; unsigned long flags; if(irq > 14) return -EINVAL; - action = irq + irq_action; - if(action->handler) + if (!handler) + return -EINVAL; + action = *(irq + irq_action); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next); + } else { return -EBUSY; - if(!handler) - return -EINVAL; - + } + if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { + printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + return -EBUSY; + } + } save_flags(flags); cli(); + action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); + + if (!action) { + restore_flags(flags); + return -ENOMEM; + } + action->handler = handler; action->flags = irqflags; action->mask = 0; action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + if (tmp) { + tmp->next = action; + } else { + *(irq + irq_action) = action; + } enable_irq(irq); if(irq == 10) probe_clock(); diff --git a/drivers/block/Config.in b/drivers/block/Config.in index 2aaa1b8f3154..9602208be115 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -21,11 +21,11 @@ else bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then comment 'Note: most of these also require special kernel boot parameters' - bool ' DTC-2278 chipset support' CONFIG_BLK_DEV_DTC2278 - bool ' Holtek HT6560B chipset support' CONFIG_BLK_DEV_HT6560B - bool ' QDI QD6580 chipset support' CONFIG_BLK_DEV_QD6580 - bool ' UMC 8672 chipset support' CONFIG_BLK_DEV_UMC8672 - bool ' ALI M1439/M1445 chipset support' CONFIG_BLK_DEV_ALI14XX + bool ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278 + bool ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B + bool ' QDI QD6580 support' CONFIG_BLK_DEV_QD6580 + bool ' UMC 8672 support' CONFIG_BLK_DEV_UMC8672 + bool ' ALI M1439/M1445 support' CONFIG_BLK_DEV_ALI14XX fi fi diff --git a/drivers/block/README.hd b/drivers/block/README.hd index 162928178b5d..ba2187425620 100644 --- a/drivers/block/README.hd +++ b/drivers/block/README.hd @@ -5,4 +5,4 @@ support for drives where the BIOS reports "more than 16 heads". The hdparm.c program for controlling various features is now packaged separately. Look for it on your favorite linux FTP site. --mlord@bnr.ca +-mlord@pobox.com diff --git a/drivers/block/README.ide b/drivers/block/README.ide index b9faf0905d2d..9459e3f64d28 100644 --- a/drivers/block/README.ide +++ b/drivers/block/README.ide @@ -1,6 +1,6 @@ README.ide -- Information regarding ide.c and ide-cd.c (IDE driver in 1.3.xx) ================================================================================ -Supported by: mlord@bnr.ca -- disks, interfaces, probing +Supported by: mlord@pobox.com -- disks, interfaces, probing snyder@fnald0.fnal.gov -- cdroms, ATAPI, audio +-----------------------------------------------------------------+ @@ -58,7 +58,7 @@ NEW! - Bus-Master DMA support for Intel PCI Triton chipset IDE interfaces NEW! - ide-cd.c now supports door locking and auto-loading. - Also preliminary support for multisession and direct reads of audio data. -NEW! - the hdparm-2.6 package can be used to set PIO modes for some chipsets. +NEW! - the hdparm-2.7 package can be used to set PIO modes for some chipsets. For work in progress, see the comments in ide.c, ide-cd.c, and triton.c. @@ -67,24 +67,6 @@ caching IDE cards, such as the DC4030VL, and early results are encouraging. Look for this support to be added to the kernel soon. -*** IMPORTANT NOTICES (for kernel versions prior to 1.3.22) -*** ================= -*** "CMD" EIDE Interfaces will not (by default) work *reliably* when drives -*** are attached to the second interface. This is due to a flaw in the -*** hardware. To "fix" this, supply the special kernel "command line" -*** parameter to LILO or LOADLIN: ide1=serialize -*** -*** "CMD 640B" EIDE Interfaces will not work *reliably* when "hdparm -u1" -*** (interrupt unmasking) is used. This is due to a flaw in the hardware, -*** and is only a problem when "hdparm -u1" is used after booting. -*** -*** "RZ1000" EIDE Interfaces will also not work *reliably* when "hdparm -u1" -*** (interrupt unmasking) is used. This is due to a flaw in the hardware, -*** and is only a problem when "hdparm -u1" is used after booting. -*** -*** Failure to abide by these restrictions can cause severe data corruption! - - *** IMPORTANT NOTICES (for kernel versions after 1.3.21) *** ================= *** PCI versions of the CMD640 and RZ1000 interfaces are now detected @@ -216,7 +198,7 @@ and still allows newer hardware to run on the 2nd/3rd/4th IDE ports under control of ide.c. To have ide.c also "take over" the primary IDE port in this situation, use the "command line" parameter: ide0=0x1f0 -mlord@bnr.ca +mlord@pobox.com snyder@fnald0.fnal.gov ================================================================================ @@ -448,7 +430,7 @@ The new WD1.6GB models are also cheap screamers. For really high end systems, go for fast/wide 7200rpm SCSI. But it'll cost ya! -mlord@bnr.ca +mlord@pobox.com ================================================================================ EIDE card compatibility reports: diff --git a/drivers/block/cmd640.c b/drivers/block/cmd640.c index 99a139dc9d06..a90d1674ea1d 100644 --- a/drivers/block/cmd640.c +++ b/drivers/block/cmd640.c @@ -482,6 +482,7 @@ static struct readahead_black_list { const char* name; int mode; } drives_ra[] = { + { "QUANTUM LIGHTNING 540A", 0 }, { "ST3655A", 0 }, { "SAMSUNG", 0 }, /* Be conservative */ { NULL, 0 } diff --git a/drivers/block/dtc2278.c b/drivers/block/dtc2278.c index 2d18111083fb..ea3bda9c99c3 100644 --- a/drivers/block/dtc2278.c +++ b/drivers/block/dtc2278.c @@ -33,9 +33,19 @@ * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my * filesystem corrupted with -u1, but under heavy disk load only :-) * - * This chipset is now forced to use the "serialize" feature, + * This card is now forced to use the "serialize" feature, * and irq-unmasking is disallowed. If io_32bit is enabled, * it must be done for BOTH drives on each interface. + * + * This code was written for the DTC2278E, but might work with any of these: + * + * DTC2278S has only a single IDE interface. + * DTC2278D has two IDE interfaces and is otherwise identical to the S version. + * DTC2278E has onboard BIOS, while the others do not. + * + * There may be a fourth controller type. The S and D versions use the + * Winbond chip, and I think the E version does also. + * */ static void sub22 (char b, char c) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 7c9014d7252b..4a14fff01127 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -1586,7 +1586,7 @@ static struct tq_struct floppy_tq = { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 }; /* interrupt handler */ -static void floppy_interrupt(int irq, struct pt_regs * regs) +static void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs) { void (*handler)(void) = DEVICE_INTR; @@ -2085,6 +2085,7 @@ static void request_done(int uptodate) DPRINT("request list destroyed in floppy request done\n"); return; } + if (uptodate){ /* maintain values for invalidation on geometry * change */ diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index e7774115fdae..cb6687c3d62f 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c @@ -8,7 +8,7 @@ * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug * in the early extended-partition checks and added DM partitions * - * Support for DiskManager v6.0x added by Mark Lord (mlord@bnr.ca) + * Support for DiskManager v6.0x added by Mark Lord, * with information provided by OnTrack. This now works for linux fdisk * and LILO, as well as loadlin and bootln. Note that disks other than * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). @@ -54,37 +54,49 @@ extern int blk_dev_init(void); extern int scsi_dev_init(void); extern int net_dev_init(void); -static void print_minor_name (struct gendisk *hd, int minor) +/* + * disk_name() is used by genhd.c and md.c. + * It formats the devicename of the indicated disk + * into the supplied buffer, and returns a pointer + * to that same buffer (for convenience). + */ +char *disk_name (struct gendisk *hd, int minor, char *buf) { - unsigned int unit = minor >> hd->minor_shift; - unsigned int part = minor & ((1 << hd->minor_shift) - 1); + unsigned int part; + const char *maj = hd->major_name; + char unit = (minor >> hd->minor_shift) + 'a'; #ifdef CONFIG_BLK_DEV_IDE /* * IDE devices use multiple major numbers, but the drives * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}.. - * This requires some creative handling here to find the - * correct name to use, with some help from ide.c + * This requires special handling here. */ - if (!strcmp(hd->major_name,"ide")) { - char name[16]; /* more than large enough */ - strcpy(name, hd->real_devices); /* courtesy ide.c */ - name[strlen(name)-1] += unit; - printk(" %s", name); - } else + switch (hd->major) { + case IDE3_MAJOR: + unit += 2; + case IDE2_MAJOR: + unit += 2; + case IDE1_MAJOR: + unit += 2; + case IDE0_MAJOR: + maj = "hd"; + } #endif - printk(" %s%c", hd->major_name, 'a' + unit); + part = minor & ((1 << hd->minor_shift) - 1); if (part) - printk("%d", part); + sprintf(buf, "%s%c%d", maj, unit, part); else - printk(":"); + sprintf(buf, "%s%c", maj, unit); + return buf; } static void add_partition (struct gendisk *hd, int minor, int start, int size) { + char buf[8]; hd->part[minor].start_sect = start; hd->part[minor].nr_sects = size; - print_minor_name(hd, minor); + printk(" %s", disk_name(hd, minor, buf)); } static inline int is_extended_partition(struct partition *p) @@ -482,6 +494,7 @@ static void check_partition(struct gendisk *hd, kdev_t dev) { static int first_time = 1; unsigned long first_sector; + char buf[8]; if (first_time) printk("Partition check:\n"); @@ -497,8 +510,7 @@ static void check_partition(struct gendisk *hd, kdev_t dev) return; } - printk(" "); - print_minor_name(hd, MINOR(dev)); + printk(" %s:", disk_name(hd, MINOR(dev), buf)); #ifdef CONFIG_MSDOS_PARTITION if (msdos_partition(hd, dev, first_sector)) return; diff --git a/drivers/block/hd.c b/drivers/block/hd.c index a146f811ab30..0cb6df210ed4 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -16,7 +16,7 @@ * in the early extended-partition checks and added DM partitions * * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", - * and general streamlining by mlord@bnr.ca (Mark Lord). + * and general streamlining by Mark Lord. */ #define DEFAULT_MULT_COUNT 0 /* set to 0 to disable multiple mode at boot */ @@ -930,7 +930,7 @@ static struct gendisk hd_gendisk = { NULL /* next */ }; -static void hd_interrupt(int irq, struct pt_regs *regs) +static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { void (*handler)(void) = DEVICE_INTR; @@ -1020,7 +1020,7 @@ static void hd_geninit(struct gendisk *ignored) special_op[i] = 1; } if (NR_HD) { - if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) { + if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) { printk("hd: unable to get IRQ%d for the harddisk driver\n",HD_IRQ); NR_HD = 0; } else { diff --git a/drivers/block/ide.c b/drivers/block/ide.c index d3bb67c5e682..b1f38179d5b7 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -1,5 +1,5 @@ /* - * linux/drivers/block/ide.c Version 5.28 Feb 11, 1996 + * linux/drivers/block/ide.c Version 5.30 Feb 27, 1996 * * Copyright (C) 1994-1996 Linus Torvalds & authors (see below) */ @@ -45,16 +45,16 @@ * | Early work on error handling by Mika Liljeberg (liljeber@cs.Helsinki.FI). * | * | IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", - * | and general streamlining by Mark Lord (mlord@bnr.ca). + * | and general streamlining by Mark Lord (mlord@pobox.com). * * October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by: * - * Mark Lord (mlord@bnr.ca) (IDE Perf.Pkg) + * Mark Lord (mlord@pobox.com) (IDE Perf.Pkg) * Delman Lee (delman@mipg.upenn.edu) ("Mr. atdisk2") * Petri Mattila (ptjmatti@kruuna.helsinki.fi) (EIDE stuff) * Scott Snyder (snyder@fnald0.fnal.gov) (ATAPI IDE cd-rom) * - * Maintained by Mark Lord (mlord@bnr.ca): ide.c, ide.h, triton.c, hd.c, .. + * Maintained by Mark Lord (mlord@pobox.com): ide.c, ide.h, triton.c, hd.c, .. * * This was a rewrite of just about everything from hd.c, though some original * code is still sprinkled about. Think of it as a major evolution, with @@ -205,6 +205,9 @@ * force io_32bit to be the same on drive pairs of dtc2278 * improved IDE tape error handling, and tape DMA support * bugfix in ide_do_drive_cmd() for cdroms + serialize + * Version 5.29 fixed non-IDE check for too many physical heads + * don't use LBA if capacity is smaller than CHS + * Version 5.30 remove real_devices kludge, formerly used by genhd.c * * Some additional driver compile-time options are in ide.h * @@ -470,19 +473,19 @@ static int lba_capacity_is_ok (struct hd_driveid *id) static unsigned long current_capacity (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - unsigned long capacity; + unsigned long capacity = drive->cyl * drive->head * drive->sect; if (!drive->present) return 0; if (drive->media != ide_disk) return 0x7fffffff; /* cdrom or tape */ + drive->select.b.lba = 0; /* Determine capacity, and use LBA if the drive properly supports it */ if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) { - drive->select.b.lba = 1; - capacity = id->lba_capacity; - } else { - drive->select.b.lba = 0; - capacity = drive->cyl * drive->head * drive->sect; + if (id->lba_capacity >= capacity) { + capacity = id->lba_capacity; + drive->select.b.lba = 1; + } } return (capacity - drive->sect0); } @@ -511,13 +514,6 @@ static void ide_geninit (struct gendisk *gd) drive->part[0].start_sect = -1; /* skip partition check */ } } - /* - * The partition check in genhd.c needs this string to identify - * our minor devices by name for display purposes. - * Note that doing this will prevent us from working correctly - * if ever called a second time for this major (never happens). - */ - gd->real_devices = hwif->drives[0].name; /* name of first drive */ } /* @@ -619,6 +615,7 @@ static void reset_pollfunc (ide_drive_t *drive) if ((tmp = GET_ERR()) == 1) printk("success\n"); else { +#if FANCY_STATUS_DUMPS printk("master: "); switch (tmp & 0x7f) { case 1: printk("passed"); @@ -636,6 +633,9 @@ static void reset_pollfunc (ide_drive_t *drive) if (tmp & 0x80) printk("; slave: failed"); printk("\n"); +#else + printk("failed\n"); +#endif /* FANCY_STATUS_DUMPS */ } } hwgroup->poll_timeout = 0; /* done polling */ @@ -1154,8 +1154,9 @@ next: } else drive->mult_req = 0; } else if (s->all) { + int special = s->all; s->all = 0; - printk("%s: bad special flag: 0x%02x\n", drive->name, s->all); + printk("%s: bad special flag: 0x%02x\n", drive->name, special); } } @@ -1461,20 +1462,26 @@ static void do_ide0_request (void) /* invoked with cli() */ do_hwgroup_request (ide_hwifs[0].hwgroup); } +#if MAX_HWIFS > 1 static void do_ide1_request (void) /* invoked with cli() */ { do_hwgroup_request (ide_hwifs[1].hwgroup); } +#endif +#if MAX_HWIFS > 2 static void do_ide2_request (void) /* invoked with cli() */ { do_hwgroup_request (ide_hwifs[2].hwgroup); } +#endif +#if MAX_HWIFS > 3 static void do_ide3_request (void) /* invoked with cli() */ { do_hwgroup_request (ide_hwifs[3].hwgroup); } +#endif static void timer_expiry (unsigned long data) { @@ -1561,7 +1568,7 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) /* * entry point for all interrupts, caller does cli() for us */ -static void ide_intr (int irq, struct pt_regs *regs) +static void ide_intr (int irq, void *dev_id, struct pt_regs *regs) { ide_hwgroup_t *hwgroup = irq_to_hwgroup[irq]; ide_handler_t *handler; @@ -2103,10 +2110,10 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap); ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap); +#ifdef CONFIG_BLK_DEV_IDEATAPI /* * Check for an ATAPI device */ - if (cmd == WIN_PIDENTIFY) { byte type = (id->config >> 8) & 0x1f; printk("%s: %s, ATAPI ", drive->name, id->model); @@ -2153,6 +2160,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) printk("- not supported by this kernel\n"); return; } +#endif /* CONFIG_BLK_DEV_IDEATAPI */ /* check for removeable disks (eg. SYQUEST), ignore 'WD' drives */ if (id->config & (1<<7)) { /* removeable disk ? */ @@ -2392,24 +2400,16 @@ static inline byte probe_for_drive (ide_drive_t *drive) #endif /* CONFIG_BLK_DEV_IDECD */ else { drive->present = 0; /* nuke it */ - return 1; /* drive was found */ - } - } - if (drive->media == ide_disk && !drive->select.b.lba) { - if (!drive->head || drive->head > 16) { - printk("%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", - drive->name, drive->head); - drive->present = 0; } } return 1; /* drive was found */ } /* - * This routine only knows how to look for drive units 0 and 1 - * on an interface, so any setting of MAX_DRIVES > 2 won't work here. + * This routine only knows how to look for drive units 0 and 1 + * on an interface, so any setting of MAX_DRIVES > 2 won't work here. */ -static void probe_for_drives (ide_hwif_t *hwif) +static void probe_hwif (ide_hwif_t *hwif) { unsigned int unit; @@ -2429,25 +2429,25 @@ static void probe_for_drives (ide_hwif_t *hwif) unsigned long flags; save_flags(flags); -#if (MAX_DRIVES > 2) - printk("%s: probing for first 2 of %d possible drives\n", hwif->name, MAX_DRIVES); -#endif sti(); /* needed for jiffies and irq probing */ /* * Second drive should only exist if first drive was found, - * but a lot of cdrom drives seem to be configured as slave-only + * but a lot of cdrom drives are configured as single slaves. */ - for (unit = 0; unit < 2; ++unit) { /* note the hardcoded '2' */ - ide_drive_t *drive = &hwif->drives[unit]; - (void) probe_for_drive (drive); - } for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; - if (drive->present) { + (void) probe_for_drive (drive); + if (drive->present && drive->media == ide_disk) { + if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { + printk("%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", + drive->name, drive->head); + drive->present = 0; + } + } + if (drive->present && !hwif->present) { hwif->present = 1; request_region(hwif->io_base, 8, hwif->name); request_region(hwif->ctl_port, 1, hwif->name); - break; } } restore_flags(flags); @@ -2883,7 +2883,7 @@ static int init_irq (ide_hwif_t *hwif) * Grab the irq if we don't already have it from a previous hwif */ if (hwgroup == NULL) { - if (request_irq(irq, ide_intr, SA_INTERRUPT|SA_SAMPLE_RANDOM, hwif->name)) { + if (request_irq(irq, ide_intr, SA_INTERRUPT|SA_SAMPLE_RANDOM, hwif->name, NULL)) { restore_flags(flags); printk(" -- FAILED!"); return 1; @@ -2893,7 +2893,7 @@ static int init_irq (ide_hwif_t *hwif) * Check for serialization with ide1. * This code depends on us having already taken care of ide1. */ - if (hwif->serialized && hwif->name[3] == '0' && ide_hwifs[1].present) + if (hwif->serialized && hwif->index == 0 && ide_hwifs[1].present) hwgroup = ide_hwifs[1].hwgroup; /* * If this is the first interface in a group, @@ -3025,7 +3025,7 @@ int ide_init (void) if (!hwif->noprobe) { if (hwif->io_base == HD_DATA) probe_cmos_for_drives (hwif); - probe_for_drives (hwif); + probe_hwif (hwif); } if (hwif->present) { if (!hwif->irq) { @@ -3055,9 +3055,15 @@ int ide_init (void) hwif->present = 0; /* we set it back to 1 if all is ok below */ switch (hwif->major) { case IDE0_MAJOR: rfn = &do_ide0_request; break; +#if MAX_HWIFS > 1 case IDE1_MAJOR: rfn = &do_ide1_request; break; +#endif +#if MAX_HWIFS > 2 case IDE2_MAJOR: rfn = &do_ide2_request; break; +#endif +#if MAX_HWIFS > 3 case IDE3_MAJOR: rfn = &do_ide3_request; break; +#endif default: printk("%s: request_fn NOT DEFINED\n", hwif->name); continue; diff --git a/drivers/block/ide.h b/drivers/block/ide.h index b1ebc4c3c88e..7b5ed8b5f374 100644 --- a/drivers/block/ide.h +++ b/drivers/block/ide.h @@ -126,7 +126,9 @@ typedef unsigned char byte; /* used everywhere */ #define PARTN_BITS 6 /* number of minor dev bits for partitions */ #define PARTN_MASK ((1<b_dev)] < (sector + count)>>1) { bh->b_state = 0; printk("attempt to access beyond end of device\n"); + printk("%s: rw=%d, want=%d, limit=%d\n", kdevname(bh->b_dev), + rw, (sector + count)>>1, blk_size[major][MINOR(bh->b_dev)]); return; } /* Uhhuh.. Nasty dead-lock possible here.. */ diff --git a/drivers/block/md.c b/drivers/block/md.c index a478cb90320e..1285ffa3a3bd 100644 --- a/drivers/block/md.c +++ b/drivers/block/md.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #define MAJOR_NR MD_MAJOR @@ -94,8 +95,6 @@ char *partition_name (kdev_t dev) static char name[10]; /* This should be long enough for a device name ! */ struct gendisk *hd=find_gendisk (dev); - char base_name; - int minor=MINOR(dev); if (!hd) { @@ -104,12 +103,7 @@ char *partition_name (kdev_t dev) return (name); } - base_name = (hd->major == IDE1_MAJOR) ? 'c' : 'a'; - sprintf(name, "%s%c%d", - hd->major_name, - base_name + (minor >> hd->minor_shift), - minor & ((1 << hd->minor_shift) - 1)); - return (name); + return disk_name (hd, MINOR(dev), name); /* routine in genhd.c */ } diff --git a/drivers/block/rz1000.c b/drivers/block/rz1000.c index 11f1dbd57421..b34b18e0eee2 100644 --- a/drivers/block/rz1000.c +++ b/drivers/block/rz1000.c @@ -5,7 +5,7 @@ */ /* - * Principal Author/Maintainer: mlord@bnr.ca (Mark Lord) + * Principal Author/Maintainer: mlord@pobox.com (Mark Lord) * * This file provides support for disabling the buggy read-ahead * mode of the RZ1000 IDE chipset, commonly used on Intel motherboards. diff --git a/drivers/block/triton.c b/drivers/block/triton.c index 5829661170a1..8471036ace5e 100644 --- a/drivers/block/triton.c +++ b/drivers/block/triton.c @@ -85,7 +85,10 @@ * - like most Conner models, this drive proves that even a fast interface * cannot improve slow media. Both DMA and PIO peak around 3.5MB/sec. * - * If you have any drive models to add, email your results to: mlord@bnr.ca + * Maxtor 71260AT (1204Meg w/256kB buffer), DMA mword0/sword2, PIO mode3. + * - works with DMA, giving 3-4MB/sec performance, about the same as mode3. + * + * If you have any drive models to add, email your results to: mlord@pobox.com * Keep an eye on /var/adm/messages for "DMA disabled" messages. * * Some people have reported trouble with Intel Zappa motherboards. @@ -118,6 +121,7 @@ * known to work fine with this interface under Linux. */ const char *good_dma_drives[] = {"Micropolis 2112A", + "Maxtor 71260 AT", "CONNER CTMA 4000"}; /* diff --git a/drivers/block/xd.c b/drivers/block/xd.c index b0c08297683e..5afa5edf4783 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -168,10 +168,10 @@ static void xd_geninit (struct gendisk *ignored) for (i = 0; i < xd_drives; i++) printk("xd_geninit: drive %d geometry - heads = %d, cylinders = %d, sectors = %d\n",i,xd_info[i].heads,xd_info[i].cylinders,xd_info[i].sectors); - if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT harddisk")) { + if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT harddisk", NULL)) { if (request_dma(xd_dma,"xd")) { printk("xd_geninit: unable to get DMA%d\n",xd_dma); - free_irq(xd_irq); + free_irq(xd_irq, NULL); } } else @@ -391,7 +391,7 @@ static void xd_recalibrate (u_char drive) } /* xd_interrupt_handler: interrupt service routine */ -static void xd_interrupt_handler(int irq, struct pt_regs * regs) +static void xd_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) { if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */ #ifdef DEBUG_OTHER diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index d227f0e4f556..8da5b3851c6c 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c @@ -521,7 +521,7 @@ write_cmd(unsigned char cmd) } static void -cdu31a_interrupt(int irq, struct pt_regs *regs) +cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char val; @@ -3085,7 +3085,7 @@ cdu31a_init(void) if (cdu31a_irq > 0) { - if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a")) + if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a", NULL)) { printk("Unable to grab IRQ%d for the CDU31A driver\n", cdu31a_irq); cdu31a_irq = 0; diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c index e64d2808df06..8f4c1e5d9afb 100644 --- a/drivers/cdrom/cm206.c +++ b/drivers/cdrom/cm206.c @@ -221,7 +221,7 @@ uch send_receive_polled(int command) as there seems so reason for this to happen. */ -static void cm206_interrupt(int sig, struct pt_regs * regs) /* you rang? */ +static void cm206_interrupt(int sig, void *dev_id, struct pt_regs * regs) /* you rang? */ { volatile ush fool; cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error, @@ -1052,7 +1052,7 @@ void cleanup(int level) return; } case 3: - free_irq(cm206_irq); + free_irq(cm206_irq, NULL); case 2: case 1: kfree(cd); @@ -1156,7 +1156,7 @@ int cm206_init(void) else printk(" single"); printk(" speed drive"); if (e & dcf_motorized_tray) printk(", motorized tray"); - if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206")) { + if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) { printk("\nUnable to reserve IRQ---aborted\n"); cleanup(2); return -EIO; diff --git a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c index 55ef2e986c6f..c829640e4223 100644 --- a/drivers/cdrom/mcd.c +++ b/drivers/cdrom/mcd.c @@ -628,7 +628,7 @@ mcd_transfer(void) */ static void -mcd_interrupt(int irq, struct pt_regs * regs) +mcd_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int st; @@ -1234,7 +1234,7 @@ int mcd_init(void) /* don't get the IRQ until we know for sure the drive is there */ - if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD")) + if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) { printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq); return -EIO; @@ -1617,7 +1617,7 @@ void cleanup_module(void) return; } release_region(mcd_port,4); - free_irq(mcd_irq); + free_irq(mcd_irq, NULL); printk("mcd module released.\n"); } #endif MODULE diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index 911186233c62..6c6726490eb9 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c @@ -191,7 +191,7 @@ void mcdx_setup(char *, int *); structure fops. */ /* ??? exported by the mcdx_sigaction struct */ -static void mcdx_intr(int, struct pt_regs*); +static void mcdx_intr(int, void *, struct pt_regs*); /* exported by file_ops */ static int mcdx_open(struct inode*, struct file*); @@ -835,7 +835,7 @@ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs) } static void -mcdx_intr(int irq, struct pt_regs* regs) +mcdx_intr(int irq, void *dev_id, struct pt_regs* regs) { struct s_drive_stuff *stuffp; unsigned char x; @@ -1002,7 +1002,7 @@ void cleanup_module(void) stuffp = mcdx_stuffp[i]; if (!stuffp) continue; release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE); - free_irq(stuffp->irq); + free_irq(stuffp->irq, NULL); if (stuffp->toc) { TRACE((MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc)); kfree(stuffp->toc); @@ -1170,7 +1170,7 @@ int mcdx_init(void) TRACE((INIT, "init() subscribe irq and i/o\n")); mcdx_irq_map[stuffp->irq] = stuffp; - if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, DEVICE_NAME)) { + if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, DEVICE_NAME, NULL)) { WARN(("%s=0x%3p,%d: Init failed. Can't get irq (%d).\n", MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq)); diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c index af2da532680a..90790632271a 100644 --- a/drivers/cdrom/sonycd535.c +++ b/drivers/cdrom/sonycd535.c @@ -313,7 +313,7 @@ disable_interrupts(void) } static void -cdu535_interrupt(int irq, struct pt_regs *regs) +cdu535_interrupt(int irq, void *dev_id, struct pt_regs *regs) { disable_interrupts(); if (cdu535_irq_wait != NULL) @@ -1566,7 +1566,7 @@ sony535_init(void) #endif if (sony535_irq_used > 0) { if (request_irq(sony535_irq_used, cdu535_interrupt, - SA_INTERRUPT, CDU535_HANDLE)) { + SA_INTERRUPT, CDU535_HANDLE, NULL)) { printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME " driver; polling instead.\n", sony535_irq_used); sony535_irq_used = 0; diff --git a/drivers/char/atixlmouse.c b/drivers/char/atixlmouse.c index 558faf735734..67e79f000fd1 100644 --- a/drivers/char/atixlmouse.c +++ b/drivers/char/atixlmouse.c @@ -69,7 +69,7 @@ static struct mouse_status { struct fasync_struct *fasync; } mouse; -void mouse_interrupt(int irq, struct pt_regs * regs) +void mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs) { char dx, dy, buttons; @@ -110,7 +110,7 @@ static void release_mouse(struct inode * inode, struct file * file) return; ATIXL_MSE_INT_OFF(); /* Interrupts are really shut down here */ mouse.ready = 0; - free_irq(ATIXL_MOUSE_IRQ); + free_irq(ATIXL_MOUSE_IRQ, NULL); MOD_DEC_USE_COUNT; } @@ -120,7 +120,7 @@ static int open_mouse(struct inode * inode, struct file * file) return -EINVAL; if (mouse.active++) return 0; - if (request_irq(ATIXL_MOUSE_IRQ, mouse_interrupt, 0, "ATIXL mouse")) { + if (request_irq(ATIXL_MOUSE_IRQ, mouse_interrupt, 0, "ATIXL mouse", NULL)) { mouse.active--; return -EBUSY; } diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c index c509dfe4f628..9dcb897f826f 100644 --- a/drivers/char/busmouse.c +++ b/drivers/char/busmouse.c @@ -60,7 +60,7 @@ void bmouse_setup(char *str, int *ints) mouse_irq=ints[1]; } -static void mouse_interrupt(int irq, struct pt_regs *regs) +static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs) { char dx, dy; unsigned char buttons; @@ -124,7 +124,7 @@ static void close_mouse(struct inode * inode, struct file * file) if (--mouse.active) return; MSE_INT_OFF(); - free_irq(mouse_irq); + free_irq(mouse_irq, NULL); MOD_DEC_USE_COUNT; } @@ -138,7 +138,7 @@ static int open_mouse(struct inode * inode, struct file * file) return -EINVAL; if (mouse.active++) return 0; - if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse")) { + if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse", NULL)) { mouse.active--; return -EBUSY; } diff --git a/drivers/char/console.c b/drivers/char/console.c index 7da2fae0d1a7..10e74050ac68 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -2001,7 +2001,7 @@ unsigned long con_init(unsigned long kmem_start) console_driver.num = MAX_NR_CONSOLES; console_driver.type = TTY_DRIVER_TYPE_CONSOLE; console_driver.init_termios = tty_std_termios; - console_driver.flags = TTY_DRIVER_REAL_RAW; + console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; console_driver.refcount = &console_refcount; console_driver.table = console_table; console_driver.termios = console_termios; diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index e6dd825a783e..89fa7c31d417 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -604,7 +604,7 @@ static int probe_ready; * while we are probing for submarines. */ static void -cy_probe(int irq, struct pt_regs *regs) +cy_probe(int irq, void *dev_id, struct pt_regs *regs) { int save_xir, save_car; int index = 0; /* probing interrupts is only for ISA */ @@ -637,7 +637,7 @@ cy_probe(int irq, struct pt_regs *regs) received, out buffer empty, modem change, etc. */ static void -cy_interrupt(int irq, struct pt_regs *regs) +cy_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct tty_struct *tty; int status; @@ -1037,7 +1037,7 @@ grab_all_interrupts(int dontgrab) for (i = 0, mask = 1; i < 16; i++, mask <<= 1) { if (!(mask & dontgrab) - && !request_irq(i, cy_probe, SA_INTERRUPT, "serial probe")) { + && !request_irq(i, cy_probe, SA_INTERRUPT, "serial probe", NULL)) { irq_lines |= mask; } } @@ -1054,7 +1054,7 @@ free_all_interrupts(int irq_lines) for (i = 0; i < 16; i++) { if (irq_lines & (1 << i)) - free_irq(i); + free_irq(i,NULL); } } /* free_all_interrupts */ @@ -2927,7 +2927,7 @@ cleanup_module(void) for (i = 0; i < NR_CARDS; i++) { if (cy_card[i].base_addr != 0) { - free_irq(cy_card[i].irq); + free_irq(cy_card[i].irq,NULL); } } } @@ -2985,7 +2985,7 @@ cy_detect_isa() } /* allocate IRQ */ - if(request_irq(cy_isa_irq,cy_interrupt,SA_INTERRUPT,"cyclades")) + if(request_irq(cy_isa_irq,cy_interrupt,SA_INTERRUPT,"cyclades",NULL)) { printk("Cyclom-Y/ISA found at 0x%x but could not allocate interrupt IRQ#%d.\n", (unsigned int) cy_isa_address,cy_isa_irq); @@ -3082,7 +3082,7 @@ cy_detect_pci() } /* allocate IRQ */ - if(request_irq(cy_pci_irq,cy_interrupt,SA_INTERRUPT,"cyclades")) + if(request_irq(cy_pci_irq,cy_interrupt,SA_INTERRUPT,"cyclades",NULL)) { printk("Cyclom-Y/PCI found at 0x%x but could not allocate interrupt IRQ%d.\n", (unsigned int) cy_pci_address,cy_pci_irq); diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index a3018131d7fd..61bcce0e3e46 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -337,7 +337,7 @@ int getkeycode(unsigned int scancode) e0_keys[scancode - 128]; } -static void keyboard_interrupt(int irq, struct pt_regs *regs) +static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char scancode, keycode; static unsigned int prev_scancode = 0; /* remember E0, E1 */ @@ -1183,7 +1183,7 @@ int kbd_init(void) ttytab = console_driver.table; bh_base[KEYBOARD_BH].routine = kbd_bh; - request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard"); + request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL); request_region(0x60,16,"kbd"); #ifdef INIT_KBD initialize_kbd(); diff --git a/drivers/char/lp.c b/drivers/char/lp.c index dcb25c310a23..77c105732023 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -147,7 +147,7 @@ static inline int lp_char_interrupt(char lpchar, int minor) return 0; } -static void lp_interrupt(int irq, struct pt_regs *regs) +static void lp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct lp_struct *lp = &lp_table[0]; @@ -358,7 +358,7 @@ static int lp_open(struct inode * inode, struct file * file) return -ENOMEM; } - ret = request_irq(irq, lp_interrupt, SA_INTERRUPT, "printer"); + ret = request_irq(irq, lp_interrupt, SA_INTERRUPT, "printer", NULL); if (ret) { kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE); lp_table[minor].lp_buffer = NULL; @@ -378,7 +378,7 @@ static void lp_release(struct inode * inode, struct file * file) unsigned int irq; if ((irq = LP_IRQ(minor))) { - free_irq(irq); + free_irq(irq, NULL); kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE); lp_table[minor].lp_buffer = NULL; } @@ -447,14 +447,14 @@ static int lp_ioctl(struct inode *inode, struct file *file, } if (oldirq) { - free_irq(oldirq); + free_irq(oldirq, NULL); } if (newirq) { /* Install new irq */ - if ((retval = request_irq(newirq, lp_interrupt, SA_INTERRUPT, "printer"))) { + if ((retval = request_irq(newirq, lp_interrupt, SA_INTERRUPT, "printer", NULL))) { if (oldirq) { /* restore old irq */ - request_irq(oldirq, lp_interrupt, SA_INTERRUPT, "printer"); + request_irq(oldirq, lp_interrupt, SA_INTERRUPT, "printer", NULL); } else { /* We don't need the buffer */ kfree_s(lp->lp_buffer, LP_BUFFER_SIZE); diff --git a/drivers/char/msbusmouse.c b/drivers/char/msbusmouse.c index c54cc79d1c77..8b7aa8b112f3 100644 --- a/drivers/char/msbusmouse.c +++ b/drivers/char/msbusmouse.c @@ -48,7 +48,7 @@ static struct mouse_status mouse; -static void ms_mouse_interrupt(int irq, struct pt_regs * regs) +static void ms_mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs) { char dx, dy; unsigned char buttons; @@ -97,7 +97,7 @@ static void release_mouse(struct inode * inode, struct file * file) return; MS_MSE_INT_OFF(); mouse.ready = 0; - free_irq(MOUSE_IRQ); + free_irq(MOUSE_IRQ, NULL); MOD_DEC_USE_COUNT; } @@ -107,7 +107,7 @@ static int open_mouse(struct inode * inode, struct file * file) return -EINVAL; if (mouse.active++) return 0; - if (request_irq(MOUSE_IRQ, ms_mouse_interrupt, 0, "MS Busmouse")) { + if (request_irq(MOUSE_IRQ, ms_mouse_interrupt, 0, "MS Busmouse", NULL)) { mouse.active--; return -EBUSY; } diff --git a/drivers/char/psaux.c b/drivers/char/psaux.c index 698e78c29dbb..24fcfef09e0b 100644 --- a/drivers/char/psaux.c +++ b/drivers/char/psaux.c @@ -208,7 +208,7 @@ static inline int queue_empty(void) * is waiting in the keyboard/aux controller. */ -static void aux_interrupt(int cpl, struct pt_regs * regs) +static void aux_interrupt(int cpl, void *dev_id, struct pt_regs * regs) { int head = queue->head; int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1); @@ -234,7 +234,7 @@ static void aux_interrupt(int cpl, struct pt_regs * regs) */ #ifdef CONFIG_82C710_MOUSE -static void qp_interrupt(int cpl, struct pt_regs * regs) +static void qp_interrupt(int cpl, void *dev_id, struct pt_regs * regs) { int head = queue->head; int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1); @@ -262,7 +262,7 @@ static void release_aux(struct inode * inode, struct file * file) poll_aux_status(); outb_p(AUX_DISABLE,AUX_COMMAND); /* Disable Aux device */ poll_aux_status(); - free_irq(AUX_IRQ); + free_irq(AUX_IRQ, NULL); MOD_DEC_USE_COUNT; } @@ -280,7 +280,7 @@ static void release_qp(struct inode * inode, struct file * file) outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status); if (!poll_qp_status()) printk("Warning: Mouse device busy in release_qp()\n"); - free_irq(QP_IRQ); + free_irq(QP_IRQ, NULL); MOD_DEC_USE_COUNT; } #endif @@ -311,7 +311,7 @@ static int open_aux(struct inode * inode, struct file * file) return -EBUSY; } queue->head = queue->tail = 0; /* Flush input queue */ - if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse")) { + if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL)) { aux_count--; return -EBUSY; } @@ -341,7 +341,7 @@ static int open_qp(struct inode * inode, struct file * file) if (qp_count++) return 0; - if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse")) { + if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse", NULL)) { qp_count--; return -EBUSY; } @@ -361,7 +361,7 @@ static int open_qp(struct inode * inode, struct file * file) qp_count--; status &= ~(QP_ENABLE|QP_INTS_ON); outb_p(status, qp_status); - free_irq(QP_IRQ); + free_irq(QP_IRQ, NULL); return -EBUSY; } diff --git a/drivers/char/scc.c b/drivers/char/scc.c index fd48b6f03605..e73603eabfd5 100644 --- a/drivers/char/scc.c +++ b/drivers/char/scc.c @@ -238,7 +238,7 @@ static void scc_txint(register struct scc_channel *scc); static void scc_exint(register struct scc_channel *scc); static void scc_rxint(register struct scc_channel *scc); static void scc_spint(register struct scc_channel *scc); -static void scc_isr(int irq, struct pt_regs *regs); +static void scc_isr(int irq, void *dev_id, struct pt_regs *regs); static void scc_tx_timer(unsigned long); static void scc_rx_timer(unsigned long); static void scc_init_timer(struct scc_channel *scc); @@ -732,7 +732,7 @@ scc_isr_dispatch(register struct scc_channel *scc, register int vector) */ static void -scc_isr(int irq, struct pt_regs *regs) +scc_isr(int irq, void *dev_id, struct pt_regs *regs) { register unsigned char vector; register struct scc_channel *scc; @@ -2128,7 +2128,7 @@ scc_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned if (!Ivec[hwcfg.irq].used && hwcfg.irq) { - if (request_irq(hwcfg.irq, scc_isr, SA_INTERRUPT, "AX.25 SCC")) + if (request_irq(hwcfg.irq, scc_isr, SA_INTERRUPT, "AX.25 SCC", NULL)) printk("z8530drv: Warning --- could not get IRQ %d\n", hwcfg.irq); else Ivec[hwcfg.irq].used = 1; @@ -2784,7 +2784,7 @@ void cleanup_module(void) } for (k=0; k < 16 ; k++) - if (Ivec[k].used) free_irq(k); + if (Ivec[k].used) free_irq(k, NULL); restore_flags(flags); } diff --git a/drivers/char/serial.c b/drivers/char/serial.c index 5833745cda70..c98d4396b797 100644 --- a/drivers/char/serial.c +++ b/drivers/char/serial.c @@ -351,7 +351,7 @@ static void rs_start(struct tty_struct *tty) * This is the serial driver's interrupt routine while we are probing * for submarines. */ -static void rs_probe(int irq, struct pt_regs * regs) +static void rs_probe(int irq, void *dev_id, struct pt_regs * regs) { rs_irq_triggered = irq; rs_triggered |= 1 << irq; @@ -514,7 +514,7 @@ static _INLINE_ void check_modem_status(struct async_struct *info) /* * This is the serial driver's generic interrupt routine */ -static void rs_interrupt(int irq, struct pt_regs * regs) +static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int status; struct async_struct * info; @@ -580,7 +580,7 @@ static void rs_interrupt(int irq, struct pt_regs * regs) /* * This is the serial driver's interrupt routine for a single port */ -static void rs_interrupt_single(int irq, struct pt_regs * regs) +static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) { int status; int pass_counter = 0; @@ -629,7 +629,7 @@ static void rs_interrupt_single(int irq, struct pt_regs * regs) /* * This is the serial driver's for multiport boards */ -static void rs_interrupt_multi(int irq, struct pt_regs * regs) +static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs) { int status; struct async_struct * info; @@ -794,11 +794,11 @@ static void rs_timer(void) info = info->next_port; } while (info); if (rs_multiport[i].port1) - rs_interrupt_multi(i, NULL); + rs_interrupt_multi(i, NULL, NULL); else - rs_interrupt(i, NULL); + rs_interrupt(i, NULL, NULL); } else - rs_interrupt_single(i, NULL); + rs_interrupt_single(i, NULL, NULL); sti(); } } @@ -808,7 +808,7 @@ static void rs_timer(void) if (IRQ_ports[0]) { cli(); - rs_interrupt(0, NULL); + rs_interrupt(0, NULL, NULL); sti(); timer_table[RS_TIMER].expires = jiffies + IRQ_timeout[0] - 2; @@ -836,7 +836,7 @@ static int grab_all_interrupts(int dontgrab) int i, mask; for (i = 0, mask = 1; i < 16; i++, mask <<= 1) { - if (!(mask & dontgrab) && !request_irq(i, rs_probe, SA_INTERRUPT, "serial probe")) { + if (!(mask & dontgrab) && !request_irq(i, rs_probe, SA_INTERRUPT, "serial probe", NULL)) { irq_lines |= mask; } } @@ -852,7 +852,7 @@ static void free_all_interrupts(int irq_lines) for (i = 0; i < 16; i++) { if (irq_lines & (1 << i)) - free_irq(i); + free_irq(i, NULL); } } @@ -886,7 +886,7 @@ static int startup(struct async_struct * info) unsigned short ICP; unsigned long flags; int retval; - void (*handler)(int, struct pt_regs *); + void (*handler)(int, void *, struct pt_regs *); unsigned long page; page = get_free_page(GFP_KERNEL); @@ -954,7 +954,7 @@ static int startup(struct async_struct * info) if (info->irq && (!IRQ_ports[info->irq] || !IRQ_ports[info->irq]->next_port)) { if (IRQ_ports[info->irq]) { - free_irq(info->irq); + free_irq(info->irq, NULL); if (rs_multiport[info->irq].port1) handler = rs_interrupt_multi; else @@ -962,7 +962,7 @@ static int startup(struct async_struct * info) } else handler = rs_interrupt_single; - retval = request_irq(info->irq, handler, SA_INTERRUPT, "serial"); + retval = request_irq(info->irq, handler, SA_INTERRUPT, "serial", NULL); if (retval) { restore_flags(flags); if (suser()) { @@ -1089,14 +1089,14 @@ static void shutdown(struct async_struct * info) if (info->irq && (!IRQ_ports[info->irq] || !IRQ_ports[info->irq]->next_port)) { if (IRQ_ports[info->irq]) { - free_irq(info->irq); - retval = request_irq(info->irq, rs_interrupt_single, SA_INTERRUPT, "serial"); + free_irq(info->irq, NULL); + retval = request_irq(info->irq, rs_interrupt_single, SA_INTERRUPT, "serial", NULL); if (retval) printk("serial shutdown: request_irq: error %d" " Couldn't reacquire IRQ.\n", retval); } else - free_irq(info->irq); + free_irq(info->irq, NULL); } if (info->xmit_buf) { @@ -1792,7 +1792,7 @@ static int set_multiport_struct(struct async_struct * info, struct rs_multiport_struct *multi; int was_multi, now_multi; int retval; - void (*handler)(int, struct pt_regs *); + void (*handler)(int, void *, struct pt_regs *); if (!suser()) return -EPERM; @@ -1846,14 +1846,14 @@ static int set_multiport_struct(struct async_struct * info, if (IRQ_ports[info->irq]->next_port && (was_multi != now_multi)) { - free_irq(info->irq); + free_irq(info->irq, NULL); if (now_multi) handler = rs_interrupt_multi; else handler = rs_interrupt; retval = request_irq(info->irq, handler, SA_INTERRUPT, - "serial"); + "serial", NULL); if (retval) { printk("Couldn't reallocate serial interrupt " "driver!!\n"); diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index e0e3806ed08d..5bc61faeecb3 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -489,7 +489,7 @@ static void stl_disableintrs(stlport_t *portp); static void stl_sendbreak(stlport_t *portp, long len); static int stl_waitcarrier(stlport_t *portp, struct file *filp); static void stl_delay(int len); -static void stl_intr(int irq, struct pt_regs *regs); +static void stl_intr(int irq, void *dev_id, struct pt_regs *regs); static void stl_offintr(void *private); static void *stl_memalloc(int len); @@ -594,7 +594,7 @@ void cleanup_module() } for (i = 0; (i < stl_numintrs); i++) - free_irq(stl_gotintrs[i]); + free_irq(stl_gotintrs[i], NULL); restore_flags(flags); } @@ -1747,7 +1747,7 @@ static inline void stl_mdmisr(stlpanel_t *panelp, int ioaddr) * io region. */ -static void stl_intr(int irq, struct pt_regs *regs) +static void stl_intr(int irq, void *dev_id, struct pt_regs *regs) { stlbrd_t *brdp; stlpanel_t *panelp; @@ -2364,7 +2364,7 @@ static int stl_mapirq(int irq) break; } if (i >= stl_numintrs) { - if (request_irq(irq, stl_intr, SA_INTERRUPT, stl_drvname) != 0) { + if (request_irq(irq, stl_intr, SA_INTERRUPT, stl_drvname, NULL) != 0) { printk("STALLION: failed to register interrupt routine for irq=%d\n", irq); rc = -ENODEV; } else { diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c index e51724279c0f..92e0cfc18695 100644 --- a/drivers/char/tpqic02.c +++ b/drivers/char/tpqic02.c @@ -1797,7 +1797,7 @@ static void qic02_tape_times_out(void) * When we are finished, set flags to indicate end, disable timer. * NOTE: This *must* be fast! */ -static void qic02_tape_interrupt(int irq, struct pt_regs *regs) +static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int stat, r, i; @@ -2812,7 +2812,7 @@ static inline unsigned long const align_buffer(unsigned long a, unsigned size) static void qic02_release_resources(void) { - free_irq(QIC02_TAPE_IRQ); + free_irq(QIC02_TAPE_IRQ, NULL); free_dma(QIC02_TAPE_DMA); status_zombie = YES; } /* qic02_release_resources */ @@ -2835,7 +2835,7 @@ static int qic02_get_resources(void) */ /* get IRQ */ - if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02")) { + if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02", NULL)) { printk(TPQIC02_NAME ": can't allocate IRQ%d for QIC-02 tape\n", QIC02_TAPE_IRQ); status_zombie = YES; @@ -2846,7 +2846,7 @@ static int qic02_get_resources(void) if (request_dma(QIC02_TAPE_DMA,"QIC-02")) { printk(TPQIC02_NAME ": can't allocate DMA%d for QIC-02 tape\n", QIC02_TAPE_DMA); - free_irq(QIC02_TAPE_IRQ); + free_irq(QIC02_TAPE_IRQ, NULL); status_zombie = YES; return -1; } @@ -2931,7 +2931,7 @@ int qic02_tape_init(void) if (register_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops)) { printk(TPQIC02_NAME ": Unable to get chrdev major %d\n", QIC02_TAPE_MAJOR); #ifndef CONFIG_QIC02_DYNCONF - free_irq(QIC02_TAPE_IRQ); + free_irq(QIC02_TAPE_IRQ, NULL); free_dma(QIC02_TAPE_DMA); #endif return -ENODEV; @@ -2947,7 +2947,7 @@ int qic02_tape_init(void) /* No drive detected, so vanish */ tpqputs(TPQD_ALWAYS, "No drive detected -- driver going on vacation..."); status_dead = YES; - free_irq(QIC02_TAPE_IRQ); + free_irq(QIC02_TAPE_IRQ, NULL); free_dma(QIC02_TAPE_DMA); unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME); return -ENODEV; diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c index 7f2b5777d24a..7ebfcb8ce662 100644 --- a/drivers/char/wdt.c +++ b/drivers/char/wdt.c @@ -69,7 +69,7 @@ static void wdt_ctr_load(int ctr, int val) * Kernel methods. */ -static void wdt_interrupt(int irq, struct pt_regs *regs) +static void wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* * Read the status register see what is up and @@ -234,7 +234,7 @@ static struct mouse temp_mouse= int init_module(void) { printk("WDT501-P module at %X(Interrupt %d)\n", io,irq); - if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p")) + if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL)) { printk("IRQ %d is not free.\n", irq); return -EIO; @@ -254,7 +254,7 @@ void cleanup_module(void) mouse_deregister(&temp_mouse); #endif release_region(io,8); - free_irq(irq); + free_irq(irq, NULL); } #else @@ -262,7 +262,7 @@ void cleanup_module(void) int wdt_init(void) { printk("WDT500/501-P driver at %X(Interrupt %d)\n", io,irq); - if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p")) + if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL)) { printk("IRQ %d is not free.\n", irq); return -EIO; diff --git a/drivers/isdn/teles/card.c b/drivers/isdn/teles/card.c index 710a02242f70..a8b4c2ead840 100644 --- a/drivers/isdn/teles/card.c +++ b/drivers/isdn/teles/card.c @@ -1050,6 +1050,15 @@ checkcard(int cardnr) readhscx_0(card->membase, 1, HSCX_VSTR) & 0xf); } } else { + switch (card->iobase) { + case 0x180: + case 0x280: + case 0x380: + printk(KERN_INFO "teles: port 0x%x specified, assuming 0x%x\n", + card->iobase, (card->iobase | 0xc00)); + card->iobase |= 0xc00; + break; + } if (check_region(card->iobase, 8)) { printk(KERN_WARNING "teles: ports %x-%x already in use\n", diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index 6f8dceb62b26..bbbdc3f60bb2 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -93,7 +93,6 @@ static const char *version = #include #include #include -#include #include #include /* for CONFIG_IP_MULTICAST */ @@ -120,7 +119,7 @@ int el1_probe(struct device *dev); static int el1_probe1(struct device *dev, int ioaddr); static int el_open(struct device *dev); static int el_start_xmit(struct sk_buff *skb, struct device *dev); -static void el_interrupt(int irq, struct pt_regs *regs); +static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void el_receive(struct device *dev); static void el_reset(struct device *dev); static int el1_close(struct device *dev); @@ -361,7 +360,7 @@ static int el_open(struct device *dev) if (el_debug > 2) printk("%s: Doing el_open()...", dev->name); - if (request_irq(dev->irq, &el_interrupt, 0, "3c501")) + if (request_irq(dev->irq, &el_interrupt, 0, "3c501", NULL)) return -EAGAIN; irq2dev_map[dev->irq] = dev; @@ -489,7 +488,7 @@ load_it_again_sam: * Handle the ether interface interrupts. */ -static void el_interrupt(int irq, struct pt_regs *regs) +static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -765,7 +764,7 @@ static int el1_close(struct device *dev) * Free and disable the IRQ. */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); outb(AX_RESET, AX_CMD); /* Reset the chip */ irq2dev_map[dev->irq] = 0; diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index 9a0c0b9e87ec..c917de75c766 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -26,6 +26,7 @@ Paul Gortmaker : add support for the 2nd 8kB of RAM on 16 bit cards. Paul Gortmaker : multiple card support for module users. + rjohnson@analogic.com : Fix up PIO interface for efficient operation. */ @@ -47,7 +48,7 @@ static const char *version = #include "8390.h" #include "3c503.h" - +#define WRD_COUNT 4 int el2_probe(struct device *dev); int el2_pio_probe(struct device *dev); @@ -193,7 +194,6 @@ el2_probe1(struct device *dev, int ioaddr) printk(version); dev->base_addr = ioaddr; - /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk ("3c503: unable to allocate memory for dev->priv.\n"); @@ -251,7 +251,7 @@ el2_probe1(struct device *dev, int ioaddr) writel(test_val, mem_base + i); if (readl(mem_base) != 0xba5eba5e || readl(mem_base + i) != test_val) { - printk("3c503.c: memory failure or memory address conflict.\n"); + printk("3c503: memory failure or memory address conflict.\n"); dev->mem_start = 0; ei_status.name = "3c503-PIO"; break; @@ -319,9 +319,12 @@ el2_probe1(struct device *dev, int ioaddr) dev->mem_start, dev->mem_end-1); else + { + ei_status.tx_start_page = EL2_MB1_START_PG; + ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES; printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n", dev->name, ei_status.name, (wordlength+1)<<3); - + } return 0; } @@ -335,13 +338,13 @@ el2_open(struct device *dev) outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */ do { - if (request_irq (*irqp, NULL, 0, "bogus") != -EBUSY) { + if (request_irq (*irqp, NULL, 0, "bogus", NULL) != -EBUSY) { /* Twinkle the interrupt, and check if it's seen. */ autoirq_setup(0); outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR); outb_p(0x00, E33G_IDCFR); if (*irqp == autoirq_report(0) /* It's a good IRQ line! */ - && request_irq (dev->irq = *irqp, &ei_interrupt, 0, ei_status.name) == 0) + && request_irq (dev->irq = *irqp, &ei_interrupt, 0, ei_status.name, NULL) == 0) break; } } while (*++irqp); @@ -350,7 +353,7 @@ el2_open(struct device *dev) return -EAGAIN; } } else { - if (request_irq(dev->irq, &ei_interrupt, 0, ei_status.name)) { + if (request_irq(dev->irq, &ei_interrupt, 0, ei_status.name, NULL)) { return -EAGAIN; } } @@ -364,7 +367,7 @@ el2_open(struct device *dev) static int el2_close(struct device *dev) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); dev->irq = ei_status.saved_irq; irq2dev_map[dev->irq] = NULL; outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */ @@ -416,20 +419,23 @@ el2_init_card(struct device *dev) /* Set the interrupt line. */ outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR); - outb_p(8, E33G_DRQCNT); /* Set burst size to 8 */ + outb_p((WRD_COUNT << 1), E33G_DRQCNT); /* Set burst size to 8 */ outb_p(0x20, E33G_DMAAH); /* Put a valid addr in the GA DMA */ outb_p(0x00, E33G_DMAAL); return; /* We always succeed */ } -/* Either use the shared memory (if enabled on the board) or put the packet - out through the ASIC FIFO. The latter is probably much slower. */ +/* + * Either use the shared memory (if enabled on the board) or put the packet + * out through the ASIC FIFO. + */ static void el2_block_output(struct device *dev, int count, const unsigned char *buf, const start_page) { - int i; /* Buffer index */ - int boguscount = 0; /* timeout counter */ + unsigned short int *wrd; + int boguscount; /* timeout counter */ + unsigned shor tmp_rev; /* temporary for reversed values */ if (ei_status.word16) /* Tx packets go into bank 0 on EL2/16 card */ outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR); @@ -443,29 +449,55 @@ el2_block_output(struct device *dev, int count, outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */ return; } - /* No shared memory, put the packet out the slow way. */ - /* Set up then start the internal memory transfer to Tx Start Page */ - outb(0x00, E33G_DMAAL); - outb_p(start_page, E33G_DMAAH); + +/* + * No shared memory, put the packet out the other way. + * Set up then start the internal memory transfer to Tx Start Page + */ + + tmp_rev = htons((unsigned short)start_page); + outb(tmp_rev&0xFF, E33G_DMAAH); + outb(tmp_rev>>8, E33G_DMAAL); + outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT | ECNTRL_START, E33G_CNTRL); - /* This is the byte copy loop: it should probably be tuned for - speed once everything is working. I think it is possible - to output 8 bytes between each check of the status bit. */ - for(i = 0; i < count; i++) { - if (i % 8 == 0) - while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) - if (++boguscount > (i<<3) + 32) { - printk("%s: FIFO blocked in el2_block_output (at %d of %d, bc=%d).\n", - dev->name, i, count, boguscount); - outb(EGACFR_NORM, E33G_GACFR); /* To MB1 for EL2/16 */ - return; - } - outb(buf[i], E33G_FIFOH); +/* + * Here I am going to write data to the FIFO as quickly as possible. + * Note that E33G_FIFOH is defined incorrectly. It is really + * E33G_FIFOL, the lowest port address for both the byte and + * word write. Variable 'count' is NOT checked. Caller must supply a + * valid count. Note that I may write a harmless extra byte to the + * 8390 if the byte-count was not even. + */ + wrd = (unsigned short int *) buf; + count = (count + 1) >> 1; + for(;;) + { + boguscount = 0x1000; + while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) + { + if(!boguscount--) + { + printk("%s: FIFO blocked in el2_block_output.\n", dev->name); + el2_reset_8390(dev); + goto blocked; + } + } + if(count > WRD_COUNT) + { + outsw(E33G_FIFOH, wrd, WRD_COUNT); + wrd += WRD_COUNT; + count -= WRD_COUNT; + } + else + { + outsw(E33G_FIFOH, wrd, count); + break; + } } + blocked:; outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); - outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */ return; } @@ -473,48 +505,50 @@ el2_block_output(struct device *dev, int count, static void el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page) { - unsigned int i; + int boguscount; unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8); - unsigned long fifo_watchdog; + unsigned short tmp_rev; if (dev->mem_start) { /* Use the shared memory. */ -#ifdef notdef - /* Officially this is what we are doing, but the readl() is faster */ memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); -#else - ((unsigned int*)hdr)[0] = readl(hdr_start); -#endif return; } - /* No shared memory, use programmed I/O. Ugh. */ - outb(0, E33G_DMAAL); - outb_p(ring_page & 0xff, E33G_DMAAH); +/* + * No shared memory, use programmed I/O. + */ + + tmp_rev = htons((unsigned short)ring_page); + outb(tmp_rev&0xFF, E33G_DMAAH); + outb(tmp_rev>>8, E33G_DMAAL); + outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT | ECNTRL_START, E33G_CNTRL); - - /* Header is < 8 bytes, so only check the FIFO at the beginning. */ - fifo_watchdog = jiffies; - while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) { - if (jiffies - fifo_watchdog > 2*HZ/100) { - printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name); - break; - } + boguscount = 0x1000; + while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) + { + if(!boguscount--) + { + printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name); + memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr)); + el2_reset_8390(dev); + goto blocked; + } } - - for(i = 0; i < sizeof(struct e8390_pkt_hdr); i++) - ((char *)(hdr))[i] = inb_p(E33G_FIFOH); - + insw(E33G_FIFOH, hdr, (sizeof(struct e8390_pkt_hdr))>> 1); + blocked:; outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); } -/* Returns the new ring pointer. */ + static void el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset) { int boguscount = 0; + unsigned short int *buf; + unsigned short tmp_rev; + int end_of_ring = dev->rmem_end; - unsigned int i; /* Maybe enable shared memory just be to be safe... nahh.*/ if (dev->mem_start) { /* Use the shared memory. */ @@ -531,32 +565,61 @@ el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_off } return; } - /* No shared memory, use programmed I/O. */ - outb(ring_offset & 0xff, E33G_DMAAL); - outb_p((ring_offset >> 8) & 0xff, E33G_DMAAH); + +/* + * No shared memory, use programmed I/O. + */ + tmp_rev = htons((unsigned short) ring_offset); + outb(tmp_rev&0xFF, E33G_DMAAL); + outb(tmp_rev>>8, E33G_DMAAH); + outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT | ECNTRL_START, E33G_CNTRL); - /* This is the byte copy loop: it should probably be tuned for - speed once everything is working. */ - for(i = 0; i < count; i++) { - if (i % 8 == 0) - while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) - if (++boguscount > (i<<3) + 32) { - printk("%s: FIFO blocked in el2_block_input() (at %d of %d, bc=%d).\n", - dev->name, i, count, boguscount); - boguscount = 0; - break; - } - (skb->data)[i] = inb_p(E33G_FIFOH); +/* + * Here I also try to get data as fast as possible. I am betting that I + * can read one extra byte without clobering anything in the kernel because + * this would only occur on an odd byte-count and allocation of skb->data + * is word-aligned. Variable 'count' is NOT checked. Caller must check + * for a valid count. + * [This is currently quite safe.... but if one day the 3c503 explodes + * you know where to come looking ;)] + */ + + buf = (unsigned short int *) skb->data; + count = (count + 1) >> 1; + for(;;) + { + boguscount = 0x1000; + while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) + { + if(!boguscount--) + { + printk("%s: FIFO blocked in el2_block_input.\n", dev->name); + el2_reset_8390(dev); + goto blocked; + } + } + if(count > WRD_COUNT) + { + insw(E33G_FIFOH, buf, WRD_COUNT); + buf += WRD_COUNT; + count -= WRD_COUNT; + } + else + { + insw(E33G_FIFOH, buf, count); + break; + } } + blocked:; outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); + return; } - - #ifdef MODULE #define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */ -#define NAMELEN 8 /* # of chars for storing dev->name */ +#define NAMELEN 8 /* #of chars for storing dev->name */ + static char namelist[NAMELEN * MAX_EL2_CARDS] = { 0, }; static struct device dev_el2[MAX_EL2_CARDS] = { { @@ -596,7 +659,6 @@ init_module(void) } found++; } - return 0; } diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index c09c4a55ff01..23f7ffff7866 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -635,7 +635,7 @@ receive_packet (struct device * dev, int len) ******************************************************/ static void -elp_interrupt (int irq, struct pt_regs *reg_ptr) +elp_interrupt (int irq, void *dev_id, struct pt_regs *reg_ptr) { int len; int dlen; @@ -859,7 +859,7 @@ elp_open (struct device *dev) /* * install our interrupt service routine */ - if (request_irq(dev->irq, &elp_interrupt, 0, "3c505")) { + if (request_irq(dev->irq, &elp_interrupt, 0, "3c505", NULL)) { irq2dev_map[dev->irq] = NULL; return -EAGAIN; } @@ -1150,7 +1150,7 @@ elp_close (struct device *dev) /* * release the IRQ */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); /* * and we no longer have to map irq to dev either diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index f18bc0a320ec..60054875bfcb 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -280,7 +280,7 @@ extern int el16_probe(struct device *dev); /* Called from Space.c */ static int el16_probe1(struct device *dev, int ioaddr); static int el16_open(struct device *dev); static int el16_send_packet(struct sk_buff *skb, struct device *dev); -static void el16_interrupt(int irq, struct pt_regs *regs); +static void el16_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void el16_rx(struct device *dev); static int el16_close(struct device *dev); static struct enet_statistics *el16_get_stats(struct device *dev); @@ -361,7 +361,7 @@ int el16_probe1(struct device *dev, int ioaddr) irq = inb(ioaddr + IRQ_CONFIG) & 0x0f; - irqval = request_irq(irq, &el16_interrupt, 0, "3c507"); + irqval = request_irq(irq, &el16_interrupt, 0, "3c507", NULL); if (irqval) { printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval); return EAGAIN; @@ -513,7 +513,7 @@ el16_send_packet(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ static void -el16_interrupt(int irq, struct pt_regs *regs) +el16_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -907,7 +907,7 @@ cleanup_module(void) dev_3c507.priv = NULL; /* If we don't do this, we can't re-insmod it later. */ - free_irq(dev_3c507.irq); + free_irq(dev_3c507.irq, NULL); release_region(dev_3c507.base_addr, EL16_IO_EXTENT); } #endif /* MODULE */ diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 59dcbed055dc..a33bad55b394 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -102,7 +102,7 @@ static ushort id_read_eeprom(int index); static ushort read_eeprom(short ioaddr, int index); static int el3_open(struct device *dev); static int el3_start_xmit(struct sk_buff *skb, struct device *dev); -static void el3_interrupt(int irq, struct pt_regs *regs); +static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void update_stats(int addr, struct device *dev); static struct enet_statistics *el3_get_stats(struct device *dev); static int el3_rx(struct device *dev); @@ -312,7 +312,7 @@ el3_open(struct device *dev) outw(RxReset, ioaddr + EL3_CMD); outw(SetReadZero | 0x00, ioaddr + EL3_CMD); - if (request_irq(dev->irq, &el3_interrupt, 0, "3c509")) { + if (request_irq(dev->irq, &el3_interrupt, 0, "3c509", NULL)) { return -EAGAIN; } @@ -464,7 +464,7 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev) /* The EL3 interrupt handler. */ static void -el3_interrupt(int irq, struct pt_regs *regs) +el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); int ioaddr, status; @@ -680,7 +680,7 @@ el3_close(struct device *dev) outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA); } - free_irq(dev->irq); + free_irq(dev->irq, NULL); /* Switching back to window 0 disables the IRQ. */ EL3WINDOW(0); /* But we explicitly zero the IRQ line select anyway. */ diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index b5c4d5b721fa..486cf2272fbe 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -237,7 +237,7 @@ static int vortex_open(struct device *dev); static void vortex_timer(unsigned long arg); static int vortex_start_xmit(struct sk_buff *skb, struct device *dev); static int vortex_rx(struct device *dev); -static void vortex_interrupt(int irq, struct pt_regs *regs); +static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int vortex_close(struct device *dev); static void update_stats(int addr, struct device *dev); static struct enet_statistics *vortex_get_stats(struct device *dev); @@ -550,7 +550,7 @@ vortex_open(struct device *dev) if (dev->irq == 0 || irq2dev_map[dev->irq] != NULL) return -EAGAIN; irq2dev_map[dev->irq] = dev; - if (request_irq(dev->irq, &vortex_interrupt, 0, vp->product_name)) { + if (request_irq(dev->irq, &vortex_interrupt, 0, vp->product_name, NULL)) { irq2dev_map[dev->irq] = NULL; return -EAGAIN; } @@ -736,7 +736,7 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void vortex_interrupt(int irq, struct pt_regs *regs) +static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) { #ifdef USE_SHARED_IRQ struct device *dev = (struct device *)(irq == 0 ? regs : irq2dev_map[irq]); @@ -774,7 +774,7 @@ static void vortex_interrupt(int irq, struct pt_regs *regs) if (donedidthis++ > 1) { printk("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n", dev->name, status, dev->start); - free_irq(dev->irq); + free_irq(dev->irq, NULL); } } @@ -955,7 +955,7 @@ vortex_close(struct device *dev) #ifdef USE_SHARED_IRQ free_shared_irq(dev->irq, dev); #else - free_irq(dev->irq); + free_irq(dev->irq, NULL); /* Mmmm, we should diable all interrupt sources here. */ irq2dev_map[dev->irq] = 0; #endif diff --git a/drivers/net/8390.c b/drivers/net/8390.c index 05ea32f6c7f1..05c896301be1 100644 --- a/drivers/net/8390.c +++ b/drivers/net/8390.c @@ -257,7 +257,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the ether interface interrupts. */ -void ei_interrupt(int irq, struct pt_regs * regs) +void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); int e8390_base; diff --git a/drivers/net/8390.h b/drivers/net/8390.h index 17b8cdb588a6..56716e783068 100644 --- a/drivers/net/8390.h +++ b/drivers/net/8390.h @@ -33,7 +33,7 @@ extern int ethdev_init(struct device *dev); extern void NS8390_init(struct device *dev, int startp); extern int ei_open(struct device *dev); extern int ei_close(struct device *dev); -extern void ei_interrupt(int irq, struct pt_regs *regs); +extern void ei_interrupt(int irq, void *dev_id, struct pt_regs *regs); #ifndef HAVE_AUTOIRQ /* From auto_irq.c */ diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 054af13a47ef..21147cc2ccc8 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -164,7 +164,7 @@ static int ac_probe1(int ioaddr, struct device *dev) else if (dev->irq == 2) dev->irq = 9; - if (request_irq(dev->irq, ei_interrupt, 0, "ac3200")) { + if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL)) { printk (" unable to get IRQ %d.\n", dev->irq); return EAGAIN; } @@ -172,7 +172,7 @@ static int ac_probe1(int ioaddr, struct device *dev) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (" unable to allocate memory for dev->priv.\n"); - free_irq(dev->irq); + free_irq(dev->irq, NULL); return -ENOMEM; } @@ -227,7 +227,7 @@ static int ac_open(struct device *dev) /* Someday we may enable the IRQ and shared memory here. */ int ioaddr = dev->base_addr; - if (request_irq(dev->irq, ei_interrupt, 0, "ac3200")) + if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL)) return -EAGAIN; #endif @@ -302,7 +302,7 @@ static int ac_close_card(struct device *dev) #ifdef notyet /* We should someday disable shared memory and interrupts. */ outb(0x00, ioaddr + 6); /* Disable interrupts. */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; #endif @@ -366,7 +366,7 @@ cleanup_module(void) kfree(dev->priv); dev->priv = NULL; /* Someday free_irq + irq2dev may be in ac_close_card() */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; release_region(dev->base_addr, AC_IO_EXTENT); unregister_netdev(dev); diff --git a/drivers/net/apricot.c b/drivers/net/apricot.c index 130d77597a73..023c310e7bf4 100644 --- a/drivers/net/apricot.c +++ b/drivers/net/apricot.c @@ -183,7 +183,7 @@ char init_setup[] = { static int i596_open(struct device *dev); static int i596_start_xmit(struct sk_buff *skb, struct device *dev); -static void i596_interrupt(int irq, struct pt_regs *regs); +static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int i596_close(struct device *dev); static struct enet_statistics *i596_get_stats(struct device *dev); static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd); @@ -537,7 +537,7 @@ i596_open(struct device *dev) if (i596_debug > 1) printk("%s: i596_open() irq %d.\n", dev->name, dev->irq); - if (request_irq(dev->irq, &i596_interrupt, 0, "apricot")) + if (request_irq(dev->irq, &i596_interrupt, 0, "apricot", NULL)) return -EAGAIN; irq2dev_map[dev->irq] = dev; @@ -549,7 +549,7 @@ i596_open(struct device *dev) if (i < 4) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; return -EAGAIN; } @@ -743,7 +743,7 @@ int apricot_probe(struct device *dev) } static void -i596_interrupt(int irq, struct pt_regs *regs) +i596_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct i596_private *lp; @@ -934,7 +934,7 @@ i596_close(struct device *dev) dev->name, lp->scb.status, lp->scb.command); break; } - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; remove_rx_bufs(dev); MOD_DEC_USE_COUNT; diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index 2733d4804431..45ddc0c47603 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -590,7 +590,7 @@ static void arcnetAS_prepare_tx(struct device *dev,u_char *hdr,int hdrlen, char *data,int length,int daddr,int exceptA); static int arcnet_go_tx(struct device *dev,int enable_irq); -static void arcnet_interrupt(int irq,struct pt_regs *regs); +static void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs); static void arcnet_inthandler(struct device *dev); static void arcnet_rx(struct device *dev,int recbuf); @@ -1023,7 +1023,7 @@ int arcnet_found(struct device *dev,int port,int airq, u_long shmem) dev->base_addr=port; /* reserve the irq */ - irqval = request_irq(airq,&arcnet_interrupt,0,"arcnet"); + irqval = request_irq(airq,&arcnet_interrupt,0,"arcnet",NULL); if (irqval) { BUGMSG(D_NORMAL,"unable to get IRQ %d (irqval=%d).\n", @@ -1820,7 +1820,7 @@ arcnet_go_tx(struct device *dev,int enable_irq) * as well. */ static void -arcnet_interrupt(int irq,struct pt_regs *regs) +arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); int ioaddr; @@ -3252,7 +3252,7 @@ cleanup_module(void) if (thiscard.irq) { - free_irq(thiscard.irq); + free_irq(thiscard.irq,NULL); /* very important! */ irq2dev_map[thiscard.irq] = NULL; } diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index 3d684c0a3046..78a1068f4f9a 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -117,7 +117,7 @@ static int at1700_probe1(struct device *dev, short ioaddr); static int read_eeprom(int ioaddr, int location); static int net_open(struct device *dev); static int net_send_packet(struct sk_buff *skb, struct device *dev); -static void net_interrupt(int irq, struct pt_regs *regs); +static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void net_rx(struct device *dev); static int net_close(struct device *dev); static struct enet_statistics *net_get_stats(struct device *dev); @@ -192,7 +192,7 @@ int at1700_probe1(struct device *dev, short ioaddr) | (read_eeprom(ioaddr, 0)>>14)]; /* Snarf the interrupt vector now. */ - if (request_irq(irq, &net_interrupt, 0, "at1700")) { + if (request_irq(irq, &net_interrupt, 0, "at1700", NULL)) { printk ("AT1700 found at %#3x, but it's unusable due to a conflict on" "IRQ %d.\n", ioaddr, irq); return EAGAIN; @@ -440,7 +440,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ static void -net_interrupt(int irq, struct pt_regs *regs) +net_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -660,7 +660,7 @@ cleanup_module(void) dev_at1700.priv = NULL; /* If we don't do this, we can't re-insmod it later. */ - free_irq(dev_at1700.irq); + free_irq(dev_at1700.irq, NULL); irq2dev_map[dev_at1700.irq] = NULL; release_region(dev_at1700.base_addr, AT1700_IO_EXTENT); } diff --git a/drivers/net/atp.c b/drivers/net/atp.c index 62aa04efc48c..6017a6743c03 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -135,7 +135,7 @@ static void hardware_init(struct device *dev); static void write_packet(short ioaddr, int length, unsigned char *packet, int mode); static void trigger_send(short ioaddr, int length); static int net_send_packet(struct sk_buff *skb, struct device *dev); -static void net_interrupt(int irq, struct pt_regs *regs); +static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void net_rx(struct device *dev); static void read_block(short ioaddr, int length, unsigned char *buffer, int data_mode); static int net_close(struct device *dev); @@ -328,7 +328,7 @@ static int net_open(struct device *dev) port or interrupt may be shared. */ if (irq2dev_map[dev->irq] != 0 || (irq2dev_map[dev->irq] = dev) == 0 - || request_irq(dev->irq, &net_interrupt, 0, "ATP")) { + || request_irq(dev->irq, &net_interrupt, 0, "ATP", NULL)) { return -EAGAIN; } @@ -484,7 +484,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ static void -net_interrupt(int irq, struct pt_regs * regs) +net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -736,7 +736,7 @@ net_close(struct device *dev) /* Free the IRQ line. */ outb(0x00, ioaddr + PAR_CONTROL); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; /* Leave the hardware in a reset state. */ diff --git a/drivers/net/auto_irq.c b/drivers/net/auto_irq.c index c6f404ca0f4a..c91da9c5227c 100644 --- a/drivers/net/auto_irq.c +++ b/drivers/net/auto_irq.c @@ -50,7 +50,7 @@ static volatile unsigned long irq_bitmap; /* The irqs we actually found. */ static unsigned long irq_handled; /* The irq lines we have a handler on. */ static volatile int irq_number; /* The latest irq number we actually found. */ -static void autoirq_probe(int irq, struct pt_regs * regs) +static void autoirq_probe(int irq, void *dev_id, struct pt_regs * regs) { irq_number = irq; set_bit(irq, (void *)&irq_bitmap); /* irq_bitmap |= 1 << irq; */ @@ -67,7 +67,7 @@ int autoirq_setup(int waittime) irq_handled = 0; for (i = 0; i < 16; i++) { if (test_bit(i, &irqs_busy) == 0 - && request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe") == 0) + && request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe", NULL) == 0) set_bit(i, (void *)&irq_handled); /* irq_handled |= 1 << i;*/ } /* Update our USED lists. */ @@ -85,7 +85,7 @@ int autoirq_setup(int waittime) #ifdef notdef printk(" Spurious interrupt on IRQ %d\n", i); #endif - free_irq(i); + free_irq(i, NULL); } } return irq_handled; @@ -106,7 +106,7 @@ int autoirq_report(int waittime) /* Retract the irq handlers that we installed. */ for (i = 0; i < 16; i++) { if (test_bit(i, (void *)&irq_handled)) - free_irq(i); + free_irq(i, NULL); } return irq_number; } diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index 0d2b5109f2e0..03c5bd6f479e 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -396,7 +396,7 @@ struct de4x5_private { */ static int de4x5_open(struct device *dev); static int de4x5_queue_pkt(struct sk_buff *skb, struct device *dev); -static void de4x5_interrupt(int irq, struct pt_regs *regs); +static void de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int de4x5_close(struct device *dev); static struct enet_statistics *de4x5_get_stats(struct device *dev); static void set_multicast_list(struct device *dev); @@ -761,7 +761,7 @@ de4x5_open(struct device *dev) dce_ms_delay(10); } - if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name)) { + if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, lp->adapter_name, dev)) { printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq); status = -EAGAIN; } else { @@ -1065,9 +1065,9 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev) ** interrupt is asserted and this routine entered. */ static void -de4x5_interrupt(int irq, struct pt_regs *regs) +de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct device *dev = (struct device *)(irq2dev_map[irq]); + struct device *dev = (struct device *)dev_id; struct de4x5_private *lp; s32 imr, omr, sts; u_long iobase; @@ -1332,7 +1332,7 @@ de4x5_close(struct device *dev) /* ** Free the associated irq */ - free_irq(dev->irq); + free_irq(dev->irq, dev); irq2dev_map[dev->irq] = 0; MOD_DEC_USE_COUNT; diff --git a/drivers/net/de600.c b/drivers/net/de600.c index d80e5ca52360..293b37790d9c 100644 --- a/drivers/net/de600.c +++ b/drivers/net/de600.c @@ -247,7 +247,7 @@ static struct netstats *get_stats(struct device *dev); static int de600_start_xmit(struct sk_buff *skb, struct device *dev); /* Dispatch from interrupts. */ -static void de600_interrupt(int irq, struct pt_regs *regs); +static void de600_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int de600_tx_intr(struct device *dev, int irq_status); static void de600_rx_intr(struct device *dev); @@ -336,7 +336,7 @@ de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros static int de600_open(struct device *dev) { - if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600")) { + if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600", NULL)) { printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ); return 1; } @@ -365,7 +365,7 @@ de600_close(struct device *dev) select_prn(); if (dev->start) { - free_irq(DE600_IRQ); + free_irq(DE600_IRQ, NULL); irq2dev_map[DE600_IRQ] = NULL; dev->start = 0; MOD_DEC_USE_COUNT; @@ -488,7 +488,7 @@ de600_start_xmit(struct sk_buff *skb, struct device *dev) * Handle the network interface interrupts. */ static void -de600_interrupt(int irq, struct pt_regs * regs) +de600_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = irq2dev_map[irq]; byte irq_status; diff --git a/drivers/net/de620.c b/drivers/net/de620.c index 487d1200d037..ecc64619b5b7 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -210,7 +210,7 @@ static void de620_set_multicast_list(struct device *); static int de620_start_xmit(struct sk_buff *, struct device *); /* Dispatch from interrupts. */ -static void de620_interrupt(int, struct pt_regs *); +static void de620_interrupt(int, void *, struct pt_regs *); static int de620_rx_intr(struct device *); /* Initialization */ @@ -432,7 +432,7 @@ de620_get_register(struct device *dev, byte reg) static int de620_open(struct device *dev) { - if (request_irq(dev->irq, de620_interrupt, 0, "de620")) { + if (request_irq(dev->irq, de620_interrupt, 0, "de620", NULL)) { printk ("%s: unable to get IRQ %d\n", dev->name, dev->irq); return 1; } @@ -457,7 +457,7 @@ de620_close(struct device *dev) /* disable recv */ de620_set_register(dev, W_TCR, RXOFF); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; dev->start = 0; @@ -598,7 +598,7 @@ de620_start_xmit(struct sk_buff *skb, struct device *dev) * */ static void -de620_interrupt(int irq_in, struct pt_regs *regs) +de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs) { struct device *dev = irq2dev_map[irq_in]; byte irq_status; diff --git a/drivers/net/depca.c b/drivers/net/depca.c index ae9a8ca3b5d0..292fcd97f53b 100644 --- a/drivers/net/depca.c +++ b/drivers/net/depca.c @@ -381,7 +381,7 @@ struct depca_private { */ static int depca_open(struct device *dev); static int depca_start_xmit(struct sk_buff *skb, struct device *dev); -static void depca_interrupt(int irq, struct pt_regs * regs); +static void depca_interrupt(int irq, void *dev_id, struct pt_regs * regs); static int depca_close(struct device *dev); static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd); static struct enet_statistics *depca_get_stats(struct device *dev); @@ -704,7 +704,7 @@ depca_open(struct device *dev) depca_dbg_open(dev); - if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name)) { + if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name, NULL)) { printk("depca_open(): Requested IRQ%d is busy\n",dev->irq); status = -EAGAIN; } else { @@ -836,7 +836,7 @@ depca_start_xmit(struct sk_buff *skb, struct device *dev) ** The DEPCA interrupt handler. */ static void -depca_interrupt(int irq, struct pt_regs * regs) +depca_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct depca_private *lp; @@ -1059,7 +1059,7 @@ depca_close(struct device *dev) /* ** Free the associated irq */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; MOD_DEC_USE_COUNT; diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c index fb0f1de6f2ad..141c444846d4 100644 --- a/drivers/net/e2100.c +++ b/drivers/net/e2100.c @@ -177,7 +177,7 @@ int e21_probe1(struct device *dev, int ioaddr) if (dev->irq < 2) { int irqlist[] = {15,11,10,12,5,9,3,4}, i; for (i = 0; i < 8; i++) - if (request_irq (irqlist[i], NULL, 0, "bogus") != -EBUSY) { + if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) { dev->irq = irqlist[i]; break; } @@ -253,7 +253,7 @@ e21_open(struct device *dev) { short ioaddr = dev->base_addr; - if (request_irq(dev->irq, ei_interrupt, 0, "e2100")) { + if (request_irq(dev->irq, ei_interrupt, 0, "e2100", NULL)) { return EBUSY; } irq2dev_map[dev->irq] = dev; @@ -352,7 +352,7 @@ e21_close(struct device *dev) if (ei_debug > 1) printk("%s: Shutting down ethercard.\n", dev->name); - free_irq(dev->irq); + free_irq(dev->irq, NULL); dev->irq = ei_status.saved_irq; /* Shut off the interrupt line and secondary interface. */ diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 2aa2bd1444eb..4e9b7173a39c 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -135,7 +135,7 @@ extern int eepro_probe(struct device *dev); static int eepro_probe1(struct device *dev, short ioaddr); static int eepro_open(struct device *dev); static int eepro_send_packet(struct sk_buff *skb, struct device *dev); -static void eepro_interrupt(int irq, struct pt_regs *regs); +static void eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void eepro_rx(struct device *dev); static void eepro_transmit_interrupt(struct device *dev); static int eepro_close(struct device *dev); @@ -376,7 +376,7 @@ int eepro_probe1(struct device *dev, short ioaddr) if (dev->irq > 2) { printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]); - if (request_irq(dev->irq, &eepro_interrupt, 0, "eepro")) { + if (request_irq(dev->irq, &eepro_interrupt, 0, "eepro", NULL)) { printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq); return -EAGAIN; } @@ -462,14 +462,14 @@ static int eepro_grab_irq(struct device *dev) outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */ - if (request_irq (*irqp, NULL, 0, "bogus") != EBUSY) { + if (request_irq (*irqp, NULL, 0, "bogus", NULL) != EBUSY) { /* Twinkle the interrupt, and check if it's seen */ autoirq_setup(0); outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */ if (*irqp == autoirq_report(2) && /* It's a good IRQ line */ - (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro") == 0)) + (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0)) break; /* clear all interrupts */ @@ -661,7 +661,7 @@ eepro_send_packet(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ static void -eepro_interrupt(int irq, struct pt_regs * regs) +eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); int ioaddr, status, boguscount = 0; @@ -744,7 +744,7 @@ eepro_close(struct device *dev) outb(RESET_CMD, ioaddr); /* release the interrupt */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 2f641d686739..ca7f77039cb2 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -286,7 +286,7 @@ extern int express_probe(struct device *dev); /* Called from Space.c */ static int eexp_probe1(struct device *dev, short ioaddr); static int eexp_open(struct device *dev); static int eexp_send_packet(struct sk_buff *skb, struct device *dev); -static void eexp_interrupt(int irq, struct pt_regs *regs); +static void eexp_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void eexp_rx(struct device *dev); static int eexp_close(struct device *dev); static struct enet_statistics *eexp_get_stats(struct device *dev); @@ -429,7 +429,7 @@ eexp_open(struct device *dev) if (irq2dev_map[dev->irq] != 0 /* This is always true, but avoid the false IRQ. */ || (irq2dev_map[dev->irq] = dev) == 0 - || request_irq(dev->irq, &eexp_interrupt, 0, "EExpress")) { + || request_irq(dev->irq, &eexp_interrupt, 0, "EExpress", NULL)) { return -EAGAIN; } @@ -513,7 +513,7 @@ eexp_send_packet(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ static void -eexp_interrupt(int irq, struct pt_regs *regs) +eexp_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -648,7 +648,7 @@ eexp_close(struct device *dev) /* Disable the physical interrupt line. */ outb(0, ioaddr + SET_IRQ); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index b21e4f336c4e..ef054b2a9c76 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -326,7 +326,7 @@ static int eth16i_open(struct device *dev); static int eth16i_close(struct device *dev); static int eth16i_tx(struct sk_buff *skb, struct device *dev); static void eth16i_rx(struct device *dev); -static void eth16i_interrupt(int irq, struct pt_regs *regs); +static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs); static void eth16i_select_regbank(unsigned char regbank, short ioaddr); static void eth16i_initialize(struct device *dev); @@ -423,7 +423,7 @@ static int eth16i_probe1(struct device *dev, short ioaddr) dev->irq = irq; /* Try to obtain interrupt vector */ - if(request_irq(dev->irq, ð16i_interrupt, 0, "eth16i")) { + if(request_irq(dev->irq, ð16i_interrupt, 0, "eth16i", NULL)) { printk("%s: %s at %#3x, but is unusable due conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq); return EAGAIN; @@ -1086,7 +1086,7 @@ static void eth16i_rx(struct device *dev) return; } -static void eth16i_interrupt(int irq, struct pt_regs *regs) +static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct eth16i_local *lp; @@ -1204,7 +1204,7 @@ int init_module(void) void cleanup_module(void) { unregister_netdev( &dev_eth16i ); - free_irq( dev_eth16i.irq ); + free_irq( dev_eth16i.irq, NULL ); irq2dev_map[ dev_eth16i.irq ] = NULL; release_region( dev_eth16i.base_addr, ETH16I_IO_EXTENT ); } diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c index 90e3b932f267..bf81142e395d 100644 --- a/drivers/net/ewrk3.c +++ b/drivers/net/ewrk3.c @@ -130,11 +130,12 @@ Added verify_area() calls in depca_ioctl() from suggestion by . Add new multicasting code. + 0.41 20-Jan-96 Fix IRQ set up problem reported by . ========================================================================= */ -static const char *version = "ewrk3.c:v0.40 95/12/27 davies@wanton.lkg.dec.com\n"; +static const char *version = "ewrk3.c:v0.41 96/1/20 davies@wanton.lkg.dec.com\n"; #include @@ -205,7 +206,7 @@ static int ewrk3_debug = 1; #define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */ #define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */ -#define QUEUE_PKT_TIMEOUT (100) /* Jiffies */ +#define QUEUE_PKT_TIMEOUT (1*HZ) /* Jiffies */ /* ** EtherWORKS 3 shared memory window sizes @@ -286,7 +287,7 @@ struct ewrk3_private { */ static int ewrk3_open(struct device *dev); static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev); -static void ewrk3_interrupt(int irq, struct pt_regs *regs); +static void ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int ewrk3_close(struct device *dev); static struct enet_statistics *ewrk3_get_stats(struct device *dev); static void set_multicast_list(struct device *dev); @@ -389,7 +390,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase) nicsr = inb(EWRK3_CSR); icr = inb(EWRK3_ICR); - icr |= 0xf0; + icr &= 0x70; outb(icr, EWRK3_ICR); /* Disable all the IRQs */ if (nicsr == CSR_TXD|CSR_RXD) { @@ -624,7 +625,7 @@ ewrk3_open(struct device *dev) if (!lp->hard_strapped) { irq2dev_map[dev->irq] = dev; /* For latched interrupts */ - if (request_irq(dev->irq, (void *)ewrk3_interrupt, 0, "ewrk3")) { + if (request_irq(dev->irq, (void *)ewrk3_interrupt, 0, "ewrk3", NULL)) { printk("ewrk3_open(): Requested IRQ%d is busy\n",dev->irq); status = -EAGAIN; } else { @@ -812,7 +813,7 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev) for (i=0; ilen; i++) { outb(*p++, EWRK3_DATA); } - outb(page, EWRK3_TQ); /* Start sending pkt */ + outb(page, EWRK3_TQ); /* Start sending pkt */ } else { writeb((char)(TCR_QMODE|TCR_PAD|TCR_IFC), (char *)buf);/* ctrl byte*/ buf+=1; @@ -821,20 +822,20 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev) if (lp->txc) { writeb((char)(((skb->len >> 8) & 0xff) | XCT), (char *)buf); buf+=1; - writeb(0x04, (char *)buf); /* index byte */ + writeb(0x04, (char *)buf); /* index byte */ buf+=1; - writeb(0x00, (char *)(buf + skb->len)); /* Write the XCT flag */ + writeb(0x00, (char *)(buf + skb->len)); /* Write the XCT flag */ memcpy_toio(buf, skb->data, PRELOAD);/* Write PRELOAD bytes*/ - outb(page, EWRK3_TQ); /* Start sending pkt */ + outb(page, EWRK3_TQ); /* Start sending pkt */ memcpy_toio(buf+PRELOAD, skb->data+PRELOAD, skb->len-PRELOAD); - writeb(0xff, (char *)(buf + skb->len)); /* Write the XCT flag */ + writeb(0xff, (char *)(buf + skb->len)); /* Write the XCT flag */ } else { writeb((char)((skb->len >> 8) & 0xff), (char *)buf); buf+=1; - writeb(0x04, (char *)buf); /* index byte */ + writeb(0x04, (char *)buf); /* index byte */ buf+=1; memcpy_toio((char *)buf, skb->data, skb->len);/* Write data bytes */ - outb(page, EWRK3_TQ); /* Start sending pkt */ + outb(page, EWRK3_TQ); /* Start sending pkt */ } } @@ -869,7 +870,7 @@ ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev) ** The EWRK3 interrupt handler. */ static void -ewrk3_interrupt(int irq, struct pt_regs * regs) +ewrk3_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct ewrk3_private *lp; @@ -1144,7 +1145,7 @@ ewrk3_close(struct device *dev) while (inb(EWRK3_RQ)); if (!lp->hard_strapped) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; } @@ -1910,8 +1911,6 @@ init_module(void) void cleanup_module(void) { - release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE); - if (thisEthwrk.priv) { kfree(thisEthwrk.priv); thisEthwrk.priv = NULL; @@ -1919,6 +1918,7 @@ cleanup_module(void) thisEthwrk.irq = 0; unregister_netdev(&thisEthwrk); + release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE); } #endif /* MODULE */ diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index aed7ee01e7db..b2074435822b 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -258,7 +258,7 @@ hpp_open(struct device *dev) int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg; - if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus")) { + if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus", NULL)) { return -EAGAIN; } @@ -287,7 +287,7 @@ hpp_close(struct device *dev) int ioaddr = dev->base_addr - NIC_OFFSET; int option_reg = inw(ioaddr + HPP_OPTION); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; ei_close(dev); outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset, diff --git a/drivers/net/hp.c b/drivers/net/hp.c index d0443a7dd374..fc965f77efe4 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -150,13 +150,13 @@ int hp_probe1(struct device *dev, int ioaddr) int *irqp = wordmode ? irq_16list : irq_8list; do { int irq = *irqp; - if (request_irq (irq, NULL, 0, "bogus") != -EBUSY) { + if (request_irq (irq, NULL, 0, "bogus", NULL) != -EBUSY) { autoirq_setup(0); /* Twinkle the interrupt, and check if it's seen. */ outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE); outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE); if (irq == autoirq_report(0) /* It's a good IRQ line! */ - && request_irq (irq, &ei_interrupt, 0, "hp") == 0) { + && request_irq (irq, &ei_interrupt, 0, "hp", NULL) == 0) { printk(" selecting IRQ %d.\n", irq); dev->irq = *irqp; break; @@ -170,7 +170,7 @@ int hp_probe1(struct device *dev, int ioaddr) } else { if (dev->irq == 2) dev->irq = 9; - if (request_irq(dev->irq, ei_interrupt, 0, "hp")) { + if (request_irq(dev->irq, ei_interrupt, 0, "hp", NULL)) { printk (" unable to get IRQ %d.\n", dev->irq); return EBUSY; } @@ -179,7 +179,7 @@ int hp_probe1(struct device *dev, int ioaddr) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (" unable to get memory for dev->priv.\n"); - free_irq(dev->irq); + free_irq(dev->irq, NULL); return -ENOMEM; } @@ -431,7 +431,7 @@ cleanup_module(void) int ioaddr = dev->base_addr - NIC_OFFSET; kfree(dev->priv); dev->priv = NULL; - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; release_region(ioaddr, HP_IO_EXTENT); unregister_netdev(dev); diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index df9f266b2b9f..732066599992 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -196,7 +196,7 @@ static struct enet_statistics *hp100_get_stats( struct device *dev ); static void hp100_update_stats( struct device *dev ); static void hp100_clear_stats( int ioaddr ); static void hp100_set_multicast_list( struct device *dev); -static void hp100_interrupt( int irq, struct pt_regs *regs ); +static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ); static void hp100_start_interface( struct device *dev ); static void hp100_stop_interface( struct device *dev ); @@ -488,7 +488,7 @@ static int hp100_open( struct device *dev ) int ioaddr = dev -> base_addr; struct hp100_private *lp = (struct hp100_private *)dev -> priv; - if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) ) + if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name, NULL ) ) { printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq ); return -EAGAIN; @@ -561,7 +561,7 @@ static int hp100_close( struct device *dev ) dev -> tbusy = 1; dev -> start = 0; - free_irq( dev -> irq ); + free_irq( dev -> irq, NULL ); irq2dev_map[ dev -> irq ] = NULL; MOD_DEC_USE_COUNT; return 0; @@ -890,7 +890,7 @@ static void hp100_set_multicast_list( struct device *dev) * hardware interrupt handling */ -static void hp100_interrupt( int irq, struct pt_regs *regs ) +static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs ) { struct device *dev = (struct device *)irq2dev_map[ irq ]; struct hp100_private *lp; diff --git a/drivers/net/ibmtr.c b/drivers/net/ibmtr.c index dd455127691a..8f7f814b4b7e 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/ibmtr.c @@ -134,7 +134,7 @@ int tok_probe(struct device *dev); unsigned char get_sram_size(struct tok_info *adapt_info); static void tok_init_card(unsigned long dev_addr); -static void tok_interrupt(int irq, struct pt_regs *regs); +static void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void initial_tok_int(struct device *dev); @@ -481,7 +481,7 @@ int tok_probe(struct device *dev) DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2); #endif - if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR") != 0) { + if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) { DPRINTK("Could not grab irq %d. Halting Token Ring driver.\n",irq); badti = ti; /* keep track of unused tok_info */ return ENODEV; @@ -590,7 +590,7 @@ static int tok_close(struct device *dev) { return 0; } -static void tok_interrupt (int irq, struct pt_regs *regs) +static void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs) { unsigned char status; @@ -1315,7 +1315,7 @@ cleanup_module(void) unregister_netdev(&dev_ibmtr); /* If we don't do this, we can't re-insmod it later. */ - free_irq(dev_ibmtr.irq); + free_irq(dev_ibmtr.irq, NULL); irq2dev_map[dev_ibmtr.irq] = NULL; release_region(dev_ibmtr.base_addr, TR_IO_EXTENT); } diff --git a/drivers/net/lance.c b/drivers/net/lance.c index 4a388f774f17..def0a471a60a 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -254,7 +254,7 @@ static int lance_open(struct device *dev); static void lance_init_ring(struct device *dev); static int lance_start_xmit(struct sk_buff *skb, struct device *dev); static int lance_rx(struct device *dev); -static void lance_interrupt(int irq, struct pt_regs *regs); +static void lance_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int lance_close(struct device *dev); static struct enet_statistics *lance_get_stats(struct device *dev); static void set_multicast_list(struct device *dev); @@ -564,7 +564,7 @@ lance_open(struct device *dev) int i; if (dev->irq == 0 || - request_irq(dev->irq, &lance_interrupt, 0, lp->name)) { + request_irq(dev->irq, &lance_interrupt, 0, lp->name, NULL)) { return -EAGAIN; } @@ -826,7 +826,7 @@ lance_start_xmit(struct sk_buff *skb, struct device *dev) /* The LANCE interrupt handler. */ static void -lance_interrupt(int irq, struct pt_regs * regs) +lance_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct lance_private *lp; @@ -1056,7 +1056,7 @@ lance_close(struct device *dev) if (dev->dma != 4) disable_dma(dev->dma); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 4da4efb7cee5..58fe093d4b2b 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -364,7 +364,7 @@ static int ne_probe1(struct device *dev, int ioaddr) /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ { - int irqval = request_irq(dev->irq, ei_interrupt, 0, name); + int irqval = request_irq(dev->irq, ei_interrupt, 0, name, NULL); if (irqval) { printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); return EAGAIN; @@ -376,7 +376,7 @@ static int ne_probe1(struct device *dev, int ioaddr) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (" unable to get memory for dev->priv.\n"); - free_irq(dev->irq); + free_irq(dev->irq, NULL); return -ENOMEM; } @@ -715,7 +715,7 @@ cleanup_module(void) if (dev->priv != NULL) { kfree(dev->priv); dev->priv = NULL; - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; release_region(dev->base_addr, NE_IO_EXTENT); unregister_netdev(dev); diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c index 2148693ff920..df4849ecd24c 100644 --- a/drivers/net/ni52.c +++ b/drivers/net/ni52.c @@ -188,7 +188,7 @@ sizeof(nop_cmd) = 8; #define NI52_ADDR2 0x01 static int ni52_probe1(struct device *dev,int ioaddr); -static void ni52_interrupt(int irq,struct pt_regs *reg_ptr); +static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr); static int ni52_open(struct device *dev); static int ni52_close(struct device *dev); static int ni52_send_packet(struct sk_buff *,struct device *); @@ -235,7 +235,7 @@ struct priv */ static int ni52_close(struct device *dev) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; ni_reset586(); /* the hard way to stop the receiver */ @@ -259,7 +259,7 @@ static int ni52_open(struct device *dev) startrecv586(dev); ni_enaint(); - if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210")) + if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210",NULL)) { ni_reset586(); return -EAGAIN; @@ -810,7 +810,7 @@ static void *alloc_rfa(struct device *dev,void *ptr) * Interrupt Handler ... */ -static void ni52_interrupt(int irq,struct pt_regs *reg_ptr) +static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr) { struct device *dev = (struct device *) irq2dev_map[irq]; unsigned short stat; diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c index ff41336aef79..41789b7686d2 100644 --- a/drivers/net/ni65.c +++ b/drivers/net/ni65.c @@ -116,7 +116,7 @@ #define writedatareg(val) {outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);} static int ni65_probe1(struct device **dev,int); -static void ni65_interrupt(int irq, struct pt_regs *regs); +static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs); static void ni65_recv_intr(struct device *dev,int); static void ni65_xmit_intr(struct device *dev,int); static int ni65_open(struct device *dev); @@ -249,7 +249,7 @@ static int ni65_probe1(struct device **dev1,int ioaddr) "ni6510", dev->base_addr, dev->irq,dev->dma); { - int irqval = request_irq(dev->irq, &ni65_interrupt,0,"ni6510"); + int irqval = request_irq(dev->irq, &ni65_interrupt,0,"ni6510",NULL); if (irqval) { printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,dev->irq, irqval); @@ -258,7 +258,7 @@ static int ni65_probe1(struct device **dev1,int ioaddr) if(request_dma(dev->dma, "ni6510") != 0) { printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma); - free_irq(dev->irq); + free_irq(dev->irq,NULL); return -EAGAIN; } } @@ -367,7 +367,7 @@ static int ni65_am7990_reinit(struct device *dev) printk(KERN_ERR "%s: can't RESET ni6510 card: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); disable_dma(dev->dma); free_dma(dev->dma); - free_irq(dev->irq); + free_irq(dev->irq, NULL); return 0; } @@ -439,7 +439,7 @@ static int ni65_am7990_reinit(struct device *dev) printk(KERN_ERR "%s: can't init am7990/lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG)); disable_dma(dev->dma); free_dma(dev->dma); - free_irq(dev->irq); + free_irq(dev->irq, NULL); return 0; /* false */ } @@ -451,7 +451,7 @@ static int ni65_am7990_reinit(struct device *dev) /* * interrupt handler */ -static void ni65_interrupt(int irq, struct pt_regs * regs) +static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs) { int csr0; struct device *dev = (struct device *) irq2dev_map[irq]; diff --git a/drivers/net/pi2.c b/drivers/net/pi2.c index d1cb0b649e21..c1248ec59afb 100644 --- a/drivers/net/pi2.c +++ b/drivers/net/pi2.c @@ -149,7 +149,7 @@ static struct device pi0b = { "pi0b", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, pi0_prepr static int pi_probe(struct device *dev, int card_type); static int pi_open(struct device *dev); static int pi_send_packet(struct sk_buff *skb, struct device *dev); -static void pi_interrupt(int reg_ptr, struct pt_regs *regs); +static void pi_interrupt(int reg_ptr, void *dev_id, struct pt_regs *regs); static int pi_close(struct device *dev); static int pi_ioctl(struct device *dev, struct ifreq *ifr, int cmd); static struct enet_statistics *pi_get_stats(struct device *dev); @@ -1398,7 +1398,7 @@ static int pi_probe(struct device *dev, int card_type) now. There is no point in waiting since no other device can use the interrupt, and this marks the 'irqaction' as busy. */ { - int irqval = request_irq(dev->irq, &pi_interrupt,0, "pi2"); + int irqval = request_irq(dev->irq, &pi_interrupt,0, "pi2", NULL); if (irqval) { printk("PI: unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); @@ -1461,7 +1461,7 @@ static int pi_open(struct device *dev) if (dev->base_addr & 2) { /* if A channel */ if (first_time) { if (request_dma(dev->dma,"pi2")) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); return -EAGAIN; } irq2dev_map[dev->irq] = dev; @@ -1509,7 +1509,7 @@ static int pi_send_packet(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ -static void pi_interrupt(int reg_ptr, struct pt_regs *regs) +static void pi_interrupt(int reg_ptr, void *dev_id, struct pt_regs *regs) { /* int irq = -(((struct pt_regs *) reg_ptr)->orig_eax + 2);*/ struct pi_local *lp; diff --git a/drivers/net/plip.c b/drivers/net/plip.c index d192de669416..d7a65bce9d70 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -139,7 +139,7 @@ static void plip_kick_bh(struct device *dev); static void plip_bh(struct device *dev); /* Interrupt handler */ -static void plip_interrupt(int irq, struct pt_regs *regs); +static void plip_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* Functions for DEV methods */ static int plip_rebuild_header(void *buff, struct device *dev, @@ -800,7 +800,7 @@ plip_error(struct device *dev, struct net_local *nl, /* Handle the parallel port interrupts. */ static void -plip_interrupt(int irq, struct pt_regs * regs) +plip_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *) irq2dev_map[irq]; struct net_local *nl = (struct net_local *)dev->priv; @@ -940,7 +940,7 @@ plip_open(struct device *dev) return -EAGAIN; } cli(); - if (request_irq(dev->irq , plip_interrupt, 0, dev->name) != 0) { + if (request_irq(dev->irq , plip_interrupt, 0, dev->name, NULL) != 0) { sti(); printk("%s: couldn't get IRQ %d.\n", dev->name, dev->irq); return -EAGAIN; @@ -983,7 +983,7 @@ plip_close(struct device *dev) dev->tbusy = 1; dev->start = 0; cli(); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; nl->is_deferred = 0; nl->connection = PLIP_CN_NONE; diff --git a/drivers/net/pt.c b/drivers/net/pt.c index ee782028e388..138807788440 100644 --- a/drivers/net/pt.c +++ b/drivers/net/pt.c @@ -120,7 +120,7 @@ static unsigned char pt_dmacfg = 0; static int pt_probe(struct device *dev); static int pt_open(struct device *dev); static int pt_send_packet(struct sk_buff *skb, struct device *dev); -static void pt_interrupt(int irq, struct pt_regs *regs); +static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int pt_close(struct device *dev); static int pt_ioctl(struct device *dev, struct ifreq *ifr, int cmd); static struct enet_statistics *pt_get_stats(struct device *dev); @@ -868,7 +868,7 @@ static int pt_probe(struct device *dev) * the interrupt, and this marks the 'irqaction' as busy. */ { - int irqval = request_irq(dev->irq, &pt_interrupt,0, "pt"); + int irqval = request_irq(dev->irq, &pt_interrupt,0, "pt", NULL); if (irqval) { printk("PT: ERROR: Unable to get IRQ %d (irqval = %d).\n", dev->irq, irqval); @@ -932,7 +932,7 @@ static int pt_open(struct device *dev) { if (request_dma(dev->dma, "pt")) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); return -EAGAIN; } } @@ -1480,7 +1480,7 @@ static void pt_tmrisr(struct pt_local *lp) * This routine is called by the kernel when there is an interrupt for the * PT. */ -static void pt_interrupt(int irq, struct pt_regs *regs) +static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* It's a tad dodgy here, but we assume pt0a until proven otherwise */ struct device *dev = &pt0a; diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c index 5799d80c5172..26a370d55696 100644 --- a/drivers/net/seeq8005.c +++ b/drivers/net/seeq8005.c @@ -81,7 +81,7 @@ extern int seeq8005_probe(struct device *dev); static int seeq8005_probe1(struct device *dev, int ioaddr); static int seeq8005_open(struct device *dev); static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev); -static void seeq8005_interrupt(int irq, struct pt_regs *regs); +static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void seeq8005_rx(struct device *dev); static int seeq8005_close(struct device *dev); static struct enet_statistics *seeq8005_get_stats(struct device *dev); @@ -304,7 +304,7 @@ static int seeq8005_probe1(struct device *dev, int ioaddr) #if 0 { - int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005"); + int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL); if (irqval) { printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, irqval); @@ -350,7 +350,7 @@ seeq8005_open(struct device *dev) struct net_local *lp = (struct net_local *)dev->priv; { - int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005"); + int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL); if (irqval) { printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, irqval); @@ -418,7 +418,7 @@ seeq8005_send_packet(struct sk_buff *skb, struct device *dev) /* The typical workload of the driver: Handle the network interface interrupts. */ static void -seeq8005_interrupt(int irq, struct pt_regs * regs) +seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -581,7 +581,7 @@ seeq8005_close(struct device *dev) /* Flush the Tx and disable Rx here. */ outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; diff --git a/drivers/net/sk_g16.c b/drivers/net/sk_g16.c index d2c8c3e288d0..1ba4f9473d91 100644 --- a/drivers/net/sk_g16.c +++ b/drivers/net/sk_g16.c @@ -63,7 +63,6 @@ static const char *rcsid = "$Id: sk_g16.c,v 1.1 1994/06/30 16:25:15 root Exp $"; #include #include #include -#include #include #include #include @@ -487,7 +486,7 @@ static int SK_probe(struct device *dev, short ioaddr); static int SK_open(struct device *dev); static int SK_send_packet(struct sk_buff *skb, struct device *dev); -static void SK_interrupt(int irq, struct pt_regs * regs); +static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs); static void SK_rxintr(struct device *dev); static void SK_txintr(struct device *dev); static int SK_close(struct device *dev); @@ -886,7 +885,7 @@ static int SK_open(struct device *dev) do { - irqval = request_irq(irqtab[i], &SK_interrupt, 0, "sk_g16"); + irqval = request_irq(irqtab[i], &SK_interrupt, 0, "sk_g16", NULL); i++; } while (irqval && irqtab[i]); @@ -903,7 +902,7 @@ static int SK_open(struct device *dev) } else if (dev->irq == 2) /* IRQ2 is always IRQ9 */ { - if (request_irq(9, &SK_interrupt, 0, "sk_g16")) + if (request_irq(9, &SK_interrupt, 0, "sk_g16", NULL)) { printk("%s: unable to get IRQ 9\n", dev->name); return -EAGAIN; @@ -924,7 +923,7 @@ static int SK_open(struct device *dev) /* check if IRQ free and valid. Then install Interrupt handler */ - if (request_irq(dev->irq, &SK_interrupt, 0, "sk_g16")) + if (request_irq(dev->irq, &SK_interrupt, 0, "sk_g16", NULL)) { printk("%s: unable to get selected IRQ\n", dev->name); return -EAGAIN; @@ -1299,7 +1298,7 @@ static int SK_send_packet(struct sk_buff *skb, struct device *dev) * Description : SK_G16 interrupt handler which checks for LANCE * Errors, handles transmit and receive interrupts * - * Parameters : I : int irq, struct pt_regs * regs - + * Parameters : I : int irq, void *dev_id, struct pt_regs * regs - * Return Value : None * Errors : None * Globals : None @@ -1308,7 +1307,7 @@ static int SK_send_packet(struct sk_buff *skb, struct device *dev) * YY/MM/DD uid Description -*/ -static void SK_interrupt(int irq, struct pt_regs * regs) +static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs) { int csr0; struct device *dev = (struct device *) irq2dev_map[irq]; @@ -1665,7 +1664,7 @@ static int SK_close(struct device *dev) SK_write_reg(CSR0, CSR0_STOP); /* STOP the LANCE */ - free_irq(dev->irq); /* Free IRQ */ + free_irq(dev->irq, NULL); /* Free IRQ */ irq2dev_map[dev->irq] = 0; /* Mark IRQ as unused */ return 0; /* always succeed */ diff --git a/drivers/net/skeleton.c b/drivers/net/skeleton.c index 7ac43dba5029..bfb9cf746dce 100644 --- a/drivers/net/skeleton.c +++ b/drivers/net/skeleton.c @@ -100,7 +100,7 @@ extern int netcard_probe(struct device *dev); static int netcard_probe1(struct device *dev, int ioaddr); static int net_open(struct device *dev); static int net_send_packet(struct sk_buff *skb, struct device *dev); -static void net_interrupt(int irq, struct pt_regs *regs); +static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void net_rx(struct device *dev); static int net_close(struct device *dev); static struct enet_statistics *net_get_stats(struct device *dev); @@ -220,7 +220,7 @@ static int netcard_probe1(struct device *dev, int ioaddr) dev->irq = 9; { - int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname); + int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname, NULL); if (irqval) { printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, irqval); @@ -313,7 +313,7 @@ net_open(struct device *dev) * This is used if the interrupt line can turned off (shared). * See 3c503.c for an example of selecting the IRQ at config-time. */ - if (request_irq(dev->irq, &net_interrupt, 0, cardname)) { + if (request_irq(dev->irq, &net_interrupt, 0, cardname, NULL)) { return -EAGAIN; } /* @@ -321,7 +321,7 @@ net_open(struct device *dev) * and clean up on failure. */ if (request_dma(dev->dma, cardname)) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); return -EAGAIN; } irq2dev_map[dev->irq] = dev; @@ -397,7 +397,7 @@ net_send_packet(struct sk_buff *skb, struct device *dev) * Handle the network interface interrupts. */ static void -net_interrupt(int irq, struct pt_regs * regs) +net_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct net_local *lp; @@ -505,7 +505,7 @@ net_close(struct device *dev) /* If not IRQ or DMA jumpered, free up the line. */ outw(0x00, ioaddr+0); /* Release the physical interrupt line. */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); free_dma(dev->dma); irq2dev_map[dev->irq] = 0; @@ -615,7 +615,7 @@ cleanup_module(void) * allocate them in net_probe1(). */ /* - free_irq(this_device.irq); + free_irq(this_device.irq, NULL); free_dma(this_device.dma); */ release_region(this_device.base_addr, NETCARD_IO_EXTENT); diff --git a/drivers/net/slip.c b/drivers/net/slip.c index b112469d3c8c..98c838692b12 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -1335,12 +1335,17 @@ cleanup_module(void) { for (i = 0; i < slip_maxdev; i++) { - if (slip_ctrls[i]->dev.start) - /* VSV = if dev->start==0, then device - unregistred while close proc. */ + if (slip_ctrls[i]) { - unregister_netdev(&(slip_ctrls[i]->dev)); + /* + * VSV = if dev->start==0, then device + * unregistred while close proc. + */ + if (slip_ctrls[i]->dev.start) + unregister_netdev(&(slip_ctrls[i]->dev)); + kfree(slip_ctrls[i]); + slip_ctrls[i] = NULL; } } kfree(slip_ctrls); diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index f13cd0a78a3a..b393828e1ef6 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c @@ -233,7 +233,7 @@ ultra_open(struct device *dev) { int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ - if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name)) + if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, NULL)) return -EAGAIN; outb(ULTRA_MEMENB, ioaddr); /* Enable memory, 16 bit mode. */ @@ -330,7 +330,7 @@ ultra_close_card(struct device *dev) printk("%s: Shutting down ethercard.\n", dev->name); outb(0x00, ioaddr + 6); /* Disable interrupts. */ - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; NS8390_init(dev, 0); diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 38ecc3862612..d12652573e0d 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -459,7 +459,7 @@ lance_tx (struct device *dev) } static void -lance_interrupt (int irq, struct pt_regs *regs) +lance_interrupt (int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *) (irq2dev_map [irq]); struct lance_private *lp; @@ -517,7 +517,7 @@ lance_open (struct device *dev) ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; - if (request_irq (dev->irq, &lance_interrupt, 0, "LANCE")){ + if (request_irq (dev->irq, &lance_interrupt, 0, "LANCE", NULL)){ printk ("Lance: Can't get irq %d\n", dev->irq); return -EAGAIN; } @@ -569,7 +569,7 @@ lance_close (struct device *dev) ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; - free_irq (dev->irq); + free_irq (dev->irq, NULL); irq2dev_map [dev->irq] = NULL; return 0; diff --git a/drivers/net/tulip.c b/drivers/net/tulip.c index 3386a9b8340d..fa31321c0cf6 100644 --- a/drivers/net/tulip.c +++ b/drivers/net/tulip.c @@ -155,7 +155,7 @@ static int tulip_open(struct device *dev); static void tulip_init_ring(struct device *dev); static int tulip_start_xmit(struct sk_buff *skb, struct device *dev); static int tulip_rx(struct device *dev); -static void tulip_interrupt(int irq, struct pt_regs *regs); +static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs); static int tulip_close(struct device *dev); static struct enet_statistics *tulip_get_stats(struct device *dev); static void set_multicast_list(struct device *dev); @@ -283,7 +283,7 @@ tulip_open(struct device *dev) if (irq2dev_map[dev->irq] != NULL || (irq2dev_map[dev->irq] = dev) == NULL || dev->irq == 0 - || request_irq(dev->irq, &tulip_interrupt, 0, "DEC 21040 Tulip")) { + || request_irq(dev->irq, &tulip_interrupt, 0, "DEC 21040 Tulip", NULL)) { return -EAGAIN; } @@ -444,7 +444,7 @@ tulip_start_xmit(struct sk_buff *skb, struct device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void tulip_interrupt(int irq, struct pt_regs *regs) +static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct device *dev = (struct device *)(irq2dev_map[irq]); struct tulip_private *lp; @@ -562,7 +562,7 @@ static void tulip_interrupt(int irq, struct pt_regs *regs) if (dev->start == 0 && --stopit < 0) { printk("%s: Emergency stop, looping startup interrupt.\n", dev->name); - free_irq(irq); + free_irq(irq, NULL); } } @@ -651,7 +651,7 @@ tulip_close(struct device *dev) tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff; - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = 0; MOD_DEC_USE_COUNT; diff --git a/drivers/net/wavelan.c b/drivers/net/wavelan.c index 59324c78b72c..19111dd33c0f 100644 --- a/drivers/net/wavelan.c +++ b/drivers/net/wavelan.c @@ -77,7 +77,7 @@ static const char *version = "wavelan.c:v7 95/4/8\n"; static int wavelan_probe1(device *, unsigned short); static int wavelan_open(device *); static int wavelan_send_packet(struct sk_buff *, device *); -static void wavelan_interrupt(int, struct pt_regs *); +static void wavelan_interrupt(int, void *, struct pt_regs *); static int wavelan_close(device *); static en_stats *wavelan_get_stats(device *); static void wavelan_set_multicast_list(device *); @@ -1240,7 +1240,7 @@ wavelan_open(device *dev) || (irq2dev_map[dev->irq] = dev) == (device *)0 || - request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN") != 0 + request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN", NULL) != 0 ) { irq2dev_map[dev->irq] = (device *)0; @@ -1259,7 +1259,7 @@ wavelan_open(device *dev) if (r == -1) { - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = (device *)0; if (wavelan_debug > 0) printk("%s: <-wavelan_open(): -EAGAIN(2)\n", dev->name); @@ -1856,7 +1856,7 @@ wavelan_watchdog(unsigned long a) static void -wavelan_interrupt(int irq, struct pt_regs *regs) +wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs) { device *dev; unsigned short ioaddr; @@ -1984,7 +1984,7 @@ wavelan_close(device *dev) wavelan_ints_off(dev); - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = (device *)0; /* diff --git a/drivers/net/wd.c b/drivers/net/wd.c index 5eaa6585bb66..7af3be77a47c 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -253,7 +253,7 @@ int wd_probe1(struct device *dev, int ioaddr) /* Snarf the interrupt now. There's no point in waiting since we cannot share and the board will usually be enabled. */ - if (request_irq(dev->irq, ei_interrupt, 0, model_name)) { + if (request_irq(dev->irq, ei_interrupt, 0, model_name, NULL)) { printk (" unable to get IRQ %d.\n", dev->irq); return EAGAIN; } @@ -261,7 +261,7 @@ int wd_probe1(struct device *dev, int ioaddr) /* Allocate dev->priv and fill in 8390 specific dev fields. */ if (ethdev_init(dev)) { printk (" unable to get memory for dev->priv.\n"); - free_irq(dev->irq); + free_irq(dev->irq, NULL); return -ENOMEM; } @@ -493,7 +493,7 @@ cleanup_module(void) int ioaddr = dev->base_addr - WD_NIC_OFFSET; kfree(dev->priv); dev->priv = NULL; - free_irq(dev->irq); + free_irq(dev->irq, NULL); irq2dev_map[dev->irq] = NULL; release_region(ioaddr, WD_IO_EXTENT); unregister_netdev(dev); diff --git a/drivers/net/znet.c b/drivers/net/znet.c index 9f44928ea80f..a9996fd65bda 100644 --- a/drivers/net/znet.c +++ b/drivers/net/znet.c @@ -182,7 +182,7 @@ struct netidblk { int znet_probe(struct device *dev); static int znet_open(struct device *dev); static int znet_send_packet(struct sk_buff *skb, struct device *dev); -static void znet_interrupt(int irq, struct pt_regs *regs); +static void znet_interrupt(int irq, void *dev_id, struct pt_regs *regs); static void znet_rx(struct device *dev); static int znet_close(struct device *dev); static struct enet_statistics *net_get_stats(struct device *dev); @@ -246,7 +246,7 @@ int znet_probe(struct device *dev) zn.tx_dma = netinfo->dma2; /* These should never fail. You can't add devices to a sealed box! */ - if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet") + if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet", NULL) || request_dma(zn.rx_dma,"ZNet rx") || request_dma(zn.tx_dma,"ZNet tx")) { printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name); @@ -402,7 +402,7 @@ static int znet_send_packet(struct sk_buff *skb, struct device *dev) } /* The ZNET interrupt handler. */ -static void znet_interrupt(int irq, struct pt_regs * regs) +static void znet_interrupt(int irq, void *dev_id, struct pt_regs * regs) { struct device *dev = irq2dev_map[irq]; int ioaddr; @@ -603,7 +603,7 @@ static int znet_close(struct device *dev) disable_dma(zn.rx_dma); disable_dma(zn.tx_dma); - free_irq(dev->irq); + free_irq(dev->irq, NULL); if (znet_debug > 1) printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); diff --git a/drivers/scsi/53c7,8xx.c b/drivers/scsi/53c7,8xx.c index 74350b087a1e..caed509af0e2 100644 --- a/drivers/scsi/53c7,8xx.c +++ b/drivers/scsi/53c7,8xx.c @@ -277,7 +277,7 @@ static int disable (struct Scsi_Host *host); static int NCR53c8xx_run_tests (struct Scsi_Host *host); static int NCR53c8xx_script_len; static int NCR53c8xx_dsa_len; -static void NCR53c7x0_intr(int irq, struct pt_regs * regs); +static void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs); static int ncr_halt (struct Scsi_Host *host); static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd); @@ -1114,7 +1114,7 @@ NCR53c7x0_init (struct Scsi_Host *host) { search->irq == host->irq && search != host); search=search->next); if (!search) { - if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) { + if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx", NULL)) { printk("scsi%d : IRQ%d not free, detaching\n" " You have either a configuration problem, or a\n" " broken BIOS. You may wish to manually assign\n" @@ -4321,7 +4321,7 @@ intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { } /* - * Function : static void NCR53c7x0_intr (int irq, struct pt_regs * regs) + * Function : static void NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) * * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing * the same IRQ line. @@ -4332,7 +4332,7 @@ intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) { */ static void -NCR53c7x0_intr (int irq, struct pt_regs * regs) { +NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) { NCR53c7x0_local_declare(); struct Scsi_Host *host; /* Host we are looking at */ unsigned char istat; /* Values of interrupt regs */ @@ -5457,7 +5457,7 @@ NCR53c7xx_abort (Scsi_Cmnd *cmd) { (hostdata->chip / 100 == 8 ? ISTAT_800_INTF : 0))) { printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no, cmd->pid); - NCR53c7x0_intr (host->irq, NULL); + NCR53c7x0_intr (host->irq, NULL, NULL); return SCSI_ABORT_BUSY; } @@ -6351,7 +6351,7 @@ NCR53c7x0_release(struct Scsi_Host *host) { if (tmp->hostt == the_template && tmp->irq == host->irq) ++irq_count; if (irq_count == 1) - free_irq(host->irq); + free_irq(host->irq, NULL); } if (host->dma_channel != DMA_NONE) free_dma(host->dma_channel); diff --git a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c index 93663eab6772..415eea1d64bc 100644 --- a/drivers/scsi/AM53C974.c +++ b/drivers/scsi/AM53C974.c @@ -131,7 +131,7 @@ static void AM53C974_config_after_reset(struct Scsi_Host *instance); static __inline__ void initialize_SCp(Scsi_Cmnd *cmd); static __inline__ void run_main(void); static void AM53C974_main (void); -static void AM53C974_intr(int irq, struct pt_regs *regs); +static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs); static void AM53C974_intr_disconnect(struct Scsi_Host *instance); static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg); static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target); @@ -656,7 +656,7 @@ for (search = first_host; (search->irq != instance->irq) || (search == instance) ); search = search->next); if (!search) { - if (request_irq(instance->irq, AM53C974_intr, SA_INTERRUPT, "AM53C974")) { + if (request_irq(instance->irq, AM53C974_intr, SA_INTERRUPT, "AM53C974", NULL)) { printk("scsi%d: IRQ%d not free, detaching\n", instance->host_no, instance->irq); scsi_unregister(instance); return -1; } @@ -916,16 +916,16 @@ do { main_running = 0; } -/********************************************************************* -* Function : AM53C974_intr(int irq, struct pt_regs *regs) * -* * -* Purpose : interrupt handler * -* * -* Inputs : irq - interrupt line, regs - ? * -* * -* Returns : nothing * -**********************************************************************/ -static void AM53C974_intr(int irq, struct pt_regs *regs) +/************************************************************************ +* Function : AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs) * +* * +* Purpose : interrupt handler * +* * +* Inputs : irq - interrupt line, regs - ? * +* * +* Returns : nothing * +************************************************************************/ +static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs) { AM53C974_local_declare(); struct Scsi_Host *instance; diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 7472dc3d9050..b59e96bed679 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -1162,7 +1162,7 @@ static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter, if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0) { if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler, - SA_INTERRUPT, HostAdapter->InterruptLabel) < 0) + SA_INTERRUPT, HostAdapter->InterruptLabel, NULL) < 0) { BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--; printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n", @@ -1236,7 +1236,7 @@ static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter) */ if (HostAdapter->IRQ_ChannelAcquired) if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0) - free_irq(HostAdapter->IRQ_Channel); + free_irq(HostAdapter->IRQ_Channel, NULL); /* Release exclusive access to the DMA Channel. */ diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index c934b222ec7a..021c294d0935 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -616,7 +616,7 @@ static void NCR5380_all_init (void) { static int probe_irq; -static void probe_intr (int irq, struct pt_regs * regs) { +static void probe_intr (int irq, void *dev_id, struct pt_regs * regs) { probe_irq = irq; }; @@ -629,7 +629,7 @@ static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) { NCR5380_setup(instance); for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1) - if ((mask & possible) && (request_irq(i, &probe_intr, SA_INTERRUPT, "NCR-probe") + if ((mask & possible) && (request_irq(i, &probe_intr, SA_INTERRUPT, "NCR-probe", NULL) == 0)) trying_irqs |= mask; @@ -660,7 +660,7 @@ static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) { for (i = 0, mask = 1; i < 16; ++i, mask <<= 1) if (trying_irqs & mask) - free_irq(i); + free_irq(i, NULL); return probe_irq; } @@ -1123,7 +1123,7 @@ static void NCR5380_main (void) { * */ -static void NCR5380_intr (int irq, struct pt_regs * regs) { +static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs) { NCR5380_local_declare(); struct Scsi_Host *instance; int done; diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 1b9f91cd0797..8cc84e25d18f 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -275,7 +275,7 @@ static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible); #endif static void NCR5380_init (struct Scsi_Host *instance, int flags); static void NCR5380_information_transfer (struct Scsi_Host *instance); -static void NCR5380_intr (int irq, struct pt_regs * regs); +static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs); static void NCR5380_main (void); static void NCR5380_print_options (struct Scsi_Host *instance); static void NCR5380_print_phase (struct Scsi_Host *instance); diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index 3105b1bb1f1a..ef51411169dd 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c @@ -169,7 +169,7 @@ enum Phase { }; /* Static function prototypes */ -static void NCR53c406a_intr(int, struct pt_regs *); +static void NCR53c406a_intr(int, void *, struct pt_regs *); static void internal_done(Scsi_Cmnd *); static void wait_intr(void); static void chip_init(void); @@ -537,7 +537,7 @@ NCR53c406a_detect(Scsi_Host_Template * tpnt){ request_region(port_base, 0x10, "NCR53c406a"); if(irq_level > 0) { - if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a")){ + if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a", NULL)){ printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level); return 0; } @@ -664,7 +664,7 @@ static void wait_intr() { return; } - NCR53c406a_intr(0, NULL); + NCR53c406a_intr(0, NULL, NULL); } int NCR53c406a_command(Scsi_Cmnd *SCpnt){ @@ -763,7 +763,7 @@ NCR53c406a_biosparm(Scsi_Disk *disk, kdev_t dev, int* info_array){ } static void -NCR53c406a_intr(int unused, struct pt_regs *regs){ +NCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs){ DEB(unsigned char fifo_size;) DEB(unsigned char seq_reg;) unsigned char status, int_reg; diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 858b44c4b573..56b8be2c2d2b 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -2551,7 +2551,7 @@ int asc_dbglvl = 0; #ifdef LINUX_1_3 STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int); #endif /* LINUX_1_3 */ -STATIC void advansys_interrupt(int, struct pt_regs *); +STATIC void advansys_interrupt(int, void *, struct pt_regs *); STATIC void advansys_command_done(Scsi_Cmnd *); STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *); STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *); @@ -3107,7 +3107,7 @@ advansys_detect(Scsi_Host_Template *tpnt) /* Register IRQ Number. */ ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq); if ((ret = request_irq(shp->irq, advansys_interrupt, - SA_INTERRUPT, "advansys")) != 0) { + SA_INTERRUPT, "advansys", NULL)) != 0) { ASC_DBG1(0, "advansys_detect: request_irq() failed %d\n", ret); release_region(shp->io_port, shp->n_io_port); if (shp->dma_channel != NO_ISA_DMA) { @@ -3130,7 +3130,7 @@ advansys_detect(Scsi_Host_Template *tpnt) if (shp->dma_channel != NO_ISA_DMA) { free_dma(shp->dma_channel); } - free_irq(shp->irq); + free_irq(shp->irq, NULL); scsi_unregister(shp); asc_board_count--; continue; @@ -3152,7 +3152,7 @@ int advansys_release(struct Scsi_Host *shp) { ASC_DBG(1, "advansys_release: begin\n"); - free_irq(shp->irq); + free_irq(shp->irq, NULL); if (shp->dma_channel != NO_ISA_DMA) { ASC_DBG(1, "advansys_release: free_dma()\n"); free_dma(shp->dma_channel); @@ -3577,7 +3577,7 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, * First-level interrupt handler. */ STATIC void -advansys_interrupt(int irq, struct pt_regs *regs) +advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int i; int flags; diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 766d5f94307d..1cdad2c0dd3f 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -381,7 +381,7 @@ struct aha152x_hostdata { #endif }; -void aha152x_intr(int irq, struct pt_regs *); +void aha152x_intr(int irq, void *dev_id, struct pt_regs *); void aha152x_done(struct Scsi_Host *shpnt, int error); void aha152x_setup(char *str, int *ints); int aha152x_checksetup(struct aha152x_setup *setup); @@ -835,7 +835,7 @@ int aha152x_detect(Scsi_Host_Template * tpnt) SETBITS(DMACNTRL0, INTEN); - ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x"); + ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x", NULL); if(ok<0) { @@ -1307,7 +1307,7 @@ void aha152x_done(struct Scsi_Host *shpnt, int error) /* * Interrupts handler (main routine of the driver) */ -void aha152x_intr(int irqno, struct pt_regs * regs) +void aha152x_intr(int irqno, void *dev_id, struct pt_regs * regs) { struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN]; unsigned int flags; diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index df08d810163f..2f39f19776e0 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -353,7 +353,7 @@ static int aha1542_test_port(int bse, struct Scsi_Host * shpnt) } /* A "high" level interrupt handler */ -static void aha1542_intr_handle(int irq, struct pt_regs *regs) +static void aha1542_intr_handle(int irq, void *dev_id, struct pt_regs *regs) { void (*my_done)(Scsi_Cmnd *) = NULL; int errstatus, mbi, mbo, mbistatus; @@ -1000,7 +1000,7 @@ int aha1542_detect(Scsi_Host_Template * tpnt) DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level)); save_flags(flags); cli(); - if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542")) { + if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542", NULL)) { printk("Unable to allocate IRQ for adaptec controller.\n"); goto unregister; } @@ -1008,7 +1008,7 @@ int aha1542_detect(Scsi_Host_Template * tpnt) if (dma_chan != 0xFF) { if (request_dma(dma_chan,"aha1542")) { printk("Unable to allocate DMA channel for Adaptec.\n"); - free_irq(irq_level); + free_irq(irq_level, NULL); goto unregister; } diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 20190a0d6857..11de4bde37d1 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -174,7 +174,7 @@ int aha1740_test_port(void) } /* A "high" level interrupt handler */ -void aha1740_intr_handle(int irq, struct pt_regs * regs) +void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs) { void (*my_done)(Scsi_Cmnd *); int errstatus, adapstat; @@ -472,7 +472,7 @@ int aha1740_detect(Scsi_Host_Template * tpnt) DEB(printk("aha1740_detect: enable interrupt channel %d\n", irq_level)); - if (request_irq(irq_level,aha1740_intr_handle, 0, "aha1740")) + if (request_irq(irq_level,aha1740_intr_handle, 0, "aha1740", NULL)) { printk("Unable to allocate IRQ for adaptec controller.\n"); return 0; diff --git a/drivers/scsi/aic7xxx.c b/drivers/scsi/aic7xxx.c index fc9a83ced5d2..c08467f54cd3 100644 --- a/drivers/scsi/aic7xxx.c +++ b/drivers/scsi/aic7xxx.c @@ -1680,7 +1680,7 @@ aic7xxx_reset_channel(struct aic7xxx_host *p, char channel, * be disabled all through this function unless we say otherwise. *-F*************************************************************************/ static void -aic7xxx_isr(int irq, struct pt_regs * regs) +aic7xxx_isr(int irq, void *dev_id, struct pt_regs * regs) { int base, intstat; struct aic7xxx_host *p; @@ -3462,7 +3462,7 @@ aic7xxx_register(Scsi_Host_Template *template, /* * Register IRQ with the kernel. */ - if (request_irq(config->irq, aic7xxx_isr, SA_INTERRUPT, "aic7xxx")) + if (request_irq(config->irq, aic7xxx_isr, SA_INTERRUPT, "aic7xxx", NULL)) { printk("aic7xxx: Couldn't register IRQ %d, ignoring.\n", config->irq); aic7xxx_boards[config->irq] = NULL; diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index 290003324a22..6a8cd7477d6b 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c @@ -322,7 +322,7 @@ static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ]; #define HD(board) ((struct hostdata *) &sh[board]->hostdata) #define BN(board) (HD(board)->board_name) -static void eata2x_interrupt_handler(int, struct pt_regs *); +static void eata2x_interrupt_handler(int, void *, struct pt_regs *); static int do_trace = FALSE; static inline unchar wait_on_busy(ushort iobase) { @@ -448,7 +448,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, /* Board detected, allocate its IRQ if not already done */ if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq - (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name))) { + (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name, NULL))) { printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq); return FALSE; } @@ -456,7 +456,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, if (subversion == ISA && request_dma(dma_channel, driver_name)) { printk("%s: unable to allocate DMA channel %u, detaching.\n", name, dma_channel); - free_irq(irq); + free_irq(irq, NULL); return FALSE; } @@ -481,7 +481,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, if (sh[j] == NULL) { printk("%s: unable to register host, detaching.\n", name); - if (irqlist[irq] == NO_IRQ) free_irq(irq); + if (irqlist[irq] == NO_IRQ) free_irq(irq, NULL); if (subversion == ISA) free_dma(dma_channel); @@ -884,7 +884,7 @@ int eata2x_reset (Scsi_Cmnd *SCarg) { } } -static void eata2x_interrupt_handler(int irq, struct pt_regs * regs) { +static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) { Scsi_Cmnd *SCpnt; unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0; struct mssp *spp; diff --git a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c index 935f31c4c0c4..924d172664a2 100644 --- a/drivers/scsi/eata_dma.c +++ b/drivers/scsi/eata_dma.c @@ -114,7 +114,7 @@ void eata_scsi_done (Scsi_Cmnd * scmd) return; } -void eata_fake_int_handler(s32 irq, struct pt_regs * regs) +void eata_fake_int_handler(s32 irq, void *dev_id, struct pt_regs * regs) { fake_int_result = inb((ulong)fake_int_base + HA_RSTATUS); fake_int_happened = TRUE; @@ -129,7 +129,7 @@ void eata_fake_int_handler(s32 irq, struct pt_regs * regs) int eata_release(struct Scsi_Host *sh) { uint i; - if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq); + if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL); else reg_IRQ[sh->irq]--; scsi_init_free((void *)status, 512); @@ -150,7 +150,7 @@ int eata_release(struct Scsi_Host *sh) #endif -void eata_int_handler(int irq, struct pt_regs * regs) +void eata_int_handler(int irq, void *dev_id, struct pt_regs * regs) { uint i, result = 0; uint hba_stat, scsi_stat, eata_stat; @@ -867,7 +867,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */ if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT, - "eata_dma")){ + "eata_dma", NULL)){ reg_IRQ[gc->IRQ]++; if (!gc->IRQ_TR) reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */ @@ -892,7 +892,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, dma_channel, base); reg_IRQ[gc->IRQ]--; if (reg_IRQ[gc->IRQ] == 0) - free_irq(gc->IRQ); + free_irq(gc->IRQ, NULL); if (gc->IRQ_TR == FALSE) reg_IRQL[gc->IRQ] = FALSE; return (FALSE); @@ -919,7 +919,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, free_dma(dma_channel); reg_IRQ[gc->IRQ]--; if (reg_IRQ[gc->IRQ] == 0) - free_irq(gc->IRQ); + free_irq(gc->IRQ, NULL); if (gc->IRQ_TR == FALSE) reg_IRQL[gc->IRQ] = FALSE; return (FALSE); @@ -956,7 +956,7 @@ short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, reg_IRQ[gc->IRQ]--; if (reg_IRQ[gc->IRQ] == 0) - free_irq(gc->IRQ); + free_irq(gc->IRQ, NULL); if (gc->IRQ_TR == FALSE) reg_IRQL[gc->IRQ] = FALSE; return (FALSE); @@ -1306,8 +1306,8 @@ int eata_detect(Scsi_Host_Template * tpnt) for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */ if (reg_IRQ[i]){ /* exchange the interrupt handler which */ - free_irq(i); /* we used for probing with the real one */ - request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma"); + free_irq(i, NULL); /* we used for probing with the real one */ + request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma", NULL); } } HBA_ptr = first_HBA; diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index bccffe6df429..94f429d6f90f 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c @@ -99,7 +99,7 @@ void hprint(const char *str) #ifdef MODULE int eata_pio_release(struct Scsi_Host *sh) { - if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq); + if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL); else reg_IRQ[sh->irq]--; if (SD(sh)->channel == 0) { if (sh->io_port && sh->n_io_port) @@ -124,7 +124,7 @@ void IncStat(Scsi_Pointer *SCp, uint Increment) } } -void eata_pio_int_handler(int irq, struct pt_regs * regs) +void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs) { uint eata_stat = 0xfffff; Scsi_Cmnd *cmd; @@ -707,7 +707,7 @@ int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt) if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */ if (!request_irq(gc->IRQ, eata_pio_int_handler, SA_INTERRUPT, - "EATA-PIO")){ + "EATA-PIO", NULL)){ reg_IRQ[gc->IRQ]++; if (!gc->IRQ_TR) reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */ @@ -989,7 +989,7 @@ int eata_pio_detect(Scsi_Host_Template * tpnt) for (i = 0; i <= MAXIRQ; i++) if (reg_IRQ[i]) - request_irq(i, eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO"); + request_irq(i, eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", NULL); HBA_ptr = first_HBA; diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index f12705e0b787..73f5314e76c5 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -339,7 +339,7 @@ static int Write_SCSI_Data_port; static int FIFO_Size = 0x2000; /* 8k FIFO for pre-tmc18c30 chips */ -extern void fdomain_16x0_intr( int irq, struct pt_regs * regs ); +extern void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs ); static void *addresses[] = { (void *)0xc8000, @@ -981,7 +981,7 @@ int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) /* Register the IRQ with the kernel */ retcode = request_irq( interrupt_level, - fdomain_16x0_intr, SA_INTERRUPT, "fdomain" ); + fdomain_16x0_intr, SA_INTERRUPT, "fdomain", NULL); if (retcode < 0) { if (retcode == -EINVAL) { @@ -1211,7 +1211,7 @@ void my_done( int error ) #endif } -void fdomain_16x0_intr( int irq, struct pt_regs * regs ) +void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs ) { int status; int done = 0; diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 46aa90e97ae3..470e878a5bde 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -211,7 +211,7 @@ int generic_NCR5380_detect(Scsi_Host_Template * tpnt) { instance->irq = NCR5380_probe_irq(instance, 0xffff); if (instance->irq != IRQ_NONE) - if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380")) { + if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) { printk("scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = IRQ_NONE; @@ -249,7 +249,7 @@ int generic_NCR5380_release_resources(struct Scsi_Host * instance) NCR5380_setup(instance); - free_irq(instance->irq); + free_irq(instance->irq, NULL); return 0; } diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index ac2cc6564f4a..752f64392d0d 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -278,7 +278,7 @@ DEB(printk("FIer:%d %02x %08x\n", in2000_datalen,fic,(unsigned int )in2000_datap ficmsk = 0;} } -static void in2000_intr_handle(int irq, struct pt_regs *regs) +static void in2000_intr_handle(int irq, void *dev_id, struct pt_regs *regs) { int result=0; unsigned int count,auxstatus,scsistatus,cmdphase,scsibyte; @@ -632,7 +632,7 @@ int in2000_detect(Scsi_Host_Template * tpnt) "\n",base, irq_level); outb(2,ININTR); /* Shut off the FIFO first, so it won't ask for data.*/ - if (request_irq(irq_level,in2000_intr_handle, 0, "in2000")) + if (request_irq(irq_level,in2000_intr_handle, 0, "in2000", NULL)) { printk("in2000_detect: Unable to allocate IRQ.\n"); return 0; diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index e45cb010d41c..aa443e220a51 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -401,7 +401,7 @@ int pas16_detect(Scsi_Host_Template * tpnt) { instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS); if (instance->irq != IRQ_NONE) - if (request_irq(instance->irq, pas16_intr, SA_INTERRUPT, "pas16")) { + if (request_irq(instance->irq, pas16_intr, SA_INTERRUPT, "pas16", NULL)) { printk("scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = IRQ_NONE; diff --git a/drivers/scsi/qlogic.c b/drivers/scsi/qlogic.c index 8333275baf24..e4f15f9ccdc4 100644 --- a/drivers/scsi/qlogic.c +++ b/drivers/scsi/qlogic.c @@ -446,7 +446,7 @@ rtrc(0) #if QL_USE_IRQ /*----------------------------------------------------------------*/ /* interrupt handler */ -static void ql_ihandl(int irq, struct pt_regs * regs) +static void ql_ihandl(int irq, void *dev_id, struct pt_regs * regs) { Scsi_Cmnd *icmd; REG0; @@ -609,7 +609,7 @@ host->proc_dir = &proc_scsi_qlogic; else printk( "Ql: Using preset IRQ %d\n", qlirq ); - if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic")) + if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic", NULL)) host->can_queue = 1; #endif request_region( qbase , 0x10 ,"qlogic"); diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c7449b207015..7a5342852a9c 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -267,8 +267,8 @@ static struct dev_info device_list[] = {"TEXEL","CD-ROM","1.06", BLIST_BORKEN}, {"INSITE","Floptical F*8I","*", BLIST_KEY}, {"INSITE","I325VM","*", BLIST_KEY}, -{"PIONEER","CD-ROMDRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, -{"PIONEER","CD-ROMDRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, +{"PIONEER","CD-ROM DRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, +{"PIONEER","CD-ROM DRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN}, /* * Must be at end of list... */ @@ -2288,8 +2288,12 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt) struct Scsi_Host * host = NULL; for(j=0;jhost->cmd_per_lun;j++){ - SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd), GFP_ATOMIC); - SCpnt->host = SDpnt->host; + host = SDpnt->host; + SCpnt = (Scsi_Cmnd *) + scsi_init_malloc(sizeof(Scsi_Cmnd), + GFP_ATOMIC | + (host->unchecked_isa_dma ? GFP_DMA : 0)); + SCpnt->host = host; SCpnt->device = SDpnt; SCpnt->target = SDpnt->id; SCpnt->lun = SDpnt->lun; @@ -2302,7 +2306,6 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt) SCpnt->underflow = 0; SCpnt->transfersize = 0; SCpnt->host_scribble = NULL; - host = SDpnt->host; if(host->host_queue) host->host_queue->prev = SCpnt; SCpnt->next = host->host_queue; @@ -2859,7 +2862,7 @@ static void scsi_unregister_host(Scsi_Host_Template * tpnt) * It should do the right thing for most correctly * written host adapters. */ - if (shpnt->irq) free_irq(shpnt->irq); + if (shpnt->irq) free_irq(shpnt->irq, NULL); if (shpnt->dma_channel != 0xff) free_dma(shpnt->dma_channel); if (shpnt->io_port && shpnt->n_io_port) release_region(shpnt->io_port, shpnt->n_io_port); diff --git a/drivers/scsi/sd_ioctl.c b/drivers/scsi/sd_ioctl.c index 1898af615c51..5ad350eab5f6 100644 --- a/drivers/scsi/sd_ioctl.c +++ b/drivers/scsi/sd_ioctl.c @@ -54,12 +54,24 @@ int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigne put_user(sd[MINOR(inode->i_rdev)].nr_sects, (long *) arg); return 0; + case BLKRASET: - if(!suser()) return -EACCES; + if (!suser()) + return -EACCES; if(!(inode->i_rdev)) return -EINVAL; if(arg > 0xff) return -EINVAL; read_ahead[MAJOR(inode->i_rdev)] = arg; return 0; + + case BLKRAGET: + if (!arg) + return -EINVAL; + error = verify_area(VERIFY_WRITE, (int *) arg, sizeof(int)); + if (error) + return error; + put_user(read_ahead[MAJOR(inode->i_rdev)], (int *) arg); + return 0; + case BLKFLSBUF: if(!suser()) return -EACCES; if(!(inode->i_rdev)) return -EINVAL; diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index 5b25a83307c8..2e409021aa5b 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -203,7 +203,7 @@ static const Signature signatures[] = { */ static int hostno = -1; -static void seagate_reconnect_intr(int, struct pt_regs *); +static void seagate_reconnect_intr(int, void *, struct pt_regs *); #ifdef FAST static int fast = 1; @@ -358,7 +358,7 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt) instance = scsi_register(tpnt, 0); hostno = instance->host_no; if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT, - (controller_type == SEAGATE) ? "seagate" : "tmc-8xx")) { + (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) { printk("scsi%d : unable to allocate IRQ%d\n", hostno, (int) irq); return 0; @@ -493,7 +493,7 @@ static int should_reconnect = 0; * asserting SEL. */ -static void seagate_reconnect_intr(int irq, struct pt_regs * regs) +static void seagate_reconnect_intr(int irq, void *dev_id, struct pt_regs *regs) { int temp; Scsi_Cmnd * SCtmp; diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index b6b10300a1c3..91901ddf7e22 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -245,7 +245,7 @@ int t128_detect(Scsi_Host_Template * tpnt) { instance->irq = NCR5380_probe_irq(instance, T128_IRQS); if (instance->irq != IRQ_NONE) - if (request_irq(instance->irq, t128_intr, SA_INTERRUPT, "t128")) { + if (request_irq(instance->irq, t128_intr, SA_INTERRUPT, "t128", NULL)) { printk("scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = IRQ_NONE; diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index ce0e378ee1de..c0e80f8225a4 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -287,7 +287,7 @@ static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ]; #define HD(board) ((struct hostdata *) &sh[board]->hostdata) #define BN(board) (HD(board)->board_name) -static void u14_34f_interrupt_handler(int, struct pt_regs *); +static void u14_34f_interrupt_handler(int, void *, struct pt_regs *); static int do_trace = FALSE; static inline unchar wait_on_busy(ushort iobase) { @@ -407,7 +407,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, /* Board detected, allocate its IRQ if not already done */ if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq - (irq, u14_34f_interrupt_handler, SA_INTERRUPT, driver_name))) { + (irq, u14_34f_interrupt_handler, SA_INTERRUPT, driver_name, NULL))) { printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq); return FALSE; } @@ -415,7 +415,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, if (subversion == ISA && request_dma(dma_channel, driver_name)) { printk("%s: unable to allocate DMA channel %u, detaching.\n", name, dma_channel); - free_irq(irq); + free_irq(irq, NULL); return FALSE; } @@ -424,7 +424,7 @@ static inline int port_detect(ushort *port_base, unsigned int j, if (sh[j] == NULL) { printk("%s: unable to register host, detaching.\n", name); - if (irqlist[irq] == NO_IRQ) free_irq(irq); + if (irqlist[irq] == NO_IRQ) free_irq(irq, NULL); if (subversion == ISA) free_dma(dma_channel); @@ -838,7 +838,7 @@ int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) { return 0; } -static void u14_34f_interrupt_handler(int irq, struct pt_regs * regs) { +static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) { Scsi_Cmnd *SCpnt; unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0; struct mscp *spp; diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index 23e94a91b39c..505a3aef0e40 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c @@ -293,7 +293,7 @@ static const unsigned short ultrastor_ports_14f[] = { }; #endif -static void ultrastor_interrupt(int, struct pt_regs *); +static void ultrastor_interrupt(int, void *, struct pt_regs *); static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt); @@ -507,7 +507,7 @@ static int ultrastor_14f_detect(Scsi_Host_Template * tpnt) config.mscp_free = ~0; #endif - if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor")) { + if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor", NULL)) { printk("Unable to allocate IRQ%u for UltraStor controller.\n", config.interrupt); return FALSE; @@ -515,7 +515,7 @@ static int ultrastor_14f_detect(Scsi_Host_Template * tpnt) if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) { printk("Unable to allocate DMA channel %u for UltraStor controller.\n", config.dma_channel); - free_irq(config.interrupt); + free_irq(config.interrupt, NULL); return FALSE; } tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG; @@ -577,7 +577,7 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt) printk("U24F: invalid IRQ\n"); return FALSE; } - if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor")) + if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor", NULL)) { printk("Unable to allocate IRQ%u for UltraStor controller.\n", config.interrupt); @@ -1025,7 +1025,7 @@ int ultrastor_biosparam(Disk * disk, kdev_t dev, int * dkinfo) return 0; } -static void ultrastor_interrupt(int irq, struct pt_regs *regs) +static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned int status; #if ULTRASTOR_MAX_CMDS > 1 diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c index e2d8771f24e2..39390416adba 100644 --- a/drivers/scsi/wd7000.c +++ b/drivers/scsi/wd7000.c @@ -808,7 +808,7 @@ static void wd7000_scsi_done(Scsi_Cmnd * SCpnt) #define wd7000_intr_ack(host) outb(0,host->iobase+ASC_INTR_ACK) -void wd7000_intr_handle(int irq, struct pt_regs * regs) +void wd7000_intr_handle(int irq, void *dev_id, struct pt_regs * regs) { register int flag, icmb, errstatus, icmb_status; register int host_error, scsi_error; @@ -1048,13 +1048,13 @@ int wd7000_init( Adapter *host ) } WAIT(host->iobase+ASC_STAT, ASC_STATMASK, ASC_INIT, 0); - if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000")) { + if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000", NULL)) { printk("wd7000_init: can't get IRQ %d.\n", host->irq); return 0; } if (request_dma(host->dma,"wd7000")) { printk("wd7000_init: can't get DMA channel %d.\n", host->dma); - free_irq(host->irq); + free_irq(host->irq, NULL); return 0; } wd7000_enable_dma(host); @@ -1062,7 +1062,7 @@ int wd7000_init( Adapter *host ) if (!wd7000_diagnostics(host,ICB_DIAG_FULL)) { free_dma(host->dma); - free_irq(host->irq); + free_irq(host->irq, NULL); return 0; } @@ -1197,7 +1197,7 @@ int wd7000_abort(Scsi_Cmnd * SCpnt) if (inb(host->iobase+ASC_STAT) & INT_IM) { printk("wd7000_abort: lost interrupt\n"); - wd7000_intr_handle(host->irq, NULL); + wd7000_intr_handle(host->irq, NULL, NULL); return SCSI_ABORT_SUCCESS; } diff --git a/drivers/sound/ad1848.c b/drivers/sound/ad1848.c index 4139444bf807..cfec50bcd29f 100644 --- a/drivers/sound/ad1848.c +++ b/drivers/sound/ad1848.c @@ -39,9 +39,6 @@ */ #include - -#define DEB(x) -#define DEB1(x) #include "sound_config.h" #if defined(CONFIG_AD1848) @@ -600,7 +597,7 @@ ad1848_close (int dev) unsigned long flags; ad1848_info *devc = (ad1848_info *) audio_devs[dev]->devc; - DEB (printk ("ad1848_close(void)\n")); + DDB (printk ("ad1848_close(void)\n")); save_flags (flags); cli (); @@ -1528,11 +1525,13 @@ ad1848_init (char *name, int io_base, int irq, int dma_playback, int dma_capture if (!share_dma) { if (sound_alloc_dma (dma_playback, "Sound System")) - printk ("ad1848.c: Can't allocate DMA%d\n", dma_playback); + printk ("ad1848.c: Can't allocate DMA%d for playback\n", + dma_playback); - if (dma_capture != dma_playback) + if (dma_capture != dma_playback && dma_capture != -1) if (sound_alloc_dma (dma_capture, "Sound System (capture)")) - printk ("ad1848.c: Can't allocate DMA%d\n", dma_capture); + printk ("ad1848.c: Can't allocate DMA%d for capture\n", + dma_capture); } /* @@ -1588,7 +1587,7 @@ ad1848_unload (int io_base, int irq, int dma_playback, int dma_capture, int shar } void -ad1848_interrupt (int irq, struct pt_regs *dummy) +ad1848_interrupt (int irq, void *dev_id, struct pt_regs *dummy) { unsigned char status; ad1848_info *devc; diff --git a/drivers/sound/dev_table.h b/drivers/sound/dev_table.h index ac4e02c78c20..ccfcfea97821 100644 --- a/drivers/sound/dev_table.h +++ b/drivers/sound/dev_table.h @@ -411,9 +411,10 @@ struct sound_timer_operations { #endif #ifdef CONFIG_MSS -# ifndef PSEUDO_MSS + /* always define full MSS even for DEC Alphas, just in case... */ {SNDCARD_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA, -1}, SND_DEFAULT_ENABLE}, -# else +# ifdef __alpha__ + /* MSS without IRQ/DMA config registers (for DEC Alphas) */ {SNDCARD_PSEUDO_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA, -1}, SND_DEFAULT_ENABLE}, # endif # ifdef MSS2_BASE diff --git a/drivers/sound/gus_card.c b/drivers/sound/gus_card.c index a3be960f66fc..f2b621ce40b2 100644 --- a/drivers/sound/gus_card.c +++ b/drivers/sound/gus_card.c @@ -35,7 +35,7 @@ #include "gus_hw.h" -void gusintr (int irq, struct pt_regs *dummy); +void gusintr (int irq, void *dev_id, struct pt_regs *dummy); int gus_base, gus_irq, gus_dma; extern int gus_wave_volume; @@ -171,7 +171,7 @@ unload_gus (struct address_info *hw_config) } void -gusintr (int irq, struct pt_regs *dummy) +gusintr (int irq, void *dev_id, struct pt_regs *dummy) { unsigned char src; extern int gus_timer_enabled; @@ -180,7 +180,7 @@ gusintr (int irq, struct pt_regs *dummy) #ifdef CONFIG_GUSMAX if (have_gus_max) - ad1848_interrupt (irq, NULL); + ad1848_interrupt (irq, NULL, NULL); #endif while (1) diff --git a/drivers/sound/gus_wave.c b/drivers/sound/gus_wave.c index 6f28e70e5297..131fe3c5923f 100644 --- a/drivers/sound/gus_wave.c +++ b/drivers/sound/gus_wave.c @@ -837,7 +837,7 @@ gus_initialize (void) gus_select_voice (0); /* This disables writes to IRQ/DMA reg */ - gusintr (0, NULL); /* Serve pending interrupts */ + gusintr (0, NULL, NULL); /* Serve pending interrupts */ restore_flags (flags); } diff --git a/drivers/sound/mad16_sb_midi.c b/drivers/sound/mad16_sb_midi.c index 122e2a3eab5e..3ba6492e6914 100644 --- a/drivers/sound/mad16_sb_midi.c +++ b/drivers/sound/mad16_sb_midi.c @@ -90,7 +90,7 @@ mad16_sb_dsp_command (unsigned char val) } void -mad16_sbintr (int irq, struct pt_regs *dummy) +mad16_sbintr (int irq, void *dev_id, struct pt_regs *dummy) { int status; diff --git a/drivers/sound/maui.c b/drivers/sound/maui.c index 3ed3f7747e55..1cc33ce4f386 100644 --- a/drivers/sound/maui.c +++ b/drivers/sound/maui.c @@ -134,7 +134,7 @@ maui_write (unsigned char data) } void -mauiintr (int irq, struct pt_regs *dummy) +mauiintr (int irq, void *dev_id, struct pt_regs *dummy) { irq_ok = 1; } diff --git a/drivers/sound/mpu401.c b/drivers/sound/mpu401.c index 9519bc64e73b..a7b7b7922867 100644 --- a/drivers/sound/mpu401.c +++ b/drivers/sound/mpu401.c @@ -450,7 +450,7 @@ mpu401_input_loop (struct mpu_config *devc) } void -mpuintr (int irq, struct pt_regs *dummy) +mpuintr (int irq, void *dev_id, struct pt_regs *dummy) { struct mpu_config *devc; int dev; diff --git a/drivers/sound/pas2_card.c b/drivers/sound/pas2_card.c index 30b07afbd7f4..78e1f29bd9bc 100644 --- a/drivers/sound/pas2_card.c +++ b/drivers/sound/pas2_card.c @@ -84,7 +84,7 @@ pas2_msg (char *foo) /******************* Begin of the Interrupt Handler ********************/ void -pasintr (int irq, struct pt_regs *dummy) +pasintr (int irq, void *dev_id, struct pt_regs *dummy) { int status; diff --git a/drivers/sound/sb16_midi.c b/drivers/sound/sb16_midi.c index 038dfdeb747e..5f85e76fe6d8 100644 --- a/drivers/sound/sb16_midi.c +++ b/drivers/sound/sb16_midi.c @@ -108,7 +108,7 @@ sb16midiintr (int unit) } void -sbmidiintr (int irq, struct pt_regs *dummy) +sbmidiintr (int irq, void *dev_id, struct pt_regs *dummy) { if (input_avail ()) sb16midi_input_loop (); diff --git a/drivers/sound/sb_dsp.c b/drivers/sound/sb_dsp.c index c13e75ffefe4..19e246061ba4 100644 --- a/drivers/sound/sb_dsp.c +++ b/drivers/sound/sb_dsp.c @@ -180,7 +180,7 @@ ess_read (unsigned char reg) } void -sbintr (int irq, struct pt_regs *dummy) +sbintr (int irq, void *dev_id, struct pt_regs *dummy) { int status; diff --git a/drivers/sound/sound_calls.h b/drivers/sound/sound_calls.h index ca67db1e103a..7111958d50fe 100644 --- a/drivers/sound/sound_calls.h +++ b/drivers/sound/sound_calls.h @@ -83,7 +83,7 @@ void tenmicrosec(int *osp); void request_sound_timer (int count); void sound_stop_timer(void); int snd_ioctl_return(int *addr, int value); -int snd_set_irq_handler (int interrupt_level, void(*hndlr)(int, struct pt_regs *), char *name, int *osp); +int snd_set_irq_handler (int interrupt_level, void(*hndlr)(int, void *, struct pt_regs *), char *name, int *osp); void snd_release_irq(int vect); void sound_dma_malloc(int dev); void sound_dma_free(int dev); @@ -118,7 +118,7 @@ void sb16midiintr (int unit); long attach_sb16midi(long mem_start, struct address_info * hw_config); int probe_sb16midi(struct address_info *hw_config); void sb_midi_interrupt(int dummy); -void sbmidiintr(int irq, struct pt_regs * dummy); +void sbmidiintr(int irq, void *dev_id, struct pt_regs * dummy); /* From sb_midi.c */ void sb_midi_init(int model); @@ -164,7 +164,7 @@ void pas_midi_interrupt(void); long attach_gus_card(long mem_start, struct address_info * hw_config); int probe_gus(struct address_info *hw_config); int gus_set_midi_irq(int num); -void gusintr(int irq, struct pt_regs * dummy); +void gusintr(int irq, void *dev_id, struct pt_regs * dummy); long attach_gus_db16(long mem_start, struct address_info * hw_config); int probe_gus_db16(struct address_info *hw_config); @@ -187,7 +187,7 @@ void gus_midi_interrupt(int dummy); /* From mpu401.c */ long attach_mpu401(long mem_start, struct address_info * hw_config); int probe_mpu401(struct address_info *hw_config); -void mpuintr(int irq, struct pt_regs * dummy); +void mpuintr(int irq, void *dev_id, struct pt_regs * dummy); /* From uart6850.c */ long attach_uart6850(long mem_start, struct address_info * hw_config); @@ -220,7 +220,7 @@ int ad1848_detect (int io_base, int *flags, int *osp); #define AD_F_CS4231 0x0001 /* Returned if a CS4232 (or compatible) detected */ #define AD_F_CS4248 0x0001 /* Returned if a CS4248 (or compatible) detected */ -void ad1848_interrupt (int irq, struct pt_regs * dummy); +void ad1848_interrupt (int irq, void *dev_id, struct pt_regs * dummy); long attach_ms_sound(long mem_start, struct address_info * hw_config); int probe_ms_sound(struct address_info *hw_config); long attach_pnp_ad1848(long mem_start, struct address_info * hw_config); diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index 612bff38007b..c24ce38d077f 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -481,11 +481,11 @@ tenmicrosec (int *osp) } int -snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *), char *name, int *osp) +snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, void *, struct pt_regs *), char *name, int *osp) { int retcode; - retcode = request_irq (interrupt_level, hndlr, 0 /* SA_INTERRUPT */ , name); + retcode = request_irq (interrupt_level, hndlr, 0 /* SA_INTERRUPT */ , name, NULL); if (retcode < 0) { printk ("Sound: IRQ%d already in use\n", interrupt_level); @@ -500,7 +500,7 @@ void snd_release_irq (int vect) { irqs &= ~(1ul << vect); - free_irq (vect); + free_irq (vect, NULL); } int diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c index 3c72ef21b3b5..4047af6cc88b 100644 --- a/drivers/sound/sscape.c +++ b/drivers/sound/sscape.c @@ -301,7 +301,7 @@ get_board_type (struct sscape_info *devc) } void -sscapeintr (int irq, struct pt_regs *dummy) +sscapeintr (int irq, void *dev_id, struct pt_regs *dummy) { unsigned char bits, tmp; static int debug = 0; @@ -323,7 +323,7 @@ sscapeintr (int irq, struct pt_regs *dummy) #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI) if (bits & 0x01) { - mpuintr (irq, NULL); + mpuintr (irq, NULL, NULL); if (debug++ > 10) /* Temporary debugging hack */ { sscape_write (devc, GA_INTENA_REG, 0x00); /* Disable all interrupts */ diff --git a/drivers/sound/uart6850.c b/drivers/sound/uart6850.c index c169b4681996..4cbc87f3ce7d 100644 --- a/drivers/sound/uart6850.c +++ b/drivers/sound/uart6850.c @@ -109,7 +109,7 @@ uart6850_input_loop (void) } void -m6850intr (int irq, struct pt_regs *dummy) +m6850intr (int irq, void *dev_id, struct pt_regs *dummy) { if (input_avail ()) uart6850_input_loop (); diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 466ce7138765..14bf0a241f39 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c @@ -257,7 +257,7 @@ ncp_msg_data_ready(struct sock *sk, int len) ntohs(sender.sipx_port), packet_buf[0], packet_buf[1]); - ncp_trigger_message(sk->protinfo.ipx.ncp_server); + ncp_trigger_message(sk->protinfo.af_ipx.ncp_server); set_fs(fs); } @@ -306,7 +306,7 @@ ncp_catch_message(struct ncp_server *server) } sk->data_ready = ncp_msg_data_ready; - sk->protinfo.ipx.ncp_server = server; + sk->protinfo.af_ipx.ncp_server = server; return 0; } diff --git a/include/asm-alpha/alcor.h b/include/asm-alpha/alcor.h new file mode 100644 index 000000000000..b152c7c3d173 --- /dev/null +++ b/include/asm-alpha/alcor.h @@ -0,0 +1,407 @@ +#ifndef __ALPHA_ALCOR__H__ +#define __ALPHA_ALCOR__H__ + +#include + +/* + * ALCOR is the internal name for the 2117x chipset which provides + * memory controller and PCI access for the 21164 chip based systems. + * + * This file is based on: + * + * DECchip 21171 Core Logic Chipset + * Technical Reference Manual + * + * EC-QE18B-TE + * + * david.rusling@reo.mts.dec.com Initial Version. + * + */ + +/*------------------------------------------------------------------------** +** ** +** EB164 I/O procedures ** +** ** +** inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers ** +** inportbxt: 8 bits only ** +** inport: alias of inportw ** +** outport: alias of outportw ** +** ** +** inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers ** +** inmembxt: 8 bits only ** +** inmem: alias of inmemw ** +** outmem: alias of outmemw ** +** ** +**------------------------------------------------------------------------*/ + + +/* ALCOR ADDRESS BIT DEFINITIONS + * + * 3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 + * 9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | \_/ \_/ + * | | | + * +-- IO space, not cached. Byte Enable --+ | + * Transfer Length --+ + * + * + * + * Byte Transfer + * Enable Length Transfer Byte Address + * adr<6:5> adr<4:3> Length Enable Adder + * --------------------------------------------- + * 00 00 Byte 1110 0x000 + * 01 00 Byte 1101 0x020 + * 10 00 Byte 1011 0x040 + * 11 00 Byte 0111 0x060 + * + * 00 01 Word 1100 0x008 + * 01 01 Word 1001 0x028 <= Not supported in this code. + * 10 01 Word 0011 0x048 + * + * 00 10 Tribyte 1000 0x010 + * 01 10 Tribyte 0001 0x030 + * + * 10 11 Longword 0000 0x058 + * + * Note that byte enables are asserted low. + * + */ + +#define BYTE_ENABLE_SHIFT 5 +#define TRANSFER_LENGTH_SHIFT 3 +#define MEM_SP1_MASK 0x1fffffff /* Mem sparse space 1 mask is 29 bits */ + + +#define ALCOR_DMA_WIN_BASE (1024UL*1024UL*1024UL) +#define ALCOR_DMA_WIN_SIZE (1024*1024*1024) + +/* + * 21171-CA Control and Status Registers (p4-1) + */ +#define ALCOR_IOC_CIA_REV (IDENT_ADDR + 0x8740000080UL) +#define ALCOR_IOC_PCI_LAT (IDENT_ADDR + 0x87400000C0UL) +#define ALCOR_IOC_CIA_CTRL (IDENT_ADDR + 0x8740000100UL) +#define ALCOR_IOC_HAE_MEM (IDENT_ADDR + 0x8740000400UL) +#define ALCOR_IOC_HAE_IO (IDENT_ADDR + 0x8740000440UL) +#define ALCOR_IOC_CFG (IDENT_ADDR + 0x8740000480UL) +#define ALCOR_IOC_CACK_EN (IDENT_ADDR + 0x8740000600UL) + +/* + * 21171-CA Diagnostic Registers (p4-2) + */ +#define ALCOR_IOC_CIA_DIAG (IDENT_ADDR + 0x8740002000UL) +#define ALCOR_IOC_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL) + +/* + * 21171-CA Performance Monitor registers (p4-3) + */ +#define ALCOR_IOC_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL) +#define ALCOR_IOC_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL) + +/* + * 21171-CA Error registers (p4-3) + */ +#define ALCOR_IOC_CPU_ERR0 (IDENT_ADDR + 0x8740008000UL) +#define ALCOR_IOC_CPU_ERR1 (IDENT_ADDR + 0x8740008040UL) +#define ALCOR_IOC_CIA_ERR (IDENT_ADDR + 0x8740008200UL) +#define ALCOR_IOC_CIA_STAT (IDENT_ADDR + 0x8740008240UL) +#define ALCOR_IOC_ERR_MASK (IDENT_ADDR + 0x8740008280UL) +#define ALCOR_IOC_CIA_SYN (IDENT_ADDR + 0x8740008300UL) +#define ALCOR_IOC_MEM_ERR0 (IDENT_ADDR + 0x8740008400UL) +#define ALCOR_IOC_MEM_ERR1 (IDENT_ADDR + 0x8740008440UL) +#define ALCOR_IOC_PCI_ERR0 (IDENT_ADDR + 0x8740008800UL) +#define ALCOR_IOC_PCI_ERR1 (IDENT_ADDR + 0x8740008840UL) +#define ALCOR_IOC_PCI_ERR3 (IDENT_ADDR + 0x8740008880UL) + +/* + * 2117A-CA PCI Address Translation Registers. I've only defined + * the first window fully as that's the only one that we're currently using. + * The other window bases are needed to disable the windows. + */ +#define ALCOR_IOC_PCI_TBIA (IDENT_ADDR + 0x8760000100UL) +#define ALCOR_IOC_PCI_W0_BASE (IDENT_ADDR + 0x8760000400UL) +#define ALCOR_IOC_PCI_W0_MASK (IDENT_ADDR + 0x8760000440UL) +#define ALCOR_IOC_PCI_T0_BASE (IDENT_ADDR + 0x8760000480UL) + +#define ALCOR_IOC_PCI_W1_BASE (IDENT_ADDR + 0x8760000500UL) +#define ALCOR_IOC_PCI_W2_BASE (IDENT_ADDR + 0x8760000600UL) +#define ALCOR_IOC_PCI_W3_BASE (IDENT_ADDR + 0x8760000700UL) + +/* + * 21171-CA System configuration registers (p4-3) + */ +#define ALCOR_IOC_MCR (IDENT_ADDR + 0x8750000000UL) +#define ALCOR_IOC_MBA0 (IDENT_ADDR + 0x8750000600UL) +#define ALCOR_IOC_MBA2 (IDENT_ADDR + 0x8750000680UL) +#define ALCOR_IOC_MBA4 (IDENT_ADDR + 0x8750000700UL) +#define ALCOR_IOC_MBA6 (IDENT_ADDR + 0x8750000780UL) +#define ALCOR_IOC_MBA8 (IDENT_ADDR + 0x8750000800UL) +#define ALCOR_IOC_MBAA (IDENT_ADDR + 0x8750000880UL) +#define ALCOR_IOC_MBAC (IDENT_ADDR + 0x8750000900UL) +#define ALCOR_IOC_MBAE (IDENT_ADDR + 0x8750000980UL) +#define ALCOR_IOC_TMG0 (IDENT_ADDR + 0x8750000B00UL) +#define ALCOR_IOC_TMG1 (IDENT_ADDR + 0x8750000B40UL) +#define ALCOR_IOC_TMG2 (IDENT_ADDR + 0x8750000B80UL) + +/* + * Memory spaces: + */ +#define ALCOR_IACK_SC (IDENT_ADDR + 0x8720000000UL) +#define ALCOR_CONF (IDENT_ADDR + 0x8700000000UL) +#define ALCOR_IO (IDENT_ADDR + 0x8580000000UL) +#define ALCOR_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL) +#define ALCOR_DENSE_MEM (IDENT_ADDR + 0x8600000000UL) + +/* + * Bit definitions for I/O Controller status register 0: + */ +#define ALCOR_IOC_STAT0_CMD 0xf +#define ALCOR_IOC_STAT0_ERR (1<<4) +#define ALCOR_IOC_STAT0_LOST (1<<5) +#define ALCOR_IOC_STAT0_THIT (1<<6) +#define ALCOR_IOC_STAT0_TREF (1<<7) +#define ALCOR_IOC_STAT0_CODE_SHIFT 8 +#define ALCOR_IOC_STAT0_CODE_MASK 0x7 +#define ALCOR_IOC_STAT0_P_NBR_SHIFT 13 +#define ALCOR_IOC_STAT0_P_NBR_MASK 0x7ffff + +#define HAE_ADDRESS ALCOR_IOC_HAE_MEM + +#ifdef __KERNEL__ + +/* + * Translate physical memory address as seen on (PCI) bus into + * a kernel virtual address and vv. + */ +extern inline unsigned long virt_to_bus(void * address) +{ + return virt_to_phys(address) + ALCOR_DMA_WIN_BASE; +} + +extern inline void * bus_to_virt(unsigned long address) +{ + return phys_to_virt(address - ALCOR_DMA_WIN_BASE); +} + +/* + * I/O functions: + * + * Alcor (the 2117x PCI/memory support chipset for the EV5 (21164) + * series of processors uses a sparse address mapping scheme to + * get at PCI memory and I/O. + */ + +#define vuip volatile unsigned int * + +extern inline unsigned int __inb(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + ALCOR_IO + 0x00); + result >>= (addr & 3) * 8; + return 0xffUL & result; +} + +extern inline void __outb(unsigned char b, unsigned long addr) +{ + unsigned int w; + + asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + ALCOR_IO + 0x00) = w; + mb(); +} + +extern inline unsigned int __inw(unsigned long addr) +{ + long result = *(vuip) ((addr << 5) + ALCOR_IO + 0x08); + result >>= (addr & 3) * 8; + return 0xffffUL & result; +} + +extern inline void __outw(unsigned short b, unsigned long addr) +{ + unsigned int w; + + asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b)); + *(vuip) ((addr << 5) + ALCOR_IO + 0x08) = w; + mb(); +} + +extern inline unsigned int __inl(unsigned long addr) +{ + return *(vuip) ((addr << 5) + ALCOR_IO + 0x18); +} + +extern inline void __outl(unsigned int b, unsigned long addr) +{ + *(vuip) ((addr << 5) + ALCOR_IO + 0x18) = b; + mb(); +} + + +/* + * Memory functions. 64-bit and 32-bit accesses are done through + * dense memory space, everything else through sparse space. + * + * For reading and writing 8 and 16 bit quantities we need to + * go through one of the three sparse address mapping regions + * and use the HAE_MEM CSR to provide some bits of the address. + * The following few routines use only sparse address region 1 + * which gives 1Gbyte of accessible space which relates exactly + * to the amount of PCI memory mapping *into* system address space. + * See p 6-17 of the specification but it looks something like this: + * + * 21164 Address: + * + * 3 2 1 + * 9876543210987654321098765432109876543210 + * 1ZZZZ0.PCI.QW.Address............BBLL + * + * ZZ = SBZ + * BB = Byte offset + * LL = Transfer length + * + * PCI Address: + * + * 3 2 1 + * 10987654321098765432109876543210 + * HHH....PCI.QW.Address........ 00 + * + * HHH = 31:29 HAE_MEM CSR + * + */ + +extern inline unsigned long __readb(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8 ; + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + result = *(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x00) ; + result >>= shift; + return 0xffUL & result; +} + +extern inline unsigned long __readw(unsigned long addr) +{ + unsigned long result, shift, msb; + + shift = (addr & 0x3) * 8; + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + result = *(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x08); + result >>= shift; + return 0xffffUL & result; +} + +extern inline unsigned long __readl(unsigned long addr) +{ + return *(vuip) (addr + ALCOR_DENSE_MEM); +} + +extern inline void __writeb(unsigned char b, unsigned long addr) +{ + unsigned long msb ; + + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + *(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x00) = b * 0x01010101; +} + +extern inline void __writew(unsigned short b, unsigned long addr) +{ + unsigned long msb ; + + msb = addr & 0xE0000000 ; + addr &= MEM_SP1_MASK ; + if (msb != hae.cache) { + set_hae(msb); + } + *(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x08) = b * 0x00010001; +} + +extern inline void __writel(unsigned int b, unsigned long addr) +{ + *(vuip) (addr + ALCOR_DENSE_MEM) = b; +} + +#define inb(port) \ +(__builtin_constant_p((port))?__inb(port):_inb(port)) + +#define outb(x, port) \ +(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port))) + +#define readl(a) __readl((unsigned long)(a)) +#define writel(v,a) __writel((v),(unsigned long)(a)) + +#undef vuip + +extern unsigned long alcor_init (unsigned long mem_start, + unsigned long mem_end); + +#endif /* __KERNEL__ */ + +/* + * Data structure for handling ALCOR machine checks: + */ +struct el_ALCOR_sysdata_mcheck { + u_long coma_gcr; + u_long coma_edsr; + u_long coma_ter; + u_long coma_elar; + u_long coma_ehar; + u_long coma_ldlr; + u_long coma_ldhr; + u_long coma_base0; + u_long coma_base1; + u_long coma_base2; + u_long coma_cnfg0; + u_long coma_cnfg1; + u_long coma_cnfg2; + u_long epic_dcsr; + u_long epic_pear; + u_long epic_sear; + u_long epic_tbr1; + u_long epic_tbr2; + u_long epic_pbr1; + u_long epic_pbr2; + u_long epic_pmr1; + u_long epic_pmr2; + u_long epic_harx1; + u_long epic_harx2; + u_long epic_pmlt; + u_long epic_tag0; + u_long epic_tag1; + u_long epic_tag2; + u_long epic_tag3; + u_long epic_tag4; + u_long epic_tag5; + u_long epic_tag6; + u_long epic_tag7; + u_long epic_data0; + u_long epic_data1; + u_long epic_data2; + u_long epic_data3; + u_long epic_data4; + u_long epic_data5; + u_long epic_data6; + u_long epic_data7; +}; + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ADDR(x) (0x80 | (x)) +#define RTC_ALWAYS_BCD 0 + +#endif /* __ALPHA_ALCOR__H__ */ diff --git a/include/asm-alpha/floppy.h b/include/asm-alpha/floppy.h index a2e50f2d3a06..b0c7b5396453 100644 --- a/include/asm-alpha/floppy.h +++ b/include/asm-alpha/floppy.h @@ -26,8 +26,8 @@ #define fd_cacheflush(addr,size) /* nothing */ #define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ SA_INTERRUPT|SA_SAMPLE_RANDOM, \ - "floppy") -#define fd_free_irq() free_irq(FLOPPY_IRQ); + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); __inline__ void virtual_dma_init(void) { diff --git a/include/asm-alpha/io.h b/include/asm-alpha/io.h index 3716dc0ae27d..bcabf7edd19a 100644 --- a/include/asm-alpha/io.h +++ b/include/asm-alpha/io.h @@ -73,6 +73,8 @@ extern void _sethae (unsigned long addr); /* cached version */ # include /* get chip-specific definitions */ #elif defined(CONFIG_ALPHA_APECS) # include /* get chip-specific definitions */ +#elif defined(CONFIG_ALPHA_ALCOR) +# include /* get chip-specific definitions */ #else # include #endif diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h index 97663c59ccf2..98d1b6c0a41f 100644 --- a/include/asm-alpha/irq.h +++ b/include/asm-alpha/irq.h @@ -10,7 +10,7 @@ #include #include -#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) +#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || defined(CONFIG_ALPHA_EB164) # define NR_IRQS 33 #elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P) # define NR_IRQS 32 diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h index 5a3707b50a79..6279dfe7105a 100644 --- a/include/asm-alpha/mmu_context.h +++ b/include/asm-alpha/mmu_context.h @@ -32,7 +32,7 @@ * work correctly and can thus not be used (explaining the lack of PAL-code * support). */ -#ifdef CONFIG_EV5 +#ifdef CONFIG_ALPHA_EV5 #define MAX_ASN 127 #else #define MAX_ASN 63 @@ -55,26 +55,28 @@ */ extern inline void get_mmu_context(struct task_struct *p) { -#ifdef CONFIG_EV5 +#ifdef CONFIG_ALPHA_EV5 static unsigned long asn_cache = ASN_FIRST_VERSION; struct mm_struct * mm = p->mm; - unsigned long asn = mm->context; - /* Check if our ASN is of an older version and thus invalid */ - if ((asn_cache ^ asn) & ASN_VERSION_MASK) { - /* get a new asn of the current version */ - asn = asn_cache++; - /* check if it's legal.. */ - if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) { - /* start a new version, invalidate all old asn's */ - tbiap(); imb(); - asn_cache = (asn_cache & ASN_VERSION_MASK) + ASN_FIRST_VERSION; - if (!asn_cache) - asn_cache = ASN_FIRST_VERSION; + if (mm) { + unsigned long asn = mm->context; + /* Check if our ASN is of an older version and thus invalid */ + if ((asn_cache ^ asn) & ASN_VERSION_MASK) { + /* get a new asn of the current version */ asn = asn_cache++; + /* check if it's legal.. */ + if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) { + /* start a new version, invalidate all old asn's */ + tbiap(); imb(); + asn_cache = (asn_cache & ASN_VERSION_MASK) + ASN_FIRST_VERSION; + if (!asn_cache) + asn_cache = ASN_FIRST_VERSION; + asn = asn_cache++; + } + mm->context = asn; /* full version + asn */ + p->tss.asn = asn & ~ASN_VERSION_MASK; /* just asn */ } - mm->context = asn; /* full version + asn */ - p->tss.asn = asn & ~ASN_VERSION_MASK; /* just asn */ } #endif } diff --git a/include/asm-alpha/signal.h b/include/asm-alpha/signal.h index 8dab8aa82316..ecccdd3e8811 100644 --- a/include/asm-alpha/signal.h +++ b/include/asm-alpha/signal.h @@ -53,6 +53,7 @@ typedef unsigned long sigset_t; /* at least 32 bits */ * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_NOCLDSTOP 0x00000004 @@ -61,6 +62,7 @@ typedef unsigned long sigset_t; /* at least 32 bits */ #define SA_INTERRUPT 0x20000000 #define SA_NOMASK 0x00000008 #define SA_ONESHOT 0x00000010 +#define SA_SHIRQ 0x00000020 #ifdef __KERNEL__ /* diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index 53459b7827fe..2da5189572b1 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h @@ -52,13 +52,13 @@ extern void wrmces (unsigned long); #define halt() __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_halt) : "memory") -extern void alpha_switch_to(unsigned long pctxp); - #define switch_to(p) do { \ current_set[0] = p; \ alpha_switch_to((unsigned long) &(p)->tss - 0xfffffc0000000000); \ } while (0) +extern void alpha_switch_to(unsigned long pctxp); + extern void imb(void); #define mb() \ diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h index 93c58fea362e..f291c4d3b465 100644 --- a/include/asm-i386/floppy.h +++ b/include/asm-i386/floppy.h @@ -26,8 +26,8 @@ #define fd_cacheflush(addr,size) /* nothing */ #define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ SA_INTERRUPT|SA_SAMPLE_RANDOM, \ - "floppy") -#define fd_free_irq() free_irq(FLOPPY_IRQ); + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); __inline__ void virtual_dma_init(void) { diff --git a/include/asm-i386/signal.h b/include/asm-i386/signal.h index b37613febfd3..c68928cd7b5a 100644 --- a/include/asm-i386/signal.h +++ b/include/asm-i386/signal.h @@ -50,8 +50,10 @@ typedef unsigned long sigset_t; /* at least 32 bits */ * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_NOCLDSTOP 1 +#define SA_SHIRQ 0x04000000 #define SA_STACK 0x08000000 #define SA_RESTART 0x10000000 #define SA_INTERRUPT 0x20000000 diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 8f3706a65b36..e89dae7626a1 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h @@ -173,18 +173,20 @@ extern struct cpuinfo_x86 cpu_data[NR_CPUS]; * Private routines/data */ +extern int smp_found_config; extern void smp_scan_config(unsigned long, unsigned long); extern unsigned long smp_alloc_memory(unsigned long mem_base); extern unsigned char *apic_reg; extern unsigned char *kernel_stacks[NR_CPUS]; extern unsigned char boot_cpu_id; extern unsigned long cpu_present_map; +extern volatile int cpu_number_map[NR_CPUS]; extern volatile unsigned long smp_invalidate_needed; extern void smp_invalidate(void); extern volatile unsigned long kernel_flag, kernel_counter; extern volatile unsigned char active_kernel_processor; -extern void smp_message_irq(int cpl, struct pt_regs *regs); -extern void smp_reschedule_irq(int cpl, struct pt_regs *regs); +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); +extern void smp_reschedule_irq(int cpl, void *dev_id, struct pt_regs *regs); extern unsigned long ipi_count; extern void smp_invalidate_rcv(void); /* Process an NMI */ extern volatile unsigned long kernel_counter; diff --git a/include/asm-mips/floppy.h b/include/asm-mips/floppy.h index cae3b112a321..31e704244ebb 100644 --- a/include/asm-mips/floppy.h +++ b/include/asm-mips/floppy.h @@ -33,8 +33,8 @@ #define fd_cacheflush(addr, size) feature->fd_cacheflush((void *)addr, size) #define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \ SA_INTERRUPT|SA_SAMPLE_RANDOM, \ - "floppy") -#define fd_free_irq() free_irq(FLOPPY_IRQ); + "floppy", NULL) +#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL); #define MAX_BUFFER_SECTORS 24 #define virtual_dma_init() \ diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index 50e6447a48d0..8c1b51f2bc32 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h @@ -66,6 +66,7 @@ typedef struct { * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_STACK 0x1 #define SA_ONSTACK SA_STACK @@ -75,6 +76,7 @@ typedef struct { #define SA_INTERRUPT 0x01000000 #define SA_NOMASK 0x02000000 #define SA_ONESHOT 0x04000000 +#define SA_SHIRQ 0x08000000 #ifdef __KERNEL__ /* diff --git a/include/asm-ppc/signal.h b/include/asm-ppc/signal.h index 9e7c9f49eba7..e4a8500c59a1 100644 --- a/include/asm-ppc/signal.h +++ b/include/asm-ppc/signal.h @@ -50,8 +50,10 @@ typedef unsigned long sigset_t; /* at least 32 bits */ * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_NOCLDSTOP 1 +#define SA_SHIRQ 0x04000000 #define SA_STACK 0x08000000 #define SA_RESTART 0x10000000 #define SA_INTERRUPT 0x20000000 diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h index e707a12ab170..3b59621a27f1 100644 --- a/include/asm-sparc/floppy.h +++ b/include/asm-sparc/floppy.h @@ -250,7 +250,7 @@ static inline void sun_fd_enable_dma(void) } /* Our low-level entry point in arch/sparc/kernel/entry.S */ -extern void floppy_hardint(int irq, struct pt_regs *regs); +extern void floppy_hardint(int irq, void *dev_id, struct pt_regs *regs); static int sun_fd_request_irq(void) { @@ -259,7 +259,7 @@ static int sun_fd_request_irq(void) if(!once) { once = 1; - error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, SA_INTERRUPT, "floppy"); + error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, SA_INTERRUPT, "floppy", NULL); return ((error == 0) ? 0 : -1); } else return 0; } diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h index eb98cd8ba012..16214ae72e4c 100644 --- a/include/asm-sparc/signal.h +++ b/include/asm-sparc/signal.h @@ -98,6 +98,7 @@ struct sigstack { * the changes in signal handling. LBT 010493. * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the * SA_RESTART flag to get restarting signals (which were the default long ago) + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. */ #define SA_NOCLDSTOP SV_IGNCHILD #define SA_STACK SV_SSTACK @@ -105,6 +106,7 @@ struct sigstack { #define SA_INTERRUPT SV_INTR #define SA_NOMASK 0x10 #define SA_ONESHOT 0x20 +#define SA_SHIRQ 0x40 #define SIG_BLOCK 0x00 /* for blocking signals */ #define SIG_UNBLOCK 0x40 /* for unblocking signals */ diff --git a/include/linux/atalk.h b/include/linux/atalk.h index 08760cdacef1..b5234136871e 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h @@ -94,9 +94,9 @@ struct ddpehdr struct ddpshdr { /* FIXME for bigendians */ - __u8 dsh_sport; - __u8 dsh_dport; __u16 dsh_len:10, dsh_pad:6; + __u8 dsh_dport; + __u8 dsh_sport; /* And netatalk apps expect to stick the type in themselves */ }; diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 2318dfbe63e6..75d1dd598c58 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -66,4 +66,12 @@ struct gendisk { extern struct gendisk *gendisk_head; /* linked list of disks */ +/* + * disk_name() is used by genhd.c and md.c. + * It formats the devicename of the indicated disk + * into the supplied buffer, and returns a pointer + * to that same buffer (for convenience). + */ +char *disk_name (struct gendisk *hd, int minor, char *buf); + #endif diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index fa350688f7c8..e107ae1d28ea 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -44,6 +44,7 @@ #define ARPHRD_FRAD 770 /* Frame Relay */ #define ARPHRD_SKIP 771 /* SKIP vif */ #define ARPHRD_LOOPBACK 772 /* Loopback device */ +#define ARPHRD_LOCALTLK 773 /* Localtalk device */ /* ARP protocol opcodes. */ #define ARPOP_REQUEST 1 /* ARP request */ diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 140784727200..3b9f60e43939 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -50,6 +50,11 @@ #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ #define ETH_P_IPX 0x8137 /* IPX over DIX */ #define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ + +/* + * Non DIX types. Won't clash for 1500 types. + */ + #define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ #define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ #define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ @@ -58,6 +63,7 @@ #define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ #define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ #define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ +#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudeo type */ /* This is an Ethernet frame header. */ struct ethhdr { diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index a20cbe8ee425..b18a04c3376e 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -5,6 +5,16 @@ #include #include +struct irqaction { + void (*handler)(int, void *, struct pt_regs *); + unsigned long flags; + unsigned long mask; + const char *name; + void *dev_id; + struct irqaction *next; +}; + + struct bh_struct { void (*routine)(void *); void *data; diff --git a/include/linux/sched.h b/include/linux/sched.h index 7eceb1f8dd47..baf6156c5edd 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -342,9 +342,12 @@ extern void notify_parent(struct task_struct * tsk); extern int send_sig(unsigned long sig,struct task_struct * p,int priv); extern int in_group_p(gid_t grp); -extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *), - unsigned long flags, const char *device); -extern void free_irq(unsigned int irq); +extern int request_irq(unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, + const char *device, + void *dev_id); +extern void free_irq(unsigned int irq, void *dev_id); extern void copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); extern void flush_thread(void); diff --git a/include/linux/xd.h b/include/linux/xd.h index 4222fcb71aed..45cce2e78fc1 100644 --- a/include/linux/xd.h +++ b/include/linux/xd.h @@ -117,7 +117,7 @@ static int xd_reread_partitions (kdev_t dev); static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count); static void xd_recalibrate (u_char drive); -static void xd_interrupt_handler (int irq, struct pt_regs * regs); +static void xd_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs); static u_char xd_setup_dma (u_char opcode,u_char *buffer,u_int count); static u_char *xd_build (u_char *cmdblk,u_char command,u_char drive,u_char head,u_short cylinder,u_char sector,u_char count,u_char control); static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout); diff --git a/init/main.c b/init/main.c index 0969d5b6a10c..befbdf85f653 100644 --- a/init/main.c +++ b/init/main.c @@ -568,18 +568,25 @@ static void smp_init(void) * Create the slave init tasks as sharing pid 0. */ - for(i=1;iprocessor=i; + if (cpu_number_map[i] > 0) + { + /* + * We use kernel_thread for the idlers which are + * unlocked tasks running in kernel space. + */ + kernel_thread(cpu_idle, NULL, CLONE_PID); + /* + * Don't assume linear processor numbering + */ + current_set[i]=task[cpu_number_map[i]]; + current_set[i]->processor=i; + } } } diff --git a/kernel/sys.c b/kernel/sys.c index 8bb0746f89a9..ebd5bcebc1a8 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -420,7 +420,7 @@ asmlinkage int sys_setfsgid(gid_t gid) return old_fsgid; } -asmlinkage int sys_times(struct tms * tbuf) +asmlinkage long sys_times(struct tms * tbuf) { if (tbuf) { int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf); diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 2abdb02b5b1b..11cf18be6461 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -431,6 +431,47 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo struct aarp_entry *a; unsigned long flags; + /* + * Check for localtalk first + */ + + if(dev->type==ARPHRD_LOCALTLK) + { + struct at_addr *at=atalk_find_dev_addr(dev); + int ft=2; + + /* + * Compressable ? + */ + + if(at->s_net==sa->s_net) + { + skb_pull(skb,sizeof(struct ddpehdr)-4); + /* + * The uper two remaining bytes are the port + * numbers we just happen to need. Now put the + * length in the lower two. + */ + *((__u16 *)skb->data)=htons(skb->len); + ft=1; + } + /* + * Nice and easy. No AARP type protocols occur here + * so we can just shovel it out with a 3 byte LLAP header + */ + + skb_push(skb,3); + skb->data[0]=sa->s_node; + skb->data[1]=at->s_node; + skb->data[2]=ft; + + if(skb->sk==NULL) + dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL); + else + dev_queue_xmit(skb, skb->dev, skb->sk->priority); + return 1; + } + /* * Non ELAP we cannot do. */ diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index aec03e0a16ab..c90ba9932cd1 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -18,6 +18,7 @@ * socket. * Alan Cox : Added firewall hooks. * Alan Cox : Supports new ARPHRD_LOOPBACK + * Christer Weinigel : Routing and /proc fixes. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -62,7 +63,7 @@ #ifdef CONFIG_ATALK -#define APPLETALK_DEBUG +#undef APPLETALK_DEBUG #ifdef APPLETALK_DEBUG @@ -247,9 +248,13 @@ int atalk_get_info(char *buffer, char **start, off_t offset, int length, int dum { len += sprintf (buffer+len,"%02X ", s->type); len += sprintf (buffer+len,"%04X:%02X:%02X ", - s->protinfo.af_at.src_net,s->protinfo.af_at.src_node,s->protinfo.af_at.src_port); + ntohs(s->protinfo.af_at.src_net), + s->protinfo.af_at.src_node, + s->protinfo.af_at.src_port); len += sprintf (buffer+len,"%04X:%02X:%02X ", - s->protinfo.af_at.dest_net,s->protinfo.af_at.dest_node,s->protinfo.af_at.dest_port); + ntohs(s->protinfo.af_at.dest_net), + s->protinfo.af_at.dest_node, + s->protinfo.af_at.dest_port); len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc); len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid); @@ -715,10 +720,16 @@ int atif_ioctl(int cmd, void *arg) return -EPERM; if(sa->sat_family!=AF_APPLETALK) return -EINVAL; - if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK) + if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK + &&dev->type!=ARPHRD_LOCALTLK) return -EPROTONOSUPPORT; nr=(struct netrange *)&sa->sat_zero[0]; - if(nr->nr_phase!=2) + /* + * Phase 1 is fine on localtalk but we don't + * do Ethertalk phase 1. Anyone wanting to add + * it go ahead. + */ + if(dev->type==ARPHRD_ETHER && nr->nr_phase!=2) return -EPROTONOSUPPORT; if(sa->sat_addr.s_node==ATADDR_BCAST || sa->sat_addr.s_node == 254) return -EINVAL; @@ -882,13 +893,13 @@ int atalk_rt_get_info(char *buffer, char **start, off_t offset, int length, int if(atrtr_default.dev) { rt=&atrtr_default; - len += sprintf (buffer+len,"Default %5d:%-3d %-4d %s\n", + len += sprintf (buffer+len,"Default %04X:%02X %-4d %s\n", ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags, rt->dev->name); } for (rt = atalk_router_list; rt != NULL; rt = rt->next) { - len += sprintf (buffer+len,"%04X:%02X %5d:%-3d %-4d %s\n", + len += sprintf (buffer+len,"%04X:%02X %04X:%02X %-4d %s\n", ntohs(rt->target.s_net),rt->target.s_node, ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags, rt->dev->name); @@ -1360,7 +1371,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, * extracted. */ -int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) +static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { atalk_socket *sock; struct ddpehdr *ddp=(void *)skb->h.raw; @@ -1470,6 +1481,17 @@ int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) } ddp->deh_hops++; + /* + * Route goes through another gateway, so + * set the target to the gateway instead. + */ + + if(rt->flags&RTF_GATEWAY) + { + ta.s_net = rt->gateway.s_net; + ta.s_node = rt->gateway.s_node; + } + /* Fix up skb->len field */ skb_trim(skb,min(origlen, rt->dev->hard_header_len + ddp_dl->header_length + ddp->deh_len)); @@ -1478,6 +1500,9 @@ int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) /* * Send the buffer onwards */ + + skb->arp = 1; /* Resolved */ + if(aarp_send_ddp(rt->dev, skb, &ta, NULL)==-1) kfree_skb(skb, FREE_READ); return 0; @@ -1512,6 +1537,69 @@ int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) return(0); } +/* + * Receive a localtalk frame. We make some demands on the caller here. + * Caller must provide enough headroom on the packet to pull the short + * header and append a long one. + */ + + +static int ltalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) +{ + struct ddpehdr *ddp; + struct at_addr *ap; + /* + * Expand any short form frames. + */ + + if(skb->mac.raw[2]==1) + { + /* + * Find our address. + */ + + ap=atalk_find_dev_addr(dev); + if(ap==NULL || skb->lendata; + + /* + * Now fill in the long header. + */ + + /* + * These two first. The mac overlays the new source/dest + * network information so we MUST copy these before + * we write the network numbers ! + */ + + ddp->deh_dnode=skb->mac.raw[0]; /* From physical header */ + ddp->deh_snode=skb->mac.raw[1]; /* From physical header */ + + ddp->deh_dnet=ap->s_net; /* Network number */ + ddp->deh_snet=ap->s_net; + ddp->deh_sum=0; /* No checksum */ + /* + * Not sure about this bit... + */ + ddp->deh_len=skb->len; + ddp->deh_hops=15; /* Non routable, so force a drop + if we slip up later */ + *((__u16 *)ddp)=htons(*((__u16 *)ddp)); /* Mend the byte order */ + } + return atalk_rcv(skb,dev,pt); +} + static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags) { atalk_socket *sk=(atalk_socket *)sock->data; @@ -1875,6 +1963,15 @@ static struct notifier_block ddp_notifier={ 0 }; +struct packet_type ltalk_packet_type= +{ + 0, + NULL, + ltalk_rcv, + NULL, + NULL +}; + /* Called by proto.c on kernel start up */ void atalk_proto_init(struct net_proto *pro) @@ -1883,6 +1980,10 @@ void atalk_proto_init(struct net_proto *pro) (void) sock_register(atalk_proto_ops.family, &atalk_proto_ops); if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL) printk("Unable to register DDP with SNAP.\n"); + + ltalk_packet_type.type=htons(ETH_P_LOCALTALK); + dev_add_pack(<alk_packet_type); + register_netdevice_notifier(&ddp_notifier); aarp_proto_init(); @@ -1905,6 +2006,6 @@ void atalk_proto_init(struct net_proto *pro) atalk_if_get_info }); - printk("Appletalk 0.14 for Linux NET3.032\n"); + printk("Appletalk 0.16 for Linux NET3.033\n"); } #endif diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index cf345c3637a5..44cb9ab7f6bc 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -28,7 +28,8 @@ * Alan Cox : MAC layer pointers/new format. * Paul Gortmaker : eth_copy_and_sum shouldn't csum padding. * Alan Cox : Protect against forwarding explosions with - * older network drivers and IFF_ALLMULTI + * older network drivers and IFF_ALLMULTI. + * Christer Weinigel : Better rebuild header message. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -147,7 +148,7 @@ int eth_rebuild_header(void *buff, struct device *dev, unsigned long dst, if(eth->h_proto != htons(ETH_P_IP)) { - printk("eth_rebuild_header: Don't know how to resolve type %d addresses?\n",(int)eth->h_proto); + printk(KERN_DEBUG "%s: unable to resolve type %X addresses.\n",dev->name,(int)eth->h_proto); memcpy(eth->h_source, dev->dev_addr, dev->addr_len); return 0; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e3cd375713c1..387e0f2a8bcd 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -863,7 +863,7 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr, /* * Allow only if both are setting reuse. */ - if(sk2->reuse && sk->reuse) + if(sk2->reuse && sk->reuse && sk2->state!=TCP_LISTEN) continue; sti(); return(-EADDRINUSE); diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 82491b9454de..0248d5d91c5c 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -402,9 +402,9 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, struct devi * are needed for AMPRnet AX.25 paths. */ else if (old_mtu > 216) - old_mtu = 216; + new_mtu = 216; else if (old_mtu > 128) - old_mtu = 128; + new_mtu = 128; else /* * Despair.. diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 77257ff7a2ac..ce7bc6ef4fa5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -902,7 +902,7 @@ int rt_cache_get_info(char *buffer, char **start, off_t offset, int length, int if (offset<128) { - sprintf(buffer,"%-127s\n","Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tHH\tARP\n"); + sprintf(buffer,"%-127s\n","Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tHH\tARP"); len = 128; } diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 6c833750e8ab..37097b82a625 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -1385,7 +1385,7 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, #ifdef CONFIG_IPX_INTERN len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", - htonl(s->ipx_intrfc->if_netnum), + htonl(s->protinfo.af_ipx.intrfc->if_netnum), s->protinfo.af_ipx.node[0], s->protinfo.af_ipx.node[1], s->protinfo.af_ipx.node[2], diff --git a/scripts/lxdialog/checklist.c b/scripts/lxdialog/checklist.c index 8dea2bd8131e..b79535fe03c7 100644 --- a/scripts/lxdialog/checklist.c +++ b/scripts/lxdialog/checklist.c @@ -113,8 +113,7 @@ print_buttons( WINDOW *dialog, int height, int width, int okval, int cancelval) */ int dialog_checklist (const char *title, const char *prompt, int height, int width, - int list_height, int item_no, const char * const * items, int flag, - int separate_output) + int list_height, int item_no, const char * const * items, int flag) { int i, x, y, cur_x, cur_y, box_x, box_y; int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; diff --git a/scripts/tkgen.c b/scripts/tkgen.c index 4da2e2178714..d89314584b9a 100644 --- a/scripts/tkgen.c +++ b/scripts/tkgen.c @@ -922,10 +922,10 @@ dump_tk_script(struct kconfig *scfg) { if(cfg->tok == tok_dep_tristate) { - printf("\tif {$%s == 2 } then {\n" + printf("\tif {$%s == 0 } then {\n" "\t\twrite_variable $cfg $autocfg %s $notset $notmod\n" "\t} else {\n" - "\t\twrite_variable $cfg $autocfg %s $%s %s\n" + "\t\twrite_variable $cfg $autocfg %s $%s $%s\n" "\t}\n", cfg->depend.str, cfg->optionname, -- 2.39.5