summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/Configure.help10
-rw-r--r--Documentation/DocBook/Makefile1
-rw-r--r--Documentation/DocBook/kernel-api.tmpl5
-rw-r--r--Documentation/i386/boot.txt36
-rw-r--r--Documentation/kernel-parameters.txt20
-rw-r--r--Makefile6
-rw-r--r--README47
-rw-r--r--arch/alpha/kernel/smp.c25
-rw-r--r--arch/ia64/kernel/smp.c26
-rw-r--r--arch/mips/defconfig-cobalt2
-rw-r--r--arch/mips/defconfig-orion2
-rw-r--r--arch/mips/defconfig-rm2002
-rw-r--r--arch/mips64/defconfig2
-rw-r--r--arch/mips64/defconfig-ip222
-rw-r--r--arch/mips64/defconfig-ip272
-rw-r--r--arch/sparc/defconfig6
-rw-r--r--arch/sparc/kernel/irq.c2
-rw-r--r--arch/sparc/kernel/sun4d_irq.c2
-rw-r--r--arch/sparc/kernel/sun4d_smp.c27
-rw-r--r--arch/sparc/kernel/sun4m_smp.c27
-rw-r--r--arch/sparc/math-emu/Makefile2
-rw-r--r--arch/sparc64/Makefile4
-rw-r--r--arch/sparc64/defconfig6
-rw-r--r--arch/sparc64/kernel/ioctl32.c2
-rw-r--r--arch/sparc64/kernel/setup.c4
-rw-r--r--arch/sparc64/kernel/smp.c30
-rw-r--r--arch/sparc64/math-emu/Makefile3
-rw-r--r--arch/sparc64/solaris/socksys.c2
-rw-r--r--drivers/block/linear.c2
-rw-r--r--drivers/block/ll_rw_blk.c193
-rw-r--r--drivers/block/md.c64
-rw-r--r--drivers/block/raid0.c4
-rw-r--r--drivers/block/raid1.c5
-rw-r--r--drivers/block/raid5.c2
-rw-r--r--drivers/char/Config.in11
-rw-r--r--drivers/char/drm/Makefile114
-rw-r--r--drivers/char/drm/auth.c2
-rw-r--r--drivers/char/drm/bufs.c2
-rw-r--r--drivers/char/drm/drmP.h18
-rw-r--r--drivers/char/drm/ffb_drv.c5
-rw-r--r--drivers/char/drm/gamma_drv.c26
-rw-r--r--drivers/char/drm/gamma_drv.h2
-rw-r--r--drivers/char/drm/i810_drv.c16
-rw-r--r--drivers/char/drm/i810_drv.h2
-rw-r--r--drivers/char/drm/memory.c2
-rw-r--r--drivers/char/drm/mga_drv.c14
-rw-r--r--drivers/char/drm/mga_drv.h2
-rw-r--r--drivers/char/drm/proc.c6
-rw-r--r--drivers/char/drm/r128_bufs.c4
-rw-r--r--drivers/char/drm/r128_drv.c24
-rw-r--r--drivers/char/drm/r128_drv.h2
-rw-r--r--drivers/char/drm/tdfx_drv.c31
-rw-r--r--drivers/char/drm/tdfx_drv.h2
-rw-r--r--drivers/char/drm/vm.c2
-rw-r--r--drivers/ide/cmd64x.c65
-rw-r--r--drivers/ide/hpt366.c24
-rw-r--r--drivers/ide/ide-dma.c14
-rw-r--r--drivers/ide/ide-features.c4
-rw-r--r--drivers/ide/ide-pci.c4
-rw-r--r--drivers/ide/ide-tape.c4
-rw-r--r--drivers/ide/ide.c35
-rw-r--r--drivers/ide/pdc202xx.c102
-rw-r--r--drivers/pci/pci.ids1
-rw-r--r--drivers/pcmcia/yenta.c2
-rw-r--r--drivers/usb/uhci.c58
-rw-r--r--drivers/usb/usb-ohci.c504
-rw-r--r--drivers/video/atyfb.c2
-rw-r--r--drivers/video/cgsixfb.c2
-rw-r--r--drivers/video/creatorfb.c2
-rw-r--r--drivers/video/leofb.c2
-rw-r--r--drivers/video/promcon.c2
-rw-r--r--fs/buffer.c8
-rw-r--r--fs/dcache.c54
-rw-r--r--fs/dquot.c9
-rw-r--r--fs/ext2/super.c1
-rw-r--r--fs/file_table.c19
-rw-r--r--fs/namei.c17
-rw-r--r--fs/openpromfs/inode.c2
-rw-r--r--include/asm-i386/bitops.h4
-rw-r--r--include/asm-sparc/audioio.h2
-rw-r--r--include/asm-sparc64/audioio.h2
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/fs.h5
-rw-r--r--include/linux/hdreg.h8
-rw-r--r--include/linux/ide.h2
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/raid/md_k.h3
-rw-r--r--include/linux/slab.h4
-rw-r--r--init/main.c5
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/fork.c14
-rw-r--r--mm/highmem.c2
92 files changed, 1082 insertions, 772 deletions
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index fddcc41f9..a5fa3b1d4 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -898,7 +898,7 @@ PROMISE PDC20246/PDC20262/PDC20267 support
CONFIG_BLK_DEV_PDC202XX
Promise Ultra33 or PDC20246
Promise Ultra66 or PDC20262
- Promise Ultra100 or PDC20267
+ Promise Ultra100 or PDC20265/PDC20267
This driver adds up to 4 more EIDE devices sharing a single
interrupt. This add-on card is a bootable PCI UDMA controller. Since
@@ -918,11 +918,11 @@ CONFIG_BLK_DEV_PDC202XX
Special UDMA Feature (EXPERIMENTAL)
CONFIG_PDC202XX_BURST
- For PDC20246, PDC20262 and PDC20267 Ultra DMA chipsets. Designed
- originally for PDC20246/Ultra33 that has BIOS setup failures when
- using 3 or more cards.
+ For PDC20246, PDC20262, PDC20265 and PDC20267 Ultra DMA chipsets.
+ Designed originally for PDC20246/Ultra33 that has BIOS setup
+ failures when using 3 or more cards.
- Unknown for PDC20267 Ultra DMA 100.
+ Unknown for PDC20265/PDC20267 Ultra DMA 100.
Please read the comments at the top of drivers/ide/pdc202xx.c
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 06a613ed1..39e5f8813 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -67,6 +67,7 @@ APISOURCES := $(TOPDIR)/drivers/char/videodev.c \
$(TOPDIR)/drivers/net/8390.c \
$(TOPDIR)/drivers/char/serial.c \
$(TOPDIR)/drivers/pci/pci.c \
+ $(TOPDIR)/drivers/block/ll_rw_blk.c \
$(TOPDIR)/drivers/sound/sound_core.c \
$(TOPDIR)/drivers/sound/sound_firmware.c \
$(TOPDIR)/drivers/net/wan/syncppp.c \
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 268a9ddc9..c5d7ca3fc 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -125,6 +125,11 @@
!Ekernel/pm.c
</chapter>
+ <chapter id="blkdev">
+ <title>Block Devices</title>
+!Edrivers/block/ll_rw_blk.c
+ </chapter>
+
<chapter id="miscdev">
<title>Miscellaneous Devices</title>
!Edrivers/char/misc.c
diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt
index 1622e4af3..8b466cde2 100644
--- a/Documentation/i386/boot.txt
+++ b/Documentation/i386/boot.txt
@@ -2,7 +2,7 @@
----------------------------
H. Peter Anvin <hpa@zytor.com>
- Updated as of protocol version 2.02
+ Last update 2000-07-27
On the i386 platform, the Linux kernel uses a rather complicated boot
convention. This has evolved partially due to historical aspects, as
@@ -98,7 +98,7 @@ sectors (1K) and then examine the bootup sector size.
The header looks like:
Offset Proto Name Meaning
-Size
+/Size
01F1/1 ALL setup_sects The size of the setup in sectors
01F2/2 ALL root_flags If set, the root is mounted readonly
@@ -120,7 +120,7 @@ Size
0218/4 2.00+ ramdisk_image initrd load address (set by boot loader)
021C/4 2.00+ ramdisk_size initrd size (set by boot loader)
0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only
-0224/4 2.01+ heap_end_ptr Free memory after setup end
+0224/2 2.01+ heap_end_ptr Free memory after setup end
0226/2 N/A pad1 Unused
0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line
@@ -267,8 +267,8 @@ Such a boot loader should enter the following fields in the header:
}
/* It is recommended to clear memory up to the 32K mark */
- memset(0x90000 + (setup_sects-1)*512, 0,
- (64-setup_sects-1)*512);
+ memset(0x90000 + (setup_sects+1)*512, 0,
+ (64-(setup_sects+1))*512);
}
@@ -296,7 +296,11 @@ much a requirement for these kernels to load the real-mode part at
If the command line provided by the boot loader is entered by the
user, the user may expect the following command line options to work.
They should normally not be deleted from the kernel command line even
-though not all of them are actually meaningful to the kernel.
+though not all of them are actually meaningful to the kernel. Boot
+loader authors who need additional command line options for the boot
+loader itself should get them registered in
+linux/Documentation/kernel-parameters.txt to make sure they will not
+conflict with actual kernel options now or in the future.
vga=<mode>
<mode> here is either an integer (in C notation, either
@@ -311,11 +315,13 @@ though not all of them are actually meaningful to the kernel.
or G (meaning << 10, << 20 or << 30). This specifies to the
kernel the memory size. This affects the possible placement
of an initrd, since an initrd should be placed near end of
- memory.
+ memory. Note that this is an option to *both* the kernel and
+ the bootloader!
initrd=<file>
An initrd should be loaded. The meaning of <file> is
- obviously bootloader-dependent.
+ obviously bootloader-dependent, and some boot loaders
+ (e.g. LILO) do not have such a command.
In addition, some boot loaders add the following options to the
user-specified command line:
@@ -340,10 +346,14 @@ located at *segment* offset 0x20 from the start of the real mode
kernel. This means that if you loaded your real-mode kernel code at
0x90000, the kernel entry point is 9020:0000.
-At entry, ds = es = ss = fs = gs should point to the start of the
-real-mode kernel code (0x9000 if the code is loaded at 0x90000), and
-sp should be set up properly, normally pointing to the top of the
-heap. In our example from above, we would do:
+At entry, ds = es = ss should point to the start of the real-mode
+kernel code (0x9000 if the code is loaded at 0x90000), sp should be
+set up properly, normally pointing to the top of the heap, and
+interrupts should be disabled. Furthermore, to guard against bugs in
+the kernel, it is recommended that the boot loader sets fs = gs = ds =
+es = ss.
+
+In our example from above, we would do:
/* Note: in the case of the "old" kernel protocol, base_ptr must
be == 0x90000 at this point; see the previous sample code */
@@ -354,7 +364,7 @@ heap. In our example from above, we would do:
/* Set up the real-mode kernel stack */
_SS = seg;
- _SP = 0x9000; /* Load SP right after loading SS! */
+ _SP = 0x9000; /* Load SP immediately after loading SS! */
_DS = _ES = _FS = _GS = seg;
jmp_far(seg+0x20, 0); /* Run the kernel */
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 86d716ed3..42f894248 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -49,6 +49,10 @@ In addition, the following text indicates that the option:
BUGS= Relates to possible processor bugs on the said processor.
KNL Is a kernel start-up parameter.
+ BOOT Is a boot loader parameter.
+
+Parameters denoted with BOOT are actually interpreted by the boot
+loader, and have no meaning to the kernel directly.
Note that ALL kernel parameters listed below are CASE SENSITIVE, and that
a trailing = on the name of any parameter states that that parameter will
@@ -228,6 +232,8 @@ running once the system is up.
init= [KNL]
+ initrd= [BOOT] Specify the location of the initial ramdisk.
+
ip= [PNP]
isp16= [HW,CD]
@@ -292,11 +298,12 @@ running once the system is up.
megaraid= [HW,SCSI]
- mem= [KNL] force use XX Mb of memory when the kernel is not
- able to see the whole system memory or for test.
+ mem=nn[KMG] [KNL,BOOT] force use of a specific amount of
+ memory; to be used when the kernel is not able
+ to see the whole system memory or for test.
memfrac= [KNL]
-
+
mga= [HW,DRM]
mpu401= [HW,SOUND]
@@ -512,8 +519,11 @@ running once the system is up.
video= [FB] frame buffer configuration.
- vga= [KNL] on ix386, enable to choose a peculiar video mode
- (use vga=ask for menu).
+ vga= [BOOT] on ix386, select a particular video mode
+ (use vga=ask for menu). This is actually a
+ boot loader parameter; the value is passed to
+ the kernel using a special protocol. See
+ linux/Documentation/i386/boot.txt for information.
vmhalt= [KNL,S390]
diff --git a/Makefile b/Makefile
index 46961707b..7fb487e7e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 0
-EXTRAVERSION = -test5-pre6
+EXTRAVERSION = -test5
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
@@ -306,13 +306,15 @@ $(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h include/config/MARKE
modules_install:
@( \
MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE); \
+ mkdir -p $$MODLIB; \
+ rm -f $$MODLIB/build; \
+ ln -s $TOPDIR $$MODLIB/build; \
cd modules; \
MODULES=""; \
inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \
mkdir -p $$MODLIB/$$2; cp $$These $$MODLIB/$$2; \
echo Installing modules under $$MODLIB/$$2; \
}; \
- mkdir -p $$MODLIB; \
\
if [ -f BLOCK_MODULES ]; then inst_mod BLOCK_MODULES block; fi; \
if [ -f NET_MODULES ]; then inst_mod NET_MODULES net; fi; \
diff --git a/README b/README
index b66eab25d..6ed9b4486 100644
--- a/README
+++ b/README
@@ -59,23 +59,27 @@ DOCUMENTATION:
INSTALLING the kernel:
- - If you install the full sources, do a
+ - If you install the full sources, put the kernel tarball in a
+ directory where you have permissions (eg. your home directory) and
+ unpack it:
- cd /usr/src
gzip -cd linux-2.3.XX.tar.gz | tar xvf -
- to get it all put in place. Replace "XX" with the version number of the
- latest kernel.
+ Replace "XX" with the version number of the latest kernel.
+
+ Do NOT use the /usr/src/linux area! This area has a (usually
+ incomplete) set of kernel headers that are used by the library header
+ files. They should match the library, and not get messed up by
+ whatever the kernel-du-jour happens to be.
- You can also upgrade between 2.3.xx releases by patching. Patches are
distributed in the traditional gzip and the new bzip2 format. To
- install by patching, get all the newer patch files and do
+ install by patching, get all the newer patch files, enter the
+ directory in which you unpacked the kernel source and execute:
- cd /usr/src
gzip -cd patchXX.gz | patch -p0
or
- cd /usr/src
bzip2 -dc patchXX.bz2 | patch -p0
(repeat xx for all versions bigger than the version of your current
@@ -88,17 +92,15 @@ INSTALLING the kernel:
process. It determines the current kernel version and applies any
patches found.
- cd /usr/src
- linux/scripts/patch-kernel
+ linux/scripts/patch-kernel linux
- The default directory for the kernel source is /usr/src/linux, but
- can be specified as the first argument. Patches are applied from
- the current directory, but an alternative directory can be specified
- as the second argument.
+ The first argument in the command above is the location of the
+ kernel source. Patches are applied from the current directory, but
+ an alternative directory can be specified as the second argument.
- Make sure you have no stale .o files and dependencies lying around:
- cd /usr/src/linux
+ cd linux
make mrproper
You should now have the sources correctly installed.
@@ -175,6 +177,9 @@ COMPILING the kernel:
"make install" if you have lilo installed to suit the kernel makefiles,
but you may want to check your particular lilo setup first.
+ To do the actual install you have to be root, but none of the normal
+ build should require that. Don't take the name of root in vain.
+
- In the unlikely event that your system cannot boot bzImage kernels you
can still compile your kernel as zImage. However, since zImage support
will be removed at some point in the future in favor of bzImage we
@@ -196,15 +201,15 @@ COMPILING the kernel:
do a "make modules_install".
- In order to boot your new kernel, you'll need to copy the kernel
- image (found in /usr/src/linux/arch/i386/boot/bzImage after compilation)
+ image (found in .../linux/arch/i386/boot/bzImage after compilation)
to the place where your regular bootable kernel is found.
- For some, this is on a floppy disk, in which case you can "cp
- /usr/src/linux/arch/i386/boot/bzImage /dev/fd0" to make a bootable
- floppy. Please note that you can not boot a kernel by
- directly dumping it to a 720k double-density 3.5" floppy. In this
- case, it is highly recommended that you install LILO on your
- double-density boot floppy or switch to high-density floppies.
+ For some, this is on a floppy disk, in which case you can copy the
+ kernel bzImage file to /dev/fd0 to make a bootable floppy. Please note
+ that you can not boot a kernel by directly dumping it to a 720k
+ double-density 3.5" floppy. In this case, it is highly recommended
+ that you install LILO on your double-density boot floppy or switch to
+ high-density floppies.
If you boot Linux from the hard drive, chances are you use LILO which
uses the kernel image as specified in the file /etc/lilo.conf. The
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index b00e7d79b..e51ff9d18 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -622,10 +622,6 @@ smp_commence(void)
}
-extern void update_one_process(struct task_struct *p, unsigned long ticks,
- unsigned long user, unsigned long system,
- int cpu);
-
void
smp_percpu_timer_interrupt(struct pt_regs *regs)
{
@@ -643,26 +639,7 @@ smp_percpu_timer_interrupt(struct pt_regs *regs)
which would be a Bad Thing. */
irq_enter(cpu, RTC_IRQ);
- update_one_process(current, 1, user, !user, cpu);
- if (current->pid) {
- if (--current->counter <= 0) {
- current->counter = 0;
- current->need_resched = 1;
- }
-
- if (user) {
- if (current->nice > 0) {
- kstat.cpu_nice++;
- kstat.per_cpu_nice[cpu]++;
- } else {
- kstat.cpu_user++;
- kstat.per_cpu_user[cpu]++;
- }
- } else {
- kstat.cpu_system++;
- kstat.per_cpu_system[cpu]++;
- }
- }
+ update_process_times(user);
data->prof_counter = data->prof_multiplier;
irq_exit(cpu, RTC_IRQ);
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index cee60fa97..b5153433f 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -396,35 +396,11 @@ void
smp_do_timer(struct pt_regs *regs)
{
int cpu = smp_processor_id();
- int user = user_mode(regs);
struct cpuinfo_ia64 *data = &cpu_data[cpu];
- extern void update_one_process(struct task_struct *, unsigned long, unsigned long,
- unsigned long, int);
if (!--data->prof_counter) {
irq_enter(cpu, TIMER_IRQ);
-
- update_one_process(current, 1, user, !user, cpu);
- if (current->pid) {
- if (--current->counter < 0) {
- current->counter = 0;
- current->need_resched = 1;
- }
-
- if (user) {
- if (current->nice > 0) {
- kstat.cpu_nice++;
- kstat.per_cpu_nice[cpu]++;
- } else {
- kstat.cpu_user++;
- kstat.per_cpu_user[cpu]++;
- }
- } else {
- kstat.cpu_system++;
- kstat.per_cpu_system[cpu]++;
- }
- }
-
+ update_process_times(user_mode(regs));
data->prof_counter = data->prof_multiplier;
irq_exit(cpu, TIMER_IRQ);
}
diff --git a/arch/mips/defconfig-cobalt b/arch/mips/defconfig-cobalt
index bfef9e3a0..01661a95d 100644
--- a/arch/mips/defconfig-cobalt
+++ b/arch/mips/defconfig-cobalt
@@ -447,8 +447,8 @@ CONFIG_RTC=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
#
# File systems
diff --git a/arch/mips/defconfig-orion b/arch/mips/defconfig-orion
index e45b978b4..4073bfd32 100644
--- a/arch/mips/defconfig-orion
+++ b/arch/mips/defconfig-orion
@@ -202,8 +202,8 @@ CONFIG_BLK_DEV_INITRD=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
#
# File systems
diff --git a/arch/mips/defconfig-rm200 b/arch/mips/defconfig-rm200
index f67154e91..de2f2e8c2 100644
--- a/arch/mips/defconfig-rm200
+++ b/arch/mips/defconfig-rm200
@@ -233,8 +233,8 @@ CONFIG_RTC=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
#
# File systems
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index aa9fdef16..12937f110 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -326,8 +326,8 @@ CONFIG_SERIAL_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
#
# File systems
diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
index 6c2835d21..497b54e17 100644
--- a/arch/mips64/defconfig-ip22
+++ b/arch/mips64/defconfig-ip22
@@ -245,8 +245,8 @@ CONFIG_VT_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
#
# File systems
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index aa9fdef16..12937f110 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -326,8 +326,8 @@ CONFIG_SERIAL_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
#
# File systems
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index b4b50975d..c58948e71 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -323,6 +323,7 @@ CONFIG_NLS=y
#
# Native Language Support
#
+CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
@@ -339,6 +340,10 @@ CONFIG_NLS=y
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
@@ -351,6 +356,7 @@ CONFIG_NLS=y
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
#
# Watchdog
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 0e05908fe..65e95afdb 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.104 2000/06/30 10:18:38 davem Exp $
+/* $Id: irq.c,v 1.105 2000/07/26 01:04:02 davem Exp $
* arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
* Sparc the IRQ's are basically 'cast in stone'
* and you are supposed to probe the prom's device
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 59f014efc..4ce99b06b 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -1,4 +1,4 @@
-/* $Id: sun4d_irq.c,v 1.25 2000/05/09 17:40:13 davem Exp $
+/* $Id: sun4d_irq.c,v 1.26 2000/07/26 01:04:03 davem Exp $
* arch/sparc/kernel/sun4d_irq.c:
* SS1000/SC2000 interrupt handling.
*
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index fe9885025..1294ad31a 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -441,10 +441,6 @@ void smp4d_message_pass(int target, int msg, unsigned long data, int wait)
extern unsigned int prof_multiplier[NR_CPUS];
extern unsigned int prof_counter[NR_CPUS];
-extern void update_one_process(struct task_struct *p, unsigned long ticks,
- unsigned long user, unsigned long system,
- int cpu);
-
extern void sparc_do_profile(unsigned long pc, unsigned long o7);
void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
@@ -471,29 +467,10 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
int user = user_mode(regs);
irq_enter(cpu, 0);
- if(current->pid) {
- update_one_process(current, 1, user, !user, cpu);
-
- if(--current->counter <= 0) {
- current->counter = 0;
- current->need_resched = 1;
- }
+ update_process_times(user);
+ irq_exit(cpu, 0);
- if(user) {
- if(current->nice > 0) {
- kstat.cpu_nice++;
- kstat.per_cpu_nice[cpu]++;
- } else {
- kstat.cpu_user++;
- kstat.per_cpu_user[cpu]++;
- }
- } else {
- kstat.cpu_system++;
- kstat.per_cpu_system[cpu]++;
- }
- }
prof_counter[cpu] = prof_multiplier[cpu];
- irq_exit(cpu, 0);
}
}
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index 3475a8df5..60c37373e 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -439,10 +439,6 @@ void smp4m_cross_call_irq(void)
extern unsigned int prof_multiplier[NR_CPUS];
extern unsigned int prof_counter[NR_CPUS];
-extern void update_one_process(struct task_struct *p, unsigned long ticks,
- unsigned long user, unsigned long system,
- int cpu);
-
extern void sparc_do_profile(unsigned long pc, unsigned long o7);
void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
@@ -458,29 +454,10 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
int user = user_mode(regs);
irq_enter(cpu, 0);
- if(current->pid) {
- update_one_process(current, 1, user, !user, cpu);
-
- if(--current->counter <= 0) {
- current->counter = 0;
- current->need_resched = 1;
- }
+ update_process_times(user);
+ irq_exit(cpu, 0);
- if(user) {
- if(current->nice > 0) {
- kstat.cpu_nice++;
- kstat.per_cpu_nice[cpu]++;
- } else {
- kstat.cpu_user++;
- kstat.per_cpu_user[cpu]++;
- }
- } else {
- kstat.cpu_system++;
- kstat.per_cpu_system[cpu]++;
- }
- }
prof_counter[cpu] = prof_multiplier[cpu];
- irq_exit(cpu, 0);
}
}
diff --git a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile
index 3c4195085..586eba5bb 100644
--- a/arch/sparc/math-emu/Makefile
+++ b/arch/sparc/math-emu/Makefile
@@ -16,6 +16,6 @@ O_OBJS := math.o ashldi3.o
.S.o:
$(CC) $(AFLAGS) -ansi -c $< -o $*.o
-CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
+EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w
include $(TOPDIR)/Rules.make
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 9b90ca4af..e97248906 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.44 2000/07/15 00:04:27 davem Exp $
+# $Id: Makefile,v 1.45 2000/07/18 15:24:28 jj Exp $
# sparc64/Makefile
#
# Makefile for the architecture dependent flags and dependencies on the
@@ -12,7 +12,7 @@
# line...
SHELL =/bin/bash
-CC := sparc64-linux-gcc
+CC := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo gcc; else echo sparc64-linux-gcc; fi )
NEW_GCC := $(shell if $(CC) -m64 -mcmodel=medlow -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo y; else echo n; fi; )
NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 55e8516c6..e013e47fb 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -460,6 +460,7 @@ CONFIG_NLS=y
#
# Native Language Support
#
+CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
@@ -476,6 +477,10 @@ CONFIG_NLS=y
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
@@ -488,6 +493,7 @@ CONFIG_NLS=y
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
#
# Watchdog
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index 795960fea..98e209de2 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.92 2000/05/26 22:44:11 davem Exp $
+/* $Id: ioctl32.c,v 1.93 2000/07/24 22:43:15 anton Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 0f3e5c069..486254fb9 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.54 2000/05/09 17:40:14 davem Exp $
+/* $Id: setup.c,v 1.55 2000/07/24 14:13:13 anton Exp $
* linux/arch/sparc64/kernel/setup.c
*
* Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
@@ -444,8 +444,6 @@ extern unsigned long phys_base;
static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 };
-extern struct consw sun_serial_con;
-
void register_prom_callbacks(void)
{
prom_setcallback(prom_callback);
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index acd65f3f2..f99b9660c 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -673,10 +673,6 @@ static unsigned long current_tick_offset;
#define prof_multiplier(__cpu) cpu_data[(__cpu)].multiplier
#define prof_counter(__cpu) cpu_data[(__cpu)].counter
-extern void update_one_process(struct task_struct *p, unsigned long ticks,
- unsigned long user, unsigned long system,
- int cpu);
-
void smp_percpu_timer_interrupt(struct pt_regs *regs)
{
unsigned long compare, tick, pstate;
@@ -707,30 +703,8 @@ void smp_percpu_timer_interrupt(struct pt_regs *regs)
irq_exit(cpu, 0);
}
- if (current->pid) {
- unsigned int *inc, *inc2;
-
- update_one_process(current, 1, user, !user, cpu);
- if (--current->counter <= 0) {
- current->counter = 0;
- current->need_resched = 1;
- }
-
- if (user) {
- if (current->nice > 0) {
- inc = &kstat.cpu_nice;
- inc2 = &kstat.per_cpu_nice[cpu];
- } else {
- inc = &kstat.cpu_user;
- inc2 = &kstat.per_cpu_user[cpu];
- }
- } else {
- inc = &kstat.cpu_system;
- inc2 = &kstat.per_cpu_system[cpu];
- }
- atomic_inc((atomic_t *)inc);
- atomic_inc((atomic_t *)inc2);
- }
+ update_process_times(user);
+
prof_counter(cpu) = prof_multiplier(cpu);
}
diff --git a/arch/sparc64/math-emu/Makefile b/arch/sparc64/math-emu/Makefile
index 382366da5..215583800 100644
--- a/arch/sparc64/math-emu/Makefile
+++ b/arch/sparc64/math-emu/Makefile
@@ -9,6 +9,7 @@
O_TARGET := math-emu.o
O_OBJS := math.o
-CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
+
+EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w
include $(TOPDIR)/Rules.make
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index 62c595e6d..c40225584 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -1,4 +1,4 @@
-/* $Id: socksys.c,v 1.15 2000/07/13 08:06:38 davem Exp $
+/* $Id: socksys.c,v 1.16 2000/07/27 00:03:48 davem Exp $
* socksys.c: /dev/inet/ stuff for Solaris emulation.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
diff --git a/drivers/block/linear.c b/drivers/block/linear.c
index b429e1bbf..fcd5b8b06 100644
--- a/drivers/block/linear.c
+++ b/drivers/block/linear.c
@@ -121,7 +121,7 @@ static int linear_stop (mddev_t *mddev)
return 0;
}
-static int linear_make_request (request_queue_t *q, mddev_t *mddev,
+static int linear_make_request (mddev_t *mddev,
int rw, struct buffer_head * bh)
{
linear_conf_t *conf = mddev_to_conf(mddev);
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 3672e8976..cf6e99878 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -5,6 +5,7 @@
* Copyright (C) 1994, Karl Keyte: Added support for disk statistics
* Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
* Queue request tables / lock, selectable elevator, Jens Axboe <axboe@suse.de>
+ * kernel-doc documentation started by NeilBrown <neilb@cse.unsw.edu.au> - July2000
*/
/*
@@ -171,10 +172,19 @@ static int __blk_cleanup_queue(struct list_head *head)
return i;
}
-/*
- * Hopefully the low level driver has finished any outstanding requests
- * first...
- */
+/**
+ * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed
+ * @q: the request queue to be released
+ *
+ * Description: blk_cleanup_queue is the pair to blk_init_queue(). It should
+ * be called when a request queue is being released; typically when a block
+ * device is being de-registered.
+ * Currently, its primary task it to free all the &struct request structures
+ * that were allocated to the queue.
+ * Caveat:
+ * Hopefully the low level driver will have finished any outstanding requests
+ * first...
+ **/
void blk_cleanup_queue(request_queue_t * q)
{
int count = QUEUE_NR_REQUESTS;
@@ -188,16 +198,78 @@ void blk_cleanup_queue(request_queue_t * q)
memset(q, 0, sizeof(*q));
}
+/**
+ * blk_queue_headactive - indicate whether head of request queue may be active
+ * @q: The queue which this applies to.
+ * @active: A flag indication where the head of the queue is active.
+ *
+ * Description:
+ * The driver for a block device may choose to leave the currently active request
+ * on the request queue, removing it only when it has completed. The queue
+ * handling routines assume this by default and will not involved the head of the
+ * request queue in any merging or reordering of requests.
+ *
+ * If a driver removes requests from the queue before processing them, then it may
+ * indicate that it does so, there by allowing the head of the queue to be involved
+ * in merging and reordering. This is done be calling blk_queue_headactive() with an
+ * @active flag of %1.
+ *
+ * If a driver processes several requests at once, it must remove them (or at least all
+ * but one of them) from the request queue.
+ *
+ * When a queue is plugged (see blk_queue_pluggable()) the head will be assumed to
+ * be inactive.
+ **/
+
void blk_queue_headactive(request_queue_t * q, int active)
{
q->head_active = active;
}
+/**
+ * blk_queue_pluggable - define a plugging function for a request queue
+ * @q: the request queue to which the function will apply
+ * @plug: the function to be called to plug a queue
+ *
+ * Description:
+ * A request queue will be "plugged" if a request is added to it while it
+ * is empty. This allows a number of requests to be added before any are
+ * processed, thus providing an opportunity for these requests to be merged
+ * or re-ordered.
+ * The default plugging function (generic_plug_device()) sets the "plugged" flag
+ * for the queue and adds a task the the $tq_disk task queue to unplug the
+ * queue and call the request function at a later time.
+ *
+ * A device driver may provide an alternate plugging function by passing it to
+ * blk_queue_pluggable(). This function should set the "plugged" flag if it
+ * want calls to the request_function to be blocked, and should place a
+ * task on $tq_disk which will unplug the queue. Alternately it can simply
+ * do nothing and there-by disable plugging of the device.
+ **/
+
void blk_queue_pluggable (request_queue_t * q, plug_device_fn *plug)
{
q->plug_device_fn = plug;
}
+
+/**
+ * blk_queue_make_request - define an alternate make_request function for a device
+ * @q: the request queue for the device to be affected
+ * @mfn: the alternate make_request function
+ *
+ * Description:
+ * The normal way for &struct buffer_heads to be passes to a device driver it to
+ * collect into requests on a request queue, and allow the device driver to select
+ * requests off that queue when it is ready. This works well for many block devices.
+ * However some block devices (typically virtual devices such as md or lvm) do not benefit
+ * from the processes on the request queue, and are served best by having the requests passed
+ * directly to them. This can be achived by providing a function to blk_queue_make_request().
+ * If this is done, then the rest of the &request_queue_t structure is unused (unless the alternate
+ * make_request function explicitly uses it). In particular, there is no need to call
+ * blk_init_queue() if blk_queue_make_request() has been called.
+ **/
+
void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
{
q->make_request_fn = mfn;
@@ -259,12 +331,6 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
*/
static void generic_plug_device(request_queue_t *q, kdev_t dev)
{
-#ifdef CONFIG_BLK_DEV_MD
- if (MAJOR(dev) == MD_MAJOR) {
- spin_unlock_irq(&io_request_lock);
- BUG();
- }
-#endif
/*
* no need to replug device
*/
@@ -275,6 +341,28 @@ static void generic_plug_device(request_queue_t *q, kdev_t dev)
queue_task(&q->plug_tq, &tq_disk);
}
+/*
+ * remove the plug and let it rip..
+ */
+static inline void __generic_unplug_device(request_queue_t *q)
+{
+ if (q->plugged) {
+ q->plugged = 0;
+ if (!list_empty(&q->queue_head))
+ q->request_fn(q);
+ }
+}
+
+static void generic_unplug_device(void *data)
+{
+ request_queue_t *q = (request_queue_t *) data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ __generic_unplug_device(q);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
static void blk_init_free_list(request_queue_t *q)
{
struct request *rq;
@@ -295,6 +383,42 @@ static void blk_init_free_list(request_queue_t *q)
spin_lock_init(&q->request_lock);
}
+/**
+ * blk_init_queue - prepare a request queue for use with a block device
+ * @q: The &request_queue_t to be initialised
+ * @rfn: The function to be called to process requests that have been
+ * placed on the queue.
+ *
+ * Description:
+ * If a block device wishes to use the stand request handling procedures,
+ * which sorts requests and coalesces adjactent requests, then it must
+ * call blk_init_queue(). The function @rfn will be called when there
+ * are requests on the queue that need to be processed. If the device
+ * supports plugging, then @rfn may not be called immediately that requests
+ * are available on the queue, but may be called at some time later instead.
+ *
+ * @rfn is not required, or even expected, to remove all requests off the queue, but
+ * only as many as it can handle at a time. If it does leave requests on the queue,
+ * it is responsible for arranging that the requests get dealt with eventually.
+ *
+ * A global spin lock $io_spin_lock must held while manipulating the requests
+ * on the request queue.
+ *
+ * The request on the head of the queue is by default assumed to be potentially active,
+ * and it is not considered for re-ordering or merging. This behaviour can
+ * be changed with blk_queue_headactive().
+ *
+ * Note:
+ * blk_init_queue() does not need to be called if
+ * blk_queue_make_request() has been called to register an alternate
+ * request handler. Ofcourse, it may be called if the handler wants
+ * to still use the fields on &request_queue_t, but in a non-standard
+ * way.
+ *
+ * blk_init_queue() should be paired with a blk_cleanup-queue() call
+ * when the block device is deactivated (such as at module unload).
+ **/
+static int __make_request(request_queue_t * q, int rw, struct buffer_head * bh);
void blk_init_queue(request_queue_t * q, request_fn_proc * rfn)
{
INIT_LIST_HEAD(&q->queue_head);
@@ -306,7 +430,7 @@ void blk_init_queue(request_queue_t * q, request_fn_proc * rfn)
q->back_merge_fn = ll_back_merge_fn;
q->front_merge_fn = ll_front_merge_fn;
q->merge_requests_fn = ll_merge_requests_fn;
- q->make_request_fn = NULL;
+ q->make_request_fn = __make_request;
q->plug_tq.sync = 0;
q->plug_tq.routine = &generic_unplug_device;
q->plug_tq.data = q;
@@ -321,27 +445,6 @@ void blk_init_queue(request_queue_t * q, request_fn_proc * rfn)
q->head_active = 1;
}
-/*
- * remove the plug and let it rip..
- */
-static inline void __generic_unplug_device(request_queue_t *q)
-{
- if (q->plugged) {
- q->plugged = 0;
- if (!list_empty(&q->queue_head))
- q->request_fn(q);
- }
-}
-
-void generic_unplug_device(void *data)
-{
- request_queue_t *q = (request_queue_t *) data;
- unsigned long flags;
-
- spin_lock_irqsave(&io_request_lock, flags);
- __generic_unplug_device(q);
- spin_unlock_irqrestore(&io_request_lock, flags);
-}
#define blkdev_free_rq(list) list_entry((list)->next, struct request, table);
/*
@@ -574,7 +677,7 @@ static inline void attempt_front_merge(request_queue_t * q,
attempt_merge(q, blkdev_entry_to_request(prev), max_sectors, max_segments);
}
-static inline void __make_request(request_queue_t * q, int rw,
+static int __make_request(request_queue_t * q, int rw,
struct buffer_head * bh)
{
unsigned int sector, count;
@@ -730,10 +833,13 @@ get_rq:
req->e = elevator;
add_request(q, req, head, latency);
out:
+ if (!q->plugged)
+ (q->request_fn)(q);
spin_unlock_irq(&io_request_lock);
- return;
+ return 0;
end_io:
bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
+ return 0;
}
void generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
@@ -771,20 +877,12 @@ void generic_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
* still free to implement/resolve their own stacking
* by explicitly returning 0)
*/
- while (q->make_request_fn) {
- if (q->make_request_fn(q, rw, bh) == 0)
- return;
+ while (q->make_request_fn(q, rw, bh))
+ /* NOTE: we don't repeat the blk_size check even though we now have a
+ * new device. stacking drivers are expected to know what
+ * they are doing.
+ */
q = blk_get_queue(bh->b_rdev);
- }
- /*
- * Does the block device want us to queue
- * the IO request? (normal case)
- */
- __make_request(q, rw, bh);
- spin_lock_irq(&io_request_lock);
- if (q && !q->plugged)
- (q->request_fn)(q);
- spin_unlock_irq(&io_request_lock);
}
/* This function can be used to request a number of buffers from a block
@@ -1052,5 +1150,4 @@ EXPORT_SYMBOL(blk_queue_headactive);
EXPORT_SYMBOL(blk_queue_pluggable);
EXPORT_SYMBOL(blk_queue_make_request);
EXPORT_SYMBOL(generic_make_request);
-EXPORT_SYMBOL(generic_unplug_device);
EXPORT_SYMBOL(blkdev_release_request);
diff --git a/drivers/block/md.c b/drivers/block/md.c
index afde399d4..9774233cc 100644
--- a/drivers/block/md.c
+++ b/drivers/block/md.c
@@ -124,37 +124,6 @@ static struct gendisk md_gendisk=
fops: &md_fops,
};
-void md_plug_device (request_queue_t *mdqueue, kdev_t dev)
-{
- mdk_rdev_t * rdev;
- struct md_list_head *tmp;
- request_queue_t *q;
- mddev_t *mddev;
-
- if (!md_test_and_set_bit(0, (atomic_t *)&mdqueue->plugged)) {
- mddev = kdev_to_mddev(dev);
- ITERATE_RDEV(mddev,rdev,tmp) {
- q = blk_get_queue(rdev->dev);
- generic_unplug_device(q);
- }
- queue_task(&mdqueue->plug_tq, &tq_disk);
- }
-}
-
-static void md_unplug_device (void * data)
-{
- mdk_rdev_t * rdev;
- struct md_list_head *tmp;
- mddev_t *mddev = (mddev_t *)data;
- request_queue_t *mdqueue = &mddev->queue, *q;
-
- clear_bit(0, (atomic_t *)&mdqueue->plugged);
- ITERATE_RDEV(mddev,rdev,tmp) {
- q = blk_get_queue(rdev->dev);
- generic_unplug_device(q);
- }
-}
-
/*
* Enables to iterate over all existing md arrays
*/
@@ -199,28 +168,12 @@ void del_mddev_mapping (mddev_t * mddev, kdev_t dev)
mddev_map[minor].data = NULL;
}
-static request_queue_t *md_get_queue (kdev_t dev)
-{
- mddev_t *mddev = kdev_to_mddev(dev);
-
- if (!mddev)
- return NULL;
- return &mddev->queue;
-}
-
-static void do_md_request (request_queue_t * q)
-{
- printk(KERN_ALERT "Got md request, not good...");
- BUG();
- return;
-}
-
static int md_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
{
mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
if (mddev && mddev->pers)
- return mddev->pers->make_request(q, mddev, rw, bh);
+ return mddev->pers->make_request(mddev, rw, bh);
else {
buffer_IO_error(bh);
return -1;
@@ -229,7 +182,6 @@ static int md_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
static mddev_t * alloc_mddev (kdev_t dev)
{
- request_queue_t *q;
mddev_t *mddev;
if (MAJOR(dev) != MD_MAJOR) {
@@ -249,15 +201,6 @@ static mddev_t * alloc_mddev (kdev_t dev)
MD_INIT_LIST_HEAD(&mddev->disks);
MD_INIT_LIST_HEAD(&mddev->all_mddevs);
- q = &mddev->queue;
- blk_init_queue(q, DEVICE_REQUEST);
- blk_queue_pluggable(q, md_plug_device);
- blk_queue_make_request(q, md_make_request);
-
- q->plug_tq.sync = 0;
- q->plug_tq.routine = &md_unplug_device;
- q->plug_tq.data = mddev;
-
/*
* The 'base' mddev is the one with data NULL.
* personalities can create additional mddevs
@@ -808,7 +751,6 @@ static void free_mddev (mddev_t *mddev)
del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev)));
md_list_del(&mddev->all_mddevs);
MD_INIT_LIST_HEAD(&mddev->all_mddevs);
- blk_cleanup_queue(&mddev->queue);
kfree(mddev);
MOD_DEC_USE_COUNT;
}
@@ -3657,7 +3599,9 @@ int md__init md_init (void)
MAJOR_NR, 0, S_IFBLK | S_IRUSR | S_IWUSR,
&md_fops, NULL);
- blk_dev[MAJOR_NR].queue = md_get_queue;
+ /* forward all md request to md_make_request */
+ blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), md_make_request);
+
read_ahead[MAJOR_NR] = INT_MAX;
md_gendisk.next = gendisk_head;
diff --git a/drivers/block/raid0.c b/drivers/block/raid0.c
index 48055ecea..4a298bc0d 100644
--- a/drivers/block/raid0.c
+++ b/drivers/block/raid0.c
@@ -223,8 +223,8 @@ static int raid0_stop (mddev_t *mddev)
* Of course, those facts may not be valid anymore (and surely won't...)
* Hey guys, there's some work out there ;-)
*/
-static int raid0_make_request (request_queue_t *q, mddev_t *mddev,
- int rw, struct buffer_head * bh)
+static int raid0_make_request (mddev_t *mddev,
+ int rw, struct buffer_head * bh)
{
unsigned int sect_in_chunk, chunksize_bits, chunk, chunk_size;
raid0_conf_t *conf = mddev_to_conf(mddev);
diff --git a/drivers/block/raid1.c b/drivers/block/raid1.c
index c8b2ce456..12eb8658f 100644
--- a/drivers/block/raid1.c
+++ b/drivers/block/raid1.c
@@ -542,8 +542,8 @@ rb_out:
return new_disk;
}
-static int raid1_make_request (request_queue_t *q, mddev_t *mddev, int rw,
- struct buffer_head * bh)
+static int raid1_make_request (mddev_t *mddev, int rw,
+ struct buffer_head * bh)
{
raid1_conf_t *conf = mddev_to_conf(mddev);
struct buffer_head *bh_req, *bhl;
@@ -551,6 +551,7 @@ static int raid1_make_request (request_queue_t *q, mddev_t *mddev, int rw,
int disks = MD_SB_DISKS;
int i, sum_bhs = 0, sectors;
struct mirror_info *mirror;
+ request_queue_t *q;
if (!buffer_locked(bh))
BUG();
diff --git a/drivers/block/raid5.c b/drivers/block/raid5.c
index 4dc2d7d40..22a66fe2a 100644
--- a/drivers/block/raid5.c
+++ b/drivers/block/raid5.c
@@ -1488,7 +1488,7 @@ static void handle_stripe(struct stripe_head *sh)
}
-static int raid5_make_request (request_queue_t *q, mddev_t *mddev, int rw, struct buffer_head * bh)
+static int raid5_make_request (mddev_t *mddev, int rw, struct buffer_head * bh)
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
const unsigned int raid_disks = conf->raid_disks;
diff --git a/drivers/char/Config.in b/drivers/char/Config.in
index ae79962f4..f41c3d48b 100644
--- a/drivers/char/Config.in
+++ b/drivers/char/Config.in
@@ -257,15 +257,6 @@ if [ "$CONFIG_FTAPE" != "n" ]; then
fi
endmenu
-bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
-if [ "$CONFIG_DRM" = "y" ]; then
- tristate ' 3dfx Banshee/Voodoo3+' CONFIG_DRM_TDFX
- tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA
- tristate ' ATI Rage 128' CONFIG_DRM_R128
- tristate ' Intel I810' CONFIG_DRM_I810
- tristate ' Matrox g200/g400' CONFIG_DRM_MGA
-fi
-
tristate '/dev/agpgart (AGP Support)' CONFIG_AGP $CONFIG_DRM_AGP
if [ "$CONFIG_AGP" != "n" ]; then
bool ' Intel 440LX/BX/GX support' CONFIG_AGP_INTEL
@@ -276,6 +267,8 @@ if [ "$CONFIG_AGP" != "n" ]; then
bool ' ALI M1541 support' CONFIG_AGP_ALI
fi
+source drivers/char/drm/Config.in
+
if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
source drivers/char/pcmcia/Config.in
fi
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 3bb727c27..5ae783f3e 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -2,88 +2,76 @@
# Makefile for the drm device driver. This driver provides support for
# the Direct Rendering Infrastructure (DRI) in XFree86 4.x.
#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now inherited from the
-# parent makes..
-#
-
-O_OBJS :=
-OX_OBJS :=
-M_OBJS :=
-MX_OBJS :=
-
-# Object file lists.
-
-obj-y :=
-obj-m :=
-obj-n :=
-obj- :=
-SUB_DIRS :=
-MOD_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS)
+O_TARGET = drm.o
+
+export-objs = drm_syms.o
+list-multi = drm.o gamma.o tdfx.o r128.o ffb.o mga.o i810.o
+drm-objs = init.o memory.o proc.o auth.o context.o \
+ drawable.o bufs.o lists.o lock.o ioctl.o \
+ fops.o vm.o dma.o ctxbitmap.o drm_syms.o
+gamma-objs = gamma_drv.o gamma_dma.o
+tdfx-objs = tdfx_drv.o tdfx_context.o
+r128-objs = r128_drv.o r128_context.o r128_dma.o r128_bufs.o
+ffb-objs = ffb_drv.o ffb_context.o
+mga-objs = mga_drv.o mga_context.o mga_dma.o mga_bufs.o mga_state.o
+i810-objs = i810_drv.o i810_context.o i810_dma.o i810_bufs.o
+
+ifeq ($(CONFIG_AGP), y)
+ drm-objs += agpsupport.o
+else
+ ifeq ($(CONFIG_AGP), m)
+ drm-objs += agpsupport.o
+ endif
+endif
-O_TARGET := drm.o
-module-list := gamma.o tdfx.o r128.o ffb.o mga.o i810.o
-export-objs := $(patsubst %.o,%_drv.o,$(module-list))
+obj-$(CONFIG_DRM) += drm.o
+obj-$(CONFIG_DRM_GAMMA) += gamma.o
+obj-$(CONFIG_DRM_TDFX) += tdfx.o
+obj-$(CONFIG_DRM_R128) += r128.o
+obj-$(CONFIG_DRM_FFB) += ffb.o
+obj-$(CONFIG_DRM_MGA) += mga.o
+obj-$(CONFIG_DRM_I810) += i810.o
-lib-objs := init.o memory.o proc.o auth.o context.o drawable.o bufs.o
-lib-objs += lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
-ifneq ($(CONFIG_AGP),)
- lib-objs += agpsupport.o
-endif
+# Extract lists of the multi-part drivers.
+# The 'int-*' lists are the intermediate files used to build the multi's.
+multi-y := $(filter $(list-multi), $(obj-y))
+multi-m := $(filter $(list-multi), $(obj-m))
+int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
+int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
-gamma-objs := $(lib-objs) gamma_drv.o gamma_dma.o
-tdfx-objs := $(lib-objs) tdfx_drv.o tdfx_context.o
-r128-objs := $(lib-objs) r128_drv.o r128_dma.o r128_context.o r128_bufs.o
-ffb-objs := $(lib-objs) ffb_drv.o ffb_context.o
-mga-objs := $(lib-objs) mga_drv.o mga_dma.o mga_context.o mga_bufs.o \
- mga_state.o
-i810-objs := $(lib-objs) i810_drv.o i810_dma.o i810_context.o i810_bufs.o
-
-obj-$(CONFIG_DRM_GAMMA) += gamma.o $(gamma-objs)
-obj-$(CONFIG_DRM_TDFX) += tdfx.o $(tdfx-objs)
-obj-$(CONFIG_DRM_R128) += r128.o $(r128-objs)
-obj-$(CONFIG_DRM_FFB) += ffb.o $(ffb-objs)
-
-ifneq ($CONFIG_AGP),)
-obj-$(CONFIG_DRM_MGA) += mga.o $(mga-objs)
-obj-$(CONFIG_DRM_I810) += i810.o $(i810-objs)
-endif
+# Files that are both resident and modular: remove from modular.
+obj-m := $(filter-out $(obj-y), $(obj-m))
+int-m := $(filter-out $(int-y), $(int-m))
-# Take module names out of obj-y and int-m
-
-obj-y := $(filter-out $(module-list), $(obj-y))
-int-m := $(filter-out $(module-list), $(obj-m))
+# Take multi-part drivers out of obj-y and put components in.
+obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)
# Translate to Rules.make lists.
-
-O_OBJS := $(filter-out $(export-objs), $(obj-y))
-OX_OBJS := $(filter $(export-objs), $(obj-y))
-M_OBJS := $(sort $(filter $(module-list), $(obj-m)))
-MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m)))
-MIX_OBJS := $(sort $(filter $(export-objs), $(int-m)))
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m)))
+MIX_OBJS := $(sort $(filter $(export-objs), $(int-m)))
include $(TOPDIR)/Rules.make
gamma.o: $(gamma-objs)
- $(LD) $(LD_RFLAG) -r -o $@ $(gamma-objs)
+ $(LD) -r -o $@ $(gamma-objs)
tdfx.o: $(tdfx-objs)
- $(LD) $(LD_RFLAG) -r -o $@ $(tdfx-objs)
+ $(LD) -r -o $@ $(tdfx-objs)
mga.o: $(mga-objs)
- $(LD) $(LD_RFLAG) -r -o $@ $(mga-objs)
+ $(LD) -r -o $@ $(mga-objs)
i810.o: $(i810-objs)
- $(LD) $(LD_RFLAG) -r -o $@ $(i810-objs)
+ $(LD) -r -o $@ $(i810-objs)
r128.o: $(r128-objs)
- $(LD) $(LD_RFLAG) -r -o $@ $(r128-objs)
+ $(LD) -r -o $@ $(r128-objs)
ffb.o: $(ffb-objs)
- $(LD) $(LD_RFLAG) -r -o $@ $(ffb-objs)
+ $(LD) -r -o $@ $(ffb-objs)
diff --git a/drivers/char/drm/auth.c b/drivers/char/drm/auth.c
index 9f81c5391..3ee85388e 100644
--- a/drivers/char/drm/auth.c
+++ b/drivers/char/drm/auth.c
@@ -45,6 +45,8 @@ static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
down(&dev->struct_sem);
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+ if (pt->priv->authenticated)
+ continue;
if (pt->magic == magic) {
retval = pt->priv;
break;
diff --git a/drivers/char/drm/bufs.c b/drivers/char/drm/bufs.c
index fd3b12488..c00f051a8 100644
--- a/drivers/char/drm/bufs.c
+++ b/drivers/char/drm/bufs.c
@@ -106,7 +106,7 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
dev->lock.hw_lock = map->handle; /* Pointer to lock */
}
break;
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
case _DRM_AGP:
map->offset = map->offset + dev->agp->base;
break;
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index d8791bf95..afc4fd43e 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -51,9 +51,6 @@
#include <asm/mtrr.h>
#endif
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
-#define DRM_AGP
-#endif
-#ifdef DRM_AGP
#include <linux/types.h>
#include <linux/agp_backend.h>
#endif
@@ -410,7 +407,7 @@ typedef struct drm_device_dma {
wait_queue_head_t waiting; /* Processes waiting on free bufs */
} drm_device_dma_t;
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
typedef struct drm_agp_mem {
unsigned long handle;
agp_memory *memory;
@@ -499,9 +496,9 @@ typedef struct drm_device {
/* Context support */
int irq; /* Interrupt used by board */
- __volatile__ int context_flag; /* Context swapping flag */
- __volatile__ int interrupt_flag;/* Interruption handler flag */
- __volatile__ int dma_flag; /* DMA dispatch flag */
+ __volatile__ long context_flag; /* Context swapping flag */
+ __volatile__ long interrupt_flag; /* Interruption handler flag */
+ __volatile__ long dma_flag; /* DMA dispatch flag */
struct timer_list timer; /* Timer for delaying ctx switch */
wait_queue_head_t context_wait; /* Processes waiting on ctx switch */
int last_checked; /* Last context checked for DMA */
@@ -524,7 +521,7 @@ typedef struct drm_device {
wait_queue_head_t buf_readers; /* Processes waiting to read */
wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
drm_agp_head_t *agp;
#endif
unsigned long *ctx_bitmap;
@@ -601,7 +598,7 @@ extern void drm_free_pages(unsigned long address, int order,
extern void *drm_ioremap(unsigned long offset, unsigned long size);
extern void drm_ioremapfree(void *pt, unsigned long size);
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
extern agp_memory *drm_alloc_agp(int pages, u32 type);
extern int drm_free_agp(agp_memory *handle, int pages);
extern int drm_bind_agp(agp_memory *handle, unsigned int start);
@@ -644,7 +641,6 @@ extern void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
extern void drm_reclaim_buffers(drm_device_t *dev, pid_t pid);
extern int drm_context_switch(drm_device_t *dev, int old, int new);
extern int drm_context_switch_complete(drm_device_t *dev, int new);
-extern void drm_wakeup(drm_device_t *dev, drm_buf_t *buf);
extern void drm_clear_next_buffer(drm_device_t *dev);
extern int drm_select_queue(drm_device_t *dev,
void (*wrapper)(unsigned long));
@@ -725,7 +721,7 @@ extern void drm_ctxbitmap_cleanup(drm_device_t *dev);
extern int drm_ctxbitmap_next(drm_device_t *dev);
extern void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
/* AGP/GART support (agpsupport.c) */
extern drm_agp_head_t *drm_agp_init(void);
extern void drm_agp_uninit(void);
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index 10594dd2e..d81685230 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -1,4 +1,4 @@
-/* $Id: ffb_drv.c,v 1.4 2000/07/13 08:06:39 davem Exp $
+/* $Id: ffb_drv.c,v 1.5 2000/07/26 01:03:57 davem Exp $
* ffb_drv.c: Creator/Creator3D direct rendering driver.
*
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
@@ -163,6 +163,9 @@ static int ffb_takedown(drm_device_t *dev)
- PAGE_SHIFT,
DRM_MEM_SAREA);
break;
+
+ default:
+ break;
};
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
diff --git a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c
index 2450d3a7b..850cc5118 100644
--- a/drivers/char/drm/gamma_drv.c
+++ b/drivers/char/drm/gamma_drv.c
@@ -30,15 +30,11 @@
*/
#include <linux/config.h>
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
-#include "drmP.h"
-#include "gamma_drv.h"
+#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
-EXPORT_SYMBOL(gamma_init);
-EXPORT_SYMBOL(gamma_cleanup);
+#include "drmP.h"
+#include "gamma_drv.h"
#ifndef PCI_DEVICE_ID_3DLABS_GAMMA
#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008
@@ -122,10 +118,6 @@ MODULE_PARM(gamma, "s");
MODULE_PARM(devices, "i");
MODULE_PARM_DESC(devices,
"devices=x, where x is the number of MX chips on card\n");
-
-module_init(gamma_init);
-module_exit(gamma_cleanup);
-
#ifndef MODULE
/* gamma_options is called by the kernel to parse command-line options
* passed via the boot-loader (e.g., LILO). It calls the insmod option
@@ -406,6 +398,10 @@ void gamma_cleanup(void)
gamma_takedown(dev);
}
+module_init(gamma_init);
+module_exit(gamma_cleanup);
+
+
int gamma_version(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -447,7 +443,6 @@ int gamma_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -462,13 +457,14 @@ int gamma_open(struct inode *inode, struct file *filp)
int gamma_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ drm_device_t *dev;
int retcode = 0;
- DRM_DEBUG("open_count = %d\n", dev->open_count);
lock_kernel();
+ dev = priv->dev;
+
+ DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_release(inode, filp))) {
- MOD_DEC_USE_COUNT;
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
diff --git a/drivers/char/drm/gamma_drv.h b/drivers/char/drm/gamma_drv.h
index 2cfbf6c8d..e9ce39589 100644
--- a/drivers/char/drm/gamma_drv.h
+++ b/drivers/char/drm/gamma_drv.h
@@ -33,8 +33,6 @@
#define _GAMMA_DRV_H_
/* gamma_drv.c */
-extern int gamma_init(void);
-extern void gamma_cleanup(void);
extern int gamma_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int gamma_open(struct inode *inode, struct file *filp);
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index f212f2bf2..eaa71a66b 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -30,18 +30,11 @@
*/
#include <linux/config.h>
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
#include "drmP.h"
#include "i810_drv.h"
#include <linux/sched.h>
#include <linux/smp_lock.h>
-
-EXPORT_SYMBOL(i810_init);
-EXPORT_SYMBOL(i810_cleanup);
-
#define I810_NAME "i810"
#define I810_DESC "Intel I810"
#define I810_DATE "20000719"
@@ -134,9 +127,6 @@ MODULE_AUTHOR("VA Linux Systems, Inc.");
MODULE_DESCRIPTION("Intel I810");
MODULE_PARM(i810, "s");
-module_init(i810_init);
-module_exit(i810_cleanup);
-
#ifndef MODULE
/* i810_options is called by the kernel to parse command-line options
* passed via the boot-loader (e.g., LILO). It calls the insmod option
@@ -430,6 +420,10 @@ void i810_cleanup(void)
}
}
+module_init(i810_init);
+module_exit(i810_cleanup);
+
+
int i810_version(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -471,7 +465,6 @@ int i810_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -552,7 +545,6 @@ int i810_release(struct inode *inode, struct file *filp)
up(&dev->struct_sem);
drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
- MOD_DEC_USE_COUNT;
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index f5411c0bc..1c9574017 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -77,8 +77,6 @@ typedef struct drm_i810_private {
} drm_i810_private_t;
/* i810_drv.c */
-extern int i810_init(void);
-extern void i810_cleanup(void);
extern int i810_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int i810_open(struct inode *inode, struct file *filp);
diff --git a/drivers/char/drm/memory.c b/drivers/char/drm/memory.c
index f342bb4fe..e1f462bdd 100644
--- a/drivers/char/drm/memory.c
+++ b/drivers/char/drm/memory.c
@@ -330,7 +330,7 @@ void drm_ioremapfree(void *pt, unsigned long size)
}
}
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
agp_memory *drm_alloc_agp(int pages, u32 type)
{
agp_memory *handle;
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index a3072c39e..45653aa56 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -31,15 +31,10 @@
*/
#include <linux/config.h>
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
#include "drmP.h"
#include "mga_drv.h"
#include <linux/sched.h>
#include <linux/smp_lock.h>
-EXPORT_SYMBOL(mga_init);
-EXPORT_SYMBOL(mga_cleanup);
#define MGA_NAME "mga"
#define MGA_DESC "Matrox g200/g400"
@@ -133,9 +128,6 @@ MODULE_AUTHOR("VA Linux Systems, Inc.");
MODULE_DESCRIPTION("Matrox g200/g400");
MODULE_PARM(mga, "s");
-module_init(mga_init);
-module_exit(mga_cleanup);
-
#ifndef MODULE
/* mga_options is called by the kernel to parse command-line options passed
* via the boot-loader (e.g., LILO). It calls the insmod option routine,
@@ -444,6 +436,10 @@ void mga_cleanup(void)
}
}
+module_init(mga_init);
+module_exit(mga_cleanup);
+
+
int mga_version(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -485,7 +481,6 @@ int mga_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -566,7 +561,6 @@ int mga_release(struct inode *inode, struct file *filp)
up(&dev->struct_sem);
drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
- MOD_DEC_USE_COUNT;
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index f217acb97..fe9e3dbe9 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -102,8 +102,6 @@ typedef struct _drm_mga_private {
} drm_mga_private_t;
/* mga_drv.c */
-extern int mga_init(void);
-extern void mga_cleanup(void);
extern int mga_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int mga_open(struct inode *inode, struct file *filp);
diff --git a/drivers/char/drm/proc.c b/drivers/char/drm/proc.c
index 24dfe5f35..ca062a09b 100644
--- a/drivers/char/drm/proc.c
+++ b/drivers/char/drm/proc.c
@@ -521,9 +521,9 @@ static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
} else {
DRM_PROC_PRINT("lock none\n");
}
- DRM_PROC_PRINT("context_flag 0x%08x\n", dev->context_flag);
- DRM_PROC_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag);
- DRM_PROC_PRINT("dma_flag 0x%08x\n", dev->dma_flag);
+ DRM_PROC_PRINT("context_flag 0x%08lx\n", dev->context_flag);
+ DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag);
+ DRM_PROC_PRINT("dma_flag 0x%08lx\n", dev->dma_flag);
DRM_PROC_PRINT("queue_count %10d\n", dev->queue_count);
DRM_PROC_PRINT("last_context %10d\n", dev->last_context);
diff --git a/drivers/char/drm/r128_bufs.c b/drivers/char/drm/r128_bufs.c
index e8ff4df43..d02fc5e00 100644
--- a/drivers/char/drm/r128_bufs.c
+++ b/drivers/char/drm/r128_bufs.c
@@ -36,7 +36,7 @@
#include "linux/un.h"
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
int r128_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -199,7 +199,7 @@ int r128_addbufs(struct inode *inode, struct file *filp, unsigned int cmd,
sizeof(request),
-EFAULT);
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
if (request.flags & _DRM_AGP_BUFFER)
return r128_addbufs_agp(inode, filp, cmd, arg);
else
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index 3e3ace345..27b16614c 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -30,15 +30,10 @@
*/
#include <linux/config.h>
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
#include "drmP.h"
#include "r128_drv.h"
#include <linux/sched.h>
#include <linux/smp_lock.h>
-EXPORT_SYMBOL(r128_init);
-EXPORT_SYMBOL(r128_cleanup);
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
@@ -101,7 +96,7 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { r128_unlock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 },
@@ -129,9 +124,6 @@ MODULE_AUTHOR("VA Linux Systems, Inc.");
MODULE_DESCRIPTION("r128");
MODULE_PARM(r128, "s");
-module_init(r128_init);
-module_exit(r128_cleanup);
-
#ifndef MODULE
/* r128_options is called by the kernel to parse command-line options
* passed via the boot-loader (e.g., LILO). It calls the insmod option
@@ -246,7 +238,7 @@ static int r128_takedown(drm_device_t *dev)
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
}
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
/* Clear AGP information */
if (dev->agp) {
drm_agp_mem_t *entry;
@@ -358,7 +350,7 @@ int r128_init(void)
drm_mem_init();
drm_proc_init(dev);
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
dev->agp = drm_agp_init();
if (dev->agp == NULL) {
DRM_ERROR("Cannot initialize agpgart module.\n");
@@ -411,7 +403,7 @@ void r128_cleanup(void)
}
drm_ctxbitmap_cleanup(dev);
r128_takedown(dev);
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
if (dev->agp) {
drm_agp_uninit();
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
@@ -420,6 +412,10 @@ void r128_cleanup(void)
#endif
}
+module_init(r128_init);
+module_exit(r128_cleanup);
+
+
int r128_version(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -461,7 +457,6 @@ int r128_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -470,6 +465,9 @@ int r128_open(struct inode *inode, struct file *filp)
}
spin_unlock(&dev->count_lock);
}
+
+ unlock_kernel();
+
return retcode;
}
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 81390bb8b..5b15dddfb 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -69,8 +69,6 @@ typedef struct drm_r128_buf_priv {
} drm_r128_buf_priv_t;
/* r128_drv.c */
-extern int r128_init(void);
-extern void r128_cleanup(void);
extern int r128_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int r128_open(struct inode *inode, struct file *filp);
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
index 97bd4180b..85f88044d 100644
--- a/drivers/char/drm/tdfx_drv.c
+++ b/drivers/char/drm/tdfx_drv.c
@@ -31,13 +31,10 @@
*/
#include <linux/config.h>
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
+#include <linux/sched.h>
+#include <linux/smp_lock.h>
#include "drmP.h"
#include "tdfx_drv.h"
-EXPORT_SYMBOL(tdfx_init);
-EXPORT_SYMBOL(tdfx_cleanup);
#define TDFX_NAME "tdfx"
#define TDFX_DESC "3dfx Banshee/Voodoo3+"
@@ -94,7 +91,7 @@ static drm_ioctl_desc_t tdfx_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { tdfx_lock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { tdfx_unlock, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 },
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = {drm_agp_acquire, 1, 1},
[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = {drm_agp_release, 1, 1},
[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = {drm_agp_enable, 1, 1},
@@ -115,9 +112,6 @@ MODULE_AUTHOR("VA Linux Systems, Inc.");
MODULE_DESCRIPTION("tdfx");
MODULE_PARM(tdfx, "s");
-module_init(tdfx_init);
-module_exit(tdfx_cleanup);
-
#ifndef MODULE
/* tdfx_options is called by the kernel to parse command-line options
* passed via the boot-loader (e.g., LILO). It calls the insmod option
@@ -230,7 +224,7 @@ static int tdfx_takedown(drm_device_t *dev)
}
dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
}
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
/* Clear AGP information */
if (dev->agp) {
drm_agp_mem_t *temp;
@@ -330,7 +324,7 @@ int tdfx_init(void)
drm_mem_init();
drm_proc_init(dev);
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
dev->agp = drm_agp_init();
#endif
if((retcode = drm_ctxbitmap_init(dev))) {
@@ -368,7 +362,7 @@ void tdfx_cleanup(void)
}
drm_ctxbitmap_cleanup(dev);
tdfx_takedown(dev);
-#ifdef DRM_AGP
+#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
if (dev->agp) {
drm_agp_uninit();
drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
@@ -377,6 +371,10 @@ void tdfx_cleanup(void)
#endif
}
+module_init(tdfx_init);
+module_exit(tdfx_cleanup);
+
+
int tdfx_version(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@@ -418,7 +416,6 @@ int tdfx_open(struct inode *inode, struct file *filp)
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_open_helper(inode, filp, dev))) {
- MOD_INC_USE_COUNT;
atomic_inc(&dev->total_open);
spin_lock(&dev->count_lock);
if (!dev->open_count++) {
@@ -433,12 +430,14 @@ int tdfx_open(struct inode *inode, struct file *filp)
int tdfx_release(struct inode *inode, struct file *filp)
{
drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
+ drm_device_t *dev;
int retcode = 0;
+ lock_kernel();
+ dev = priv->dev;
+
DRM_DEBUG("open_count = %d\n", dev->open_count);
if (!(retcode = drm_release(inode, filp))) {
- MOD_DEC_USE_COUNT;
atomic_inc(&dev->total_close);
spin_lock(&dev->count_lock);
if (!--dev->open_count) {
@@ -454,6 +453,8 @@ int tdfx_release(struct inode *inode, struct file *filp)
}
spin_unlock(&dev->count_lock);
}
+
+ unlock_kernel();
return retcode;
}
diff --git a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h
index 6bfcef1d0..bee840e19 100644
--- a/drivers/char/drm/tdfx_drv.h
+++ b/drivers/char/drm/tdfx_drv.h
@@ -34,8 +34,6 @@
#define _TDFX_DRV_H_
/* tdfx_drv.c */
-extern int tdfx_init(void);
-extern void tdfx_cleanup(void);
extern int tdfx_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_open(struct inode *inode, struct file *filp);
diff --git a/drivers/char/drm/vm.c b/drivers/char/drm/vm.c
index 8469097a7..01487f965 100644
--- a/drivers/char/drm/vm.c
+++ b/drivers/char/drm/vm.c
@@ -147,7 +147,6 @@ void drm_vm_open(struct vm_area_struct *vma)
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
atomic_inc(&dev->vma_count);
- MOD_INC_USE_COUNT;
#if DRM_DEBUG_CODE
vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
@@ -172,7 +171,6 @@ void drm_vm_close(struct vm_area_struct *vma)
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
- MOD_DEC_USE_COUNT;
atomic_dec(&dev->vma_count);
#if DRM_DEBUG_CODE
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 6e45bf0e0..80688e5a3 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -54,9 +54,9 @@
#define ARTTIM1 0x55
#define DRWTIM1 0x56
#define ARTTIM23 0x57
-#define ARTTIM23_INTR_CH1 0x04
#define ARTTIM23_DIS_RA2 0x04
#define ARTTIM23_DIS_RA3 0x08
+#define ARTTIM23_INTR_CH1 0x10
#define ARTTIM2 0x57
#define ARTTIM3 0x57
#define DRWTIM23 0x58
@@ -160,7 +160,6 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"):"X"):"?" );
p += sprintf(p, "PIO Mode: %s %s %s %s\n",
"?", "?", "?", "?");
-
p += sprintf(p, " %s %s\n",
(reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ",
(reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling");
@@ -589,9 +588,45 @@ no_dma_set:
static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
+ byte dma_stat = 0;
+ byte dma_alt_stat = 0;
+ byte mask = (HWIF(drive)->channel) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;
+ unsigned long dma_base = HWIF(drive)->dma_base;
+ struct pci_dev *dev = HWIF(drive)->pci_dev;
+ byte jack_slap = ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;
+
switch (func) {
case ide_dma_check:
return cmd64x_config_drive_for_dma(drive);
+ case ide_dma_end: /* returns 1 on error, 0 otherwise */
+ drive->waiting_for_dma = 0;
+ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
+ dma_stat = inb(dma_base+2); /* get DMA status */
+ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ if (jack_slap) {
+ byte dma_intr = 0;
+ byte dma_mask = (HWIF(drive)->channel) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;
+ byte dma_reg = (HWIF(drive)->channel) ? ARTTIM2 : CFR;
+ (void) pci_read_config_byte(dev, dma_reg, &dma_intr);
+ /*
+ * DAMN BMIDE is not connected to PCI space!
+ * Have to manually jack-slap that bitch!
+ * To allow the PCI side to read incoming interrupts.
+ */
+ (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); /* clear the INTR bit */
+ }
+ ide_destroy_dmatable(drive); /* purge DMA mappings */
+ return (dma_stat & 7) != 4; /* verify good DMA status */
+ case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
+ dma_stat = inb(dma_base+2);
+ (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
+#ifdef DEBUG
+ printk("%s: dma_stat: 0x%02x dma_alt_stat: 0x%02x mask: 0x%02x\n", drive->name, dma_stat, dma_alt_stat, mask);
+#endif
+ if (!(dma_alt_stat & mask)) {
+ return 0;
+ }
+ return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
default:
break;
}
@@ -609,17 +644,22 @@ static int cmd646_1_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned long dma_base = hwif->dma_base;
byte dma_stat;
- if (func == ide_dma_end) {
- drive->waiting_for_dma = 0;
- dma_stat = inb(dma_base+2); /* get DMA status */
- outb(inb(dma_base)&~1, dma_base); /* stop DMA */
- outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
- ide_destroy_dmatable(drive); /* and free any DMA resources */
- return (dma_stat & 7) != 4; /* verify good DMA status */
+ switch (func) {
+ case ide_dma_check:
+ return cmd64x_config_drive_for_dma(drive);
+ case ide_dma_end:
+ drive->waiting_for_dma = 0;
+ dma_stat = inb(dma_base+2); /* get DMA status */
+ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
+ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ ide_destroy_dmatable(drive); /* and free any DMA resources */
+ return (dma_stat & 7) != 4; /* verify good DMA status */
+ default:
+ break;
}
/* Other cases are done by generic IDE-DMA code. */
- return cmd64x_dmaproc(func, drive);
+ return ide_dmaproc(func, drive);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -671,6 +711,7 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name)
(void) pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x10);
#endif
+
/* Setup interrupts. */
(void) pci_read_config_byte(dev, MRDMODE, &mrdmode);
mrdmode &= ~(0x30);
@@ -728,8 +769,8 @@ void __init ide_init_cmd64x (ide_hwif_t *hwif)
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
- hwif->tuneproc = &cmd64x_tuneproc;
- hwif->speedproc = &cmd64x_tune_chipset;
+ hwif->tuneproc = &cmd64x_tuneproc;
+ hwif->speedproc = &cmd64x_tune_chipset;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 74d3018c5..270cacc61 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -45,6 +45,7 @@ extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);
const char *quirk_drives[] = {
"QUANTUM FIREBALLlct08 08",
"QUANTUM FIREBALLP KA6.4",
+ "QUANTUM FIREBALLP LM20.4",
"QUANTUM FIREBALLP LM20.5",
NULL
};
@@ -224,6 +225,14 @@ static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev)
return ((int) (class_rev > 0x02) ? 1 : 0);
}
+static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev)
+{
+ unsigned int class_rev;
+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+ class_rev &= 0xff;
+ return ((int) (class_rev > 0x01) ? 1 : 0);
+}
+
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
struct hd_driveid *id = drive->id;
@@ -469,6 +478,11 @@ int hpt3xx_quirkproc (ide_drive_t *drive)
void hpt3xx_intrproc (ide_drive_t *drive)
{
+ if (drive->quirk_list) {
+ /* drives in the quirk_list may not like intr setups/cleanups */
+ } else {
+ OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
+ }
}
void hpt3xx_maskproc (ide_drive_t *drive, int mask)
@@ -556,11 +570,15 @@ no_dma_set:
*/
int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
- byte reg50h = 0, reg52h = 0, reg5ah = 0;
+ byte reg50h = 0, reg52h = 0, reg5ah = 0, dma_stat = 0;
+ unsigned long dma_base = HWIF(drive)->dma_base;
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
+ case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
+ dma_stat = inb(dma_base+2);
+ return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
case ide_dma_lostirq:
pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, &reg52h);
@@ -651,6 +669,10 @@ void __init ide_init_hpt366 (ide_hwif_t *hwif)
hwif->intrproc = &hpt3xx_intrproc;
hwif->maskproc = &hpt3xx_maskproc;
+ if (pci_rev2_check_hpt3xx(hwif->pci_dev)) {
+ /* do nothing now but will split device types */
+ }
+
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
if (pci_rev_check_hpt3xx(hwif->pci_dev)) {
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index e9a34afc1..c15e7ee38 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -423,6 +423,14 @@ static int dma_timer_expiry (ide_drive_t *drive)
printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat);
#endif /* DEBUG */
+#if 1
+ HWGROUP(drive)->expiry = NULL; /* one free ride for now */
+#endif
+
+ if (dma_stat & 2) { /* ERROR */
+ byte stat = GET_STAT();
+ return ide_error(drive, "dma_timer_expiry", stat);
+ }
if (dma_stat & 1) /* DMAing */
return WAIT_CMD;
return 0;
@@ -495,6 +503,12 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
return (dma_stat & 7) != 4; /* verify good DMA status */
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
dma_stat = inb(dma_base+2);
+#if 0 /* do not set unless you know what you are doing */
+ if (dma_stat & 4) {
+ byte stat = GET_STAT();
+ outb(dma_base+2, dma_stat & 0xE4);
+ }
+#endif
return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
case ide_dma_bad_drive:
case ide_dma_good_drive:
diff --git a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c
index 967b91e55..e46d16e7f 100644
--- a/drivers/ide/ide-features.c
+++ b/drivers/ide/ide-features.c
@@ -39,8 +39,6 @@
#include <asm/io.h>
#include <asm/bitops.h>
-#define SETFEATURES_CONTROL_REG (0) /* some arch's may need */
-
/*
* A Verbose noise maker for debugging on the attempted transfer rates.
*/
@@ -310,7 +308,7 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
OUT_BYTE(speed, IDE_NSECTOR_REG);
OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
- if ((IDE_CONTROL_REG) && (SETFEATURES_CONTROL_REG))
+ if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
udelay(1);
/*
diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c
index 8c9354394..b09b889d7 100644
--- a/drivers/ide/ide-pci.c
+++ b/drivers/ide/ide-pci.c
@@ -39,6 +39,7 @@
#define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1})
#define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246})
#define DEVID_PDC20262 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262})
+#define DEVID_PDC20265 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265})
#define DEVID_PDC20267 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267})
#define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000})
#define DEVID_RZ1001 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001})
@@ -318,6 +319,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 },
{DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 },
{DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 },
+ {DEVID_PDC20265,"PDC20265", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 },
{DEVID_PDC20267,"PDC20267", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 },
{DEVID_RZ1000, "RZ1000", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_RZ1001, "RZ1001", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
@@ -362,6 +364,7 @@ static unsigned int __init ide_special_settings (struct pci_dev *dev, const char
case PCI_DEVICE_ID_TTI_HPT366:
case PCI_DEVICE_ID_PROMISE_20246:
case PCI_DEVICE_ID_PROMISE_20262:
+ case PCI_DEVICE_ID_PROMISE_20265:
case PCI_DEVICE_ID_PROMISE_20267:
case PCI_DEVICE_ID_ARTOP_ATP850UF:
case PCI_DEVICE_ID_ARTOP_ATP860:
@@ -633,6 +636,7 @@ check_if_enabled:
hwif->autodma = 1;
if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 298603394..f36dbd8ff 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -3913,10 +3913,14 @@ static int idetape_get_logical_blk (ide_drive_t *drive, int logical_blk_num, int
#endif
clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
position = idetape_read_position(drive);
+ if (position >= 3000 && position < 3080)
+ position += 32;
if (position >= 2980 && position < 3000)
position = 3000;
else
position += 60;
+ if (position >= 2980 && position < 3000)
+ position = 3000;
printk(KERN_INFO "ide-tape: %s: blank block detected, positioning tape to block %d\n", tape->name, position);
idetape_position_tape(drive, position, 0, 1);
cnt += 40;
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 6fe3f9d36..d9ef9510f 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -481,13 +481,27 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecoun
*/
static inline int drive_is_ready (ide_drive_t *drive)
{
+ byte stat = 0;
if (drive->waiting_for_dma)
return HWIF(drive)->dmaproc(ide_dma_test_irq, drive);
#if 0
udelay(1); /* need to guarantee 400ns since last command was issued */
#endif
-// if (GET_STAT() & BUSY_STAT) /* Note: this may clear a pending IRQ!! */
- if (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT)
+
+#ifdef CONFIG_IDEPCI_SHARE_IRQ
+ /*
+ * We do a passive status test under shared PCI interrupts on
+ * cards that truly share the ATA side interrupt, but may also share
+ * an interrupt with another pci card/device. We make no assumptions
+ * about possible isa-pnp and pci-pnp issues yet.
+ */
+ if (IDE_CONTROL_REG)
+ stat = GET_ALTSTAT();
+ else
+#endif /* CONFIG_IDEPCI_SHARE_IRQ */
+ stat = GET_STAT(); /* Note: this may clear a pending IRQ!! */
+
+ if (stat & BUSY_STAT)
return 0; /* drive busy: definitely not interrupting */
return 1; /* drive ready: *might* be interrupting */
}
@@ -2635,6 +2649,22 @@ static int ide_ioctl (struct inode *inode, struct file *file,
}
drive->nice1 = (arg >> IDE_NICE_1) & 1;
return 0;
+ case HDIO_DRIVE_RESET:
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+ (void) ide_do_reset(drive);
+ if (drive->suspend_reset) {
+/*
+ * APM WAKE UP todo !!
+ * int nogoodpower = 1;
+ * while(nogoodpower) {
+ * check_power1() or check_power2()
+ * nogoodpower = 0;
+ * }
+ * HWIF(drive)->multiproc(drive);
+ */
+ return ide_revalidate_disk(inode->i_rdev);
+ }
+ return 0;
case BLKROSET:
case BLKROGET:
@@ -3469,6 +3499,7 @@ int ide_register_subdriver (ide_drive_t *drive, ide_driver_t *driver, int versio
drive->nice1 = 1;
}
drive->revalidate = 1;
+ drive->suspend_reset = 0;
#ifdef CONFIG_PROC_FS
ide_add_proc_entries(drive->proc, generic_subdriver_entries, drive);
ide_add_proc_entries(drive->proc, driver->proc, drive);
diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c
index 66a123841..6385cd81b 100644
--- a/drivers/ide/pdc202xx.c
+++ b/drivers/ide/pdc202xx.c
@@ -101,11 +101,18 @@ char *pdc202xx_ultra_verbose (u32 drive_pci, u16 slow_cable)
return(pdc202xx_dma_verbose(drive_pci));
}
-static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count)
+char *pdc202xx_interrupt_verbose (u8 sc1d)
{
- char *p = buffer;
+ char *p = NULL;
+ p += sprintf(p,"0x%02x ", sc1d);
+ return (char *)p;
+}
+
+static char * pdc202xx_info (char *buf, struct pci_dev *dev)
+{
+ char *p = buf;
- u32 bibma = pci_resource_start(bmide_dev, 4);
+ u32 bibma = pci_resource_start(dev, 4);
u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0;
u16 reg50h = 0, pmask = (1<<10), smask = (1<<11);
u8 hi = 0, lo = 0;
@@ -125,16 +132,19 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
u8 sc1e = inb_p((unsigned short)bibma + 0x1e);
u8 sc1f = inb_p((unsigned short)bibma + 0x1f);
- pci_read_config_word(bmide_dev, 0x50, &reg50h);
- pci_read_config_dword(bmide_dev, 0x60, &reg60h);
- pci_read_config_dword(bmide_dev, 0x64, &reg64h);
- pci_read_config_dword(bmide_dev, 0x68, &reg68h);
- pci_read_config_dword(bmide_dev, 0x6c, &reg6ch);
+ pci_read_config_word(dev, 0x50, &reg50h);
+ pci_read_config_dword(dev, 0x60, &reg60h);
+ pci_read_config_dword(dev, 0x64, &reg64h);
+ pci_read_config_dword(dev, 0x68, &reg68h);
+ pci_read_config_dword(dev, 0x6c, &reg6ch);
- switch(bmide_dev->device) {
+ switch(dev->device) {
case PCI_DEVICE_ID_PROMISE_20267:
p += sprintf(p, "\n PDC20267 Chipset.\n");
break;
+ case PCI_DEVICE_ID_PROMISE_20265:
+ p += sprintf(p, "\n PDC20265 Chipset.\n");
+ break;
case PCI_DEVICE_ID_PROMISE_20262:
p += sprintf(p, "\n PDC20262 Chipset.\n");
break;
@@ -174,10 +184,12 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
(sc1b & 0x01) ? "MASTER" : "PCI ");
p += sprintf(p, " %s %s\n",
(sc1d & 0x08) ? "Error " :
+ ((sc1d & 0x05) == 0x05) ? "Not My INTR " :
(sc1d & 0x04) ? "Interrupting" :
(sc1d & 0x02) ? "FIFO Full " :
(sc1d & 0x01) ? "FIFO Empty " : "????????????",
(sc1d & 0x80) ? "Error " :
+ ((sc1d & 0x50) == 0x50) ? "Not My INTR " :
(sc1d & 0x40) ? "Interrupting" :
(sc1d & 0x20) ? "FIFO Full " :
(sc1d & 0x10) ? "FIFO Empty " : "????????????");
@@ -195,13 +207,27 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
#if 0
p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n");
#endif
-
+ return (char *)p;
+}
+
+static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+ char *p = buffer;
+ p = pdc202xx_info(buffer, bmide_dev);
return p-buffer; /* => must be less than 4k! */
}
#endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
byte pdc202xx_proc = 0;
+const char *pdc_quirk_drives[] = {
+ "QUANTUM FIREBALLlct08 08",
+ "QUANTUM FIREBALLP KA6.4",
+ "QUANTUM FIREBALLP LM20.4",
+ "QUANTUM FIREBALLP LM20.5",
+ NULL
+};
+
extern char *ide_xfer_verbose (byte xfer_rate);
/* A Register */
@@ -314,6 +340,26 @@ static void decode_registers (byte registers, byte value)
#endif /* PDC202XX_DECODE_REGISTER_INFO */
+static int check_in_drive_lists (ide_drive_t *drive, const char **list)
+{
+ struct hd_driveid *id = drive->id;
+
+ if (pdc_quirk_drives == list) {
+ while (*list) {
+ if (strstr(id->model, *list++)) {
+ return 2;
+ }
+ }
+ } else {
+ while (*list) {
+ if (!strcmp(*list++,id->model)) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -473,7 +519,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
byte CLKSPD = IN_BYTE(high_16 + 0x11);
byte udma_33 = ultra ? (inb(high_16 + 0x001f) & 1) : 0;
byte udma_66 = ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0;
- byte udma_100 = ((dev->device == PCI_DEVICE_ID_PROMISE_20267) && udma_66) ? 1 : 0;
+ byte udma_100 = (((dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20267)) && udma_66) ? 1 : 0;
/*
* Set the control register to use the 66Mhz system
@@ -655,14 +701,37 @@ no_dma_set:
return HWIF(drive)->dmaproc(dma_func, drive);
}
+int pdc202xx_quirkproc (ide_drive_t *drive)
+{
+ return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
+}
+
/*
* pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
*/
int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
+ byte dma_stat = 0, sc1d = 0;
+ unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4);
+ unsigned long dma_base = HWIF(drive)->dma_base;
+
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
+ case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
+ dma_stat = inb(dma_base+2);
+ sc1d = inb(high_16 + 0x001d);
+ if (HWIF(drive)->channel) {
+ if ((sc1d & 0x50) == 0x50) goto somebody_else;
+ else if ((sc1d & 0x40) == 0x40)
+ return (dma_stat & 4) == 4;
+ } else {
+ if ((sc1d & 0x05) == 0x05) goto somebody_else;
+ else if ((sc1d & 0x04) == 0x04)
+ return (dma_stat & 4) == 4;
+ }
+somebody_else:
+ return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
case ide_dma_lostirq:
case ide_dma_timeout:
if (HWIF(drive)->resetproc != NULL)
@@ -696,6 +765,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
byte secondary_mode = inb(high_16 + 0x001b);
if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
+ (dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
(dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
int i = 0;
/*
@@ -725,7 +795,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
byte irq = 0, irq2 = 0;
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */
- if ((irq != irq2) && (dev->device != PCI_DEVICE_ID_PROMISE_20267)) {
+ if ((irq != irq2) && (dev->device != PCI_DEVICE_ID_PROMISE_20265) && (dev->device != PCI_DEVICE_ID_PROMISE_20267)) {
pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */
printk("%s: pci-config space interrupt mirror fixed.\n", name);
}
@@ -779,17 +849,21 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif)
unsigned short CIS;
pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
- return ((CIS & mask) ? 0 : 1);
+ return ((CIS & mask) ? 0 : 1);
}
void __init ide_init_pdc202xx (ide_hwif_t *hwif)
{
hwif->tuneproc = &pdc202xx_tune_drive;
hwif->speedproc = &pdc202xx_tune_chipset;
+ hwif->quirkproc = &pdc202xx_quirkproc;
if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
- (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267))
+ (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) ||
+ (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
hwif->resetproc = &pdc202xx_reset;
+ hwif->tri_proc = &pdc202xx_tristate;
+ }
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids
index 068c2fd14..288caf5ce 100644
--- a/drivers/pci/pci.ids
+++ b/drivers/pci/pci.ids
@@ -983,6 +983,7 @@
1058 Electronics & Telecommunications RSH
1059 Teknor Industrial Computers Inc
105a Promise Technology, Inc.
+ 0d30 20265
4d30 20267
4d33 20246
4d38 20262
diff --git a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
index 0556c7906..6b0a9e1ae 100644
--- a/drivers/pcmcia/yenta.c
+++ b/drivers/pcmcia/yenta.c
@@ -596,7 +596,7 @@ static void yenta_clear_maps(pci_socket_t *socket)
/*
* Initialize the standard cardbus registers
*/
-static int yenta_config_init(pci_socket_t *socket)
+static void yenta_config_init(pci_socket_t *socket)
{
u16 bridge;
struct pci_dev *dev = socket->dev;
diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c
index a3d8d3d42..31be1c0e2 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/uhci.c
@@ -1296,6 +1296,7 @@ static int uhci_submit_urb(struct urb *urb)
struct uhci *uhci;
unsigned long flags;
struct urb *u;
+ int bustime;
if (!urb)
return -EINVAL;
@@ -1325,13 +1326,40 @@ static int uhci_submit_urb(struct urb *urb)
ret = uhci_submit_control(urb);
break;
case PIPE_INTERRUPT:
- ret = uhci_submit_interrupt(urb);
+ if (urb->bandwidth == 0) { /* not yet checked/allocated */
+ bustime = usb_check_bandwidth (urb->dev, urb);
+ if (bustime < 0)
+ ret = bustime;
+ else {
+ ret = uhci_submit_interrupt(urb);
+ if (ret == -EINPROGRESS)
+ usb_claim_bandwidth (urb->dev, urb, bustime, 0);
+ }
+ } else { /* bandwidth is already set */
+ ret = uhci_submit_interrupt(urb);
+ }
break;
case PIPE_BULK:
ret = uhci_submit_bulk(urb, u);
break;
case PIPE_ISOCHRONOUS:
- ret = uhci_submit_isochronous(urb);
+ if (urb->bandwidth == 0) { /* not yet checked/allocated */
+ if (urb->number_of_packets <= 0) {
+ ret = -EINVAL;
+ break;
+ }
+ bustime = usb_check_bandwidth (urb->dev, urb);
+ if (bustime < 0) {
+ ret = bustime;
+ break;
+ }
+
+ ret = uhci_submit_isochronous(urb);
+ if (ret == -EINPROGRESS)
+ usb_claim_bandwidth (urb->dev, urb, bustime, 1);
+ } else { /* bandwidth is already set */
+ ret = uhci_submit_isochronous(urb);
+ }
break;
}
@@ -1387,6 +1415,10 @@ static void uhci_transfer_result(struct urb *urb)
case PIPE_CONTROL:
case PIPE_BULK:
case PIPE_ISOCHRONOUS:
+ /* Release bandwidth for Interrupt or Isoc. transfers */
+ /* Spinlock needed ? */
+ if (urb->bandwidth)
+ usb_release_bandwidth (urb->dev, urb, 1);
uhci_unlink_generic(urb);
break;
case PIPE_INTERRUPT:
@@ -1394,8 +1426,13 @@ static void uhci_transfer_result(struct urb *urb)
urb->complete(urb);
if (urb->interval)
uhci_reset_interrupt(urb);
- else
+ else {
+ /* Release bandwidth for Interrupt or Isoc. transfers */
+ /* Spinlock needed ? */
+ if (urb->bandwidth)
+ usb_release_bandwidth (urb->dev, urb, 0);
uhci_unlink_generic(urb);
+ }
return; /* <-- Note the return */
}
@@ -1476,6 +1513,21 @@ static int uhci_unlink_urb(struct urb *urb)
if (usb_pipedevice(urb->pipe) == uhci->rh.devnum)
return rh_unlink_urb(urb);
+ /* Release bandwidth for Interrupt or Isoc. transfers */
+ /* Spinlock needed ? */
+ if (urb->bandwidth) {
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_INTERRUPT:
+ usb_release_bandwidth (urb->dev, urb, 0);
+ break;
+ case PIPE_ISOCHRONOUS:
+ usb_release_bandwidth (urb->dev, urb, 1);
+ break;
+ default:
+ break;
+ }
+ }
+
if (urb->status == -EINPROGRESS) {
uhci_unlink_generic(urb);
diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
index 8300fc7d2..48a5df48e 100644
--- a/drivers/usb/usb-ohci.c
+++ b/drivers/usb/usb-ohci.c
@@ -11,6 +11,11 @@
*
* History:
*
+ * 2000/06/28 use PCI hotplug framework, for better power management
+ * and for Cardbus support (David Brownell)
+ * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling
+ * when the controller loses power; handle UE; cleanup; ...
+ *
* v5.2 1999/12/07 URB 3rd preview,
* v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi)
* v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume
@@ -24,8 +29,6 @@
* v2.1 1999/05/09 code clean up
* v2.0 1999/05/04
* v1.0 1999/04/27 initial release
- *
-
*/
#include <linux/config.h>
@@ -38,6 +41,7 @@
#include <linux/malloc.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
+#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h> /* for in_interrupt() */
@@ -50,13 +54,15 @@
#include <asm/unaligned.h>
#define OHCI_USE_NPS // force NoPowerSwitching mode
+// #define OHCI_VERBOSE_DEBUG /* not always helpful */
#include "usb-ohci.h"
-#include <linux/pm.h>
-static int handle_pm_event (struct pm_dev *dev, pm_request_t rqst, void *data);
#ifdef CONFIG_PMAC_PBOOK
+/* All this PMAC_PBOOK stuff should disappear when those
+ * platforms fully support the 2.4 kernel PCI APIs.
+ */
#include <linux/adb.h>
#include <linux/pmu.h>
#endif
@@ -105,13 +111,15 @@ static int sohci_get_current_frame_number (struct usb_device * dev);
static void urb_print (urb_t * urb, char * str, int small)
{
unsigned int pipe= urb->pipe;
- int i, len;
if (!urb->dev || !urb->dev->bus) {
dbg("%s URB: no dev", str);
return;
}
+#ifndef OHCI_VERBOSE_DEBUG
+ if (urb->status != 0)
+#endif
dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)",
str,
sohci_get_current_frame_number (urb->dev),
@@ -124,7 +132,10 @@ static void urb_print (urb_t * urb, char * str, int small)
urb->actual_length,
urb->transfer_buffer_length,
urb->status, urb->status);
+#ifdef OHCI_VERBOSE_DEBUG
if (!small) {
+ int i, len;
+
if (usb_pipecontrol (pipe)) {
printk (KERN_DEBUG __FILE__ ": cmd(8):");
for (i = 0; i < 8 ; i++)
@@ -142,6 +153,7 @@ static void urb_print (urb_t * urb, char * str, int small)
printk ("%s stat:%d\n", i < len? "...": "", urb->status);
}
}
+#endif
}
/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
@@ -307,7 +319,7 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose)
static void ohci_dump (ohci_t *controller, int verbose)
{
- dbg ("OHCI controller %s state", controller->ohci_dev->slot_name);
+ dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name);
// dumps some of the state we know about
ohci_dump_status (controller);
@@ -421,7 +433,7 @@ static int sohci_submit_urb (urb_t * urb)
if (usb_pipedevice (pipe) == ohci->rh.devnum)
return rh_submit_urb (urb);
- /* when controller's hung, permit only hub cleanup attempts
+ /* when controller's hung, permit only roothub cleanup attempts
* such as powering down ports */
if (ohci->disabled)
return -ESHUTDOWN;
@@ -509,6 +521,7 @@ static int sohci_submit_urb (urb_t * urb)
/*-------------------------------------------------------------------------*/
/* deactivate all TDs and remove the private part of the URB */
+/* interrupt callers must use async unlink mode */
static int sohci_unlink_urb (urb_t * urb)
{
@@ -537,21 +550,34 @@ static int sohci_unlink_urb (urb_t * urb)
/* URB active? */
if (urb->status == USB_ST_URB_PENDING && !ohci->disabled) {
urb_priv_t * urb_priv = urb->hcpriv;
- urb_priv->state = URB_DEL;
- /* we want to delete the TDs of an URB from an ed
- * request the deletion, it will be handled at the
- * next USB-frame */
+ /* interrupt code may not sleep; it must use
+ * async status return to unlink pending urbs.
+ */
+ if (!(urb->transfer_flags & USB_ASYNC_UNLINK)
+ && in_interrupt ()) {
+ err ("bug in call from %p; use async!",
+ __builtin_return_address(0));
+ return -EWOULDBLOCK;
+ }
+
+
+ /* flag the urb and its TDs for deletion in some
+ * upcoming SF interrupt delete list processing
+ */
+ urb_priv->state = URB_DEL;
spin_lock_irqsave (&usb_ed_lock, flags);
ep_rm_ed (urb->dev, urb_priv->ed);
urb_priv->ed->state |= ED_URB_DEL;
spin_unlock_irqrestore (&usb_ed_lock, flags);
+
if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
usb_dec_dev_use (urb->dev);
add_wait_queue (&op_wakeup, &wait);
current->state = TASK_UNINTERRUPTIBLE;
- if (!schedule_timeout (HZ / 10)) /* wait until all TDs are deleted */
+ /* wait until all TDs are deleted */
+ if (!schedule_timeout (HZ / 10))
err("unlink URB timeout!");
remove_wait_queue (&op_wakeup, &wait);
urb->status = -ENOENT;
@@ -593,7 +619,8 @@ static int sohci_alloc_dev (struct usb_device *usb_dev)
/*-------------------------------------------------------------------------*/
-/* free private data space of usb device */
+/* may be called from interrupt context */
+/* frees private data space of usb device */
static int sohci_free_dev (struct usb_device * usb_dev)
{
@@ -604,7 +631,8 @@ static int sohci_free_dev (struct usb_device * usb_dev)
struct ohci_device * dev = usb_to_ohci (usb_dev);
ohci_t * ohci = usb_dev->bus->hcpriv;
- if (!dev) return 0;
+ if (!dev)
+ return 0;
if (usb_dev->devnum >= 0) {
@@ -613,7 +641,8 @@ static int sohci_free_dev (struct usb_device * usb_dev)
for(i = 0; i < NUM_EDS; i++) {
ed = &(dev->ed[i]);
if (ed->state != ED_NEW) {
- if (ed->state == ED_OPER) ep_unlink (ohci, ed);
+ if (ed->state == ED_OPER)
+ ep_unlink (ohci, ed);
ep_rm_ed (usb_dev, ed);
ed->state = ED_DEL;
cnt++;
@@ -633,7 +662,6 @@ static int sohci_free_dev (struct usb_device * usb_dev)
*/
warn ("TD leak, %d", cnt);
-
} else if (!in_interrupt ()) {
/* SF interrupt handler calls dl_del_list */
add_wait_queue (&op_wakeup, &wait);
@@ -961,24 +989,31 @@ static ed_t * ep_add_ed (struct usb_device * usb_dev, unsigned int pipe, int int
/* request the removal of an endpoint
* put the ep on the rm_list and request a stop of the bulk or ctrl list
- * real removal is done at the next start of frame (SOF) hardware interrupt */
+ * real removal is done at the next start frame (SF) hardware interrupt */
static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed)
{
unsigned int frame;
ohci_t * ohci = usb_dev->bus->hcpriv;
- if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) return;
+ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL))
+ return;
ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
-
- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
- writel (OHCI_INTR_SF, &ohci->regs->intrenable); /* enable sof interrupt */
+
+ if (!ohci->disabled) {
+ /* enable SOF interrupt */
+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
+ }
frame = le16_to_cpu (ohci->hcca.frame_no) & 0x1;
ed->ed_rm_list = ohci->ed_rm_list[frame];
ohci->ed_rm_list[frame] = ed;
+ if (ohci->disabled)
+ return;
+
switch (ed->type) {
case CTRL: /* stop CTRL list */
writel (ohci->hc_control &= ~OHCI_CTRL_CLE, &ohci->regs->control);
@@ -1259,11 +1294,16 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
if ((ed->type & 3) == BULK) bulk |= 1;
}
- if (ctrl) writel (0, &ohci->regs->ed_controlcurrent); /* reset CTRL list */
- if (bulk) writel (0, &ohci->regs->ed_bulkcurrent); /* reset BULK list */
- if (!ohci->ed_rm_list[!frame]) { /* enable CTRL and BULK lists */
- ohci->hc_control |= OHCI_CTRL_CLE | OHCI_CTRL_BLE;
- writel (ohci->hc_control, &ohci->regs->control);
+ /* maybe reenable CTRL and BULK lists */
+ if (!ohci->disabled) {
+ if (ctrl) /* reset CTRL list */
+ writel (0, &ohci->regs->ed_controlcurrent);
+ if (bulk) /* reset BULK list */
+ writel (0, &ohci->regs->ed_bulkcurrent);
+ if (!ohci->ed_rm_list[!frame]) {
+ ohci->hc_control |= OHCI_CTRL_CLE | OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
}
ohci->ed_rm_list[frame] = NULL;
@@ -1412,7 +1452,7 @@ static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len)
num_ports = readl (&ohci->regs->roothub.a) & RH_A_NDP;
if (num_ports > MAX_ROOT_PORTS) {
- err ("bogus NDP=%d for OHCI %s", num_ports,
+ err ("bogus NDP=%d for OHCI usb-%s", num_ports,
ohci->ohci_dev->slot_name);
err ("rereads as NDP=%d",
readl (&ohci->regs->roothub.a) & RH_A_NDP);
@@ -1677,7 +1717,7 @@ static int rh_submit_urb (urb_t * urb)
}
#ifdef DEBUG
- ohci_dump_roothub (ohci, 0);
+ // ohci_dump_roothub (ohci, 0);
#endif
len = min(len, leni);
@@ -1733,7 +1773,7 @@ static int hc_reset (ohci_t * ohci)
/* Disable HC interrupts */
writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
- dbg("USB HC reset_hc %s: ctrl = %x ;",
+ dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;",
ohci->ohci_dev->slot_name,
readl (&ohci->regs->control));
@@ -1749,7 +1789,6 @@ static int hc_reset (ohci_t * ohci)
}
udelay (1);
}
- ohci->disabled = 0;
return 0;
}
@@ -1766,6 +1805,8 @@ static int hc_start (ohci_t * ohci)
struct usb_device * usb_dev;
struct ohci_device * dev;
+ ohci->disabled = 1;
+
/* Tell the controller where the control and bulk lists are
* The lists are empty now. */
@@ -1811,6 +1852,7 @@ static int hc_start (ohci_t * ohci)
return -ENODEV;
}
+ ohci->disabled = 0;
return 0;
}
@@ -1834,7 +1876,7 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
if (ints & OHCI_INTR_UE) {
ohci->disabled++;
- err ("OHCI Unrecoverable Error, controller %s disabled",
+ err ("OHCI Unrecoverable Error, controller usb-%s disabled",
ohci->ohci_dev->slot_name);
// e.g. due to PCI Master/Target Abort
@@ -1872,28 +1914,9 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
/*-------------------------------------------------------------------------*/
-/* reinitialize after controller reset */
-
-static void hc_reinit_ohci (ohci_t *ohci)
-{
- int i;
-
- /* for load balancing of the interrupt branches */
- for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
- for (i = 0; i < NUM_INTS; i++) ohci->hcca.int_table[i] = 0;
-
- ohci->ed_rm_list [0] = NULL;
- ohci->ed_rm_list [1] = NULL;
-
- /* end of control and bulk lists */
- ohci->ed_isotail = NULL;
- ohci->ed_controltail = NULL;
- ohci->ed_bulktail = NULL;
-}
-
/* allocate OHCI */
-static ohci_t * hc_alloc_ohci (void * mem_base)
+static ohci_t * __devinit hc_alloc_ohci (void * mem_base)
{
ohci_t * ohci;
struct usb_bus * bus;
@@ -1915,6 +1938,7 @@ static ohci_t * hc_alloc_ohci (void * mem_base)
ohci->bus = bus;
bus->hcpriv = (void *) ohci;
+ ohci->disabled = 1;
return ohci;
}
@@ -1926,7 +1950,7 @@ static ohci_t * hc_alloc_ohci (void * mem_base)
static void hc_release_ohci (ohci_t * ohci)
{
- dbg ("USB HC release ohci %s", ohci->ohci_dev->slot_name);
+ dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name);
/* disconnect all devices */
if (ohci->bus->root_hub)
@@ -1943,6 +1967,9 @@ static void hc_release_ohci (ohci_t * ohci)
usb_deregister_bus (ohci->bus);
usb_free_bus (ohci->bus);
+
+ list_del (&ohci->ohci_hcd_list);
+ INIT_LIST_HEAD (&ohci->ohci_hcd_list);
/* unmap the IO address space */
iounmap (ohci->regs);
@@ -1954,8 +1981,11 @@ static void hc_release_ohci (ohci_t * ohci)
/* Increment the module usage count, start the control thread and
* return success. */
+
+static struct pci_driver ohci_pci_driver;
-static int hc_found_ohci (struct pci_dev *dev, int irq, void * mem_base)
+static int __devinit
+hc_found_ohci (struct pci_dev *dev, int irq, void * mem_base)
{
ohci_t * ohci;
char buf[8], *bufp = buf;
@@ -1967,7 +1997,7 @@ static int hc_found_ohci (struct pci_dev *dev, int irq, void * mem_base)
#endif
printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
(unsigned long) mem_base, bufp);
- printk(KERN_INFO __FILE__ ": pci slot %s, %s\n", dev->slot_name, dev->name);
+ printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
ohci = hc_alloc_ohci (mem_base);
if (!ohci) {
@@ -1984,58 +2014,263 @@ static int hc_found_ohci (struct pci_dev *dev, int irq, void * mem_base)
return -ENODEV;
}
+ /* FIXME this is a second HC reset; why?? */
writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
wait_ms (10);
+
usb_register_bus (ohci->bus);
- if (request_irq (irq, hc_interrupt, SA_SHIRQ, "usb-ohci", ohci) == 0) {
- struct pm_dev *pmdev;
-
- ohci->irq = irq;
- hc_start (ohci);
+ if (request_irq (irq, hc_interrupt, SA_SHIRQ,
+ ohci_pci_driver.name, ohci) != 0) {
+ err ("request interrupt %d failed", irq);
+ hc_release_ohci (ohci);
+ return -EBUSY;
+ }
+ ohci->irq = irq;
- pmdev = pm_register (PM_PCI_DEV,
- PM_PCI_ID(dev),
- handle_pm_event);
- if (pmdev)
- pmdev->data = ohci;
+ if (hc_start (ohci) < 0) {
+ err ("can't start usb-%s", dev->slot_name);
+ hc_release_ohci (ohci);
+ return -EBUSY;
+ }
#ifdef DEBUG
- ohci_dump (ohci, 1);
+ ohci_dump (ohci, 1);
#endif
- return 0;
- }
- err("request interrupt %d failed", irq);
- hc_release_ohci (ohci);
- return -EBUSY;
+ return 0;
}
/*-------------------------------------------------------------------------*/
-
-static int hc_start_ohci (struct pci_dev * dev)
+
+#ifdef CONFIG_PM
+
+/* controller died; cleanup debris, then restart */
+/* must not be called from interrupt context */
+
+static void hc_restart (ohci_t *ohci)
+{
+ int temp;
+ int i;
+
+ ohci->disabled = 1;
+ if (ohci->bus->root_hub)
+ usb_disconnect (&ohci->bus->root_hub);
+
+ /* empty the interrupt branches */
+ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
+ for (i = 0; i < NUM_INTS; i++) ohci->hcca.int_table[i] = 0;
+
+ /* no EDs to remove */
+ ohci->ed_rm_list [0] = NULL;
+ ohci->ed_rm_list [1] = NULL;
+
+ /* empty control and bulk lists */
+ ohci->ed_isotail = NULL;
+ ohci->ed_controltail = NULL;
+ ohci->ed_bulktail = NULL;
+
+ if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
+ err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
+ } else
+ dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
+}
+
+#endif /* CONFIG_PM */
+
+/*-------------------------------------------------------------------------*/
+
+/* configured so that an OHCI device is always provided */
+/* always called with process context; sleeping is OK */
+
+static int __devinit
+ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
- unsigned long mem_base;
+ unsigned long mem_resource;
+ u8 latency, limit;
+ void *mem_base;
if (pci_enable_device(dev) < 0)
return -ENODEV;
+ /* controller writes into our memory */
pci_set_master (dev);
- mem_base = pci_resource_start(dev, 0);
- mem_base = (unsigned long) ioremap_nocache (mem_base, 4096);
+ pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
+ if (latency) {
+ pci_read_config_byte (dev, PCI_MAX_LAT, &limit);
+ if (limit && limit < latency) {
+ dbg ("PCI latency reduced to max %d", limit);
+ pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit);
+ }
+ }
+ /* we read its hardware registers as memory */
+ mem_resource = pci_resource_start(dev, 0);
+ /* request_mem_region ... */
+ mem_base = ioremap_nocache (mem_resource, 4096);
if (!mem_base) {
err("Error mapping OHCI memory");
return -EFAULT;
}
- return hc_found_ohci (dev, dev->irq, (void *) mem_base);
+
+ return hc_found_ohci (dev, dev->irq, mem_base);
}
/*-------------------------------------------------------------------------*/
+/* may be called from interrupt context [interface spec] */
+/* may be called without controller present */
+/* may be called with controller, bus, and devices active */
+
+static void __devexit
+ohci_pci_remove (struct pci_dev *dev)
+{
+ ohci_t *ohci = (ohci_t *) dev->driver_data;
+
+ dbg ("remove %s controller usb-%s%s%s",
+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
+ dev->slot_name,
+ ohci->disabled ? " (disabled)" : "",
+ in_interrupt () ? " in interrupt" : ""
+ );
+
+ /* don't wake up sleeping controllers, or block in interrupt context */
+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER || in_interrupt ()) {
+ dbg ("controller being disabled");
+ ohci->disabled = 1;
+ }
+
+ /* on return, USB will always be reset (if present) */
+ if (ohci->disabled)
+ writel (ohci->hc_control = OHCI_USB_RESET,
+ &ohci->regs->control);
+
+ hc_release_ohci (ohci);
+}
+
+
+#ifdef CONFIG_PM
+
+/*-------------------------------------------------------------------------*/
+
+static void
+ohci_pci_suspend (struct pci_dev *dev)
+{
+ ohci_t *ohci = (ohci_t *) dev->driver_data;
+
+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
+ dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
+ return;
+ }
+
+ /* act as if usb suspend can always be used */
+ info ("USB suspend: usb-%s", dev->slot_name);
+#ifdef CONFIG_PMAC_PBOOK
+ disable_irq (ohci->irq);
+ /* else, 2.4 assumes shared irqs -- don't disable */
+#endif
+ ohci->hc_control = OHCI_USB_SUSPEND;
+ writel (ohci->hc_control, &ohci->regs->control);
+ wait_ms (10);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+ohci_pci_resume (struct pci_dev *dev)
+{
+ ohci_t *ohci = (ohci_t *) dev->driver_data;
+ int temp;
+
+ /* did we suspend, or were we powered off? */
+ ohci->hc_control = readl (&ohci->regs->control);
+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
+
+#ifdef DEBUG
+ /* the registers may look crazy here */
+ ohci_dump_status (ohci);
+#endif
+
+ switch (temp) {
+
+ case OHCI_USB_RESET: // lost power
+ info ("USB restart: usb-%s", dev->slot_name);
+ hc_restart (ohci);
+ break;
+
+ case OHCI_USB_SUSPEND: // host wakeup
+ case OHCI_USB_RESUME: // remote wakeup
+ info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
+ (temp == OHCI_USB_SUSPEND)
+ ? "host" : "remote");
+ ohci->hc_control = OHCI_USB_RESUME;
+ writel (ohci->hc_control, &ohci->regs->control);
+ wait_ms (20);
+
+ temp = readl (&ohci->regs->control);
+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
+ if (temp != OHCI_USB_RESUME) {
+ err ("controller usb-%s won't resume", dev->slot_name);
+ ohci->disabled = 1;
+ return;
+ }
+
+ ohci->disabled = 0;
+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ writel (ohci->hc_control, &ohci->regs->control);
#ifdef CONFIG_PMAC_PBOOK
+ enable_irq (ohci->irq);
+#endif
+ break;
+
+ default:
+ warn ("odd PCI resume for usb-%s", dev->slot_name);
+ }
+}
+
+#endif /* CONFIG_PM */
+
+
+/*-------------------------------------------------------------------------*/
+
+static const struct __devinitdata pci_device_id ohci_pci_ids [] = { {
-/* On Powerbooks, put the controller into suspend mode when going
- * to sleep, and do a resume when waking up. */
+ /* handle any USB OHCI controller */
+ class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
+ class_mask: ~0,
+
+ /* no matter who makes it */
+ vendor: PCI_ANY_ID,
+ device: PCI_ANY_ID,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+
+ }, { /* end: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
+
+static struct pci_driver ohci_pci_driver = {
+ name: "usb-ohci",
+ id_table: &ohci_pci_ids [0],
+
+ probe: ohci_pci_probe,
+ remove: ohci_pci_remove,
+
+#ifdef CONFIG_PMAC_PBOOK
+ /* pbook PCI thinks different ... for now :-) */
+#else
+#ifdef CONFIG_PM
+ suspend: ohci_pci_suspend,
+ resume: ohci_pci_resume,
+#endif /* PM */
+#endif /* PBOOK */
+};
+
+
+#ifdef CONFIG_PMAC_PBOOK
+
+/*-------------------------------------------------------------------------*/
static int ohci_sleep_notify (struct pmu_sleep_notifier * self, int when)
{
@@ -2047,16 +2282,10 @@ static int ohci_sleep_notify (struct pmu_sleep_notifier * self, int when)
switch (when) {
case PBOOK_SLEEP_NOW:
- disable_irq (ohci->irq);
- writel (ohci->hc_control = OHCI_USB_SUSPEND, &ohci->regs->control);
- wait_ms (10);
+ ohci_pci_suspend (ohci->ohci_dev);
break;
case PBOOK_WAKE:
- writel (ohci->hc_control = OHCI_USB_RESUME, &ohci->regs->control);
- wait_ms (20);
- ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
- writel (ohci->hc_control, &ohci->regs->control);
- enable_irq (ohci->irq);
+ ohci_pci_resume (ohci->ohci_dev);
break;
}
}
@@ -2070,108 +2299,33 @@ static struct pmu_sleep_notifier ohci_sleep_notifier = {
/*-------------------------------------------------------------------------*/
-static int handle_pm_event (struct pm_dev *dev, pm_request_t rqst, void *data)
+int __init ohci_hcd_init (void)
{
- ohci_t * ohci = (ohci_t*) dev->data;
- int temp = 0;
-
- if (ohci) {
- switch (rqst) {
- case PM_SUSPEND:
- /* act as if usb suspend can always be used */
- dbg("USB suspend: %s", ohci->ohci_dev->slot_name);
- ohci->hc_control = OHCI_USB_SUSPEND;
- writel (ohci->hc_control, &ohci->regs->control);
- wait_ms (10);
- break;
+ int ret = pci_module_init (&ohci_pci_driver);
- case PM_RESUME:
- /* did we suspend, or were we powered off? */
- ohci->hc_control = readl (&ohci->regs->control);
- temp = ohci->hc_control & OHCI_CTRL_HCFS;
- switch (temp) {
-
- case OHCI_USB_RESET: // lost power
- dbg("USB reset: %s", ohci->ohci_dev->slot_name);
- ohci->disabled = 1;
- if (ohci->bus->root_hub)
- usb_disconnect (&ohci->bus->root_hub);
- hc_reinit_ohci (ohci);
- if ((temp = hc_reset (ohci)) < 0
- || (temp = hc_start (ohci)) < 0) {
- ohci->disabled = 1;
- err ("can't restart %s, %d",
- ohci->ohci_dev->slot_name,
- temp);
- }
- dbg ("reset done");
- break;
-
- case OHCI_USB_SUSPEND: // host wakeup
- case OHCI_USB_RESUME: // remote wakeup
- dbg("USB resume: %s", ohci->ohci_dev->slot_name);
- ohci->hc_control = OHCI_USB_RESUME;
- writel (ohci->hc_control, &ohci->regs->control);
- wait_ms (20);
-
- ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
- writel (ohci->hc_control, &ohci->regs->control);
- break;
-
- default:
- warn ("odd PM_RESUME");
- }
- break;
- }
- }
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define PCI_CLASS_SERIAL_USB_OHCI 0x0C0310
-
-int ohci_hcd_init (void)
-{
- int ret = -ENODEV;
- struct pci_dev * dev = NULL;
-
- while ((dev = pci_find_class (PCI_CLASS_SERIAL_USB_OHCI, dev))) {
- if (hc_start_ohci(dev) >= 0) ret = 0;
- }
-
#ifdef CONFIG_PMAC_PBOOK
- pmu_register_sleep_notifier (&ohci_sleep_notifier);
+ if (ret >= 0)
+ pmu_register_sleep_notifier (&ohci_sleep_notifier);
#endif
- return ret;
+ return ret;
}
-/*-------------------------------------------------------------------------*/
-
#ifdef MODULE
-int init_module (void)
-{
- return ohci_hcd_init ();
-}
/*-------------------------------------------------------------------------*/
-void cleanup_module (void)
+void __exit ohci_hcd_cleanup (void)
{
- ohci_t * ohci;
-
- pm_unregister_all (handle_pm_event);
-
#ifdef CONFIG_PMAC_PBOOK
pmu_unregister_sleep_notifier (&ohci_sleep_notifier);
#endif
-
- while (!list_empty (&ohci_hcd_list)) {
- ohci = list_entry (ohci_hcd_list.next, ohci_t, ohci_hcd_list);
- list_del (&ohci->ohci_hcd_list);
- INIT_LIST_HEAD (&ohci->ohci_hcd_list);
- hc_release_ohci (ohci);
- }
+ pci_unregister_driver (&ohci_pci_driver);
}
-#endif //MODULE
+module_init (ohci_hcd_init);
+module_exit (ohci_hcd_cleanup);
+
+#endif /* MODULE */
+
+
+MODULE_DESCRIPTION ("USB OHCI Host Controller Driver");
diff --git a/drivers/video/atyfb.c b/drivers/video/atyfb.c
index 868a2485a..f6206dd66 100644
--- a/drivers/video/atyfb.c
+++ b/drivers/video/atyfb.c
@@ -1,4 +1,4 @@
-/* $Id: atyfb.c,v 1.142 2000/04/12 01:39:41 davem Exp $
+/* $Id: atyfb.c,v 1.146 2000/07/26 23:02:51 davem Exp $
* linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
*
* Copyright (C) 1997-1998 Geert Uytterhoeven
diff --git a/drivers/video/cgsixfb.c b/drivers/video/cgsixfb.c
index 1b4ae093a..b569589d0 100644
--- a/drivers/video/cgsixfb.c
+++ b/drivers/video/cgsixfb.c
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.22 2000/02/14 08:44:26 jj Exp $
+/* $Id: cgsixfb.c,v 1.23 2000/07/26 23:02:51 davem Exp $
* cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
*
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
diff --git a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c
index 5ee5295c1..22349c380 100644
--- a/drivers/video/creatorfb.c
+++ b/drivers/video/creatorfb.c
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.31 1999/11/19 09:57:12 davem Exp $
+/* $Id: creatorfb.c,v 1.32 2000/07/26 23:02:51 davem Exp $
* creatorfb.c: Creator/Creator3D frame buffer driver
*
* Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
diff --git a/drivers/video/leofb.c b/drivers/video/leofb.c
index 1ff9987f9..6b233e5f8 100644
--- a/drivers/video/leofb.c
+++ b/drivers/video/leofb.c
@@ -1,4 +1,4 @@
-/* $Id: leofb.c,v 1.10 1999/11/19 09:57:05 davem Exp $
+/* $Id: leofb.c,v 1.11 2000/07/26 23:02:52 davem Exp $
* leofb.c: Leo (ZX) 24/8bit frame buffer driver
*
* Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
diff --git a/drivers/video/promcon.c b/drivers/video/promcon.c
index d1090613e..9715ae881 100644
--- a/drivers/video/promcon.c
+++ b/drivers/video/promcon.c
@@ -1,4 +1,4 @@
-/* $Id: promcon.c,v 1.16 1999/08/10 15:56:22 davem Exp $
+/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
* Console driver utilizing PROM sun terminal emulation
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
diff --git a/fs/buffer.c b/fs/buffer.c
index 8b5d19bda..dad4fbcfb 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -92,8 +92,6 @@ struct bh_free_head {
};
static struct bh_free_head free_list[NR_SIZES];
-kmem_cache_t *bh_cachep;
-
static int grow_buffers(int size);
static void __refile_buffer(struct buffer_head *);
@@ -2302,12 +2300,6 @@ void __init buffer_init(unsigned long mempages)
for(i = 0; i < NR_LIST; i++)
lru_list[i] = NULL;
- bh_cachep = kmem_cache_create("buffer_head",
- sizeof(struct buffer_head),
- 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if(!bh_cachep)
- panic("Cannot create buffer head SLAB cache\n");
}
diff --git a/fs/dcache.c b/fs/dcache.c
index 8c27b5f94..729b48855 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1168,7 +1168,7 @@ out:
return ino;
}
-void __init dcache_init(unsigned long mempages)
+static void __init dcache_init(unsigned long mempages)
{
struct list_head *d;
unsigned long order;
@@ -1226,3 +1226,55 @@ void __init dcache_init(unsigned long mempages)
i--;
} while (i);
}
+
+/* SLAB cache for __getname() consumers */
+kmem_cache_t *names_cachep;
+
+/* SLAB cache for files_struct structures */
+kmem_cache_t *files_cachep;
+
+/* SLAB cache for file structures */
+kmem_cache_t *filp_cachep;
+
+/* SLAB cache for dquot structures */
+kmem_cache_t *dquot_cachep;
+
+/* SLAB cache for buffer_head structures */
+kmem_cache_t *bh_cachep;
+
+void __init vfs_caches_init(unsigned long mempages)
+{
+ bh_cachep = kmem_cache_create("buffer_head",
+ sizeof(struct buffer_head), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if(!bh_cachep)
+ panic("Cannot create buffer head SLAB cache\n");
+
+ names_cachep = kmem_cache_create("names_cache",
+ PAGE_SIZE, 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (!names_cachep)
+ panic("Cannot create names SLAB cache");
+
+ files_cachep = kmem_cache_create("files_cache",
+ sizeof(struct files_struct), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (!files_cachep)
+ panic("Cannot create files SLAB cache");
+
+ filp_cachep = kmem_cache_create("filp",
+ sizeof(struct file), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if(!filp_cachep)
+ panic("Cannot create filp SLAB cache");
+
+#if defined (CONFIG_QUOTA)
+ dquot_cachep = kmem_cache_create("dquot",
+ sizeof(struct dquot), sizeof(unsigned long) * 4,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if (!dquot_cachep)
+ panic("Cannot create dquot SLAB cache");
+#endif
+
+ dcache_init(mempages);
+}
diff --git a/fs/dquot.c b/fs/dquot.c
index 15f7dad8f..2271f4746 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -64,8 +64,6 @@ int max_dquots = NR_DQUOTS;
static char quotamessage[MAX_QUOTA_MESSAGE];
static char *quotatypes[] = INITQFNAMES;
-static kmem_cache_t *dquot_cachep;
-
static inline struct quota_mount_options *sb_dqopt(struct super_block *sb)
{
return &sb->s_dquot;
@@ -1345,13 +1343,6 @@ void __init dquot_init_hash(void)
{
printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
- dquot_cachep = kmem_cache_create("dquot", sizeof(struct dquot),
- sizeof(unsigned long) * 4,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
-
- if (!dquot_cachep)
- panic("Cannot create dquot SLAB cache\n");
-
memset(dquot_hash, 0, sizeof(dquot_hash));
memset((caddr_t)&dqstats, 0, sizeof(dqstats));
}
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 1ba0b0f79..e395c75a1 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -653,6 +653,7 @@ int ext2_remount (struct super_block * sb, int * flags, char * data)
/*
* Allow the "check" option to be passed as a remount option.
*/
+ new_mount_opt = sb->u.ext2_sb.s_mount_opt;
if (!parse_options (data, &tmp, &resuid, &resgid,
&new_mount_opt))
return -EINVAL;
diff --git a/fs/file_table.c b/fs/file_table.c
index f50058828..54538ddf0 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -12,9 +12,6 @@
#include <linux/module.h>
#include <linux/smp_lock.h>
-/* SLAB cache for filp's. */
-static kmem_cache_t *filp_cache;
-
/* sysctl tunables... */
struct files_stat_struct files_stat = {0, 0, NR_FILE};
@@ -25,20 +22,6 @@ static LIST_HEAD(free_list);
/* public *and* exported. Not pretty! */
spinlock_t files_lock = SPIN_LOCK_UNLOCKED;
-void __init file_table_init(void)
-{
- filp_cache = kmem_cache_create("filp", sizeof(struct file),
- 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if(!filp_cache)
- panic("VFS: Cannot alloc filp SLAB cache.");
- /*
- * We could allocate the reserved files here, but really
- * shouldn't need to: the normal boot process will create
- * plenty of free files.
- */
-}
-
/* Find an unused file structure and return a pointer to it.
* Returns NULL, if there are no more free file structures or
* we run out of memory.
@@ -78,7 +61,7 @@ struct file * get_empty_filp(void)
*/
if (files_stat.nr_files < files_stat.max_files) {
file_list_unlock();
- f = kmem_cache_alloc(filp_cache, SLAB_KERNEL);
+ f = kmem_cache_alloc(filp_cachep, SLAB_KERNEL);
file_list_lock();
if (f) {
files_stat.nr_files++;
diff --git a/fs/namei.c b/fs/namei.c
index b85a6419d..55658cd6b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1954,20 +1954,3 @@ struct inode_operations page_symlink_inode_operations = {
readlink: page_readlink,
follow_link: page_follow_link,
};
-
-/* SLAB cache for name blocks */
-kmem_cache_t *names_cachep;
-
-static int __init namecache_init(void)
-{
- names_cachep = kmem_cache_create("names_cache",
- PAGE_SIZE,
- 0,
- SLAB_HWCACHE_ALIGN,
- NULL, NULL);
- if (!names_cachep)
- panic("Cannot create names cache");
- return 0;
-}
-
-module_init(namecache_init)
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
index 430f7b412..abd6ec28e 100644
--- a/fs/openpromfs/inode.c
+++ b/fs/openpromfs/inode.c
@@ -1,4 +1,4 @@
-/* $Id: inode.c,v 1.11 2000/05/22 07:29:42 davem Exp $
+/* $Id: inode.c,v 1.12 2000/07/13 08:06:42 davem Exp $
* openpromfs.c: /proc/openprom handling routines
*
* Copyright (C) 1996-1999 Jakub Jelinek (jakub@redhat.com)
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index 53486c977..18454e929 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -134,7 +134,9 @@ extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
if (!size)
return 0;
- __asm__("movl $-1,%%eax\n\t"
+ /* This looks at memory. Mark it volatile to tell gcc not to move it around */
+ __asm__ __volatile__(
+ "movl $-1,%%eax\n\t"
"xorl %%edx,%%edx\n\t"
"repe; scasl\n\t"
"je 1f\n\t"
diff --git a/include/asm-sparc/audioio.h b/include/asm-sparc/audioio.h
index 28fe82dc7..fc5458949 100644
--- a/include/asm-sparc/audioio.h
+++ b/include/asm-sparc/audioio.h
@@ -586,6 +586,7 @@ int BAL_TO_OSS(int value, unsigned char balance)
return ((r << 8) + l);
}
+#ifdef __KERNEL__
/* OSS mixer ioctl port handling */
static __inline__
int OSS_PORT_AUDIO(struct sparcaudio_driver *drv, unsigned int set)
@@ -642,4 +643,5 @@ void OSS_TWIDDLE_IPORT(struct sparcaudio_driver *drv, unsigned int ioctl,
}
}
}
+#endif /* __KERNEL__ */
#endif /* _AUDIOIO_H_ */
diff --git a/include/asm-sparc64/audioio.h b/include/asm-sparc64/audioio.h
index 28fe82dc7..fc5458949 100644
--- a/include/asm-sparc64/audioio.h
+++ b/include/asm-sparc64/audioio.h
@@ -586,6 +586,7 @@ int BAL_TO_OSS(int value, unsigned char balance)
return ((r << 8) + l);
}
+#ifdef __KERNEL__
/* OSS mixer ioctl port handling */
static __inline__
int OSS_PORT_AUDIO(struct sparcaudio_driver *drv, unsigned int set)
@@ -642,4 +643,5 @@ void OSS_TWIDDLE_IPORT(struct sparcaudio_driver *drv, unsigned int ioctl,
}
}
}
+#endif /* __KERNEL__ */
#endif /* _AUDIOIO_H_ */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index f8ec698cc..44853fbe7 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -150,7 +150,6 @@ extern struct sec_size * blk_sec[MAX_BLKDEV];
extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
extern void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size);
extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size);
-extern void generic_unplug_device(void *data);
extern void generic_make_request(request_queue_t *q, int rw,
struct buffer_head * bh);
extern request_queue_t *blk_get_queue(kdev_t dev);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 050318926..a33f33768 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -193,8 +193,6 @@ extern void update_atime (struct inode *);
extern void buffer_init(unsigned long);
extern void inode_init(unsigned long);
-extern void file_table_init(void);
-extern void dcache_init(unsigned long);
/* bh state bits */
#define BH_Uptodate 0 /* 1 if the buffer contains valid data */
@@ -882,6 +880,9 @@ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
extern int filp_close(struct file *, fl_owner_t id);
extern char * getname(const char *);
+/* fs/dcache.c */
+extern void vfs_caches_init(unsigned long);
+
#define __getname() kmem_cache_alloc(names_cachep, SLAB_KERNEL)
#define putname(name) kmem_cache_free(names_cachep, (void *)(name))
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index e229fa2b4..8e449d0cb 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -181,10 +181,14 @@ struct hd_geometry {
#define HDIO_GET_DMA 0x030b /* get use-dma flag */
#define HDIO_GET_NICE 0x030c /* get nice flags */
#define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */
-#define HDIO_DRIVE_CMD_AEB 0x031e
-#define HDIO_DRIVE_TASK 0x031e
+
+#define HDIO_DRIVE_RESET 0x031c /* execute a device reset */
+#define HDIO_TRISTATE_HWIF 0x031d /* execute a channel tristate */
+#define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */
#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
+#define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK
+
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
#define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
#define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 13876daf5..e00d44760 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -143,6 +143,7 @@ typedef unsigned char byte; /* used everywhere */
#define GET_ERR() IN_BYTE(IDE_ERROR_REG)
#define GET_STAT() IN_BYTE(IDE_STATUS_REG)
+#define GET_ALTSTAT() IN_BYTE(IDE_CONTROL_REG)
#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))
#define BAD_R_STAT (BUSY_STAT | ERR_STAT)
#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT)
@@ -341,6 +342,7 @@ typedef struct ide_drive_s {
int lun; /* logical unit */
int crc_count; /* crc counter to reduce drive speed */
byte quirk_list; /* drive is considered quirky if set for a specific host */
+ byte suspend_reset; /* drive suspend mode flag, soft-reset recovers */
byte init_speed; /* transfer rate set at boot */
byte current_speed; /* current transfer rate set */
byte dn; /* now wide spread use */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index a53a165b1..fb2175942 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -420,6 +420,7 @@
#define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806
#define PCI_VENDOR_ID_PROMISE 0x105a
+#define PCI_DEVICE_ID_PROMISE_20265 0x0d30
#define PCI_DEVICE_ID_PROMISE_20267 0x4d30
#define PCI_DEVICE_ID_PROMISE_20246 0x4d33
#define PCI_DEVICE_ID_PROMISE_20262 0x4d38
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 9f722b49e..08d2a1b78 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -212,13 +212,12 @@ struct mddev_s
md_wait_queue_head_t recovery_wait;
struct md_list_head all_mddevs;
- request_queue_t queue;
};
struct mdk_personality_s
{
char *name;
- int (*make_request)(request_queue_t *q, mddev_t *mddev, int rw, struct buffer_head * bh);
+ int (*make_request)(mddev_t *mddev, int rw, struct buffer_head * bh);
int (*run)(mddev_t *mddev);
int (*stop)(mddev_t *mddev);
int (*status)(char *page, mddev_t *mddev);
diff --git a/include/linux/slab.h b/include/linux/slab.h
index ace3e2863..9b255c3cd 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -69,6 +69,10 @@ extern int slabinfo_write_proc(struct file *file, const char *buffer,
extern kmem_cache_t *vm_area_cachep;
extern kmem_cache_t *mm_cachep;
extern kmem_cache_t *names_cachep;
+extern kmem_cache_t *files_cachep;
+extern kmem_cache_t *filp_cachep;
+extern kmem_cache_t *dquot_cachep;
+extern kmem_cache_t *bh_cachep;
#endif /* __KERNEL__ */
diff --git a/init/main.c b/init/main.c
index bb7fabc6a..46b7b557f 100644
--- a/init/main.c
+++ b/init/main.c
@@ -93,7 +93,6 @@ extern void mca_init(void);
extern void sbus_init(void);
extern void ppc_init(void);
extern void sysctl_init(void);
-extern void filescache_init(void);
extern void signals_init(void);
extern void bdev_init(void);
extern int init_pcmcia_ds(void);
@@ -567,8 +566,7 @@ asmlinkage void __init start_kernel(void)
mempages = num_physpages;
fork_init(mempages);
- filescache_init();
- dcache_init(mempages);
+ vfs_caches_init(mempages);
vma_init();
buffer_init(mempages);
page_cache_init(mempages);
@@ -576,7 +574,6 @@ asmlinkage void __init start_kernel(void)
signals_init();
bdev_init();
inode_init(mempages);
- file_table_init();
#if defined(CONFIG_SYSVIPC)
ipc_init();
#endif
diff --git a/kernel/exit.c b/kernel/exit.c
index 5675c7f53..89dcd1a3b 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -180,8 +180,6 @@ static inline void close_files(struct files_struct * files)
}
}
-extern kmem_cache_t *files_cachep;
-
void put_files_struct(struct files_struct *files)
{
if (atomic_dec_and_test(&files->count)) {
diff --git a/kernel/fork.c b/kernel/fork.c
index b27087d7e..683f047ad 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -35,9 +35,6 @@ int last_pid;
/* SLAB cache for mm_struct's. */
kmem_cache_t *mm_cachep;
-/* SLAB cache for files structs */
-kmem_cache_t *files_cachep;
-
struct task_struct *pidhash[PIDHASH_SZ];
/* UID task count cache, to prevent walking entire process list every
@@ -810,14 +807,3 @@ bad_fork_free:
free_task_struct(p);
goto bad_fork;
}
-
-void __init filescache_init(void)
-{
- files_cachep = kmem_cache_create("files_cache",
- sizeof(struct files_struct),
- 0,
- SLAB_HWCACHE_ALIGN,
- NULL, NULL);
- if (!files_cachep)
- panic("Cannot create files cache");
-}
diff --git a/mm/highmem.c b/mm/highmem.c
index 6c7485327..91b45ae5a 100644
--- a/mm/highmem.c
+++ b/mm/highmem.c
@@ -240,8 +240,6 @@ void kunmap_high(struct page *page)
* This will be moved to the block layer in 2.5.
*/
-extern kmem_cache_t *bh_cachep;
-
static inline void copy_from_high_bh (struct buffer_head *to,
struct buffer_head *from)
{