aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linuxfoundation.org>2007-11-23 15:35:26 -0500
committerLinus Torvalds <torvalds@linuxfoundation.org>2007-11-23 15:35:26 -0500
commitf68565831e7269e49b20f201ddef99f136a8c348 (patch)
tree0e05cc22e5f1fea08113fd08549bf1e875abce9a
parentbdd9c8e5286db0c47362e34a29fa1343fa83a4a6 (diff)
downloadlinux-f68565831e72.tar.gz
Import 2.4.0-test2pre3
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
-rw-r--r--Documentation/md.txt25
-rw-r--r--Documentation/powerpc/00-INDEX4
-rw-r--r--Documentation/sound/README.ymfsb107
-rw-r--r--Documentation/sound/via82cxxx.txt37
-rw-r--r--Documentation/video4linux/bttv/CARDLIST2
-rw-r--r--Documentation/video4linux/bttv/Insmod-options44
-rw-r--r--arch/i386/kernel/setup.c18
-rw-r--r--arch/mips/config.in2
-rw-r--r--arch/mips/kernel/irixelf.c10
-rw-r--r--arch/mips/kernel/sysirix.c2
-rw-r--r--arch/mips64/config.in2
-rw-r--r--arch/mips64/kernel/syscall.c4
-rw-r--r--arch/mips64/sgi-ip27/ip27-rtc.c5
-rw-r--r--drivers/acorn/char/Makefile5
-rw-r--r--drivers/acorn/char/keyb_arc.c2
-rw-r--r--drivers/acorn/char/mouse_rpc.c2
-rw-r--r--drivers/acorn/net/etherh.c6
-rw-r--r--drivers/atm/Config.in2
-rw-r--r--drivers/atm/Makefile2
-rw-r--r--drivers/block/acsi_slm.c1
-rw-r--r--drivers/block/amiflop.c22
-rw-r--r--drivers/block/ll_rw_blk.c2
-rw-r--r--drivers/block/nbd.c11
-rw-r--r--drivers/block/paride/paride.c4
-rw-r--r--drivers/block/paride/pd.c2
-rw-r--r--drivers/block/paride/pg.c6
-rw-r--r--drivers/block/paride/pt.c8
-rw-r--r--drivers/block/swim3.c10
-rw-r--r--drivers/block/xd.c11
-rw-r--r--drivers/block/z2ram.c32
-rw-r--r--drivers/char/acquirewdt.c3
-rw-r--r--drivers/char/adbmouse.c8
-rw-r--r--drivers/char/agp/agpgart_fe.c1
-rw-r--r--drivers/char/atarimouse.c51
-rw-r--r--drivers/char/bttv.c308
-rw-r--r--drivers/char/bttv.h30
-rw-r--r--drivers/char/busmouse.c25
-rw-r--r--drivers/char/cyclades.c33
-rw-r--r--drivers/char/ds1620.c19
-rw-r--r--drivers/char/dsp56k.c8
-rw-r--r--drivers/char/dtlk.c3
-rw-r--r--drivers/char/efirtc.c1
-rw-r--r--drivers/char/epca.c3
-rw-r--r--drivers/char/generic_serial.c2
-rw-r--r--drivers/char/hp600_keyb.c119
-rw-r--r--drivers/char/ip2main.c3
-rw-r--r--drivers/char/isicom.c23
-rw-r--r--drivers/char/istallion.c26
-rw-r--r--drivers/char/joystick/joystick.c1
-rw-r--r--drivers/char/lp.c8
-rw-r--r--drivers/char/misc.c13
-rw-r--r--drivers/char/mixcomwd.c4
-rw-r--r--drivers/char/msp3400.c33
-rw-r--r--drivers/char/nvram.c3
-rw-r--r--drivers/char/nwbutton.c31
-rw-r--r--drivers/char/nwflash.c12
-rw-r--r--drivers/char/pc110pad.c3
-rw-r--r--drivers/char/pc_keyb.c4
-rw-r--r--drivers/char/pcwd.c3
-rw-r--r--drivers/char/ppdev.c1
-rw-r--r--drivers/char/rio/rio_linux.c33
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/char/stallion.c48
-rw-r--r--drivers/char/sx.c24
-rw-r--r--drivers/char/tpqic02.c8
-rw-r--r--drivers/char/tuner.c14
-rw-r--r--drivers/char/tvmixer.c351
-rw-r--r--drivers/char/wdt.c4
-rw-r--r--drivers/char/wdt_pci.c133
-rw-r--r--drivers/ide/aec62xx.c28
-rw-r--r--drivers/ide/alim15x3.c50
-rw-r--r--drivers/ide/amd7409.c74
-rw-r--r--drivers/ide/cmd64x.c85
-rw-r--r--drivers/ide/cs5530.c4
-rw-r--r--drivers/ide/cy82c693.c4
-rw-r--r--drivers/ide/gayle.c24
-rw-r--r--drivers/ide/hd.c2
-rw-r--r--drivers/ide/hpt34x.c10
-rw-r--r--drivers/ide/hpt366.c436
-rw-r--r--drivers/ide/icside.c6
-rw-r--r--drivers/ide/ide-cd.c32
-rw-r--r--drivers/ide/ide-disk.c19
-rw-r--r--drivers/ide/ide-dma.c53
-rw-r--r--drivers/ide/ide-features.c48
-rw-r--r--drivers/ide/ide-geometry.c4
-rw-r--r--drivers/ide/ide-pci.c54
-rw-r--r--drivers/ide/ide-pmac.c6
-rw-r--r--drivers/ide/ide-probe.c6
-rw-r--r--drivers/ide/ide.c76
-rw-r--r--drivers/ide/ns87415.c2
-rw-r--r--drivers/ide/pdc202xx.c159
-rw-r--r--drivers/ide/piix.c35
-rw-r--r--drivers/ide/qd6580.c332
-rw-r--r--drivers/ide/sis5513.c22
-rw-r--r--drivers/ide/trm290.c4
-rw-r--r--drivers/ide/via82cxxx.c48
-rw-r--r--drivers/pnp/isapnp.c6
-rw-r--r--drivers/scsi/sg.c458
-rw-r--r--drivers/sgi/char/graphics.c2
-rw-r--r--drivers/sgi/char/shmiq.c7
-rw-r--r--drivers/sound/724hwmcode.h1575
-rw-r--r--drivers/sound/Config.in9
-rw-r--r--drivers/sound/Hwmcode.h804
-rw-r--r--drivers/sound/Makefile1
-rw-r--r--drivers/sound/ac97_codec.c63
-rw-r--r--drivers/sound/cmpci.c16
-rw-r--r--drivers/sound/dmasound/dmasound_awacs.c6
-rw-r--r--drivers/sound/dmasound/dmasound_core.c13
-rw-r--r--drivers/sound/emu10k1/audio.c7
-rw-r--r--drivers/sound/emu10k1/main.c2
-rw-r--r--drivers/sound/emu10k1/midi.c12
-rw-r--r--drivers/sound/emu10k1/mixer.c4
-rw-r--r--drivers/sound/es1370.c14
-rw-r--r--drivers/sound/es1371.c18
-rw-r--r--drivers/sound/esssolo1.c12
-rw-r--r--drivers/sound/i810_audio.c105
-rw-r--r--drivers/sound/maestro.c17
-rw-r--r--drivers/sound/sonicvibes.c12
-rw-r--r--drivers/sound/sound_core.c22
-rw-r--r--drivers/sound/soundcard.c4
-rw-r--r--drivers/sound/trident.c123
-rw-r--r--drivers/sound/via82cxxx_audio.c325
-rw-r--r--drivers/sound/wavfront.c3
-rw-r--r--drivers/sound/ymf_sb.c867
-rw-r--r--drivers/telephony/phonedev.c13
-rw-r--r--drivers/zorro/zorro.c25
-rw-r--r--fs/devfs/base.c18
-rw-r--r--fs/devices.c6
-rw-r--r--fs/file_table.c2
-rw-r--r--fs/open.c4
-rw-r--r--fs/proc/base.c18
-rw-r--r--fs/proc/generic.c7
-rw-r--r--fs/read_write.c14
-rw-r--r--include/linux/ac97_codec.h7
-rw-r--r--include/linux/ide.h44
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/linux/proc_fs.h2
-rw-r--r--include/scsi/sg.h20
-rw-r--r--lib/Makefile1
-rw-r--r--lib/cmdline.c117
140 files changed, 6566 insertions, 1654 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 0107ca5d870d34..7e894fd977cfd7 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -1,15 +1,17 @@
-Tools that manage md devices can be found at sweet-smoke.ufr-info-p7.ibp.fr
-in public/Linux/md035.tar.gz.
+Tools that manage md devices can be found at
+ http://www.<country>.kernel.org/pub/linux/daemons/raid/....
- Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
---
You can boot (if you selected boot support in the configuration) with your md
-device with the following kernel command line:
+device with the following kernel command lines:
-md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn
+for old raid arrays without persistant superblocks:
+ md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn
+for raid arrays with persistant superblocks
+ md=<md device no.>,dev0,dev1,...,devn
+
md device no. = the number of the md device ...
0 means md0,
1 md1,
@@ -19,19 +21,16 @@ md device no. = the number of the md device ...
raid level = -1 linear mode
0 striped mode
- other modes are currently unsupported.
+ other modes are only supported with persistant super blocks
chunk size factor = (raid-0 and raid-1 only)
- Set the chunk size as PAGE_SIZE << n.
+ Set the chunk size as 4k << n.
-fault level = (raid-1 only)
- Set the maximum fault number as n.
- Currently unsupported due to lack of boot support for raid1.
+fault level = totally ignored
dev0-devn: e.g. /dev/hda1,/dev/hdc1,/dev/sda1,/dev/sdb1
-my loadlin line looks like this:
+A possible loadlin line (Harald Hoyer <HarryH@Royal.Net>) looks like this:
e:\loadlin\loadlin e:\zimage root=/dev/md0 md=0,0,4,0,/dev/hdb2,/dev/hdc3 ro
- Harald Hoyer <HarryH@Royal.Net>
diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
index d4ed9cabeecb27..2a46c07a84a99e 100644
--- a/Documentation/powerpc/00-INDEX
+++ b/Documentation/powerpc/00-INDEX
@@ -1,7 +1,7 @@
Index of files in Documentation/powerpc. If you think something about
Linux/PPC needs an entry here, needs correction or you've written one
please mail me.
- Cort Dougan (cort@cs.nmt.edu)
+ Cort Dougan (cort@fsmlabs.com)
00-INDEX
- this file
@@ -9,6 +9,8 @@ ppc_htab.txt
- info about the Linux/PPC /proc/ppc_htab entry
smp.txt
- use and state info about Linux/PPC on MP machines
+SBC8260_memory_mapping.txt
+ - EST SBC8260 board info
sound.txt
- info on sound support under Linux/PPC
zImage_layout.txt
diff --git a/Documentation/sound/README.ymfsb b/Documentation/sound/README.ymfsb
new file mode 100644
index 00000000000000..feda77915b1869
--- /dev/null
+++ b/Documentation/sound/README.ymfsb
@@ -0,0 +1,107 @@
+Legacy audio driver for YMF7xx PCI cards.
+
+
+FIRST OF ALL
+============
+
+ This code references YAMAHA's sample codes and data sheets.
+ I respect and thank for all people they made open the informations
+ about YMF7xx cards.
+
+ And this codes heavily based on Jeff Garzik <jgarzik@pobox.com>'s
+ old VIA 82Cxxx driver (via82cxxx.c). I also respect him.
+
+
+DISCLIMER
+=========
+
+ This driver is currently at early ALPHA stage. It may cause serious
+ damage to your computer when used.
+ PLEASE USE IT AT YOUR OWN RISK.
+
+
+ABOUT THIS DRIVER
+=================
+
+ This code enables you to use your YMF724[A-F], YMF740[A-C], YMF744, YMF754
+ cards. When enabled, your card acts as "SoundBlaster Pro" compatible card.
+ It can only play 22.05kHz / 8bit / Stereo samples, control external MIDI
+ port.
+ If you want to use your card as recent "16-bit" card, you should use
+ Alsa or OSS/Linux driver. Ofcource you can write native PCI driver for
+ your cards :)
+
+
+USAGE
+=====
+
+ # modprobe ymfsb (options)
+
+
+OPTIONS FOR MODULE
+==================
+
+ io : SB base address (0x220, 0x240, 0x260, 0x280)
+ synth_io : OPL3 base address (0x388, 0x398, 0x3a0, 0x3a8)
+ dma : DMA number (0,1,3)
+ master_volume: AC'97 PCM out Vol (0-100)
+ spdif_out : SPDIF-out flag (0:disable 1:enable)
+
+ These options will change in future...
+
+
+FREQUENCY
+=========
+
+ When playing sounds via this driver, you will hear its pitch is slightly
+ lower than original sounds. Since this driver recognizes your card acts
+ with 21.739kHz sample rates rather than 22.050kHz (I think it must be
+ hardware restriction). So many players become tone deafness.
+ To prevent this, you should express some options to your sound player
+ that specify correct sample frequency. For example, to play your MP3 file
+ correctly with mpg123, specify the frequency like following:
+
+ % mpg123 -r 21739 foo.mp3
+
+
+SPDIF OUT
+=========
+
+ With installing modules with option 'spdif_out=1', you can enjoy your
+ sounds from SPDIF-out of your card (if it had).
+ Its Fs is fixed to 48kHz (It never means the sample frequency become
+ up to 48kHz. All sounds via SPDIF-out also 22kHz samples). So your
+ digital-in capable components has to be able to handle 48kHz Fs.
+
+
+COPYING
+=======
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+TODO
+====
+ * support for multiple cards
+ (set the different SB_IO,MPU_IO,OPL_IO for each cards)
+
+ * support for OPL (dmfm) : There will be no requirements... :-<
+
+
+AUTHOR
+======
+
+ Daisuke Nagano <breeze.nagano@nifty.ne.jp>
+
diff --git a/Documentation/sound/via82cxxx.txt b/Documentation/sound/via82cxxx.txt
index af963c3b4be400..bfaf99b643202e 100644
--- a/Documentation/sound/via82cxxx.txt
+++ b/Documentation/sound/via82cxxx.txt
@@ -48,6 +48,15 @@ be added to your /etc/conf.modules (or /etc/modules.conf) file:
Driver notes
------------------------------------------------------------------------
+Two /proc pseudo-files provide diagnostic information. This is generally
+not useful to most users. Power users can disable VIA_PROC_FS macro in the
+driver source code, and remove the /proc support code. In any case, once
+version 2.0.0 is released, the /proc support code will be disabled by
+default. Available /proc pseudo-files:
+
+ /proc/driver/via/0/info
+ /proc/driver/via/0/ac97
+
This driver by default supports all PCI audio devices which report
a vendor id of 0x1106, and a device id of 0x3058. Subsystem vendor
and device ids are not examined.
@@ -110,7 +119,8 @@ Known bugs (patches/suggestions welcome)
1) Volume too low on many systems. Workaround: use mixer program
such as xmixer to increase volume.
-2) RealPlayer output very scratchy.
+2) RealPlayer output very scratchy. Workaround: use esd, and
+configure RealPlayer to output to esd.
3) Applications which attempt to open the sound device in read/write
mode (O_RDWR) will fail. This is incorrect OSS behavior, but since
@@ -139,3 +149,28 @@ change the LOG_BUF_LEN macro at the top of linux/kernel/printk.c, recompile
your kernel, and pass the "-s <size>" option to 'dmesg'.
+
+Change history
+------------------------------------------------------------------------
+Version 1.1.7:
+* Fix module unload bug where mixer device left registered
+ after driver exit
+
+Version 1.1.6:
+* Rewrite via_set_rate to mimic ALSA basic AC97 rate setting
+* Remove much dead code
+* Complete spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl
+* Fix build problem in via_dsp_ioctl
+* Optimize included headers to eliminate headers found in linux/drivers/sound
+
+Version 1.1.5:
+* Disable some overly-verbose debugging code
+* Remove unnecessary sound locks
+* Fix some ioctls for better time resolution
+* Begin spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl
+
+Version 1.1.4:
+* Completed rewrite of driver. Eliminated SoundBlaster compatibility
+ completely, and now uses the much-faster scatter-gather DMA engine.
+
+
diff --git a/Documentation/video4linux/bttv/CARDLIST b/Documentation/video4linux/bttv/CARDLIST
index 02ec58baac5616..28f11aeac08ec1 100644
--- a/Documentation/video4linux/bttv/CARDLIST
+++ b/Documentation/video4linux/bttv/CARDLIST
@@ -42,6 +42,8 @@ bttv.o
card=40 - STB2
card=41 - AVerMedia TVPhone 98
card=42 - ProVideo PV951
+ card=43 - Little OnAir TV
+ card=44 - Sigma TVII-FM
tuner.o
type=0 - Temic PAL
diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options
index 5d1774a32ecdd6..b6d4c5a6cb23c7 100644
--- a/Documentation/video4linux/bttv/Insmod-options
+++ b/Documentation/video4linux/bttv/Insmod-options
@@ -3,7 +3,7 @@ bttv.o
the bt848 (grabber chip) driver
insmod args:
- card=n card type, see cardlist for a list.
+ card=n card type, see CARDLIST for a list.
radio=0/1 card supports radio
pll=0/1/2 pll settings
0: don't use PLL
@@ -31,6 +31,29 @@ bttv.o
remap, card, radio and pll accept up to four comma-separated arguments
(for multiple boards).
+tuner.o
+ The tuner driver. You need this unless you want to use only
+ with a camera or external tuner ...
+
+ insmod args:
+ debug=1 print some debug info to the syslog
+ type=n type of the tuner chip. n as follows:
+ see CARDLIST for a complete list.
+
+tvmixer.o
+ registers a mixer device for the TV card's volume/bass/treble
+ controls (requires a i2c audio control chip like the msp3400).
+
+ insmod args:
+ debug=1 print some debug info to the syslog.
+ devnr=n allocate device #n (0 == /dev/mixer,
+ 1 = /dev/mixer1, ...), default is to
+ use the first free one.
+
+tvaudio.o
+ new, experimental module which is supported to provide a single
+ driver for all simple i2c audio control chips (tda/tea*).
+
msp3400.o
The driver for the msp34xx sound processor chips. If you have a
stereo card, you probably want to insmod this one.
@@ -47,8 +70,6 @@ msp3400.o
amsound=1 Audio carrier is AM/NICAM at 6.5 Mhz. This
should improve things for french people, the
carrier autoscan seems to work with FM only...
- mixer=n allocate mixer device #n. Default is the
- first free slot.
tea6300.o
The driver for the tea6300 fader chip. If you have a stereo
@@ -73,20 +94,3 @@ tda985x.o
insmod args:
debug=1 print some debug info to the syslog.
chip=9850/9855 set the chip type.
-
-tuner.o
- The tuner driver. You need this unless you want to use only
- with a camera or external tuner ...
-
- insmod args:
- debug=1 print some debug info to the syslog
- type=n type of the tuner chip. n as follows:
- 0: Temic PAL tuner
- 1: Philips PAL_I tuner
- 2: Philips NTSC tuner
- 3: Philips SECAM tuner
- 4: no tuner
- 5: Philips PAL tuner
- 6: Temic NTSC tuner
- 7: Temic PAL tuner
-
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index c59951cd18e331..03bee2e69326f9 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -373,24 +373,6 @@ static void __init probe_roms(void)
}
}
-unsigned long __init memparse(char *ptr, char **retptr)
-{
- unsigned long ret;
-
- ret = simple_strtoul(ptr, retptr, 0);
-
- if (**retptr == 'K' || **retptr == 'k') {
- ret <<= 10;
- (*retptr)++;
- }
- else if (**retptr == 'M' || **retptr == 'm') {
- ret <<= 20;
- (*retptr)++;
- }
- return ret;
-} /* memparse */
-
-
void __init add_memory_region(unsigned long start,
unsigned long size, int type)
{
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 9e6e664d2ea69d..950f665b6225c6 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -1,6 +1,6 @@
# $Id: config.in,v 1.46 2000/03/26 22:59:01 ralf Exp $
# For a description of the syntax of this configuration file,
-# see the Configure script.
+# see Documentation/kbuild/config-language.txt.
#
mainmenu_name "Linux Kernel Configuration"
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index ddf2340450f437..1b9774a3de0df7 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -315,10 +315,12 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
(unsigned long) elf_prot, (unsigned long) elf_type,
(unsigned long) (eppnt->p_offset & 0xfffff000));
#endif
+ down(&current->mm->mmap_sem);
error = do_mmap(interpreter, vaddr,
eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
elf_prot, elf_type,
eppnt->p_offset & 0xfffff000);
+ up(&current->mm->mmap_sem);
if(error < 0 && error > -1024) {
printk("Aieee IRIX interp mmap error=%d\n", error);
@@ -465,6 +467,7 @@ static inline int look_for_irix_interpreter(char **name,
return 0;
dput_and_out:
+ allow_write_access(file);
fput(file);
out:
kfree(*name);
@@ -497,10 +500,12 @@ static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnu
prot = (epp->p_flags & PF_R) ? PROT_READ : 0;
prot |= (epp->p_flags & PF_W) ? PROT_WRITE : 0;
prot |= (epp->p_flags & PF_X) ? PROT_EXEC : 0;
+ down(&current->mm->mmap_sem);
(void) do_mmap(fp, (epp->p_vaddr & 0xfffff000),
(epp->p_filesz + (epp->p_vaddr & 0xfff)),
prot, EXEC_MAP_FLAGS,
(epp->p_offset & 0xfffff000));
+ up(&current->mm->mmap_sem);
/* Fixup location tracking vars. */
if((epp->p_vaddr & 0xfffff000) < *estack)
@@ -759,8 +764,10 @@ static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
* Since we do not have the power to recompile these, we
* emulate the SVr4 behavior. Sigh.
*/
+ down(&current->mm->mmap_sem);
(void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, 0);
+ up(&current->mm->mmap_sem);
#endif
start_thread(regs, elf_entry, bprm->p);
@@ -771,6 +778,7 @@ out:
return retval;
out_free_dentry:
+ allow_write_access(interpreter);
fput(interpreter);
out_free_interp:
if (elf_interpreter)
@@ -910,10 +918,12 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt)
prot = (hp->p_flags & PF_R) ? PROT_READ : 0;
prot |= (hp->p_flags & PF_W) ? PROT_WRITE : 0;
prot |= (hp->p_flags & PF_X) ? PROT_EXEC : 0;
+ down(&current->mm->mmap_sem);
retval = do_mmap(filp, (hp->p_vaddr & 0xfffff000),
(hp->p_filesz + (hp->p_vaddr & 0xfff)),
prot, (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE),
(hp->p_offset & 0xfffff000));
+ up(&current->mm->mmap_sem);
if(retval != (hp->p_vaddr & 0xfffff000)) {
printk("irix_mapelf: do_mmap fails with %d!\n", retval);
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 847acadd99aeae..3293fa6c2cb37b 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1099,7 +1099,9 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ down(&current->mm->mmap_sem);
retval = do_mmap(file, addr, len, prot, flags, offset);
+ up(&current->mm->mmap_sem);
if (file)
fput(file);
diff --git a/arch/mips64/config.in b/arch/mips64/config.in
index b2454b8cc3015d..57b54865200786 100644
--- a/arch/mips64/config.in
+++ b/arch/mips64/config.in
@@ -1,7 +1,7 @@
# $Id: config.in,v 1.19 2000/03/27 01:44:45 ralf Exp $
#
# For a description of the syntax of this configuration file,
-# see the Configure script.
+# see Documentation/kbuild/config-language.txt.
#
mainmenu_name "Linux Kernel Configuration"
diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c
index f791806d606f32..8f90aad889952c 100644
--- a/arch/mips64/kernel/syscall.c
+++ b/arch/mips64/kernel/syscall.c
@@ -56,7 +56,6 @@ sys_mmap(unsigned long addr, size_t len, unsigned long prot,
struct file * file = NULL;
unsigned long error = -EFAULT;
- down(&current->mm->mmap_sem);
lock_kernel();
if (!(flags & MAP_ANONYMOUS)) {
error = -EBADF;
@@ -66,12 +65,13 @@ sys_mmap(unsigned long addr, size_t len, unsigned long prot,
}
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ down(&current->mm->mmap_sem);
error = do_mmap(file, addr, len, prot, flags, offset);
+ up(&current->mm->mmap_sem);
if (file)
fput(file);
out:
unlock_kernel();
- up(&current->mm->mmap_sem);
return error;
}
diff --git a/arch/mips64/sgi-ip27/ip27-rtc.c b/arch/mips64/sgi-ip27/ip27-rtc.c
index e5f174ab10d74e..0e3987296e62e7 100644
--- a/arch/mips64/sgi-ip27/ip27-rtc.c
+++ b/arch/mips64/sgi-ip27/ip27-rtc.c
@@ -168,8 +168,6 @@ static int rtc_open(struct inode *inode, struct file *file)
if(rtc_status & RTC_IS_OPEN)
return -EBUSY;
- MOD_INC_USE_COUNT;
-
rtc_status |= RTC_IS_OPEN;
return 0;
}
@@ -181,8 +179,6 @@ static int rtc_release(struct inode *inode, struct file *file)
* in use, and clear the data.
*/
- MOD_DEC_USE_COUNT;
-
rtc_status &= ~RTC_IS_OPEN;
return 0;
}
@@ -192,6 +188,7 @@ static int rtc_release(struct inode *inode, struct file *file)
*/
static struct file_operations rtc_fops = {
+ owner: THIS_MODULE,
ioctl: rtc_ioctl,
open: rtc_open,
release: rtc_release,
diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile
index 24bab45a94288e..316af0d4e71b34 100644
--- a/drivers/acorn/char/Makefile
+++ b/drivers/acorn/char/Makefile
@@ -18,7 +18,7 @@ MX_OBJS :=
# Object file lists.
-obj-y := i2c.o pcf8583.o
+obj-y :=
obj-m :=
obj-n :=
obj- :=
@@ -34,7 +34,8 @@ obj-$(CONFIG_RPCMOUSE) += mouse_rpc.o
obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o
obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o
-obj-y += $(obj-$(MACHINE))
+# Do the i2c and rtc last
+obj-y += $(obj-$(MACHINE)) i2c.o pcf8583.o
O_OBJS := $(filter-out $(export-objs), $(obj-y))
OX_OBJS := $(filter $(export-objs), $(obj-y))
diff --git a/drivers/acorn/char/keyb_arc.c b/drivers/acorn/char/keyb_arc.c
index 44395fd97ef574..4e37bb9d0115b9 100644
--- a/drivers/acorn/char/keyb_arc.c
+++ b/drivers/acorn/char/keyb_arc.c
@@ -415,7 +415,7 @@ static void a5kkbd_tx(int irq, void *dev_id, struct pt_regs *regs)
#ifdef CONFIG_KBDMOUSE
static struct busmouse a5kkbd_mouse = {
- 6, "kbdmouse", NULL, NULL, 7
+ 6, "kbdmouse", NULL, NULL, NULL, 7
};
#endif
diff --git a/drivers/acorn/char/mouse_rpc.c b/drivers/acorn/char/mouse_rpc.c
index 68b1b9642c4fef..fb6e4537362f52 100644
--- a/drivers/acorn/char/mouse_rpc.c
+++ b/drivers/acorn/char/mouse_rpc.c
@@ -46,7 +46,7 @@ mouse_rpc_irq(int irq, void *dev_id, struct pt_regs *regs)
}
static struct busmouse rpcmouse = {
- 6, "arcmouse", NULL, NULL, 7
+ 6, "arcmouse", NULL, NULL, NULL, 7
};
static int __init mouse_rpc_init(void)
diff --git a/drivers/acorn/net/etherh.c b/drivers/acorn/net/etherh.c
index 96f51c68eba67a..5134f6f15ddef8 100644
--- a/drivers/acorn/net/etherh.c
+++ b/drivers/acorn/net/etherh.c
@@ -621,8 +621,6 @@ static int __init etherh_init(void)
if (load_8390_module("etherh.c"))
return -ENOSYS;
- lock_8390_module();
-
ecard_startfind();
for (i = 0; i < MAX_ECARDS; i++) {
@@ -643,7 +641,7 @@ static int __init etherh_init(void)
}
if (ret)
- unlock_8390_module();
+ unload_8390_module();
return ret;
}
@@ -665,7 +663,7 @@ static void __exit etherh_exit(void)
e_card[i] = NULL;
}
}
- unlock_8390_module();
+ unload_8390_module();
}
module_init(etherh_init);
diff --git a/drivers/atm/Config.in b/drivers/atm/Config.in
index c603f71affd71c..b04a354bc14007 100644
--- a/drivers/atm/Config.in
+++ b/drivers/atm/Config.in
@@ -59,7 +59,7 @@ if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then
if [ "$CONFIG_ATM_FORE200E_PCA" = "y" ]; then
bool ' Use default PCA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_PCA_DEFAULT_FW
if [ "$CONFIG_ATM_FORE200E_PCA_DEFAULT_FW" = "n" ]; then
- string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW
+ string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW ""
fi
fi
fi
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index 330d5d1c37b28d..b41bc415a4c3e4 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -45,7 +45,7 @@ else
NEED_SUNI_MX = suni.o
endif
ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y)
- NEED_SUNI_MX = idt77105.o
+ NEED_IDT77105_MX = idt77105.o
endif
endif
endif
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index 88fa04ac668e1e..51bb6b1a3aa9e6 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -272,6 +272,7 @@ static int slm_get_pagesize( int device, int *w, int *h );
static struct timer_list slm_timer = { NULL, NULL, 0, 0, slm_test_ready };
static struct file_operations slm_fops = {
+ owner: THIS_MODULE,
read: slm_read,
write: slm_write,
ioctl: slm_ioctl,
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 095fc0870606d1..d33bda6419cbb4 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -70,6 +70,7 @@
#include <linux/init.h>
#include <linux/amifdreg.h>
#include <linux/amifd.h>
+#include <linux/ioport.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
@@ -127,11 +128,6 @@ MODULE_PARM(fd_def_df0,"l");
#define DESELECT(mask) (ciab.prb |= mask)
#define SELMASK(drive) (1 << (3 + (drive & 3)))
-#define DRIVE(x) ((x) & 3)
-#define PROBE(x) ((x) >> 2) & 1)
-#define TYPE(x) ((x) >> 3) & 2)
-#define DATA(x) ((x) >> 5) & 3)
-
static struct fd_drive_type drive_types[] = {
/* code name tr he rdsz wrsz sm pc1 pc2 sd st st*/
/* warning: times are now in milliseconds (ms) */
@@ -1794,17 +1790,26 @@ int __init amiga_floppy_init(void)
printk("fd: Unable to get major %d for floppy\n",MAJOR_NR);
return -EBUSY;
}
-
+ /*
+ * We request DSKPTR, DSKLEN and DSKDATA only, because the other
+ * floppy registers are too spreaded over the custom register space
+ */
+ if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) {
+ printk("fd: cannot get floppy registers\n");
+ unregister_blkdev(MAJOR_NR,"fd");
+ return -EBUSY;
+ }
if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) ==
NULL) {
printk("fd: cannot get chip mem buffer\n");
+ release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
unregister_blkdev(MAJOR_NR,"fd");
return -ENOMEM;
}
-
if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) {
printk("fd: cannot get irq for dma\n");
amiga_chip_free(raw_buf);
+ release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
unregister_blkdev(MAJOR_NR,"fd");
return -EBUSY;
}
@@ -1812,6 +1817,7 @@ int __init amiga_floppy_init(void)
printk("fd: cannot get irq for timer\n");
free_irq(IRQ_AMIGA_DSKBLK, NULL);
amiga_chip_free(raw_buf);
+ release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
unregister_blkdev(MAJOR_NR,"fd");
return -EBUSY;
}
@@ -1819,6 +1825,7 @@ int __init amiga_floppy_init(void)
free_irq(IRQ_AMIGA_CIAA_TB, NULL);
free_irq(IRQ_AMIGA_DSKBLK, NULL);
amiga_chip_free(raw_buf);
+ release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
unregister_blkdev(MAJOR_NR,"fd");
return -ENXIO;
}
@@ -1889,6 +1896,7 @@ void cleanup_module(void)
blk_size[MAJOR_NR] = NULL;
blksize_size[MAJOR_NR] = NULL;
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ release_mem_region(CUSTOM_PHYSADDR+0x20, 8);
unregister_blkdev(MAJOR_NR, "fd");
}
#endif
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index afb9e7bc4b3e3f..18c7dc1faf6de2 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -411,6 +411,7 @@ static inline void add_request(request_queue_t * q, struct request * req,
drive_stat_acct(req->rq_dev, req->cmd, req->nr_sectors, 1);
+ elevator_account_request(&q->elevator, req);
if (list_empty(head)) {
req->elevator_sequence = elevator_sequence(&q->elevator, latency);
list_add(&req->queue, &q->queue_head);
@@ -748,7 +749,6 @@ get_rq:
req->bhtail = bh;
req->q = q;
add_request(q, req, head, orig_latency);
- elevator_account_request(elevator, req);
spin_unlock_irqrestore(&io_request_lock, flags);
return;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index b21be6bd261f42..8256c57bd0b003 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -38,6 +38,8 @@
#include <linux/ioctl.h>
#include <net/sock.h>
+#include <linux/devfs_fs_kernel.h>
+
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <asm/types.h>
@@ -53,6 +55,7 @@ static int nbd_sizes[MAX_NBD];
static u64 nbd_bytesizes[MAX_NBD];
static struct nbd_device nbd_dev[MAX_NBD];
+static devfs_handle_t devfs_handle = NULL;
#define DEBUG( s )
/* #define DEBUG( s ) printk( s )
@@ -514,12 +517,20 @@ int nbd_init(void)
register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &nbd_fops,
nbd_bytesizes[i]>>9);
}
+ devfs_handle = devfs_mk_dir (NULL, "nbd", 0, NULL);
+ devfs_register_series (devfs_handle, "%u", MAX_NBD,
+ DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+ S_IFBLK | S_IRUSR | S_IWUSR, 0, 0,
+ &nbd_fops, NULL);
+
return 0;
}
#ifdef MODULE
void cleanup_module(void)
{
+ devfs_unregister (devfs_handle);
+
if (unregister_blkdev(MAJOR_NR, "nbd") != 0)
printk("nbd: cleanup_module failed\n");
else
diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c
index 9c4cabbbffc871..2315e1d300c0cc 100644
--- a/drivers/block/paride/paride.c
+++ b/drivers/block/paride/paride.c
@@ -120,8 +120,8 @@ static void pi_claim( PIA *pi)
pi->claimed = 1;
#ifdef CONFIG_PARPORT
if (pi->pardev)
- while (parport_claim((struct pardevice *)(pi->pardev)))
- sleep_on(&(pi->parq));
+ wait_event (pi->parq,
+ !parport_claim ((struct pardevice *)pi->pardev));
#endif
}
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 6c5a87e5c4c6ea..9b1ff3a32fe6d6 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -487,7 +487,7 @@ static int pd_open (struct inode *inode, struct file *file)
MOD_INC_USE_COUNT;
- while (!pd_valid) sleep_on(&pd_wait_open);
+ wait_event (pd_wait_open, pd_valid);
PD.access++;
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index b4e36726c49fa1..3cb11286da1d6c 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -261,6 +261,7 @@ static char pg_scratch[512]; /* scratch block buffer */
/* kernel glue structures */
static struct file_operations pg_fops = {
+ owner: THIS_MODULE,
read: pg_read,
write: pg_write,
open: pg_open,
@@ -578,8 +579,6 @@ static int pg_open (struct inode *inode, struct file *file)
return -EBUSY;
}
- MOD_INC_USE_COUNT;
-
if (PG.busy) {
pg_reset(unit);
PG.busy = 0;
@@ -591,7 +590,6 @@ static int pg_open (struct inode *inode, struct file *file)
PG.bufptr = kmalloc(PG_MAX_DATA,GFP_KERNEL);
if (PG.bufptr == NULL) {
PG.access--;
- MOD_DEC_USE_COUNT;
printk("%s: buffer allocation failed\n",PG.name);
return -ENOMEM;
}
@@ -611,8 +609,6 @@ static int pg_release (struct inode *inode, struct file *file)
kfree(PG.bufptr);
PG.bufptr = NULL;
- MOD_DEC_USE_COUNT;
-
return 0;
}
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 459ef7237ab537..739755a93787ad 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -263,6 +263,7 @@ static char pt_scratch[512]; /* scratch block buffer */
/* kernel glue structures */
static struct file_operations pt_fops = {
+ owner: THIS_MODULE,
read: pt_read,
write: pt_write,
ioctl: pt_ioctl,
@@ -701,19 +702,15 @@ static int pt_open (struct inode *inode, struct file *file)
return -EBUSY;
}
- MOD_INC_USE_COUNT;
-
pt_identify(unit);
if (!PT.flags & PT_MEDIA) {
PT.access--;
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) {
PT.access--;
- MOD_DEC_USE_COUNT;
return -EROFS;
}
@@ -723,7 +720,6 @@ static int pt_open (struct inode *inode, struct file *file)
PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL);
if (PT.bufptr == NULL) {
PT.access--;
- MOD_DEC_USE_COUNT;
printk("%s: buffer allocation failed\n",PT.name);
return -ENOMEM;
}
@@ -786,8 +782,6 @@ static int pt_release (struct inode *inode, struct file *file)
kfree(PT.bufptr);
PT.bufptr = NULL;
- MOD_DEC_USE_COUNT;
-
return 0;
}
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index f38e102093bf83..802b04e89d7204 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -801,6 +801,16 @@ static int fd_eject(struct floppy_state *fs)
return err;
}
+int swim3_fd_eject(int devnum)
+{
+ if (devnum >= floppy_count)
+ return -ENODEV;
+ /* Do not check this - this function should ONLY be called early
+ * in the boot process! */
+ /* if (floppy_states[devnum].ref_count != 1) return -EBUSY; */
+ return fd_eject(&floppy_states[devnum]);
+}
+
static struct floppy_struct floppy_type =
{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 74df1096ef0824..5ac2a16a6fc8fa 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -258,20 +258,19 @@ static int xd_open (struct inode *inode,struct file *file)
{
int dev = DEVICE_NR(inode->i_rdev);
+ MOD_INC_USE_COUNT;
+
if (dev < xd_drives) {
while (!xd_valid[dev])
sleep_on(&xd_wait_open);
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif /* MODULE */
-
xd_access[dev]++;
return (0);
}
- else
- return -ENXIO;
+
+ MOD_DEC_USE_COUNT;
+ return -ENXIO;
}
/* do_xd_request: handle an incoming request */
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
index e585bb34c4c2a6..74ea30a41ebcb2 100644
--- a/drivers/block/z2ram.c
+++ b/drivers/block/z2ram.c
@@ -165,12 +165,16 @@ z2_open( struct inode *inode, struct file *filp )
sizeof( z2ram_map[0] );
int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) *
sizeof( z2ram_map[0] );
+ int rc = -ENOMEM;
+
+ MOD_INC_USE_COUNT;
device = DEVICE_NR( inode->i_rdev );
if ( current_device != -1 && current_device != device )
{
- return -EBUSY;
+ rc = -EBUSY;
+ goto err_out;
}
if ( current_device == -1 )
@@ -188,7 +192,7 @@ z2_open( struct inode *inode, struct file *filp )
if (index >= m68k_realnum_memory) {
printk( KERN_ERR DEVICE_NAME
": no such entry in z2ram_map\n" );
- return -ENOMEM;
+ goto err_out;
}
paddr = m68k_memory[index].addr;
@@ -215,7 +219,7 @@ z2_open( struct inode *inode, struct file *filp )
{
printk( KERN_ERR DEVICE_NAME
": cannot get mem for z2ram_map\n" );
- return -ENOMEM;
+ goto err_out;
}
while (size) {
@@ -240,7 +244,7 @@ z2_open( struct inode *inode, struct file *filp )
{
printk( KERN_ERR DEVICE_NAME
": cannot get mem for z2ram_map\n" );
- return -ENOMEM;
+ goto err_out;
}
get_z2ram();
@@ -261,7 +265,7 @@ z2_open( struct inode *inode, struct file *filp )
{
printk( KERN_ERR DEVICE_NAME
": cannot get mem for z2ram_map\n" );
- return -ENOMEM;
+ goto err_out;
}
get_z2ram();
@@ -279,7 +283,7 @@ z2_open( struct inode *inode, struct file *filp )
{
printk( KERN_ERR DEVICE_NAME
": cannot get mem for z2ram_map\n" );
- return -ENOMEM;
+ goto err_out;
}
get_chipram();
@@ -292,15 +296,17 @@ z2_open( struct inode *inode, struct file *filp )
break;
default:
- return -ENODEV;
+ rc = -ENODEV;
+ goto err_out;
+
+ break;
}
if ( z2ram_size == 0 )
{
- kfree( z2ram_map );
printk( KERN_NOTICE DEVICE_NAME
": no unused ZII/Chip RAM found\n" );
- return -ENOMEM;
+ goto err_out_kfree;
}
current_device = device;
@@ -309,9 +315,13 @@ z2_open( struct inode *inode, struct file *filp )
blk_size[ MAJOR_NR ] = z2_sizes;
}
- MOD_INC_USE_COUNT;
-
return 0;
+
+err_out_kfree:
+ kfree( z2ram_map );
+err_out:
+ MOD_DEC_USE_COUNT;
+ return rc;
}
static int
diff --git a/drivers/char/acquirewdt.c b/drivers/char/acquirewdt.c
index 9d86479dc1ee13..eaa9e6bae6d6b7 100644
--- a/drivers/char/acquirewdt.c
+++ b/drivers/char/acquirewdt.c
@@ -125,7 +125,6 @@ static int acq_open(struct inode *inode, struct file *file)
spin_unlock(&acq_lock);
return -EBUSY;
}
- MOD_INC_USE_COUNT;
/*
* Activate
*/
@@ -150,7 +149,6 @@ static int acq_close(struct inode *inode, struct file *file)
acq_is_open=0;
spin_unlock(&acq_lock);
}
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -175,6 +173,7 @@ static int acq_notify_sys(struct notifier_block *this, unsigned long code,
static struct file_operations acq_fops = {
+ owner: THIS_MODULE,
read: acq_read,
write: acq_write,
ioctl: acq_ioctl,
diff --git a/drivers/char/adbmouse.c b/drivers/char/adbmouse.c
index a33693c1497dc1..a4108cf0ec42a9 100644
--- a/drivers/char/adbmouse.c
+++ b/drivers/char/adbmouse.c
@@ -132,20 +132,22 @@ static void adb_mouse_interrupt(unsigned char *buf, int nb)
static int release_mouse(struct inode *inode, struct file *file)
{
adb_mouse_interrupt_hook = NULL;
- MOD_DEC_USE_COUNT;
+ /*
+ * FIXME?: adb_mouse_interrupt_hook may still be executing
+ * on another CPU.
+ */
return 0;
}
static int open_mouse(struct inode *inode, struct file *file)
{
- MOD_INC_USE_COUNT;
adb_mouse_interrupt_hook = adb_mouse_interrupt;
return 0;
}
static struct busmouse adb_mouse =
{
- ADB_MOUSE_MINOR, "adbmouse", open_mouse, release_mouse, 7
+ ADB_MOUSE_MINOR, "adbmouse", THIS_MODULE, open_mouse, release_mouse, 7
};
static int __init adb_mouse_init(void)
diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c
index 66ec50b9f2e263..e67beef382a01f 100644
--- a/drivers/char/agp/agpgart_fe.c
+++ b/drivers/char/agp/agpgart_fe.c
@@ -1061,6 +1061,7 @@ ioctl_out:
static struct file_operations agp_fops =
{
+ owner: THIS_MODULE,
llseek: agp_lseek,
read: agp_read,
write: agp_write,
diff --git a/drivers/char/atarimouse.c b/drivers/char/atarimouse.c
index a188320c2f7b02..ce084372596084 100644
--- a/drivers/char/atarimouse.c
+++ b/drivers/char/atarimouse.c
@@ -39,53 +39,50 @@ extern int atari_mouse_buttons;
static void atari_mouse_interrupt(char *buf)
{
- int buttons;
+ int buttons;
-/* ikbd_mouse_disable(); */
+/* ikbd_mouse_disable(); */
- buttons = ((buf[0] & 1)
+ buttons = ((buf[0] & 1)
| ((buf[0] & 2) << 1)
| (atari_mouse_buttons & 2));
- atari_mouse_buttons = buttons;
+ atari_mouse_buttons = buttons;
- busmouse_add_movementbuttons(msedev, buf[1], -buf[2], buttons ^ 7);
-/* ikbd_mouse_rel_pos(); */
+ busmouse_add_movementbuttons(msedev, buf[1], -buf[2], buttons ^ 7);
+/* ikbd_mouse_rel_pos(); */
}
static int release_mouse(struct inode *inode, struct file *file)
{
- ikbd_mouse_disable();
-
- atari_mouse_interrupt_hook = NULL;
- MOD_DEC_USE_COUNT;
- return 0;
+ ikbd_mouse_disable();
+ atari_mouse_interrupt_hook = NULL;
+ return 0;
}
static int open_mouse(struct inode *inode, struct file *file)
{
- atari_mouse_buttons = 0;
- ikbd_mouse_y0_top ();
- ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]);
- ikbd_mouse_rel_pos();
- MOD_INC_USE_COUNT;
- atari_mouse_interrupt_hook = atari_mouse_interrupt;
- return 0;
+ atari_mouse_buttons = 0;
+ ikbd_mouse_y0_top ();
+ ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]);
+ ikbd_mouse_rel_pos();
+ atari_mouse_interrupt_hook = atari_mouse_interrupt;
+ return 0;
}
static struct busmouse atarimouse = {
- ATARIMOUSE_MINOR, "atarimouse", open_mouse, release_mouse, 0
+ ATARIMOUSE_MINOR, "atarimouse", THIS_MODULE, open_mouse, release_mouse, 0
};
static int __init atari_mouse_init(void)
{
- if (!MACH_IS_ATARI)
- return -ENODEV;
- msedev = register_busmouse(&atarimouse);
- if (msedev < 0)
- printk(KERN_WARNING "Unable to register Atari mouse driver.\n");
- else
- printk(KERN_INFO "Atari mouse installed.\n");
- return msedev < 0 ? msedev : 0;
+ if (!MACH_IS_ATARI)
+ return -ENODEV;
+ msedev = register_busmouse(&atarimouse);
+ if (msedev < 0)
+ printk(KERN_WARNING "Unable to register Atari mouse driver.\n");
+ else
+ printk(KERN_INFO "Atari mouse installed.\n");
+ return msedev < 0 ? msedev : 0;
}
diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c
index dd9ca78c6fb7c9..e1cc54e3bd2490 100644
--- a/drivers/char/bttv.c
+++ b/drivers/char/bttv.c
@@ -64,7 +64,6 @@ static struct bttv bttvs[BTTV_MAX];
/* insmod args */
MODULE_PARM(triton1,"i");
-MODULE_PARM(remap,"1-4i");
MODULE_PARM(radio,"1-4i");
MODULE_PARM(card,"1-4i");
MODULE_PARM(pll,"1-4i");
@@ -76,6 +75,7 @@ MODULE_PARM(autoload,"i");
MODULE_PARM(gbuffers,"i");
MODULE_PARM(gbufsize,"i");
+EXPORT_SYMBOL(bttv_get_cardinfo);
EXPORT_SYMBOL(bttv_get_id);
EXPORT_SYMBOL(bttv_gpio_enable);
EXPORT_SYMBOL(bttv_read_gpio);
@@ -91,7 +91,6 @@ static unsigned int bigendian=1;
static unsigned int bigendian=0;
#endif
static int triton1=0;
-static unsigned long remap[BTTV_MAX];
static unsigned int radio[BTTV_MAX];
static unsigned int card[BTTV_MAX] = { 0, 0, 0, 0 };
static unsigned int pll[BTTV_MAX] = { -1, -1, -1, -1};
@@ -123,8 +122,19 @@ static unsigned int autoload = 0;
/* gpio ports (IR for example) */
/* see bttv.h for comments */
+int bttv_get_cardinfo(unsigned int card, int *type, int *cardid)
+{
+ if (card >= bttv_num) {
+ return -1;
+ }
+ *type = bttvs[card].type;
+ *cardid = bttvs[card].cardid;
+ return 0;
+}
+
int bttv_get_id(unsigned int card)
{
+ printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n");
if (card >= bttv_num) {
return -1;
}
@@ -180,7 +190,7 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
return 0;
}
-WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card)
+wait_queue_head_t* bttv_get_gpio_queue(unsigned int card)
{
struct bttv *btv;
@@ -467,7 +477,7 @@ static struct i2c_client i2c_client_template = {
NULL
};
-static int __init init_bttv_i2c(struct bttv *btv)
+static int __devinit init_bttv_i2c(struct bttv *btv)
{
/* i2c bit_adapter */
memcpy(&btv->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter));
@@ -489,7 +499,7 @@ static int __init init_bttv_i2c(struct bttv *btv)
}
/* read I2C */
-static int __init I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
+static int I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
{
unsigned char buffer = 0;
@@ -514,7 +524,7 @@ static int __init I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
}
/* write I2C */
-static int __init I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
+static int I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
unsigned char b2, int both)
{
unsigned char buffer[2];
@@ -531,7 +541,7 @@ static int __init I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b
}
/* read EEPROM */
-static void __init readee(struct bttv *btv, unsigned char *eedata, int addr)
+static void __devinit readee(struct bttv *btv, unsigned char *eedata, int addr)
{
int i;
@@ -558,7 +568,7 @@ static struct HAUPPAUGE_TUNER
int id;
char *name;
}
-hauppauge_tuner[] __initdata =
+hauppauge_tuner[] __devinitdata =
{
{ TUNER_ABSENT, "" },
{ TUNER_ABSENT, "External" },
@@ -606,7 +616,7 @@ hauppauge_tuner[] __initdata =
{ TUNER_ABSENT, "Temic 4046FM5" },
};
-static void __init hauppauge_eeprom(struct bttv *btv)
+static void __devinit hauppauge_eeprom(struct bttv *btv)
{
if (eeprom_data[9] < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER))
{
@@ -615,11 +625,9 @@ static void __init hauppauge_eeprom(struct bttv *btv)
printk("bttv%d: Hauppauge eeprom: tuner=%s (%d)\n",btv->nr,
hauppauge_tuner[eeprom_data[9]].name,btv->tuner_type);
}
-
- return;
}
-static void __init hauppauge_boot_msp34xx(struct bttv *btv)
+static void __devinit hauppauge_boot_msp34xx(struct bttv *btv)
{
int i;
@@ -655,7 +663,7 @@ static void __init hauppauge_boot_msp34xx(struct bttv *btv)
/* This is basically the same procedure as
* used by Alessandro Rubini in his pxc200
* driver, but using BTTV functions */
-static void __init init_PXC200(struct bttv *btv)
+static void __devinit init_PXC200(struct bttv *btv)
{
static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
@@ -705,7 +713,7 @@ static struct CARD {
unsigned id;
int cardnr;
char *name;
-} cards[] __initdata = {
+} cards[] __devinitdata = {
{ 0x00011002, BTTV_HAUPPAUGE878, "ATI TV Wonder" },
{ 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
{ 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" },
@@ -813,7 +821,7 @@ static struct tvcard tvcards[] =
/* 0x10 */
{ "Pixelview PlayTV (bt878)",
- 3, 1, 0, 2, 0x01fe00, { 2, 0, 1, 1},
+ 3, 1, 0, 2, 0x01fe00, { 2, 3, 1, 1},
{ 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },0,
1,1,1,1,0,0,0,1, PLL_28, -1 },
{ "Leadtek WinView 601",
@@ -910,10 +918,18 @@ static struct tvcard tvcards[] =
{ "ProVideo PV951", /* pic16c54 */
3, 1, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0},0,
0,0,0,0,0,0,0,0, PLL_28, 1 },
+ { "Little OnAir TV",
+ 3, 1, 0, 2, 0xe00b, {2, 3, 1, 1},
+ {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},0,
+ 0,0,0,0,0,0,0,0, PLL_NONE, -1 },
+
+ { "Sigma TVII-FM",
+ 2, 1, 0, -1, 3, {2, 3, 1, 1}, {1, 1, 0, 2, 3},0,
+ 0,0,0,0,0,0,0,0, PLL_NONE, -1 },
};
#define TVCARDS (sizeof(tvcards)/sizeof(struct tvcard))
-static void __init dump_eeprom(struct bttv *btv,int addr)
+static void __devinit dump_eeprom(struct bttv *btv,int addr)
{
int i;
@@ -930,7 +946,7 @@ static void __init dump_eeprom(struct bttv *btv,int addr)
}
}
-static int __init idcard_eeprom(struct bttv *btv)
+static int __devinit idcard_eeprom(struct bttv *btv)
{
unsigned id;
int i,n;
@@ -943,6 +959,7 @@ static int __init idcard_eeprom(struct bttv *btv)
return -1;
/* look for the card */
+ btv->cardid = id;
for (n = -1, i = 0; cards[i].id != 0; i++)
if (cards[i].id == id)
n = i;
@@ -1203,7 +1220,7 @@ static void make_vbitab(struct bttv *btv)
unsigned int *po=(unsigned int *) btv->vbi_odd;
unsigned int *pe=(unsigned int *) btv->vbi_even;
- if (debug)
+ if (debug > 1)
printk("bttv%d: vbi1: po=%08lx pe=%08lx\n",
btv->nr,virt_to_bus(po), virt_to_bus(pe));
@@ -1225,7 +1242,7 @@ static void make_vbitab(struct bttv *btv)
*(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16));
*(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
- if (debug)
+ if (debug > 1)
printk("bttv%d: vbi2: po=%08lx pe=%08lx\n",
btv->nr,virt_to_bus(po), virt_to_bus(pe));
}
@@ -1302,7 +1319,7 @@ static int make_prisctab(struct bttv *btv, unsigned int *ro,
unsigned long vadr=(unsigned long) vbuf;
int shift, csize;
- if (debug)
+ if (debug > 1)
printk("bttv%d: prisc1: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1399,7 +1416,7 @@ static int make_prisctab(struct bttv *btv, unsigned int *ro,
*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
*(re++)=cpu_to_le32(btv->bus_vbi_odd);
- if (debug)
+ if (debug > 1)
printk("bttv%d: prisc2: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1424,7 +1441,7 @@ static int make_vrisctab(struct bttv *btv, unsigned int *ro,
if (palette>=VIDEO_PALETTE_PLANAR)
return make_prisctab(btv, ro, re, vbuf, width, height, palette);
- if (debug)
+ if (debug > 1)
printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1476,7 +1493,7 @@ static int make_vrisctab(struct bttv *btv, unsigned int *ro,
*(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16));
*(re++)=cpu_to_le32(btv->bus_vbi_odd);
- if (debug)
+ if (debug > 1)
printk("bttv%d: vrisc2: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
@@ -1494,7 +1511,7 @@ static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int
int W, l, r;
int i;
- if (debug)
+ if (debug > 1)
printk("bttv clip: %dx%d+%d+%d\n",w,h,x,y);
/* bitmap is fixed width, 128 bytes (1024 pixels represented) */
@@ -1559,7 +1576,7 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
inter=(btv->win.interlace&1)^1;
width=btv->win.width;
height=btv->win.height;
- if (debug)
+ if (debug > 1)
printk("bttv%d: clip1: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
btv->nr,btv->picture.palette,width,height,bpl,bpp);
if(width > 1023)
@@ -1573,7 +1590,7 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
printk("bttv%d: clip: ro=%08lx re=%08lx\n",
btv->nr,virt_to_bus(ro), virt_to_bus(re));
- if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) {
+ if ((clipmap=vmalloc_32(VIDEO_CLIPMAP_SIZE))==NULL) {
/* can't clip, don't generate any risc code */
*(ro++)=cpu_to_le32(BT848_RISC_JUMP);
*(ro++)=cpu_to_le32(btv->bus_vbi_even);
@@ -1668,7 +1685,7 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
*(re++)=cpu_to_le32(BT848_RISC_JUMP);
*(re++)=cpu_to_le32(btv->bus_vbi_odd);
- if (debug)
+ if (debug > 1)
printk("bttv%d: clip2: pal=%d size=%dx%d, bpl=%d bpp=%d\n",
btv->nr,btv->picture.palette,width,height,bpl,bpp);
}
@@ -1734,9 +1751,6 @@ static void bt848_set_geo(struct bttv *btv,
u16 ewidth, eheight, owidth, oheight;
u16 format, bswap;
struct tvnorm *tvn;
- unsigned long flags;
-
- spin_lock_irqsave(&btv->s_lock, flags);
tvn=&tvnorms[btv->win.norm];
@@ -1789,8 +1803,6 @@ static void bt848_set_geo(struct bttv *btv,
btwrite(format, BT848_COLOR_FMT);
btwrite(bswap | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
-
- spin_unlock_irqrestore(&btv->s_lock, flags);
}
@@ -1847,7 +1859,6 @@ static void bt848_set_winsize(struct bttv *btv)
/*
* Grab into virtual memory.
- * Currently only does double buffering. Do we need more?
*/
static int vgrab(struct bttv *btv, struct video_mmap *mp)
@@ -1904,16 +1915,16 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
btv->gbuf[mp->frame].ro = 0;
#endif
- if (btv->gq_in == btv->gq_out) {
+ if (-1 == btv->gq_grab && btv->gq_in == btv->gq_out) {
btv->gq_start = 1;
btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ);
}
btv->gqueue[btv->gq_in++] = mp->frame;
btv->gq_in = btv->gq_in % MAX_GBUFFERS;
- spin_unlock_irqrestore(&btv->s_lock, flags);
btor(3, BT848_CAP_CTL);
btor(3, BT848_GPIO_DMA_CTL);
+ spin_unlock_irqrestore(&btv->s_lock, flags);
return 0;
}
@@ -1927,39 +1938,43 @@ static long bttv_read(struct video_device *v, char *buf, unsigned long count, in
{
struct bttv *btv= (struct bttv *)v;
int q,todo;
+ DECLARE_WAITQUEUE(wait, current);
/* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
- unsigned long flags;
-
if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q))
return -EFAULT;
todo-=q;
buf+=q;
- spin_lock_irqsave(&btv->s_lock, flags);
+ add_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_INTERRUPTIBLE;
if (todo && q==VBIBUF_SIZE-btv->vbip)
{
if(nonblock)
{
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
if(count==todo)
return -EWOULDBLOCK;
return count-todo;
}
- spin_unlock_irqrestore(&btv->s_lock, flags);
- interruptible_sleep_on(&btv->vbiq);
+ schedule();
if(signal_pending(current))
{
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
+
if(todo==count)
return -EINTR;
else
return count-todo;
}
- } else
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ }
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
}
if (todo)
{
@@ -1980,9 +1995,11 @@ static inline void burst(int on)
static void bt848_restart(struct bttv *btv)
{
+ unsigned long irq_flags;
+
if (verbose)
printk("bttv%d: resetting chip\n",btv->nr);
- btwrite(~0x0UL, BT848_INT_STAT);
+ btwrite(0xfffffUL, BT848_INT_STAT);
btand(~15, BT848_GPIO_DMA_CTL);
btwrite(0, BT848_SRESET);
btwrite(virt_to_bus(btv->risc_jmp+2),
@@ -1994,8 +2011,10 @@ static void bt848_restart(struct bttv *btv)
btv->errors = 0;
btv->needs_restart = 0;
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_geo(btv,0);
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
/*
@@ -2042,13 +2061,16 @@ static int bttv_open(struct video_device *dev, int flags)
static void bttv_close(struct video_device *dev)
{
struct bttv *btv=(struct bttv *)dev;
+ unsigned long irq_flags;
down(&btv->lock);
btv->user--;
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->scr_on = 0;
btv->risc_cap_odd = 0;
btv->risc_cap_even = 0;
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
/*
* A word of warning. At this point the chip
@@ -2133,9 +2155,11 @@ static inline void bt848_sat_v(struct bttv *btv, unsigned long data)
static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
{
struct bttv *btv=(struct bttv *)dev;
+ unsigned long irq_flags;
int i,ret = 0;
- if (debug) printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd);
+ if (debug > 1)
+ printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd);
switch (cmd) {
case VIDIOCGCAP:
@@ -2206,7 +2230,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
if (btv->win.norm != v.norm) {
btv->win.norm = v.norm;
make_vbitab(btv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_winsize(btv);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
up(&btv->lock);
return 0;
@@ -2248,7 +2274,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
down(&btv->lock);
set_pll(btv);
make_vbitab(btv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_winsize(btv);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
up(&btv->lock);
}
return 0;
@@ -2289,12 +2317,13 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
if(copy_from_user(&vw,arg,sizeof(vw)))
return -EFAULT;
+ down(&btv->lock);
if(vw.flags || vw.width < 16 || vw.height < 16)
{
- down(&btv->lock);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->scr_on = 0;
bt848_set_risc_jmps(btv,-1);
- up(&btv->lock);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
return -EINVAL;
}
if (btv->win.bpp < 4)
@@ -2302,18 +2331,17 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
vw.x = (vw.x + 3) & ~3;
vw.width &= ~3;
}
- down(&btv->lock);
if (btv->needs_restart)
bt848_restart(btv);
btv->win.x=vw.x;
btv->win.y=vw.y;
btv->win.width=vw.width;
btv->win.height=vw.height;
-
+
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_risc_jmps(btv,0);
-
bt848_set_winsize(btv);
- up(&btv->lock);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
/*
* Do any clips.
@@ -2337,11 +2365,12 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return -EFAULT;
}
}
- down(&btv->lock);
make_clip_tab(btv, vcp, vw.clipcount);
if (vw.clipcount != 0)
vfree(vcp);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
up(&btv->lock);
return 0;
}
@@ -2370,13 +2399,13 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
return -EINVAL;
if (btv->win.width==0 || btv->win.height==0)
return -EINVAL;
- down(&btv->lock);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
if (v == 1 && btv->win.vidadr != 0)
btv->scr_on = 1;
if (v == 0)
btv->scr_on = 0;
bt848_set_risc_jmps(btv,-1);
- up(&btv->lock);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
return 0;
}
case VIDIOCGFBUF:
@@ -2500,9 +2529,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
if(!(v.flags&VIDEO_AUDIO_MUTE))
audio(btv, AUDIO_UNMUTE, 1);
- up(&btv->lock);
call_i2c_clients(btv,cmd,&v);
- down(&btv->lock);
if (btv->type == BTTV_TERRATV) {
unsigned int con = 0;
@@ -2554,6 +2581,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
}
case VIDIOCSYNC:
+ {
+ DECLARE_WAITQUEUE(wait, current);
+
if(copy_from_user((void *)&i,arg,sizeof(int)))
return -EFAULT;
if (i < 0 || i >= gbuffers)
@@ -2563,13 +2593,20 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
ret = -EINVAL;
break;
case GBUFFER_GRABBING:
+ add_wait_queue(&btv->capq, &wait);
+ current->state = TASK_INTERRUPTIBLE;
while(btv->gbuf[i].stat==GBUFFER_GRABBING) {
if (debug)
printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i);
- interruptible_sleep_on(&btv->capq);
- if(signal_pending(current))
+ schedule();
+ if(signal_pending(current)) {
+ remove_wait_queue(&btv->capq, &wait);
+ current->state = TASK_RUNNING;
return -EINTR;
+ }
}
+ remove_wait_queue(&btv->capq, &wait);
+ current->state = TASK_RUNNING;
/* fall throuth */
case GBUFFER_DONE:
case GBUFFER_ERROR:
@@ -2584,6 +2621,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
up(&btv->lock);
}
return ret;
+ }
case BTTV_FIELDNR:
if(copy_to_user((void *) arg, (void *) &btv->last_field,
@@ -2602,7 +2640,6 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
btv->pll.pll_ofreq = p.pll_ofreq;
btv->pll.pll_crystal = p.pll_crystal;
up(&btv->lock);
-
break;
}
@@ -2749,12 +2786,11 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
{
struct bttv *btv=(struct bttv *)(v-2);
int q,todo;
+ DECLARE_WAITQUEUE(wait, current);
todo=count;
while (todo && todo>(q=VBIBUF_SIZE-btv->vbip))
{
- unsigned long flags;
-
if (btv->needs_restart) {
down(&btv->lock);
bt848_restart(btv);
@@ -2765,27 +2801,31 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count,
todo-=q;
buf+=q;
- spin_lock_irqsave(&btv->s_lock, flags);
+ add_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_INTERRUPTIBLE;
if (todo && q==VBIBUF_SIZE-btv->vbip)
{
if(nonblock)
{
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
if(count==todo)
return -EWOULDBLOCK;
return count-todo;
}
- spin_unlock_irqrestore(&btv->s_lock, flags);
- interruptible_sleep_on(&btv->vbiq);
+ schedule();
if(signal_pending(current))
{
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
if(todo==count)
return -EINTR;
else
return count-todo;
}
- } else
- spin_unlock_irqrestore(&btv->s_lock, flags);
+ }
+ remove_wait_queue(&btv->vbiq, &wait);
+ current->state = TASK_RUNNING;
}
if (todo)
{
@@ -2813,15 +2853,18 @@ static unsigned int vbi_poll(struct video_device *dev, struct file *file,
static int vbi_open(struct video_device *dev, int flags)
{
struct bttv *btv=(struct bttv *)(dev-2);
+ unsigned long irq_flags;
MOD_INC_USE_COUNT;
-
down(&btv->lock);
if (btv->needs_restart)
bt848_restart(btv);
+ set_pll(btv);
btv->vbip=VBIBUF_SIZE;
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->vbi_on = 1;
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
up(&btv->lock);
return 0;
@@ -2830,12 +2873,12 @@ static int vbi_open(struct video_device *dev, int flags)
static void vbi_close(struct video_device *dev)
{
struct bttv *btv=(struct bttv *)(dev-2);
+ unsigned long irq_flags;
- down(&btv->lock);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->vbi_on = 0;
bt848_set_risc_jmps(btv,-1);
- up(&btv->lock);
-
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
MOD_DEC_USE_COUNT;
}
@@ -3018,7 +3061,7 @@ static struct video_device radio_template=
#define TRITON_PEER_CONCURRENCY (1<<3)
-static void __init handle_chipset(void)
+static void __devinit handle_chipset(void)
{
struct pci_dev *dev = NULL;
@@ -3050,7 +3093,7 @@ static void __init handle_chipset(void)
/* can tda9855.c handle this too maybe? */
-static void __init init_tda9840(struct bttv *btv)
+static void __devinit init_tda9840(struct bttv *btv)
{
/* Horrible Hack */
I2CWrite(btv, I2C_TDA9840, TDA9840_SW, 0x2a, 1); /* sound mode switching */
@@ -3066,12 +3109,11 @@ static void __init init_tda9840(struct bttv *btv)
/* Figure out card and tuner type */
-static void __init idcard(struct bttv *btv)
+static void __devinit idcard(struct bttv *btv)
{
int type,eeprom = 0;
btwrite(0, BT848_GPIO_OUT_EN);
- DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", btv->nr, btread(BT848_GPIO_DATA)));
/* Default the card to the user-selected one. */
if (card[btv->nr] >= 0 && card[btv->nr] < TVCARDS)
@@ -3114,7 +3156,6 @@ static void __init idcard(struct bttv *btv)
(btv->id==848 && btv->revision==0x12) ? "A" : "",
tvcards[btv->type].name);
printk(KERN_INFO "bttv%d: model: %s\n",btv->nr,btv->video_dev.name);
-
/* board specific initialisations */
if (btv->type == BTTV_MIRO || btv->type == BTTV_MIROPRO) {
@@ -3228,10 +3269,6 @@ static void __init idcard(struct bttv *btv)
static void bt848_set_risc_jmps(struct bttv *btv, int flags)
{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&btv->s_lock, irq_flags);
-
if (-1 == flags) {
/* defaults */
flags = 0;
@@ -3241,8 +3278,9 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags)
flags |= 0x0c;
}
- if (debug) printk("bttv%d: set_risc_jmp %08lx:",
- btv->nr,virt_to_bus(btv->risc_jmp));
+ if (debug > 1)
+ printk("bttv%d: set_risc_jmp %08lx:",
+ btv->nr,virt_to_bus(btv->risc_jmp));
/* Sync to start of odd field */
btv->risc_jmp[0]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC
@@ -3252,24 +3290,29 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags)
/* Jump to odd vbi sub */
btv->risc_jmp[2]=cpu_to_le32(BT848_RISC_JUMP|(0xd<<20));
if (flags&8) {
- if (debug) printk(" ev=%08lx",virt_to_bus(btv->vbi_odd));
+ if (debug > 1)
+ printk(" ev=%08lx",virt_to_bus(btv->vbi_odd));
btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->vbi_odd));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
}
/* Jump to odd sub */
btv->risc_jmp[4]=cpu_to_le32(BT848_RISC_JUMP|(0xe<<20));
if (0 != btv->risc_cap_odd) {
- if (debug) printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd);
+ if (debug > 1)
+ printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd);
flags |= 3;
btv->risc_jmp[5]=cpu_to_le32(btv->risc_cap_odd);
} else if (flags&2) {
- if (debug) printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd));
+ if (debug > 1)
+ printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd));
btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_scr_odd));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_jmp+6));
}
@@ -3282,24 +3325,29 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags)
/* Jump to even vbi sub */
btv->risc_jmp[8]=cpu_to_le32(BT848_RISC_JUMP);
if (flags&4) {
- if (debug) printk(" ov=%08lx",virt_to_bus(btv->vbi_even));
+ if (debug > 1)
+ printk(" ov=%08lx",virt_to_bus(btv->vbi_even));
btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->vbi_even));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->risc_jmp+10));
}
/* Jump to even sub */
btv->risc_jmp[10]=cpu_to_le32(BT848_RISC_JUMP|(8<<20));
if (0 != btv->risc_cap_even) {
- if (debug) printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even);
+ if (debug > 1)
+ printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even);
flags |= 3;
btv->risc_jmp[11]=cpu_to_le32(btv->risc_cap_even);
} else if (flags&1) {
- if (debug) printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even));
+ if (debug > 1)
+ printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even));
btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_scr_even));
} else {
- if (debug) printk(" -----------");
+ if (debug > 1)
+ printk(" -----------");
btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12));
}
@@ -3311,18 +3359,17 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags)
btv->risc_jmp[13]=cpu_to_le32(virt_to_bus(btv->risc_jmp));
/* enable cpaturing and DMA */
- if (debug) printk(" flags=0x%x dma=%s\n",
- flags,(flags&0x0f) ? "on" : "off");
+ if (debug > 1)
+ printk(" flags=0x%x dma=%s\n",
+ flags,(flags&0x0f) ? "on" : "off");
btaor(flags, ~0x0f, BT848_CAP_CTL);
if (flags&0x0f)
bt848_dma(btv, 3);
else
bt848_dma(btv, 0);
-
- spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
-static int __init init_video_dev(struct bttv *btv)
+static int __devinit init_video_dev(struct bttv *btv)
{
memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template));
memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template));
@@ -3349,9 +3396,10 @@ static int __init init_video_dev(struct bttv *btv)
return 1;
}
-static int __init init_bt848(struct bttv *btv)
+static int __devinit init_bt848(struct bttv *btv)
{
int j;
+ unsigned long irq_flags;
btv->user=0;
init_MUTEX(&btv->lock);
@@ -3412,14 +3460,13 @@ static int __init init_bt848(struct bttv *btv)
return -1;
if (!(btv->risc_jmp =(unsigned int *) kmalloc(2048, GFP_KERNEL)))
return -1;
- DEBUG(printk(KERN_DEBUG "risc_jmp: %p\n",btv->risc_jmp));
btv->vbi_odd=btv->risc_jmp+16;
btv->vbi_even=btv->vbi_odd+256;
btv->bus_vbi_odd=virt_to_bus(btv->risc_jmp+12);
btv->bus_vbi_even=virt_to_bus(btv->risc_jmp+6);
btwrite(virt_to_bus(btv->risc_jmp+2), BT848_RISC_STRT_ADD);
- btv->vbibuf=(unsigned char *) vmalloc(VBIBUF_SIZE);
+ btv->vbibuf=(unsigned char *) vmalloc_32(VBIBUF_SIZE);
if (!btv->vbibuf)
return -1;
if (!(btv->gbuf = kmalloc(sizeof(struct bttv_gbuf)*gbuffers,GFP_KERNEL)))
@@ -3475,7 +3522,7 @@ static int __init init_bt848(struct bttv *btv)
btwrite(0x00, BT848_O_SCLOOP);
/* clear interrupt status */
- btwrite(~0x0UL, BT848_INT_STAT);
+ btwrite(0xfffffUL, BT848_INT_STAT);
/* set interrupt mask */
btwrite(btv->triton1|
@@ -3489,8 +3536,10 @@ static int __init init_bt848(struct bttv *btv)
BT848_INT_MASK);
make_vbitab(btv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
bt848_set_risc_jmps(btv,-1);
-
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
+
/*
* Now add the template and register the device unit.
*/
@@ -3505,7 +3554,8 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
u32 dstat;
int count,i;
struct bttv *btv;
-
+ unsigned long irq_flags;
+
btv=(struct bttv *)dev_id;
count=0;
while (1)
@@ -3515,6 +3565,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
astat=stat&btread(BT848_INT_MASK);
if (!astat)
return;
+ btwrite(astat,BT848_INT_STAT);
IDEBUG(printk ("bttv%d: astat=%08x\n", btv->nr, astat));
IDEBUG(printk ("bttv%d: stat=%08x\n", btv->nr, stat));
@@ -3550,15 +3601,18 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
btread(BT848_RISC_COUNT));
btv->errors++;
if (btv->errors < BTTV_ERRORS) {
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btand(~15, BT848_GPIO_DMA_CTL);
btwrite(virt_to_bus(btv->risc_jmp+2),
BT848_RISC_STRT_ADD);
bt848_set_geo(btv,0);
bt848_set_risc_jmps(btv,-1);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
} else {
if (verbose)
printk("bttv%d: aiee: error loops\n",btv->nr);
/* cancel all outstanding grab requests */
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->gq_in = 0;
btv->gq_out = 0;
btv->gq_grab = -1;
@@ -3569,8 +3623,9 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
btv->risc_cap_odd = 0;
btv->risc_cap_even = 0;
bt848_set_risc_jmps(btv,0);
-
btv->needs_restart = 1;
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
+
wake_up_interruptible(&btv->vbiq);
wake_up_interruptible(&btv->capq);
}
@@ -3596,6 +3651,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
if (debug)
printk("bttv%d: cap irq: done %d\n",btv->nr,btv->gq_grab);
do_gettimeofday(&btv->gbuf[btv->gq_grab].tv);
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->gbuf[btv->gq_grab].stat = GBUFFER_DONE;
btv->gq_grab = -1;
if (btv->gq_in != btv->gq_out)
@@ -3618,22 +3674,25 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA,
BT848_COLOR_CTL);
}
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
wake_up_interruptible(&btv->capq);
break;
}
if (stat&(8<<28))
{
+ spin_lock_irqsave(&btv->s_lock, irq_flags);
btv->gq_start = 0;
btv->gq_grab = btv->gqueue[btv->gq_out++];
btv->gq_out = btv->gq_out % MAX_GBUFFERS;
if (debug)
- printk("bttv%d: cap irq: capture %d\n",btv->nr,btv->gq_grab);
+ printk("bttv%d: cap irq: capture %d [start]\n",btv->nr,btv->gq_grab);
btv->risc_cap_odd = btv->gbuf[btv->gq_grab].ro;
btv->risc_cap_even = btv->gbuf[btv->gq_grab].re;
bt848_set_risc_jmps(btv,-1);
bt848_set_geo(btv,0);
btwrite(BT848_COLOR_CTL_GAMMA,
BT848_COLOR_CTL);
+ spin_unlock_irqrestore(&btv->s_lock, irq_flags);
}
}
if (astat&BT848_INT_OCERR)
@@ -3676,9 +3735,6 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
{
IDEBUG(printk ("bttv%d: IRQ_I2CDONE\n", btv->nr));
}
-
- btwrite(astat,BT848_INT_STAT);
-
count++;
if (count > 10)
printk (KERN_WARNING "bttv%d: irq loop %d\n",
@@ -3698,11 +3754,11 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
* Scan for a Bt848 card, request the irq and map the io memory
*/
-static void __init bttv_remove(struct pci_dev *pci_dev)
+static void __devinit bttv_remove(struct pci_dev *pci_dev)
{
u8 command;
int j;
- struct bttv *btv = pci_dev->driver_data;
+ struct bttv *btv = PCI_GET_DRIVER_DATA(pci_dev);
/* unregister i2c_bus */
i2c_bit_del_bus(&btv->i2c_adap);
@@ -3767,7 +3823,7 @@ static void __init bttv_remove(struct pci_dev *pci_dev)
}
-static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
+static int __devinit bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
{
int result;
unsigned char command;
@@ -3788,20 +3844,17 @@ static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pc
btv->vbi_even=NULL;
init_waitqueue_head(&btv->vbiq);
init_waitqueue_head(&btv->capq);
- init_waitqueue_head(&btv->capqo);
- init_waitqueue_head(&btv->capqe);
btv->vbip=VBIBUF_SIZE;
-
- init_waitqueue_head(&btv->gpioq);
btv->s_lock = SPIN_LOCK_UNLOCKED;
+ init_waitqueue_head(&btv->gpioq);
btv->shutdown=0;
btv->id=dev->device;
btv->irq=dev->irq;
- btv->bt848_adr=pci_resource_start(dev, 0);
+ btv->bt848_adr=pci_resource_start(dev,0);
if (pci_enable_device(dev))
return -EIO;
- if (!request_mem_region(btv->bt848_adr,
+ if (!request_mem_region(pci_resource_start(dev,0),
pci_resource_len(dev,0),
"bttv")) {
return -EBUSY;
@@ -3871,24 +3924,23 @@ static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pc
}
}
- dev->driver_data = btv;
+ PCI_SET_DRIVER_DATA(dev,btv);
if(init_bt848(btv) < 0) {
bttv_remove(dev);
return -EIO;
}
-
bttv_num++;
return 0;
fail:
- release_mem_region(btv->bt848_adr,
+ release_mem_region(pci_resource_start(btv->dev,0),
pci_resource_len(btv->dev,0));
return result;
}
-static struct pci_device_id bttv_pci_tbl[] __initdata = {
+static struct pci_device_id bttv_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
@@ -3903,13 +3955,13 @@ static struct pci_device_id bttv_pci_tbl[] __initdata = {
MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
static struct pci_driver bttv_pci_driver = {
- name:"bttv",
- id_table:bttv_pci_tbl,
- probe:bttv_probe,
- remove:bttv_remove,
+ name: "bttv",
+ id_table: bttv_pci_tbl,
+ probe: bttv_probe,
+ remove: bttv_remove,
};
-static int __init bttv_init_module(void)
+int bttv_init_module(void)
{
bttv_num = 0;
@@ -3930,10 +3982,10 @@ static int __init bttv_init_module(void)
return pci_module_init(&bttv_pci_driver);
}
-static void __exit bttv_cleanup_module(void)
+void bttv_cleanup_module(void)
{
pci_unregister_driver(&bttv_pci_driver);
- return;
+ return;
}
module_init(bttv_init_module);
diff --git a/drivers/char/bttv.h b/drivers/char/bttv.h
index 3f4229fe89ce69..9189bfa777d6dc 100644
--- a/drivers/char/bttv.h
+++ b/drivers/char/bttv.h
@@ -21,7 +21,12 @@
#ifndef _BTTV_H_
#define _BTTV_H_
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,28)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,31)
+
+#ifndef PCI_GET_DRIVER_DATA
+# define PCI_GET_DRIVER_DATA(pdev) ((pdev)->driver_data)
+# define PCI_SET_DRIVER_DATA(pdev,data) (((pdev)->driver_data) = (data))
+#endif /* PCI_GET_DRIVER_DATA */
#include <linux/types.h>
#include <linux/wait.h>
@@ -32,12 +37,13 @@
#include "audiochip.h"
#include "bt848.h"
-#define WAIT_QUEUE wait_queue_head_t
-
-/* returns card type,
+/* returns card type + card ID (for bt878-based ones)
for possible values see lines below beginning with #define BTTV_UNKNOWN
returns negative value if error ocurred
*/
+extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid);
+
+/* obsolete, use bttv_get_cardinfo instead */
extern int bttv_get_id(unsigned int card);
/* sets GPOE register (BT848_GPIO_OUT_EN) to new value:
@@ -68,7 +74,7 @@ extern int bttv_write_gpio(unsigned int card,
WARNING: because there is no buffer for GPIO data, one MUST
process data ASAP
*/
-extern WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card);
+extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
#ifndef O_NONCAP
@@ -130,6 +136,7 @@ struct bttv {
struct video_picture picture; /* Current picture params */
struct video_audio audio_dev; /* Current audio params */
+ spinlock_t s_lock;
struct semaphore lock;
int user;
int capuser;
@@ -143,8 +150,6 @@ struct bttv {
int tuner_type;
int channel;
-
- spinlock_t s_lock;
unsigned int nr;
unsigned short id;
@@ -160,6 +165,7 @@ struct bttv {
struct bttv_window win;
int fb_color_ctl;
int type; /* card type */
+ int cardid;
int audio; /* audio mode */
int audio_chip; /* set to one of the chips supported by bttv.c */
int radio;
@@ -169,10 +175,8 @@ struct bttv {
u32 *vbi_even;
u32 bus_vbi_even;
u32 bus_vbi_odd;
- WAIT_QUEUE vbiq;
- WAIT_QUEUE capq;
- WAIT_QUEUE capqo;
- WAIT_QUEUE capqe;
+ wait_queue_head_t vbiq;
+ wait_queue_head_t capq;
int vbip;
u32 *risc_scr_odd;
@@ -198,7 +202,7 @@ struct bttv {
int errors;
int needs_restart;
- WAIT_QUEUE gpioq;
+ wait_queue_head_t gpioq;
int shutdown;
};
#endif
@@ -277,6 +281,8 @@ extern __inline__ void io_st_le32(volatile unsigned *addr, unsigned val)
#define BTTV_STB2 0x28
#define BTTV_AVPHONE98 0x29
#define BTTV_PV951 0x2a
+#define BTTV_ONAIR_TV 0x2b
+#define BTTV_SIGMA_TVII_FM 0x2c
#define PLL_NONE 0
#define PLL_28 1
diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c
index 1b09081c119f3a..5051e80baf17e1 100644
--- a/drivers/char/busmouse.c
+++ b/drivers/char/busmouse.c
@@ -171,13 +171,13 @@ static int busmouse_release(struct inode *inode, struct file *file)
busmouse_fasync(-1, file, 0);
if (--mse->active == 0) {
- if (mse->ops &&
- mse->ops->release)
- ret = mse->ops->release(inode, file);
-
+ if (mse->ops) {
+ if (mse->ops->release)
+ ret = mse->ops->release(inode, file);
+ if (mse->ops->owner)
+ __MOD_DEC_USE_COUNT(mse->ops->owner);
+ }
mse->ready = 0;
-
- MOD_DEC_USE_COUNT;
}
return ret;
@@ -192,16 +192,20 @@ static int busmouse_open(struct inode *inode, struct file *file)
mousedev = DEV_TO_MOUSE(inode->i_rdev);
if (mousedev >= NR_MICE)
return -EINVAL;
-
+
down(&mouse_sem);
mse = busmouse_data[mousedev];
if (!mse)
/* shouldn't happen, but... */
goto end;
- if (mse->ops &&
- mse->ops->open)
+ if (mse->ops && mse->ops->owner)
+ __MOD_INC_USE_COUNT(mse->ops->owner);
+ if (mse->ops && mse->ops->open) {
ret = mse->ops->open(inode, file);
+ if (ret && mse->ops->owner)
+ __MOD_DEC_USE_COUNT(mse->ops->owner);
+ }
if (ret)
goto end;
@@ -211,8 +215,6 @@ static int busmouse_open(struct inode *inode, struct file *file)
if (mse->active++)
goto end;
- MOD_INC_USE_COUNT;
-
spin_lock_irq(&mse->lock);
mse->ready = 0;
@@ -333,6 +335,7 @@ static unsigned int busmouse_poll(struct file *file, poll_table *wait)
struct file_operations busmouse_fops=
{
+ owner: THIS_MODULE,
read: busmouse_read,
write: busmouse_write,
poll: busmouse_poll,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 48047a637509d8..cf4bb1f8381a70 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -1,7 +1,8 @@
#undef BLOCKMOVE
#define Z_WAKE
+#undef Z_EXT_CHARS_IN_BUFFER
static char rcsid[] =
-"$Revision: 2.3.2.6 $$Date: 2000/05/05 13:56:05 $";
+"$Revision: 2.3.2.7 $$Date: 2000/06/01 18:26:34 $";
/*
* linux/drivers/char/cyclades.c
@@ -24,6 +25,12 @@ static char rcsid[] =
* This version supports shared IRQ's (only for PCI boards).
*
* $Log: cyclades.c,v $
+ * Revision 2.3.2.7 2000/06/01 18:26:34 ivan
+ * Request PLX I/O region, although driver doesn't use it, to avoid
+ * problems with other drivers accessing it.
+ * Removed count for on-board buffer characters in cy_chars_in_buffer
+ * (Cyclades-Z only).
+ *
* Revision 2.3.2.6 2000/05/05 13:56:05 ivan
* Driver now reports physical instead of virtual memory addresses.
* Masks were added to some Cyclades-Z read accesses.
@@ -636,6 +643,7 @@ static char rcsid[] =
#include <linux/ptrace.h>
#include <linux/cyclades.h>
#include <linux/mm.h>
+#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
@@ -882,9 +890,8 @@ static void cyz_poll(unsigned long);
static long cyz_polling_cycle = CZ_DEF_POLL;
static int cyz_timeron = 0;
-static struct timer_list
-cyz_timerlist = {
- NULL, NULL, 0, 0, cyz_poll
+static struct timer_list cyz_timerlist = {
+ function: cyz_poll
};
#else /* CONFIG_CYZ_INTR */
static void cyz_rx_restart(unsigned long);
@@ -3122,12 +3129,15 @@ cy_chars_in_buffer(struct tty_struct *tty)
card = info->card;
channel = (info->line) - (cy_card[card].first_line);
+#ifdef Z_EXT_CHARS_IN_BUFFER
if (!IS_CYC_Z(cy_card[card])) {
+#endif /* Z_EXT_CHARS_IN_BUFFER */
#ifdef CY_DEBUG_IO
printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
info->line, info->xmit_cnt); /* */
#endif
return info->xmit_cnt;
+#ifdef Z_EXT_CHARS_IN_BUFFER
} else {
static volatile struct FIRM_ID *firm_id;
static volatile struct ZFW_CTRL *zfw_ctrl;
@@ -3156,6 +3166,7 @@ cy_chars_in_buffer(struct tty_struct *tty)
#endif
return (info->xmit_cnt + char_count);
}
+#endif /* Z_EXT_CHARS_IN_BUFFER */
} /* cy_chars_in_buffer */
@@ -4856,7 +4867,7 @@ cy_detect_pci(void)
struct pci_dev *pdev = NULL;
unsigned char cyy_rev_id;
unsigned char cy_pci_irq = 0;
- uclong cy_pci_phys0, cy_pci_phys2;
+ uclong cy_pci_phys0, cy_pci_phys1, cy_pci_phys2;
uclong cy_pci_addr0, cy_pci_addr2;
unsigned short i,j,cy_pci_nchan, plx_ver;
unsigned short device_id,dev_index = 0;
@@ -4885,6 +4896,7 @@ cy_detect_pci(void)
/* read PCI configuration area */
cy_pci_irq = pdev->irq;
cy_pci_phys0 = pci_resource_start(pdev, 0);
+ cy_pci_phys1 = pci_resource_start(pdev, 1);
cy_pci_phys2 = pci_resource_start(pdev, 2);
pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
@@ -4907,6 +4919,11 @@ cy_detect_pci(void)
pdev->resource[2].flags &= ~IORESOURCE_IO;
}
+ /* Although we don't use this I/O region, we should
+ request it from the kernel anyway, to avoid problems
+ with other drivers accessing it. */
+ request_region(cy_pci_phys1, CyPCI_Yctl, "Cyclom-Y");
+
#if defined(__alpha__)
if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
@@ -5054,6 +5071,12 @@ cy_detect_pci(void)
"Ignoring it...\n");
pdev->resource[2].flags &= ~IORESOURCE_IO;
}
+
+ /* Although we don't use this I/O region, we should
+ request it from the kernel anyway, to avoid problems
+ with other drivers accessing it. */
+ request_region(cy_pci_phys1, CyPCI_Zctl, "Cyclades-Z");
+
if (mailbox == ZE_V1) {
#if !defined(__alpha__)
cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 5a89e008a16305..f0c76181ba39ac 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -311,22 +311,6 @@ ds1620_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned
return 0;
}
-static int
-ds1620_open(struct inode *inode, struct file *file)
-{
- MOD_INC_USE_COUNT;
-
- return 0;
-}
-
-static int
-ds1620_release(struct inode *inode, struct file *file)
-{
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
#ifdef THERM_USE_PROC
static int
proc_therm_ds1620_read(char *buf, char **start, off_t offset,
@@ -352,10 +336,9 @@ static struct proc_dir_entry *proc_therm_ds1620;
#endif
static struct file_operations ds1620_fops = {
+ owner: THIS_MODULE,
read: ds1620_read,
ioctl: ds1620_ioctl,
- open: ds1620_open,
- release: ds1620_release,
};
static struct miscdevice ds1620_miscdev = {
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index ac27c9e0e9ef0b..dc076dd5a400a3 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -472,10 +472,6 @@ static int dsp56k_open(struct inode *inode, struct file *file)
return -ENXIO;
}
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif /* MODULE */
-
return 0;
}
@@ -495,13 +491,11 @@ static int dsp56k_release(struct inode *inode, struct file *file)
return -ENXIO;
}
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
return 0;
}
static struct file_operations dsp56k_fops = {
+ owner: THIS_MODULE,
read: dsp56k_read,
write: dsp56k_write,
ioctl: dsp56k_ioctl,
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 542ad99bf6ba69..730b69b1773dd5 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -102,6 +102,7 @@ static int dtlk_ioctl(struct inode *inode, struct file *file,
static struct file_operations dtlk_fops =
{
+ owner: THIS_MODULE,
read: dtlk_read,
write: dtlk_write,
poll: dtlk_poll,
@@ -306,7 +307,6 @@ static int dtlk_ioctl(struct inode *inode,
static int dtlk_open(struct inode *inode, struct file *file)
{
- MOD_INC_USE_COUNT;
TRACE_TEXT("(dtlk_open");
switch (MINOR(inode->i_rdev)) {
@@ -322,7 +322,6 @@ static int dtlk_open(struct inode *inode, struct file *file)
static int dtlk_release(struct inode *inode, struct file *file)
{
- MOD_DEC_USE_COUNT;
TRACE_TEXT("(dtlk_release");
switch (MINOR(inode->i_rdev)) {
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 103e60eef5f397..9ad85c68797810 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -281,6 +281,7 @@ efi_rtc_close(struct inode *inode, struct file *file)
*/
static struct file_operations efi_rtc_fops = {
+ owner: THIS_MODULE,
ioctl: efi_rtc_ioctl,
open: efi_rtc_open,
release: efi_rtc_close,
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 9238ae3eb214ce..13656af4bd7edd 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -4007,6 +4007,9 @@ static int __init epca_init_one (struct pci_dev *pdev,
int board_idx, info_idx = ent->driver_data;
unsigned long addr;
+ if (pci_enable_device(pdev))
+ return -EIO;
+
board_num++;
board_idx = board_num + num_cards;
if (board_idx >= MAXBOARDS)
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index dfe89b9707b641..01eb20e9202fb0 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -330,7 +330,7 @@ int gs_chars_in_buffer(struct tty_struct *tty)
int gs_real_chars_in_buffer(struct tty_struct *tty)
{
- struct gs_port *port = tty->driver_data;
+ struct gs_port *port;
func_enter ();
if (!tty) return 0;
diff --git a/drivers/char/hp600_keyb.c b/drivers/char/hp600_keyb.c
new file mode 100644
index 00000000000000..52f66ba5fbf54c
--- /dev/null
+++ b/drivers/char/hp600_keyb.c
@@ -0,0 +1,119 @@
+/*
+ * $Id: hp600_keyb.c,v 1.1 2000/06/10 21:45:30 yaegashi Exp $
+ * Copyright (C) 2000 YAEGASHI Takeshi
+ * HP600 keyboard scan routine and translate table
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include "scan_keyb.h"
+
+#define PCDR 0xa4000124
+#define PDDR 0xa4000126
+#define PEDR 0xa4000128
+#define PFDR 0xa400012a
+#define PGDR 0xa400012c
+#define PHDR 0xa400012e
+
+static const unsigned char hp690_japanese_table[]={
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x29, 0x70, 0x3a,
+ 0x3f, 0x3e, 0x40, 0x41, 0x42, 0x3d, 0x3c, 0x3b,
+
+ 0x00, 0x00, 0x00, 0x2c, 0x00, 0x1c, 0x28, 0x35,
+ 0x31, 0x30, 0x32, 0x33, 0x34, 0x2f, 0x2e, 0x2d,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x50,
+ 0x7b, 0x38, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf9, 0x73, 0x53, 0x39, 0x00, 0x1d,
+
+ 0x00, 0x00, 0x00, 0x1e, 0x00, 0x2b, 0x1b, 0x27,
+ 0x23, 0x22, 0x24, 0x25, 0x26, 0x21, 0x20, 0x1f,
+
+ 0x00, 0x00, 0x00, 0x0f, 0x00, 0x36, 0x7d, 0x48,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00,
+
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x1a, 0x19,
+ 0x15, 0x14, 0x16, 0x17, 0x18, 0x13, 0x12, 0x11,
+
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x0c, 0x0b,
+ 0x07, 0x06, 0x08, 0x09, 0x0a, 0x05, 0x04, 0x03,
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+
+static void hp690_japanese_scan_kbd(unsigned char *s)
+{
+ ctrl_outb(0xfd, PDDR); ctrl_outb(0xff, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ ctrl_outb(0xdf, PDDR); ctrl_outb(0xff, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ ctrl_outb(0x7f, PDDR); ctrl_outb(0xff, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ ctrl_outb(0xff, PDDR); ctrl_outb(0xfe, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ ctrl_outb(0xff, PDDR); ctrl_outb(0xfd, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ ctrl_outb(0xff, PDDR); ctrl_outb(0xf7, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ ctrl_outb(0xff, PDDR); ctrl_outb(0xbf, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ ctrl_outb(0xff, PDDR); ctrl_outb(0x7f, PEDR);
+ *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR);
+ *s++=ctrl_inb(PGDR); *s++=ctrl_inb(PHDR);
+}
+
+
+void __init hp600_kbd_init_hw(void)
+{
+ scan_kbd_init();
+ register_scan_keyboard(hp690_japanese_scan_kbd,
+ hp690_japanese_table, 18);
+ printk(KERN_INFO "HP600 matrix scan keyboard registered\n");
+}
+
+
+/****************************************************************
+HP Jornada 690(Japanese version) keyboard scan matrix
+
+ PTC7 PTC6 PTC5 PTC4 PTC3 PTC2 PTC1 PTC0
+PTD1 REC Escape on/off Han/Zen Hira Eisu
+PTD5 REC Z on/off Enter : /
+PTD7 REC Right Down
+PTE0 REC Windows on/off
+PTE1 REC A on/off ] [ ;
+PTE3 REC Tab on/off ShirtR \ Up
+PTE6 REC Q on/off BS @ P
+PTE7 REC 1 on/off ^ - 0
+
+
+ PTF7 PTF6 PTF5 PTF4 PTF3 PTF2 PTF1 PTF0
+PTD1 F5 F4 F6 F7 F8 F3 F2 F1
+PTD5 N B M , . V C X
+PTD7 Muhen Alt Left
+PTE0 Henkan _ Del Space Ctrl
+PTE1 H G J K L F D S
+PTE3 ShiftL
+PTE6 Y T U I O R E W
+PTE7 6 5 7 8 9 4 3 2
+
+ PTG5 PTG4 PTG3 PTG0 PTH0
+* REC REW FWW Cover on/off
+
+
+ 7 6 5 4 3 2 1 0
+C: 0xffff 0xdf IP IP IP IP IP IP IP IP
+D: 0x6786 0x59 O I O IP I F O I
+E: 0x5045 0x00 O O F F O F O O
+F: 0xffff 0xff IP IP IP IP IP IP IP IP
+G: 0xaffe 0xfd I I IP IP IP IP IP I
+H: 0x70f2 0x49 O IP F F IP IP F I
+J: 0x0704 0x22 F F O IP F F O F
+K: 0x0100 0x10 F F F O F F F F
+L: 0x0c3c 0x26 F F IP F F IP IP F
+
+****************************************************************/
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 6b42c7f63caccc..033eb9aafe7239 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -311,6 +311,7 @@ static struct termios * TermiosLocked[IP2_MAX_PORTS];
* download the loadware to the boards.
*/
static struct file_operations ip2_ipl = {
+ owner: THIS_MODULE,
read: ip2_ipl_read,
write: ip2_ipl_write,
ioctl: ip2_ipl_ioctl,
@@ -3202,8 +3203,6 @@ ip2_ipl_open( struct inode *pInode, struct file *pFile )
printk (KERN_DEBUG "IP2IPL: open\n" );
#endif
- //MOD_INC_USE_COUNT; // Needs close entry with decrement.
-
switch(iplminor) {
// These are the IPL devices
case 0:
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 958fbf77638274..52c6b5f1950ed0 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -86,8 +86,6 @@ static char re_schedule = 1;
static unsigned long tx_count = 0;
#endif
-static int ISILoad_open(struct inode *inode, struct file *filp);
-static int ISILoad_release(struct inode *inode, struct file *filp);
static int ISILoad_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
static void isicom_tx(unsigned long _data);
@@ -109,9 +107,8 @@ static signed char linuxb_to_isib[] = {
*/
static struct file_operations ISILoad_fops = {
+ owner: THIS_MODULE,
ioctl: ISILoad_ioctl,
- open: ISILoad_open,
- release: ISILoad_release,
};
struct miscdevice isiloader_device = {
@@ -129,24 +126,6 @@ extern inline int WaitTillCardIsFree(unsigned short base)
return 1;
}
-static int ISILoad_open(struct inode *inode, struct file *filp)
-{
-#ifdef ISICOM_DEBUG
- printk(KERN_DEBUG "ISILoad:Firmware loader Opened!!!\n");
-#endif
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int ISILoad_release(struct inode *inode, struct file *filp)
-{
-#ifdef ISICOM_DEBUG
- printk(KERN_DEBUG "ISILoad:Firmware loader Close(Release)d\n",);
-#endif
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
static int ISILoad_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 5733fac43c1757..8d16c9daf1adcc 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -687,8 +687,6 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p
static int stli_brdinit(stlibrd_t *brdp);
static int stli_startbrd(stlibrd_t *brdp);
-static int stli_memopen(struct inode *ip, struct file *fp);
-static int stli_memclose(struct inode *ip, struct file *fp);
static ssize_t stli_memread(struct file *fp, char *buf, size_t count, loff_t *offp);
static ssize_t stli_memwrite(struct file *fp, const char *buf, size_t count, loff_t *offp);
static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
@@ -780,11 +778,10 @@ static inline int stli_initpcibrd(int brdtype, struct pci_dev *devp);
* board. This is also a very useful debugging tool.
*/
static struct file_operations stli_fsiomem = {
+ owner: THIS_MODULE,
read: stli_memread,
write: stli_memwrite,
ioctl: stli_memioctl,
- open: stli_memopen,
- release: stli_memclose,
};
/*****************************************************************************/
@@ -5183,27 +5180,6 @@ static int stli_getbrdstruct(unsigned long arg)
/*****************************************************************************/
/*
- * Memory device open code. Need to keep track of opens and close
- * for module handling.
- */
-
-static int stli_memopen(struct inode *ip, struct file *fp)
-{
- MOD_INC_USE_COUNT;
- return(0);
-}
-
-/*****************************************************************************/
-
-static int stli_memclose(struct inode *ip, struct file *fp)
-{
- MOD_DEC_USE_COUNT;
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
* The "staliomem" device is also required to do some special operations on
* the board. We need to be able to send an interrupt to the board,
* reset it, and start/stop it.
diff --git a/drivers/char/joystick/joystick.c b/drivers/char/joystick/joystick.c
index 81ec240ba4c43e..c9bd56ce361dec 100644
--- a/drivers/char/joystick/joystick.c
+++ b/drivers/char/joystick/joystick.c
@@ -752,6 +752,7 @@ void js_unregister_device(struct js_dev *dev)
static struct file_operations js_fops =
{
+ owner: THIS_MODULE,
read: js_read,
poll: js_poll,
ioctl: js_ioctl,
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 90f0343966bc15..c2df7ea1858c0c 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -371,8 +371,6 @@ static int lp_open(struct inode * inode, struct file * file)
if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor)))
return -EBUSY;
- MOD_INC_USE_COUNT;
-
/* If ABORTOPEN is set and the printer is offline or out of paper,
we may still want to open it to perform ioctl()s. Therefore we
have commandeered O_NONBLOCK, even though it is being used in
@@ -385,24 +383,20 @@ static int lp_open(struct inode * inode, struct file * file)
parport_release (lp_table[minor].dev);
if (status & LP_POUTPA) {
printk(KERN_INFO "lp%d out of paper\n", minor);
- MOD_DEC_USE_COUNT;
LP_F(minor) &= ~LP_BUSY;
return -ENOSPC;
} else if (!(status & LP_PSELECD)) {
printk(KERN_INFO "lp%d off-line\n", minor);
- MOD_DEC_USE_COUNT;
LP_F(minor) &= ~LP_BUSY;
return -EIO;
} else if (!(status & LP_PERRORP)) {
printk(KERN_ERR "lp%d printer error\n", minor);
- MOD_DEC_USE_COUNT;
LP_F(minor) &= ~LP_BUSY;
return -EIO;
}
}
lp_table[minor].lp_buffer = (char *) kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
if (!lp_table[minor].lp_buffer) {
- MOD_DEC_USE_COUNT;
LP_F(minor) &= ~LP_BUSY;
return -ENOMEM;
}
@@ -415,7 +409,6 @@ static int lp_release(struct inode * inode, struct file * file)
kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE);
lp_table[minor].lp_buffer = NULL;
- MOD_DEC_USE_COUNT;
LP_F(minor) &= ~LP_BUSY;
return 0;
}
@@ -526,6 +519,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
}
static struct file_operations lp_fops = {
+ owner: THIS_MODULE,
write: lp_write,
ioctl: lp_ioctl,
open: lp_open,
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index ca084211855876..cecf896168d0cc 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -111,8 +111,7 @@ static int misc_open(struct inode * inode, struct file * file)
int minor = MINOR(inode->i_rdev);
struct miscdevice *c;
int err = -ENODEV;
-
- file->f_op = NULL;
+ struct file_operations *old_fops;
down(&misc_sem);
@@ -133,14 +132,22 @@ static int misc_open(struct inode * inode, struct file * file)
goto fail;
}
- if ((file->f_op = c->fops) && file->f_op->open)
+ old_fops = file->f_op;
+ file->f_op = fops_get(c->fops);
+ if (file->f_op && file->f_op->open)
err=file->f_op->open(inode,file);
+ if (err) {
+ fops_put(file->f_op);
+ file->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
fail:
up(&misc_sem);
return err;
}
static struct file_operations misc_fops = {
+ owner: THIS_MODULE,
open: misc_open,
};
diff --git a/drivers/char/mixcomwd.c b/drivers/char/mixcomwd.c
index 5894353e380ab7..6352d6f73e7665 100644
--- a/drivers/char/mixcomwd.c
+++ b/drivers/char/mixcomwd.c
@@ -94,8 +94,6 @@ static int mixcomwd_open(struct inode *inode, struct file *file)
mixcomwd_timer_alive=0;
}
#endif
- MOD_INC_USE_COUNT;
-
return 0;
}
@@ -114,7 +112,6 @@ static int mixcomwd_release(struct inode *inode, struct file *file)
mixcomwd_timer_alive=1;
add_timer(&mixcomwd_timer);
#endif
- MOD_DEC_USE_COUNT;
clear_bit(0,&mixcomwd_opened);
return 0;
@@ -171,6 +168,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
static struct file_operations mixcomwd_fops=
{
+ owner: THIS_MODULE,
write: mixcomwd_write,
ioctl: mixcomwd_ioctl,
open: mixcomwd_open,
diff --git a/drivers/char/msp3400.c b/drivers/char/msp3400.c
index f4252a07122cd6..d6fa8314bfc172 100644
--- a/drivers/char/msp3400.c
+++ b/drivers/char/msp3400.c
@@ -1,7 +1,7 @@
/*
* programming the msp34* sound processor family
*
- * (c) 1997,1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ * (c) 1997-2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
*
* what works and what doesn't:
*
@@ -46,6 +46,7 @@
#include <linux/i2c.h>
#include <linux/videodev.h>
#include <asm/semaphore.h>
+#include <linux/init.h>
#ifdef CONFIG_SMP
#include <asm/pgtable.h>
@@ -57,16 +58,14 @@
#include "audiochip.h"
-#define WAIT_QUEUE wait_queue_head_t
-
/* sound mixer stuff */
-#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
+#if 0 /* defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE) */
# define REGISTER_MIXER 1
#endif
/* Addresses to scan */
static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {0x40,0x44,I2C_CLIENT_END};
+static unsigned short normal_i2c_range[] = {0x40,0x40,I2C_CLIENT_END};
static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
@@ -102,7 +101,7 @@ struct msp3400c {
/* thread */
struct task_struct *thread;
- WAIT_QUEUE wq;
+ wait_queue_head_t wq;
struct semaphore *notify;
int active,restart,rmmod;
@@ -680,10 +679,10 @@ static int msp3400c_thread(void *data)
#endif
exit_mm(current);
+ exit_fs(current);
current->session = 1;
current->pgrp = 1;
sigfillset(&current->blocked);
- current->fs->umask = 0;
strcpy(current->comm,"msp3400");
msp->thread = current;
@@ -932,10 +931,10 @@ static int msp3410d_thread(void *data)
#endif
exit_mm(current);
+ exit_fs(current);
current->session = 1;
current->pgrp = 1;
sigfillset(&current->blocked);
- current->fs->umask = 0;
strcpy(current->comm,"msp3410 [auto]");
msp->thread = current;
@@ -1256,7 +1255,6 @@ msp3400c_mixer_open(struct inode *inode, struct file *file)
if (client->adapter->inc_use)
client->adapter->inc_use(client->adapter);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1267,7 +1265,6 @@ msp3400c_mixer_release(struct inode *inode, struct file *file)
if (client->adapter->dec_use)
client->adapter->dec_use(client->adapter);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1278,6 +1275,7 @@ msp3400c_mixer_llseek(struct file *file, loff_t offset, int origin)
}
static struct file_operations msp3400c_mixer_fops = {
+ owner: THIS_MODULE,
llseek: msp3400c_mixer_llseek,
ioctl: msp3400c_mixer_ioctl,
open: msp3400c_mixer_open,
@@ -1370,7 +1368,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr,
if (simple == -1) {
/* default mode */
- msp->simple = 0;
+ msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1;
} else {
/* use insmod option */
msp->simple = simple;
@@ -1632,22 +1630,19 @@ static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
/* ----------------------------------------------------------------------- */
-#ifdef MODULE
-int init_module(void)
-#else
-int msp3400c_init(void)
-#endif
+int msp3400_init_module(void)
{
i2c_add_driver(&driver);
return 0;
}
-#ifdef MODULE
-void cleanup_module(void)
+void msp3400_cleanup_module(void)
{
i2c_del_driver(&driver);
}
-#endif
+
+module_init(msp3400_init_module);
+module_exit(msp3400_cleanup_module);
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index c5be675c72ce52..42063cefaa988a 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -332,7 +332,6 @@ static int nvram_open( struct inode *inode, struct file *file )
if (file->f_mode & 2)
nvram_open_mode |= NVRAM_WRITE;
nvram_open_cnt++;
- MOD_INC_USE_COUNT;
return( 0 );
}
@@ -344,7 +343,6 @@ static int nvram_release( struct inode *inode, struct file *file )
if (file->f_mode & 2)
nvram_open_mode &= ~NVRAM_WRITE;
- MOD_DEC_USE_COUNT;
return( 0 );
}
@@ -393,6 +391,7 @@ static int nvram_read_proc( char *buffer, char **start, off_t offset,
#endif /* CONFIG_PROC_FS */
static struct file_operations nvram_fops = {
+ owner: THIS_MODULE,
llseek: nvram_llseek,
read: nvram_read,
write: nvram_write,
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 34d99658283800..8cf8a15a7cd33c 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -172,34 +172,6 @@ static int button_read (struct file *filp, char *buffer,
? -EFAULT : bcount;
}
-/*
- * This function is called when a user space process attempts to open the
- * device. If the driver is compiled into the kernel it does nothing but
- * succeed, but if it is compiled in as a module it also increments the
- * module usage count to prevent the module from being removed whilst a
- * process has the device open.
- */
-
-static int button_open (struct inode *inode, struct file *filp)
-{
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * This function is called when a user space process attempts to close the
- * device. If the driver is compiled into the kernel it does nothing at all,
- * but if it is compiled in as a module it also decrements the module usage
- * count so that it will be possible to unload the module again once all the
- * user processes have closed the device.
- */
-
-static int button_release (struct inode *inode, struct file *filp)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
/*
* This structure is the file operations structure, which specifies what
* callbacks functions the kernel should call when a user mode process
@@ -207,9 +179,8 @@ static int button_release (struct inode *inode, struct file *filp)
*/
static struct file_operations button_fops = {
+ owner: THIS_MODULE,
read: button_read,
- open: button_open,
- release: button_release,
};
/*
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index 579e970d4a1fec..5be07b7696a160 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -39,7 +39,6 @@ MSTATIC int get_flash_id(void);
MSTATIC int erase_block(int nBlock);
MSTATIC int write_block(unsigned long p, const char *buf, int count);
static int open_flash(struct inode *inodep, struct file *filep);
-static int release_flash(struct inode *inodep, struct file *filep);
static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg);
static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos);
static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos);
@@ -60,12 +59,12 @@ extern spinlock_t gpio_lock;
static struct file_operations flash_fops =
{
+ owner: THIS_MODULE,
llseek: flash_llseek,
read: flash_read,
write: flash_write,
ioctl: flash_ioctl,
open: open_flash,
- release: release_flash,
};
static struct miscdevice flash_miscdev =
@@ -128,19 +127,10 @@ static int open_flash(struct inode *inodep, struct file *filep)
printk("Flash: incorrect ID 0x%04X.\n", id);
return -ENXIO;
}
- MOD_INC_USE_COUNT;
return 0;
}
-
-static int release_flash(struct inode *inodep, struct file *filep)
-{
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-
static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg)
{
// printk("Flash_ioctl: cmd = 0x%X.\n",cmd);
diff --git a/drivers/char/pc110pad.c b/drivers/char/pc110pad.c
index e0b6205969c052..b2370ed7154b63 100644
--- a/drivers/char/pc110pad.c
+++ b/drivers/char/pc110pad.c
@@ -588,7 +588,6 @@ static int close_pad(struct inode * inode, struct file * file)
if (--active)
return 0;
outb(0x30, current_params.io+2); /* switch off digitiser */
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -610,7 +609,6 @@ static int open_pad(struct inode * inode, struct file * file)
if (active++)
return 0;
- MOD_INC_USE_COUNT;
save_flags(flags);
cli();
@@ -772,6 +770,7 @@ static int pad_ioctl(struct inode *inode, struct file * file,
static struct file_operations pad_fops = {
+ owner: THIS_MODULE,
read: read_pad,
write: write_pad,
poll: pad_poll,
diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c
index 8226b50309f94f..f215b9dd3ef535 100644
--- a/drivers/char/pc_keyb.c
+++ b/drivers/char/pc_keyb.c
@@ -452,7 +452,9 @@ static unsigned char handle_kbd_event(void)
scancode = kbd_read_input();
-#if 0
+ /* Error bytes must be ignored to make the
+ Synaptics touchpads compaq use work */
+#if 1
/* Ignore error bytes */
if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
#endif
diff --git a/drivers/char/pcwd.c b/drivers/char/pcwd.c
index 2e2d391fa1d34f..b85a168de36b96 100644
--- a/drivers/char/pcwd.c
+++ b/drivers/char/pcwd.c
@@ -414,7 +414,6 @@ static int pcwd_open(struct inode *ino, struct file *filep)
is_open = 1;
return(0);
case TEMP_MINOR:
- MOD_INC_USE_COUNT;
return(0);
default:
return (-ENODEV);
@@ -450,7 +449,6 @@ static ssize_t pcwd_read(struct file *file, char *buf, size_t count,
static int pcwd_close(struct inode *ino, struct file *filep)
{
- MOD_DEC_USE_COUNT;
if (MINOR(ino->i_rdev)==WATCHDOG_MINOR)
{
is_open = 0;
@@ -543,6 +541,7 @@ static void debug_off(void)
}
static struct file_operations pcwd_fops = {
+ owner: THIS_MODULE,
read: pcwd_read,
write: pcwd_write,
ioctl: pcwd_ioctl,
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 19224560203661..819ed0b1a8bda8 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -639,6 +639,7 @@ static unsigned int pp_poll (struct file * file, poll_table * wait)
}
static struct file_operations pp_fops = {
+ owner: THIS_MODULE,
llseek: pp_lseek,
read: pp_read,
write: pp_write,
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 625f7022bea0a9..01865a09d3fe0f 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -201,8 +201,6 @@ static void rio_close (void *ptr);
static int rio_chars_in_buffer (void * ptr);
static int rio_fw_ioctl (struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-static int rio_fw_open(struct inode *inode, struct file *filp);
-static INT rio_fw_release(struct inode *inode, struct file *filp);
static int rio_init_drivers(void);
@@ -277,9 +275,8 @@ static struct real_driver rio_real_driver = {
*/
static struct file_operations rio_fw_fops = {
+ owner: THIS_MODULE,
ioctl: rio_fw_ioctl,
- open: rio_fw_open,
- release: rio_fw_release,
};
struct miscdevice rio_fw_device = {
@@ -634,32 +631,6 @@ static void rio_shutdown_port (void * ptr)
func_exit();
}
-
-
-/* ********************************************************************** *
- * Here are the routines that actually *
- * interface with the rest of the system *
- * ********************************************************************** */
-
-
-static int rio_fw_open(struct inode *inode, struct file *filp)
-{
- func_enter ();
- rio_inc_mod_count ();
- func_exit ();
- return 0;
-}
-
-
-static INT rio_fw_release(struct inode *inode, struct file *filp)
-{
- func_enter ();
- rio_dec_mod_count ();
- func_exit ();
- return NO_ERROR;
-}
-
-
/* I haven't the foggiest why the decrement use count has to happen
here. The whole linux serial drivers stuff needs to be redesigned.
My guess is that this is a hack to minimize the impact of a bug
@@ -1149,6 +1120,7 @@ int rio_init(void)
while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
pdev))) {
+ if (pci_enable_device(pdev)) continue;
#else
for (i=0;i< RIO_NBOARDS;i++) {
if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
@@ -1234,6 +1206,7 @@ int rio_init(void)
while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_RIO,
pdev))) {
+ if (pci_enable_device(pdev)) continue;
#else
for (i=0;i< RIO_NBOARDS;i++) {
if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX,
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index d62e02017ac78f..4aca69903185b8 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -514,8 +514,6 @@ static int rtc_open(struct inode *inode, struct file *file)
if(rtc_status & RTC_IS_OPEN)
return -EBUSY;
- MOD_INC_USE_COUNT;
-
rtc_status |= RTC_IS_OPEN;
spin_lock_irq (&rtc_lock);
@@ -559,7 +557,6 @@ static int rtc_release(struct inode *inode, struct file *file)
}
#endif
- MOD_DEC_USE_COUNT;
spin_lock_irq (&rtc_lock);
rtc_irq_data = 0;
@@ -591,6 +588,7 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait)
*/
static struct file_operations rtc_fops = {
+ owner: THIS_MODULE,
llseek: rtc_llseek,
read: rtc_read,
#ifndef __alpha__
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 1898849d865ccb..fdaeeaea063e9f 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -511,8 +511,6 @@ static void stl_breakctl(struct tty_struct *tty, int state);
static void stl_waituntilsent(struct tty_struct *tty, int timeout);
static void stl_sendxchar(struct tty_struct *tty, char ch);
static void stl_hangup(struct tty_struct *tty);
-static int stl_memopen(struct inode *ip, struct file *fp);
-static int stl_memclose(struct inode *ip, struct file *fp);
static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
static int stl_portinfo(stlport_t *portp, int portnr, char *pos);
static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data);
@@ -744,9 +742,8 @@ static unsigned int sc26198_baudtable[] = {
* to get at port stats - only not using the port device itself.
*/
static struct file_operations stl_fsiomem = {
+ owner: THIS_MODULE,
ioctl: stl_memioctl,
- open: stl_memopen,
- release: stl_memclose,
};
/*****************************************************************************/
@@ -2795,8 +2792,8 @@ static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
*/
#if DEBUG
printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__,
- devp->resource[0].start, devp->resource[1].start,
- devp->resource[2].start, devp->resource[3].start, devp->irq);
+ pci_resource_start(devp, 0), pci_resource_start(devp, 1),
+ pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq);
#endif
/*
@@ -2805,22 +2802,16 @@ static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp)
*/
switch (brdtype) {
case BRD_ECHPCI:
- brdp->ioaddr2 = (devp->resource[0].start &
- PCI_BASE_ADDRESS_IO_MASK);
- brdp->ioaddr1 = (devp->resource[1].start &
- PCI_BASE_ADDRESS_IO_MASK);
+ brdp->ioaddr2 = pci_resource_start(devp, 0);
+ brdp->ioaddr1 = pci_resource_start(devp, 1);
break;
case BRD_ECH64PCI:
- brdp->ioaddr2 = (devp->resource[2].start &
- PCI_BASE_ADDRESS_IO_MASK);
- brdp->ioaddr1 = (devp->resource[1].start &
- PCI_BASE_ADDRESS_IO_MASK);
+ brdp->ioaddr2 = pci_resource_start(devp, 2);
+ brdp->ioaddr1 = pci_resource_start(devp, 1);
break;
case BRD_EASYIOPCI:
- brdp->ioaddr1 = (devp->resource[2].start &
- PCI_BASE_ADDRESS_IO_MASK);
- brdp->ioaddr2 = (devp->resource[1].start &
- PCI_BASE_ADDRESS_IO_MASK);
+ brdp->ioaddr1 = pci_resource_start(devp, 2);
+ brdp->ioaddr2 = pci_resource_start(devp, 1);
break;
default:
printk("STALLION: unknown PCI board type=%d\n", brdtype);
@@ -3123,27 +3114,6 @@ static int stl_getbrdstruct(unsigned long arg)
/*****************************************************************************/
/*
- * Memory device open code. Need to keep track of opens and close
- * for module handling.
- */
-
-static int stl_memopen(struct inode *ip, struct file *fp)
-{
- MOD_INC_USE_COUNT;
- return(0);
-}
-
-/*****************************************************************************/
-
-static int stl_memclose(struct inode *ip, struct file *fp)
-{
- MOD_DEC_USE_COUNT;
- return(0);
-}
-
-/*****************************************************************************/
-
-/*
* The "staliomem" device is also required to do some special operations
* on the board and/or ports. In this driver it is mostly used for stats
* collection.
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 15a24851f8f6d1..82e3cae1ec4d43 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -304,8 +304,6 @@ static int sx_init_board (struct sx_board *board);
static int sx_init_portstructs (int nboards, int nports);
static int sx_fw_ioctl (struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
-static int sx_fw_open(struct inode *inode, struct file *filp);
-static INT sx_fw_release(struct inode *inode, struct file *filp);
static int sx_init_drivers(void);
@@ -419,9 +417,8 @@ static struct real_driver sx_real_driver = {
*/
static struct file_operations sx_fw_fops = {
+ owner: THIS_MODULE,
ioctl: sx_fw_ioctl,
- open: sx_fw_open,
- release: sx_fw_release,
};
struct miscdevice sx_fw_device = {
@@ -1418,25 +1415,6 @@ static void sx_shutdown_port (void * ptr)
* interface with the rest of the system *
* ********************************************************************** */
-
-static int sx_fw_open(struct inode *inode, struct file *filp)
-{
- func_enter ();
- MOD_INC_USE_COUNT;
- func_exit ();
- return 0;
-}
-
-
-static INT sx_fw_release(struct inode *inode, struct file *filp)
-{
- func_enter ();
- MOD_DEC_USE_COUNT;
- func_exit ();
- return NO_ERROR;
-}
-
-
static int sx_open (struct tty_struct * tty, struct file * filp)
{
struct sx_port *port;
diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c
index d29c634079836a..133f19aac06014 100644
--- a/drivers/char/tpqic02.c
+++ b/drivers/char/tpqic02.c
@@ -2177,10 +2177,6 @@ static int qic02_tape_open(struct inode * inode, struct file * filp)
int open_error;
open_error = qic02_tape_open_no_use_count(inode, filp);
- if (!open_error)
- {
- MOD_INC_USE_COUNT;
- }
return open_error;
}
@@ -2440,9 +2436,6 @@ static int qic02_tape_release(struct inode * inode, struct file * filp)
(void) do_qic_cmd(QCMD_REWIND, TIM_R);
}
}
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
return 0;
} /* qic02_tape_release */
@@ -2766,6 +2759,7 @@ static int qic02_tape_ioctl(struct inode * inode, struct file * filp,
/* These are (most) of the interface functions: */
static struct file_operations qic02_tape_fops = {
+ owner: THIS_MODULE,
llseek: qic02_tape_lseek, /* not allowed */
read: qic02_tape_read,
write: qic02_tape_write,
diff --git a/drivers/char/tuner.c b/drivers/char/tuner.c
index 0ed55b715399a6..81e19a4abda713 100644
--- a/drivers/char/tuner.c
+++ b/drivers/char/tuner.c
@@ -10,6 +10,7 @@
#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/videodev.h>
+#include <linux/init.h>
#include "tuner.h"
#include "audiochip.h"
@@ -428,22 +429,19 @@ static struct i2c_client client_template =
EXPORT_NO_SYMBOLS;
-#ifdef MODULE
-int init_module(void)
-#else
-int i2c_tuner_init(void)
-#endif
+int tuner_init_module(void)
{
i2c_add_driver(&driver);
return 0;
}
-#ifdef MODULE
-void cleanup_module(void)
+void tuner_cleanup_module(void)
{
i2c_del_driver(&driver);
}
-#endif
+
+module_init(tuner_init_module);
+module_exit(tuner_cleanup_module);
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/char/tvmixer.c b/drivers/char/tvmixer.c
new file mode 100644
index 00000000000000..0ef5bbd0300f3c
--- /dev/null
+++ b/drivers/char/tvmixer.c
@@ -0,0 +1,351 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/malloc.h>
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <asm/semaphore.h>
+#include <linux/init.h>
+
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+#include <asm/uaccess.h>
+
+#include "audiochip.h"
+
+#define DEV_MAX 4
+
+static int debug = 0;
+static int devnr = -1;
+
+MODULE_PARM(debug,"i");
+MODULE_PARM(devnr,"i");
+
+/* ----------------------------------------------------------------------- */
+
+struct TVMIXER {
+ struct i2c_client *dev;
+ int minor;
+ int count;
+};
+
+static struct TVMIXER devices[DEV_MAX];
+
+static int tvmixer_adapters(struct i2c_adapter *adap);
+static int tvmixer_clients(struct i2c_client *client);
+
+static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+static int tvmixer_open(struct inode *inode, struct file *file);
+static int tvmixer_release(struct inode *inode, struct file *file);
+static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin);
+
+
+static struct i2c_driver driver = {
+ "tv card mixer driver",
+ 42 /* I2C_DRIVERID_FIXME */,
+ I2C_DF_DUMMY,
+ tvmixer_adapters,
+ tvmixer_clients,
+};
+
+static struct file_operations tvmixer_fops = {
+ owner: THIS_MODULE,
+ llseek: tvmixer_llseek,
+ ioctl: tvmixer_ioctl,
+ open: tvmixer_open,
+ release: tvmixer_release,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int mix_to_v4l(int i)
+{
+ int r;
+
+ r = ((i & 0xff) * 65536 + 50) / 100;
+ if (r > 65535) r = 65535;
+ if (r < 0) r = 0;
+ return r;
+}
+
+static int v4l_to_mix(int i)
+{
+ int r;
+
+ r = (i * 100 + 32768) / 65536;
+ if (r > 100) r = 100;
+ if (r < 0) r = 0;
+ return r | (r << 8);
+}
+
+static int v4l_to_mix2(int l, int r)
+{
+ r = (r * 100 + 32768) / 65536;
+ if (r > 100) r = 100;
+ if (r < 0) r = 0;
+ l = (l * 100 + 32768) / 65536;
+ if (l > 100) l = 100;
+ if (l < 0) l = 0;
+ return (r << 8) | l;
+}
+
+static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct video_audio va;
+ int left,right,ret,val = 0;
+ struct TVMIXER *mix = file->private_data;
+ struct i2c_client *client = mix->dev;
+
+ if (NULL == client)
+ return -ENODEV;
+
+ if (cmd == SOUND_MIXER_INFO) {
+ mixer_info info;
+ strncpy(info.id, "tv card", sizeof(info.id));
+ strncpy(info.name, client->name, sizeof(info.name));
+ info.modify_counter = 42 /* FIXME */;
+ if (copy_to_user((void *)arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == SOUND_OLD_MIXER_INFO) {
+ _old_mixer_info info;
+ strncpy(info.id, "tv card", sizeof(info.id));
+ strncpy(info.name, client->name, sizeof(info.name));
+ if (copy_to_user((void *)arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == OSS_GETVERSION)
+ return put_user(SOUND_VERSION, (int *)arg);
+
+ if (_SIOC_DIR(cmd) & _SIOC_WRITE)
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+
+ /* read state */
+ memset(&va,0,sizeof(va));
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+
+ switch (cmd) {
+ case MIXER_READ(SOUND_MIXER_RECMASK):
+ case MIXER_READ(SOUND_MIXER_CAPS):
+ case MIXER_READ(SOUND_MIXER_RECSRC):
+ case MIXER_WRITE(SOUND_MIXER_RECSRC):
+ ret = 0;
+ break;
+
+ case MIXER_READ(SOUND_MIXER_STEREODEVS):
+ ret = SOUND_MASK_VOLUME;
+ break;
+ case MIXER_READ(SOUND_MIXER_DEVMASK):
+ ret = SOUND_MASK_VOLUME;
+ if (va.flags & VIDEO_AUDIO_BASS)
+ ret |= SOUND_MASK_BASS;
+ if (va.flags & VIDEO_AUDIO_TREBLE)
+ ret |= SOUND_MASK_TREBLE;
+ break;
+
+ case MIXER_WRITE(SOUND_MIXER_VOLUME):
+ left = mix_to_v4l(val);
+ right = mix_to_v4l(val >> 8);
+ va.volume = MAX(left,right);
+ va.balance = (32768*MIN(left,right)) / (va.volume ? va.volume : 1);
+ va.balance = (left<right) ? (65535-va.balance) : va.balance;
+ client->driver->command(client,VIDIOCSAUDIO,&va);
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+ /* fall throuth */
+ case MIXER_READ(SOUND_MIXER_VOLUME):
+ left = (MIN(65536 - va.balance,32768) *
+ va.volume) / 32768;
+ right = (MIN(va.balance,32768) *
+ va.volume) / 32768;
+ ret = v4l_to_mix2(left,right);
+ break;
+
+ case MIXER_WRITE(SOUND_MIXER_BASS):
+ va.bass = mix_to_v4l(val);
+ client->driver->command(client,VIDIOCSAUDIO,&va);
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+ /* fall throuth */
+ case MIXER_READ(SOUND_MIXER_BASS):
+ ret = v4l_to_mix(va.bass);
+ break;
+
+ case MIXER_WRITE(SOUND_MIXER_TREBLE):
+ va.treble = mix_to_v4l(val);
+ client->driver->command(client,VIDIOCSAUDIO,&va);
+ client->driver->command(client,VIDIOCGAUDIO,&va);
+ /* fall throuth */
+ case MIXER_READ(SOUND_MIXER_TREBLE):
+ ret = v4l_to_mix(va.treble);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ if (put_user(ret, (int *)arg))
+ return -EFAULT;
+ return 0;
+}
+
+static int tvmixer_open(struct inode *inode, struct file *file)
+{
+ int i, minor = MINOR(inode->i_rdev);
+ struct TVMIXER *mix = NULL;
+ struct i2c_client *client = NULL;
+
+ for (i = 0; i < DEV_MAX; i++) {
+ if (devices[i].minor == minor) {
+ mix = devices+i;
+ client = mix->dev;
+ break;
+ }
+ }
+
+ if (NULL == client)
+ return -ENODEV;
+
+ /* lock bttv in memory while the mixer is in use */
+ file->private_data = mix;
+ if (client->adapter->inc_use)
+ client->adapter->inc_use(client->adapter);
+ return 0;
+}
+
+static int tvmixer_release(struct inode *inode, struct file *file)
+{
+ struct TVMIXER *mix = file->private_data;
+ struct i2c_client *client = mix->dev;
+
+ if (NULL == client)
+ return -ENODEV;
+
+ if (client->adapter->dec_use)
+ client->adapter->dec_use(client->adapter);
+ return 0;
+}
+
+static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int tvmixer_adapters(struct i2c_adapter *adap)
+{
+ return 0;
+}
+
+static int tvmixer_clients(struct i2c_client *client)
+{
+ struct video_audio va;
+ int i,minor;
+
+ /* TV card ??? */
+ if (client->adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848)) {
+ if (debug)
+ printk("tvmixer: %s is not a tv card\n",
+ client->adapter->name);
+ return -1;
+ }
+ printk("tvmixer: debug: %s\n",client->name);
+
+ /* unregister ?? */
+ for (i = 0; i < DEV_MAX; i++) {
+ if (devices[i].dev == client) {
+ /* unregister */
+ unregister_sound_mixer(devices[i].minor);
+ devices[i].dev = NULL;
+ devices[i].minor = -1;
+ printk("tvmixer: %s unregistered (#1)\n",client->name);
+ return 0;
+ }
+ }
+
+ /* look for a free slot */
+ for (i = 0; i < DEV_MAX; i++)
+ if (NULL == devices[i].dev)
+ break;
+ if (i == DEV_MAX) {
+ printk(KERN_WARNING "tvmixer: DEV_MAX too small\n");
+ return -1;
+ }
+
+ /* audio chip with mixer ??? */
+ if (NULL == client->driver->command) {
+ if (debug)
+ printk("tvmixer: %s: driver->command is NULL\n",
+ client->driver->name);
+ return -1;
+ }
+ memset(&va,0,sizeof(va));
+ if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) {
+ if (debug)
+ printk("tvmixer: %s: VIDIOCGAUDIO failed\n",
+ client->name);
+ return -1;
+ }
+ if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) {
+ if (debug)
+ printk("tvmixer: %s: has no volume control\n",
+ client->name);
+ return -1;
+ }
+
+ /* everything is fine, register */
+ if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) {
+ printk(KERN_ERR "tvmixer: cannot allocate mixer device\n");
+ return -1;
+ }
+
+ devices[i].minor = minor;
+ devices[i].count = 0;
+ devices[i].dev = client;
+ printk("tvmixer: %s (%s) registered with minor %d\n",
+ client->name,client->adapter->name,minor);
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+int tvmixer_init_module(void)
+{
+ int i;
+
+ for (i = 0; i < DEV_MAX; i++)
+ devices[i].minor = -1;
+ i2c_add_driver(&driver);
+ return 0;
+}
+
+void tvmixer_cleanup_module(void)
+{
+ int i;
+
+ i2c_del_driver(&driver);
+ for (i = 0; i < DEV_MAX; i++) {
+ if (devices[i].minor != -1) {
+ unregister_sound_mixer(devices[i].minor);
+ printk("tvmixer: %s unregistered (#2)\n",
+ devices[i].dev->name);
+ }
+ }
+}
+
+module_init(tvmixer_init_module);
+module_exit(tvmixer_cleanup_module);
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c
index 0ce42945d0e42b..3ac86bf3ae5075 100644
--- a/drivers/char/wdt.c
+++ b/drivers/char/wdt.c
@@ -337,7 +337,6 @@ static int wdt_open(struct inode *inode, struct file *file)
case WATCHDOG_MINOR:
if(wdt_is_open)
return -EBUSY;
- MOD_INC_USE_COUNT;
/*
* Activate
*/
@@ -353,7 +352,6 @@ static int wdt_open(struct inode *inode, struct file *file)
outb_p(0, WDT_DC); /* Enable */
return 0;
case TEMP_MINOR:
- MOD_INC_USE_COUNT;
return 0;
default:
return -ENODEV;
@@ -382,7 +380,6 @@ static int wdt_release(struct inode *inode, struct file *file)
#endif
wdt_is_open=0;
}
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -416,6 +413,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
static struct file_operations wdt_fops = {
+ owner: THIS_MODULE,
llseek: wdt_llseek,
read: wdt_read,
write: wdt_write,
diff --git a/drivers/char/wdt_pci.c b/drivers/char/wdt_pci.c
index 6e99a72ac04cf5..2bd09930a14a2c 100644
--- a/drivers/char/wdt_pci.c
+++ b/drivers/char/wdt_pci.c
@@ -28,6 +28,7 @@
* Parameterized timeout
* JP Nollmann : Added support for PCI wdt501p
* Alan Cox : Split ISA and PCI cards into two drivers
+ * Jeff Garzik : PCI cleanups
*/
#include <linux/config.h>
@@ -53,6 +54,8 @@
#include <linux/pci.h>
+#define PFX "wdt_pci: "
+
/*
* Until Access I/O gets their application for a PCI vendor ID approved,
* I don't think that it's appropriate to move these constants into the
@@ -487,12 +490,86 @@ static struct notifier_block wdtpci_notifier=
0
};
-#ifdef MODULE
-#define wdtpci_init init_module
+static int __init wdtpci_init_one (struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ static int dev_count = 0;
+
+ dev_count++;
+ if (dev_count > 1) {
+ printk (KERN_ERR PFX
+ "this driver only supports 1 device\n");
+ return -ENODEV;
+ }
+
+ irq = dev->irq;
+ io = pci_resource_start (dev, 2);
+ printk ("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X "
+ "(Interrupt %d)\n", io, irq);
+
+ if (pci_enable_device (dev))
+ goto err_out;
+
+ if (request_region (io, 16, "wdt-pci") == NULL) {
+ printk (KERN_ERR PFX "I/O %d is not free.\n", io);
+ goto err_out;
+ }
+
+ if (request_irq (irq, wdtpci_interrupt, SA_INTERRUPT | SA_SHIRQ,
+ "wdt-pci", &wdtpci_miscdev)) {
+ printk (KERN_ERR PFX "IRQ %d is not free.\n", irq);
+ goto err_out_free_res;
+ }
+
+ misc_register (&wdtpci_miscdev);
+
+#ifdef CONFIG_WDT_501
+ misc_register (&temp_miscdev);
+#endif
+
+ register_reboot_notifier (&wdtpci_notifier);
+
+ return 0;
+
+err_out_free_res:
+ release_region (io, 16);
+err_out:
+ return -EIO;
+}
+
+
+static void __exit wdtpci_remove_one (struct pci_dev *pdev)
+{
+ /* here we assume only one device will ever have
+ * been picked up and registered by probe function */
+ unregister_reboot_notifier(&wdtpci_notifier);
+#ifdef CONFIG_WDT_501_PCI
+ misc_deregister(&temp_miscdev);
+#endif
+ misc_deregister(&wdtpci_miscdev);
+ free_irq(irq, &wdtpci_miscdev);
+ release_region(io, 16);
+}
+
+
+static struct pci_device_id wdtpci_pci_tbl[] __initdata = {
+ { PCI_VENDOR_ID_ACCESSIO, PCI_DEVICE_ID_WDG_CSM, PCI_ANY_ID, PCI_ANY_ID, },
+ { 0, }, /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
+
+
+static struct pci_driver wdtpci_driver = {
+ name: "wdt-pci",
+ id_table: wdtpci_pci_tbl,
+ probe: wdtpci_init_one,
+ remove: wdtpci_remove_one,
+};
+
/**
- * cleanup_module:
+ * wdtpci_cleanup:
*
* Unload the watchdog. You cannot do this with any file handles open.
* If your watchdog is set to continue ticking on close and you unload
@@ -501,18 +578,11 @@ static struct notifier_block wdtpci_notifier=
* module in 60 seconds or reboot.
*/
-void cleanup_module(void)
+static void __exit wdtpci_cleanup(void)
{
- misc_deregister(&wdtpci_miscdev);
-#ifdef CONFIG_WDT_501_PCI
- misc_deregister(&temp_miscdev);
-#endif
- unregister_reboot_notifier(&wdtpci_notifier);
- release_region(io,16);
- free_irq(irq, &wdtpci_miscdev);
+ pci_unregister_driver (&wdtpci_driver);
}
-#endif
/**
* wdtpci_init:
@@ -522,37 +592,16 @@ void cleanup_module(void)
* The open() function will actually kick the board off.
*/
-int __init wdtpci_init(void)
+static int __init wdtpci_init(void)
{
- struct pci_dev *dev = NULL;
-
- if (pci_present())
- {
- while ((dev = pci_find_device(PCI_VENDOR_ID_ACCESSIO,
- PCI_DEVICE_ID_WDG_CSM, dev))) {
- /* See if we can do this device */
- irq = dev->irq;
- io = dev->resource[2].start;
- printk("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X "
- "(Interrupt %d)\n", io, irq);
- }
- }
- if(request_region(io, 16, "wdt-pci")==NULL)
- {
- printk(KERN_ERR "I/O %d is not free.\n", io);
- return -EIO;
- }
- if(request_irq(irq, wdtpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "wdt-pci", &wdtpci_miscdev))
- {
- printk(KERN_ERR "IRQ %d is not free.\n", irq);
- release_region(io, 16);
- return -EIO;
- }
- misc_register(&wdtpci_miscdev);
-#ifdef CONFIG_WDT_501
- misc_register(&temp_miscdev);
-#endif
- register_reboot_notifier(&wdtpci_notifier);
+ int rc = pci_register_driver (&wdtpci_driver);
+
+ if (rc < 1)
+ return -ENODEV;
+
return 0;
}
+
+module_init(wdtpci_init);
+module_exit(wdtpci_cleanup);
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 75b3153b7ad150..2f3d2fc3a83d09 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/ide/aec62xx.c Version 0.08 Mar. 28, 2000
+ * linux/drivers/ide/aec62xx.c Version 0.09 June. 9, 2000
*
- * Copyright (C) 2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1999-2000 Andre Hedrick (andre@linux-ide.org)
* May be copied or modified under the terms of the GNU General Public License
*
*/
@@ -55,7 +55,7 @@ static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
- u32 bibma = bmide_dev->resource[4].start;
+ u32 bibma = pci_resource_start(bmide_dev, 4);
u8 c0 = 0, c1 = 0;
u8 art = 0, uart = 0;
@@ -358,7 +358,7 @@ static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra)
byte unit = (drive->select.b.unit & 0x01);
unsigned long dma_base = hwif->dma_base;
byte speed = -1;
- byte ultra66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
+ byte ultra66 = eighty_ninty_three(drive);
if (drive->media != ide_disk)
return ((int) ide_dma_off_quietly);
@@ -497,6 +497,23 @@ int aec62xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
+ case ide_dma_lostirq:
+ case ide_dma_timeout:
+ switch(HWIF(drive)->pci_dev->device) {
+ case PCI_DEVICE_ID_ARTOP_ATP860:
+ case PCI_DEVICE_ID_ARTOP_ATP860R:
+// {
+// int i = 0;
+// byte reg49h = 0;
+// pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, &reg49h);
+// for (i=0;i<256;i++)
+// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10);
+// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10);
+// }
+// return 0;
+ default:
+ break;
+ }
default:
break;
}
@@ -529,9 +546,6 @@ unsigned int __init ata66_aec62xx (ide_hwif_t *hwif)
byte ata66 = 0;
pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
-#if 1
- printk("AEC6260: reg49h=0x%02x ATA-%s Cable Port%d\n", ata66, (ata66 & mask) ? "33" : "66", hwif->channel);
-#endif
return ((ata66 & mask) ? 0 : 1);
}
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 02af0a0f801a10..41768bb908863f 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -1,17 +1,15 @@
/*
- * linux/drivers/ide/alim15x3.c Version 0.09 Mar. 18, 2000
+ * linux/drivers/ide/alim15x3.c Version 0.10 Jun. 9, 2000
*
* Copyright (C) 1998-2000 Michel Aubry, Maintainer
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
+ * Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer
*
- * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org)
* May be copied or modified under the terms of the GNU General Public License
*
* (U)DMA capable version of ali 1533/1543(C), 1535(D)
*
- * version: 1.0 beta2 (Sep. 2, 1999)
- * e-mail your problems to cjtsai@ali.com.tw
- *
**********************************************************************
* 9/7/99 --Parts from the above author are included and need to be
* converted into standard interface, once I finish the thought.
@@ -237,7 +235,6 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
static byte m5229_revision = 0;
static byte chip_is_1543c_e = 0;
-static byte cable_80_pin[2] = { 0, 0 };
byte ali_proc = 0;
static struct pci_dev *isa_dev;
@@ -346,7 +343,7 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, byte speed)
/*
* enable ultra dma and set timing
*/
- tmpbyte |= ((0x08 | (4-speed)) << (unit << 2));
+ tmpbyte |= ((0x08 | ((4-speed)&0x07)) << (unit << 2));
pci_write_config_byte(dev, m5229_udma, tmpbyte);
if (speed >= XFER_UDMA_3) {
pci_read_config_byte(dev, 0x4b, &tmpbyte);
@@ -370,12 +367,14 @@ static void config_chipset_for_pio (ide_drive_t *drive)
static int config_chipset_for_dma (ide_drive_t *drive, byte ultra33)
{
struct hd_driveid *id = drive->id;
- ide_hwif_t *hwif = HWIF(drive);
byte speed = 0x00;
- byte ultra66 = ((hwif->udma_four) && (id->hw_config & 0x2000)) ? 1 : 0;
+ byte ultra66 = eighty_ninty_three(drive);
+ byte ultra100 = (m5229_revision>=0xc4) ? 1 : 0;
int rval;
- if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) {
+ if ((id->dma_ultra & 0x0020) && (ultra100) && (ultra66) && (ultra33)) {
+ speed = XFER_UDMA_5;
+ } else if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) {
speed = XFER_UDMA_4;
} else if ((id->dma_ultra & 0x0008) && (ultra66) && (ultra33)) {
speed = XFER_UDMA_3;
@@ -454,7 +453,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
}
dma_func = ide_dma_off_quietly;
if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) {
- if (id->dma_ultra & 0x001F) {
+ if (id->dma_ultra & 0x002F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive, can_ultra_dma);
if ((id->field_valid & 2) &&
@@ -508,13 +507,13 @@ static int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name)
{
- unsigned long fixdma_base = dev->resource[4].start;
+ unsigned long fixdma_base = pci_resource_start(dev, 4);
pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision);
isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
- if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) {
+ if (!fixdma_base) {
/*
*
*/
@@ -539,11 +538,16 @@ unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name)
return 0;
}
+/*
+ * This checks if the controller and the cable are capable
+ * of UDMA66 transfers. It doesn't check the drives.
+ * But see note 2 below!
+ */
unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
- byte ata66mask = hwif->channel ? 0x02 : 0x01;
unsigned int ata66 = 0;
+ byte cable_80_pin[2] = { 0, 0 };
unsigned long flags;
byte tmpbyte;
@@ -575,7 +579,7 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
* 1543C-B0 (m1533, 0x79, bit 2)
*/
pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04);
- } else if (m5229_revision == 0xC3) {
+ } else if (m5229_revision >= 0xC3) {
/*
* 1553/1535 (m1533, 0x79, bit 1)
*/
@@ -596,6 +600,10 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
* has 80-pin (from host view)
*/
if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1;
+ /*
+ * Allow ata66 if cable of current channel has 80 pins
+ */
+ ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0];
} else {
/*
* revision 0x20 (1543-E, 1543-F)
@@ -625,18 +633,6 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
pci_write_config_byte(dev, 0x53, tmpbyte);
- /*
- * Ultra66 cable detection (from Host View)
- * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin
- *
- * 0x4a, bit0 is 0 => primary channel
- * has 80-pin (from host view)
- *
- * 0x4a, bit1 is 0 => secondary channel
- * has 80-pin (from host view)
- */
- pci_read_config_byte(dev, 0x4a, &tmpbyte);
- ata66 = (!(tmpbyte & ata66mask)) ? 1 : 0;
__restore_flags(flags);
return(ata66);
diff --git a/drivers/ide/amd7409.c b/drivers/ide/amd7409.c
index d54a240d4c931c..ca23d3af456338 100644
--- a/drivers/ide/amd7409.c
+++ b/drivers/ide/amd7409.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/ide/amd7409.c Version 0.04 Mar. 18, 2000
+ * linux/drivers/ide/amd7409.c Version 0.05 June 9, 2000
*
- * Copyright (C) 2000 Andre Hedrick <andre@suse.com>
+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
*/
@@ -40,7 +40,7 @@ static struct pci_dev *bmide_dev;
static int amd7409_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
- u32 bibma = bmide_dev->resource[4].start;
+ u32 bibma = pci_resource_start(bmide_dev, 4);
u8 c0 = 0, c1 = 0;
/*
@@ -71,6 +71,20 @@ byte amd7409_proc = 0;
extern char *ide_xfer_verbose (byte xfer_rate);
+static unsigned int amd7409_swdma_check (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 >= 7) ? 1 : 0);
+}
+
+static int amd7409_swdma_error(ide_drive_t *drive)
+{
+ printk("%s: single-word DMA not support (revision < C4)\n", drive->name);
+ return 0;
+}
+
/*
* Here is where all the hard work goes to program the chipset.
*
@@ -122,64 +136,68 @@ static int amd7409_tune_chipset (ide_drive_t *drive, byte speed)
case XFER_UDMA_4:
ultra_timing |= 0x45;
dma_pio_timing |= 0x20;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_UDMA_3:
ultra_timing |= 0x44;
dma_pio_timing |= 0x20;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_UDMA_2:
ultra_timing |= 0x40;
dma_pio_timing |= 0x20;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_UDMA_1:
ultra_timing |= 0x41;
dma_pio_timing |= 0x20;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_UDMA_0:
ultra_timing |= 0x42;
dma_pio_timing |= 0x20;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_MW_DMA_2:
dma_pio_timing |= 0x20;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_MW_DMA_1:
dma_pio_timing |= 0x21;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_MW_DMA_0:
dma_pio_timing |= 0x77;
- pio_timing |= (0x03 << drive->dn);
+ break;
+ case XFER_SW_DMA_2:
+ if (!amd7409_swdma_check(dev))
+ return amd7409_swdma_error(drive);
+ dma_pio_timing |= 0x42;
+ break;
+ case XFER_SW_DMA_1:
+ if (!amd7409_swdma_check(dev))
+ return amd7409_swdma_error(drive);
+ dma_pio_timing |= 0x65;
+ break;
+ case XFER_SW_DMA_0:
+ if (!amd7409_swdma_check(dev))
+ return amd7409_swdma_error(drive);
+ dma_pio_timing |= 0xA8;
break;
#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4:
dma_pio_timing |= 0x20;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_PIO_3:
dma_pio_timing |= 0x22;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_PIO_2:
dma_pio_timing |= 0x42;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_PIO_1:
dma_pio_timing |= 0x65;
- pio_timing |= (0x03 << drive->dn);
break;
case XFER_PIO_0:
default:
dma_pio_timing |= 0xA8;
- pio_timing |= (0x03 << drive->dn);
break;
}
+ pio_timing |= (0x03 << drive->dn);
+
if (!drive->init_speed)
drive->init_speed = speed;
@@ -268,12 +286,14 @@ static void amd7409_tune_drive (ide_drive_t *drive, byte pio)
static int config_chipset_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- byte udma_66 = ((id->hw_config & 0x2000) &&
- (HWIF(drive)->udma_four)) ? 1 : 0;
+ byte udma_66 = eighty_ninty_three(drive);
+ byte udma_100 = 0;
byte speed = 0x00;
int rval;
- if ((id->dma_ultra & 0x0010) && (udma_66)) {
+ if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) {
+ speed = XFER_UDMA_5;
+ } else if ((id->dma_ultra & 0x0010) && (udma_66)) {
speed = XFER_UDMA_4;
} else if ((id->dma_ultra & 0x0008) && (udma_66)) {
speed = XFER_UDMA_3;
@@ -318,7 +338,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
- if (id->dma_ultra & 0x001F) {
+ if (id->dma_ultra & 0x002F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive);
if ((id->field_valid & 2) &&
@@ -327,12 +347,15 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
} else if (id->field_valid & 2) {
try_dma_modes:
- if (id->dma_mword & 0x0007) {
+ if ((id->dma_mword & 0x0007) ||
+ ((id->dma_1word & 0x007) &&
+ (amd7409_swdma_check(HWIF(drive)->pci_dev)))) {
/* Force if Capable regular DMA modes */
dma_func = config_chipset_for_dma(drive);
if (dma_func != ide_dma_on)
goto no_dma_set;
}
+
} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
@@ -372,9 +395,14 @@ int amd7409_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned int __init pci_init_amd7409 (struct pci_dev *dev, const char *name)
{
- unsigned long fixdma_base = dev->resource[4].start;
+ unsigned long fixdma_base = pci_resource_start(dev, 4);
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ if (!amd7409_swdma_check(dev))
+ printk("%s: disabling single-word DMA support (revision < C4)\n", name);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
- if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) {
+ if (!fixdma_base) {
/*
*
*/
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 7e9f0c7eecb9a4..6e45bf0e0fa5d9 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -1,6 +1,6 @@
/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16
*
- * linux/drivers/ide/cmd64x.c Version 1.21 Mar. 18, 2000
+ * linux/drivers/ide/cmd64x.c Version 1.22 June 9, 2000
*
* cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
* Note, this driver is not used at all on other systems because
@@ -10,7 +10,7 @@
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1998 David S. Miller (davem@redhat.com)
- * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
*/
#include <linux/config.h>
@@ -41,6 +41,8 @@
* CMD64x specific registers definition.
*/
+#define CFR 0x50
+#define CFR_INTR_CH0 0x02
#define CNTRL 0x51
#define CNTRL_DIS_RA0 0x40
#define CNTRL_DIS_RA1 0x80
@@ -52,6 +54,7 @@
#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 ARTTIM2 0x57
@@ -63,6 +66,10 @@
#define BMIDECR0 0x70
#define MRDMODE 0x71
+#define MRDMODE_INTR_CH0 0x04
+#define MRDMODE_INTR_CH1 0x08
+#define MRDMODE_BLK_CH0 0x10
+#define MRDMODE_BLK_CH1 0x20
#define BMIDESR0 0x72
#define UDIDETCR0 0x73
#define DTPR0 0x74
@@ -90,9 +97,13 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
u8 reg57 = 0, reg58 = 0, reg5b; /* secondary */
u8 reg72 = 0, reg73 = 0; /* primary */
u8 reg7a = 0, reg7b = 0; /* secondary */
+ u8 reg50 = 0, reg71 = 0; /* extra */
u8 hi_byte = 0, lo_byte = 0;
switch(bmide_dev->device) {
+ case PCI_DEVICE_ID_CMD_649:
+ p += sprintf(p, "\n CMD649 Chipset.\n");
+ break;
case PCI_DEVICE_ID_CMD_648:
p += sprintf(p, "\n CMD648 Chipset.\n");
break;
@@ -106,6 +117,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
p += sprintf(p, "\n CMD64? Chipse.\n");
break;
}
+ (void) pci_read_config_byte(bmide_dev, CFR, &reg50);
(void) pci_read_config_byte(bmide_dev, ARTTIM0, &reg53);
(void) pci_read_config_byte(bmide_dev, DRWTIM0, &reg54);
(void) pci_read_config_byte(bmide_dev, ARTTIM1, &reg55);
@@ -113,6 +125,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
(void) pci_read_config_byte(bmide_dev, ARTTIM2, &reg57);
(void) pci_read_config_byte(bmide_dev, DRWTIM2, &reg58);
(void) pci_read_config_byte(bmide_dev, DRWTIM3, &reg5b);
+ (void) pci_read_config_byte(bmide_dev, MRDMODE, &reg71);
(void) pci_read_config_byte(bmide_dev, BMIDESR0, &reg72);
(void) pci_read_config_byte(bmide_dev, UDIDETCR0, &reg73);
(void) pci_read_config_byte(bmide_dev, BMIDESR1, &reg7a);
@@ -128,42 +141,42 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
(reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO",
(reg72&0x20)?( ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"):
((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"):
- ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"):"X"):"?",
+ ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"):
+ ((reg73&0x00)==0x00)?(((reg73&0x05)==0x05)?"5":"2"):"X"):"?",
(reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO",
(reg72&0x40)?( ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"):
((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"):
- ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"):"X"):"?",
+ ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"):
+ ((reg73&0x00)==0x00)?(((reg73&0x0A)==0x0A)?"5":"2"):"X"):"?",
(reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO",
(reg7a&0x20)?( ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"):
((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"):
- ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"):"X"):"?",
+ ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"):
+ ((reg7b&0x00)==0x00)?(((reg7b&0x05)==0x05)?"5":"2"):"X"):"?",
(reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO",
(reg7a&0x40)?( ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"):
((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"):
- ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"):"X"):"?" );
+ ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"):
+ ((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"):"X"):"?" );
p += sprintf(p, "PIO Mode: %s %s %s %s\n",
"?", "?", "?", "?");
- p += sprintf(p, "PIO\n");
-
- SPLIT_BYTE(reg53, hi_byte, lo_byte);
- p += sprintf(p, "ARTTIM0 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg53, hi_byte, lo_byte);
- SPLIT_BYTE(reg54, hi_byte, lo_byte);
- p += sprintf(p, "DRWTIM0 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg54, hi_byte, lo_byte);
- SPLIT_BYTE(reg55, hi_byte, lo_byte);
- p += sprintf(p, "ARTTIM1 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg55, hi_byte, lo_byte);
- SPLIT_BYTE(reg56, hi_byte, lo_byte);
- p += sprintf(p, "DRWTIM1 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg56, hi_byte, lo_byte);
+ p += sprintf(p, " %s %s\n",
+ (reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ",
+ (reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling");
+ p += sprintf(p, " %s %s\n",
+ (reg71 & MRDMODE_INTR_CH0) ? "pending" : "clear ",
+ (reg71 & MRDMODE_INTR_CH1) ? "pending" : "clear");
+ p += sprintf(p, " %s %s\n",
+ (reg71 & MRDMODE_BLK_CH0) ? "blocked" : "enabled",
+ (reg71 & MRDMODE_BLK_CH1) ? "blocked" : "enabled");
+
+ SPLIT_BYTE(reg50, hi_byte, lo_byte);
+ p += sprintf(p, "CFR = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg50, hi_byte, lo_byte);
SPLIT_BYTE(reg57, hi_byte, lo_byte);
p += sprintf(p, "ARTTIM23 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg57, hi_byte, lo_byte);
- SPLIT_BYTE(reg58, hi_byte, lo_byte);
- p += sprintf(p, "DRWTIM2 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg58, hi_byte, lo_byte);
- SPLIT_BYTE(reg5b, hi_byte, lo_byte);
- p += sprintf(p, "DRWTIM3 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg5b, hi_byte, lo_byte);
- SPLIT_BYTE(reg73, hi_byte, lo_byte);
- p += sprintf(p, "UDIDETCR0 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg73, hi_byte, lo_byte);
- SPLIT_BYTE(reg7b, hi_byte, lo_byte);
- p += sprintf(p, "UDIDETCR1 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg7b, hi_byte, lo_byte);
+ SPLIT_BYTE(reg71, hi_byte, lo_byte);
+ p += sprintf(p, "MRDMODE = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg71, hi_byte, lo_byte);
return p-buffer; /* => must be less than 4k! */
}
@@ -349,9 +362,9 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
#ifdef CONFIG_BLK_DEV_IDEDMA
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- byte unit = (drive->select.b.unit & 0x01);
int err = 0;
+ byte unit = (drive->select.b.unit & 0x01);
u8 pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0;
u8 pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0;
u8 regU = 0;
@@ -369,6 +382,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
(void) pci_read_config_byte(dev, pciD, &regD);
(void) pci_read_config_byte(dev, pciU, &regU);
switch(speed) {
+ case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break;
case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break;
case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break;
case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break;
@@ -383,7 +397,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
#else
int err = 0;
- switch(speed) {
+ switch(speed) {
#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break;
case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break;
@@ -394,6 +408,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed)
default:
return 1;
}
+
#ifdef CONFIG_BLK_DEV_IDEDMA
(void) pci_write_config_byte(dev, pciU, regU);
#endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -420,10 +435,12 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul
byte speed = 0x00;
byte set_pio = 0x00;
byte udma_33 = ((rev >= 0x05) || (ultra_66)) ? 1 : 0;
- byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
+ byte udma_66 = eighty_ninty_three(drive);
+ byte udma_100 = 0;
int rval;
switch(dev->device) {
+ case PCI_DEVICE_ID_CMD_649: udma_100 = 1; break;
case PCI_DEVICE_ID_CMD_648:
case PCI_DEVICE_ID_CMD_646:
case PCI_DEVICE_ID_CMD_643:
@@ -446,7 +463,9 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul
* in the 646U2.
* So we only do UltraDMA on revision 0x05 and 0x07 chipsets.
*/
- if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) {
+ if ((id->dma_ultra & 0x0020) && (udma_100) && (udma_66) && (udma_33)) {
+ speed = XFER_UDMA_5;
+ } else if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) {
speed = XFER_UDMA_4;
} else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) {
speed = XFER_UDMA_3;
@@ -483,7 +502,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul
if (cmd64x_tune_chipset(drive, speed))
return ((int) ide_dma_off);
- rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
((id->dma_1word >> 8) & 7) ? ide_dma_on :
@@ -500,12 +519,15 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
unsigned int class_rev = 0;
byte can_ultra_33 = 0;
byte can_ultra_66 = 0;
+ byte can_ultra_100 = 0;
ide_dma_action_t dma_func = ide_dma_on;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
switch(dev->device) {
+ case PCI_DEVICE_ID_CMD_649:
+ can_ultra_100 = 1;
case PCI_DEVICE_ID_CMD_648:
can_ultra_66 = 1;
case PCI_DEVICE_ID_CMD_643:
@@ -514,6 +536,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
case PCI_DEVICE_ID_CMD_646:
can_ultra_33 = (class_rev >= 0x05) ? 1 : 0;
can_ultra_66 = 0;
+ can_ultra_100 = 0;
break;
default:
return hwif->dmaproc(ide_dma_off, drive);
@@ -528,7 +551,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
}
dma_func = ide_dma_off_quietly;
if ((id->field_valid & 4) && (can_ultra_33)) {
- if (id->dma_ultra & 0x001F) {
+ if (id->dma_ultra & 0x002F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive, class_rev, can_ultra_66);
if ((id->field_valid & 2) &&
@@ -636,6 +659,7 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name)
printk("\n");
break;
case PCI_DEVICE_ID_CMD_648:
+ case PCI_DEVICE_ID_CMD_649:
break;
default:
break;
@@ -714,6 +738,7 @@ void __init ide_init_cmd64x (ide_hwif_t *hwif)
#ifdef CONFIG_BLK_DEV_IDEDMA
switch(dev->device) {
+ case PCI_DEVICE_ID_CMD_649:
case PCI_DEVICE_ID_CMD_648:
case PCI_DEVICE_ID_CMD_643:
hwif->dmaproc = &cmd64x_dmaproc;
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index b160d7716361a2..fb531e81336e78 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/ide/cs5530.c Version 0.6 Mar. 18, 2000
*
- * Copyright (C) 2000 Andre Hedrick <andre@suse.com>
+ * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* Ditto of GNU General Public License.
*
* Copyright (C) 2000 Mark Lord <mlord@pobox.com>
@@ -43,7 +43,7 @@ static struct pci_dev *bmide_dev;
static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
- u32 bibma = bmide_dev->resource[4].start;
+ u32 bibma = pci_resource_start(bmide_dev, 4);
u8 c0 = 0, c1 = 0;
/*
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 3ecaa31ece2c54..3e4961cbe2ee1f 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -1,8 +1,8 @@
/*
* linux/drivers/ide/cy82c693.c Version 0.34 Dec. 13, 1999
*
- * Copyright (C) 1998-99 Andreas S. Krebs (akrebs@altavista.net), Maintainer
- * Copyright (C) 1998-99 Andre Hedrick, Integrater
+ * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>, Integrater
*
* CYPRESS CY82C693 chipset IDE controller
*
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index 74806824219b9b..2011b6a266ff34 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -67,11 +67,13 @@ static int __init gayle_offsets[IDE_NR_PORTS] = {
#define GAYLE_NUM_HWIFS 1
#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS
#define GAYLE_HAS_CONTROL_REG 1
+#define GAYLE_IDEREG_SIZE 0x2000
#else /* CONFIG_BLK_DEV_IDEDOUBLER */
#define GAYLE_NUM_HWIFS 2
#define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \
GAYLE_NUM_HWIFS-1)
#define GAYLE_HAS_CONTROL_REG (!ide_doubler)
+#define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000)
int ide_doubler = 0; /* support IDE doublers? */
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
@@ -121,23 +123,27 @@ void __init gayle_init(void)
ide_ack_intr_t *ack_intr;
hw_regs_t hw;
int index;
+ unsigned long phys_base, res_start, res_n;
if (a4000) {
- base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_4000);
+ phys_base = GAYLE_BASE_4000;
irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000);
ack_intr = gayle_ack_intr_a4000;
} else {
- base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_1200);
+ phys_base = GAYLE_BASE_1200;
irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200);
ack_intr = gayle_ack_intr_a1200;
}
+ phys_base += i*GAYLE_NEXT_PORT;
- if (GAYLE_HAS_CONTROL_REG)
- ctrlport = base + GAYLE_CONTROL;
- else
- ctrlport = 0;
+ res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
+ res_n = GAYLE_IDEREG_SIZE;
- base += i*GAYLE_NEXT_PORT;
+ if (!request_mem_region(res_start, res_n, "IDE"))
+ continue;
+
+ base = (ide_ioreg_t)ZTWO_VADDR(phys_base);
+ ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
ide_setup_ports(&hw, base, gayle_offsets,
ctrlport, irqport, ack_intr, IRQ_AMIGA_PORTS);
@@ -155,7 +161,9 @@ void __init gayle_init(void)
break;
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
}
- }
+ } else
+ release_mem_region(res_start, res_n);
+
#if 1 /* TESTING */
if (i == 1) {
volatile u_short *addr = (u_short *)base;
diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c
index eb73c24456c88c..6fd109c83230a9 100644
--- a/drivers/ide/hd.c
+++ b/drivers/ide/hd.c
@@ -889,7 +889,7 @@ static int parse_hd_setup (char *line) {
(void) get_options(line, ARRAY_SIZE(ints), ints);
hd_setup(NULL, ints);
- return 0;
+ return 1;
}
__setup("hd=", parse_hd_setup);
diff --git a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c
index 911068f7846139..cbd71e60ae852f 100644
--- a/drivers/ide/hpt34x.c
+++ b/drivers/ide/hpt34x.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/ide/hpt34x.c Version 0.30 Mar. 18, 2000
+ * linux/drivers/ide/hpt34x.c Version 0.31 June. 9, 2000
*
- * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
*
@@ -62,7 +62,7 @@ static struct pci_dev *bmide_dev;
static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
- u32 bibma = bmide_dev->resource[4].start;
+ u32 bibma = pci_resource_start(bmide_dev, 4);
u8 c0 = 0, c1 = 0;
/*
@@ -360,7 +360,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name)
{
int i = 0;
- unsigned long hpt34xIoBase = dev->resource[4].start;
+ unsigned long hpt34xIoBase = pci_resource_start(dev, 4);
unsigned short cmd;
unsigned long flags;
@@ -371,7 +371,7 @@ unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (cmd & PCI_COMMAND_MEMORY) {
- if (dev->resource[PCI_ROM_RESOURCE].start) {
+ if (pci_resource_start(dev, PCI_ROM_RESOURCE)) {
pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", dev->resource[PCI_ROM_RESOURCE].start);
}
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 28232b5768dc51..74d3018c522686 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -1,13 +1,16 @@
/*
- * linux/drivers/ide/hpt366.c Version 0.17 Mar. 18, 2000
+ * linux/drivers/ide/hpt366.c Version 0.18 June. 9, 2000
*
- * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com>
+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
* Thanks to HighPoint Technologies for their assistance, and hardware.
* Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
* donation of an ABit BP6 mainboard, processor, and memory acellerated
* development and support.
+ *
+ * Note that final HPT370 support was done by force extraction of GPL.
+ *
*/
#include <linux/config.h>
@@ -30,13 +33,26 @@
#include "ide_modes.h"
-#undef DISPLAY_HPT366_TIMINGS
+#define DISPLAY_HPT366_TIMINGS
#if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
#endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */
+extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);
+
+const char *quirk_drives[] = {
+ "QUANTUM FIREBALLlct08 08",
+ "QUANTUM FIREBALLP KA6.4",
+ "QUANTUM FIREBALLP LM20.5",
+ NULL
+};
+
+const char *bad_ata100_5[] = {
+ NULL
+};
+
const char *bad_ata66_4[] = {
"WDC AC310200R",
NULL
@@ -60,70 +76,92 @@ const char *bad_ata33[] = {
struct chipset_bus_clock_list_entry {
byte xfer_speed;
- unsigned int chipset_settings;
+ unsigned int chipset_settings_write;
+ unsigned int chipset_settings_read;
};
struct chipset_bus_clock_list_entry forty_base [] = {
- { XFER_UDMA_4 , 0x900fd943 },
- { XFER_UDMA_3 , 0x900ad943 },
- { XFER_UDMA_2 , 0x900bd943 },
- { XFER_UDMA_1 , 0x9008d943 },
- { XFER_UDMA_0 , 0x9008d943 },
-
- { XFER_MW_DMA_2 , 0xa008d943 },
- { XFER_MW_DMA_1 , 0xa010d955 },
- { XFER_MW_DMA_0 , 0xa010d9fc },
-
- { XFER_PIO_4 , 0xc008d963 },
- { XFER_PIO_3 , 0xc010d974 },
- { XFER_PIO_2 , 0xc010d997 },
- { XFER_PIO_1 , 0xc010d9c7 },
- { XFER_PIO_0 , 0xc018d9d9 },
- { 0 , 0x0120d9d9 }
+ { XFER_UDMA_4, 0x900fd943, 0x900fd943 },
+ { XFER_UDMA_3, 0x900ad943, 0x900ad943 },
+ { XFER_UDMA_2, 0x900bd943, 0x900bd943 },
+ { XFER_UDMA_1, 0x9008d943, 0x9008d943 },
+ { XFER_UDMA_0, 0x9008d943, 0x9008d943 },
+
+ { XFER_MW_DMA_2, 0xa008d943, 0xa008d943 },
+ { XFER_MW_DMA_1, 0xa010d955, 0xa010d955 },
+ { XFER_MW_DMA_0, 0xa010d9fc, 0xa010d9fc },
+
+ { XFER_PIO_4, 0xc008d963, 0xc008d963 },
+ { XFER_PIO_3, 0xc010d974, 0xc010d974 },
+ { XFER_PIO_2, 0xc010d997, 0xc010d997 },
+ { XFER_PIO_1, 0xc010d9c7, 0xc010d9c7 },
+ { XFER_PIO_0, 0xc018d9d9, 0xc018d9d9 },
+ { 0, 0x0120d9d9, 0x0120d9d9 }
};
struct chipset_bus_clock_list_entry thirty_three_base [] = {
- { XFER_UDMA_4 , 0x90c9a731 },
- { XFER_UDMA_3 , 0x90cfa731 },
- { XFER_UDMA_2 , 0x90caa731 },
- { XFER_UDMA_1 , 0x90cba731 },
- { XFER_UDMA_0 , 0x90c8a731 },
-
- { XFER_MW_DMA_2 , 0xa0c8a731 },
- { XFER_MW_DMA_1 , 0xa0c8a732 }, /* 0xa0c8a733 */
- { XFER_MW_DMA_0 , 0xa0c8a797 },
-
- { XFER_PIO_4 , 0xc0c8a731 },
- { XFER_PIO_3 , 0xc0c8a742 },
- { XFER_PIO_2 , 0xc0d0a753 },
- { XFER_PIO_1 , 0xc0d0a7a3 }, /* 0xc0d0a793 */
- { XFER_PIO_0 , 0xc0d0a7aa }, /* 0xc0d0a7a7 */
- { 0 , 0x0120a7a7 }
+ { XFER_UDMA_4, 0x90c9a731, 0x90c9a731 },
+ { XFER_UDMA_3, 0x90cfa731, 0x90cfa731 },
+ { XFER_UDMA_2, 0x90caa731, 0x90caa731 },
+ { XFER_UDMA_1, 0x90cba731, 0x90cba731 },
+ { XFER_UDMA_0, 0x90c8a731, 0x90c8a731 },
+
+ { XFER_MW_DMA_2, 0xa0c8a731, 0xa0c8a731 },
+ { XFER_MW_DMA_1, 0xa0c8a732, 0xa0c8a732 }, /* 0xa0c8a733 */
+ { XFER_MW_DMA_0, 0xa0c8a797, 0xa0c8a797 },
+
+ { XFER_PIO_4, 0xc0c8a731, 0xc0c8a731 },
+ { XFER_PIO_3, 0xc0c8a742, 0xc0c8a742 },
+ { XFER_PIO_2, 0xc0d0a753, 0xc0d0a753 },
+ { XFER_PIO_1, 0xc0d0a7a3, 0xc0d0a7a3 }, /* 0xc0d0a793 */
+ { XFER_PIO_0, 0xc0d0a7aa, 0xc0d0a7aa }, /* 0xc0d0a7a7 */
+ { 0, 0x0120a7a7, 0x0120a7a7 }
};
struct chipset_bus_clock_list_entry twenty_five_base [] = {
- { XFER_UDMA_4 , 0x90c98521 },
- { XFER_UDMA_3 , 0x90cf8521 },
- { XFER_UDMA_2 , 0x90cf8521 },
- { XFER_UDMA_1 , 0x90cb8521 },
- { XFER_UDMA_0 , 0x90cb8521 },
-
- { XFER_MW_DMA_2 , 0xa0ca8521 },
- { XFER_MW_DMA_1 , 0xa0ca8532 },
- { XFER_MW_DMA_0 , 0xa0ca8575 },
-
- { XFER_PIO_4 , 0xc0ca8521 },
- { XFER_PIO_3 , 0xc0ca8532 },
- { XFER_PIO_2 , 0xc0ca8542 },
- { XFER_PIO_1 , 0xc0d08572 },
- { XFER_PIO_0 , 0xc0d08585 },
- { 0 , 0x01208585 }
+ { XFER_UDMA_4, 0x90c98521, 0x90c98521 },
+ { XFER_UDMA_3, 0x90cf8521, 0x90cf8521 },
+ { XFER_UDMA_2, 0x90cf8521, 0x90cf8521 },
+ { XFER_UDMA_1, 0x90cb8521, 0x90cb8521 },
+ { XFER_UDMA_0, 0x90cb8521, 0x90cb8521 },
+
+ { XFER_MW_DMA_2, 0xa0ca8521, 0xa0ca8521 },
+ { XFER_MW_DMA_1, 0xa0ca8532, 0xa0ca8532 },
+ { XFER_MW_DMA_0, 0xa0ca8575, 0xa0ca8575 },
+
+ { XFER_PIO_4, 0xc0ca8521, 0xc0ca8521 },
+ { XFER_PIO_3, 0xc0ca8532, 0xc0ca8532 },
+ { XFER_PIO_2, 0xc0ca8542, 0xc0ca8542 },
+ { XFER_PIO_1, 0xc0d08572, 0xc0d08572 },
+ { XFER_PIO_0, 0xc0d08585, 0xc0d08585 },
+ { 0, 0x01208585, 0x01208585 }
+};
+
+struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
+ { XFER_UDMA_5, 0x1A85F442, 0x16454e31 },
+ { XFER_UDMA_4, 0x16454e31, 0x16454e31 },
+ { XFER_UDMA_3, 0x166d4e31, 0x166d4e31 },
+ { XFER_UDMA_2, 0x16494e31, 0x16494e31 },
+ { XFER_UDMA_1, 0x164d4e31, 0x164d4e31 },
+ { XFER_UDMA_0, 0x16514e31, 0x16514e31 },
+
+ { XFER_MW_DMA_2, 0x26514e21, 0x26514e21 },
+ { XFER_MW_DMA_1, 0x26514e33, 0x26514e33 },
+ { XFER_MW_DMA_0, 0x26514e97, 0x26514e97 },
+
+ { XFER_PIO_4, 0x06514e21, 0x06514e21 },
+ { XFER_PIO_3, 0x06514e22, 0x06514e22 },
+ { XFER_PIO_2, 0x06514e33, 0x06514e33 },
+ { XFER_PIO_1, 0x06914e43, 0x06914e43 },
+ { XFER_PIO_0, 0x06914e57, 0x06914e57 },
+ { 0, 0x06514e57, 0x06514e57 }
};
#define HPT366_DEBUG_DRIVE_INFO 0
+#define HPT370_ALLOW_ATA100_5 1
#define HPT366_ALLOW_ATA66_4 1
#define HPT366_ALLOW_ATA66_3 1
@@ -139,7 +177,12 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count)
char *p = buffer;
u32 bibma = bmide_dev->resource[4].start;
u32 bibma2 = bmide2_dev->resource[4].start;
+ char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"};
u8 c0 = 0, c1 = 0;
+ u32 class_rev;
+
+ pci_read_config_dword(bmide_dev, PCI_CLASS_REVISION, &class_rev);
+ class_rev &= 0xff;
/*
* at that point bibma+0x2 et bibma+0xa are byte registers
@@ -149,7 +192,7 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count)
if (bmide2_dev)
c1 = inb_p((unsigned short)bibma2 + 0x02);
- p += sprintf(p, "\n HPT366 Chipset.\n");
+ p += sprintf(p, "\n %s Chipset.\n", chipset_names[class_rev]);
p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
p += sprintf(p, " %sabled %sabled\n",
(c0&0x80) ? "dis" : " en",
@@ -173,74 +216,74 @@ extern char *ide_xfer_verbose (byte xfer_rate);
byte hpt363_shared_irq = 0;
byte hpt363_shared_pin = 0;
-static unsigned int pci_rev_check_hpt366 (struct pci_dev *dev)
+static unsigned int pci_rev_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 == 0x03) ? 1 : 0);
+ return ((int) (class_rev > 0x02) ? 1 : 0);
}
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
struct hd_driveid *id = drive->id;
-#if HPT366_DEBUG_DRIVE_INFO
- printk("check_in_drive_lists(%s, %p)\n", drive->name, list);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
- while (*list) {
- if (!strcmp(*list++,id->model)) {
-#ifdef DEBUG
- printk("%s: Broken ASIC, BackSpeeding (U)DMA for %s\n", drive->name, id->model);
-#endif /* DEBUG */
- return 1;
+ if (quirk_drives == list) {
+ while (*list) {
+ if (strstr(id->model, *list++)) {
+ return 1;
+ }
+ }
+ } else {
+ while (*list) {
+ if (!strcmp(*list++,id->model)) {
+ return 1;
+ }
}
}
return 0;
}
-static unsigned int pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
+static unsigned int pci_bus_clock_list (byte speed, int direction, struct chipset_bus_clock_list_entry * chipset_table)
{
-#if HPT366_DEBUG_DRIVE_INFO
- printk("pci_bus_clock_list(speed=0x%02x, table=%p)\n", speed, chipset_table);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
for ( ; chipset_table->xfer_speed ; chipset_table++)
if (chipset_table->xfer_speed == speed) {
-#if HPT366_DEBUG_DRIVE_INFO
- printk("pci_bus_clock_list: found match: 0x%08x\n", chipset_table->chipset_settings);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
- return chipset_table->chipset_settings;
+ return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read;
}
-#if HPT366_DEBUG_DRIVE_INFO
- printk("pci_bus_clock_list: using default: 0x%08x\n", 0x01208585);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
- return 0x01208585;
+ return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read;
}
-static int hpt366_tune_chipset (ide_drive_t *drive, byte speed)
+static void hpt366_tune_chipset (ide_drive_t *drive, byte speed, int direction)
{
- int err;
byte regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
+ byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51;
+ /*
+ * since the channel is always 0 it does not matter.
+ */
+
unsigned int reg1 = 0;
unsigned int reg2 = 0;
+ byte drive_fast = 0;
-#if HPT366_DEBUG_DRIVE_INFO
- printk("hpt366_tune_chipset(%s, speed=0x%02x)\n", drive->name, speed);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
+ /*
+ * Disable the "fast interrupt" prediction.
+ */
+ pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast);
+ if (drive_fast & 0x02)
+ pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x20);
pci_read_config_dword(HWIF(drive)->pci_dev, regtime, &reg1);
/* detect bus speed by looking at control reg timing: */
switch((reg1 >> 8) & 7) {
case 5:
- reg2 = pci_bus_clock_list(speed, forty_base);
+ reg2 = pci_bus_clock_list(speed, direction, forty_base);
break;
case 9:
- reg2 = pci_bus_clock_list(speed, twenty_five_base);
+ reg2 = pci_bus_clock_list(speed, direction, twenty_five_base);
break;
default:
- printk("hpt366: assuming 33Mhz PCI bus\n");
case 7:
- reg2 = pci_bus_clock_list(speed, thirty_three_base);
+ reg2 = pci_bus_clock_list(speed, direction, thirty_three_base);
break;
}
/*
@@ -254,18 +297,56 @@ static int hpt366_tune_chipset (ide_drive_t *drive, byte speed)
reg2 &= ~0x80000000;
pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2);
- err = ide_config_drive_speed(drive, speed);
+}
+
+static void hpt370_tune_chipset (ide_drive_t *drive, byte speed, int direction)
+{
+ byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51;
+ byte reg5bh = (speed != XFER_UDMA_5) ? 0x22 : (direction) ? 0x20 : 0x22;
+ unsigned int list_conf = pci_bus_clock_list(speed, direction, thirty_three_base_hpt370);
+ unsigned int drive_conf = 0;
+ unsigned int conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
+ byte drive_pci = 0;
+ byte drive_fast = 0;
+
+ switch (drive->dn) {
+ case 0: drive_pci = 0x40; break;
+ case 1: drive_pci = 0x44; break;
+ case 2: drive_pci = 0x48; break;
+ case 3: drive_pci = 0x4c; break;
+ default: return;
+ }
+ /*
+ * Disable the "fast interrupt" prediction.
+ */
+ pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast);
+ if (drive_fast & 0x80)
+ pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x80);
+
+ pci_read_config_dword(HWIF(drive)->pci_dev, drive_pci, &drive_conf);
+ pci_write_config_byte(HWIF(drive)->pci_dev, 0x5b, reg5bh);
+
+ list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
+ /*
+ * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later)
+ */
+ list_conf &= ~0x80000000;
+
+ pci_write_config_dword(HWIF(drive)->pci_dev, drive_pci, list_conf);
+}
+static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed)
+{
if (!drive->init_speed)
drive->init_speed = speed;
-#if HPT366_DEBUG_DRIVE_INFO
- printk("%s: speed=0x%02x(%s), drive%d, old=0x%08x, new=0x%08x, err=0x%04x\n",
- drive->name, speed, ide_xfer_verbose(speed),
- drive->dn, reg1, reg2, err);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
+ if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) {
+ hpt370_tune_chipset(drive, speed, 0);
+ } else {
+ hpt366_tune_chipset(drive, speed, 0);
+ }
drive->current_speed = speed;
- return(err);
+ return ((int) ide_config_drive_speed(drive, speed));
}
static void config_chipset_for_pio (ide_drive_t *drive)
@@ -274,9 +355,6 @@ static void config_chipset_for_pio (ide_drive_t *drive)
unsigned short xfer_pio = drive->id->eide_pio_modes;
byte timing, speed, pio;
-#if HPT366_DEBUG_DRIVE_INFO
- printk("%s: config_chipset_for_pio\n", drive->name);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
if (xfer_pio> 4)
@@ -306,13 +384,10 @@ static void config_chipset_for_pio (ide_drive_t *drive)
speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
break;
}
-#if HPT366_DEBUG_DRIVE_INFO
- printk("%s: config_chipset_for_pio: speed=0x%04x\n", drive->name, speed);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
- (void) hpt366_tune_chipset(drive, speed);
+ (void) hpt3xx_tune_chipset(drive, speed);
}
-static void hpt366_tune_drive (ide_drive_t *drive, byte pio)
+static void hpt3xx_tune_drive (ide_drive_t *drive, byte pio)
{
byte speed;
switch(pio) {
@@ -322,7 +397,7 @@ static void hpt366_tune_drive (ide_drive_t *drive, byte pio)
case 1: speed = XFER_PIO_1;break;
default: speed = XFER_PIO_0;break;
}
- (void) hpt366_tune_chipset(drive, speed);
+ (void) hpt3xx_tune_chipset(drive, speed);
}
#ifdef CONFIG_BLK_DEV_IDEDMA
@@ -341,18 +416,24 @@ static int config_chipset_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
byte speed = 0x00;
- byte reg51h = 0;
+ byte ultra66 = eighty_ninty_three(drive);
int rval;
- if ((id->dma_ultra & 0x0010) &&
- (!check_in_drive_lists(drive, bad_ata66_4)) &&
- (HPT366_ALLOW_ATA66_4) &&
- (HWIF(drive)->udma_four)) {
+ if ((id->dma_ultra & 0x0020) &&
+ (!check_in_drive_lists(drive, bad_ata100_5)) &&
+ (HPT370_ALLOW_ATA100_5) &&
+ (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) &&
+ (ultra66)) {
+ speed = XFER_UDMA_5;
+ } else if ((id->dma_ultra & 0x0010) &&
+ (!check_in_drive_lists(drive, bad_ata66_4)) &&
+ (HPT366_ALLOW_ATA66_4) &&
+ (ultra66)) {
speed = XFER_UDMA_4;
} else if ((id->dma_ultra & 0x0008) &&
(!check_in_drive_lists(drive, bad_ata66_3)) &&
(HPT366_ALLOW_ATA66_3) &&
- (HWIF(drive)->udma_four)) {
+ (ultra66)) {
speed = XFER_UDMA_3;
} else if (id->dma_ultra && (!check_in_drive_lists(drive, bad_ata33))) {
if (id->dma_ultra & 0x0004) {
@@ -368,52 +449,56 @@ static int config_chipset_for_dma (ide_drive_t *drive)
speed = XFER_MW_DMA_1;
} else if (id->dma_mword & 0x0001) {
speed = XFER_MW_DMA_0;
- } else if (id->dma_1word & 0x0004) {
- speed = XFER_SW_DMA_2;
- } else if (id->dma_1word & 0x0002) {
- speed = XFER_SW_DMA_1;
- } else if (id->dma_1word & 0x0001) {
- speed = XFER_SW_DMA_0;
- } else {
-#if HPT366_DEBUG_DRIVE_INFO
- printk("%s: config_chipset_for_dma: returning 'ide_dma_off_quietly'\n", drive->name);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
+ } else {
return ((int) ide_dma_off_quietly);
}
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x51, &reg51h);
+ (void) hpt3xx_tune_chipset(drive, speed);
-#ifdef CONFIG_HPT366_FIP
- /*
- * Some drives prefer/allow for the method of handling interrupts.
- */
- if (!(reg51h & 0x80))
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h|0x80);
-#else /* ! CONFIG_HPT366_FIP */
- /*
- * Disable the "fast interrupt" prediction.
- * Instead, always wait for the real interrupt from the drive!
- */
- if (reg51h & 0x80)
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h & ~0x80);
-#endif /* CONFIG_HPT366_FIP */
-#if HPT366_DEBUG_DRIVE_INFO
- printk("%s: config_chipset_for_dma: speed=0x%04x\n", drive->name, speed);
-#endif /* HPT366_DEBUG_DRIVE_INFO */
- (void) hpt366_tune_chipset(drive, speed);
-
- rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
- ((id->dma_1word >> 8) & 7) ? ide_dma_on :
ide_dma_off_quietly);
-
-#if HPT366_DEBUG_DRIVE_INFO
- printk("%s: config_chipset_for_dma: returning %d (%s)\n", drive->name, rval, rval == ide_dma_on ? "dma_on" : "dma_off");
-#endif /* HPT366_DEBUG_DRIVE_INFO */
return rval;
}
+int hpt3xx_quirkproc (ide_drive_t *drive)
+{
+ return ((int) check_in_drive_lists(drive, quirk_drives));
+}
+
+void hpt3xx_intrproc (ide_drive_t *drive)
+{
+}
+
+void hpt3xx_maskproc (ide_drive_t *drive, int mask)
+{
+ if (drive->quirk_list) {
+ if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) {
+ byte reg5a = 0;
+ pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, &reg5a);
+ if (((reg5a & 0x10) >> 4) != mask)
+ pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10));
+ } else {
+ if (mask) {
+ disable_irq(HWIF(drive)->irq);
+ } else {
+ enable_irq(HWIF(drive)->irq);
+ }
+ }
+ } else {
+ if (IDE_CONTROL_REG)
+ OUT_BYTE(mask ? (drive->ctl | 2) : (drive->ctl & ~2), IDE_CONTROL_REG);
+ }
+}
+
+void hpt370_rw_proc (ide_drive_t *drive, ide_dma_action_t func)
+{
+ if ((func != ide_dma_write) || (func != ide_dma_read))
+ return;
+ hpt370_tune_chipset(drive, drive->current_speed, (func == ide_dma_write));
+}
+
static int config_drive_xfer_rate (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -427,7 +512,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
- if (id->dma_ultra & 0x001F) {
+ if (id->dma_ultra & 0x002F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive);
if ((id->field_valid & 2) &&
@@ -436,8 +521,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
} else if (id->field_valid & 2) {
try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x0007)) {
+ if (id->dma_mword & 0x0007) {
/* Force if Capable regular DMA modes */
dma_func = config_chipset_for_dma(drive);
if (dma_func != ide_dma_on)
@@ -472,24 +556,39 @@ no_dma_set:
*/
int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
- byte reg50h = 0;
+ byte reg50h = 0, reg52h = 0, reg5ah = 0;
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
case ide_dma_lostirq:
-#if 0
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0x03);
pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, &reg50h);
- /* ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); */
-#endif
+ pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, &reg52h);
+ pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, &reg5ah);
+ printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n",
+ drive->name,
+ ide_dmafunc_verbose(func),
+ reg50h, reg52h, reg5ah);
+ if (reg5ah & 0x10)
+ pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, reg5ah & ~0x10);
+ break;
case ide_dma_timeout:
default:
break;
}
return ide_dmaproc(func, drive); /* use standard DMA stuff */
}
+
+int hpt370_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+{
+ switch (func) {
+ case ide_dma_check:
+ return config_drive_xfer_rate(drive);
+ default:
+ break;
+ }
+ return ide_dmaproc(func, drive); /* use standard DMA stuff */
+}
#endif /* CONFIG_BLK_DEV_IDEDMA */
unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name)
@@ -519,7 +618,7 @@ unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name)
if (!hpt366_proc) {
hpt366_proc = 1;
bmide_dev = dev;
- if (pci_rev_check_hpt366(dev))
+ if (pci_rev_check_hpt3xx(dev))
bmide2_dev = dev;
hpt366_display_info = &hpt366_get_info;
}
@@ -546,14 +645,24 @@ unsigned int __init ata66_hpt366 (ide_hwif_t *hwif)
void __init ide_init_hpt366 (ide_hwif_t *hwif)
{
- if (pci_rev_check_hpt366(hwif->pci_dev)) return;
-
- hwif->tuneproc = &hpt366_tune_drive;
- hwif->speedproc = &hpt366_tune_chipset;
+ hwif->tuneproc = &hpt3xx_tune_drive;
+ hwif->speedproc = &hpt3xx_tune_chipset;
+ hwif->quirkproc = &hpt3xx_quirkproc;
+ hwif->intrproc = &hpt3xx_intrproc;
+ hwif->maskproc = &hpt3xx_maskproc;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
- hwif->dmaproc = &hpt366_dmaproc;
+ if (pci_rev_check_hpt3xx(hwif->pci_dev)) {
+ byte reg5ah = 0;
+ pci_read_config_byte(hwif->pci_dev, 0x5a, &reg5ah);
+ if (reg5ah & 0x10) /* interrupt force enable */
+ pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10);
+ hwif->dmaproc = &hpt370_dmaproc;
+ hwif->rwproc = &hpt370_rw_proc;
+ } else {
+ hwif->dmaproc = &hpt366_dmaproc;
+ }
hwif->autodma = 1;
} else {
hwif->autodma = 0;
@@ -571,19 +680,16 @@ void ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
{
byte masterdma = 0, slavedma = 0;
byte dma_new = 0, dma_old = inb(dmabase+2);
+ byte primary = hwif->channel ? 0x4b : 0x43;
+ byte secondary = hwif->channel ? 0x4f : 0x47;
unsigned long flags;
- if (pci_rev_check_hpt366(hwif->pci_dev)) {
- ide_setup_dma(hwif, dmabase, 8);
- return;
- }
-
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
dma_new = dma_old;
- pci_read_config_byte(hwif->pci_dev, 0x43, &masterdma);
- pci_read_config_byte(hwif->pci_dev, 0x47, &slavedma);
+ pci_read_config_byte(hwif->pci_dev, primary, &masterdma);
+ pci_read_config_byte(hwif->pci_dev, secondary, &slavedma);
if (masterdma & 0x30) dma_new |= 0x20;
if (slavedma & 0x30) dma_new |= 0x40;
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index dcc50362faae8c..7d5bfaedffbc19 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -351,7 +351,7 @@ icside_config_if(ide_drive_t *drive, int xfer_mode)
static int
icside_set_speed(ide_drive_t *drive, byte speed)
{
- return ((int) icside_config_if(drive, (int) speed));
+ return icside_config_if(drive, speed);
}
static int
@@ -508,9 +508,9 @@ icside_setup_dma(ide_hwif_t *hwif, int autodma)
goto failed;
}
- hwif->dmaproc = &icside_dmaproc;
+ hwif->speedproc = icside_set_speed;
+ hwif->dmaproc = icside_dmaproc;
hwif->autodma = autodma;
- hwif->speedproc = &icside_set_speed;
printk(" capable%s\n", autodma ?
", auto-enable" : "");
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index d209c29fff0885..ab4d3afbb9e158 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -426,11 +426,13 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
while (hi > lo) {
mid = (lo + hi) / 2;
- if (packet_command_texts[mid].packet_command == failed_command->c[0]) {
+ if (packet_command_texts[mid].packet_command ==
+ failed_command->c[0]) {
s = packet_command_texts[mid].text;
break;
}
- else if (packet_command_texts[mid].packet_command > failed_command->c[0])
+ if (packet_command_texts[mid].packet_command >
+ failed_command->c[0])
hi = mid;
else
lo = mid+1;
@@ -1524,7 +1526,7 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
memset(&pc, 0, sizeof(pc));
pc.sense = sense;
pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
- pc.c[4] = lockflag ? 3 : 0;
+ pc.c[4] = lockflag ? 1 : 0;
stat = cdrom_queue_packet_command (drive, &pc);
}
@@ -1624,7 +1626,8 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
/* Try to read the entire TOC for the disk into our internal buffer. */
static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
{
- int stat, ntracks, i;
+ int minor, stat, ntracks, i;
+ kdev_t dev;
struct cdrom_info *info = drive->driver_data;
struct atapi_toc *toc = info->toc;
struct {
@@ -1663,8 +1666,10 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
#endif /* not STANDARD_ATAPI */
ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
- if (ntracks <= 0) return -EIO;
- if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS;
+ if (ntracks <= 0)
+ return -EIO;
+ if (ntracks > MAX_TRACKS)
+ ntracks = MAX_TRACKS;
/* Now read the whole schmeer. */
stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
@@ -1755,13 +1760,13 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
/* Now try to get the total cdrom capacity. */
-#if 0
- stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor),
- (long *)&toc->capacity);
+ minor = (drive->select.b.unit) << PARTN_BITS;
+ dev = MKDEV(HWIF(drive)->major, minor);
+ stat = cdrom_get_last_written(dev, (long *)&toc->capacity);
if (stat)
-#endif
- stat = cdrom_read_capacity(drive, &toc->capacity, sense);
- if (stat) toc->capacity = 0x1fffff;
+ stat = cdrom_read_capacity(drive, &toc->capacity, sense);
+ if (stat)
+ toc->capacity = 0x1fffff;
/* Remember that we've read this stuff. */
CDROM_STATE_FLAGS (drive)->toc_valid = 1;
@@ -2552,7 +2557,8 @@ unsigned long ide_cdrom_capacity (ide_drive_t *drive)
{
unsigned capacity;
- return cdrom_read_capacity(drive, &capacity, NULL) ? 0 : capacity * SECTORS_PER_FRAME;
+ return cdrom_read_capacity(drive, &capacity, NULL)
+ ? 0 : capacity * SECTORS_PER_FRAME;
}
static
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 4e29520180495d..ae9f62768c5593 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1,14 +1,13 @@
/*
- * linux/drivers/ide/ide-disk.c Version 1.09 April 23, 1999
+ * linux/drivers/ide/ide-disk.c Version 1.10 June 9, 2000
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/
/*
* Mostly written by Mark Lord <mlord@pobox.com>
- * and Gadi Oxman <gadio@netvision.net.il>
- *
- * See linux/MAINTAINERS for address of current maintainer.
+ * and Gadi Oxman <gadio@netvision.net.il>
+ * and Andre Hedrick <andre@linux-ide.org>
*
* This is the IDE/ATA disk driver, as evolved from hd.c and ide.c.
*
@@ -27,9 +26,10 @@
* the entire disk.
* Version 1.09 added increment of rq->sector in ide_multwrite
* added UDMA 3/4 reporting
+ * Version 1.10 request queue changes, Ultra DMA 100
*/
-#define IDEDISK_VERSION "1.09"
+#define IDEDISK_VERSION "1.10"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
@@ -140,11 +140,8 @@ static ide_startstop_t read_intr (ide_drive_t *drive)
int i;
unsigned int msect, nsect;
struct request *rq;
-#if 0
- if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
- return ide_error(drive, "read_intr", stat);
- }
-#else /* new way for dealing with premature shared PCI interrupts */
+
+ /* new way for dealing with premature shared PCI interrupts */
if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
if (stat & (ERR_STAT|DRQ_STAT)) {
return ide_error(drive, "read_intr", stat);
@@ -153,7 +150,6 @@ static ide_startstop_t read_intr (ide_drive_t *drive)
ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
return ide_started;
}
-#endif
msect = drive->mult_count;
read_next:
@@ -688,7 +684,6 @@ static int set_nowerr(ide_drive_t *drive, int arg)
{
if (ide_spin_wait_hwgroup(drive))
return -EBUSY;
-
drive->nowerr = arg;
drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
spin_unlock_irq(&io_request_lock);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 835fa91e34e465..e9a34afc1a7203 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/ide/ide-dma.c Version 4.09 April 23, 1999
+ * linux/drivers/ide/ide-dma.c Version 4.10 June 9, 2000
*
- * Copyright (c) 1999 Andre Hedrick
+ * Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*/
@@ -70,12 +70,11 @@
*
* And, yes, Intel Zappa boards really *do* use both PIIX IDE ports.
*
- * ACARD ATP850UF Chipset "Modified SCSI Class" with other names
- * AEC6210 U/UF
- * SIIG's UltraIDE Pro CN-2449
- * TTI HPT343 Chipset "Modified SCSI Class" but reports as an
- * unknown storage device.
- * NEW check_drive_lists(ide_drive_t *drive, int good_bad)
+ * check_drive_lists(ide_drive_t *drive, int good_bad)
+ *
+ * ATA-66/100 and recovery functions, I forgot the rest......
+ * SELECT_READ_WRITE(hwif,drive,func) for active tuning based on IO direction.
+ *
*/
#include <linux/config.h>
@@ -358,10 +357,11 @@ int report_drive_dmaing (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- if ((id->field_valid & 4) && (id->hw_config & 0x2000) &&
- (HWIF(drive)->udma_four) &&
- (id->dma_ultra & (id->dma_ultra >> 11) & 3)) {
- if ((id->dma_ultra >> 12) & 1) {
+ if ((id->field_valid & 4) && (eighty_ninty_three(drive)) &&
+ (id->dma_ultra & (id->dma_ultra >> 11) & 7)) {
+ if ((id->dma_ultra >> 13) & 1) {
+ printk(", UDMA(100)"); /* UDMA BIOS-enabled! */
+ } else if ((id->dma_ultra >> 12) & 1) {
printk(", UDMA(66)"); /* UDMA BIOS-enabled! */
} else {
printk(", UDMA(44)"); /* UDMA BIOS-enabled! */
@@ -393,9 +393,9 @@ static int config_drive_for_dma (ide_drive_t *drive)
if (ide_dmaproc(ide_dma_bad_drive, drive))
return hwif->dmaproc(ide_dma_off, drive);
- /* Enable DMA on any drive that has UltraDMA (mode 3/4) enabled */
- if ((id->field_valid & 4) && (hwif->udma_four) && (id->hw_config & 0x2000))
- if ((id->dma_ultra & (id->dma_ultra >> 11) & 3))
+ /* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */
+ if ((id->field_valid & 4) && (eighty_ninty_three(drive)))
+ if ((id->dma_ultra & (id->dma_ultra >> 11) & 7))
return hwif->dmaproc(ide_dma_on, drive);
/* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */
if (id->field_valid & 4) /* UltraDMA */
@@ -413,6 +413,22 @@ static int config_drive_for_dma (ide_drive_t *drive)
}
/*
+ * 1 dmaing, 2 error, 4 intr
+ */
+static int dma_timer_expiry (ide_drive_t *drive)
+{
+ byte dma_stat = inb(HWIF(drive)->dma_base+2);
+
+#ifdef DEBUG
+ printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat);
+#endif /* DEBUG */
+
+ if (dma_stat & 1) /* DMAing */
+ return WAIT_CMD;
+ return 0;
+}
+
+/*
* ide_dmaproc() initiates/aborts DMA read/write operations on a drive.
*
* The caller is assumed to have selected the drive and programmed the drive's
@@ -451,6 +467,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
case ide_dma_read:
reading = 1 << 3;
case ide_dma_write:
+ SELECT_READ_WRITE(hwif,drive,func);
if (!(count = ide_build_dmatable(drive, func)))
return 1; /* try PIO instead of DMA */
outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
@@ -459,7 +476,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */
+ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
case ide_dma_begin:
/* Note that this is done *after* the cmd has
@@ -570,8 +587,8 @@ unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const
if (hwif->mate && hwif->mate->dma_base) {
dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
} else {
- dma_base = dev->resource[4].start;
- if (!dma_base || dma_base == PCI_BASE_ADDRESS_IO_MASK) {
+ dma_base = pci_resource_start(dev, 4);
+ if (!dma_base) {
printk("%s: dma_base is invalid (0x%04lx)\n", name, dma_base);
dma_base = 0;
}
diff --git a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c
index cb3790fa62f4f5..967b91e55c199f 100644
--- a/drivers/ide/ide-features.c
+++ b/drivers/ide/ide-features.c
@@ -1,14 +1,16 @@
/*
- * linux/drivers/block/ide-features.c Version 0.03 Feb. 10, 2000
+ * linux/drivers/block/ide-features.c Version 0.04 June 9, 2000
*
* Copyright (C) 1999-2000 Linus Torvalds & authors (see below)
*
- * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com>
+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
*
* Extracts if ide.c to address the evolving transfer rate code for
* the SETFEATURES_XFER callouts. Various parts of any given function
* are credited to previous ATA-IDE maintainers.
*
+ * Auto-CRC downgrade for Ultra DMA(ing)
+ *
* May be copied or modified under the terms of the GNU General Public License
*/
@@ -115,6 +117,10 @@ char *ide_dmafunc_verbose (ide_dma_action_t dmafunc)
*/
byte ide_auto_reduce_xfer (ide_drive_t *drive)
{
+ if (!drive->crc_count)
+ return drive->current_speed;
+ drive->crc_count = 0;
+
switch(drive->current_speed) {
case XFER_UDMA_7: return XFER_UDMA_6;
case XFER_UDMA_6: return XFER_UDMA_5;
@@ -164,6 +170,7 @@ int ide_driveid_update (ide_drive_t *drive)
probe_irq_off(probe_irq_on());
irqs = probe_irq_on();
+ SELECT_MASK(HWIF(drive), drive, 1);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
ide_delay_50ms();
@@ -173,17 +180,20 @@ int ide_driveid_update (ide_drive_t *drive)
if (0 < (signed long)(jiffies - timeout)) {
if (irqs)
(void) probe_irq_off(irqs);
+ SELECT_MASK(HWIF(drive), drive, 0);
return 0; /* drive timed-out */
}
ide_delay_50ms(); /* give drive a breather */
} while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT);
ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */
if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
+ SELECT_MASK(HWIF(drive), drive, 0);
printk("%s: CHECK for good STATUS\n", drive->name);
return 0;
}
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only; some systems need this */
+ SELECT_MASK(HWIF(drive), drive, 0);
id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
ide_input_data(drive, id, SECTOR_WORDS);
(void) GET_STAT(); /* clear drive IRQ */
@@ -214,11 +224,15 @@ int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
(nsect > XFER_UDMA_2) &&
(feature == SETFEATURES_XFER)) {
if (!HWIF(drive)->udma_four) {
- printk("%s: Speed warnings UDMA 3/4 is not functional.\n", HWIF(drive)->name);
+ printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name);
return 1;
}
+#ifndef CONFIG_IDEDMA_IVB
+ if ((drive->id->hw_config & 0x6000) == 0) {
+#else /* !CONFIG_IDEDMA_IVB */
if ((drive->id->hw_config & 0x2000) == 0) {
- printk("%s: Speed warnings UDMA 3/4 is not functional.\n", drive->name);
+#endif /* CONFIG_IDEDMA_IVB */
+ printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name);
return 1;
}
}
@@ -244,6 +258,18 @@ int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
}
/*
+ * All hosts that use the 80c ribbon mus use!
+ */
+byte eighty_ninty_three (ide_drive_t *drive)
+{
+ return ((byte) ((HWIF(drive)->udma_four) &&
+#ifndef CONFIG_IDEDMA_IVB
+ (drive->id->hw_config & 0x4000) &&
+#endif /* CONFIG_IDEDMA_IVB */
+ (drive->id->hw_config & 0x2000)) ? 1 : 0);
+}
+
+/*
* Similar to ide_wait_stat(), except it never calls ide_error internally.
* This is a kludge to handle the new ide_config_drive_speed() function,
* and should not otherwise be used anywhere. Eventually, the tuneproc's
@@ -260,10 +286,11 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
int i, error = 1;
byte stat;
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
byte unit = (drive->select.b.unit & 0x01);
outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
-#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
+#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
+
/*
* Don't use ide_wait_cmd here - it will
* attempt to set_geometry and recalibrate,
@@ -276,6 +303,7 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
disable_irq(hwif->irq); /* disable_irq_nosync ?? */
udelay(1);
SELECT_DRIVE(HWIF(drive), drive);
+ SELECT_MASK(HWIF(drive), drive, 0);
udelay(1);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
@@ -315,6 +343,8 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
}
}
+ SELECT_MASK(HWIF(drive), drive, 0);
+
enable_irq(hwif->irq);
if (error) {
@@ -326,13 +356,13 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
drive->id->dma_mword &= ~0x0F00;
drive->id->dma_1word &= ~0x0F00;
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
if (speed > XFER_PIO_4) {
outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
} else {
outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
}
-#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
+#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
switch(speed) {
case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break;
@@ -358,5 +388,5 @@ EXPORT_SYMBOL(ide_auto_reduce_xfer);
EXPORT_SYMBOL(ide_driveid_update);
EXPORT_SYMBOL(ide_ata66_check);
EXPORT_SYMBOL(set_transfer);
+EXPORT_SYMBOL(eighty_ninty_three);
EXPORT_SYMBOL(ide_config_drive_speed);
-
diff --git a/drivers/ide/ide-geometry.c b/drivers/ide/ide-geometry.c
index a291785971cf52..639d4c6f1c07ae 100644
--- a/drivers/ide/ide-geometry.c
+++ b/drivers/ide/ide-geometry.c
@@ -3,7 +3,7 @@
*/
#include <linux/config.h>
-#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD)
+#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD_ONLY)
#include <linux/ide.h>
#include <asm/io.h>
@@ -211,4 +211,4 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg)
drive->bios_cyl, drive->bios_head, drive->bios_sect);
return ret;
}
-#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD) */
+#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD_ONLY) */
diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c
index c10ae4b51cbf91..8c935439491718 100644
--- a/drivers/ide/ide-pci.c
+++ b/drivers/ide/ide-pci.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/ide-pci.c Version 1.04 July 27, 1999
+ * linux/drivers/ide/ide-pci.c Version 1.05 June 9, 2000
*
* Copyright (c) 1998-2000 Andre Hedrick <andre@linux-ide.org>
*
@@ -33,10 +33,13 @@
#define DEVID_PIIX4E2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1})
#define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1})
#define DEVID_PIIX4U2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1})
+#define DEVID_PIIX4NX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX})
+#define DEVID_PIIX4U3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82820FW_5})
#define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561})
#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_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})
#define DEVID_SAMURAI ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE})
@@ -44,6 +47,7 @@
#define DEVID_CMD643 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643})
#define DEVID_CMD646 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646})
#define DEVID_CMD648 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648})
+#define DEVID_CMD649 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649})
#define DEVID_SIS5513 ((ide_pci_devid_t){PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513})
#define DEVID_OPTI621 ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621})
#define DEVID_OPTI621V ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558})
@@ -65,6 +69,7 @@
#define DEVID_CY82C693 ((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693})
#define DEVID_HINT ((ide_pci_devid_t){0x3388, 0x8013})
#define DEVID_CS5530 ((ide_pci_devid_t){PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE})
+#define DEVID_AMD7403 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7403})
#define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409})
#define IDE_IGNORE ((void *)-1)
@@ -288,7 +293,7 @@ typedef struct ide_pci_enablebit_s {
typedef struct ide_pci_device_s {
ide_pci_devid_t devid;
- const char *name;
+ char *name;
unsigned int (*init_chipset)(struct pci_dev *dev, const char *name);
unsigned int (*ata66_check)(ide_hwif_t *hwif);
void (*init_hwif)(ide_hwif_t *hwif);
@@ -307,10 +312,13 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_PIIX4E2, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_PIIX4U, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_PIIX4U2, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_PIIX4NX, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_PIIX4U3, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{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_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 },
{DEVID_SAMURAI, "SAMURAI", NULL, NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
@@ -320,6 +328,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_CMD643, "CMD643", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_CMD646, "CMD646", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 },
{DEVID_CMD648, "CMD648", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_CMD649, "CMD649", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_HT6565, "HT6565", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_OPTI621, "OPTI621", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 },
{DEVID_OPTI621X,"OPTI621X", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 },
@@ -338,6 +347,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{DEVID_CY82C693,"CY82C693", PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_CS5530, "CS5530", PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_AMD7403, "AMD7403", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_AMD7409, "AMD7409", PCI_AMD7409, ATA66_AMD7409, INIT_AMD7409, DMA_AMD7409, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 },
{IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }};
@@ -352,6 +362,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_20267:
case PCI_DEVICE_ID_ARTOP_ATP850UF:
case PCI_DEVICE_ID_ARTOP_ATP860:
case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -510,6 +521,14 @@ check_if_enabled:
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
+
+ if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) {
+ /* see comments in hpt34x.c on why..... */
+ char *chipset_names[] = {"HPT343", "HPT345"};
+ strcpy(d->name, chipset_names[(pcicmd & PCI_COMMAND_MEMORY)]);
+ d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
+ }
+
printk("%s: chipset revision %d\n", d->name, class_rev);
/*
@@ -541,10 +560,7 @@ check_if_enabled:
printk("%s: 100%% native mode on irq %d\n", d->name, pciirq);
#endif
}
- if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) {
- /* see comments in hpt34x.c on why..... */
- d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD;
- }
+
/*
* Set up the IDE ports
*/
@@ -553,14 +569,14 @@ check_if_enabled:
ide_pci_enablebit_t *e = &(d->enablebits[port]);
if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val))
continue; /* port not enabled */
- if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev != 0x03))
+ if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev < 0x03))
return;
if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE || (dev->class & (port ? 4 : 1)) != 0) {
ctl = dev->resource[(2*port)+1].start;
base = dev->resource[2*port].start;
if (!(ctl & PCI_BASE_ADDRESS_IO_MASK) ||
!(base & PCI_BASE_ADDRESS_IO_MASK)) {
- printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@suse.com>.\n", d->name);
+ printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@linux-ide.org>.\n", d->name);
#if 0
/* FIXME! This really should check that it really gets the IO/MEM part right! */
continue;
@@ -603,19 +619,21 @@ check_if_enabled:
goto bypass_umc_dma;
}
if (hwif->udma_four) {
- printk("%s: ATA-66 forced bit set (WARNING)!!\n", d->name);
+ printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name);
} else {
hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0;
}
#ifdef CONFIG_BLK_DEV_IDEDMA
if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_PIIX4NX) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X))
autodma = 0;
if (autodma)
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_PDC20267) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) ||
@@ -625,6 +643,7 @@ check_if_enabled:
IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) ||
((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) {
unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name);
if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
@@ -665,6 +684,7 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic
ide_pci_device_t *d2;
unsigned char pin1 = 0, pin2 = 0;
unsigned int class_rev;
+ char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"};
if (PCI_FUNC(dev->devfn) & 1)
return;
@@ -672,8 +692,13 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
+ strcpy(d->name, chipset_names[class_rev]);
+
switch(class_rev) {
- case 3: return;
+ case 4:
+ case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
+ ide_setup_pci_device(dev, d);
+ return;
default: break;
}
@@ -700,15 +725,6 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic
return;
d2 = d;
printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn);
- if (hpt363_shared_pin && !hpt363_shared_irq) {
- printk("%s: IDE controller run unsupported mode three!!!\n", d2->name);
-#ifndef CONFIG_HPT366_MODE3
- printk("%s: IDE controller report to <andre@suse.com>\n", d->name);
- return;
-#else /* CONFIG_HPT366_MODE3 */
- printk("%s: OVERRIDE IDE controller not advisable this mode!!!\n", d2->name);
-#endif /* CONFIG_HPT366_MODE3 */
- }
ide_setup_pci_device(dev2, d2);
}
diff --git a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c
index 45bbe77ac13096..83cea6ba2bd615 100644
--- a/drivers/ide/ide-pmac.c
+++ b/drivers/ide/ide-pmac.c
@@ -813,12 +813,6 @@ pmac_ide_dma_onoff(ide_drive_t *drive, int enable)
return 0;
}
-static int
-pmac_ide_tune_chipset(ide_drive_t *drive, byte speed)
-{
- return 0;
-}
-
int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index ddf6c8daefa78e..dd5f660fecc88d 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/ide-probe.c Version 1.05 July 3, 1999
+ * linux/drivers/ide/ide-probe.c Version 1.06 June 9, 2000
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/
@@ -7,6 +7,7 @@
/*
* Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il>
+ * and Andre Hedrick <andre@linux-ide.org>
*
* See linux/MAINTAINERS for address of current maintainer.
*
@@ -23,6 +24,7 @@
* added ide6/7/8/9
* allowed for secondary flash card to be detectable
* with new flag : drive->ata_flash : 1;
+ * Version 1.06 stream line request queue and prep for cascade project.
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
@@ -41,6 +43,7 @@
#include <linux/malloc.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/spinlock.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -167,6 +170,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
}
drive->media = ide_disk;
printk("ATA DISK drive\n");
+ QUIRK_LIST(HWIF(drive),drive);
return;
}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index a3394807b16684..932c6f1142f2f9 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/ide.c Version 6.30 Dec 28, 1999
+ * linux/drivers/ide/ide.c Version 6.31 June 9, 2000
*
* Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
*/
@@ -7,6 +7,7 @@
/*
* Mostly written by Mark Lord <mlord@pobox.com>
* and Gadi Oxman <gadio@netvision.net.il>
+ * and Andre Hedrick <andre@linux-ide.org>
*
* See linux/MAINTAINERS for address of current maintainer.
*
@@ -109,6 +110,9 @@
* Version 6.21 Fixing/Fixed SMP spinlock issue with insight from an old
* hat that clarified original low level driver design.
* Version 6.30 Added SMP support; fixed multmode issues. -ml
+ * Version 6.31 Debug Share INTR's and request queue streaming
+ * Native ATA-100 support
+ * Prep for Cascades Project
*
* Some additional driver compile-time options are in ./include/linux/ide.h
*
@@ -117,8 +121,8 @@
*
*/
-#define REVISION "Revision: 6.30"
-#define VERSION "Id: ide.c 6.30 1999/12/28"
+#define REVISION "Revision: 6.31"
+#define VERSION "Id: ide.c 6.31 2000/06/09"
#undef REALLY_SLOW_IO /* most systems can safely undef this */
@@ -482,7 +486,8 @@ static inline int drive_is_ready (ide_drive_t *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 (GET_STAT() & BUSY_STAT) /* Note: this may clear a pending IRQ!! */
+ if (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT)
return 0; /* drive busy: definitely not interrupting */
return 1; /* drive ready: *might* be interrupting */
}
@@ -651,6 +656,19 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
return ide_stopped;
}
+static void check_dma_crc (ide_drive_t *drive)
+{
+ if (drive->crc_count) {
+ (void) HWIF(drive)->dmaproc(ide_dma_off_quietly, drive);
+ if ((HWIF(drive)->speedproc) != NULL)
+ HWIF(drive)->speedproc(drive, ide_auto_reduce_xfer(drive));
+ if (drive->current_speed >= XFER_SW_DMA_0)
+ (void) HWIF(drive)->dmaproc(ide_dma_on, drive);
+ } else {
+ (void) HWIF(drive)->dmaproc(ide_dma_off, drive);
+ }
+}
+
static void pre_reset (ide_drive_t *drive)
{
if (drive->driver != NULL)
@@ -658,12 +676,15 @@ static void pre_reset (ide_drive_t *drive)
if (!drive->keep_settings) {
if (drive->using_dma) {
- (void) HWIF(drive)->dmaproc(ide_dma_off, drive);
+ check_dma_crc(drive);
} else {
drive->unmask = 0;
drive->io_32bit = 0;
}
+ return;
}
+ if (drive->using_dma)
+ check_dma_crc(drive);
}
/*
@@ -902,9 +923,9 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat)
if (err == ABRT_ERR) {
if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY)
return ide_stopped; /* some newer drives don't support WIN_SPECIFY */
- } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR))
- ; /* UDMA crc error -- just retry the operation */
- else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
+ } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) {
+ drive->crc_count++; /* UDMA crc error -- just retry the operation */
+ } else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
rq->errors = ERROR_MAX;
else if (err & TRK0_ERR) /* help it find track zero */
rq->errors |= ERROR_RECAL;
@@ -941,6 +962,7 @@ void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
ide_set_handler (drive, handler, WAIT_CMD, NULL);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
+ SELECT_MASK(HWIF(drive),drive,0);
OUT_BYTE(nsect,IDE_NSECTOR_REG);
OUT_BYTE(cmd,IDE_COMMAND_REG);
}
@@ -1298,7 +1320,7 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
hwif = HWIF(drive);
if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && hwif->io_ports[IDE_CONTROL_OFFSET]) {
/* set nIEN for previous hwif */
- OUT_BYTE(hwgroup->drive->ctl|2, hwgroup->hwif->io_ports[IDE_CONTROL_OFFSET]);
+ SELECT_INTERRUPT(hwif, drive);
}
hwgroup->hwif = hwif;
hwgroup->drive = drive;
@@ -1316,13 +1338,13 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq)
* happens anyway when any interrupt comes in, IDE or otherwise
* -- the kernel masks the IRQ while it is being handled.
*/
- if (hwif->irq != masked_irq)
+ if (masked_irq && hwif->irq != masked_irq)
disable_irq_nosync(hwif->irq);
spin_unlock(&io_request_lock);
ide__sti(); /* allow other IRQs while we start this request */
startstop = start_request(drive);
spin_lock_irq(&io_request_lock);
- if (hwif->irq != masked_irq)
+ if (masked_irq && hwif->irq != masked_irq)
enable_irq(hwif->irq);
if (startstop == ide_stopped)
hwgroup->busy = 0;
@@ -1404,7 +1426,11 @@ void ide_timer_expiry (unsigned long data)
*/
spin_unlock(&io_request_lock);
hwif = HWIF(drive);
+#if DISABLE_IRQ_NOSYNC
+ disable_irq_nosync(hwif->irq);
+#else
disable_irq(hwif->irq); /* disable_irq_nosync ?? */
+#endif /* DISABLE_IRQ_NOSYNC */
__cli(); /* local CPU only, as if we were handling an interrupt */
if (hwgroup->poll_timeout != 0) {
startstop = handler(drive);
@@ -2008,12 +2034,12 @@ void ide_unregister (unsigned int index)
else
hwgroup->hwif = HWIF(hwgroup->drive);
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
if (hwif->dma_base) {
(void) ide_release_dma(hwif);
hwif->dma_base = 0;
}
-#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
+#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
/*
* Remove us from the kernel's knowledge
@@ -2048,6 +2074,10 @@ void ide_unregister (unsigned int index)
hwif->speedproc = old_hwif.speedproc;
hwif->selectproc = old_hwif.selectproc;
hwif->resetproc = old_hwif.resetproc;
+ hwif->intrproc = old_hwif.intrproc;
+ hwif->maskproc = old_hwif.maskproc;
+ hwif->quirkproc = old_hwif.quirkproc;
+ hwif->rwproc = old_hwif.rwproc;
hwif->dmaproc = old_hwif.dmaproc;
hwif->dma_base = old_hwif.dma_base;
hwif->dma_extra = old_hwif.dma_extra;
@@ -2275,17 +2305,18 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive)
unsigned long timeout = jiffies + (3 * HZ);
spin_lock_irq(&io_request_lock);
+
while (hwgroup->busy) {
- unsigned long flags;
+ unsigned long lflags;
spin_unlock_irq(&io_request_lock);
- __save_flags(flags); /* local CPU only */
+ __save_flags(lflags); /* local CPU only */
__sti(); /* local CPU only; needed for jiffies */
if (0 < (signed long)(jiffies - timeout)) {
- __restore_flags(flags);
+ __restore_flags(lflags); /* local CPU only */
printk("%s: channel busy\n", drive->name);
return -EBUSY;
}
- __restore_flags(flags); /* local CPU only */
+ __restore_flags(lflags); /* local CPU only */
spin_lock_irq(&io_request_lock);
}
return 0;
@@ -2422,13 +2453,13 @@ int ide_wait_cmd_task (ide_drive_t *drive, byte *buf)
*/
void ide_delay_50ms (void)
{
-#if 0
+#ifndef CONFIG_BLK_DEV_IDECS
unsigned long timeout = jiffies + ((HZ + 19)/20) + 1;
while (0 < (signed long)(timeout - jiffies));
#else
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/20);
-#endif
+#endif /* CONFIG_BLK_DEV_IDECS */
}
int system_bus_clock (void)
@@ -2576,7 +2607,6 @@ static int ide_ioctl (struct inode *inode, struct file *file,
err = -EFAULT;
return err;
}
-
case HDIO_SCAN_HWIF:
{
int args[3];
@@ -3266,6 +3296,7 @@ void __init ide_init_builtin_drivers (void)
if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) {
ide_get_lock(&ide_lock, NULL, NULL); /* for atari only */
disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */
+// disable_irq_nosync(ide_hwifs[0].irq);
}
#endif /* __mc68000__ || CONFIG_APUS */
@@ -3619,10 +3650,10 @@ void cleanup_module (void)
for (index = 0; index < MAX_HWIFS; ++index) {
ide_unregister(index);
-#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
if (ide_hwifs[index].dma_base)
(void) ide_release_dma(&ide_hwifs[index]);
-#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
+#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
}
#ifdef CONFIG_PROC_FS
@@ -3636,6 +3667,7 @@ void cleanup_module (void)
static int parse_ide_setup (char *line)
{
parse_options(line);
+ /* We MUST return 0 as otherwise no subsequent __setup option works... */
return 0;
}
__setup("", parse_ide_setup);
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 70f1851088d0b4..1837f01e0edff1 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1997-1998 Mark Lord <mlord@pobox.com>
* Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be>
- * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com>
+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
*
* Inspired by an earlier effort from David S. Miller <davem@redhat.com>
*/
diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c
index f16d3392143590..66a12384133ba4 100644
--- a/drivers/ide/pdc202xx.c
+++ b/drivers/ide/pdc202xx.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/ide/pdc202xx.c Version 0.30 Mar. 18, 2000
*
- * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
* Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
@@ -12,6 +12,8 @@
* Promise Ultra66 cards with BIOS v1.11 this
* compiled into the kernel if you have more than one card installed.
*
+ * Promise Ultra100 cards.
+ *
* The latest chipset code will support the following ::
* Three Ultra33 controllers and 12 drives.
* 8 are UDMA supported and 4 are limited to DMA mode 2 multi-word.
@@ -51,6 +53,10 @@
#define DISPLAY_PDC202XX_TIMINGS
+#ifndef SPLIT_BYTE
+#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
+#endif
+
#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
@@ -99,10 +105,25 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
{
char *p = buffer;
- u32 bibma = bmide_dev->resource[4].start;
+ u32 bibma = pci_resource_start(bmide_dev, 4);
u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0;
u16 reg50h = 0, pmask = (1<<10), smask = (1<<11);
- u8 c0 = 0, c1 = 0;
+ u8 hi = 0, lo = 0;
+
+ /*
+ * at that point bibma+0x2 et bibma+0xa are byte registers
+ * to investigate:
+ */
+ u8 c0 = inb_p((unsigned short)bibma + 0x02);
+ u8 c1 = inb_p((unsigned short)bibma + 0x0a);
+
+ u8 sc11 = inb_p((unsigned short)bibma + 0x11);
+ u8 sc1a = inb_p((unsigned short)bibma + 0x1a);
+ u8 sc1b = inb_p((unsigned short)bibma + 0x1b);
+ u8 sc1c = inb_p((unsigned short)bibma + 0x1c);
+ u8 sc1d = inb_p((unsigned short)bibma + 0x1d);
+ 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);
@@ -110,14 +131,10 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
pci_read_config_dword(bmide_dev, 0x68, &reg68h);
pci_read_config_dword(bmide_dev, 0x6c, &reg6ch);
- /*
- * at that point bibma+0x2 et bibma+0xa are byte registers
- * to investigate:
- */
- c0 = inb_p((unsigned short)bibma + 0x02);
- c1 = inb_p((unsigned short)bibma + 0x0a);
-
- switch(bmide_dev->device) {
+ switch(bmide_dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20267:
+ p += sprintf(p, "\n PDC20267 Chipset.\n");
+ break;
case PCI_DEVICE_ID_PROMISE_20262:
p += sprintf(p, "\n PDC20262 Chipset.\n");
break;
@@ -130,9 +147,40 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
break;
}
+ p += sprintf(p, "------------------------------- General Status ---------------------------------\n");
+ p += sprintf(p, "Burst Mode : %sabled\n", (sc1f & 0x01) ? "en" : "dis");
+ p += sprintf(p, "Host Mode : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal");
+ p += sprintf(p, "Bus Clocking : %s\n",
+ ((sc1f & 0xC0) == 0xC0) ? "100 External" :
+ ((sc1f & 0x80) == 0x80) ? "66 External" :
+ ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal");
+ p += sprintf(p, "IO pad select : %s mA\n",
+ ((sc1c & 0x03) == 0x03) ? "10" :
+ ((sc1c & 0x02) == 0x02) ? "8" :
+ ((sc1c & 0x01) == 0x01) ? "6" :
+ ((sc1c & 0x00) == 0x00) ? "4" : "??");
+ SPLIT_BYTE(sc1e, hi, lo);
+ p += sprintf(p, "Status Polling Period : %d\n", hi);
+ p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo);
p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
- p += sprintf(p, " %sabled %sabled\n",
- (c0&0x80)?"dis":" en",(c1&0x80)?"dis":" en");
+ p += sprintf(p, " %s %s\n",
+ (c0&0x80)?"disabled":"enabled ",
+ (c1&0x80)?"disabled":"enabled ");
+ p += sprintf(p, "66 Clocking %s %s\n",
+ (sc11&0x02)?"enabled ":"disabled",
+ (sc11&0x08)?"enabled ":"disabled");
+ p += sprintf(p, " Mode %s Mode %s\n",
+ (sc1a & 0x01) ? "MASTER" : "PCI ",
+ (sc1b & 0x01) ? "MASTER" : "PCI ");
+ p += sprintf(p, " %s %s\n",
+ (sc1d & 0x08) ? "Error " :
+ (sc1d & 0x04) ? "Interrupting" :
+ (sc1d & 0x02) ? "FIFO Full " :
+ (sc1d & 0x01) ? "FIFO Empty " : "????????????",
+ (sc1d & 0x80) ? "Error " :
+ (sc1d & 0x40) ? "Interrupting" :
+ (sc1d & 0x20) ? "FIFO Full " :
+ (sc1d & 0x10) ? "FIFO Empty " : "????????????");
p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
p += sprintf(p, "DMA enabled: %s %s %s %s\n",
(c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no ");
@@ -141,9 +189,13 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)),
pdc202xx_ultra_verbose(reg68h, (reg50h & smask)),
pdc202xx_ultra_verbose(reg6ch, (reg50h & smask)));
- p += sprintf(p, " PIO Mode: %s %s %s %s\n",
+ p += sprintf(p, "PIO Mode: %s %s %s %s\n",
pdc202xx_pio_verbose(reg60h),pdc202xx_pio_verbose(reg64h),
pdc202xx_pio_verbose(reg68h),pdc202xx_pio_verbose(reg6ch));
+#if 0
+ p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n");
+#endif
+
return p-buffer; /* => must be less than 4k! */
}
#endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
@@ -324,6 +376,7 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed)
switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
+ case XFER_UDMA_5:
case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; /* speed 8 == UDMA mode 4 */
case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; /* speed 7 == UDMA mode 3 */
case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; /* speed 6 == UDMA mode 2 */
@@ -408,7 +461,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK;
+ unsigned long high_16 = pci_resource_start(dev, 4);
unsigned long dma_base = hwif->dma_base;
byte unit = (drive->select.b.unit & 0x01);
@@ -418,8 +471,9 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
byte AP;
unsigned short EP;
byte CLKSPD = IN_BYTE(high_16 + 0x11);
- byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
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;
/*
* Set the control register to use the 66Mhz system
@@ -436,11 +490,15 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
byte mask = hwif->channel ? 0x08 : 0x02;
unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10);
- byte ultra_66 = ((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008)) ? 1 : 0;
+ byte ultra_66 = ((id->dma_ultra & 0x0010) ||
+ (id->dma_ultra & 0x0008)) ? 1 : 0;
+ byte ultra_100 = ((id->dma_ultra & 0x0020) ||
+ (id->dma_ultra & 0x0010) ||
+ (id->dma_ultra & 0x0008)) ? 1 : 0;
pci_read_config_word(dev, 0x50, &EP);
- if ((ultra_66) && (EP & c_mask)) {
+ if (((ultra_66) || (ultra_100)) && (EP & c_mask)) {
#ifdef DEBUG
printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary", "Primary");
printk(" Switching to Ultra33 mode.\n");
@@ -449,13 +507,14 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
/* Secondary : zero out fourth bit */
OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
} else {
- if (ultra_66) {
+ if ((ultra_66) || (ultra_100)) {
/*
* check to make sure drive on same channel
* is u66 capable
*/
if (hwif->drives[!(drive->dn%2)].id) {
- if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) ||
+ if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) ||
+ (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) ||
(hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) {
OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
} else {
@@ -517,17 +576,18 @@ chipset_is_set:
if (drive->media == ide_disk) /* PREFETCH_EN */
pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
- if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) speed = XFER_UDMA_4;
- else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) speed = XFER_UDMA_3;
- else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2;
- else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1;
- else if ((id->dma_ultra & 0x0001) && (udma_33)) speed = XFER_UDMA_0;
- else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2;
- else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1;
- else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0;
- else if (id->dma_1word & 0x0004) speed = XFER_SW_DMA_2;
- else if (id->dma_1word & 0x0002) speed = XFER_SW_DMA_1;
- else if (id->dma_1word & 0x0001) speed = XFER_SW_DMA_0;
+ if ((id->dma_ultra & 0x0020) && (udma_100)) speed = XFER_UDMA_5;
+ else if ((id->dma_ultra & 0x0010) && (udma_66)) speed = XFER_UDMA_4;
+ else if ((id->dma_ultra & 0x0008) && (udma_66)) speed = XFER_UDMA_3;
+ else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2;
+ else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1;
+ else if ((id->dma_ultra & 0x0001) && (udma_33)) speed = XFER_UDMA_0;
+ else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2;
+ else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1;
+ else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0;
+ else if (id->dma_1word & 0x0004) speed = XFER_SW_DMA_2;
+ else if (id->dma_1word & 0x0002) speed = XFER_SW_DMA_1;
+ else if (id->dma_1word & 0x0001) speed = XFER_SW_DMA_0;
else {
/* restore original pci-config space */
pci_write_config_dword(dev, drive_pci, drive_conf);
@@ -537,7 +597,7 @@ chipset_is_set:
outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
(void) pdc202xx_tune_chipset(drive, speed);
- return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
((id->dma_1word >> 8) & 7) ? ide_dma_on :
@@ -558,7 +618,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
- if (id->dma_ultra & 0x001F) {
+ if (id->dma_ultra & 0x002F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive, 1);
if ((id->field_valid & 2) &&
@@ -603,6 +663,10 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
+ case ide_dma_lostirq:
+ case ide_dma_timeout:
+ if (HWIF(drive)->resetproc != NULL)
+ HWIF(drive)->resetproc(drive);
default:
break;
}
@@ -610,14 +674,29 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
+void pdc202xx_reset (ide_drive_t *drive)
+{
+ unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4);
+ byte udma_speed_flag = inb(high_16 + 0x001f);
+ int i = 0;
+
+ OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
+ ide_delay_50ms();
+ ide_delay_50ms();
+ OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
+ for (i = 0; i < 40; i++)
+ ide_delay_50ms();
+}
+
unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
{
- unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK;
+ unsigned long high_16 = pci_resource_start(dev, 4);
byte udma_speed_flag = inb(high_16 + 0x001f);
byte primary_mode = inb(high_16 + 0x001a);
byte secondary_mode = inb(high_16 + 0x001b);
- if (dev->device == PCI_DEVICE_ID_PROMISE_20262) {
+ if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
+ (dev->device == PCI_DEVICE_ID_PROMISE_20267)) {
int i = 0;
/*
* software reset - this is required because the bios
@@ -646,7 +725,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) {
+ if ((irq != irq2) && (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);
}
@@ -705,8 +784,12 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif)
void __init ide_init_pdc202xx (ide_hwif_t *hwif)
{
- hwif->tuneproc = &pdc202xx_tune_drive;
- hwif->speedproc = &pdc202xx_tune_chipset;
+ hwif->tuneproc = &pdc202xx_tune_drive;
+ hwif->speedproc = &pdc202xx_tune_chipset;
+
+ if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) ||
+ (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267))
+ hwif->resetproc = &pdc202xx_reset;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index 56c1852361d43b..0dbb8d88382bf5 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -1,8 +1,8 @@
/*
- * linux/drivers/ide/piix.c Version 0.31 Mar. 18, 2000
+ * linux/drivers/ide/piix.c Version 0.32 June 9, 2000
*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
- * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
* PIO mode setting function for Intel chipsets.
@@ -83,7 +83,7 @@ static struct pci_dev *bmide_dev;
static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
- u32 bibma = bmide_dev->resource[4].start;
+ u32 bibma = pci_resource_start(bmide_dev, 4);
u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0;
u8 c0 = 0, c1 = 0;
u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0;
@@ -108,10 +108,14 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
c1 = inb_p((unsigned short)bibma + 0x0a);
switch(bmide_dev->device) {
+ case PCI_DEVICE_ID_INTEL_82820FW_5:
+ p += sprintf(p, "\n Intel PIIX4 Ultra 100 Chipset.\n");
+ break;
case PCI_DEVICE_ID_INTEL_82372FB_1:
case PCI_DEVICE_ID_INTEL_82801AA_1:
p += sprintf(p, "\n Intel PIIX4 Ultra 66 Chipset.\n");
break;
+ case PCI_DEVICE_ID_INTEL_82451NX:
case PCI_DEVICE_ID_INTEL_82801AB_1:
case PCI_DEVICE_ID_INTEL_82443MX_1:
case PCI_DEVICE_ID_INTEL_82371AB:
@@ -142,21 +146,25 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
(reg48&0x04) ? "yes" : "no ",
(reg48&0x08) ? "yes" : "no " );
p += sprintf(p, "UDMA enabled: %s %s %s %s\n",
+ ((reg54&0x11) && (reg55&0x10) && (reg4a&0x01)) ? "5" :
((reg54&0x11) && (reg4a&0x02)) ? "4" :
((reg54&0x11) && (reg4a&0x01)) ? "3" :
(reg4a&0x02) ? "2" :
(reg4a&0x01) ? "1" :
(reg4a&0x00) ? "0" : "X",
+ ((reg54&0x22) && (reg55&0x20) && (reg4a&0x10)) ? "5" :
((reg54&0x22) && (reg4a&0x20)) ? "4" :
((reg54&0x22) && (reg4a&0x10)) ? "3" :
(reg4a&0x20) ? "2" :
(reg4a&0x10) ? "1" :
(reg4a&0x00) ? "0" : "X",
+ ((reg54&0x44) && (reg55&0x40) && (reg4b&0x03)) ? "5" :
((reg54&0x44) && (reg4b&0x02)) ? "4" :
((reg54&0x44) && (reg4b&0x01)) ? "3" :
(reg4b&0x02) ? "2" :
(reg4b&0x01) ? "1" :
(reg4b&0x00) ? "0" : "X",
+ ((reg54&0x88) && (reg55&0x80) && (reg4b&0x30)) ? "5" :
((reg54&0x88) && (reg4b&0x20)) ? "4" :
((reg54&0x88) && (reg4b&0x10)) ? "3" :
(reg4b&0x20) ? "2" :
@@ -188,6 +196,7 @@ extern char *ide_xfer_verbose (byte xfer_rate);
*/
static byte piix_dma_2_pio (byte xfer_rate) {
switch(xfer_rate) {
+ case XFER_UDMA_5:
case XFER_UDMA_4:
case XFER_UDMA_3:
case XFER_UDMA_2:
@@ -286,6 +295,7 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed)
switch(speed) {
case XFER_UDMA_4:
case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
+ case XFER_UDMA_5:
case XFER_UDMA_3:
case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
@@ -298,7 +308,11 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed)
if (speed >= XFER_UDMA_0) {
if (!(reg48 & u_flag))
pci_write_config_word(dev, 0x48, reg48|u_flag);
- pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag);
+ if (speed == XFER_UDMA_5) {
+ pci_write_config_byte(dev, 0x55, (byte) reg55|w_flag);
+ } else {
+ pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag);
+ }
if (!(reg4a & u_speed)) {
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
pci_write_config_word(dev, 0x4a, reg4a|u_speed);
@@ -341,15 +355,20 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
struct pci_dev *dev = hwif->pci_dev;
byte speed;
- byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
- int ultra66 = ((dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ||
+ byte udma_66 = eighty_ninty_three(drive);
+ int ultra100 = ((dev->device == PCI_DEVICE_ID_INTEL_82820FW_5)) ? 1 : 0;
+ int ultra66 = ((ultra100) ||
+ (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) ||
(dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0;
int ultra = ((ultra66) ||
(dev->device == PCI_DEVICE_ID_INTEL_82371AB) ||
(dev->device == PCI_DEVICE_ID_INTEL_82443MX_1) ||
+ (dev->device == PCI_DEVICE_ID_INTEL_82451NX) ||
(dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0;
- if ((id->dma_ultra & 0x0010) && (ultra)) {
+ if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) {
+ speed = XFER_UDMA_5;
+ } else if ((id->dma_ultra & 0x0010) && (ultra)) {
speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2;
} else if ((id->dma_ultra & 0x0008) && (ultra)) {
speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1;
@@ -371,7 +390,7 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
(void) piix_tune_chipset(drive, speed);
- return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
((id->dma_1word >> 8) & 7) ? ide_dma_on :
diff --git a/drivers/ide/qd6580.c b/drivers/ide/qd6580.c
index 4c00de5042f13e..5787b73f21a470 100644
--- a/drivers/ide/qd6580.c
+++ b/drivers/ide/qd6580.c
@@ -1,16 +1,19 @@
/*
- * linux/drivers/ide/qd6580.c Version 0.03 May 13, 2000
+ * linux/drivers/ide/qd6580.c Version 0.04 June 4, 2000
*
* Copyright (C) 1996-2000 Linus Torvalds & author (see below)
*/
/*
* Version 0.03 Cleaned auto-tune, added probe
- *
+ * Version 0.04 Added second channel tuning
+ *
* QDI QD6580 EIDE controller fast support
- *
+ *
* To activate controller support use kernel parameter "ide0=qd6580"
* To enable tuning use kernel parameter "ide0=autotune"
+ * To enable tuning second channel (not really tested),
+ * use parameter "ide1=autotune"
*/
/*
@@ -36,146 +39,254 @@
#include "ide_modes.h"
/*
- * I/O ports are 0xb0 0xb1 0xb2 and 0xb3
- * or 0x30 0x31 0x32 and 0x33
+ * I/O ports are 0xb0-0xb3
+ * or 0x30-0x33
* -- this is a dual IDE interface with I/O chips
*
* More research on qd6580 being done by willmore@cig.mot.com (David)
+ * More Information given by Petr Sourcek (petr@ryston.cz)
+ * http://www.ryston.cz/petr/vlb
*/
-/*
+/*
* 0xb0: Timer1
*
- *
- * 0xb1: Status
*
- * && 0xf0 is either 0b1010000 or 0b01010000, or else it isn't a qd6580
- * bit 3 & 2: unknown (useless ?) I have 0 & 1, respectively
- * bit 1: 1 if qd6580 baseport is 0xb0
- * 0 if qd6580 baseport is 0x30
- * bit 0: 1 if ide baseport is 0x1f0
- * 0 if ide baseport is 0x170
+ * 0xb1: Config
+ *
+ * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170
* (? Strange: the Dos driver uses it, and then forces baseport to 0x1f0 ?)
- *
- *
+ * bit 1: qd baseport: 1 = 0xb0 ; 0 = 0x30
+ * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
+ * bit 3: 1 for qd6580
+ * upper nibble is either 1010 or 0101, or else it isn't a qd6580
+ *
+ *
* 0xb2: Timer2
*
- *
+ *
* 0xb3: Control
*
- * bits 0-3 are always set 1
- * bit 6 : if 1, must be set 1
- * bit 1 : if 1, bit 7 must be set 1
- * bit 0 : if 1, drives are independant, we can have two different timers for
- * the two drives.
- * if 0, we have to take the slowest drive into account,
- * but we may tune the second hwif ?
+ * bits 0-3 must always be set 1
+ * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
+ * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
+ * 0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
+ * channel 1 for hdc & hdd
+ * bit 1 : 1 = only disks on primary port
+ * 0 = disks & ATAPI devices on primary port
+ * bit 2-4 : always 0
+ * bit 5 : status, but of what ?
+ * bit 6 : always set 1 by dos driver
+ * bit 7 : set 1 for non-ATAPI devices (read-ahead and post-write buffer ?)
*/
+/* truncates a in [b,c] */
+#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
+
typedef struct ide_hd_timings_s {
int active_time; /* Active pulse (ns) minimum */
int recovery_time; /* Recovery pulse (ns) minimum */
} ide_hd_timings_t;
static int basePort; /* base port address (0x30 or 0xb0) */
-static byte status; /* status register of qd6580 */
+static byte config; /* config register of qd6580 */
static byte control; /* control register of qd6580 */
-/* truncates a in [b,c] */
-#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
-
static int bus_clock; /* Vesa local bus clock (ns) */
static int tuned=0; /* to remember whether we've already been tuned */
+static int snd_tuned=0; /* to remember whether we've already been tuned */
+static int nb_disks_prim=0; /* number of disk drives on primary port */
+
+/*
+ * write_reg
+ *
+ * writes the specified byte on the specified register
+ */
+
+static void write_reg ( byte content, byte reg )
+{
+ unsigned long flags;
+
+ save_flags(flags); /* all CPUs */
+ cli(); /* all CPUs */
+ outb_p(content,reg);
+ inb(0x3f6);
+ restore_flags(flags); /* all CPUs */
+}
/*
* tune_drive
*
- * Finds timings for the specified drive, returns it in struc t
+ * Finds timings for the specified drive, returns it in struct t
*/
-static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t)
+static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
{
ide_pio_data_t d;
- t->active_time = 0xaf;
- t->recovery_time = 0x19f; /* worst cases values from the dos driver */
+ t->active_time = 175;
+ t->recovery_time = 415; /* worst cases values from the dos driver */
- if (drive->present == 0) { /* not present : free to give any timing */
- t->active_time = 0x0;
- t->recovery_time = 0x0;
+ if (!drive->present) { /* not present : free to give any timing */
+ t->active_time = 0;
+ t->recovery_time = 0;
return;
}
-
- pio = ide_get_best_pio_mode(drive, pio, 4, &d);
-
- if (pio) {
-
- switch (pio) {
- case 0: break;
- case 3: t->active_time = 0x56;
- t->recovery_time = d.cycle_time-0x66;
- break;
- case 4: t->active_time = 0x46;
- t->recovery_time = d.cycle_time-0x3d;
- break;
- default: if (d.cycle_time >= 0xb4) {
- t->active_time = 0x6e;
- t->recovery_time = d.cycle_time - 0x78;
- } else {
- t->active_time = ide_pio_timings[pio].active_time;
- t->recovery_time = d.cycle_time
- -t->active_time
- -ide_pio_timings[pio].setup_time;
- }
- }
- }
+
+ pio = ide_get_best_pio_mode(drive, pio, 255, &d);
+ pio = IDE_MIN(pio,4);
+
+ switch (pio) {
+ case 0: break;
+ case 3:
+ if (d.cycle_time >= 110) {
+ t->active_time = 86;
+ t->recovery_time = d.cycle_time-102;
+ } else {
+ printk("%s: Strange recovery time !\n",drive->name);
+ return;
+ }
+ break;
+ case 4:
+ if (d.cycle_time >= 69) {
+ t->active_time = 70;
+ t->recovery_time = d.cycle_time-61;
+ } else {
+ printk("%s: Strange recovery time !\n",drive->name);
+ return;
+ }
+ break;
+ default:
+ if (d.cycle_time >= 180) {
+ t->active_time = 110;
+ t->recovery_time = d.cycle_time - 120;
+ } else {
+ t->active_time = ide_pio_timings[pio].active_time;
+ t->recovery_time = d.cycle_time
+ -t->active_time;
+ }
+ }
printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
+
+ if (drive->media == ide_disk)
+ nb_disks_prim++;
+ else {
+/* need to disable read-ahead FIFO and post-write buffer for ATAPI drives*/
+ write_reg(0x5f,basePort+0x03);
+ printk("%s: Warning: please try to connect this drive to secondary IDE port\nto improve data transfer rate on primary IDE port.\n",drive->name);
+ }
}
-/*
+/*
+ * tune_snd_drive
+ *
+ * Finds timings for the specified drive, using second channel rules
+ */
+
+static void tune_snd_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
+{
+ ide_pio_data_t d;
+
+ t->active_time = 175;
+ t->recovery_time = 415;
+
+ if (!drive->present) { /* not present : free to give any timing */
+ t->active_time = 0;
+ t->recovery_time = 0;
+ return;
+ }
+
+ pio = ide_get_best_pio_mode(drive, pio, 255, &d);
+
+ if ((pio) && (d.cycle_time >= 180)) {
+ t->active_time = 115;
+ t->recovery_time = d.cycle_time - 115;
+ }
+ printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
+
+ if ((drive->media == ide_disk) && (nb_disks_prim<2)) {
+/* a disk drive on secondary port while there's room on primary, which is the
+ * only one that has read-ahead fifo and post-write buffer ? What a waste !*/
+ printk("%s: Warning: please try to connect this drive to primary IDE port\nto improve data transfer rate.\n",drive->name);
+ }
+}
+
+/*
+ * compute_timing
+ *
+ * computes the timing value where
+ * lower nibble is active time, in count of VLB clocks, 17-(from 2 to 17)
+ * upper nibble is recovery time, in count of VLB clocks, 15-(from 2 to 15)
+ */
+
+static byte compute_timing ( char name[6], ide_hd_timings_t *t )
+{
+ byte active_cycle;
+ byte recovery_cycle;
+ byte parameter;
+
+ active_cycle = 17-IDE_IN(t->active_time / bus_clock + 1, 2, 17);
+ recovery_cycle = 15-IDE_IN(t->recovery_time / bus_clock + 1, 2, 15);
+
+ parameter = active_cycle | (recovery_cycle<<4);
+
+ printk("%s: tim1=%dns tim2=%dns => %#x\n", name, t[0].active_time, t[0].recovery_time, parameter);
+ return(parameter);
+}
+
+/*
* tune_ide
*
- * Tunes the whole ide, ie tunes each drives, and takes the worst timings
- * to tune qd6580
+ * Tunes the whole hwif, ie tunes each drives, and in case we have to share,
+ * takes the worse timings to tune qd6580
*/
static void tune_ide ( ide_hwif_t *hwif, byte pio )
{
unsigned long flags;
ide_hd_timings_t t[2]={{0,0},{0,0}};
-
- byte active_cycle;
- byte recovery_cycle;
- byte parameter;
int bus_speed = ide_system_bus_speed ();
-
+
bus_clock = 1000 / bus_speed;
-
+
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
outb( (bus_clock<30) ? 0x0 : 0x0a, basePort + 0x02);
outb( 0x40 | ((control & 0x02) ? 0x9f:0x1f), basePort+0x03);
- restore_flags(flags);
+ restore_flags(flags);
tune_drive (&hwif->drives[0], pio, &t[0]);
tune_drive (&hwif->drives[1], pio, &t[1]);
+ if (control & 0x01) { /* only primary port enabled, can tune separately */
+ write_reg(compute_timing (hwif->drives[0].name, &t[0]),basePort);
+ write_reg(compute_timing (hwif->drives[1].name, &t[1]),basePort+0x02);
+ } else { /* both ports enabled, we have to share */
+
+ t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time);
+ t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
+ write_reg(compute_timing (hwif->name, &t[0]),basePort);
+ }
+}
+
+/*
+ * tune_snd_ide
+ *
+ * Tunes the whole secondary hwif, ie tunes each drives, and takes the worse
+ * timings to tune qd6580
+ */
+
+static void tune_snd_ide ( ide_hwif_t *hwif, byte pio )
+{
+ ide_hd_timings_t t[2]={{0,0},{0,0}};
+
+ tune_snd_drive (&hwif->drives[0], pio, &t[0]);
+ tune_snd_drive (&hwif->drives[1], pio, &t[1]);
+
t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time);
t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
-
- active_cycle = 17-IDE_IN(t[0].active_time / bus_clock + 1, 2, 17);
- recovery_cycle = 15-IDE_IN(t[0].recovery_time / bus_clock + 1, 2, 15);
-
- parameter=active_cycle | (recovery_cycle<<4);
-
- printk("%s: tim1=%dns tim2=%dns => %#x\n", hwif->name, t[0].active_time, t[0].recovery_time, parameter);
-
- save_flags(flags); /* all CPUs */
- cli(); /* all CPUs */
- outb_p(parameter,0xb0);
- inb(0x3f6);
- restore_flags(flags); /* all CPUs */
-
+
+ write_reg(compute_timing (hwif->name, &t[0]),basePort+0x02);
}
/*
@@ -193,6 +304,20 @@ static void tune_qd6580 (ide_drive_t *drive, byte pio)
}
/*
+ * tune_snd_qd6580
+ *
+ * tunes the second hwif if not tuned
+ */
+
+static void tune_snd_qd6580 (ide_drive_t *drive, byte pio)
+{
+ if (! snd_tuned) {
+ tune_snd_ide(HWIF(drive), pio);
+ snd_tuned = 1;
+ }
+}
+
+/*
* testreg
*
* tests if the given port is a register
@@ -203,7 +328,7 @@ static int __init testreg(int port)
byte savereg;
byte readreg;
unsigned long flags;
-
+
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
savereg = inb(port);
@@ -214,14 +339,15 @@ static int __init testreg(int port)
if (savereg == 0x15) {
printk("Outch ! the probe for qd6580 isn't reliable !\n");
- printk("Please contact samuel.thibault@fnac.net to tell about your hardware\n");
- printk("Assuming qd6580 is present");
+ printk("Please contact maintainers to tell about your hardware\n");
+ printk("Assuming qd6580 is not present.\n");
+ return 0;
}
return (readreg == 0x15);
}
-/*
+/*
* trybase:
*
* tries to find a qd6580 at the given base and save it if found
@@ -233,20 +359,20 @@ static int __init trybase (int base)
save_flags(flags); /* all CPUs */
cli(); /* all CPUs */
- status = inb(base+0x01);
+ config = inb(base+0x01);
control = inb(base+0x03);
restore_flags(flags); /* all CPUs */
- if (((status & 0xf0) != 0x50) && ((status & 0xf0) != 0xa0)) return(0);
- if (! ( ((status & 0x02) == 0x0) == (base == 0x30) ) ) return (0);
+ if (((config & 0xf0) != 0x50) && ((config & 0xf0) != 0xa0)) return(0);
+ if (! ( ((config & 0x02) == 0x0) == (base == 0x30) ) ) return (0);
/* Seems to be OK, let's use it */
-
+
basePort = base;
return(testreg(base));
}
-/*
+/*
* probe:
*
* probes qd6580 at 0xb0 (the default) or 0x30
@@ -257,6 +383,11 @@ static int __init probe (void)
return (trybase(0xb0) ? 1 : trybase(0x30));
}
+/*
+ * init_qd6580:
+ *
+ * called at the very beginning of initialization ; should just probe and link
+ */
void __init init_qd6580 (void)
{
@@ -264,13 +395,16 @@ void __init init_qd6580 (void)
printk("qd6580: not found\n");
return;
}
-
- printk("qd6580: base=%#x, status=%#x, control=%#x\n", basePort, status, control);
-
+
+ printk("qd6580: base=%#x, config=%#x, control=%#x\n", basePort, config, control);
+
ide_hwifs[0].chipset = ide_qd6580;
- ide_hwifs[1].chipset = ide_qd6580;
ide_hwifs[0].tuneproc = &tune_qd6580;
- ide_hwifs[0].mate = &ide_hwifs[1];
- ide_hwifs[1].mate = &ide_hwifs[0];
- ide_hwifs[1].channel = 1;
+ if (!(control & 0x01)) {
+ ide_hwifs[1].chipset = ide_qd6580;
+ ide_hwifs[1].tuneproc = &tune_snd_qd6580;
+ ide_hwifs[0].mate = &ide_hwifs[1];
+ ide_hwifs[1].mate = &ide_hwifs[0];
+ ide_hwifs[1].channel = 1;
+ }
}
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index be56a7f2489ac4..4f0a330863e618 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/ide/sis5513.c Version 0.10 Mar. 18, 2000
+ * linux/drivers/ide/sis5513.c Version 0.11 June 9, 2000
*
- * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
* Thanks to SIS Taiwan for direct support and hardware.
@@ -111,12 +111,12 @@ static int sis_get_info(char *, char **, off_t, int);
extern int (*sis_display_info)(char *, char **, off_t, int); /* ide-proc.c */
static struct pci_dev *bmide_dev;
-static char *cable_type[] __initdata = {
+static char *cable_type[] = {
"80 pins",
"40 pins"
};
-static char *recovery_time [] __initdata ={
+static char *recovery_time [] ={
"12 PCICLK", "1 PCICLK",
"2 PCICLK", "3 PCICLK",
"4 PCICLK", "5 PCICLCK",
@@ -127,14 +127,14 @@ static char *recovery_time [] __initdata ={
"15 PCICLK", "15 PCICLK"
};
-static char * cycle_time [] __initdata = {
+static char * cycle_time [] = {
"Undefined", "2 CLCK",
"3 CLK", "4 CLK",
"5 CLK", "6 CLK",
"7 CLK", "8 CLK"
};
-static char * active_time [] __initdata = {
+static char * active_time [] = {
"8 PCICLK", "1 PCICLCK",
"2 PCICLK", "2 PCICLK",
"4 PCICLK", "5 PCICLK",
@@ -185,7 +185,7 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
- active_time[(reg & 0x07)], active_time[(reg &0x07)] );
+ active_time[(reg & 0x07)], active_time[(reg1 &0x07)] );
rc = pci_read_config_byte(bmide_dev, 0x40, &reg);
rc = pci_read_config_byte(bmide_dev, 0x44, &reg1);
@@ -209,7 +209,7 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
- active_time[(reg & 0x07)], active_time[(reg &0x07)] );
+ active_time[(reg & 0x07)], active_time[(reg1 &0x07)] );
rc = pci_read_config_byte(bmide_dev, 0x42, &reg);
rc = pci_read_config_byte(bmide_dev, 0x46, &reg1);
@@ -335,7 +335,7 @@ static void sis5513_tune_drive (ide_drive_t *drive, byte pio)
#ifdef CONFIG_BLK_DEV_IDEDMA
/*
- * ((id->hw_config & 0x2000) && (HWIF(drive)->udma_four))
+ * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four))
*/
static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
{
@@ -349,7 +349,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
unsigned long dma_base = hwif->dma_base;
byte unit = (drive->select.b.unit & 0x01);
byte speed = 0x00, unmask = 0xE0, four_two = 0x00;
- byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
+ byte udma_66 = eighty_ninty_three(drive);
if (host_dev) {
switch(host_dev->device) {
@@ -536,7 +536,7 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
pci_read_config_byte(dev, 0x52, &reg52h);
if (!(reg52h & 0x04)) {
- /* set IDE controller to operate in Compabitility mode obly */
+ /* set IDE controller to operate in Compabitility mode only */
pci_write_config_byte(dev, 0x52, reg52h|0x04);
}
#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index e7ee2e9777b224..c1aa3fb4eddcaa 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -224,10 +224,10 @@ void __init ide_init_trm290 (ide_hwif_t *hwif)
struct pci_dev *dev = hwif->pci_dev;
hwif->chipset = ide_trm290;
- cfgbase = dev->resource[4].start;
+ cfgbase = pci_resource_start(dev, 4);
if ((dev->class & 5) && cfgbase)
{
- hwif->config_data = cfgbase & PCI_BASE_ADDRESS_IO_MASK;
+ hwif->config_data = cfgbase;
printk("TRM290: chip config base at 0x%04lx\n", hwif->config_data);
} else {
hwif->config_data = 0x3df0;
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 6c201599f81f84..3ab29859669473 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -1,10 +1,10 @@
/*
- * linux/drivers/ide/via82cxxx.c Version 0.09 Apr. 02, 2000
+ * linux/drivers/ide/via82cxxx.c Version 0.10 June 9, 2000
*
* Copyright (C) 1998-99 Michel Aubry, Maintainer
* Copyright (C) 1999 Jeff Garzik, MVP4 Support
* (jgarzik@mandrakesoft.com)
- * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com)
+ * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
* The VIA MVP-4 is reported OK with UDMA.
@@ -101,19 +101,19 @@ static struct pci_dev *isa_dev = NULL;
struct chipset_bus_clock_list_entry {
byte xfer_speed;
- byte chipset_settings_25;
byte ultra_settings_25;
- byte chipset_settings_33;
+ byte chipset_settings_25;
byte ultra_settings_33;
- byte chipset_settings_37;
+ byte chipset_settings_33;
byte ultra_settings_37;
- byte chipset_settings_41;
+ byte chipset_settings_37;
byte ultra_settings_41;
+ byte chipset_settings_41;
};
static struct chipset_bus_clock_list_entry * via82cxxx_table = NULL;
-struct chipset_bus_clock_list_entry via82cxxx_type_one [] = {
+static struct chipset_bus_clock_list_entry via82cxxx_type_one [] = {
/* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
#ifdef CONFIG_BLK_DEV_IDEDMA
{ XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -134,7 +134,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_one [] = {
{ 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xA9, 0x00, 0x00 }
};
-struct chipset_bus_clock_list_entry via82cxxx_type_two [] = {
+static struct chipset_bus_clock_list_entry via82cxxx_type_two [] = {
/* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
#ifdef CONFIG_BLK_DEV_IDEDMA
{ XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -155,7 +155,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_two [] = {
{ 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE }
};
-struct chipset_bus_clock_list_entry via82cxxx_type_three [] = {
+static struct chipset_bus_clock_list_entry via82cxxx_type_three [] = {
/* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
#ifdef CONFIG_BLK_DEV_IDEDMA
{ XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -176,7 +176,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_three [] = {
{ 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE }
};
-struct chipset_bus_clock_list_entry via82cxxx_type_four [] = {
+static struct chipset_bus_clock_list_entry via82cxxx_type_four [] = {
/* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
#ifdef CONFIG_BLK_DEV_IDEDMA
{ XFER_UDMA_4, 0x00, 0x00, 0xE0, 0x20, 0xE1, 0x31, 0x00, 0x00 },
@@ -243,20 +243,20 @@ static const struct {
#define arraysize(x) (sizeof(x)/sizeof(*(x)))
-#undef DISPLAY_VIA_TIMINGS
+#define DISPLAY_VIA_TIMINGS
#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
-static char *FIFO_str[] __initdata = {
+static char *FIFO_str[] = {
" 1 ",
"3/4",
"1/2",
"1/4"
};
-static char *control3_str[] __initdata = {
+static char *control3_str[] = {
"No limitation",
"64",
"128",
@@ -760,11 +760,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
byte speed = 0x00;
+ byte ultra66 = eighty_ninty_three(drive);
+ byte ultra100 = 0;
int rval;
- if ((id->dma_ultra & 0x0010) && (HWIF(drive)->udma_four)) {
+ if ((id->dma_ultra & 0x0020) && (ultra66) && (ultra100)) {
+ speed = XFER_UDMA_5;
+ } else if ((id->dma_ultra & 0x0010) && (ultra66)) {
speed = XFER_UDMA_4;
- } else if ((id->dma_ultra & 0x0008) && (HWIF(drive)->udma_four)) {
+ } else if ((id->dma_ultra & 0x0008) && (ultra66)) {
speed = XFER_UDMA_3;
} else if (id->dma_ultra & 0x0004) {
speed = XFER_UDMA_2;
@@ -778,12 +782,6 @@ static int config_chipset_for_dma (ide_drive_t *drive)
speed = XFER_MW_DMA_1;
} else if (id->dma_mword & 0x0001) {
speed = XFER_MW_DMA_0;
- } else if (id->dma_1word & 0x0004) {
- speed = XFER_SW_DMA_2;
- } else if (id->dma_1word & 0x0002) {
- speed = XFER_SW_DMA_1;
- } else if (id->dma_1word & 0x0001) {
- speed = XFER_SW_DMA_0;
} else {
return ((int) ide_dma_off_quietly);
}
@@ -793,7 +791,6 @@ static int config_chipset_for_dma (ide_drive_t *drive)
rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
- ((id->dma_1word >> 8) & 7) ? ide_dma_on :
ide_dma_off_quietly);
return rval;
}
@@ -811,7 +808,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
- if (id->dma_ultra & 0x001F) {
+ if (id->dma_ultra & 0x002F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive);
if ((id->field_valid & 2) &&
@@ -820,8 +817,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
} else if (id->field_valid & 2) {
try_dma_modes:
- if ((id->dma_mword & 0x0007) ||
- (id->dma_1word & 0x0007)) {
+ if (id->dma_mword & 0x0007) {
/* Force if Capable regular DMA modes */
dma_func = config_chipset_for_dma(drive);
if (dma_func != ide_dma_on)
@@ -870,7 +866,7 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name)
byte revision = 0;
for (i = 0; i < arraysize (ApolloHostChipInfo) && !host_dev; i++) {
- host = pci_find_device (PCI_VENDOR_ID_VIA,
+ host = pci_find_device (ApolloHostChipInfo[i].vendor_id,
ApolloHostChipInfo[i].host_id,
NULL);
if (!host)
diff --git a/drivers/pnp/isapnp.c b/drivers/pnp/isapnp.c
index 06bf946645abf2..497879619cbd5f 100644
--- a/drivers/pnp/isapnp.c
+++ b/drivers/pnp/isapnp.c
@@ -2059,14 +2059,14 @@ static void isapnp_free_all_resources(void)
if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff)
release_resource(isapnp_rdp_res);
#ifdef MODULE
+#ifdef CONFIG_PROC_FS
+ isapnp_proc_done();
+#endif
while (!list_empty(&isapnp_cards)) {
struct list_head *list = isapnp_cards.next;
list_del(list);
isapnp_free_card(pci_bus_b(list));
}
-#ifdef CONFIG_PROC_FS
- isapnp_proc_done();
-#endif
#endif
}
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 4fca4d14db5103..71b93e379a70cb 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -17,8 +17,8 @@
* any later version.
*
*/
- static char * sg_version_str = "Version: 3.1.13 (20000323)";
- static int sg_version_num = 30113; /* 2 digits for each component */
+ static char * sg_version_str = "Version: 3.1.15 (20000528)";
+ static int sg_version_num = 30115; /* 2 digits for each component */
/*
* D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
* - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -113,7 +113,8 @@ static void sg_detach(Scsi_Device *);
static Scsi_Cmnd * dummy_cmdp = 0; /* only used for sizeof */
-static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED;
+static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; /* Also used to lock
+ file descriptor list for device */
struct Scsi_Device_Template sg_template =
{
@@ -155,7 +156,7 @@ typedef struct sg_request /* SG_MAX_QUEUE requests outstanding per file */
char res_used; /* 1 -> using reserve buffer, 0 -> not ... */
char orphan; /* 1 -> drop on sight, 0 -> normal */
char sg_io_owned; /* 1 -> packet belongs to SG_IO */
- char done; /* 1 -> bh handler done, 0 -> prior to bh */
+ char done; /* 0->before bh, 1->before read, 2->read */
} Sg_request; /* 168 bytes long on i386 */
typedef struct sg_fd /* holds the state of a file descriptor */
@@ -163,6 +164,7 @@ typedef struct sg_fd /* holds the state of a file descriptor */
struct sg_fd * nextfp; /* NULL when last opened fd on this device */
struct sg_device * parentdp; /* owning device */
wait_queue_head_t read_wait; /* queue read until command done */
+ rwlock_t rq_list_lock; /* protect access to list in req_arr */
int timeout; /* defaults to SG_DEFAULT_TIMEOUT */
Sg_scatter_hold reserve; /* buffer held for this file descriptor */
unsigned save_scat_len; /* original length of trunc. scat. element */
@@ -176,7 +178,7 @@ typedef struct sg_fd /* holds the state of a file descriptor */
char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */
char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
-} Sg_fd; /* 2760 bytes long on i386 */
+} Sg_fd; /* 2768 bytes long on i386 */
typedef struct sg_device /* holds the state of each scsi generic device */
{
@@ -189,7 +191,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */
char exclude; /* opened for exclusive access */
char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
char detached; /* 0->attached, 1->detached pending removal */
-} Sg_device; /* 40 bytes long on i386 */
+} Sg_device; /* 44 bytes long on i386 */
static int sg_fasync(int fd, struct file * filp, int mode);
@@ -222,11 +224,11 @@ static char * sg_low_malloc(int rqSz, int lowDma, int mem_src,
static void sg_low_free(char * buff, int size, int mem_src);
static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev);
static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
-static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id);
+static Sg_request * sg_get_rq_mark(Sg_fd * sfp, int pack_id);
static Sg_request * sg_add_request(Sg_fd * sfp);
static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
-static int sg_res_in_use(const Sg_fd * sfp);
-static int sg_dio_in_use(const Sg_fd * sfp);
+static int sg_res_in_use(Sg_fd * sfp);
+static int sg_dio_in_use(Sg_fd * sfp);
static void sg_clr_scpnt(Scsi_Cmnd * SCpnt);
static void sg_shorten_timeout(Scsi_Cmnd * scpnt);
static int sg_ms_to_jif(unsigned int msecs);
@@ -364,7 +366,7 @@ static ssize_t sg_read(struct file * filp, char * buf,
else
req_pack_id = old_hdr.pack_id;
}
- srp = sg_get_request(sfp, req_pack_id);
+ srp = sg_get_rq_mark(sfp, req_pack_id);
if (! srp) { /* now wait on packet to arrive */
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
@@ -372,7 +374,7 @@ static ssize_t sg_read(struct file * filp, char * buf,
int dio = sg_dio_in_use(sfp);
res = 0; /* following is a macro that beats race condition */
__wait_event_interruptible(sfp->read_wait,
- (srp = sg_get_request(sfp, req_pack_id)),
+ (srp = sg_get_rq_mark(sfp, req_pack_id)),
res);
if (0 == res)
break;
@@ -550,7 +552,7 @@ static ssize_t sg_write(struct file * filp, const char * buf,
hp->cmd_len = (unsigned char)cmd_size;
hp->iovec_count = 0;
hp->mx_sb_len = 0;
-#if 1
+#if 0
hp->dxfer_direction = SG_DXFER_UNKNOWN;
#else
if (input_size > 0)
@@ -686,7 +688,7 @@ static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
srp->data.sglist_len = 0;
srp->data.bufflen = 0;
srp->data.buffer = NULL;
- hp->duration = jiffies;
+ hp->duration = jiffies; /* unit jiffies now, millisecs after done */
/* Now send everything of to mid-level. The next time we hear about this
packet is when sg_cmd_done_bh() is called (i.e. a callback). */
scsi_do_cmd(SCpnt, (void *)cmnd,
@@ -703,6 +705,7 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
Sg_device * sdp;
Sg_fd * sfp;
Sg_request * srp;
+ unsigned long iflags;
if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp)))
return -ENXIO;
@@ -740,6 +743,7 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
return result; /* -ERESTARTSYS because signal hit process */
}
}
+ srp->done = 2;
result = sg_new_read(sfp, (char *)arg, size_sg_io_hdr, srp);
return (result < 0) ? result : 0;
}
@@ -794,24 +798,24 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
case SG_GET_PACK_ID:
result = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int));
if (result) return result;
- srp = sfp->headrp;
- while (srp) {
- if (srp->done && (! srp->sg_io_owned)) {
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (srp = sfp->headrp; srp; srp = srp->nextrp) {
+ if ((1 == srp->done) && (! srp->sg_io_owned)) {
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
__put_user(srp->header.pack_id, (int *)arg);
return 0;
}
- srp = srp->nextrp;
}
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
__put_user(-1, (int *)arg);
return 0;
case SG_GET_NUM_WAITING:
- srp = sfp->headrp;
- val = 0;
- while (srp) {
- if (srp->done && (! srp->sg_io_owned))
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) {
+ if ((1 == srp->done) && (! srp->sg_io_owned))
++val;
- srp = srp->nextrp;
}
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
return put_user(val, (int *)arg);
case SG_GET_SG_TABLESIZE:
return put_user(sdp->sg_tablesize, (int *)arg);
@@ -855,16 +859,17 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
if (result) return result;
else {
sg_req_info_t rinfo[SG_MAX_QUEUE];
- Sg_request * srp = sfp->headrp;
- for (val = 0; val < SG_MAX_QUEUE;
+ Sg_request * srp;
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
++val, srp = srp ? srp->nextrp : srp) {
memset(&rinfo[val], 0, size_sg_req_info);
if (srp) {
- rinfo[val].req_state = srp->done ? 2 : 1;
+ rinfo[val].req_state = srp->done + 1;
rinfo[val].problem = srp->header.masked_status &
srp->header.host_status & srp->header.driver_status;
rinfo[val].duration = srp->done ?
- sg_jif_to_ms(srp->header.duration) :
+ srp->header.duration :
sg_jif_to_ms(jiffies - srp->header.duration);
rinfo[val].orphan = srp->orphan;
rinfo[val].sg_io_owned = srp->sg_io_owned;
@@ -872,6 +877,7 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
rinfo[val].usr_ptr = srp->header.usr_ptr;
}
}
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
__copy_to_user((void *)arg, rinfo, size_sg_req_info * SG_MAX_QUEUE);
return 0;
}
@@ -882,8 +888,29 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
return -EBUSY;
result = get_user(val, (int *)arg);
if (result) return result;
- /* Don't do anything till scsi mid level visibility */
- return 0;
+ if (SG_SCSI_RESET_NOTHING == val)
+ return 0;
+#ifdef SCSI_TRY_RESET_DEVICE
+ switch (val)
+ {
+ case SG_SCSI_RESET_DEVICE:
+ val = SCSI_TRY_RESET_DEVICE;
+ break;
+ case SG_SCSI_RESET_BUS:
+ val = SCSI_TRY_RESET_BUS;
+ break;
+ case SG_SCSI_RESET_HOST:
+ val = SCSI_TRY_RESET_HOST;
+ break;
+ default:
+ return -EINVAL;
+ }
+ if(! capable(CAP_SYS_ADMIN)) return -EACCES;
+ return (scsi_reset_provider(sdp->device, val) == SUCCESS) ? 0 : -EIO;
+#else
+ SCSI_LOG_TIMEOUT(1, printk("sg_ioctl: SG_RESET_SCSI not supported\n"));
+ result = -EINVAL;
+#endif
case SCSI_IOCTL_SEND_COMMAND:
if (read_only) {
unsigned char opcode = WRITE_6;
@@ -918,17 +945,19 @@ static unsigned int sg_poll(struct file * filp, poll_table * wait)
Sg_fd * sfp;
Sg_request * srp;
int count = 0;
+ unsigned long iflags;
if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp)))
return POLLERR;
poll_wait(filp, &sfp->read_wait, wait);
- srp = sfp->headrp;
- while (srp) { /* if any read waiting, flag it */
- if ((0 == res) && srp->done && (! srp->sg_io_owned))
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (srp = sfp->headrp; srp; srp = srp->nextrp) {
+ /* if any read waiting, flag it */
+ if ((0 == res) && (1 == srp->done) && (! srp->sg_io_owned))
res = POLLIN | POLLRDNORM;
++count;
- srp = srp->nextrp;
}
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
if (! sfp->cmd_q) {
if (0 == count)
res |= POLLOUT | POLLWRNORM;
@@ -960,11 +989,17 @@ static int sg_fasync(int fd, struct file * filp, int mode)
static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
{
int dev = MINOR(SCpnt->request.rq_dev);
- Sg_device * sdp;
+ Sg_device * sdp = NULL;
Sg_fd * sfp;
Sg_request * srp = NULL;
- if (NULL == (sdp = sg_get_dev(dev))) {
+ read_lock(&sg_dev_arr_lock);
+ if (sg_dev_arr && (dev >= 0)) {
+ if (dev < sg_template.dev_max)
+ sdp = sg_dev_arr[dev];
+ }
+ if (NULL == sdp) {
+ read_unlock(&sg_dev_arr_lock);
SCSI_LOG_TIMEOUT(1, printk("sg...bh: bad args dev=%d\n", dev));
scsi_release_command(SCpnt);
SCpnt = NULL;
@@ -972,16 +1007,17 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
}
sfp = sdp->headfp;
while (sfp) {
- srp = sfp->headrp;
- while (srp) {
+ read_lock(&sfp->rq_list_lock);
+ for (srp = sfp->headrp; srp; srp = srp->nextrp) {
if (SCpnt == srp->my_cmdp)
break;
- srp = srp->nextrp;
}
+ read_unlock(&sfp->rq_list_lock);
if (srp)
break;
sfp = sfp->nextfp;
}
+ read_unlock(&sg_dev_arr_lock);
if (! srp) {
SCSI_LOG_TIMEOUT(1, printk("sg...bh: req missing, dev=%d\n", dev));
scsi_release_command(SCpnt);
@@ -1001,6 +1037,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
dev, srp->header.pack_id, (int)SCpnt->result));
srp->header.resid = SCpnt->resid;
/* sg_unmap_and(&srp->data, 0); */ /* unmap locked pages a.s.a.p. */
+ /* N.B. unit of duration changes here from jiffies to millisecs */
srp->header.duration = sg_jif_to_ms(jiffies - (int)srp->header.duration);
if (0 != SCpnt->result) {
memcpy(srp->sense_b, SCpnt->sense_buffer, sizeof(srp->sense_b));
@@ -1052,8 +1089,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
if (sfp && srp) {
/* Now wake up any sg_read() that is waiting for this packet. */
wake_up_interruptible(&sfp->read_wait);
- if (sfp->async_qp)
- kill_fasync(sfp->async_qp, SIGPOLL, POLL_IN);
+ kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
}
}
@@ -1091,18 +1127,18 @@ static int sg_detect(Scsi_Device * scsidp)
static int sg_init()
{
static int sg_registered = 0;
- unsigned long flags = 0;
+ unsigned long iflags;
if ((sg_template.dev_noticed == 0) || sg_dev_arr)
return 0;
- write_lock_irqsave(&sg_dev_arr_lock, flags);
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
if(!sg_registered) {
if (devfs_register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
{
printk("Unable to get major %d for generic SCSI device\n",
SCSI_GENERIC_MAJOR);
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
return 1;
}
sg_registered++;
@@ -1114,11 +1150,11 @@ static int sg_init()
sizeof(Sg_device *), GFP_ATOMIC);
if (NULL == sg_dev_arr) {
printk("sg_init: no space for sg_dev_arr\n");
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
return 1;
}
memset(sg_dev_arr, 0, sg_template.dev_max * sizeof(Sg_device *));
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
#ifdef CONFIG_PROC_FS
sg_proc_init();
#endif /* CONFIG_PROC_FS */
@@ -1149,10 +1185,10 @@ __setup("sg_def_reserved_size=", sg_def_reserved_size_setup);
static int sg_attach(Scsi_Device * scsidp)
{
Sg_device * sdp;
- unsigned long flags = 0;
+ unsigned long iflags;
int k;
- write_lock_irqsave(&sg_dev_arr_lock, flags);
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
if (sg_template.nr_dev >= sg_template.dev_max) { /* try to resize */
Sg_device ** tmp_da;
int tmp_dev_max = sg_template.nr_dev + SG_DEV_ARR_LUMP;
@@ -1161,7 +1197,7 @@ static int sg_attach(Scsi_Device * scsidp)
sizeof(Sg_device *), GFP_ATOMIC);
if (NULL == tmp_da) {
scsidp->attached--;
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
printk("sg_attach: device array cannot be resized\n");
return 1;
}
@@ -1180,7 +1216,7 @@ static int sg_attach(Scsi_Device * scsidp)
sdp = NULL;
if (NULL == sdp) {
scsidp->attached--;
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
printk("sg_attach: Sg_device cannot be allocated\n");
return 1;
}
@@ -1200,7 +1236,7 @@ static int sg_attach(Scsi_Device * scsidp)
&sg_fops, NULL);
sg_template.nr_dev++;
sg_dev_arr[k] = sdp;
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
return 0;
}
@@ -1214,37 +1250,36 @@ static void sg_finish(void)
static void sg_detach(Scsi_Device * scsidp)
{
Sg_device * sdp;
- unsigned long flags = 0;
+ unsigned long iflags;
Sg_fd * sfp;
Sg_request * srp;
int k;
if (NULL == sg_dev_arr)
return;
- write_lock_irqsave(&sg_dev_arr_lock, flags);
-/* Need to stop sg_cmd_done_bh() playing with this list during this loop */
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
for (k = 0; k < sg_template.dev_max; k++) {
sdp = sg_dev_arr[k];
if ((NULL == sdp) || (sdp->device != scsidp))
continue; /* dirty but lowers nesting */
if (sdp->headfp) {
- sfp = sdp->headfp;
- while (sfp) {
- srp = sfp->headrp;
- while (srp) {
- if (! srp->done)
+ for (sfp = sdp->headfp; sfp; sfp = sfp->nextfp) {
+ /* no lock on request list here */
+ for (srp = sfp->headrp; srp; srp = srp->nextrp) {
+ if (! srp->done) {
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
sg_shorten_timeout(srp->my_cmdp);
- srp = srp->nextrp;
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
}
- sfp = sfp->nextfp;
}
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ }
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty, sleep(3)\n", k));
scsi_sleep(3); /* sleep 3 jiffies, hoping for timeout to go off */
devfs_unregister (sdp->de);
sdp->de = NULL;
sdp->detached = 1;
- write_lock_irqsave(&sg_dev_arr_lock, flags);
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
}
else {
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k));
@@ -1259,7 +1294,7 @@ static void sg_detach(Scsi_Device * scsidp)
sg_template.dev_noticed--;
break;
}
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
return;
}
@@ -1277,12 +1312,11 @@ int init_module(void) {
void cleanup_module( void)
{
- scsi_unregister_module(MODULE_SCSI_DEV, &sg_template);
- devfs_unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
-
#ifdef CONFIG_PROC_FS
sg_proc_cleanup();
#endif /* CONFIG_PROC_FS */
+ scsi_unregister_module(MODULE_SCSI_DEV, &sg_template);
+ devfs_unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
if(sg_dev_arr != NULL) {
/* Really worrying situation of writes still pending and get here */
/* Strategy: shorten timeout on release + wait on detach ... */
@@ -1301,7 +1335,7 @@ extern void scsi_old_times_out (Scsi_Cmnd * SCpnt);
/* Can't see clean way to abort a command so shorten timeout to 1 jiffy */
static void sg_shorten_timeout(Scsi_Cmnd * scpnt)
-{ /* assumed to be called with sg_dev_arr_lock held */
+{
#if 0 /* scsi_syms.c is very miserly about exported functions */
scsi_delete_timer(scpnt);
if (! scpnt)
@@ -1313,11 +1347,7 @@ static void sg_shorten_timeout(Scsi_Cmnd * scpnt)
scsi_add_timer(scpnt, scpnt->timeout_per_command,
scsi_old_times_out);
#else
- unsigned long flags = 0;
-
- write_unlock_irqrestore(&sg_dev_arr_lock, flags);
scsi_sleep(HZ); /* just sleep 1 second and hope ... */
- write_lock_irqsave(&sg_dev_arr_lock, flags);
#endif
}
@@ -1859,6 +1889,8 @@ static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
Sg_scatter_hold * rsv_schp = &sfp->reserve;
SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
+ /* round request up to next highest SG_SECTOR_SZ byte boundary */
+ size = (size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
if (rsv_schp->k_use_sg > 0) {
int k, num;
int rem = size;
@@ -1921,17 +1953,35 @@ static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
srp->res_used = 0;
}
-static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id)
+static Sg_request * sg_get_rq_mark(Sg_fd * sfp, int pack_id)
{
- Sg_request * resp = NULL;
+ Sg_request * resp;
+ unsigned long iflags;
- resp = sfp->headrp;
- while (resp) { /* look for requests that are ready + not SG_IO owned */
- if (resp->done && (! resp->sg_io_owned) &&
- ((-1 == pack_id) || (resp->header.pack_id == pack_id)))
- return resp;
- resp = resp->nextrp;
+ write_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (resp = sfp->headrp; resp; resp = resp->nextrp) {
+ /* look for requests that are ready + not SG_IO owned */
+ if ((1 == resp->done) && (! resp->sg_io_owned) &&
+ ((-1 == pack_id) || (resp->header.pack_id == pack_id))) {
+ resp->done = 2; /* guard against other readers */
+ break;
+ }
}
+ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+ return resp;
+}
+
+static Sg_request * sg_get_nth_request(Sg_fd * sfp, int nth)
+{
+ Sg_request * resp;
+ unsigned long iflags;
+ int k;
+
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (k = 0, resp = sfp->headrp; resp && (k < nth);
+ ++k, resp = resp->nextrp)
+ ;
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
return resp;
}
@@ -1939,46 +1989,45 @@ static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id)
static Sg_request * sg_add_request(Sg_fd * sfp)
{
int k;
- Sg_request * resp = NULL;
- Sg_request * rp;
+ unsigned long iflags;
+ Sg_request * resp;
+ Sg_request * rp = sfp->req_arr;
+ write_lock_irqsave(&sfp->rq_list_lock, iflags);
resp = sfp->headrp;
- rp = sfp->req_arr;
if (! resp) {
- resp = rp;
- sfp->headrp = resp;
+ memset(rp, 0, sizeof(Sg_request));
+ rp->parentfp = sfp;
+ resp = rp;
+ sfp->headrp = resp;
}
else {
if (0 == sfp->cmd_q)
resp = NULL; /* command queuing disallowed */
else {
- for (k = 0, rp; k < SG_MAX_QUEUE; ++k, ++rp) {
+ for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) {
if (! rp->parentfp)
break;
}
if (k < SG_MAX_QUEUE) {
- while (resp->nextrp) resp = resp->nextrp;
- resp->nextrp = rp;
- resp = rp;
+ memset(rp, 0, sizeof(Sg_request));
+ rp->parentfp = sfp;
+ while (resp->nextrp)
+ resp = resp->nextrp;
+ resp->nextrp = rp;
+ resp = rp;
}
else
resp = NULL;
}
}
if (resp) {
- resp->parentfp = sfp;
resp->nextrp = NULL;
- resp->res_used = 0;
- resp->orphan = 0;
- resp->sg_io_owned = 0;
- resp->done = 0;
- memset(&resp->data, 0, sizeof(Sg_scatter_hold));
- memset(&resp->header, 0, size_sg_io_hdr);
resp->header.duration = jiffies;
resp->my_cmdp = NULL;
resp->data.kiobp = NULL;
- resp->data.mapped = 0;
}
+ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
return resp;
}
@@ -1987,29 +2036,51 @@ static int sg_remove_request(Sg_fd * sfp, Sg_request * srp)
{
Sg_request * prev_rp;
Sg_request * rp;
+ unsigned long iflags;
+ int res = 0;
if ((! sfp) || (! srp) || (! sfp->headrp))
- return 0;
+ return res;
+ write_lock_irqsave(&sfp->rq_list_lock, iflags);
prev_rp = sfp->headrp;
if (srp == prev_rp) {
- prev_rp->parentfp = NULL;
sfp->headrp = prev_rp->nextrp;
- return 1;
+ prev_rp->parentfp = NULL;
+ res = 1;
}
- while ((rp = prev_rp->nextrp)) {
- if (srp == rp) {
- rp->parentfp = NULL;
- prev_rp->nextrp = rp->nextrp;
- return 1;
- }
- prev_rp = rp;
+ else {
+ while ((rp = prev_rp->nextrp)) {
+ if (srp == rp) {
+ prev_rp->nextrp = rp->nextrp;
+ rp->parentfp = NULL;
+ res = 1;
+ break;
+ }
+ prev_rp = rp;
+ }
}
- return 0;
+ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+ return res;
+}
+
+static Sg_fd * sg_get_nth_sfp(Sg_device * sdp, int nth)
+{
+ Sg_fd * resp;
+ unsigned long iflags;
+ int k;
+
+ read_lock_irqsave(&sg_dev_arr_lock, iflags);
+ for (k = 0, resp = sdp->headfp; resp && (k < nth);
+ ++k, resp = resp->nextfp)
+ ;
+ read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+ return resp;
}
static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev)
{
Sg_fd * sfp;
+ unsigned long iflags;
sfp = (Sg_fd *)sg_low_malloc(sizeof(Sg_fd), 0, SG_HEAP_KMAL, 0);
if (! sfp)
@@ -2017,6 +2088,7 @@ static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev)
memset(sfp, 0, sizeof(Sg_fd));
sfp->fd_mem_src = SG_HEAP_KMAL;
init_waitqueue_head(&sfp->read_wait);
+ sfp->rq_list_lock = RW_LOCK_UNLOCKED;
sfp->timeout = SG_DEFAULT_TIMEOUT;
sfp->force_packid = SG_DEF_FORCE_PACK_ID;
@@ -2025,14 +2097,16 @@ static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev)
sfp->cmd_q = SG_DEF_COMMAND_Q;
sfp->keep_orphan = SG_DEF_KEEP_ORPHAN;
sfp->parentdp = sdp;
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
if (! sdp->headfp)
sdp->headfp = sfp;
else { /* add to tail of existing list */
- Sg_fd * pfp = sdp->headfp;
- while (pfp->nextfp)
- pfp = pfp->nextfp;
- pfp->nextfp = sfp;
+ Sg_fd * pfp = sdp->headfp;
+ while (pfp->nextfp)
+ pfp = pfp->nextfp;
+ pfp->nextfp = sfp;
}
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p, m_s=%d\n",
sfp, (int)sfp->fd_mem_src));
sg_build_reserve(sfp, sg_big_buff);
@@ -2048,36 +2122,41 @@ static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
int dirty = 0;
int res = 0;
+ /* no lock since not expecting any parallel action on this fd */
srp = sfp->headrp;
if (srp) {
- while (srp) {
- tsrp = srp->nextrp;
+ while (srp) {
+ tsrp = srp->nextrp;
if (srp->done)
sg_finish_rem_req(srp);
- else
- ++dirty;
- srp = tsrp;
- }
+ else
+ ++dirty;
+ srp = tsrp;
+ }
}
if (0 == dirty) {
- Sg_fd * fp;
- Sg_fd * prev_fp = sdp->headfp;
-
- if (sfp == prev_fp)
- sdp->headfp = prev_fp->nextfp;
- else {
- while ((fp = prev_fp->nextfp)) {
- if (sfp == fp) {
- prev_fp->nextfp = fp->nextfp;
- break;
- }
- prev_fp = fp;
- }
- }
- if (sfp->reserve.bufflen > 0) {
+ Sg_fd * fp;
+ Sg_fd * prev_fp;
+ unsigned long iflags;
+
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
+ prev_fp = sdp->headfp;
+ if (sfp == prev_fp)
+ sdp->headfp = prev_fp->nextfp;
+ else {
+ while ((fp = prev_fp->nextfp)) {
+ if (sfp == fp) {
+ prev_fp->nextfp = fp->nextfp;
+ break;
+ }
+ prev_fp = fp;
+ }
+ }
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+ if (sfp->reserve.bufflen > 0) {
SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: bufflen=%d, k_use_sg=%d\n",
(int)sfp->reserve.bufflen, (int)sfp->reserve.k_use_sg));
- sg_remove_scat(&sfp->reserve);
+ sg_remove_scat(&sfp->reserve);
}
sfp->parentdp = NULL;
SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: sfp=0x%p\n", sfp));
@@ -2104,28 +2183,28 @@ SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: bufflen=%d, k_use_sg=%d\n",
return res;
}
-static int sg_res_in_use(const Sg_fd * sfp)
+static int sg_res_in_use(Sg_fd * sfp)
{
- const Sg_request * srp = sfp->headrp;
+ const Sg_request * srp;
+ unsigned long iflags;
- while (srp) {
- if (srp->res_used)
- return 1;
- srp = srp->nextrp;
- }
- return 0;
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (srp = sfp->headrp; srp; srp = srp->nextrp)
+ if (srp->res_used) break;
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+ return srp ? 1 : 0;
}
-static int sg_dio_in_use(const Sg_fd * sfp)
+static int sg_dio_in_use(Sg_fd * sfp)
{
- const Sg_request * srp = sfp->headrp;
+ const Sg_request * srp;
+ unsigned long iflags;
- while (srp) {
- if ((! srp->done) && srp->data.kiobp)
- return 1;
- srp = srp->nextrp;
- }
- return 0;
+ read_lock_irqsave(&sfp->rq_list_lock, iflags);
+ for (srp = sfp->headrp; srp; srp = srp->nextrp)
+ if ((! srp->done) && srp->data.kiobp) break;
+ read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+ return srp ? 1 : 0;
}
/* If retSzp==NULL want exact size or fail */
@@ -2314,7 +2393,8 @@ static unsigned sg_jif_to_ms(int jifs)
}
static unsigned char allow_ops[] = {TEST_UNIT_READY, INQUIRY,
-READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12};
+READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12,
+MODE_SENSE, MODE_SENSE_10};
static int sg_allow_access(unsigned char opcode, char dev_type)
{
@@ -2331,28 +2411,29 @@ static int sg_allow_access(unsigned char opcode, char dev_type)
static int sg_last_dev()
-{ /* assumed to be called with sg_dev_arr_lock held */
+{
int k;
+ unsigned long iflags;
- for (k = sg_template.dev_max - 1; k >= 0; --k) {
- if (sg_dev_arr[k] && sg_dev_arr[k]->device)
- return k + 1;
- }
- return 0; /* origin 1 */
+ read_lock_irqsave(&sg_dev_arr_lock, iflags);
+ for (k = sg_template.dev_max - 1; k >= 0; --k)
+ if (sg_dev_arr[k] && sg_dev_arr[k]->device) break;
+ read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+ return k + 1; /* origin 1 */
}
static Sg_device * sg_get_dev(int dev)
{
- Sg_device * sdp;
+ Sg_device * sdp = NULL;
+ unsigned long iflags;
- if ((NULL == sg_dev_arr) || (dev < 0))
- return NULL;
- read_lock(&sg_dev_arr_lock);
+ if (sg_dev_arr && (dev >= 0))
+ {
+ read_lock_irqsave(&sg_dev_arr_lock, iflags);
if (dev < sg_template.dev_max)
sdp = sg_dev_arr[dev];
- else
- sdp = NULL;
- read_unlock(&sg_dev_arr_lock);
+ read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+ }
return sdp;
}
@@ -2429,8 +2510,7 @@ static write_proc_t * sg_proc_leaf_writes[] = {
*eof = infofp(buffer, &len, &begin, offset, size); \
if (offset >= (begin + len)) \
return 0; \
- *start = buffer + ((begin > offset) ? \
- (begin - offset) : (offset - begin)); \
+ *start = buffer + offset - begin; \
return (size < (begin + len - offset)) ? \
size : begin + len - offset; \
} while(0)
@@ -2520,7 +2600,6 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin,
PRINT_PROC("sg_dev_arr NULL, driver not initialized\n");
return 1;
}
- read_lock(&sg_dev_arr_lock);
max_dev = sg_last_dev();
PRINT_PROC("dev_max(currently)=%d max_active_device=%d (origin 1)\n",
sg_template.dev_max, max_dev);
@@ -2528,11 +2607,11 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin,
"def_reserved_size=%d\n",
scsi_dma_free_sectors, sg_pool_secs_avail, sg_big_buff);
for (j = 0; j < max_dev; ++j) {
- if ((sdp = sg_dev_arr[j])) {
+ if ((sdp = sg_get_dev(j))) {
Sg_fd * fp;
Sg_request * srp;
struct scsi_device * scsidp;
- int dev, k, blen, usg;
+ int dev, k, m, blen, usg;
if (! (scsidp = sdp->device)) {
PRINT_PROC("device %d detached ??\n", j);
@@ -2540,48 +2619,45 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin,
}
dev = MINOR(sdp->i_rdev);
- if ((fp = sdp->headfp)) {
- PRINT_PROC(" >>> device=%d(sg%d) ", dev, dev);
+ if (sg_get_nth_sfp(sdp, 0)) {
+ PRINT_PROC(" >>> device=sg%d ", dev);
PRINT_PROC("scsi%d chan=%d id=%d lun=%d em=%d sg_tablesize=%d"
" excl=%d\n", scsidp->host->host_no, scsidp->channel,
scsidp->id, scsidp->lun, scsidp->host->hostt->emulated,
sdp->sg_tablesize, sdp->exclude);
}
- for (k = 1; fp; fp = fp->nextfp, ++k) {
- PRINT_PROC(" FD(%d): timeout=%d bufflen=%d "
- "(res)sgat=%d low_dma=%d\n",
- k, fp->timeout, fp->reserve.bufflen,
+ for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) {
+ PRINT_PROC(" FD(%d): timeout=%dms bufflen=%d "
+ "(res)sgat=%d low_dma=%d\n", k + 1,
+ sg_jif_to_ms(fp->timeout), fp->reserve.bufflen,
(int)fp->reserve.k_use_sg, (int)fp->low_dma);
PRINT_PROC(" cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n",
(int)fp->cmd_q, (int)fp->force_packid,
(int)fp->keep_orphan, (int)fp->closed);
- srp = fp->headrp;
- if (NULL == srp)
- PRINT_PROC(" No requests active\n");
- while (srp) {
+ for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) {
hp = &srp->header;
/* stop indenting so far ... */
PRINT_PROC(srp->res_used ? " rb>> " :
((SG_INFO_DIRECT_IO_MASK & hp->info) ? " dio>> " : " "));
blen = srp->my_cmdp ? srp->my_cmdp->bufflen : srp->data.bufflen;
usg = srp->my_cmdp ? srp->my_cmdp->use_sg : srp->data.k_use_sg;
- PRINT_PROC(srp->done ? "rcv: id=%d" : (srp->my_cmdp ? "act: id=%d" :
- "prior: id=%d"), srp->header.pack_id);
- PRINT_PROC(" blen=%d", blen);
+ PRINT_PROC(srp->done ? ((1 == srp->done) ? "rcv:" : "fin:")
+ : (srp->my_cmdp ? "act:" : "prior:"));
+ PRINT_PROC(" id=%d blen=%d", srp->header.pack_id, blen);
if (srp->done)
- PRINT_PROC(" dur=%d", sg_jif_to_ms(hp->duration));
+ PRINT_PROC(" dur=%d", hp->duration);
else
PRINT_PROC(" t_o/elap=%d/%d", ((hp->interface_id == '\0') ?
sg_jif_to_ms(fp->timeout) : hp->timeout),
sg_jif_to_ms(hp->duration ? (jiffies - hp->duration) : 0));
- PRINT_PROC(" sgat=%d op=0x%02x\n", usg, (int)srp->data.cmd_opcode);
- srp = srp->nextrp;
+ PRINT_PROC("ms sgat=%d op=0x%02x\n", usg, (int)srp->data.cmd_opcode);
/* reset indenting */
}
+ if (0 == m)
+ PRINT_PROC(" No requests active\n");
}
}
}
- read_unlock(&sg_dev_arr_lock);
return 1;
}
@@ -2596,19 +2672,17 @@ static int sg_proc_dev_info(char * buffer, int * len, off_t * begin,
int j, max_dev;
struct scsi_device * scsidp;
- read_lock(&sg_dev_arr_lock);
max_dev = sg_last_dev();
for (j = 0; j < max_dev; ++j) {
- sdp = sg_dev_arr[j];
+ sdp = sg_get_dev(j);
if (sdp && (scsidp = sdp->device))
PRINT_PROC("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
scsidp->host->host_no, scsidp->channel, scsidp->id,
- scsidp->lun, (int)scsidp->type, (int)scsidp->disconnect,
- (int)scsidp->queue_depth, (int)scsidp->tagged_queue);
+ scsidp->lun, (int)scsidp->type, (int)scsidp->access_count,
+ (int)scsidp->queue_depth, (int)scsidp->device_busy);
else
PRINT_PROC("-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n");
}
- read_unlock(&sg_dev_arr_lock);
return 1;
}
@@ -2619,7 +2693,7 @@ static int sg_proc_devhdr_read(char * buffer, char ** start, off_t offset,
static int sg_proc_devhdr_info(char * buffer, int * len, off_t * begin,
off_t offset, int size)
{
- PRINT_PROC("host\tchan\tid\tlun\ttype\tdiscon\tqdepth\ttq\n");
+ PRINT_PROC("host\tchan\tid\tlun\ttype\tbopens\tqdepth\tbusy\n");
return 1;
}
@@ -2634,17 +2708,15 @@ static int sg_proc_devstrs_info(char * buffer, int * len, off_t * begin,
int j, max_dev;
struct scsi_device * scsidp;
- read_lock(&sg_dev_arr_lock);
max_dev = sg_last_dev();
for (j = 0; j < max_dev; ++j) {
- sdp = sg_dev_arr[j];
+ sdp = sg_get_dev(j);
if (sdp && (scsidp = sdp->device))
PRINT_PROC("%8.8s\t%16.16s\t%4.4s\n",
scsidp->vendor, scsidp->model, scsidp->rev);
else
PRINT_PROC("<no active device>\n");
}
- read_unlock(&sg_dev_arr_lock);
return 1;
}
diff --git a/drivers/sgi/char/graphics.c b/drivers/sgi/char/graphics.c
index 352a210d4b4b3c..b0f3103e428abc 100644
--- a/drivers/sgi/char/graphics.c
+++ b/drivers/sgi/char/graphics.c
@@ -150,9 +150,11 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un
* sgi_graphics_mmap
*/
disable_gconsole ();
+ down(&current->mm->mmap_sem);
r = do_mmap (file, (unsigned long)vaddr,
cards[board].g_regs_size, PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_PRIVATE, 0);
+ up(&current->mm->mmap_sem);
if (r)
return r;
}
diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c
index 19d44b090be1e8..2d6a4b6f4fc9a9 100644
--- a/drivers/sgi/char/shmiq.c
+++ b/drivers/sgi/char/shmiq.c
@@ -118,8 +118,7 @@ shmiq_push_event (struct shmqevent *e)
e->data.device, e->data.which, e->data.type, e->data.flags);
s->tail = tail_next;
shmiqs [device].tail = tail_next;
- if (shmiqs [device].fasync)
- kill_fasync (shmiqs [device].fasync, SIGIO, POLL_IN);
+ kill_fasync (&shmiqs [device].fasync, SIGIO, POLL_IN);
wake_up_interruptible (&shmiqs [device].proc_list);
}
@@ -279,8 +278,10 @@ qcntl_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned
return -EINVAL;
}
s = req.arg * sizeof (struct shmqevent) + sizeof (struct sharedMemoryInputQueue);
- v = sys_munmap (vaddr, s);
+ down(&current->mm->mmap_sem);
+ do_munmap (current->mm, vaddr, s);
do_mmap (filp, vaddr, s, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 0);
+ up(&current->mm->mmap_sem);
shmiqs [minor].events = req.arg;
shmiqs [minor].mapped = 1;
return 0;
diff --git a/drivers/sound/724hwmcode.h b/drivers/sound/724hwmcode.h
new file mode 100644
index 00000000000000..75658352946582
--- /dev/null
+++ b/drivers/sound/724hwmcode.h
@@ -0,0 +1,1575 @@
+//=============================================================================
+// Copyright (c) 1997-1999 Yamaha Corporation. All Rights Reserved.
+//
+// Title:
+// hwmcode.c
+// Desc:
+// micro-code for CTRL & DSP
+//=============================================================================
+#ifndef _HWMCODE_
+#define _HWMCODE_
+
+static unsigned long int DspInst[] = {
+ 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
+ 0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
+ 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
+ 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+static unsigned long int CntrlInst[] = {
+ 0x000007, 0x240007, 0x0C0007, 0x1C0007,
+ 0x060007, 0x700002, 0x000020, 0x030040,
+ 0x007104, 0x004286, 0x030040, 0x000F0D,
+ 0x000810, 0x20043A, 0x000282, 0x00020D,
+ 0x000810, 0x20043A, 0x001282, 0x200E82,
+ 0x001A82, 0x032D0D, 0x000810, 0x10043A,
+ 0x02D38D, 0x000810, 0x18043A, 0x00010D,
+ 0x020015, 0x0000FD, 0x000020, 0x038860,
+ 0x039060, 0x038060, 0x038040, 0x038040,
+ 0x038040, 0x018040, 0x000A7D, 0x038040,
+ 0x038040, 0x018040, 0x200402, 0x000882,
+ 0x08001A, 0x000904, 0x015986, 0x000007,
+ 0x260007, 0x000007, 0x000007, 0x018A06,
+ 0x000007, 0x030C8D, 0x000810, 0x18043A,
+ 0x260007, 0x00087D, 0x018042, 0x00160A,
+ 0x04A206, 0x000007, 0x00218D, 0x000810,
+ 0x08043A, 0x21C206, 0x000007, 0x0007FD,
+ 0x018042, 0x08000A, 0x000904, 0x029386,
+ 0x000195, 0x090D04, 0x000007, 0x000820,
+ 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD,
+ 0x032206, 0x018040, 0x000A7D, 0x038042,
+ 0x13804A, 0x18000A, 0x001820, 0x059060,
+ 0x058860, 0x018040, 0x0000FD, 0x018042,
+ 0x70000A, 0x000115, 0x071144, 0x032386,
+ 0x030000, 0x007020, 0x034A06, 0x018040,
+ 0x00348D, 0x000810, 0x08043A, 0x21EA06,
+ 0x000007, 0x02D38D, 0x000810, 0x18043A,
+ 0x018206, 0x000007, 0x240007, 0x000F8D,
+ 0x000810, 0x00163A, 0x002402, 0x005C02,
+ 0x0028FD, 0x000020, 0x018040, 0x08000D,
+ 0x000815, 0x510984, 0x000007, 0x00004D,
+ 0x000E5D, 0x000E02, 0x00418D, 0x000810,
+ 0x08043A, 0x2C8A06, 0x000007, 0x00008D,
+ 0x000924, 0x000F02, 0x00458D, 0x000810,
+ 0x08043A, 0x2C8A06, 0x000007, 0x00387D,
+ 0x018042, 0x08000A, 0x001015, 0x010984,
+ 0x018386, 0x000007, 0x01AA06, 0x000007,
+ 0x0008FD, 0x018042, 0x18000A, 0x001904,
+ 0x218086, 0x280007, 0x001810, 0x28043A,
+ 0x280C02, 0x00000D, 0x000810, 0x28143A,
+ 0x08808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00020D, 0x189904, 0x000007,
+ 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x055A86, 0x000007,
+ 0x000100, 0x000A20, 0x00047D, 0x018040,
+ 0x018042, 0x20000A, 0x003015, 0x012144,
+ 0x034986, 0x000007, 0x002104, 0x034986,
+ 0x000007, 0x000F8D, 0x000810, 0x280C3A,
+ 0x023944, 0x06C986, 0x000007, 0x001810,
+ 0x28043A, 0x08810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x002810, 0x78003A,
+ 0x00688D, 0x000810, 0x08043A, 0x288A06,
+ 0x000007, 0x00400D, 0x001015, 0x189904,
+ 0x292904, 0x393904, 0x000007, 0x060206,
+ 0x000007, 0x0004F5, 0x00007D, 0x000020,
+ 0x00008D, 0x010860, 0x018040, 0x00047D,
+ 0x038042, 0x21804A, 0x18000A, 0x021944,
+ 0x215886, 0x000007, 0x004075, 0x71F104,
+ 0x000007, 0x010042, 0x28000A, 0x002904,
+ 0x212086, 0x000007, 0x003C0D, 0x30A904,
+ 0x000007, 0x00077D, 0x018042, 0x08000A,
+ 0x000904, 0x07DA86, 0x00057D, 0x002820,
+ 0x03B060, 0x07F206, 0x018040, 0x003020,
+ 0x03A860, 0x018040, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x07FA86, 0x000007,
+ 0x00057D, 0x018042, 0x28040A, 0x000E8D,
+ 0x000810, 0x280C3A, 0x00000D, 0x000810,
+ 0x28143A, 0x09000D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x003DFD, 0x000020,
+ 0x018040, 0x00107D, 0x008D8D, 0x000810,
+ 0x08043A, 0x288A06, 0x000007, 0x000815,
+ 0x08001A, 0x010984, 0x095186, 0x00137D,
+ 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x038A60, 0x018040, 0x007FBD, 0x383DC4,
+ 0x000007, 0x001A7D, 0x001375, 0x018042,
+ 0x09004A, 0x10000A, 0x0B8D04, 0x139504,
+ 0x000007, 0x000820, 0x019060, 0x001104,
+ 0x212086, 0x010040, 0x0017FD, 0x018042,
+ 0x08000A, 0x000904, 0x212286, 0x000007,
+ 0x00197D, 0x038042, 0x09804A, 0x10000A,
+ 0x000924, 0x001664, 0x0011FD, 0x038042,
+ 0x2B804A, 0x19804A, 0x00008D, 0x218944,
+ 0x000007, 0x002244, 0x0AE186, 0x000007,
+ 0x001A64, 0x002A24, 0x00197D, 0x080102,
+ 0x100122, 0x000820, 0x039060, 0x018040,
+ 0x003DFD, 0x00008D, 0x000820, 0x018040,
+ 0x001375, 0x001A7D, 0x010042, 0x09804A,
+ 0x10000A, 0x00021D, 0x0189E4, 0x2992E4,
+ 0x309144, 0x000007, 0x00060D, 0x000A15,
+ 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4,
+ 0x000464, 0x01B3E4, 0x0232E4, 0x000464,
+ 0x000464, 0x000464, 0x000464, 0x00040D,
+ 0x08B1C4, 0x000007, 0x000820, 0x000BF5,
+ 0x030040, 0x00197D, 0x038042, 0x09804A,
+ 0x000A24, 0x08000A, 0x080E64, 0x000007,
+ 0x100122, 0x000820, 0x031060, 0x010040,
+ 0x0064AC, 0x00027D, 0x000020, 0x018040,
+ 0x00107D, 0x018042, 0x0011FD, 0x3B804A,
+ 0x09804A, 0x20000A, 0x000095, 0x1A1144,
+ 0x00A144, 0x0D2086, 0x00040D, 0x00B984,
+ 0x0D2186, 0x0018FD, 0x018042, 0x0010FD,
+ 0x09804A, 0x28000A, 0x000095, 0x010924,
+ 0x002A64, 0x0D1186, 0x000007, 0x002904,
+ 0x0D2286, 0x000007, 0x0D2A06, 0x080002,
+ 0x00008D, 0x00387D, 0x000820, 0x018040,
+ 0x00127D, 0x018042, 0x10000A, 0x003904,
+ 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984,
+ 0x0DA186, 0x000025, 0x0E7A06, 0x00002D,
+ 0x000015, 0x00082D, 0x02C78D, 0x000820,
+ 0x0EC206, 0x00000D, 0x7F8035, 0x00B984,
+ 0x0E7186, 0x400025, 0x00008D, 0x110944,
+ 0x000007, 0x00018D, 0x109504, 0x000007,
+ 0x009164, 0x000424, 0x000424, 0x000424,
+ 0x100102, 0x280002, 0x02C68D, 0x000820,
+ 0x0EC206, 0x00018D, 0x00042D, 0x00008D,
+ 0x109504, 0x000007, 0x00020D, 0x109184,
+ 0x000007, 0x02C70D, 0x000820, 0x00008D,
+ 0x0038FD, 0x018040, 0x003BFD, 0x001020,
+ 0x03A860, 0x000815, 0x313184, 0x212184,
+ 0x000007, 0x03B060, 0x03A060, 0x018040,
+ 0x0022FD, 0x000095, 0x010924, 0x000424,
+ 0x000424, 0x001264, 0x100102, 0x000820,
+ 0x039060, 0x018040, 0x001924, 0x00FB8D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x000424,
+ 0x000424, 0x00117D, 0x018042, 0x08000A,
+ 0x000A24, 0x280502, 0x280C02, 0x09800D,
+ 0x000820, 0x0002FD, 0x018040, 0x200007,
+ 0x0022FD, 0x018042, 0x08000A, 0x000095,
+ 0x280DC4, 0x011924, 0x00197D, 0x018042,
+ 0x0011FD, 0x09804A, 0x10000A, 0x0000B5,
+ 0x113144, 0x0A8D04, 0x000007, 0x080A44,
+ 0x129504, 0x000007, 0x0023FD, 0x001020,
+ 0x038040, 0x101244, 0x000007, 0x000820,
+ 0x039060, 0x018040, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x10FA86, 0x000007,
+ 0x003BFD, 0x000100, 0x000A10, 0x0B807A,
+ 0x13804A, 0x090984, 0x000007, 0x000095,
+ 0x013D04, 0x118086, 0x10000A, 0x100002,
+ 0x090984, 0x000007, 0x038042, 0x11804A,
+ 0x090D04, 0x000007, 0x10000A, 0x090D84,
+ 0x000007, 0x00257D, 0x000820, 0x018040,
+ 0x00010D, 0x000810, 0x28143A, 0x00127D,
+ 0x018042, 0x20000A, 0x00197D, 0x018042,
+ 0x00117D, 0x31804A, 0x10000A, 0x003124,
+ 0x01280D, 0x00397D, 0x000820, 0x058040,
+ 0x038042, 0x09844A, 0x000606, 0x08040A,
+ 0x300102, 0x003124, 0x000424, 0x000424,
+ 0x001224, 0x280502, 0x001A4C, 0x130186,
+ 0x700002, 0x00002D, 0x030000, 0x00387D,
+ 0x018042, 0x10000A, 0x132A06, 0x002124,
+ 0x0000AD, 0x100002, 0x00010D, 0x000924,
+ 0x006B24, 0x01368D, 0x00397D, 0x000820,
+ 0x058040, 0x038042, 0x09844A, 0x000606,
+ 0x08040A, 0x003264, 0x00008D, 0x000A24,
+ 0x001020, 0x00227D, 0x018040, 0x013C0D,
+ 0x000810, 0x08043A, 0x29D206, 0x000007,
+ 0x002820, 0x00207D, 0x018040, 0x00117D,
+ 0x038042, 0x13804A, 0x33800A, 0x00387D,
+ 0x018042, 0x08000A, 0x000904, 0x163A86,
+ 0x000007, 0x00008D, 0x030964, 0x01478D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x380102,
+ 0x000424, 0x000424, 0x001224, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x14A286,
+ 0x000007, 0x280502, 0x001A4C, 0x163986,
+ 0x000007, 0x032164, 0x00632C, 0x003DFD,
+ 0x018042, 0x08000A, 0x000095, 0x090904,
+ 0x000007, 0x000820, 0x001A4C, 0x156186,
+ 0x018040, 0x030000, 0x157A06, 0x002124,
+ 0x00010D, 0x000924, 0x006B24, 0x015B8D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x003A64,
+ 0x000095, 0x001224, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x15DA86, 0x000007,
+ 0x01628D, 0x000810, 0x08043A, 0x29D206,
+ 0x000007, 0x14D206, 0x000007, 0x007020,
+ 0x08010A, 0x10012A, 0x0020FD, 0x038860,
+ 0x039060, 0x018040, 0x00227D, 0x018042,
+ 0x003DFD, 0x08000A, 0x31844A, 0x000904,
+ 0x16D886, 0x18008B, 0x00008D, 0x189904,
+ 0x00312C, 0x17AA06, 0x000007, 0x00324C,
+ 0x173386, 0x000007, 0x001904, 0x173086,
+ 0x000007, 0x000095, 0x199144, 0x00222C,
+ 0x003124, 0x00636C, 0x000E3D, 0x001375,
+ 0x000BFD, 0x010042, 0x09804A, 0x10000A,
+ 0x038AEC, 0x0393EC, 0x00224C, 0x17A986,
+ 0x000007, 0x00008D, 0x189904, 0x00226C,
+ 0x00322C, 0x30050A, 0x301DAB, 0x002083,
+ 0x0018FD, 0x018042, 0x08000A, 0x018924,
+ 0x300502, 0x001083, 0x001875, 0x010042,
+ 0x10000A, 0x00008D, 0x010924, 0x001375,
+ 0x330542, 0x330CCB, 0x332CCB, 0x3334CB,
+ 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB,
+ 0x305C8B, 0x006083, 0x0002F5, 0x010042,
+ 0x08000A, 0x000904, 0x187A86, 0x000007,
+ 0x001E2D, 0x0005FD, 0x018042, 0x08000A,
+ 0x028924, 0x280502, 0x00060D, 0x000810,
+ 0x280C3A, 0x00008D, 0x000810, 0x28143A,
+ 0x0A808D, 0x000820, 0x0002F5, 0x010040,
+ 0x220007, 0x001275, 0x030042, 0x21004A,
+ 0x00008D, 0x1A0944, 0x000007, 0x01980D,
+ 0x000810, 0x08043A, 0x2B2206, 0x000007,
+ 0x0001F5, 0x030042, 0x0D004A, 0x10000A,
+ 0x089144, 0x000007, 0x000820, 0x010040,
+ 0x0025F5, 0x0A3144, 0x000007, 0x000820,
+ 0x032860, 0x030040, 0x00217D, 0x038042,
+ 0x0B804A, 0x10000A, 0x000820, 0x031060,
+ 0x030040, 0x00008D, 0x000124, 0x00012C,
+ 0x000E64, 0x001A64, 0x00636C, 0x08010A,
+ 0x10012A, 0x000820, 0x031060, 0x030040,
+ 0x0020FD, 0x018042, 0x08000A, 0x00227D,
+ 0x018042, 0x10000A, 0x000820, 0x031060,
+ 0x030040, 0x00197D, 0x018042, 0x08000A,
+ 0x0022FD, 0x038042, 0x10000A, 0x000820,
+ 0x031060, 0x030040, 0x090D04, 0x000007,
+ 0x000820, 0x030040, 0x038042, 0x0B804A,
+ 0x10000A, 0x000820, 0x031060, 0x030040,
+ 0x038042, 0x13804A, 0x19804A, 0x110D04,
+ 0x198D04, 0x000007, 0x08000A, 0x001020,
+ 0x031860, 0x030860, 0x030040, 0x00008D,
+ 0x0B0944, 0x000007, 0x000820, 0x010040,
+ 0x0005F5, 0x030042, 0x08000A, 0x000820,
+ 0x010040, 0x0000F5, 0x010042, 0x08000A,
+ 0x000904, 0x1C6086, 0x001E75, 0x030042,
+ 0x01044A, 0x000C0A, 0x1C7206, 0x000007,
+ 0x000402, 0x000C02, 0x00177D, 0x001AF5,
+ 0x018042, 0x03144A, 0x031C4A, 0x03244A,
+ 0x032C4A, 0x03344A, 0x033C4A, 0x03444A,
+ 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD,
+ 0x030042, 0x0B004A, 0x1B804A, 0x13804A,
+ 0x20000A, 0x089144, 0x19A144, 0x0389E4,
+ 0x0399EC, 0x005502, 0x005D0A, 0x030042,
+ 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
+ 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
+ 0x006502, 0x006D0A, 0x030042, 0x0B004A,
+ 0x19004A, 0x2B804A, 0x13804A, 0x21804A,
+ 0x30000A, 0x089144, 0x19A144, 0x2AB144,
+ 0x0389E4, 0x0399EC, 0x007502, 0x007D0A,
+ 0x03A9E4, 0x000702, 0x00107D, 0x000415,
+ 0x018042, 0x08000A, 0x0109E4, 0x000F02,
+ 0x002AF5, 0x0019FD, 0x010042, 0x09804A,
+ 0x10000A, 0x000934, 0x001674, 0x0029F5,
+ 0x010042, 0x10000A, 0x00917C, 0x002075,
+ 0x010042, 0x08000A, 0x000904, 0x1ED286,
+ 0x0026F5, 0x0027F5, 0x030042, 0x09004A,
+ 0x10000A, 0x000A3C, 0x00167C, 0x001A75,
+ 0x000BFD, 0x010042, 0x51804A, 0x48000A,
+ 0x160007, 0x001075, 0x010042, 0x282C0A,
+ 0x281D12, 0x282512, 0x001F32, 0x1E0007,
+ 0x0E0007, 0x001975, 0x010042, 0x002DF5,
+ 0x0D004A, 0x10000A, 0x009144, 0x1FB286,
+ 0x010042, 0x28340A, 0x000E5D, 0x00008D,
+ 0x000375, 0x000820, 0x010040, 0x05D2F4,
+ 0x54D104, 0x00735C, 0x205386, 0x000007,
+ 0x0C0007, 0x080007, 0x0A0007, 0x02040D,
+ 0x000810, 0x08043A, 0x332206, 0x000007,
+ 0x205A06, 0x000007, 0x080007, 0x002275,
+ 0x010042, 0x20000A, 0x002104, 0x212086,
+ 0x001E2D, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x209286, 0x000007, 0x002010,
+ 0x30043A, 0x00057D, 0x0180C3, 0x08000A,
+ 0x028924, 0x280502, 0x280C02, 0x0A810D,
+ 0x000820, 0x0002F5, 0x010040, 0x220007,
+ 0x0004FD, 0x018042, 0x70000A, 0x030000,
+ 0x007020, 0x06FA06, 0x018040, 0x02180D,
+ 0x000810, 0x08043A, 0x2B2206, 0x000007,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x218A86, 0x000007, 0x01F206, 0x000007,
+ 0x000875, 0x0009FD, 0x00010D, 0x220A06,
+ 0x000295, 0x000B75, 0x00097D, 0x00000D,
+ 0x000515, 0x010042, 0x18000A, 0x001904,
+ 0x287886, 0x0006F5, 0x001020, 0x010040,
+ 0x0004F5, 0x000820, 0x010040, 0x000775,
+ 0x010042, 0x09804A, 0x10000A, 0x001124,
+ 0x000904, 0x22BA86, 0x000815, 0x080102,
+ 0x101204, 0x22DA06, 0x000575, 0x081204,
+ 0x000007, 0x100102, 0x000575, 0x000425,
+ 0x021124, 0x100102, 0x000820, 0x031060,
+ 0x010040, 0x001924, 0x287886, 0x00008D,
+ 0x000464, 0x009D04, 0x278886, 0x180102,
+ 0x000575, 0x010042, 0x28040A, 0x00018D,
+ 0x000924, 0x280D02, 0x00000D, 0x000924,
+ 0x281502, 0x10000D, 0x000820, 0x0002F5,
+ 0x010040, 0x200007, 0x001175, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x23C286,
+ 0x000007, 0x000100, 0x080B20, 0x130B60,
+ 0x1B0B60, 0x030A60, 0x010040, 0x050042,
+ 0x3D004A, 0x35004A, 0x2D004A, 0x20000A,
+ 0x0006F5, 0x010042, 0x28140A, 0x0004F5,
+ 0x010042, 0x08000A, 0x000315, 0x010D04,
+ 0x24CA86, 0x004015, 0x000095, 0x010D04,
+ 0x24B886, 0x100022, 0x10002A, 0x24E206,
+ 0x000007, 0x333104, 0x2AA904, 0x000007,
+ 0x032124, 0x280502, 0x001124, 0x000424,
+ 0x000424, 0x003224, 0x00292C, 0x00636C,
+ 0x25F386, 0x000007, 0x02B164, 0x000464,
+ 0x000464, 0x00008D, 0x000A64, 0x280D02,
+ 0x10008D, 0x000820, 0x0002F5, 0x010040,
+ 0x220007, 0x00008D, 0x38B904, 0x000007,
+ 0x03296C, 0x30010A, 0x0002F5, 0x010042,
+ 0x08000A, 0x000904, 0x25BA86, 0x000007,
+ 0x02312C, 0x28050A, 0x00008D, 0x01096C,
+ 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x001124, 0x000424,
+ 0x000424, 0x003224, 0x300102, 0x032944,
+ 0x267A86, 0x000007, 0x300002, 0x0004F5,
+ 0x010042, 0x08000A, 0x000315, 0x010D04,
+ 0x26C086, 0x003124, 0x000464, 0x300102,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x26CA86, 0x000007, 0x003124, 0x300502,
+ 0x003924, 0x300583, 0x000883, 0x0005F5,
+ 0x010042, 0x28040A, 0x00008D, 0x008124,
+ 0x280D02, 0x00008D, 0x008124, 0x281502,
+ 0x10018D, 0x000820, 0x0002F5, 0x010040,
+ 0x220007, 0x001025, 0x000575, 0x030042,
+ 0x09004A, 0x10000A, 0x0A0904, 0x121104,
+ 0x000007, 0x001020, 0x050860, 0x050040,
+ 0x0006FD, 0x018042, 0x09004A, 0x10000A,
+ 0x0000A5, 0x0A0904, 0x121104, 0x000007,
+ 0x000820, 0x019060, 0x010040, 0x0002F5,
+ 0x010042, 0x08000A, 0x000904, 0x284286,
+ 0x000007, 0x230A06, 0x000007, 0x000606,
+ 0x000007, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x289286, 0x000007, 0x000100,
+ 0x080B20, 0x138B60, 0x1B8B60, 0x238B60,
+ 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60,
+ 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60,
+ 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60,
+ 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60,
+ 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60,
+ 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60,
+ 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60,
+ 0x000606, 0x018040, 0x00008D, 0x000A64,
+ 0x280D02, 0x000A24, 0x00027D, 0x018042,
+ 0x10000A, 0x001224, 0x0003FD, 0x018042,
+ 0x08000A, 0x000904, 0x2A8286, 0x000007,
+ 0x00018D, 0x000A24, 0x000464, 0x000464,
+ 0x080102, 0x000924, 0x000424, 0x000424,
+ 0x100102, 0x02000D, 0x009144, 0x2AD986,
+ 0x000007, 0x0001FD, 0x018042, 0x08000A,
+ 0x000A44, 0x2ABB86, 0x018042, 0x0A000D,
+ 0x000820, 0x0002FD, 0x018040, 0x200007,
+ 0x00027D, 0x001020, 0x000606, 0x018040,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x2B2A86, 0x000007, 0x00037D, 0x018042,
+ 0x08000A, 0x000904, 0x2B5A86, 0x000007,
+ 0x000075, 0x002E7D, 0x010042, 0x0B804A,
+ 0x000020, 0x000904, 0x000686, 0x010040,
+ 0x31844A, 0x30048B, 0x000883, 0x00008D,
+ 0x000810, 0x28143A, 0x00008D, 0x000810,
+ 0x280C3A, 0x000675, 0x010042, 0x08000A,
+ 0x003815, 0x010924, 0x280502, 0x0B000D,
+ 0x000820, 0x0002F5, 0x010040, 0x000606,
+ 0x220007, 0x000464, 0x000464, 0x000606,
+ 0x000007, 0x000134, 0x007F8D, 0x00093C,
+ 0x281D12, 0x282512, 0x001F32, 0x0E0007,
+ 0x00010D, 0x00037D, 0x000820, 0x018040,
+ 0x05D2F4, 0x000007, 0x080007, 0x00037D,
+ 0x018042, 0x08000A, 0x000904, 0x2D0286,
+ 0x000007, 0x000606, 0x000007, 0x000007,
+ 0x000012, 0x100007, 0x320007, 0x600007,
+ 0x100080, 0x48001A, 0x004904, 0x2D6186,
+ 0x000007, 0x001210, 0x58003A, 0x000145,
+ 0x5C5D04, 0x000007, 0x000080, 0x48001A,
+ 0x004904, 0x2DB186, 0x000007, 0x001210,
+ 0x50003A, 0x005904, 0x2E0886, 0x000045,
+ 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524,
+ 0x004224, 0x500102, 0x200502, 0x000082,
+ 0x40001A, 0x004104, 0x2E3986, 0x000007,
+ 0x003865, 0x40001A, 0x004020, 0x00104D,
+ 0x04C184, 0x301B86, 0x000040, 0x040007,
+ 0x000165, 0x000145, 0x004020, 0x000040,
+ 0x000765, 0x080080, 0x40001A, 0x004104,
+ 0x2EC986, 0x000007, 0x001210, 0x40003A,
+ 0x004104, 0x2F2286, 0x00004D, 0x0000CD,
+ 0x004810, 0x20043A, 0x000882, 0x40001A,
+ 0x004104, 0x2F3186, 0x000007, 0x004820,
+ 0x005904, 0x300886, 0x000040, 0x0007E5,
+ 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0,
+ 0x4216E0, 0x021260, 0x000040, 0x000032,
+ 0x400075, 0x00007D, 0x07D574, 0x200512,
+ 0x000082, 0x40001A, 0x004104, 0x2FE186,
+ 0x000007, 0x037206, 0x640007, 0x060007,
+ 0x0000E5, 0x000020, 0x000040, 0x000A65,
+ 0x000020, 0x020040, 0x020040, 0x000040,
+ 0x000165, 0x000042, 0x70000A, 0x007104,
+ 0x30A286, 0x000007, 0x018206, 0x640007,
+ 0x050000, 0x007020, 0x000040, 0x037206,
+ 0x640007, 0x000007, 0x00306D, 0x028860,
+ 0x029060, 0x08000A, 0x028860, 0x008040,
+ 0x100012, 0x00100D, 0x009184, 0x314186,
+ 0x000E0D, 0x009184, 0x325186, 0x000007,
+ 0x300007, 0x001020, 0x003B6D, 0x008040,
+ 0x000080, 0x08001A, 0x000904, 0x316186,
+ 0x000007, 0x001220, 0x000DED, 0x008040,
+ 0x008042, 0x10000A, 0x40000D, 0x109544,
+ 0x000007, 0x001020, 0x000DED, 0x008040,
+ 0x008042, 0x20040A, 0x000082, 0x08001A,
+ 0x000904, 0x31F186, 0x000007, 0x003B6D,
+ 0x008042, 0x08000A, 0x000E15, 0x010984,
+ 0x329B86, 0x600007, 0x08001A, 0x000C15,
+ 0x010984, 0x328386, 0x000020, 0x1A0007,
+ 0x0002ED, 0x008040, 0x620007, 0x00306D,
+ 0x028042, 0x0A804A, 0x000820, 0x0A804A,
+ 0x000606, 0x10804A, 0x000007, 0x282512,
+ 0x001F32, 0x05D2F4, 0x54D104, 0x00735C,
+ 0x000786, 0x000007, 0x0C0007, 0x0A0007,
+ 0x1C0007, 0x003465, 0x020040, 0x004820,
+ 0x025060, 0x40000A, 0x024060, 0x000040,
+ 0x454944, 0x000007, 0x004020, 0x003AE5,
+ 0x000040, 0x0028E5, 0x000042, 0x48000A,
+ 0x004904, 0x386886, 0x002C65, 0x000042,
+ 0x40000A, 0x0000D5, 0x454104, 0x000007,
+ 0x000655, 0x054504, 0x34F286, 0x0001D5,
+ 0x054504, 0x34F086, 0x002B65, 0x000042,
+ 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4,
+ 0x000007, 0x454504, 0x000007, 0x0000CD,
+ 0x444944, 0x000007, 0x454504, 0x000007,
+ 0x00014D, 0x554944, 0x000007, 0x045144,
+ 0x34E986, 0x002C65, 0x000042, 0x48000A,
+ 0x4CD104, 0x000007, 0x04C144, 0x34F386,
+ 0x000007, 0x160007, 0x002CE5, 0x040042,
+ 0x40000A, 0x004020, 0x000040, 0x002965,
+ 0x000042, 0x40000A, 0x004104, 0x356086,
+ 0x000007, 0x002402, 0x36A206, 0x005C02,
+ 0x0025E5, 0x000042, 0x40000A, 0x004274,
+ 0x002AE5, 0x000042, 0x40000A, 0x004274,
+ 0x500112, 0x0029E5, 0x000042, 0x40000A,
+ 0x004234, 0x454104, 0x000007, 0x004020,
+ 0x000040, 0x003EE5, 0x000020, 0x000040,
+ 0x002DE5, 0x400152, 0x50000A, 0x045144,
+ 0x364A86, 0x0000C5, 0x003EE5, 0x004020,
+ 0x000040, 0x002BE5, 0x000042, 0x40000A,
+ 0x404254, 0x000007, 0x002AE5, 0x004020,
+ 0x000040, 0x500132, 0x040134, 0x005674,
+ 0x0029E5, 0x020042, 0x42000A, 0x000042,
+ 0x50000A, 0x05417C, 0x0028E5, 0x000042,
+ 0x48000A, 0x0000C5, 0x4CC144, 0x371086,
+ 0x0026E5, 0x0027E5, 0x020042, 0x40004A,
+ 0x50000A, 0x00423C, 0x00567C, 0x0028E5,
+ 0x004820, 0x000040, 0x281D12, 0x282512,
+ 0x001F72, 0x002965, 0x000042, 0x40000A,
+ 0x004104, 0x37AA86, 0x0E0007, 0x160007,
+ 0x1E0007, 0x003EE5, 0x000042, 0x40000A,
+ 0x004104, 0x37E886, 0x002D65, 0x000042,
+ 0x28340A, 0x003465, 0x020042, 0x42004A,
+ 0x004020, 0x4A004A, 0x50004A, 0x05D2F4,
+ 0x54D104, 0x00735C, 0x385186, 0x000007,
+ 0x000606, 0x080007, 0x0C0007, 0x080007,
+ 0x0A0007, 0x0001E5, 0x020045, 0x004020,
+ 0x000060, 0x000365, 0x000040, 0x002E65,
+ 0x001A20, 0x0A1A60, 0x000040, 0x003465,
+ 0x020042, 0x42004A, 0x004020, 0x4A004A,
+ 0x000606, 0x50004A, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000
+};
+
+// --------------------------------------------
+// DS-1E Controller InstructionRAM Code
+// 1999/06/21
+// Buf441 slot is Enabled.
+// --------------------------------------------
+// 04/09?@creat
+// 04/12 stop nise fix
+// 06/21?@WorkingOff timming
+static unsigned long int CntrlInst1E[] = {
+ 0x000007, 0x240007, 0x0C0007, 0x1C0007,
+ 0x060007, 0x700002, 0x000020, 0x030040,
+ 0x007104, 0x004286, 0x030040, 0x000F0D,
+ 0x000810, 0x20043A, 0x000282, 0x00020D,
+ 0x000810, 0x20043A, 0x001282, 0x200E82,
+ 0x00800D, 0x000810, 0x20043A, 0x001A82,
+ 0x03460D, 0x000810, 0x10043A, 0x02EC0D,
+ 0x000810, 0x18043A, 0x00010D, 0x020015,
+ 0x0000FD, 0x000020, 0x038860, 0x039060,
+ 0x038060, 0x038040, 0x038040, 0x038040,
+ 0x018040, 0x000A7D, 0x038040, 0x038040,
+ 0x018040, 0x200402, 0x000882, 0x08001A,
+ 0x000904, 0x017186, 0x000007, 0x260007,
+ 0x400007, 0x000007, 0x03258D, 0x000810,
+ 0x18043A, 0x260007, 0x284402, 0x00087D,
+ 0x018042, 0x00160A, 0x05A206, 0x000007,
+ 0x440007, 0x00230D, 0x000810, 0x08043A,
+ 0x22FA06, 0x000007, 0x0007FD, 0x018042,
+ 0x08000A, 0x000904, 0x02AB86, 0x000195,
+ 0x090D04, 0x000007, 0x000820, 0x0000F5,
+ 0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
+ 0x018040, 0x000A7D, 0x038042, 0x13804A,
+ 0x18000A, 0x001820, 0x059060, 0x058860,
+ 0x018040, 0x0000FD, 0x018042, 0x70000A,
+ 0x000115, 0x071144, 0x033B86, 0x030000,
+ 0x007020, 0x036206, 0x018040, 0x00360D,
+ 0x000810, 0x08043A, 0x232206, 0x000007,
+ 0x02EC0D, 0x000810, 0x18043A, 0x019A06,
+ 0x000007, 0x240007, 0x000F8D, 0x000810,
+ 0x00163A, 0x002402, 0x005C02, 0x0028FD,
+ 0x000020, 0x018040, 0x08000D, 0x000815,
+ 0x510984, 0x000007, 0x00004D, 0x000E5D,
+ 0x000E02, 0x00430D, 0x000810, 0x08043A,
+ 0x2E1206, 0x000007, 0x00008D, 0x000924,
+ 0x000F02, 0x00470D, 0x000810, 0x08043A,
+ 0x2E1206, 0x000007, 0x480480, 0x001210,
+ 0x28043A, 0x00778D, 0x000810, 0x280C3A,
+ 0x00068D, 0x000810, 0x28143A, 0x284402,
+ 0x03258D, 0x000810, 0x18043A, 0x07FF8D,
+ 0x000820, 0x0002FD, 0x018040, 0x260007,
+ 0x200007, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x051286, 0x000007, 0x240007,
+ 0x02EC0D, 0x000810, 0x18043A, 0x00387D,
+ 0x018042, 0x08000A, 0x001015, 0x010984,
+ 0x019B86, 0x000007, 0x01B206, 0x000007,
+ 0x0008FD, 0x018042, 0x18000A, 0x001904,
+ 0x22B886, 0x280007, 0x001810, 0x28043A,
+ 0x280C02, 0x00000D, 0x000810, 0x28143A,
+ 0x08808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00020D, 0x189904, 0x000007,
+ 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x065A86, 0x000007,
+ 0x000100, 0x000A20, 0x00047D, 0x018040,
+ 0x018042, 0x20000A, 0x003015, 0x012144,
+ 0x036186, 0x000007, 0x002104, 0x036186,
+ 0x000007, 0x000F8D, 0x000810, 0x280C3A,
+ 0x023944, 0x07C986, 0x000007, 0x001810,
+ 0x28043A, 0x08810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x002810, 0x78003A,
+ 0x00788D, 0x000810, 0x08043A, 0x2A1206,
+ 0x000007, 0x00400D, 0x001015, 0x189904,
+ 0x292904, 0x393904, 0x000007, 0x070206,
+ 0x000007, 0x0004F5, 0x00007D, 0x000020,
+ 0x00008D, 0x010860, 0x018040, 0x00047D,
+ 0x038042, 0x21804A, 0x18000A, 0x021944,
+ 0x229086, 0x000007, 0x004075, 0x71F104,
+ 0x000007, 0x010042, 0x28000A, 0x002904,
+ 0x225886, 0x000007, 0x003C0D, 0x30A904,
+ 0x000007, 0x00077D, 0x018042, 0x08000A,
+ 0x000904, 0x08DA86, 0x00057D, 0x002820,
+ 0x03B060, 0x08F206, 0x018040, 0x003020,
+ 0x03A860, 0x018040, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x08FA86, 0x000007,
+ 0x00057D, 0x018042, 0x28040A, 0x000E8D,
+ 0x000810, 0x280C3A, 0x00000D, 0x000810,
+ 0x28143A, 0x09000D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x003DFD, 0x000020,
+ 0x018040, 0x00107D, 0x009D8D, 0x000810,
+ 0x08043A, 0x2A1206, 0x000007, 0x000815,
+ 0x08001A, 0x010984, 0x0A5186, 0x00137D,
+ 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x038A60, 0x018040, 0x00107D, 0x018042,
+ 0x08000A, 0x000215, 0x010984, 0x3A8186,
+ 0x000007, 0x007FBD, 0x383DC4, 0x000007,
+ 0x001A7D, 0x001375, 0x018042, 0x09004A,
+ 0x10000A, 0x0B8D04, 0x139504, 0x000007,
+ 0x000820, 0x019060, 0x001104, 0x225886,
+ 0x010040, 0x0017FD, 0x018042, 0x08000A,
+ 0x000904, 0x225A86, 0x000007, 0x00197D,
+ 0x038042, 0x09804A, 0x10000A, 0x000924,
+ 0x001664, 0x0011FD, 0x038042, 0x2B804A,
+ 0x19804A, 0x00008D, 0x218944, 0x000007,
+ 0x002244, 0x0C1986, 0x000007, 0x001A64,
+ 0x002A24, 0x00197D, 0x080102, 0x100122,
+ 0x000820, 0x039060, 0x018040, 0x003DFD,
+ 0x00008D, 0x000820, 0x018040, 0x001375,
+ 0x001A7D, 0x010042, 0x09804A, 0x10000A,
+ 0x00021D, 0x0189E4, 0x2992E4, 0x309144,
+ 0x000007, 0x00060D, 0x000A15, 0x000C1D,
+ 0x001025, 0x00A9E4, 0x012BE4, 0x000464,
+ 0x01B3E4, 0x0232E4, 0x000464, 0x000464,
+ 0x000464, 0x000464, 0x00040D, 0x08B1C4,
+ 0x000007, 0x000820, 0x000BF5, 0x030040,
+ 0x00197D, 0x038042, 0x09804A, 0x000A24,
+ 0x08000A, 0x080E64, 0x000007, 0x100122,
+ 0x000820, 0x031060, 0x010040, 0x0064AC,
+ 0x00027D, 0x000020, 0x018040, 0x00107D,
+ 0x018042, 0x0011FD, 0x3B804A, 0x09804A,
+ 0x20000A, 0x000095, 0x1A1144, 0x00A144,
+ 0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
+ 0x0018FD, 0x018042, 0x0010FD, 0x09804A,
+ 0x28000A, 0x000095, 0x010924, 0x002A64,
+ 0x0E4986, 0x000007, 0x002904, 0x0E5A86,
+ 0x000007, 0x0E6206, 0x080002, 0x00008D,
+ 0x00387D, 0x000820, 0x018040, 0x00127D,
+ 0x018042, 0x10000A, 0x003904, 0x0F0986,
+ 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
+ 0x000025, 0x0FB206, 0x00002D, 0x000015,
+ 0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
+ 0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
+ 0x400025, 0x00008D, 0x110944, 0x000007,
+ 0x00018D, 0x109504, 0x000007, 0x009164,
+ 0x000424, 0x000424, 0x000424, 0x100102,
+ 0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
+ 0x00018D, 0x00042D, 0x00008D, 0x109504,
+ 0x000007, 0x00020D, 0x109184, 0x000007,
+ 0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
+ 0x018040, 0x003BFD, 0x001020, 0x03A860,
+ 0x000815, 0x313184, 0x212184, 0x000007,
+ 0x03B060, 0x03A060, 0x018040, 0x0022FD,
+ 0x000095, 0x010924, 0x000424, 0x000424,
+ 0x001264, 0x100102, 0x000820, 0x039060,
+ 0x018040, 0x001924, 0x010F0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x000424, 0x000424,
+ 0x00117D, 0x018042, 0x08000A, 0x000A24,
+ 0x280502, 0x280C02, 0x09800D, 0x000820,
+ 0x0002FD, 0x018040, 0x200007, 0x0022FD,
+ 0x018042, 0x08000A, 0x000095, 0x280DC4,
+ 0x011924, 0x00197D, 0x018042, 0x0011FD,
+ 0x09804A, 0x10000A, 0x0000B5, 0x113144,
+ 0x0A8D04, 0x000007, 0x080A44, 0x129504,
+ 0x000007, 0x0023FD, 0x001020, 0x038040,
+ 0x101244, 0x000007, 0x000820, 0x039060,
+ 0x018040, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x123286, 0x000007, 0x003BFD,
+ 0x000100, 0x000A10, 0x0B807A, 0x13804A,
+ 0x090984, 0x000007, 0x000095, 0x013D04,
+ 0x12B886, 0x10000A, 0x100002, 0x090984,
+ 0x000007, 0x038042, 0x11804A, 0x090D04,
+ 0x000007, 0x10000A, 0x090D84, 0x000007,
+ 0x00257D, 0x000820, 0x018040, 0x00010D,
+ 0x000810, 0x28143A, 0x00127D, 0x018042,
+ 0x20000A, 0x00197D, 0x018042, 0x00117D,
+ 0x31804A, 0x10000A, 0x003124, 0x013B8D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x300102,
+ 0x003124, 0x000424, 0x000424, 0x001224,
+ 0x280502, 0x001A4C, 0x143986, 0x700002,
+ 0x00002D, 0x030000, 0x00387D, 0x018042,
+ 0x10000A, 0x146206, 0x002124, 0x0000AD,
+ 0x100002, 0x00010D, 0x000924, 0x006B24,
+ 0x014A0D, 0x00397D, 0x000820, 0x058040,
+ 0x038042, 0x09844A, 0x000606, 0x08040A,
+ 0x003264, 0x00008D, 0x000A24, 0x001020,
+ 0x00227D, 0x018040, 0x014F8D, 0x000810,
+ 0x08043A, 0x2B5A06, 0x000007, 0x002820,
+ 0x00207D, 0x018040, 0x00117D, 0x038042,
+ 0x13804A, 0x33800A, 0x00387D, 0x018042,
+ 0x08000A, 0x000904, 0x177286, 0x000007,
+ 0x00008D, 0x030964, 0x015B0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x380102, 0x000424,
+ 0x000424, 0x001224, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x15DA86, 0x000007,
+ 0x280502, 0x001A4C, 0x177186, 0x000007,
+ 0x032164, 0x00632C, 0x003DFD, 0x018042,
+ 0x08000A, 0x000095, 0x090904, 0x000007,
+ 0x000820, 0x001A4C, 0x169986, 0x018040,
+ 0x030000, 0x16B206, 0x002124, 0x00010D,
+ 0x000924, 0x006B24, 0x016F0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x003A64, 0x000095,
+ 0x001224, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x171286, 0x000007, 0x01760D,
+ 0x000810, 0x08043A, 0x2B5A06, 0x000007,
+ 0x160A06, 0x000007, 0x007020, 0x08010A,
+ 0x10012A, 0x0020FD, 0x038860, 0x039060,
+ 0x018040, 0x00227D, 0x018042, 0x003DFD,
+ 0x08000A, 0x31844A, 0x000904, 0x181086,
+ 0x18008B, 0x00008D, 0x189904, 0x00312C,
+ 0x18E206, 0x000007, 0x00324C, 0x186B86,
+ 0x000007, 0x001904, 0x186886, 0x000007,
+ 0x000095, 0x199144, 0x00222C, 0x003124,
+ 0x00636C, 0x000E3D, 0x001375, 0x000BFD,
+ 0x010042, 0x09804A, 0x10000A, 0x038AEC,
+ 0x0393EC, 0x00224C, 0x18E186, 0x000007,
+ 0x00008D, 0x189904, 0x00226C, 0x00322C,
+ 0x30050A, 0x301DAB, 0x002083, 0x0018FD,
+ 0x018042, 0x08000A, 0x018924, 0x300502,
+ 0x001083, 0x001875, 0x010042, 0x10000A,
+ 0x00008D, 0x010924, 0x001375, 0x330542,
+ 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
+ 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
+ 0x006083, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x19B286, 0x000007, 0x001E2D,
+ 0x0005FD, 0x018042, 0x08000A, 0x028924,
+ 0x280502, 0x00060D, 0x000810, 0x280C3A,
+ 0x00008D, 0x000810, 0x28143A, 0x0A808D,
+ 0x000820, 0x0002F5, 0x010040, 0x220007,
+ 0x001275, 0x030042, 0x21004A, 0x00008D,
+ 0x1A0944, 0x000007, 0x01AB8D, 0x000810,
+ 0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
+ 0x030042, 0x0D004A, 0x10000A, 0x089144,
+ 0x000007, 0x000820, 0x010040, 0x0025F5,
+ 0x0A3144, 0x000007, 0x000820, 0x032860,
+ 0x030040, 0x00217D, 0x038042, 0x0B804A,
+ 0x10000A, 0x000820, 0x031060, 0x030040,
+ 0x00008D, 0x000124, 0x00012C, 0x000E64,
+ 0x001A64, 0x00636C, 0x08010A, 0x10012A,
+ 0x000820, 0x031060, 0x030040, 0x0020FD,
+ 0x018042, 0x08000A, 0x00227D, 0x018042,
+ 0x10000A, 0x000820, 0x031060, 0x030040,
+ 0x00197D, 0x018042, 0x08000A, 0x0022FD,
+ 0x038042, 0x10000A, 0x000820, 0x031060,
+ 0x030040, 0x090D04, 0x000007, 0x000820,
+ 0x030040, 0x038042, 0x0B804A, 0x10000A,
+ 0x000820, 0x031060, 0x030040, 0x038042,
+ 0x13804A, 0x19804A, 0x110D04, 0x198D04,
+ 0x000007, 0x08000A, 0x001020, 0x031860,
+ 0x030860, 0x030040, 0x00008D, 0x0B0944,
+ 0x000007, 0x000820, 0x010040, 0x0005F5,
+ 0x030042, 0x08000A, 0x000820, 0x010040,
+ 0x0000F5, 0x010042, 0x08000A, 0x000904,
+ 0x1D9886, 0x001E75, 0x030042, 0x01044A,
+ 0x000C0A, 0x1DAA06, 0x000007, 0x000402,
+ 0x000C02, 0x00177D, 0x001AF5, 0x018042,
+ 0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
+ 0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
+ 0x00043D, 0x0013F5, 0x001AFD, 0x030042,
+ 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
+ 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
+ 0x005502, 0x005D0A, 0x030042, 0x0B004A,
+ 0x1B804A, 0x13804A, 0x20000A, 0x089144,
+ 0x19A144, 0x0389E4, 0x0399EC, 0x006502,
+ 0x006D0A, 0x030042, 0x0B004A, 0x19004A,
+ 0x2B804A, 0x13804A, 0x21804A, 0x30000A,
+ 0x089144, 0x19A144, 0x2AB144, 0x0389E4,
+ 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
+ 0x000702, 0x00107D, 0x000415, 0x018042,
+ 0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
+ 0x0019FD, 0x010042, 0x09804A, 0x10000A,
+ 0x000934, 0x001674, 0x0029F5, 0x010042,
+ 0x10000A, 0x00917C, 0x002075, 0x010042,
+ 0x08000A, 0x000904, 0x200A86, 0x0026F5,
+ 0x0027F5, 0x030042, 0x09004A, 0x10000A,
+ 0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
+ 0x010042, 0x51804A, 0x48000A, 0x160007,
+ 0x001075, 0x010042, 0x282C0A, 0x281D12,
+ 0x282512, 0x001F32, 0x1E0007, 0x0E0007,
+ 0x001975, 0x010042, 0x002DF5, 0x0D004A,
+ 0x10000A, 0x009144, 0x20EA86, 0x010042,
+ 0x28340A, 0x000E5D, 0x00008D, 0x000375,
+ 0x000820, 0x010040, 0x05D2F4, 0x54D104,
+ 0x00735C, 0x218B86, 0x000007, 0x0C0007,
+ 0x080007, 0x0A0007, 0x02178D, 0x000810,
+ 0x08043A, 0x34B206, 0x000007, 0x219206,
+ 0x000007, 0x080007, 0x002275, 0x010042,
+ 0x20000A, 0x002104, 0x225886, 0x001E2D,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x21CA86, 0x000007, 0x002010, 0x30043A,
+ 0x00057D, 0x0180C3, 0x08000A, 0x028924,
+ 0x280502, 0x280C02, 0x0A810D, 0x000820,
+ 0x0002F5, 0x010040, 0x220007, 0x0004FD,
+ 0x018042, 0x70000A, 0x030000, 0x007020,
+ 0x07FA06, 0x018040, 0x022B8D, 0x000810,
+ 0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x22C286,
+ 0x000007, 0x020206, 0x000007, 0x000875,
+ 0x0009FD, 0x00010D, 0x234206, 0x000295,
+ 0x000B75, 0x00097D, 0x00000D, 0x000515,
+ 0x010042, 0x18000A, 0x001904, 0x2A0086,
+ 0x0006F5, 0x001020, 0x010040, 0x0004F5,
+ 0x000820, 0x010040, 0x000775, 0x010042,
+ 0x09804A, 0x10000A, 0x001124, 0x000904,
+ 0x23F286, 0x000815, 0x080102, 0x101204,
+ 0x241206, 0x000575, 0x081204, 0x000007,
+ 0x100102, 0x000575, 0x000425, 0x021124,
+ 0x100102, 0x000820, 0x031060, 0x010040,
+ 0x001924, 0x2A0086, 0x00008D, 0x000464,
+ 0x009D04, 0x291086, 0x180102, 0x000575,
+ 0x010042, 0x28040A, 0x00018D, 0x000924,
+ 0x280D02, 0x00000D, 0x000924, 0x281502,
+ 0x10000D, 0x000820, 0x0002F5, 0x010040,
+ 0x200007, 0x001175, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x24FA86, 0x000007,
+ 0x000100, 0x080B20, 0x130B60, 0x1B0B60,
+ 0x030A60, 0x010040, 0x050042, 0x3D004A,
+ 0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
+ 0x010042, 0x28140A, 0x0004F5, 0x010042,
+ 0x08000A, 0x000315, 0x010D04, 0x260286,
+ 0x004015, 0x000095, 0x010D04, 0x25F086,
+ 0x100022, 0x10002A, 0x261A06, 0x000007,
+ 0x333104, 0x2AA904, 0x000007, 0x032124,
+ 0x280502, 0x284402, 0x001124, 0x400102,
+ 0x000424, 0x000424, 0x003224, 0x00292C,
+ 0x00636C, 0x277386, 0x000007, 0x02B164,
+ 0x000464, 0x000464, 0x00008D, 0x000A64,
+ 0x280D02, 0x10008D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x00008D, 0x38B904,
+ 0x000007, 0x03296C, 0x30010A, 0x0002F5,
+ 0x010042, 0x08000A, 0x000904, 0x270286,
+ 0x000007, 0x00212C, 0x28050A, 0x00316C,
+ 0x00046C, 0x00046C, 0x28450A, 0x001124,
+ 0x006B64, 0x100102, 0x00008D, 0x01096C,
+ 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x004124, 0x000424,
+ 0x000424, 0x003224, 0x300102, 0x032944,
+ 0x27FA86, 0x000007, 0x300002, 0x0004F5,
+ 0x010042, 0x08000A, 0x000315, 0x010D04,
+ 0x284086, 0x003124, 0x000464, 0x300102,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x284A86, 0x000007, 0x284402, 0x003124,
+ 0x300502, 0x003924, 0x300583, 0x000883,
+ 0x0005F5, 0x010042, 0x28040A, 0x00008D,
+ 0x008124, 0x280D02, 0x00008D, 0x008124,
+ 0x281502, 0x10018D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x001025, 0x000575,
+ 0x030042, 0x09004A, 0x10000A, 0x0A0904,
+ 0x121104, 0x000007, 0x001020, 0x050860,
+ 0x050040, 0x0006FD, 0x018042, 0x09004A,
+ 0x10000A, 0x0000A5, 0x0A0904, 0x121104,
+ 0x000007, 0x000820, 0x019060, 0x010040,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x29CA86, 0x000007, 0x244206, 0x000007,
+ 0x000606, 0x000007, 0x0002F5, 0x010042,
+ 0x08000A, 0x000904, 0x2A1A86, 0x000007,
+ 0x000100, 0x080B20, 0x138B60, 0x1B8B60,
+ 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
+ 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
+ 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
+ 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
+ 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
+ 0x038A60, 0x000606, 0x018040, 0x00008D,
+ 0x000A64, 0x280D02, 0x000A24, 0x00027D,
+ 0x018042, 0x10000A, 0x001224, 0x0003FD,
+ 0x018042, 0x08000A, 0x000904, 0x2C0A86,
+ 0x000007, 0x00018D, 0x000A24, 0x000464,
+ 0x000464, 0x080102, 0x000924, 0x000424,
+ 0x000424, 0x100102, 0x02000D, 0x009144,
+ 0x2C6186, 0x000007, 0x0001FD, 0x018042,
+ 0x08000A, 0x000A44, 0x2C4386, 0x018042,
+ 0x0A000D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00027D, 0x001020, 0x000606,
+ 0x018040, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x2CB286, 0x000007, 0x00037D,
+ 0x018042, 0x08000A, 0x000904, 0x2CE286,
+ 0x000007, 0x000075, 0x002E7D, 0x010042,
+ 0x0B804A, 0x000020, 0x000904, 0x000686,
+ 0x010040, 0x31844A, 0x30048B, 0x000883,
+ 0x00008D, 0x000810, 0x28143A, 0x00008D,
+ 0x000810, 0x280C3A, 0x000675, 0x010042,
+ 0x08000A, 0x003815, 0x010924, 0x280502,
+ 0x0B000D, 0x000820, 0x0002F5, 0x010040,
+ 0x000606, 0x220007, 0x000464, 0x000464,
+ 0x000606, 0x000007, 0x000134, 0x007F8D,
+ 0x00093C, 0x281D12, 0x282512, 0x001F32,
+ 0x0E0007, 0x00010D, 0x00037D, 0x000820,
+ 0x018040, 0x05D2F4, 0x000007, 0x080007,
+ 0x00037D, 0x018042, 0x08000A, 0x000904,
+ 0x2E8A86, 0x000007, 0x000606, 0x000007,
+ 0x000007, 0x000012, 0x100007, 0x320007,
+ 0x600007, 0x460007, 0x100080, 0x48001A,
+ 0x004904, 0x2EF186, 0x000007, 0x001210,
+ 0x58003A, 0x000145, 0x5C5D04, 0x000007,
+ 0x000080, 0x48001A, 0x004904, 0x2F4186,
+ 0x000007, 0x001210, 0x50003A, 0x005904,
+ 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
+ 0x7FFF7D, 0x07D524, 0x004224, 0x500102,
+ 0x200502, 0x000082, 0x40001A, 0x004104,
+ 0x2FC986, 0x000007, 0x003865, 0x40001A,
+ 0x004020, 0x00104D, 0x04C184, 0x31AB86,
+ 0x000040, 0x040007, 0x000165, 0x000145,
+ 0x004020, 0x000040, 0x000765, 0x080080,
+ 0x40001A, 0x004104, 0x305986, 0x000007,
+ 0x001210, 0x40003A, 0x004104, 0x30B286,
+ 0x00004D, 0x0000CD, 0x004810, 0x20043A,
+ 0x000882, 0x40001A, 0x004104, 0x30C186,
+ 0x000007, 0x004820, 0x005904, 0x319886,
+ 0x000040, 0x0007E5, 0x200480, 0x2816A0,
+ 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
+ 0x000040, 0x000032, 0x400075, 0x00007D,
+ 0x07D574, 0x200512, 0x000082, 0x40001A,
+ 0x004104, 0x317186, 0x000007, 0x038A06,
+ 0x640007, 0x0000E5, 0x000020, 0x000040,
+ 0x000A65, 0x000020, 0x020040, 0x020040,
+ 0x000040, 0x000165, 0x000042, 0x70000A,
+ 0x007104, 0x323286, 0x000007, 0x060007,
+ 0x019A06, 0x640007, 0x050000, 0x007020,
+ 0x000040, 0x038A06, 0x640007, 0x000007,
+ 0x00306D, 0x028860, 0x029060, 0x08000A,
+ 0x028860, 0x008040, 0x100012, 0x00100D,
+ 0x009184, 0x32D186, 0x000E0D, 0x009184,
+ 0x33E186, 0x000007, 0x300007, 0x001020,
+ 0x003B6D, 0x008040, 0x000080, 0x08001A,
+ 0x000904, 0x32F186, 0x000007, 0x001220,
+ 0x000DED, 0x008040, 0x008042, 0x10000A,
+ 0x40000D, 0x109544, 0x000007, 0x001020,
+ 0x000DED, 0x008040, 0x008042, 0x20040A,
+ 0x000082, 0x08001A, 0x000904, 0x338186,
+ 0x000007, 0x003B6D, 0x008042, 0x08000A,
+ 0x000E15, 0x010984, 0x342B86, 0x600007,
+ 0x08001A, 0x000C15, 0x010984, 0x341386,
+ 0x000020, 0x1A0007, 0x0002ED, 0x008040,
+ 0x620007, 0x00306D, 0x028042, 0x0A804A,
+ 0x000820, 0x0A804A, 0x000606, 0x10804A,
+ 0x000007, 0x282512, 0x001F32, 0x05D2F4,
+ 0x54D104, 0x00735C, 0x000786, 0x000007,
+ 0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
+ 0x020040, 0x004820, 0x025060, 0x40000A,
+ 0x024060, 0x000040, 0x454944, 0x000007,
+ 0x004020, 0x003AE5, 0x000040, 0x0028E5,
+ 0x000042, 0x48000A, 0x004904, 0x39F886,
+ 0x002C65, 0x000042, 0x40000A, 0x0000D5,
+ 0x454104, 0x000007, 0x000655, 0x054504,
+ 0x368286, 0x0001D5, 0x054504, 0x368086,
+ 0x002B65, 0x000042, 0x003AE5, 0x50004A,
+ 0x40000A, 0x45C3D4, 0x000007, 0x454504,
+ 0x000007, 0x0000CD, 0x444944, 0x000007,
+ 0x454504, 0x000007, 0x00014D, 0x554944,
+ 0x000007, 0x045144, 0x367986, 0x002C65,
+ 0x000042, 0x48000A, 0x4CD104, 0x000007,
+ 0x04C144, 0x368386, 0x000007, 0x160007,
+ 0x002CE5, 0x040042, 0x40000A, 0x004020,
+ 0x000040, 0x002965, 0x000042, 0x40000A,
+ 0x004104, 0x36F086, 0x000007, 0x002402,
+ 0x383206, 0x005C02, 0x0025E5, 0x000042,
+ 0x40000A, 0x004274, 0x002AE5, 0x000042,
+ 0x40000A, 0x004274, 0x500112, 0x0029E5,
+ 0x000042, 0x40000A, 0x004234, 0x454104,
+ 0x000007, 0x004020, 0x000040, 0x003EE5,
+ 0x000020, 0x000040, 0x002DE5, 0x400152,
+ 0x50000A, 0x045144, 0x37DA86, 0x0000C5,
+ 0x003EE5, 0x004020, 0x000040, 0x002BE5,
+ 0x000042, 0x40000A, 0x404254, 0x000007,
+ 0x002AE5, 0x004020, 0x000040, 0x500132,
+ 0x040134, 0x005674, 0x0029E5, 0x020042,
+ 0x42000A, 0x000042, 0x50000A, 0x05417C,
+ 0x0028E5, 0x000042, 0x48000A, 0x0000C5,
+ 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
+ 0x020042, 0x40004A, 0x50000A, 0x00423C,
+ 0x00567C, 0x0028E5, 0x004820, 0x000040,
+ 0x281D12, 0x282512, 0x001F72, 0x002965,
+ 0x000042, 0x40000A, 0x004104, 0x393A86,
+ 0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
+ 0x000042, 0x40000A, 0x004104, 0x397886,
+ 0x002D65, 0x000042, 0x28340A, 0x003465,
+ 0x020042, 0x42004A, 0x004020, 0x4A004A,
+ 0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
+ 0x39E186, 0x000007, 0x000606, 0x080007,
+ 0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
+ 0x020045, 0x004020, 0x000060, 0x000365,
+ 0x000040, 0x002E65, 0x001A20, 0x0A1A60,
+ 0x000040, 0x003465, 0x020042, 0x42004A,
+ 0x004020, 0x4A004A, 0x000606, 0x50004A,
+ 0x0017FD, 0x018042, 0x08000A, 0x000904,
+ 0x225A86, 0x000007, 0x00107D, 0x018042,
+ 0x0011FD, 0x33804A, 0x19804A, 0x20000A,
+ 0x000095, 0x2A1144, 0x01A144, 0x3B9086,
+ 0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
+ 0x018042, 0x0010FD, 0x09804A, 0x38000A,
+ 0x000095, 0x010924, 0x003A64, 0x3B8186,
+ 0x000007, 0x003904, 0x3B9286, 0x000007,
+ 0x3B9A06, 0x00000D, 0x00008D, 0x000820,
+ 0x00387D, 0x018040, 0x700002, 0x00117D,
+ 0x018042, 0x00197D, 0x29804A, 0x30000A,
+ 0x380002, 0x003124, 0x000424, 0x000424,
+ 0x002A24, 0x280502, 0x00068D, 0x000810,
+ 0x28143A, 0x00750D, 0x00B124, 0x002264,
+ 0x3D0386, 0x284402, 0x000810, 0x280C3A,
+ 0x0B800D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00758D, 0x00B124, 0x100102,
+ 0x012144, 0x3E4986, 0x001810, 0x10003A,
+ 0x00387D, 0x018042, 0x08000A, 0x000904,
+ 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
+ 0x00008D, 0x023164, 0x000A64, 0x280D02,
+ 0x0B808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00387D, 0x018042, 0x08000A,
+ 0x000904, 0x3E3286, 0x030000, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x3D8286,
+ 0x000007, 0x002810, 0x28043A, 0x00750D,
+ 0x030924, 0x002264, 0x280D02, 0x02316C,
+ 0x28450A, 0x0B810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x00008D, 0x000A24,
+ 0x3E4A06, 0x100102, 0x001810, 0x10003A,
+ 0x0000BD, 0x003810, 0x30043A, 0x00187D,
+ 0x018042, 0x0018FD, 0x09804A, 0x20000A,
+ 0x0000AD, 0x028924, 0x07212C, 0x001010,
+ 0x300583, 0x300D8B, 0x3014BB, 0x301C83,
+ 0x002083, 0x00137D, 0x038042, 0x33844A,
+ 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
+ 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
+ 0x001E0D, 0x0005FD, 0x018042, 0x20000A,
+ 0x020924, 0x00068D, 0x00A96C, 0x00009D,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x3F6A86, 0x000007, 0x280502, 0x280D0A,
+ 0x284402, 0x001810, 0x28143A, 0x0C008D,
+ 0x000820, 0x0002FD, 0x018040, 0x220007,
+ 0x003904, 0x225886, 0x001E0D, 0x00057D,
+ 0x018042, 0x20000A, 0x020924, 0x0000A5,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x402A86, 0x000007, 0x280502, 0x280C02,
+ 0x002010, 0x28143A, 0x0C010D, 0x000820,
+ 0x0002FD, 0x018040, 0x225A06, 0x220007,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000
+};
+
+#endif //_HWMCODE_
+
+
diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in
index eea182f5e67579..640d9b21912aa7 100644
--- a/drivers/sound/Config.in
+++ b/drivers/sound/Config.in
@@ -3,9 +3,6 @@
# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
# More hacking for modularisation.
#
-# See drivers/sound/README.CONFIG for more information.
-
-
# Prompt user for primary drivers.
@@ -27,7 +24,7 @@ if [ "$CONFIG_VISWS" = "y" ]; then
dep_tristate ' SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
fi
-dep_tristate ' Trident 4DWave DX/NX or SiS 7018 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND
+dep_tristate ' Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND
dep_tristate ' Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND
if [ "$CONFIG_SOUND_MSNDCLAS" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "m" ]; then
@@ -79,7 +76,7 @@ if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then
int 'MSND buffer size (kB)' CONFIG_MSND_FIFOSIZE 128
fi
-tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX
+dep_tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_PCI
dep_tristate ' OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND
@@ -149,6 +146,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
dep_tristate ' Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS
dep_tristate ' Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS
dep_tristate ' Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS
+ dep_tristate ' Yamaha PCI legacy mode support' CONFIG_SOUND_YMPCI $CONFIG_SOUND_OSS $CONFIG_PCI
dep_tristate ' 6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS
dep_tristate ' Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_SOUND_AEDSP16 $CONFIG_SOUND_OSS
@@ -181,3 +179,4 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
fi
+dep_tristate ' TV card (bt848) mixer support' CONFIG_SOUND_TVMIXER $CONFIG_SOUND $CONFIG_I2C
diff --git a/drivers/sound/Hwmcode.h b/drivers/sound/Hwmcode.h
new file mode 100644
index 00000000000000..e4d9a68fa6a88a
--- /dev/null
+++ b/drivers/sound/Hwmcode.h
@@ -0,0 +1,804 @@
+//=============================================================================
+// Copyright (c) 1997 Yamaha Corporation. All Rights Reserved.
+//
+// Title:
+// hwmcode.c
+// Desc:
+// micro-code for CTRL & DSP
+// HISTORY:
+// April 03, 1997: 1st try by M. Mukojima
+//=============================================================================
+#define YDSXG_DSPLENGTH 0x0080
+#define YDSXG_CTRLLENGTH 0x3000
+
+
+static unsigned long int gdwDSPCode[YDSXG_DSPLENGTH >> 2] = {
+ 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
+ 0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
+ 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
+ 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000
+};
+
+
+// --------------------------------------------
+// DS-1E Controller InstructionRAM Code
+// 1999/06/21
+// Buf441 slot is Enabled.
+// --------------------------------------------
+// 04/09?@creat
+// 04/12 stop nise fix
+// 06/21?@WorkingOff timming
+static unsigned long gdwCtrl1eCode[YDSXG_CTRLLENGTH >> 2] = {
+ 0x000007, 0x240007, 0x0C0007, 0x1C0007,
+ 0x060007, 0x700002, 0x000020, 0x030040,
+ 0x007104, 0x004286, 0x030040, 0x000F0D,
+ 0x000810, 0x20043A, 0x000282, 0x00020D,
+ 0x000810, 0x20043A, 0x001282, 0x200E82,
+ 0x00800D, 0x000810, 0x20043A, 0x001A82,
+ 0x03460D, 0x000810, 0x10043A, 0x02EC0D,
+ 0x000810, 0x18043A, 0x00010D, 0x020015,
+ 0x0000FD, 0x000020, 0x038860, 0x039060,
+ 0x038060, 0x038040, 0x038040, 0x038040,
+ 0x018040, 0x000A7D, 0x038040, 0x038040,
+ 0x018040, 0x200402, 0x000882, 0x08001A,
+ 0x000904, 0x017186, 0x000007, 0x260007,
+ 0x400007, 0x000007, 0x03258D, 0x000810,
+ 0x18043A, 0x260007, 0x284402, 0x00087D,
+ 0x018042, 0x00160A, 0x05A206, 0x000007,
+ 0x440007, 0x00230D, 0x000810, 0x08043A,
+ 0x22FA06, 0x000007, 0x0007FD, 0x018042,
+ 0x08000A, 0x000904, 0x02AB86, 0x000195,
+ 0x090D04, 0x000007, 0x000820, 0x0000F5,
+ 0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
+ 0x018040, 0x000A7D, 0x038042, 0x13804A,
+ 0x18000A, 0x001820, 0x059060, 0x058860,
+ 0x018040, 0x0000FD, 0x018042, 0x70000A,
+ 0x000115, 0x071144, 0x033B86, 0x030000,
+ 0x007020, 0x036206, 0x018040, 0x00360D,
+ 0x000810, 0x08043A, 0x232206, 0x000007,
+ 0x02EC0D, 0x000810, 0x18043A, 0x019A06,
+ 0x000007, 0x240007, 0x000F8D, 0x000810,
+ 0x00163A, 0x002402, 0x005C02, 0x0028FD,
+ 0x000020, 0x018040, 0x08000D, 0x000815,
+ 0x510984, 0x000007, 0x00004D, 0x000E5D,
+ 0x000E02, 0x00430D, 0x000810, 0x08043A,
+ 0x2E1206, 0x000007, 0x00008D, 0x000924,
+ 0x000F02, 0x00470D, 0x000810, 0x08043A,
+ 0x2E1206, 0x000007, 0x480480, 0x001210,
+ 0x28043A, 0x00778D, 0x000810, 0x280C3A,
+ 0x00068D, 0x000810, 0x28143A, 0x284402,
+ 0x03258D, 0x000810, 0x18043A, 0x07FF8D,
+ 0x000820, 0x0002FD, 0x018040, 0x260007,
+ 0x200007, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x051286, 0x000007, 0x240007,
+ 0x02EC0D, 0x000810, 0x18043A, 0x00387D,
+ 0x018042, 0x08000A, 0x001015, 0x010984,
+ 0x019B86, 0x000007, 0x01B206, 0x000007,
+ 0x0008FD, 0x018042, 0x18000A, 0x001904,
+ 0x22B886, 0x280007, 0x001810, 0x28043A,
+ 0x280C02, 0x00000D, 0x000810, 0x28143A,
+ 0x08808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00020D, 0x189904, 0x000007,
+ 0x00402D, 0x0000BD, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x065A86, 0x000007,
+ 0x000100, 0x000A20, 0x00047D, 0x018040,
+ 0x018042, 0x20000A, 0x003015, 0x012144,
+ 0x036186, 0x000007, 0x002104, 0x036186,
+ 0x000007, 0x000F8D, 0x000810, 0x280C3A,
+ 0x023944, 0x07C986, 0x000007, 0x001810,
+ 0x28043A, 0x08810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x002810, 0x78003A,
+ 0x00788D, 0x000810, 0x08043A, 0x2A1206,
+ 0x000007, 0x00400D, 0x001015, 0x189904,
+ 0x292904, 0x393904, 0x000007, 0x070206,
+ 0x000007, 0x0004F5, 0x00007D, 0x000020,
+ 0x00008D, 0x010860, 0x018040, 0x00047D,
+ 0x038042, 0x21804A, 0x18000A, 0x021944,
+ 0x229086, 0x000007, 0x004075, 0x71F104,
+ 0x000007, 0x010042, 0x28000A, 0x002904,
+ 0x225886, 0x000007, 0x003C0D, 0x30A904,
+ 0x000007, 0x00077D, 0x018042, 0x08000A,
+ 0x000904, 0x08DA86, 0x00057D, 0x002820,
+ 0x03B060, 0x08F206, 0x018040, 0x003020,
+ 0x03A860, 0x018040, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x08FA86, 0x000007,
+ 0x00057D, 0x018042, 0x28040A, 0x000E8D,
+ 0x000810, 0x280C3A, 0x00000D, 0x000810,
+ 0x28143A, 0x09000D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x003DFD, 0x000020,
+ 0x018040, 0x00107D, 0x009D8D, 0x000810,
+ 0x08043A, 0x2A1206, 0x000007, 0x000815,
+ 0x08001A, 0x010984, 0x0A5186, 0x00137D,
+ 0x200500, 0x280F20, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x038A60, 0x018040, 0x00107D, 0x018042,
+ 0x08000A, 0x000215, 0x010984, 0x3A8186,
+ 0x000007, 0x007FBD, 0x383DC4, 0x000007,
+ 0x001A7D, 0x001375, 0x018042, 0x09004A,
+ 0x10000A, 0x0B8D04, 0x139504, 0x000007,
+ 0x000820, 0x019060, 0x001104, 0x225886,
+ 0x010040, 0x0017FD, 0x018042, 0x08000A,
+ 0x000904, 0x225A86, 0x000007, 0x00197D,
+ 0x038042, 0x09804A, 0x10000A, 0x000924,
+ 0x001664, 0x0011FD, 0x038042, 0x2B804A,
+ 0x19804A, 0x00008D, 0x218944, 0x000007,
+ 0x002244, 0x0C1986, 0x000007, 0x001A64,
+ 0x002A24, 0x00197D, 0x080102, 0x100122,
+ 0x000820, 0x039060, 0x018040, 0x003DFD,
+ 0x00008D, 0x000820, 0x018040, 0x001375,
+ 0x001A7D, 0x010042, 0x09804A, 0x10000A,
+ 0x00021D, 0x0189E4, 0x2992E4, 0x309144,
+ 0x000007, 0x00060D, 0x000A15, 0x000C1D,
+ 0x001025, 0x00A9E4, 0x012BE4, 0x000464,
+ 0x01B3E4, 0x0232E4, 0x000464, 0x000464,
+ 0x000464, 0x000464, 0x00040D, 0x08B1C4,
+ 0x000007, 0x000820, 0x000BF5, 0x030040,
+ 0x00197D, 0x038042, 0x09804A, 0x000A24,
+ 0x08000A, 0x080E64, 0x000007, 0x100122,
+ 0x000820, 0x031060, 0x010040, 0x0064AC,
+ 0x00027D, 0x000020, 0x018040, 0x00107D,
+ 0x018042, 0x0011FD, 0x3B804A, 0x09804A,
+ 0x20000A, 0x000095, 0x1A1144, 0x00A144,
+ 0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
+ 0x0018FD, 0x018042, 0x0010FD, 0x09804A,
+ 0x28000A, 0x000095, 0x010924, 0x002A64,
+ 0x0E4986, 0x000007, 0x002904, 0x0E5A86,
+ 0x000007, 0x0E6206, 0x080002, 0x00008D,
+ 0x00387D, 0x000820, 0x018040, 0x00127D,
+ 0x018042, 0x10000A, 0x003904, 0x0F0986,
+ 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
+ 0x000025, 0x0FB206, 0x00002D, 0x000015,
+ 0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
+ 0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
+ 0x400025, 0x00008D, 0x110944, 0x000007,
+ 0x00018D, 0x109504, 0x000007, 0x009164,
+ 0x000424, 0x000424, 0x000424, 0x100102,
+ 0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
+ 0x00018D, 0x00042D, 0x00008D, 0x109504,
+ 0x000007, 0x00020D, 0x109184, 0x000007,
+ 0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
+ 0x018040, 0x003BFD, 0x001020, 0x03A860,
+ 0x000815, 0x313184, 0x212184, 0x000007,
+ 0x03B060, 0x03A060, 0x018040, 0x0022FD,
+ 0x000095, 0x010924, 0x000424, 0x000424,
+ 0x001264, 0x100102, 0x000820, 0x039060,
+ 0x018040, 0x001924, 0x010F0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x000424, 0x000424,
+ 0x00117D, 0x018042, 0x08000A, 0x000A24,
+ 0x280502, 0x280C02, 0x09800D, 0x000820,
+ 0x0002FD, 0x018040, 0x200007, 0x0022FD,
+ 0x018042, 0x08000A, 0x000095, 0x280DC4,
+ 0x011924, 0x00197D, 0x018042, 0x0011FD,
+ 0x09804A, 0x10000A, 0x0000B5, 0x113144,
+ 0x0A8D04, 0x000007, 0x080A44, 0x129504,
+ 0x000007, 0x0023FD, 0x001020, 0x038040,
+ 0x101244, 0x000007, 0x000820, 0x039060,
+ 0x018040, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x123286, 0x000007, 0x003BFD,
+ 0x000100, 0x000A10, 0x0B807A, 0x13804A,
+ 0x090984, 0x000007, 0x000095, 0x013D04,
+ 0x12B886, 0x10000A, 0x100002, 0x090984,
+ 0x000007, 0x038042, 0x11804A, 0x090D04,
+ 0x000007, 0x10000A, 0x090D84, 0x000007,
+ 0x00257D, 0x000820, 0x018040, 0x00010D,
+ 0x000810, 0x28143A, 0x00127D, 0x018042,
+ 0x20000A, 0x00197D, 0x018042, 0x00117D,
+ 0x31804A, 0x10000A, 0x003124, 0x013B8D,
+ 0x00397D, 0x000820, 0x058040, 0x038042,
+ 0x09844A, 0x000606, 0x08040A, 0x300102,
+ 0x003124, 0x000424, 0x000424, 0x001224,
+ 0x280502, 0x001A4C, 0x143986, 0x700002,
+ 0x00002D, 0x030000, 0x00387D, 0x018042,
+ 0x10000A, 0x146206, 0x002124, 0x0000AD,
+ 0x100002, 0x00010D, 0x000924, 0x006B24,
+ 0x014A0D, 0x00397D, 0x000820, 0x058040,
+ 0x038042, 0x09844A, 0x000606, 0x08040A,
+ 0x003264, 0x00008D, 0x000A24, 0x001020,
+ 0x00227D, 0x018040, 0x014F8D, 0x000810,
+ 0x08043A, 0x2B5A06, 0x000007, 0x002820,
+ 0x00207D, 0x018040, 0x00117D, 0x038042,
+ 0x13804A, 0x33800A, 0x00387D, 0x018042,
+ 0x08000A, 0x000904, 0x177286, 0x000007,
+ 0x00008D, 0x030964, 0x015B0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x380102, 0x000424,
+ 0x000424, 0x001224, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x15DA86, 0x000007,
+ 0x280502, 0x001A4C, 0x177186, 0x000007,
+ 0x032164, 0x00632C, 0x003DFD, 0x018042,
+ 0x08000A, 0x000095, 0x090904, 0x000007,
+ 0x000820, 0x001A4C, 0x169986, 0x018040,
+ 0x030000, 0x16B206, 0x002124, 0x00010D,
+ 0x000924, 0x006B24, 0x016F0D, 0x00397D,
+ 0x000820, 0x058040, 0x038042, 0x09844A,
+ 0x000606, 0x08040A, 0x003A64, 0x000095,
+ 0x001224, 0x0002FD, 0x018042, 0x08000A,
+ 0x000904, 0x171286, 0x000007, 0x01760D,
+ 0x000810, 0x08043A, 0x2B5A06, 0x000007,
+ 0x160A06, 0x000007, 0x007020, 0x08010A,
+ 0x10012A, 0x0020FD, 0x038860, 0x039060,
+ 0x018040, 0x00227D, 0x018042, 0x003DFD,
+ 0x08000A, 0x31844A, 0x000904, 0x181086,
+ 0x18008B, 0x00008D, 0x189904, 0x00312C,
+ 0x18E206, 0x000007, 0x00324C, 0x186B86,
+ 0x000007, 0x001904, 0x186886, 0x000007,
+ 0x000095, 0x199144, 0x00222C, 0x003124,
+ 0x00636C, 0x000E3D, 0x001375, 0x000BFD,
+ 0x010042, 0x09804A, 0x10000A, 0x038AEC,
+ 0x0393EC, 0x00224C, 0x18E186, 0x000007,
+ 0x00008D, 0x189904, 0x00226C, 0x00322C,
+ 0x30050A, 0x301DAB, 0x002083, 0x0018FD,
+ 0x018042, 0x08000A, 0x018924, 0x300502,
+ 0x001083, 0x001875, 0x010042, 0x10000A,
+ 0x00008D, 0x010924, 0x001375, 0x330542,
+ 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
+ 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
+ 0x006083, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x19B286, 0x000007, 0x001E2D,
+ 0x0005FD, 0x018042, 0x08000A, 0x028924,
+ 0x280502, 0x00060D, 0x000810, 0x280C3A,
+ 0x00008D, 0x000810, 0x28143A, 0x0A808D,
+ 0x000820, 0x0002F5, 0x010040, 0x220007,
+ 0x001275, 0x030042, 0x21004A, 0x00008D,
+ 0x1A0944, 0x000007, 0x01AB8D, 0x000810,
+ 0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
+ 0x030042, 0x0D004A, 0x10000A, 0x089144,
+ 0x000007, 0x000820, 0x010040, 0x0025F5,
+ 0x0A3144, 0x000007, 0x000820, 0x032860,
+ 0x030040, 0x00217D, 0x038042, 0x0B804A,
+ 0x10000A, 0x000820, 0x031060, 0x030040,
+ 0x00008D, 0x000124, 0x00012C, 0x000E64,
+ 0x001A64, 0x00636C, 0x08010A, 0x10012A,
+ 0x000820, 0x031060, 0x030040, 0x0020FD,
+ 0x018042, 0x08000A, 0x00227D, 0x018042,
+ 0x10000A, 0x000820, 0x031060, 0x030040,
+ 0x00197D, 0x018042, 0x08000A, 0x0022FD,
+ 0x038042, 0x10000A, 0x000820, 0x031060,
+ 0x030040, 0x090D04, 0x000007, 0x000820,
+ 0x030040, 0x038042, 0x0B804A, 0x10000A,
+ 0x000820, 0x031060, 0x030040, 0x038042,
+ 0x13804A, 0x19804A, 0x110D04, 0x198D04,
+ 0x000007, 0x08000A, 0x001020, 0x031860,
+ 0x030860, 0x030040, 0x00008D, 0x0B0944,
+ 0x000007, 0x000820, 0x010040, 0x0005F5,
+ 0x030042, 0x08000A, 0x000820, 0x010040,
+ 0x0000F5, 0x010042, 0x08000A, 0x000904,
+ 0x1D9886, 0x001E75, 0x030042, 0x01044A,
+ 0x000C0A, 0x1DAA06, 0x000007, 0x000402,
+ 0x000C02, 0x00177D, 0x001AF5, 0x018042,
+ 0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
+ 0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
+ 0x00043D, 0x0013F5, 0x001AFD, 0x030042,
+ 0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
+ 0x089144, 0x19A144, 0x0389E4, 0x0399EC,
+ 0x005502, 0x005D0A, 0x030042, 0x0B004A,
+ 0x1B804A, 0x13804A, 0x20000A, 0x089144,
+ 0x19A144, 0x0389E4, 0x0399EC, 0x006502,
+ 0x006D0A, 0x030042, 0x0B004A, 0x19004A,
+ 0x2B804A, 0x13804A, 0x21804A, 0x30000A,
+ 0x089144, 0x19A144, 0x2AB144, 0x0389E4,
+ 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
+ 0x000702, 0x00107D, 0x000415, 0x018042,
+ 0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
+ 0x0019FD, 0x010042, 0x09804A, 0x10000A,
+ 0x000934, 0x001674, 0x0029F5, 0x010042,
+ 0x10000A, 0x00917C, 0x002075, 0x010042,
+ 0x08000A, 0x000904, 0x200A86, 0x0026F5,
+ 0x0027F5, 0x030042, 0x09004A, 0x10000A,
+ 0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
+ 0x010042, 0x51804A, 0x48000A, 0x160007,
+ 0x001075, 0x010042, 0x282C0A, 0x281D12,
+ 0x282512, 0x001F32, 0x1E0007, 0x0E0007,
+ 0x001975, 0x010042, 0x002DF5, 0x0D004A,
+ 0x10000A, 0x009144, 0x20EA86, 0x010042,
+ 0x28340A, 0x000E5D, 0x00008D, 0x000375,
+ 0x000820, 0x010040, 0x05D2F4, 0x54D104,
+ 0x00735C, 0x218B86, 0x000007, 0x0C0007,
+ 0x080007, 0x0A0007, 0x02178D, 0x000810,
+ 0x08043A, 0x34B206, 0x000007, 0x219206,
+ 0x000007, 0x080007, 0x002275, 0x010042,
+ 0x20000A, 0x002104, 0x225886, 0x001E2D,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x21CA86, 0x000007, 0x002010, 0x30043A,
+ 0x00057D, 0x0180C3, 0x08000A, 0x028924,
+ 0x280502, 0x280C02, 0x0A810D, 0x000820,
+ 0x0002F5, 0x010040, 0x220007, 0x0004FD,
+ 0x018042, 0x70000A, 0x030000, 0x007020,
+ 0x07FA06, 0x018040, 0x022B8D, 0x000810,
+ 0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x22C286,
+ 0x000007, 0x020206, 0x000007, 0x000875,
+ 0x0009FD, 0x00010D, 0x234206, 0x000295,
+ 0x000B75, 0x00097D, 0x00000D, 0x000515,
+ 0x010042, 0x18000A, 0x001904, 0x2A0086,
+ 0x0006F5, 0x001020, 0x010040, 0x0004F5,
+ 0x000820, 0x010040, 0x000775, 0x010042,
+ 0x09804A, 0x10000A, 0x001124, 0x000904,
+ 0x23F286, 0x000815, 0x080102, 0x101204,
+ 0x241206, 0x000575, 0x081204, 0x000007,
+ 0x100102, 0x000575, 0x000425, 0x021124,
+ 0x100102, 0x000820, 0x031060, 0x010040,
+ 0x001924, 0x2A0086, 0x00008D, 0x000464,
+ 0x009D04, 0x291086, 0x180102, 0x000575,
+ 0x010042, 0x28040A, 0x00018D, 0x000924,
+ 0x280D02, 0x00000D, 0x000924, 0x281502,
+ 0x10000D, 0x000820, 0x0002F5, 0x010040,
+ 0x200007, 0x001175, 0x0002FD, 0x018042,
+ 0x08000A, 0x000904, 0x24FA86, 0x000007,
+ 0x000100, 0x080B20, 0x130B60, 0x1B0B60,
+ 0x030A60, 0x010040, 0x050042, 0x3D004A,
+ 0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
+ 0x010042, 0x28140A, 0x0004F5, 0x010042,
+ 0x08000A, 0x000315, 0x010D04, 0x260286,
+ 0x004015, 0x000095, 0x010D04, 0x25F086,
+ 0x100022, 0x10002A, 0x261A06, 0x000007,
+ 0x333104, 0x2AA904, 0x000007, 0x032124,
+ 0x280502, 0x284402, 0x001124, 0x400102,
+ 0x000424, 0x000424, 0x003224, 0x00292C,
+ 0x00636C, 0x277386, 0x000007, 0x02B164,
+ 0x000464, 0x000464, 0x00008D, 0x000A64,
+ 0x280D02, 0x10008D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x00008D, 0x38B904,
+ 0x000007, 0x03296C, 0x30010A, 0x0002F5,
+ 0x010042, 0x08000A, 0x000904, 0x270286,
+ 0x000007, 0x00212C, 0x28050A, 0x00316C,
+ 0x00046C, 0x00046C, 0x28450A, 0x001124,
+ 0x006B64, 0x100102, 0x00008D, 0x01096C,
+ 0x280D0A, 0x10010D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x004124, 0x000424,
+ 0x000424, 0x003224, 0x300102, 0x032944,
+ 0x27FA86, 0x000007, 0x300002, 0x0004F5,
+ 0x010042, 0x08000A, 0x000315, 0x010D04,
+ 0x284086, 0x003124, 0x000464, 0x300102,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x284A86, 0x000007, 0x284402, 0x003124,
+ 0x300502, 0x003924, 0x300583, 0x000883,
+ 0x0005F5, 0x010042, 0x28040A, 0x00008D,
+ 0x008124, 0x280D02, 0x00008D, 0x008124,
+ 0x281502, 0x10018D, 0x000820, 0x0002F5,
+ 0x010040, 0x220007, 0x001025, 0x000575,
+ 0x030042, 0x09004A, 0x10000A, 0x0A0904,
+ 0x121104, 0x000007, 0x001020, 0x050860,
+ 0x050040, 0x0006FD, 0x018042, 0x09004A,
+ 0x10000A, 0x0000A5, 0x0A0904, 0x121104,
+ 0x000007, 0x000820, 0x019060, 0x010040,
+ 0x0002F5, 0x010042, 0x08000A, 0x000904,
+ 0x29CA86, 0x000007, 0x244206, 0x000007,
+ 0x000606, 0x000007, 0x0002F5, 0x010042,
+ 0x08000A, 0x000904, 0x2A1A86, 0x000007,
+ 0x000100, 0x080B20, 0x138B60, 0x1B8B60,
+ 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
+ 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
+ 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
+ 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
+ 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
+ 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
+ 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
+ 0x038A60, 0x000606, 0x018040, 0x00008D,
+ 0x000A64, 0x280D02, 0x000A24, 0x00027D,
+ 0x018042, 0x10000A, 0x001224, 0x0003FD,
+ 0x018042, 0x08000A, 0x000904, 0x2C0A86,
+ 0x000007, 0x00018D, 0x000A24, 0x000464,
+ 0x000464, 0x080102, 0x000924, 0x000424,
+ 0x000424, 0x100102, 0x02000D, 0x009144,
+ 0x2C6186, 0x000007, 0x0001FD, 0x018042,
+ 0x08000A, 0x000A44, 0x2C4386, 0x018042,
+ 0x0A000D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00027D, 0x001020, 0x000606,
+ 0x018040, 0x0002F5, 0x010042, 0x08000A,
+ 0x000904, 0x2CB286, 0x000007, 0x00037D,
+ 0x018042, 0x08000A, 0x000904, 0x2CE286,
+ 0x000007, 0x000075, 0x002E7D, 0x010042,
+ 0x0B804A, 0x000020, 0x000904, 0x000686,
+ 0x010040, 0x31844A, 0x30048B, 0x000883,
+ 0x00008D, 0x000810, 0x28143A, 0x00008D,
+ 0x000810, 0x280C3A, 0x000675, 0x010042,
+ 0x08000A, 0x003815, 0x010924, 0x280502,
+ 0x0B000D, 0x000820, 0x0002F5, 0x010040,
+ 0x000606, 0x220007, 0x000464, 0x000464,
+ 0x000606, 0x000007, 0x000134, 0x007F8D,
+ 0x00093C, 0x281D12, 0x282512, 0x001F32,
+ 0x0E0007, 0x00010D, 0x00037D, 0x000820,
+ 0x018040, 0x05D2F4, 0x000007, 0x080007,
+ 0x00037D, 0x018042, 0x08000A, 0x000904,
+ 0x2E8A86, 0x000007, 0x000606, 0x000007,
+ 0x000007, 0x000012, 0x100007, 0x320007,
+ 0x600007, 0x460007, 0x100080, 0x48001A,
+ 0x004904, 0x2EF186, 0x000007, 0x001210,
+ 0x58003A, 0x000145, 0x5C5D04, 0x000007,
+ 0x000080, 0x48001A, 0x004904, 0x2F4186,
+ 0x000007, 0x001210, 0x50003A, 0x005904,
+ 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
+ 0x7FFF7D, 0x07D524, 0x004224, 0x500102,
+ 0x200502, 0x000082, 0x40001A, 0x004104,
+ 0x2FC986, 0x000007, 0x003865, 0x40001A,
+ 0x004020, 0x00104D, 0x04C184, 0x31AB86,
+ 0x000040, 0x040007, 0x000165, 0x000145,
+ 0x004020, 0x000040, 0x000765, 0x080080,
+ 0x40001A, 0x004104, 0x305986, 0x000007,
+ 0x001210, 0x40003A, 0x004104, 0x30B286,
+ 0x00004D, 0x0000CD, 0x004810, 0x20043A,
+ 0x000882, 0x40001A, 0x004104, 0x30C186,
+ 0x000007, 0x004820, 0x005904, 0x319886,
+ 0x000040, 0x0007E5, 0x200480, 0x2816A0,
+ 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
+ 0x000040, 0x000032, 0x400075, 0x00007D,
+ 0x07D574, 0x200512, 0x000082, 0x40001A,
+ 0x004104, 0x317186, 0x000007, 0x038A06,
+ 0x640007, 0x0000E5, 0x000020, 0x000040,
+ 0x000A65, 0x000020, 0x020040, 0x020040,
+ 0x000040, 0x000165, 0x000042, 0x70000A,
+ 0x007104, 0x323286, 0x000007, 0x060007,
+ 0x019A06, 0x640007, 0x050000, 0x007020,
+ 0x000040, 0x038A06, 0x640007, 0x000007,
+ 0x00306D, 0x028860, 0x029060, 0x08000A,
+ 0x028860, 0x008040, 0x100012, 0x00100D,
+ 0x009184, 0x32D186, 0x000E0D, 0x009184,
+ 0x33E186, 0x000007, 0x300007, 0x001020,
+ 0x003B6D, 0x008040, 0x000080, 0x08001A,
+ 0x000904, 0x32F186, 0x000007, 0x001220,
+ 0x000DED, 0x008040, 0x008042, 0x10000A,
+ 0x40000D, 0x109544, 0x000007, 0x001020,
+ 0x000DED, 0x008040, 0x008042, 0x20040A,
+ 0x000082, 0x08001A, 0x000904, 0x338186,
+ 0x000007, 0x003B6D, 0x008042, 0x08000A,
+ 0x000E15, 0x010984, 0x342B86, 0x600007,
+ 0x08001A, 0x000C15, 0x010984, 0x341386,
+ 0x000020, 0x1A0007, 0x0002ED, 0x008040,
+ 0x620007, 0x00306D, 0x028042, 0x0A804A,
+ 0x000820, 0x0A804A, 0x000606, 0x10804A,
+ 0x000007, 0x282512, 0x001F32, 0x05D2F4,
+ 0x54D104, 0x00735C, 0x000786, 0x000007,
+ 0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
+ 0x020040, 0x004820, 0x025060, 0x40000A,
+ 0x024060, 0x000040, 0x454944, 0x000007,
+ 0x004020, 0x003AE5, 0x000040, 0x0028E5,
+ 0x000042, 0x48000A, 0x004904, 0x39F886,
+ 0x002C65, 0x000042, 0x40000A, 0x0000D5,
+ 0x454104, 0x000007, 0x000655, 0x054504,
+ 0x368286, 0x0001D5, 0x054504, 0x368086,
+ 0x002B65, 0x000042, 0x003AE5, 0x50004A,
+ 0x40000A, 0x45C3D4, 0x000007, 0x454504,
+ 0x000007, 0x0000CD, 0x444944, 0x000007,
+ 0x454504, 0x000007, 0x00014D, 0x554944,
+ 0x000007, 0x045144, 0x367986, 0x002C65,
+ 0x000042, 0x48000A, 0x4CD104, 0x000007,
+ 0x04C144, 0x368386, 0x000007, 0x160007,
+ 0x002CE5, 0x040042, 0x40000A, 0x004020,
+ 0x000040, 0x002965, 0x000042, 0x40000A,
+ 0x004104, 0x36F086, 0x000007, 0x002402,
+ 0x383206, 0x005C02, 0x0025E5, 0x000042,
+ 0x40000A, 0x004274, 0x002AE5, 0x000042,
+ 0x40000A, 0x004274, 0x500112, 0x0029E5,
+ 0x000042, 0x40000A, 0x004234, 0x454104,
+ 0x000007, 0x004020, 0x000040, 0x003EE5,
+ 0x000020, 0x000040, 0x002DE5, 0x400152,
+ 0x50000A, 0x045144, 0x37DA86, 0x0000C5,
+ 0x003EE5, 0x004020, 0x000040, 0x002BE5,
+ 0x000042, 0x40000A, 0x404254, 0x000007,
+ 0x002AE5, 0x004020, 0x000040, 0x500132,
+ 0x040134, 0x005674, 0x0029E5, 0x020042,
+ 0x42000A, 0x000042, 0x50000A, 0x05417C,
+ 0x0028E5, 0x000042, 0x48000A, 0x0000C5,
+ 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
+ 0x020042, 0x40004A, 0x50000A, 0x00423C,
+ 0x00567C, 0x0028E5, 0x004820, 0x000040,
+ 0x281D12, 0x282512, 0x001F72, 0x002965,
+ 0x000042, 0x40000A, 0x004104, 0x393A86,
+ 0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
+ 0x000042, 0x40000A, 0x004104, 0x397886,
+ 0x002D65, 0x000042, 0x28340A, 0x003465,
+ 0x020042, 0x42004A, 0x004020, 0x4A004A,
+ 0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
+ 0x39E186, 0x000007, 0x000606, 0x080007,
+ 0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
+ 0x020045, 0x004020, 0x000060, 0x000365,
+ 0x000040, 0x002E65, 0x001A20, 0x0A1A60,
+ 0x000040, 0x003465, 0x020042, 0x42004A,
+ 0x004020, 0x4A004A, 0x000606, 0x50004A,
+ 0x0017FD, 0x018042, 0x08000A, 0x000904,
+ 0x225A86, 0x000007, 0x00107D, 0x018042,
+ 0x0011FD, 0x33804A, 0x19804A, 0x20000A,
+ 0x000095, 0x2A1144, 0x01A144, 0x3B9086,
+ 0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
+ 0x018042, 0x0010FD, 0x09804A, 0x38000A,
+ 0x000095, 0x010924, 0x003A64, 0x3B8186,
+ 0x000007, 0x003904, 0x3B9286, 0x000007,
+ 0x3B9A06, 0x00000D, 0x00008D, 0x000820,
+ 0x00387D, 0x018040, 0x700002, 0x00117D,
+ 0x018042, 0x00197D, 0x29804A, 0x30000A,
+ 0x380002, 0x003124, 0x000424, 0x000424,
+ 0x002A24, 0x280502, 0x00068D, 0x000810,
+ 0x28143A, 0x00750D, 0x00B124, 0x002264,
+ 0x3D0386, 0x284402, 0x000810, 0x280C3A,
+ 0x0B800D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00758D, 0x00B124, 0x100102,
+ 0x012144, 0x3E4986, 0x001810, 0x10003A,
+ 0x00387D, 0x018042, 0x08000A, 0x000904,
+ 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
+ 0x00008D, 0x023164, 0x000A64, 0x280D02,
+ 0x0B808D, 0x000820, 0x0002FD, 0x018040,
+ 0x200007, 0x00387D, 0x018042, 0x08000A,
+ 0x000904, 0x3E3286, 0x030000, 0x0002FD,
+ 0x018042, 0x08000A, 0x000904, 0x3D8286,
+ 0x000007, 0x002810, 0x28043A, 0x00750D,
+ 0x030924, 0x002264, 0x280D02, 0x02316C,
+ 0x28450A, 0x0B810D, 0x000820, 0x0002FD,
+ 0x018040, 0x200007, 0x00008D, 0x000A24,
+ 0x3E4A06, 0x100102, 0x001810, 0x10003A,
+ 0x0000BD, 0x003810, 0x30043A, 0x00187D,
+ 0x018042, 0x0018FD, 0x09804A, 0x20000A,
+ 0x0000AD, 0x028924, 0x07212C, 0x001010,
+ 0x300583, 0x300D8B, 0x3014BB, 0x301C83,
+ 0x002083, 0x00137D, 0x038042, 0x33844A,
+ 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
+ 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
+ 0x001E0D, 0x0005FD, 0x018042, 0x20000A,
+ 0x020924, 0x00068D, 0x00A96C, 0x00009D,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x3F6A86, 0x000007, 0x280502, 0x280D0A,
+ 0x284402, 0x001810, 0x28143A, 0x0C008D,
+ 0x000820, 0x0002FD, 0x018040, 0x220007,
+ 0x003904, 0x225886, 0x001E0D, 0x00057D,
+ 0x018042, 0x20000A, 0x020924, 0x0000A5,
+ 0x0002FD, 0x018042, 0x08000A, 0x000904,
+ 0x402A86, 0x000007, 0x280502, 0x280C02,
+ 0x002010, 0x28143A, 0x0C010D, 0x000820,
+ 0x0002FD, 0x018040, 0x225A06, 0x220007,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000,
+ 0x000000, 0x000000, 0x000000, 0x000000
+};
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index ec43a1d2662148..10fbd5871e5803 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_SOUND_ACI_MIXER) += aci.o
obj-$(CONFIG_SOUND_AWE32_SYNTH) += awe_wave.o
obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o ac97_codec.o
+obj-$(CONFIG_SOUND_YMPCI) += ymf_sb.o sb_lib.o uart401.o
obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o
obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o
obj-$(CONFIG_SOUND_VWSND) += vwsnd.o
diff --git a/drivers/sound/ac97_codec.c b/drivers/sound/ac97_codec.c
index b26c3a8d5d3f61..23e94845a0bcaa 100644
--- a/drivers/sound/ac97_codec.c
+++ b/drivers/sound/ac97_codec.c
@@ -21,7 +21,7 @@
*
* History
* v0.4 Mar 15 2000 Ollie Lho
- * dual codec support verified with 4 channel output
+ * dual codecs support verified with 4 channels output
* v0.3 Feb 22 2000 Ollie Lho
* bug fix for record mask setting
* v0.2 Feb 10 2000 Ollie Lho
@@ -332,9 +332,10 @@ static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask)
/* else, write the first set in the mask as the
output */
/* clear out current set value first (AC97 supports only 1 input!) */
- val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT)&0x07]);
- if (mask != val) mask &= ~val;
-
+ val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT) & 0x07]);
+ if (mask != val)
+ mask &= ~val;
+
val = ffs(mask);
val = ac97_oss_rm[val-1];
val |= val << 8; /* set both channels */
@@ -423,7 +424,7 @@ static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned
switch (_IOC_NR(cmd)) {
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
if (!codec->recmask_io) return -EINVAL;
- if(!val) return 0;
+ if (!val) return 0;
if (!(val &= codec->record_sources)) return -EINVAL;
codec->recmask_io(codec, 0, val);
@@ -449,6 +450,7 @@ int ac97_read_proc (char *page, char **start, off_t off,
{
int len = 0, cap, extid, val, id1, id2;
struct ac97_codec *codec;
+ int is_ac97_20 = 0;
if ((codec = data) == NULL)
return -ENODEV;
@@ -462,6 +464,7 @@ int ac97_read_proc (char *page, char **start, off_t off,
extid &= ~((1<<2)|(1<<4)|(1<<5)|(1<<10)|(1<<11)|(1<<12)|(1<<13));
len += sprintf (page+len, "AC97 Version : %s\n",
extid ? "2.0 or later" : "1.0");
+ if (extid) is_ac97_20 = 1;
cap = codec->codec_read(codec, AC97_RESET);
len += sprintf (page+len, "Capabilities :%s%s%s%s%s%s\n",
@@ -500,6 +503,7 @@ int ac97_read_proc (char *page, char **start, off_t off,
val & 0x0100 ? "MIC2" : "MIC1",
val & 0x0080 ? "on" : "off");
+ extid = codec->codec_read(codec, AC97_EXTENDED_ID);
cap = extid;
len += sprintf (page+len, "Ext Capabilities :%s%s%s%s%s%s%s\n",
cap & 0x0001 ? " -var rate PCM audio-" : "",
@@ -509,10 +513,37 @@ int ac97_read_proc (char *page, char **start, off_t off,
cap & 0x0080 ? " -PCM surround DAC-" : "",
cap & 0x0100 ? " -PCM LFE DAC-" : "",
cap & 0x0200 ? " -slot/DAC mappings-" : "");
+ if (is_ac97_20) {
+ len += sprintf (page+len, "Front DAC rate : %d\n",
+ codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE));
+ }
return len;
}
+/**
+ * ac97_probe_codec - Initialize and setup AC97-compatible codec
+ * @codec: (in/out) Kernel info for a single AC97 codec
+ *
+ * Reset the AC97 codec, then initialize the mixer and
+ * the rest of the @codec structure.
+ *
+ * The codec_read and codec_write fields of @codec are
+ * required to be setup and working when this function
+ * is called. All other fields are set by this function.
+ *
+ * codec_wait field of @codec can optionally be provided
+ * when calling this function. If codec_wait is not %NULL,
+ * this function will call codec_wait any time it is
+ * necessary to wait for the audio chip to reach the
+ * codec-ready state. If codec_wait is %NULL, then
+ * the default behavior is to call schedule_timeout.
+ * Currently codec_wait is used to wait for AC97 codec
+ * reset to complete.
+ *
+ * Returns 1 (true) on success, or 0 (false) on failure.
+ */
+
int ac97_probe_codec(struct ac97_codec *codec)
{
u16 id1, id2;
@@ -520,8 +551,19 @@ int ac97_probe_codec(struct ac97_codec *codec)
int i;
/* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should
- be read zero. Probing of AC97 in this way is not reliable, it is not even SAFE !! */
+ * be read zero.
+ *
+ * FIXME: is the following comment outdated? -jgarzik
+ * Probing of AC97 in this way is not reliable, it is not even SAFE !!
+ */
codec->codec_write(codec, AC97_RESET, 0L);
+
+ /* also according to spec, we wait for codec-ready state */
+ if (codec->codec_wait)
+ codec->codec_wait(codec);
+ else
+ schedule_timeout(5);
+
if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) {
printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n",
codec->id ? "Secondary" : "Primary");
@@ -546,8 +588,8 @@ int ac97_probe_codec(struct ac97_codec *codec)
}
if (codec->name == NULL)
codec->name = "Unknown";
- printk(KERN_INFO "ac97_codec: AC97 %s codec, vendor id1: 0x%04x, "
- "id2: 0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""),
+ printk(KERN_INFO "ac97_codec: AC97%s codec, id: 0x%04x:0x%04x (%s)\n",
+ audio ? " audio" : (modem ? " modem" : ""),
id1, id2, codec->name);
return ac97_init_mixer(codec);
@@ -597,11 +639,6 @@ static int ac97_init_mixer(struct ac97_codec *codec)
return 1;
}
-static int ac97_init_modem(struct ac97_codec *codec)
-{
- return 0;
-}
-
static int sigmatel_init(struct ac97_codec * codec)
{
codec->codec_write(codec, AC97_SURROUND_MASTER, 0L);
diff --git a/drivers/sound/cmpci.c b/drivers/sound/cmpci.c
index df05c9b64bde8a..527d570cfbe931 100644
--- a/drivers/sound/cmpci.c
+++ b/drivers/sound/cmpci.c
@@ -1161,7 +1161,6 @@ static int cm_open_mixdev(struct inode *inode, struct file *file)
return -ENODEV;
VALIDATE_STATE(s);
file->private_data = s;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1170,7 +1169,6 @@ static int cm_release_mixdev(struct inode *inode, struct file *file)
struct cm_state *s = (struct cm_state *)file->private_data;
VALIDATE_STATE(s);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1180,6 +1178,7 @@ static int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int
}
static /*const*/ struct file_operations cm_mixer_fops = {
+ owner: THIS_MODULE,
llseek: cm_llseek,
ioctl: cm_ioctl_mixdev,
open: cm_open_mixdev,
@@ -1765,7 +1764,6 @@ static int cm_open(struct inode *inode, struct file *file)
set_fmt(s, fmtm, fmts);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1788,11 +1786,11 @@ static int cm_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations cm_audio_fops = {
+ owner: THIS_MODULE,
llseek: cm_llseek,
read: cm_read,
write: cm_write,
@@ -2012,7 +2010,6 @@ static int cm_midi_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2062,11 +2059,11 @@ static int cm_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations cm_midi_fops = {
+ owner: THIS_MODULE,
llseek: cm_llseek,
read: cm_midi_read,
write: cm_midi_write,
@@ -2207,7 +2204,6 @@ static int cm_dmfm_open(struct inode *inode, struct file *file)
outb(1, s->iosynth+3); /* enable OPL3 */
s->open_mode |= FMODE_DMFM;
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2227,11 +2223,11 @@ static int cm_dmfm_release(struct inode *inode, struct file *file)
}
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations cm_dmfm_fops = {
+ owner: THIS_MODULE,
llseek: cm_llseek,
ioctl: cm_dmfm_ioctl,
open: cm_dmfm_open,
@@ -2321,6 +2317,8 @@ int __init init_cmpci(void)
(pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)) ||
(pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)) ||
(pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) {
+ if (pci_enable_device(pcidev))
+ continue;
if (pcidev->irq == 0)
continue;
if (!(s = kmalloc(sizeof(struct cm_state), GFP_KERNEL))) {
@@ -2345,7 +2343,7 @@ int __init init_cmpci(void)
init_MUTEX(&s->open_sem);
spin_lock_init(&s->lock);
s->magic = CM_MAGIC;
- s->iobase = pcidev->resource[0].start;
+ s->iobase = pci_resource_start(pcidev, 0);
s->iosynth = 0x388;
s->iomidi = 0x330;
spin_lock_init(&s->lock);
diff --git a/drivers/sound/dmasound/dmasound_awacs.c b/drivers/sound/dmasound/dmasound_awacs.c
index 3893f9b58dee41..f80ada7fd4a33e 100644
--- a/drivers/sound/dmasound/dmasound_awacs.c
+++ b/drivers/sound/dmasound/dmasound_awacs.c
@@ -1184,7 +1184,7 @@ static void awacs_nosound(unsigned long xx)
}
static struct timer_list beep_timer = {
- NULL, NULL, 0, 0, awacs_nosound
+ function: awacs_nosound
};
static void awacs_mksound(unsigned int hz, unsigned int ticks)
@@ -1703,14 +1703,14 @@ static int awacs_mixer_ioctl(u_int cmd, u_long arg)
case SOUND_MIXER_READ_RECLEV:
data = awacs_get_volume(awacs_reg[0], 4);
return IOCTL_OUT(arg, data);
- case MIXER_WRITE(SOUND_MASK_MONITOR):
+ case MIXER_WRITE(SOUND_MIXER_MONITOR):
IOCTL_IN(arg, data);
awacs_reg[1] &= ~MASK_LOOPTHRU;
if ((data & 0xff) >= 50)
awacs_reg[1] |= MASK_LOOPTHRU;
awacs_write(MASK_ADDR1 | awacs_reg[1]);
/* fall through */
- case MIXER_READ(SOUND_MASK_MONITOR):
+ case MIXER_READ(SOUND_MIXER_MONITOR):
data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0;
return IOCTL_OUT(arg, data);
}
diff --git a/drivers/sound/dmasound/dmasound_core.c b/drivers/sound/dmasound/dmasound_core.c
index 4aed3953e859af..da60c783b70b69 100644
--- a/drivers/sound/dmasound/dmasound_core.c
+++ b/drivers/sound/dmasound/dmasound_core.c
@@ -494,7 +494,6 @@ static struct {
static int mixer_open(struct inode *inode, struct file *file)
{
- MOD_INC_USE_COUNT;
dmasound.mach.open();
mixer.busy = 1;
return 0;
@@ -504,7 +503,6 @@ static int mixer_release(struct inode *inode, struct file *file)
{
mixer.busy = 0;
dmasound.mach.release();
- MOD_DEC_USE_COUNT;
return 0;
}
static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
@@ -533,6 +531,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
static struct file_operations mixer_fops =
{
+ owner: THIS_MODULE,
llseek: sound_lseek,
ioctl: mixer_ioctl,
open: mixer_open,
@@ -843,11 +842,9 @@ static int sq_open(struct inode *inode, struct file *file)
{
int rc;
- MOD_INC_USE_COUNT;
dmasound.mach.open();
if ((rc = write_sq_open(file)) || (rc = read_sq_open(file))) {
dmasound.mach.release();
- MOD_DEC_USE_COUNT;
return rc;
}
@@ -917,7 +914,6 @@ static int sq_release(struct inode *inode, struct file *file)
write_sq_release_buffers();
read_sq_release_buffers();
dmasound.mach.release();
- MOD_DEC_USE_COUNT;
/* There is probably a DOS atack here. They change the mode flag. */
/* XXX add check here */
@@ -1029,6 +1025,7 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
static struct file_operations sq_fops =
{
+ owner: THIS_MODULE,
llseek: sound_lseek,
write: sq_write,
ioctl: sq_ioctl,
@@ -1088,7 +1085,6 @@ static int state_open(struct inode *inode, struct file *file)
if (state.busy)
return -EBUSY;
- MOD_INC_USE_COUNT;
dmasound.mach.open();
state.ptr = 0;
state.busy = 1;
@@ -1147,7 +1143,6 @@ static int state_release(struct inode *inode, struct file *file)
{
state.busy = 0;
dmasound.mach.release();
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1165,8 +1160,8 @@ static ssize_t state_read(struct file *file, char *buf, size_t count,
return n;
}
-static struct file_operations state_fops =
-{
+static struct file_operations state_fops = {
+ owner: THIS_MODULE,
llseek: sound_lseek,
read: state_read,
open: state_open,
diff --git a/drivers/sound/emu10k1/audio.c b/drivers/sound/emu10k1/audio.c
index a682879844930c..06f84dfc3ee621 100644
--- a/drivers/sound/emu10k1/audio.c
+++ b/drivers/sound/emu10k1/audio.c
@@ -969,12 +969,9 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
if (entry == &emu10k1_devs)
return -ENODEV;
- MOD_INC_USE_COUNT;
-
if ((wave_dev = (struct emu10k1_wavedevice *)
kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL)) == NULL) {
ERROR();
- MOD_DEC_USE_COUNT;
return -EINVAL;
}
@@ -988,7 +985,6 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
ERROR();
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
@@ -1055,7 +1051,6 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file)
if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
ERROR();
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
@@ -1176,7 +1171,6 @@ static int emu10k1_audio_release(struct inode *inode, struct file *file)
kfree(wave_dev);
wake_up_interruptible(&card->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1430,6 +1424,7 @@ void emu10k1_waveout_bh(unsigned long refdata)
}
struct file_operations emu10k1_audio_fops = {
+ owner:THIS_MODULE,
llseek:emu10k1_audio_llseek,
read:emu10k1_audio_read,
write:emu10k1_audio_write,
diff --git a/drivers/sound/emu10k1/main.c b/drivers/sound/emu10k1/main.c
index bce892fe33ce96..acb65d7e56de5a 100644
--- a/drivers/sound/emu10k1/main.c
+++ b/drivers/sound/emu10k1/main.c
@@ -622,7 +622,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev
pci_set_master(pci_dev);
- card->iobase = pci_dev->resource[0].start;
+ card->iobase = pci_resource_start(pci_dev, 0);
if (request_region(card->iobase, EMU10K1_EXTENT, card_names[pci_id->driver_data]) == NULL) {
printk(KERN_ERR "emu10k1: IO space in use\n");
diff --git a/drivers/sound/emu10k1/midi.c b/drivers/sound/emu10k1/midi.c
index 497e4811311693..04b1424a8a15e2 100644
--- a/drivers/sound/emu10k1/midi.c
+++ b/drivers/sound/emu10k1/midi.c
@@ -98,14 +98,11 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
if (entry == &emu10k1_devs)
return -ENODEV;
- MOD_INC_USE_COUNT;
-
/* Wait for device to become free */
down(&card->open_sem);
while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
if (file->f_flags & O_NONBLOCK) {
up(&card->open_sem);
- MOD_DEC_USE_COUNT;
return -EBUSY;
}
@@ -113,7 +110,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
interruptible_sleep_on(&card->open_wait);
if (signal_pending(current)) {
- MOD_DEC_USE_COUNT;
return -ERESTARTSYS;
}
@@ -121,7 +117,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
}
if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
- MOD_DEC_USE_COUNT;
return -EINVAL;
}
@@ -145,14 +140,12 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
!= CTSTATUS_SUCCESS) {
ERROR();
kfree(midi_dev);
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
/* Add two buffers to receive sysex buffer */
if (midiin_add_buffer(midi_dev, &midihdr1) != CTSTATUS_SUCCESS) {
kfree(midi_dev);
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
@@ -161,7 +154,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
kfree(midihdr1->data);
kfree(midihdr1);
kfree(midi_dev);
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
}
@@ -175,7 +167,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file)
!= CTSTATUS_SUCCESS) {
ERROR();
kfree(midi_dev);
- MOD_DEC_USE_COUNT;
return -ENODEV;
}
}
@@ -237,8 +228,6 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file)
up(&card->open_sem);
wake_up_interruptible(&card->open_wait);
- MOD_DEC_USE_COUNT;
-
return 0;
}
@@ -438,6 +427,7 @@ int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned lon
/* MIDI file operations */
struct file_operations emu10k1_midi_fops = {
+ owner:THIS_MODULE,
read:emu10k1_midi_read,
write:emu10k1_midi_write,
poll:emu10k1_midi_poll,
diff --git a/drivers/sound/emu10k1/mixer.c b/drivers/sound/emu10k1/mixer.c
index fa54ca435f0a44..62796146f49b09 100644
--- a/drivers/sound/emu10k1/mixer.c
+++ b/drivers/sound/emu10k1/mixer.c
@@ -803,8 +803,6 @@ static int emu10k1_mixer_open(struct inode *inode, struct file *file)
if (entry == &emu10k1_devs)
return -ENODEV;
- MOD_INC_USE_COUNT;
-
file->private_data = card;
return 0;
}
@@ -812,11 +810,11 @@ static int emu10k1_mixer_open(struct inode *inode, struct file *file)
static int emu10k1_mixer_release(struct inode *inode, struct file *file)
{
DPF(3, "emu10k1_mixer_release()\n");
- MOD_DEC_USE_COUNT;
return 0;
}
struct file_operations emu10k1_mixer_fops = {
+ owner:THIS_MODULE,
llseek:emu10k1_mixer_llseek,
ioctl:emu10k1_mixer_ioctl,
open:emu10k1_mixer_open,
diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c
index ec3849a748b72b..47d1d875f5321d 100644
--- a/drivers/sound/es1370.c
+++ b/drivers/sound/es1370.c
@@ -1030,7 +1030,6 @@ static int es1370_open_mixdev(struct inode *inode, struct file *file)
}
VALIDATE_STATE(s);
file->private_data = s;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1039,7 +1038,6 @@ static int es1370_release_mixdev(struct inode *inode, struct file *file)
struct es1370_state *s = (struct es1370_state *)file->private_data;
VALIDATE_STATE(s);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1049,6 +1047,7 @@ static int es1370_ioctl_mixdev(struct inode *inode, struct file *file, unsigned
}
static /*const*/ struct file_operations es1370_mixer_fops = {
+ owner: THIS_MODULE,
llseek: es1370_llseek,
ioctl: es1370_ioctl_mixdev,
open: es1370_open_mixdev,
@@ -1710,7 +1709,6 @@ static int es1370_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1734,11 +1732,11 @@ static int es1370_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations es1370_audio_fops = {
+ owner: THIS_MODULE,
llseek: es1370_llseek,
read: es1370_read,
write: es1370_write,
@@ -1975,7 +1973,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int
return 0;
case SNDCTL_DSP_GETOSPACE:
- if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac1(s)) != 0)
+ if (!(s->ctrl & CTRL_DAC1_EN) && (val = prog_dmabuf_dac1(s)) != 0)
return val;
spin_lock_irqsave(&s->lock, flags);
es1370_update_ptr(s);
@@ -2116,7 +2114,6 @@ static int es1370_open_dac(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= FMODE_DAC;
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2132,11 +2129,11 @@ static int es1370_release_dac(struct inode *inode, struct file *file)
s->open_mode &= ~FMODE_DAC;
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations es1370_dac_fops = {
+ owner: THIS_MODULE,
llseek: es1370_llseek,
write: es1370_write_dac,
poll: es1370_poll_dac,
@@ -2357,7 +2354,6 @@ static int es1370_midi_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2403,11 +2399,11 @@ static int es1370_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations es1370_midi_fops = {
+ owner: THIS_MODULE,
llseek: es1370_llseek,
read: es1370_midi_read,
write: es1370_midi_write,
diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c
index 44189f010c0b45..109ac71c022420 100644
--- a/drivers/sound/es1371.c
+++ b/drivers/sound/es1371.c
@@ -168,6 +168,7 @@
#define CT5880REV_CT5880_C 0x02
#define ES1371REV_ES1371_B 0x09
#define EV1938REV_EV1938_A 0x00
+#define ES1371REV_ES1373_8 0x08
#define ES1371_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371)
@@ -1216,7 +1217,6 @@ static int es1371_open_mixdev(struct inode *inode, struct file *file)
}
VALIDATE_STATE(s);
file->private_data = s;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1225,7 +1225,6 @@ static int es1371_release_mixdev(struct inode *inode, struct file *file)
struct es1371_state *s = (struct es1371_state *)file->private_data;
VALIDATE_STATE(s);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1238,6 +1237,7 @@ static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned
}
static /*const*/ struct file_operations es1371_mixer_fops = {
+ owner: THIS_MODULE,
llseek: es1371_llseek,
ioctl: es1371_ioctl_mixdev,
open: es1371_open_mixdev,
@@ -1895,7 +1895,6 @@ static int es1371_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1918,11 +1917,11 @@ static int es1371_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations es1371_audio_fops = {
+ owner: THIS_MODULE,
llseek: es1371_llseek,
read: es1371_read,
write: es1371_write,
@@ -2150,7 +2149,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int
return 0;
case SNDCTL_DSP_GETOSPACE:
- if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac1(s)) != 0)
+ if (!(s->ctrl & CTRL_DAC1_EN) && (val = prog_dmabuf_dac1(s)) != 0)
return val;
spin_lock_irqsave(&s->lock, flags);
es1371_update_ptr(s);
@@ -2290,7 +2289,6 @@ static int es1371_open_dac(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= FMODE_DAC;
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2306,11 +2304,11 @@ static int es1371_release_dac(struct inode *inode, struct file *file)
s->open_mode &= ~FMODE_DAC;
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations es1371_dac_fops = {
+ owner: THIS_MODULE,
llseek: es1371_llseek,
write: es1371_write_dac,
poll: es1371_poll_dac,
@@ -2531,7 +2529,6 @@ static int es1371_midi_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2576,11 +2573,11 @@ static int es1371_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations es1371_midi_fops = {
+ owner: THIS_MODULE,
llseek: es1371_llseek,
read: es1371_midi_read,
write: es1371_midi_write,
@@ -2778,7 +2775,8 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
/* if we are a 5880 turn on the AC97 */
if (s->vendor == PCI_VENDOR_ID_ENSONIQ &&
((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev == CT5880REV_CT5880_C) ||
- (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A))) {
+ (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) ||
+ (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) {
cssr |= CSTAT_5880_AC97_RST;
outl(cssr, s->io+ES1371_REG_STATUS);
/* need to delay around 20ms(bleech) to give
diff --git a/drivers/sound/esssolo1.c b/drivers/sound/esssolo1.c
index 2d7e15f5132bf9..930e58f463fa4a 100644
--- a/drivers/sound/esssolo1.c
+++ b/drivers/sound/esssolo1.c
@@ -909,7 +909,6 @@ static int solo1_open_mixdev(struct inode *inode, struct file *file)
}
VALIDATE_STATE(s);
file->private_data = s;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -918,7 +917,6 @@ static int solo1_release_mixdev(struct inode *inode, struct file *file)
struct solo1_state *s = (struct solo1_state *)file->private_data;
VALIDATE_STATE(s);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -928,6 +926,7 @@ static int solo1_ioctl_mixdev(struct inode *inode, struct file *file, unsigned i
}
static /*const*/ struct file_operations solo1_mixer_fops = {
+ owner: THIS_MODULE,
llseek: solo1_llseek,
ioctl: solo1_ioctl_mixdev,
open: solo1_open_mixdev,
@@ -1526,7 +1525,6 @@ static int solo1_release(struct inode *inode, struct file *file)
s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1572,12 +1570,12 @@ static int solo1_open(struct inode *inode, struct file *file)
s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
prog_codec(s);
return 0;
}
static /*const*/ struct file_operations solo1_audio_fops = {
+ owner: THIS_MODULE,
llseek: solo1_llseek,
read: solo1_read,
write: solo1_write,
@@ -1869,7 +1867,6 @@ static int solo1_midi_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1915,11 +1912,11 @@ static int solo1_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations solo1_midi_fops = {
+ owner: THIS_MODULE,
llseek: solo1_llseek,
read: solo1_midi_read,
write: solo1_midi_write,
@@ -2075,7 +2072,6 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file)
outb(1, s->sbbase+3); /* enable OPL3 */
s->open_mode |= FMODE_DMFM;
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2096,11 +2092,11 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
release_region(s->sbbase, FMSYNTH_EXTENT);
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations solo1_dmfm_fops = {
+ owner: THIS_MODULE,
llseek: solo1_llseek,
ioctl: solo1_dmfm_ioctl,
open: solo1_dmfm_open,
diff --git a/drivers/sound/i810_audio.c b/drivers/sound/i810_audio.c
index 76bfcc3c058098..1ac21c429ac50c 100644
--- a/drivers/sound/i810_audio.c
+++ b/drivers/sound/i810_audio.c
@@ -46,6 +46,18 @@
* There is no midi support, no synth support. Use timidity. To get
* esd working you need to use esd -r 48000 as it won't probe 48KHz
* by default. mpg123 can't handle 48Khz only audio so use xmms.
+ *
+ * Fix The Sound On Dell
+ *
+ * Not everyone uses 48KHz. We know of no way to detect this reliably
+ * and certainly not to get the right data. If your i810 audio sounds
+ * stupid you may need to investigate other speeds. According to Analog
+ * they tend to use a 14.318MHz clock which gives you a base rate of
+ * 41194Hz.
+ *
+ * This is available via the 'ftsodell=1' option.
+ *
+ * If you need to force a specific rate set the clocking= option
*/
#include <linux/module.h>
@@ -74,10 +86,17 @@
#ifndef PCI_DEVICE_ID_INTEL_82901
#define PCI_DEVICE_ID_INTEL_82901 0x2425
#endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH2
+#define PCI_DEVICE_ID_INTEL_ICH2 0x2445
+#endif
#ifndef PCI_DEVICE_ID_INTEL_440MX
#define PCI_DEVICE_ID_INTEL_440MX 0x7195
#endif
+static int ftsodell=0;
+static int clocking=48000;
+
+
#define ADC_RUNNING 1
#define DAC_RUNNING 2
@@ -180,13 +199,15 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 };
enum {
ICH82801AA = 0,
ICH82901AB,
- INTEL440MX
+ INTEL440MX,
+ INTELICH2,
};
static char * card_names[] = {
"Intel ICH 82801AA",
"Intel ICH 82901AB",
- "Intel 440MX"
+ "Intel 440MX",
+ "Intel ICH2"
};
static struct pci_device_id i810_pci_tbl [] __initdata = {
@@ -196,6 +217,8 @@ static struct pci_device_id i810_pci_tbl [] __initdata = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82901AB},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_440MX,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTEL440MX},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH2},
{0,}
};
@@ -295,7 +318,6 @@ struct i810_card {
static struct i810_card *devs = NULL;
static int i810_open_mixdev(struct inode *inode, struct file *file);
-static int i810_release_mixdev(struct inode *inode, struct file *file);
static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg);
static loff_t i810_llseek(struct file *file, loff_t offset, int origin);
@@ -363,12 +385,27 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra
struct ac97_codec *codec=state->card->ac97_codec[0];
if(!(state->card->ac97_features&0x0001))
- return 48000;
+ {
+ dmabuf->rate = clocking;
+ return clocking;
+ }
if (rate > 48000)
rate = 48000;
- if (rate < 4000)
- rate = 4000;
+ if (rate < 8000)
+ rate = 8000;
+
+ /*
+ * Adjust for misclocked crap
+ */
+
+ rate = ( rate * clocking)/48000;
+
+ /* Analog codecs can go lower via magic registers but others
+ might not */
+
+ if(rate < 8000)
+ rate = 8000;
/* Power down the DAC */
dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
@@ -378,10 +415,10 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra
i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate);
rp=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
- printk("DAC rate set to %d Returned %d\n",
- rate, (int)rp);
+// printk("DAC rate set to %d Returned %d\n",
+// rate, (int)rp);
- rate=rp;
+ rate=(rp * 48000) / clocking;
/* Power it back up */
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
@@ -402,25 +439,41 @@ static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int ra
struct ac97_codec *codec=state->card->ac97_codec[0];
if(!(state->card->ac97_features&0x0001))
- return 48000;
+ {
+ dmabuf->rate = clocking;
+ return clocking;
+ }
if (rate > 48000)
rate = 48000;
- if (rate < 4000)
- rate = 4000;
+ if (rate < 8000)
+ rate = 8000;
+
+ /*
+ * Adjust for misclocked crap
+ */
+
+ rate = ( rate * clocking)/48000;
+
+ /* Analog codecs can go lower via magic registers but others
+ might not */
+
+ if(rate < 8000)
+ rate = 8000;
+
/* Power down the ADC */
dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100);
/* Load the rate and read the effective rate */
- i810_ac97_set(codec, AC97_PCM_LR_ADC_RATE, rate);
- rp=i810_ac97_get(codec, AC97_PCM_LR_ADC_RATE);
+ i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate);
+ rp=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE);
- printk("ADC rate set to %d Returned %d\n",
- rate, (int)rp);
+// printk("ADC rate set to %d Returned %d\n",
+// rate, (int)rp);
- rate=rp;
+ rate = (rp * 48000) / clocking;
/* Power it back up */
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
@@ -1547,7 +1600,6 @@ static int i810_open(struct inode *inode, struct file *file)
state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&state->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1582,11 +1634,11 @@ static int i810_release(struct inode *inode, struct file *file)
/* we're covered by the open_sem */
up(&state->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations i810_audio_fops = {
+ owner: THIS_MODULE,
llseek: i810_llseek,
read: i810_read,
write: i810_write,
@@ -1640,13 +1692,6 @@ static int i810_open_mixdev(struct inode *inode, struct file *file)
match:
file->private_data = card->ac97_codec[i];
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int i810_release_mixdev(struct inode *inode, struct file *file)
-{
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1659,10 +1704,10 @@ static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned in
}
static /*const*/ struct file_operations i810_mixer_fops = {
+ owner: THIS_MODULE,
llseek: i810_llseek,
ioctl: i810_ioctl_mixdev,
open: i810_open_mixdev,
- release: i810_release_mixdev,
};
/* AC97 codec initialisation. */
@@ -1828,8 +1873,11 @@ static void __exit i810_remove(struct pci_dev *pci_dev)
kfree(card);
}
+
MODULE_AUTHOR("");
MODULE_DESCRIPTION("Intel 810 audio support");
+MODULE_PARM(ftsodell, "i");
+MODULE_PARM(clocking, "i");
#define I810_MODULE_NAME "intel810_audio"
@@ -1845,6 +1893,9 @@ static int __init i810_init_module (void)
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
+ if(ftsodell==1)
+ clocking=41194;
+
printk(KERN_INFO "Intel 810 + AC97 Audio, version "
DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c
index 81a7d21d25f762..cd5a2bc2719e57 100644
--- a/drivers/sound/maestro.c
+++ b/drivers/sound/maestro.c
@@ -236,6 +236,7 @@
#include <linux/reboot.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
+#include <linux/bitops.h>
#include <linux/pm.h>
static int maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d);
@@ -2081,7 +2082,6 @@ static int ess_open_mixdev(struct inode *inode, struct file *file)
return -ENODEV;
file->private_data = card;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2091,7 +2091,6 @@ static int ess_release_mixdev(struct inode *inode, struct file *file)
VALIDATE_CARD(card);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -2105,6 +2104,7 @@ static int ess_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int
}
static /*const*/ struct file_operations ess_mixer_fops = {
+ owner: THIS_MODULE,
llseek: ess_llseek,
ioctl: ess_ioctl_mixdev,
open: ess_open_mixdev,
@@ -2976,7 +2976,6 @@ ess_open(struct inode *inode, struct file *file)
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -3007,11 +3006,11 @@ ess_release(struct inode *inode, struct file *file)
}
up(&s->open_sem);
wake_up(&s->open_wait);
- MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations ess_audio_fops = {
+ owner: THIS_MODULE,
llseek: ess_llseek,
read: ess_read,
write: ess_write,
@@ -3447,11 +3446,7 @@ maestro_install(struct pci_dev *pcidev, int card_type)
return 1;
}
-#ifdef MODULE
-int init_module(void)
-#else
-int SILLY_MAKE_INIT(init_maestro(void))
-#endif
+int __init init_maestro(void)
{
struct pci_dev *pcidev = NULL;
int foundone = 0;
@@ -3558,8 +3553,6 @@ void cleanup_module(void) {
nuke_maestros();
}
-#else /* MODULE */
-__initcall(init_maestro);
#endif
/* --------------------------------------------------------------------- */
@@ -3718,3 +3711,5 @@ maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
out:
return 0;
}
+
+module_init(init_maestro);
diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c
index 7a8a7117b4730e..0d50924d8e2f2e 100644
--- a/drivers/sound/sonicvibes.c
+++ b/drivers/sound/sonicvibes.c
@@ -1240,7 +1240,6 @@ static int sv_open_mixdev(struct inode *inode, struct file *file)
}
VALIDATE_STATE(s);
file->private_data = s;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1249,7 +1248,6 @@ static int sv_release_mixdev(struct inode *inode, struct file *file)
struct sv_state *s = (struct sv_state *)file->private_data;
VALIDATE_STATE(s);
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1259,6 +1257,7 @@ static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int
}
static /*const*/ struct file_operations sv_mixer_fops = {
+ owner: THIS_MODULE,
llseek: sv_llseek,
ioctl: sv_ioctl_mixdev,
open: sv_open_mixdev,
@@ -1900,7 +1899,6 @@ static int sv_open(struct inode *inode, struct file *file)
set_fmt(s, fmtm, fmts);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1923,11 +1921,11 @@ static int sv_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations sv_audio_fops = {
+ owner: THIS_MODULE,
llseek: sv_llseek,
read: sv_read,
write: sv_write,
@@ -2157,7 +2155,6 @@ static int sv_midi_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2203,11 +2200,11 @@ static int sv_midi_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations sv_midi_fops = {
+ owner: THIS_MODULE,
llseek: sv_llseek,
read: sv_midi_read,
write: sv_midi_write,
@@ -2357,7 +2354,6 @@ static int sv_dmfm_open(struct inode *inode, struct file *file)
outb(1, s->iosynth+3); /* enable OPL3 */
s->open_mode |= FMODE_DMFM;
up(&s->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -2377,11 +2373,11 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
}
wake_up(&s->open_wait);
up(&s->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations sv_dmfm_fops = {
+ owner: THIS_MODULE,
llseek: sv_llseek,
ioctl: sv_dmfm_ioctl,
open: sv_dmfm_open,
diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c
index 053b43160f4ff4..da0cfe51c4c2f0 100644
--- a/drivers/sound/sound_core.c
+++ b/drivers/sound/sound_core.c
@@ -456,6 +456,7 @@ static int soundcore_open(struct inode *, struct file *);
static struct file_operations soundcore_fops=
{
+ owner: THIS_MODULE,
open: soundcore_open,
};
@@ -508,12 +509,25 @@ int soundcore_open(struct inode *inode, struct file *file)
s = __look_for_unit(chain, unit);
}
if (s) {
- file->f_op=s->unit_fops;
+ /*
+ * We rely upon the fact that we can't be unloaded while the
+ * subdriver is there, so if ->open() is successful we can
+ * safely drop the reference counter and if it is not we can
+ * revert to old ->f_op. Ugly, indeed, but that's the cost of
+ * switching ->f_op in the first place.
+ */
+ int err = 0;
+ struct file_operations *old_fops = file->f_op;
+ file->f_op = fops_get(s->unit_fops);
spin_unlock(&sound_loader_lock);
if(file->f_op->open)
- return file->f_op->open(inode,file);
- else
- return 0;
+ err = file->f_op->open(inode,file);
+ if (err) {
+ fops_put(file->f_op);
+ file->f_op = fops_get(old_fops);
+ }
+ fops_put(old_fops);
+ return err;
}
spin_unlock(&sound_loader_lock);
return -ENODEV;
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index 0bf2b8e0fa4975..5018ad1e774671 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -495,8 +495,8 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
-struct file_operations oss_sound_fops =
-{
+struct file_operations oss_sound_fops = {
+ owner: THIS_MODULE,
llseek: sound_lseek,
read: sound_read,
write: sound_write,
diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c
index 6a3b8b4d6c1de3..2eb45827448822 100644
--- a/drivers/sound/trident.c
+++ b/drivers/sound/trident.c
@@ -1,6 +1,6 @@
/*
*
- * Trident 4D-Wave/SiS 7018 OSS driver for Linux 2.2.x
+ * Trident 4D-Wave/SiS 7018/ALi 5451 OSS driver for Linux 2.2.x
*
* Driver: Alan Cox <alan@redhat.com>
*
@@ -12,6 +12,7 @@
* Hacked up by:
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support
+ * Ching Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support
*
*
* This program is free software; you can redistribute it and/or modify
@@ -29,10 +30,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* History
- * v0.14.3 May 20 2000 Aaron Holtzman
- * Fix kfree'd memory access in release
- * Fix race in open while looking for a free virtual channel slot
- * remove open_wait wq (which appears to be unused)
+ * v0.14.5 May 23 2000 Ollie Lho
+ * Misc bug fix from the Net
+ * v0.14.4 May 20 2000 Aaron Holtzman
+ * Fix kfree'd memory access in release
+ * Fix race in open while looking for a free virtual channel slot
+ * remove open_wait wq (which appears to be unused)
+ * v0.14.3 May 10 2000 Ollie Lho
+ * fixed a small bug in trident_update_ptr, xmms 1.0.1 no longer uses 100% CPU
* v0.14.2 Mar 29 2000 Ching Ling Lee
* Add clear to silence advance in trident_update_ptr
* fix invalid data of the end of the sound
@@ -109,13 +114,13 @@
#include "trident.h"
-#define DRIVER_VERSION "0.14"
+#define DRIVER_VERSION "0.14.5"
/* magic numbers to protect our data structures */
#define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */
#define TRIDENT_STATE_MAGIC 0x63657373 /* "cess" */
-#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */
+#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */
#define NR_HW_CH 32
@@ -151,7 +156,7 @@ static char * card_names[] = {
"ALi Audio Accelerator"
};
-static struct pci_device_id trident_pci_tbl [] __initdata = {
+static struct pci_device_id trident_pci_tbl [] __devinitdata = {
{PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX},
{PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX,
@@ -314,7 +319,6 @@ static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val);
static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg);
static int trident_open_mixdev(struct inode *inode, struct file *file);
-static int trident_release_mixdev(struct inode *inode, struct file *file);
static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg);
static loff_t trident_llseek(struct file *file, loff_t offset, int origin);
@@ -438,16 +442,14 @@ static void trident_stop_voice(struct trident_card * card, unsigned int channel)
#endif
}
-static u32 trident_get_interrupt_mask (struct trident_card * card,
- unsigned int b)
+static u32 trident_get_interrupt_mask (struct trident_card * card, unsigned int channel)
{
- struct trident_pcm_bank *bank = &card->banks[b];
+ struct trident_pcm_bank *bank = &card->banks[channel];
u32 addr = bank->addresses->aint;
return inl(TRID_REG(card, addr));
}
-static int trident_check_channel_interrupt(struct trident_card * card,
- unsigned int channel)
+static int trident_check_channel_interrupt(struct trident_card * card, unsigned int channel)
{
unsigned int mask = 1 << (channel & 0x1f);
u32 reg = trident_get_interrupt_mask (card, channel >> 5);
@@ -460,8 +462,7 @@ static int trident_check_channel_interrupt(struct trident_card * card,
return (reg & mask) ? TRUE : FALSE;
}
-static void trident_ack_channel_interrupt(struct trident_card * card,
- unsigned int channel)
+static void trident_ack_channel_interrupt(struct trident_card * card, unsigned int channel)
{
unsigned int mask = 1 << (channel & 0x1f);
struct trident_pcm_bank *bank = &card->banks[channel >> 5];
@@ -537,8 +538,7 @@ static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *ca
}
-static void trident_free_pcm_channel(struct trident_card *card,
- unsigned int channel)
+static void trident_free_pcm_channel(struct trident_card *card, int channel)
{
int bank;
@@ -551,7 +551,7 @@ static void trident_free_pcm_channel(struct trident_card *card,
card->banks[bank].bitmap &= ~(1 << (channel));
}
-static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel)
+static void ali_free_pcm_channel(struct trident_card *card, int channel)
{
int bank;
@@ -574,18 +574,16 @@ static int trident_load_channel_registers(struct trident_card *card, u32 *data,
if (channel > 63)
return FALSE;
- /* select hardware channel to write */
+ /* select hardware channel to write */
outb(channel, TRID_REG(card, T4D_LFO_GC_CIR));
/* Output the channel registers, but don't write register
three to an ALI chip. */
-
for (i = 0; i < CHANNEL_REGS; i++) {
if (i == 3 && card->pci_id == PCI_DEVICE_ID_ALI_5451)
continue;
outl(data[i], TRID_REG(card, CHANNEL_START + 4*i));
}
-
return TRUE;
}
@@ -1141,7 +1139,7 @@ static void trident_update_ptr(struct trident_state *state)
dmabuf->hwptr = hwptr;
dmabuf->total_bytes += diff;
- /* error handling and process wake up for DAC */
+ /* error handling and process wake up for ADC */
if (dmabuf->enable == ADC_RUNNING) {
if (dmabuf->mapped) {
dmabuf->count -= diff;
@@ -1171,7 +1169,10 @@ static void trident_update_ptr(struct trident_state *state)
//there is invalid data in the end of half buffer
if ((clear_cnt = half_dmasize - swptr) < 0)
clear_cnt += half_dmasize;
- memset (dmabuf->rawbuf + swptr, silence, clear_cnt); //clear the invalid data
+ //clear the invalid data
+ memset (dmabuf->rawbuf + swptr,
+ silence, clear_cnt);
+
dmabuf->endcleared = 1;
}
} else if (dmabuf->count < (signed) dmabuf->fragsize) {
@@ -1181,12 +1182,15 @@ static void trident_update_ptr(struct trident_state *state)
memset (dmabuf->rawbuf + swptr, silence, clear_cnt);
dmabuf->endcleared = 1;
}
- }
- /* since dma machine only interrupts at ESO and ESO/2, we sure have at
- least half of dma buffer free, so wake up the process unconditionally */
- wake_up(&dmabuf->wait);
+ }
+ /* trident_update_ptr is called by interrupt handler or by process via
+ ioctl/poll, we only wake up the waiting process when we have more
+ than 1/2 buffer of data to process (always true for interrupt handler) */
+ if (dmabuf->count > (signed)dmabuf->dmasize/2)
+ wake_up(&dmabuf->wait);
}
}
+
/* error handling and process wake up for DAC */
if (dmabuf->enable == DAC_RUNNING) {
if (dmabuf->mapped) {
@@ -1203,9 +1207,11 @@ static void trident_update_ptr(struct trident_state *state)
__stop_dac(state);
dmabuf->error++;
}
- /* since dma machine only interrupts at ESO and ESO/2, we sure have at
- least half of dma buffer free, so wake up the process unconditionally */
- wake_up(&dmabuf->wait);
+ /* trident_update_ptr is called by interrupt handler or by process via
+ ioctl/poll, we only wake up the waiting process when we have more
+ than 1/2 buffer free (always true for interrupt handler) */
+ if (dmabuf->count < (signed)dmabuf->dmasize/2)
+ wake_up(&dmabuf->wait);
}
}
dmabuf->update_flag &= ~ALI_ADDRESS_INT_UPDATE;
@@ -1336,7 +1342,8 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_
ret = 0;
if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)
- outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) | ALI_PCM_IN_ENABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL));
+ outl(inl(TRID_REG (state->card, ALI_GLOBAL_CONTROL)) | ALI_PCM_IN_ENABLE,
+ TRID_REG (state->card, ALI_GLOBAL_CONTROL));
while (count > 0) {
spin_lock_irqsave(&state->card->lock, flags);
@@ -1439,7 +1446,8 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count
if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)
if (dmabuf->channel->num == ALI_PCM_IN_CHANNEL)
- outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) & ALI_PCM_IN_DISABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL));
+ outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) &
+ ALI_PCM_IN_DISABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL));
while (count > 0) {
spin_lock_irqsave(&state->card->lock, flags);
@@ -1912,8 +1920,9 @@ static int trident_open(struct inode *inode, struct file *file)
if (card->states[i] == NULL) {
state = card->states[i] = (struct trident_state *)
kmalloc(sizeof(struct trident_state), GFP_KERNEL);
- if (state == NULL)
+ if (state == NULL) {
return -ENOMEM;
+ }
memset(state, 0, sizeof(struct trident_state));
dmabuf = &state->dmabuf;
goto found_virt;
@@ -1923,9 +1932,9 @@ static int trident_open(struct inode *inode, struct file *file)
card = card->next;
}
/* no more virtual channel avaiable */
- if (!state)
+ if (!state) {
return -ENODEV;
-
+ }
found_virt:
/* found a free virtual channel, allocate hardware channels */
if(file->f_mode & FMODE_READ)
@@ -1946,7 +1955,6 @@ static int trident_open(struct inode *inode, struct file *file)
init_waitqueue_head(&dmabuf->wait);
file->private_data = state;
-
/* set default sample format. According to OSS Programmer's Guide /dev/dsp
should be default to unsigned 8-bits, mono, with sample rate 8kHz and
/dev/dspW will accept 16-bits sample */
@@ -1991,11 +1999,10 @@ static int trident_open(struct inode *inode, struct file *file)
up(&card->open_sem);
#ifdef DEBUG
- printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n",
- state->virt,
- dmabuf->channel->num);
+ printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n",
+ state->virt, dmabuf->channel->num);
#endif
- MOD_INC_USE_COUNT;
+
return 0;
}
@@ -2020,7 +2027,6 @@ static int trident_release(struct inode *inode, struct file *file)
dealloc_dmabuf(state);
state->card->free_pcm_channel(state->card, dmabuf->channel->num);
}
-
if (file->f_mode & FMODE_READ) {
stop_adc(state);
dealloc_dmabuf(state);
@@ -2033,11 +2039,11 @@ static int trident_release(struct inode *inode, struct file *file)
/* we're covered by the open_sem */
up(&card->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations trident_audio_fops = {
+ owner: THIS_MODULE,
llseek: trident_llseek,
read: trident_read,
write: trident_write,
@@ -2261,19 +2267,13 @@ static int trident_open_mixdev(struct inode *inode, struct file *file)
card->ac97_codec[i]->dev_mixer == minor)
goto match;
- if (!card)
+ if (!card) {
return -ENODEV;
-
+ }
match:
file->private_data = card->ac97_codec[i];
- MOD_INC_USE_COUNT;
- return 0;
-}
-static int trident_release_mixdev(struct inode *inode, struct file *file)
-{
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -2286,10 +2286,10 @@ static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned
}
static /*const*/ struct file_operations trident_mixer_fops = {
+ owner: THIS_MODULE,
llseek: trident_llseek,
ioctl: trident_ioctl_mixdev,
open: trident_open_mixdev,
- release: trident_release_mixdev,
};
/* AC97 codec initialisation. */
@@ -2385,7 +2385,7 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
}
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
- iobase = pci_resource_start (pci_dev, 0);
+ iobase = pci_resource_start(pci_dev, 0);
if (check_region(iobase, 256)) {
printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
iobase);
@@ -2393,7 +2393,7 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
}
if (pci_enable_device(pci_dev))
- return -ENODEV;
+ return -ENODEV;
if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "trident: out of memory\n");
@@ -2421,20 +2421,19 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
printk(KERN_INFO "trident: %s found at IO 0x%04lx, IRQ %d\n",
card_names[pci_id->driver_data], card->iobase, card->irq);
- if(card->pci_id == PCI_DEVICE_ID_ALI_5451)
- {
+ if(card->pci_id == PCI_DEVICE_ID_ALI_5451) {
card->alloc_pcm_channel = ali_alloc_pcm_channel;
card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel;
card->free_pcm_channel = ali_free_pcm_channel;
card->address_interrupt = ali_address_interrupt;
}
- else
- {
+ else {
card->alloc_pcm_channel = trident_alloc_pcm_channel;
card->alloc_rec_pcm_channel = trident_alloc_pcm_channel;
card->free_pcm_channel = trident_free_pcm_channel;
card->address_interrupt = trident_address_interrupt;
}
+
/* claim our iospace and irq */
request_region(card->iobase, 256, card_names[pci_id->driver_data]);
if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ,
@@ -2462,12 +2461,12 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
}
outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
- if (card->pci_id == PCI_DEVICE_ID_ALI_5451)
- {
+ if (card->pci_id == PCI_DEVICE_ID_ALI_5451) {
/* edited by HMSEO for GT sound */
#ifdef CONFIG_ALPHA_NAUTILUS
- ac97_data = trident_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL);
- trident_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, ac97_data | ALI_EAPD_POWER_DOWN);
+ u16 ac97_data = trident_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL);
+ trident_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL,
+ ac97_data | ALI_EAPD_POWER_DOWN);
#endif
/* edited by HMSEO for GT sound*/
}
diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c
index e4403d9664ab73..ab14427d637533 100644
--- a/drivers/sound/via82cxxx_audio.c
+++ b/drivers/sound/via82cxxx_audio.c
@@ -6,12 +6,16 @@
* See the "COPYING" file distributed with this software for more info.
*
* For a list of known bugs (errata) and documentation,
- * see via82cxxx.txt in linux/Documentation/sound.
+ * see via-audio.pdf in linux/Documentation/DocBook.
+ * If this documentation does not exist, run "make pdfdocs".
+ * If "make pdfdocs" fails, obtain the documentation from
+ * the driver's Website at
+ * http://gtf.org/garzik/drivers/via82cxxx/
*
*/
-#define VIA_VERSION "1.1.6"
+#define VIA_VERSION "1.1.8"
#include <linux/config.h>
@@ -304,7 +308,7 @@ static void via_chan_pcm_fmt (struct via_info *card,
static struct pci_device_id via_pci_tbl[] __initdata = {
- { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, }
};
MODULE_DEVICE_TABLE(pci,via_pci_tbl);
@@ -325,12 +329,40 @@ static struct pci_driver via_driver = {
*
*/
+/**
+ * via_chan_stop - Terminate DMA on specified PCM channel
+ * @iobase: PCI base address for SGD channel registers
+ *
+ * Terminate scatter-gather DMA operation for given
+ * channel (derived from @iobase), if DMA is active.
+ *
+ * Note that @iobase is not the PCI base address,
+ * but the PCI base address plus an offset to
+ * one of three PCM channels supported by the chip.
+ *
+ */
+
static inline void via_chan_stop (int iobase)
{
if (inb (iobase + VIA_PCM_STATUS) & VIA_SGD_ACTIVE)
outb (VIA_SGD_TERMINATE, iobase + VIA_PCM_CONTROL);
}
+
+/**
+ * via_chan_status_clear - Clear status flags on specified DMA channel
+ * @iobase: PCI base address for SGD channel registers
+ *
+ * Clear any pending status flags for the given
+ * DMA channel (derived from @iobase), if any
+ * flags are asserted.
+ *
+ * Note that @iobase is not the PCI base address,
+ * but the PCI base address plus an offset to
+ * one of three PCM channels supported by the chip.
+ *
+ */
+
static inline void via_chan_status_clear (int iobase)
{
u8 tmp = inb (iobase + VIA_PCM_STATUS);
@@ -339,12 +371,33 @@ static inline void via_chan_status_clear (int iobase)
outb (tmp, iobase + VIA_PCM_STATUS);
}
+
+/**
+ * sg_begin - Begin recording or playback on a PCM channel
+ * @chan: Channel for which DMA operation shall begin
+ *
+ * Start scatter-gather DMA for the given channel.
+ *
+ */
+
static inline void sg_begin (struct via_channel *chan)
{
outb (VIA_SGD_START, chan->iobase + VIA_PCM_CONTROL);
}
+/**
+ * via_chan_bufs_in_use - Number of buffers waiting to be consumed
+ * @chan: Channel for which DMA buffers will be counted
+ *
+ * Count the number of buffers waiting to be consumed. For a
+ * playback operation, this is the number of buffers which have
+ * yet to be sent to the DAC. For a recording operation, this
+ * is the number of buffers waiting to be consumed by software
+ * calling read() system call.
+ *
+ */
+
static inline int via_chan_bufs_in_use (struct via_channel *chan)
{
return atomic_read(&chan->next_buf) -
@@ -352,12 +405,31 @@ static inline int via_chan_bufs_in_use (struct via_channel *chan)
}
+/**
+ * via_chan_full - Check for no-free-buffers condition
+ * @chan: Channel for which DMA full condition will be checked
+ *
+ * Count the number of buffers waiting to be consumed, and return
+ * true (non-zero) if no buffers are available to be filled on the
+ * given DMA channel.
+ *
+ */
+
static inline int via_chan_full (struct via_channel *chan)
{
return (via_chan_bufs_in_use (chan) == VIA_DMA_BUFFERS);
}
+/**
+ * via_chan_empty - Check for no-buffers-in-use condition
+ * @chan: Channel for which DMA empty condition will be checked
+ *
+ * Count the number of buffers waiting to be consumed, and return
+ * true (non-zero) if no buffers are currently in use.
+ *
+ */
+
static inline int via_chan_empty (struct via_channel *chan)
{
return (atomic_read(&chan->next_buf) ==
@@ -372,6 +444,15 @@ static inline int via_chan_empty (struct via_channel *chan)
*
*/
+
+/**
+ * via_stop_everything - Stop all audio operations
+ * @card: Private info for specified board
+ *
+ * Stops all DMA operations and interrupts, and clear
+ * any pending status bits resulting from those operations.
+ */
+
static void via_stop_everything (struct via_info *card)
{
DPRINTK ("ENTER\n");
@@ -402,6 +483,24 @@ static void via_stop_everything (struct via_info *card)
}
+/**
+ * via_set_rate - Set PCM rate for given channel
+ * @card: Private info for specified board
+ * @rate: Desired PCM sample rate, in Khz
+ * @inhale_deeply: Boolean. If non-zero (true), the recording sample rate
+ * is set. If zero (false), the playback sample rate
+ * is set.
+ *
+ * Sets the PCM sample rate for a channel.
+ *
+ * Values for @rate are clamped to a range of 4000 Khz through 48000 Khz,
+ * due to hardware constraints.
+ *
+ * FIXME: @inhale_deeply argument is ignored, and %AC97_PCM_FRONT_DAC_RATE
+ * is the only rate which is really set. This needs to be fixed when
+ * recording support is added.
+ */
+
static int via_set_rate (struct via_info *card, unsigned rate, int inhale_deeply)
{
@@ -423,12 +522,32 @@ static int via_set_rate (struct via_info *card, unsigned rate, int inhale_deeply
}
+/**
+ * via_set_adc_rate - Set PCM rate for recording channel
+ * @card: Private info for specified board
+ * @rate: Desired PCM sample rate, in Khz
+ *
+ * Sets the PCM sample rate for a recording channel.
+ *
+ * FIXME: @inhale_deeply argument to via_set_rate is ignored, and %AC97_PCM_FRONT_DAC_RATE
+ * is the only rate which is really set. Thus, this function will
+ * not work until via_set_rate is fixed.
+ */
+
static inline int via_set_adc_rate (struct via_info *card, int rate)
{
return via_set_rate (card, rate, 1);
}
+/**
+ * via_set_dac_rate - Set PCM rate for playback channel
+ * @card: Private info for specified board
+ * @rate: Desired PCM sample rate, in Khz
+ *
+ * Sets the PCM sample rate for a playback channel.
+ */
+
static inline int via_set_dac_rate (struct via_info *card, int rate)
{
return via_set_rate (card, rate, 0);
@@ -442,6 +561,27 @@ static inline int via_set_dac_rate (struct via_info *card, int rate)
*
*/
+/**
+ * via_chan_init - Initialize PCM channel
+ * @card: Private audio chip info
+ * @chan: Channel to be initialized
+ * @chan_ofs: Offset from PCI address, which determines the
+ * set of SGD registers to use.
+ *
+ * Performs all the preparations necessary to begin
+ * using a PCM channel.
+ *
+ * Currently the preparations include allocating the
+ * scatter-gather DMA table and buffers, setting the
+ * PCM channel to a known state, and passing the
+ * address of the DMA table to the hardware.
+ *
+ * Note that special care is taken when passing the
+ * DMA table address to hardware, because it was found
+ * during driver development that the hardware did not
+ * always "take" the address.
+ */
+
static int via_chan_init (struct via_info *card,
struct via_channel *chan, long chan_ofs)
{
@@ -533,6 +673,20 @@ err_out_nomem:
}
+/**
+ * via_chan_free - Release a PCM channel
+ * @card: Private audio chip info
+ * @chan: Channel to be released
+ *
+ * Performs all the functions necessary to clean up
+ * an initialized channel.
+ *
+ * Currently these functions include disabled any
+ * active DMA operations, setting the PCM channel
+ * back to a known state, and releasing any allocated
+ * sound buffers.
+ */
+
static void via_chan_free (struct via_info *card, struct via_channel *chan)
{
int i;
@@ -575,6 +729,22 @@ static void via_chan_free (struct via_info *card, struct via_channel *chan)
}
+/**
+ * via_chan_pcm_fmt - Update PCM channel settings
+ * @card: Private audio chip info
+ * @chan: Channel to be updated
+ * @reset: Boolean. If non-zero, channel will be reset
+ * to 8-bit mono mode.
+ *
+ * Stores the settings of the current PCM format,
+ * 8-bit or 16-bit, and mono/stereo, into the
+ * hardware settings for the specified channel.
+ * If @reset is non-zero, the channel is reset
+ * to 8-bit mono mode. Otherwise, the channel
+ * is set to the values stored in the channel
+ * information struct @chan.
+ */
+
static void via_chan_pcm_fmt (struct via_info *card,
struct via_channel *chan, int reset)
{
@@ -603,6 +773,14 @@ static void via_chan_pcm_fmt (struct via_info *card,
}
+/**
+ * via_chan_clear - Stop DMA channel operation, and reset pointers
+ * @chan: Channel to be cleared
+ *
+ * Call via_chan_stop to halt DMA operations, and then resets
+ * all software pointers which track DMA operation.
+ */
+
static void via_chan_clear (struct via_channel *chan)
{
via_chan_stop (chan->iobase);
@@ -612,6 +790,21 @@ static void via_chan_clear (struct via_channel *chan)
}
+/**
+ * via_chan_set_speed - Set PCM sample rate for given channel
+ * @card: Private info for specified board
+ * @chan: Channel whose sample rate will be adjusted
+ * @val: New sample rate, in Khz
+ *
+ * Helper function for the %SNDCTL_DSP_SPEED ioctl. OSS semantics
+ * demand that all audio operations halt (if they are not already
+ * halted) when the %SNDCTL_DSP_SPEED is given.
+ *
+ * This function halts all audio operations for the given channel
+ * @chan, and then calls via_set_rate to set the audio hardware
+ * to the new rate.
+ */
+
static int via_chan_set_speed (struct via_info *card,
struct via_channel *chan, int val)
{
@@ -626,6 +819,21 @@ static int via_chan_set_speed (struct via_info *card,
}
+/**
+ * via_chan_set_fmt - Set PCM sample size for given channel
+ * @card: Private info for specified board
+ * @chan: Channel whose sample size will be adjusted
+ * @val: New sample size, use the %AFMT_xxx constants
+ *
+ * Helper function for the %SNDCTL_DSP_SETFMT ioctl. OSS semantics
+ * demand that all audio operations halt (if they are not already
+ * halted) when the %SNDCTL_DSP_SETFMT is given.
+ *
+ * This function halts all audio operations for the given channel
+ * @chan, and then calls via_chan_pcm_fmt to set the audio hardware
+ * to the new sample size, either 8-bit or 16-bit.
+ */
+
static int via_chan_set_fmt (struct via_info *card,
struct via_channel *chan, int val)
{
@@ -656,6 +864,21 @@ static int via_chan_set_fmt (struct via_info *card,
}
+/**
+ * via_chan_set_stereo - Enable or disable stereo for a DMA channel
+ * @card: Private info for specified board
+ * @chan: Channel whose stereo setting will be adjusted
+ * @val: New sample size, use the %AFMT_xxx constants
+ *
+ * Helper function for the %SNDCTL_DSP_CHANNELS and %SNDCTL_DSP_STEREO ioctls. OSS semantics
+ * demand that all audio operations halt (if they are not already
+ * halted) when %SNDCTL_DSP_CHANNELS or SNDCTL_DSP_STEREO is given.
+ *
+ * This function halts all audio operations for the given channel
+ * @chan, and then calls via_chan_pcm_fmt to set the audio hardware
+ * to enable or disable stereo.
+ */
+
static int via_chan_set_stereo (struct via_info *card,
struct via_channel *chan, int val)
{
@@ -690,6 +913,14 @@ static int via_chan_set_stereo (struct via_info *card,
#if 0
+/**
+ * via_chan_dump_bufs - Display DMA table contents
+ * @chan: Channel whose DMA table will be displayed
+ *
+ * Debugging function which displays the contents of the
+ * scatter-gather DMA table for the given channel @chan.
+ */
+
static void via_chan_dump_bufs (struct via_channel *chan)
{
int i;
@@ -715,6 +946,15 @@ static void via_chan_dump_bufs (struct via_channel *chan)
*
*/
+/**
+ * via_ac97_wait_idle - Wait until AC97 codec is not busy
+ * @card: Private info for specified board
+ *
+ * Sleep until the AC97 codec is no longer busy.
+ * Returns the final value read from the SGD
+ * register being polled.
+ */
+
static u8 via_ac97_wait_idle (struct via_info *card)
{
u8 tmp8;
@@ -740,6 +980,21 @@ static u8 via_ac97_wait_idle (struct via_info *card)
}
+/**
+ * via_ac97_read_reg - Read AC97 standard register
+ * @codec: Pointer to generic AC97 codec info
+ * @reg: Index of AC97 register to be read
+ *
+ * Read the value of a single AC97 codec register,
+ * as defined by the Intel AC97 specification.
+ *
+ * Defines the standard AC97 read-register operation
+ * required by the kernel's ac97_codec interface.
+ *
+ * Returns the 16-bit value stored in the specified
+ * register.
+ */
+
static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg)
{
u32 data;
@@ -788,6 +1043,19 @@ err_out:
}
+/**
+ * via_ac97_write_reg - Write AC97 standard register
+ * @codec: Pointer to generic AC97 codec info
+ * @reg: Index of AC97 register to be written
+ * @value: Value to be written to AC97 register
+ *
+ * Write the value of a single AC97 codec register,
+ * as defined by the Intel AC97 specification.
+ *
+ * Defines the standard AC97 write-register operation
+ * required by the kernel's ac97_codec interface.
+ */
+
static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value)
{
u32 data;
@@ -829,8 +1097,6 @@ static int via_mixer_open (struct inode *inode, struct file *file)
DPRINTK ("ENTER\n");
- MOD_INC_USE_COUNT;
-
pci_for_each_dev(pdev) {
drvr = pci_dev_driver (pdev);
if (drvr == &via_driver) {
@@ -843,7 +1109,6 @@ static int via_mixer_open (struct inode *inode, struct file *file)
}
DPRINTK ("EXIT, returning -ENODEV\n");
- MOD_DEC_USE_COUNT;
return -ENODEV;
match:
@@ -853,18 +1118,6 @@ match:
return 0;
}
-
-static int via_mixer_release (struct inode *inode, struct file *file)
-{
- DPRINTK ("ENTER\n");
-
- MOD_DEC_USE_COUNT;
-
- DPRINTK ("EXIT, returning 0\n");
- return 0;
-}
-
-
static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -889,8 +1142,8 @@ static loff_t via_llseek(struct file *file, loff_t offset, int origin)
static struct file_operations via_mixer_fops = {
+ owner: THIS_MODULE,
open: via_mixer_open,
- release: via_mixer_release,
llseek: via_llseek,
ioctl: via_mixer_ioctl,
};
@@ -971,9 +1224,11 @@ static int __init via_ac97_reset (struct via_info *card)
VIA_CR41_VRA | VIA_CR41_AC97_RESET);
udelay (100);
+#if 0 /* this breaks on K7M */
/* disable legacy stuff */
pci_write_config_byte (pdev, 0x42, 0x00);
udelay(10);
+#endif
/* route FM trap to IRQ, disable FM trap */
pci_write_config_byte (pdev, 0x48, 0x05);
@@ -1097,50 +1352,36 @@ static void via_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct via_info *card = dev_id;
struct via_channel *chan;
u8 status;
- int unhandled = 1;
- static long intcount = 0;
- assert (irq == card->pdev->irq);
-
- intcount++;
-
status = inb (card->baseaddr + 0x00);
if (status) {
assert (card->open_mode & FMODE_WRITE);
chan = &card->ch_out;
- unhandled = 0;
if (status & VIA_SGD_FLAG) {
assert ((status & VIA_SGD_EOL) == 0);
outb (VIA_SGD_FLAG, chan->iobase + 0x00);
- DPRINTK("FLAG intr, status=0x%02X, intcount=%ld\n",
- status, intcount);
+ DPRINTK("FLAG intr, status=0x%02X\n", status);
via_interrupt_write (chan);
}
if (status & VIA_SGD_EOL) {
assert ((status & VIA_SGD_FLAG) == 0);
outb (VIA_SGD_EOL, chan->iobase + 0x00);
- DPRINTK("EOL intr, status=0x%02X, intcount=%ld\n",
- status, intcount);
+ DPRINTK("EOL intr, status=0x%02X\n", status);
via_interrupt_write (chan);
}
if (status & VIA_SGD_STOPPED) {
outb (VIA_SGD_STOPPED, chan->iobase + 0x00);
- DPRINTK("STOPPED intr, status=0x%02X, intcount=%ld\n",
- status, intcount);
+ DPRINTK("STOPPED intr, status=0x%02X\n", status);
}
#if 0
via_chan_dump_bufs (&card->ch_out);
#endif
}
-
- if (unhandled)
- printk (KERN_WARNING PFX "unhandled interrupt, st=%02x, st32=%08x\n",
- status, inl (card->baseaddr + 0x84));
}
@@ -1229,6 +1470,7 @@ static void via_interrupt_cleanup (struct via_info *card)
*/
static struct file_operations via_dsp_fops = {
+ owner: THIS_MODULE,
open: via_dsp_open,
release: via_dsp_release,
read: via_dsp_read,
@@ -1860,8 +2102,6 @@ static int via_dsp_open (struct inode *inode, struct file *file)
DPRINTK ("ENTER, minor=%d, file->f_mode=0x%x\n", minor, file->f_mode);
- MOD_INC_USE_COUNT;
-
if (file->f_mode & FMODE_READ) /* no input ATM */
goto err_out;
@@ -1951,7 +2191,6 @@ err_out_clear_mode:
card->open_mode &= ~file->f_mode;
spin_unlock_irqrestore (&card->lock, flags);
err_out:
- MOD_DEC_USE_COUNT;
DPRINTK("ERROR EXIT, returning %d\n", rc);
return rc;
}
@@ -1981,7 +2220,6 @@ static int via_dsp_release(struct inode *inode, struct file *file)
spin_unlock_irqrestore (&card->lock, flags);
wake_up (&card->open_wait);
- MOD_DEC_USE_COUNT;
DPRINTK("EXIT, returning 0\n");
return 0;
@@ -2331,6 +2569,7 @@ static void __exit via_remove_one (struct pci_dev *pdev)
via_interrupt_cleanup (card);
via_card_cleanup_proc (card);
via_dsp_cleanup (card);
+ via_ac97_cleanup (card);
release_region (pci_resource_start (pdev, 0), pci_resource_len (pdev, 0));
@@ -2360,12 +2599,9 @@ static int __init init_via82cxxx_audio(void)
int rc;
DPRINTK ("ENTER\n");
-
- MOD_INC_USE_COUNT;
rc = via_init_proc ();
if (rc) {
- MOD_DEC_USE_COUNT;
DPRINTK ("EXIT, returning %d\n", rc);
return rc;
}
@@ -2375,13 +2611,10 @@ static int __init init_via82cxxx_audio(void)
if (rc == 0)
pci_unregister_driver (&via_driver);
via_cleanup_proc ();
- MOD_DEC_USE_COUNT;
DPRINTK ("EXIT, returning -ENODEV\n");
return -ENODEV;
}
- MOD_DEC_USE_COUNT;
-
DPRINTK ("EXIT, returning 0\n");
return 0;
}
diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c
index 4bf595f86afd73..a8f826031b71f9 100644
--- a/drivers/sound/wavfront.c
+++ b/drivers/sound/wavfront.c
@@ -1953,7 +1953,6 @@ wavefront_open (struct inode *inode, struct file *file)
{
/* XXX fix me */
dev.opened = file->f_flags;
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1962,7 +1961,6 @@ wavefront_release(struct inode *inode, struct file *file)
{
dev.opened = 0;
dev.debug = 0;
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1996,6 +1994,7 @@ wavefront_ioctl(struct inode *inode, struct file *file,
}
static /*const*/ struct file_operations wavefront_fops = {
+ owner: THIS_MODULE,
llseek: wavefront_llseek,
ioctl: wavefront_ioctl,
open: wavefront_open,
diff --git a/drivers/sound/ymf_sb.c b/drivers/sound/ymf_sb.c
new file mode 100644
index 00000000000000..a221a05d0d30e1
--- /dev/null
+++ b/drivers/sound/ymf_sb.c
@@ -0,0 +1,867 @@
+/*
+ Legacy audio driver for YMF724, 740, 744, 754 series.
+ Copyright 2000 Daisuke Nagano <breeze.nagano@nifty.ne.jp>
+
+ Based on the VIA 82Cxxx driver by Jeff Garzik <jgarzik@pobox.com>
+ And ported to 2.3.x by Jeff Garzik too :) My it is a small world.
+
+ Distribued under the GNU PUBLIC LICENSE (GPL) Version 2.
+ See the "COPYING" file distributed with kernel source tree for more info.
+
+ -------------------------------------------------------------------------
+
+ It only supports SBPro compatible function of YMF7xx series s.t.
+ * 22.05kHz, 8-bit and stereo sample
+ * OPL3-compatible FM synthesizer
+ * MPU-401 compatible "external" MIDI interface
+
+ -------------------------------------------------------------------------
+
+ Revision history
+
+ Tue May 14 19:00:00 2000 0.0.1
+ * initial release
+
+ Tue May 16 19:29:29 2000 0.0.2
+
+ * add a little delays for reset devices.
+ * fixed addressing bug.
+
+ Sun May 21 15:14:37 2000 0.0.3
+
+ * Add 'master_vol' module parameter to change 'PCM out Vol' of AC'97.
+ * remove native UART401 support. External MIDI port should be supported
+ by sb_midi driver.
+ * add support for SPDIF OUT. Module parameter 'spdif_out' is now available.
+
+ Wed May 31 00:13:57 2000 0.0.4
+
+ * remove entries in Hwmcode.h. Now YMF744 / YMF754 sets instructions
+ in 724hwmcode.h.
+ * fixed wrong legacy_io setting on YMF744/YMF754 .
+
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ac97_codec.h>
+
+#include <asm/io.h>
+
+#include "sound_config.h"
+#include "soundmodule.h"
+#include "sb.h"
+
+#include "724hwmcode.h"
+
+#undef YMF_DEBUG
+#define SUPPORT_UART401_MIDI 1
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef SOUND_LOCK
+#define SOUND_LOCK do {} while (0)
+#define SOUND_LOCK_END do {} while (0)
+#endif
+
+#ifndef PCI_VENDOR_ID_YAMAHA
+#define PCI_VENDOR_ID_YAMAHA 0x1073
+#endif
+#ifndef PCI_DEVICE_ID_YMF724
+#define PCI_DEVICE_ID_YMF724 0x0004
+#endif
+#ifndef PCI_DEVICE_ID_YMF740
+#define PCI_DEVICE_ID_YMF740 0x000A
+#endif
+#ifndef PCI_DEVICE_ID_YMF740C
+#define PCI_DEVICE_ID_YMF740C 0x000C
+#endif
+#ifndef PCI_DEVICE_ID_YMF724F
+#define PCI_DEVICE_ID_YMF724F 0x000D
+#endif
+#ifndef PCI_DEVICE_ID_YMF744
+#define PCI_DEVICE_ID_YMF744 0x0010
+#endif
+#ifndef PCI_DEVICE_ID_YMF754
+#define PCI_DEVICE_ID_YMF754 0x0012
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#define YMFSB_RESET_DELAY 5
+
+#define YMFSB_REGSIZE 0x8000
+
+#define YMFSB_AC97TIMEOUT 2000
+
+#define YMFSB_WORKBITTIMEOUT 250000
+
+#define YMFSB_DSPLENGTH 0x0080
+#define YMFSB_CTRLLENGTH 0x3000
+
+#define YMFSB_PCIR_VENDORID 0x00
+#define YMFSB_PCIR_DEVICEID 0x02
+#define YMFSB_PCIR_CMD 0x04
+#define YMFSB_PCIR_REVISIONID 0x08
+#define YMFSB_PCIR_BASEADDR 0x10
+#define YMFSB_PCIR_IRQ 0x3c
+
+#define YMFSB_PCIR_LEGCTRL 0x40
+#define YMFSB_PCIR_ELEGCTRL 0x42
+#define YMFSB_PCIR_DSXGCTRL 0x48
+#define YMFSB_PCIR_OPLADR 0x60
+#define YMFSB_PCIR_SBADR 0x62
+#define YMFSB_PCIR_MPUADR 0x64
+
+#define YMFSB_INTFLAG 0x0004
+#define YMFSB_ACTIVITY 0x0006
+#define YMFSB_GLOBALCTRL 0x0008
+#define YMFSB_ZVCTRL 0x000A
+#define YMFSB_TIMERCTRL 0x0010
+#define YMFSB_TIMERCOUNT 0x0012
+#define YMFSB_SPDIFOUTCTRL 0x0018
+#define YMFSB_SPDIFOUTSTATUS 0x001C
+#define YMFSB_EEPROMCTRL 0x0020
+#define YMFSB_SPDIFINCTRL 0x0034
+#define YMFSB_SPDIFINSTATUS 0x0038
+#define YMFSB_DSPPROGRAMDL 0x0048
+#define YMFSB_DLCNTRL 0x004C
+#define YMFSB_GPIOININTFLAG 0x0050
+#define YMFSB_GPIOININTENABLE 0x0052
+#define YMFSB_GPIOINSTATUS 0x0054
+#define YMFSB_GPIOOUTCTRL 0x0056
+#define YMFSB_GPIOFUNCENABLE 0x0058
+#define YMFSB_GPIOTYPECONFIG 0x005A
+#define YMFSB_AC97CMDDATA 0x0060
+#define YMFSB_AC97CMDADR 0x0062
+#define YMFSB_PRISTATUSDATA 0x0064
+#define YMFSB_PRISTATUSADR 0x0066
+#define YMFSB_SECSTATUSDATA 0x0068
+#define YMFSB_SECSTATUSADR 0x006A
+#define YMFSB_SECCONFIG 0x0070
+#define YMFSB_LEGACYOUTVOL 0x0080
+#define YMFSB_LEGACYOUTVOLL 0x0080
+#define YMFSB_LEGACYOUTVOLR 0x0082
+#define YMFSB_NATIVEDACOUTVOL 0x0084
+#define YMFSB_NATIVEDACOUTVOLL 0x0084
+#define YMFSB_NATIVEDACOUTVOLR 0x0086
+#define YMFSB_SPDIFOUTVOL 0x0088
+#define YMFSB_SPDIFOUTVOLL 0x0088
+#define YMFSB_SPDIFOUTVOLR 0x008A
+#define YMFSB_AC3OUTVOL 0x008C
+#define YMFSB_AC3OUTVOLL 0x008C
+#define YMFSB_AC3OUTVOLR 0x008E
+#define YMFSB_PRIADCOUTVOL 0x0090
+#define YMFSB_PRIADCOUTVOLL 0x0090
+#define YMFSB_PRIADCOUTVOLR 0x0092
+#define YMFSB_LEGACYLOOPVOL 0x0094
+#define YMFSB_LEGACYLOOPVOLL 0x0094
+#define YMFSB_LEGACYLOOPVOLR 0x0096
+#define YMFSB_NATIVEDACLOOPVOL 0x0098
+#define YMFSB_NATIVEDACLOOPVOLL 0x0098
+#define YMFSB_NATIVEDACLOOPVOLR 0x009A
+#define YMFSB_SPDIFLOOPVOL 0x009C
+#define YMFSB_SPDIFLOOPVOLL 0x009E
+#define YMFSB_SPDIFLOOPVOLR 0x009E
+#define YMFSB_AC3LOOPVOL 0x00A0
+#define YMFSB_AC3LOOPVOLL 0x00A0
+#define YMFSB_AC3LOOPVOLR 0x00A2
+#define YMFSB_PRIADCLOOPVOL 0x00A4
+#define YMFSB_PRIADCLOOPVOLL 0x00A4
+#define YMFSB_PRIADCLOOPVOLR 0x00A6
+#define YMFSB_NATIVEADCINVOL 0x00A8
+#define YMFSB_NATIVEADCINVOLL 0x00A8
+#define YMFSB_NATIVEADCINVOLR 0x00AA
+#define YMFSB_NATIVEDACINVOL 0x00AC
+#define YMFSB_NATIVEDACINVOLL 0x00AC
+#define YMFSB_NATIVEDACINVOLR 0x00AE
+#define YMFSB_BUF441OUTVOL 0x00B0
+#define YMFSB_BUF441OUTVOLL 0x00B0
+#define YMFSB_BUF441OUTVOLR 0x00B2
+#define YMFSB_BUF441LOOPVOL 0x00B4
+#define YMFSB_BUF441LOOPVOLL 0x00B4
+#define YMFSB_BUF441LOOPVOLR 0x00B6
+#define YMFSB_SPDIFOUTVOL2 0x00B8
+#define YMFSB_SPDIFOUTVOL2L 0x00B8
+#define YMFSB_SPDIFOUTVOL2R 0x00BA
+#define YMFSB_SPDIFLOOPVOL2 0x00BC
+#define YMFSB_SPDIFLOOPVOL2L 0x00BC
+#define YMFSB_SPDIFLOOPVOL2R 0x00BE
+#define YMFSB_ADCSLOTSR 0x00C0
+#define YMFSB_RECSLOTSR 0x00C4
+#define YMFSB_ADCFORMAT 0x00C8
+#define YMFSB_RECFORMAT 0x00CC
+#define YMFSB_P44SLOTSR 0x00D0
+#define YMFSB_STATUS 0x0100
+#define YMFSB_CTRLSELECT 0x0104
+#define YMFSB_MODE 0x0108
+#define YMFSB_SAMPLECOUNT 0x010C
+#define YMFSB_NUMOFSAMPLES 0x0110
+#define YMFSB_CONFIG 0x0114
+#define YMFSB_PLAYCTRLSIZE 0x0140
+#define YMFSB_RECCTRLSIZE 0x0144
+#define YMFSB_EFFCTRLSIZE 0x0148
+#define YMFSB_WORKSIZE 0x014C
+#define YMFSB_MAPOFREC 0x0150
+#define YMFSB_MAPOFEFFECT 0x0154
+#define YMFSB_PLAYCTRLBASE 0x0158
+#define YMFSB_RECCTRLBASE 0x015C
+#define YMFSB_EFFCTRLBASE 0x0160
+#define YMFSB_WORKBASE 0x0164
+#define YMFSB_DSPINSTRAM 0x1000
+#define YMFSB_CTRLINSTRAM 0x4000
+
+
+/* ---------------------------------------------------------------------- */
+
+#define MAX_CARDS 4
+
+#define PFX "ymf_sb: "
+
+#define YMFSB_VERSION "0.0.4"
+#define YMFSB_CARD_NAME "YMF7xx Legacy Audio driver " YMFSB_VERSION
+
+#ifdef SUPPORT_UART401_MIDI
+#if 0
+# define ymf7xxsb_probe_midi probe_uart401
+# define ymf7xxsb_attach_midi attach_uart401
+# define ymf7xxsb_unload_midi unload_uart401
+#else
+# define ymf7xxsb_probe_midi probe_sbmpu
+# define ymf7xxsb_attach_midi attach_sbmpu
+# define ymf7xxsb_unload_midi unload_sbmpu
+#endif
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static struct address_info sb_data[MAX_CARDS];
+static struct address_info opl3_data[MAX_CARDS];
+#ifdef SUPPORT_UART401_MIDI
+static struct address_info mpu_data[MAX_CARDS];
+#endif
+static unsigned cards = 0;
+static unsigned short *ymfbase[MAX_CARDS];
+
+/* ---------------------------------------------------------------------- */
+
+#ifdef MODULE
+#ifdef SUPPORT_UART401_MIDI
+static int mpu_io = 0;
+#endif
+static int synth_io = 0;
+static int io = 0;
+static int dma = 0;
+static int master_vol = -1;
+static int spdif_out = 0;
+#ifdef SUPPORT_UART401_MIDI
+MODULE_PARM(mpu_io, "i");
+#endif
+MODULE_PARM(synth_io, "i");
+MODULE_PARM(io,"i");
+MODULE_PARM(dma,"i");
+MODULE_PARM(master_vol,"i");
+MODULE_PARM(spdif_out,"i");
+#else
+#ifdef SUPPORT_UART401_MIDI
+static int mpu_io = 0x330;
+#endif
+static int synth_io = 0x388;
+static int io = 0x220;
+static int dma = 1;
+static int master_vol = 80;
+static int spdif_out = 0;
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+static int readRegWord( int adr ) {
+
+ if (ymfbase[cards]==NULL) return 0;
+
+ return readw(ymfbase[cards]+adr/2);
+}
+
+static void writeRegWord( int adr, int val ) {
+
+ if (ymfbase[cards]==NULL) return;
+
+ writew((unsigned short)(val&0xffff), ymfbase[cards] + adr/2);
+
+ return;
+}
+
+static int readRegDWord( int adr ) {
+
+ if (ymfbase[cards]==NULL) return 0;
+
+ return (readl(ymfbase[cards]+adr/2));
+}
+
+static void writeRegDWord( int adr, int val ) {
+
+ if (ymfbase[cards]==NULL) return;
+
+ writel((unsigned int)(val&0xffffffff), ymfbase[cards]+adr/2);
+
+ return;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int checkPrimaryBusy( void )
+{
+ int timeout=0;
+
+ while ( timeout++ < YMFSB_AC97TIMEOUT )
+ {
+ if ( (readRegWord(YMFSB_PRISTATUSADR) & 0x8000) == 0x0000 )
+ return 0;
+ }
+ return -1;
+}
+
+static int writeAc97( int adr, unsigned short val )
+{
+
+ if ( adr > 0x7f || adr < 0x00 ) return -1;
+
+ if ( checkPrimaryBusy() ) return -1;
+
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "AC97 0x%0x = 0x%0x\n",adr,val);
+#endif
+
+ writeRegWord( YMFSB_AC97CMDADR, 0x0000 | adr );
+ writeRegWord( YMFSB_AC97CMDDATA, val );
+
+ return 0;
+}
+
+static int checkCodec( struct pci_dev *pcidev )
+{
+ u8 tmp8;
+
+ pci_read_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, &tmp8);
+ if ( tmp8 & 0x03 ) {
+ pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc);
+ mdelay(YMFSB_RESET_DELAY);
+ pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8|0x03);
+ mdelay(YMFSB_RESET_DELAY);
+ pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc);
+ mdelay(YMFSB_RESET_DELAY);
+ }
+
+ if ( checkPrimaryBusy() ) return -1;
+
+ return 0;
+}
+
+static int setupLegacyIO( struct pci_dev *pcidev )
+{
+ int v;
+ int sbio=0,mpuio=0,oplio=0,dma=0;
+
+ switch(sb_data[cards].io_base) {
+ case 0x220:
+ sbio = 0;
+ break;
+ case 0x240:
+ sbio = 1;
+ break;
+ case 0x260:
+ sbio = 2;
+ break;
+ case 0x280:
+ sbio = 3;
+ break;
+ default:
+ return -1;
+ break;
+ }
+#ifdef YMF_DEBUG
+ printk(PFX "set SBPro I/O at 0x%x\n",sb_data[cards].io_base);
+#endif
+
+#ifdef SUPPORT_UART401_MIDI
+ switch(mpu_data[cards].io_base) {
+ case 0x330:
+ mpuio = 0;
+ break;
+ case 0x300:
+ mpuio = 1;
+ break;
+ case 0x332:
+ mpuio = 2;
+ break;
+ case 0x334:
+ mpuio = 3;
+ break;
+ default:
+ mpuio = 0;
+ break;
+ }
+# ifdef YMF_DEBUG
+ printk(PFX "set MPU401 I/O at 0x%x\n",mpu_data[cards].io_base);
+# endif
+#endif
+
+ switch(opl3_data[cards].io_base) {
+ case 0x388:
+ oplio = 0;
+ break;
+ case 0x398:
+ oplio = 1;
+ break;
+ case 0x3a0:
+ oplio = 2;
+ break;
+ case 0x3a8:
+ oplio = 3;
+ break;
+ default:
+ return -1;
+ break;
+ }
+#ifdef YMF_DEBUG
+ printk(PFX "set OPL3 I/O at 0x%x\n",opl3_data[cards].io_base);
+#endif
+
+ dma = sb_data[cards].dma;
+#ifdef YMF_DEBUG
+ printk(PFX "set DMA address at 0x%x\n",sb_data[cards].dma);
+#endif
+
+ v = 0x0000 | ((dma<<6)&0x03) | 0x003f;
+ pci_write_config_word(pcidev, YMFSB_PCIR_LEGCTRL, v);
+#ifdef YMF_DEBUG
+ printk(PFX "LEGCTRL: 0x%x\n",v);
+#endif
+ switch( pcidev->device ) {
+ case PCI_DEVICE_ID_YMF724:
+ case PCI_DEVICE_ID_YMF740:
+ case PCI_DEVICE_ID_YMF724F:
+ case PCI_DEVICE_ID_YMF740C:
+ v = 0x8800 | ((mpuio<<4)&0x03) | ((sbio<<2)&0x03) | (oplio&0x03);
+ pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v);
+#ifdef YMF_DEBUG
+ printk(PFX "ELEGCTRL: 0x%x\n",v);
+#endif
+ break;
+
+ case PCI_DEVICE_ID_YMF744:
+ case PCI_DEVICE_ID_YMF754:
+ v = 0x8800;
+ pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v);
+#ifdef YMF_DEBUG
+ printk(PFX "ELEGCTRL: 0x%x\n",v);
+#endif
+ pci_write_config_word(pcidev, YMFSB_PCIR_OPLADR, opl3_data[cards].io_base);
+ pci_write_config_word(pcidev, YMFSB_PCIR_SBADR, sb_data[cards].
+io_base);
+#ifdef SUPPORT_UART401_MIDI
+ pci_write_config_word(pcidev, YMFSB_PCIR_MPUADR, mpu_data[cards].io_base);
+#endif
+ break;
+
+ default:
+ printk(KERN_ERR PFX "Invalid device ID: %d\n",pcidev->device);
+ return -1;
+ break;
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void enableDSP( void )
+{
+ writeRegDWord( YMFSB_CONFIG, 0x00000001 );
+ return;
+}
+
+static void disableDSP( void )
+{
+ int val;
+ int i;
+
+ val = readRegDWord( YMFSB_CONFIG );
+ if ( val ) {
+ writeRegDWord( YMFSB_CONFIG, 0 );
+ }
+
+ i=0;
+ while( ++i < YMFSB_WORKBITTIMEOUT ) {
+ val = readRegDWord(YMFSB_STATUS);
+ if ( (val & 0x00000002) == 0x00000000 ) break;
+ }
+
+ return;
+}
+
+static int setupInstruction( struct pci_dev *pcidev )
+{
+ int i;
+ int val;
+
+ writeRegDWord( YMFSB_NATIVEDACOUTVOL, 0 ); /* mute dac */
+ disableDSP();
+
+ writeRegDWord( YMFSB_MODE, 0x00010000 );
+
+ /* DS-XG Software Reset */
+ writeRegDWord( YMFSB_MODE, 0x00000000 );
+ writeRegDWord( YMFSB_MAPOFREC, 0x00000000 );
+ writeRegDWord( YMFSB_MAPOFEFFECT, 0x00000000 );
+ writeRegDWord( YMFSB_PLAYCTRLBASE, 0x00000000 );
+ writeRegDWord( YMFSB_RECCTRLBASE, 0x00000000 );
+ writeRegDWord( YMFSB_EFFCTRLBASE, 0x00000000 );
+
+ val = readRegWord( YMFSB_GLOBALCTRL );
+ writeRegWord( YMFSB_GLOBALCTRL, (val&~0x0007) );
+
+ /* setup DSP instruction code */
+ for ( i=0 ; i<YMFSB_DSPLENGTH ; i+=4 ) {
+ writeRegDWord( YMFSB_DSPINSTRAM+i, DspInst[i>>2] );
+ }
+
+ switch( pcidev->device ) {
+ case PCI_DEVICE_ID_YMF724:
+ case PCI_DEVICE_ID_YMF740:
+ /* setup Control instruction code */
+ for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {
+ writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst[i>>2] );
+ }
+ break;
+
+ case PCI_DEVICE_ID_YMF724F:
+ case PCI_DEVICE_ID_YMF740C:
+ case PCI_DEVICE_ID_YMF744:
+ case PCI_DEVICE_ID_YMF754:
+ /* setup Control instruction code */
+ for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {
+ writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst1E[i>>2] );
+ }
+ break;
+
+ default:
+ return -1;
+ }
+
+ enableDSP();
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int __init ymf7xx_init(struct pci_dev *pcidev)
+{
+ unsigned short v;
+
+ /* Read hardware information */
+#ifdef YMF_DEBUG
+ unsigned int dv;
+ pci_read_config_word(pcidev, YMFSB_PCIR_VENDORID, &v);
+ printk(KERN_INFO PFX "Vendor ID = 0x%x\n",v);
+ pci_read_config_word(pcidev, YMFSB_PCIR_DEVICEID, &v);
+ printk(KERN_INFO PFX "Device ID = 0x%x\n",v);
+ pci_read_config_word(pcidev, YMFSB_PCIR_REVISIONID, &v);
+ printk(KERN_INFO PFX "Revision ID = 0x%x\n",v&0xff);
+ pci_read_config_dword(pcidev, YMFSB_PCIR_BASEADDR, &dv);
+ printk(KERN_INFO PFX "Base address = 0x%x\n",dv);
+ pci_read_config_word(pcidev, YMFSB_PCIR_IRQ, &v);
+ printk(KERN_INFO PFX "IRQ line = 0x%x\n",v&0xff);
+#endif
+
+ /* enables memory space access / bus mastering */
+ pci_read_config_word(pcidev, YMFSB_PCIR_CMD, &v);
+ pci_write_config_word(pcidev, YMFSB_PCIR_CMD, v|0x06);
+
+ /* check codec */
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "check codec...\n");
+#endif
+ if (checkCodec(pcidev)) return -1;
+
+ /* setup legacy I/O */
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "setup legacy I/O...\n");
+#endif
+ if (setupLegacyIO(pcidev)) return -1;
+
+ /* setup instruction code */
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "setup instructions...\n");
+#endif
+ if (setupInstruction(pcidev)) return -1;
+
+ /* AC'97 setup */
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "setup AC'97...\n");
+#endif
+ if ( writeAc97(AC97_RESET ,0x0000) ) /* Reset */
+ return -1;
+ if ( writeAc97(AC97_MASTER_VOL_STEREO,0x0000) ) /* Master Volume */
+ return -1;
+
+ v = 31*(100-master_vol)/100;
+ v = (v<<8 | v)&0x7fff;
+ if ( writeAc97(AC97_PCMOUT_VOL ,v ) ) /* PCM out Volume */
+ return -1;
+
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "setup Legacy Volume...\n");
+#endif
+ /* Legacy Audio Output Volume L & R ch */
+ writeRegDWord( YMFSB_LEGACYOUTVOL, 0x3fff3fff );
+
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "setup SPDIF output control...\n");
+#endif
+ /* SPDIF Output control */
+ v = spdif_out != 0 ? 0x0001 : 0x0000;
+ writeRegWord( YMFSB_SPDIFOUTCTRL, v );
+ /* no copyright protection,
+ sample-rate converted,
+ re-recorded software comercially available (the 1st generation),
+ original */
+ writeRegWord( YMFSB_SPDIFOUTSTATUS, 0x9a04 );
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void __init ymf7xxsb_attach_sb(struct address_info *hw_config)
+{
+ if(!sb_dsp_init(hw_config))
+ hw_config->slots[0] = -1;
+}
+
+static int __init ymf7xxsb_probe_sb(struct address_info *hw_config)
+{
+ if (check_region(hw_config->io_base, 16))
+ {
+ printk(KERN_DEBUG PFX "SBPro port 0x%x is already in use\n",
+ hw_config->io_base);
+ return 0;
+ }
+ return sb_dsp_detect(hw_config, SB_PCI_YAMAHA, 0, NULL);
+}
+
+
+static void ymf7xxsb_unload_sb(struct address_info *hw_config, int unload_mpu)
+{
+ if(hw_config->slots[0]!=-1)
+ sb_dsp_unload(hw_config, unload_mpu);
+}
+
+/* ---------------------------------------------------------------------- */
+
+enum chip_types {
+ CH_YMF724 = 0,
+ CH_YMF724F,
+ CH_YMF740,
+ CH_YMF740C,
+ CH_YMF744,
+ CH_YMF754,
+};
+
+/* directly indexed by chip_types enum above */
+/* note we keep this a struct to ease adding
+ * other per-board or per-chip info here */
+struct {
+ const char *devicename;
+} devicetable[] __initdata =
+{
+ { "YMF724A-E" },
+ { "YMF724F" },
+ { "YMF740A-B" },
+ { "YMF740C" },
+ { "YMF744" },
+ { "YMF754" },
+};
+
+static struct pci_device_id ymf7xxsb_pci_tbl[] __initdata = {
+ { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724 },
+ { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724F },
+ { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740 },
+ { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740C },
+ { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF744 },
+ { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF754 },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, ymf7xxsb_pci_tbl);
+
+static int __init ymf7xxsb_init_one (struct pci_dev *pcidev, const struct pci_device_id *ent)
+{
+
+ const char *devicename;
+ unsigned long iobase;
+
+ if (cards == MAX_CARDS) {
+ printk (KERN_DEBUG PFX "maximum number of cards reached\n");
+ return -ENODEV;
+ }
+
+ if ( pcidev->irq == 0 ) return -ENODEV;
+ iobase = pci_resource_start (pcidev, 0);
+ if ( iobase == 0x00000000 ) return -ENODEV;
+
+ devicename = devicetable[ent->driver_data].devicename;
+
+ /* remap memory mapped I/O onto kernel virtual memory */
+ if ( (ymfbase[cards] = ioremap_nocache(iobase, YMFSB_REGSIZE)) == 0 )
+ {
+ printk(KERN_ERR PFX "ioremap (0x%lx) returns zero\n", iobase);
+ return -ENODEV;
+ }
+ printk(KERN_INFO PFX "found %s at 0x%lx\n", devicename, iobase);
+#ifdef YMF_DEBUG
+ printk(KERN_INFO PFX "remappling to 0x%p\n", ymfbase[cards]);
+#endif
+
+ memset (&sb_data[cards], 0, sizeof (struct address_info));
+ memset (&opl3_data[cards], 0, sizeof (struct address_info));
+#ifdef SUPPORT_UART401_MIDI
+ memset (&mpu_data[cards], 0, sizeof (struct address_info));
+#endif
+
+ sb_data[cards].name = YMFSB_CARD_NAME;
+ opl3_data[cards].name = YMFSB_CARD_NAME;
+#ifdef SUPPORT_UART401_MIDI
+ mpu_data[cards].name = YMFSB_CARD_NAME;
+#endif
+
+ sb_data[cards].card_subtype = MDL_YMPCI;
+
+ if ( io == 0 ) io = 0x220;
+ sb_data[cards].io_base = io;
+ sb_data[cards].irq = pcidev->irq;
+ sb_data[cards].dma = dma;
+
+ if ( synth_io == 0 ) synth_io = 0x388;
+ opl3_data[cards].io_base = synth_io;
+ opl3_data[cards].irq = -1;
+
+#ifdef SUPPORT_UART401_MIDI
+ if ( mpu_io == 0 ) mpu_io = 0x330;
+ mpu_data[cards].io_base = mpu_io;
+ mpu_data[cards].irq = -1;
+#endif
+
+ if ( ymf7xx_init(pcidev) ) {
+ printk (KERN_ERR PFX
+ "Cannot initialize %s, aborting\n",
+ devicename);
+ return -ENODEV;
+ }
+
+ /* register legacy SoundBlaster Pro */
+ if (!ymf7xxsb_probe_sb(&sb_data[cards])) {
+ printk (KERN_ERR PFX
+ "SB probe at 0x%X failed, aborting\n",
+ io);
+ return -ENODEV;
+ }
+ ymf7xxsb_attach_sb (&sb_data[cards]);
+
+#ifdef SUPPORT_UART401_MIDI
+ /* register legacy MIDI */
+ if ( mpu_io > 0 && 0)
+ {
+ if (!ymf7xxsb_probe_midi (&mpu_data[cards])) {
+ printk (KERN_ERR PFX
+ "MIDI probe @ 0x%X failed, aborting\n",
+ mpu_io);
+ ymf7xxsb_unload_sb (&sb_data[cards], 0);
+ return -ENODEV;
+ }
+ ymf7xxsb_attach_midi (&mpu_data[cards]);
+ }
+#endif
+
+ /* register legacy OPL3 */
+
+ cards++;
+ return 0;
+}
+
+static struct pci_driver ymf7xxsb_driver = {
+ name: "ymf7xxsb",
+ id_table: ymf7xxsb_pci_tbl,
+ probe: ymf7xxsb_init_one,
+};
+
+static int __init init_ymf7xxsb_module(void)
+{
+ int i;
+
+ /*
+ * Binds us to the sound subsystem
+ */
+ SOUND_LOCK;
+
+ if ( master_vol < 0 ) master_vol = 50;
+ if ( master_vol > 100 ) master_vol = 100;
+
+ for (i=0 ; i<MAX_CARDS ; i++ )
+ ymfbase[i] = NULL;
+
+ i = pci_module_init (&ymf7xxsb_driver);
+ if (i < 0) {
+ SOUND_LOCK_END;
+ return i;
+ }
+
+ printk (KERN_INFO PFX YMFSB_CARD_NAME " loaded\n");
+
+ return 0;
+}
+
+static void __exit free_iomaps( void )
+{
+ int i;
+
+ for ( i=0 ; i<MAX_CARDS ; i++ ) {
+ if ( ymfbase[i]!=NULL )
+ iounmap(ymfbase[i]);
+ }
+
+ return;
+}
+
+static void __exit cleanup_ymf7xxsb_module(void)
+{
+ int i;
+
+ for (i = 0; i < cards; i++) {
+#ifdef SUPPORT_UART401_MIDI
+ ymf7xxsb_unload_sb (&sb_data[i], 0);
+ ymf7xxsb_unload_midi (&mpu_data[i]);
+#else
+ ymf7xxsb_unload_sb (&sb_data[i], 1);
+#endif
+ }
+
+ free_iomaps();
+
+ /*
+ * Final clean up with the sound layer
+ */
+ SOUND_LOCK_END;
+}
+
+MODULE_AUTHOR("Daisuke Nagano, breeze.nagano@nifty.ne.jp");
+MODULE_DESCRIPTION("YMF7xx Legacy Audio Driver");
+
+module_init(init_ymf7xxsb_module);
+module_exit(cleanup_ymf7xxsb_module);
+
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c
index fc4f61b34eb820..3fde30bfad8af3 100644
--- a/drivers/telephony/phonedev.c
+++ b/drivers/telephony/phonedev.c
@@ -49,6 +49,7 @@ static int phone_open(struct inode *inode, struct file *file)
unsigned int minor = MINOR(inode->i_rdev);
int err = 0;
struct phone_device *p;
+ struct file_operations *old_fops;
if (minor >= PHONE_NUM_DEVICES)
return -ENODEV;
@@ -69,12 +70,15 @@ static int phone_open(struct inode *inode, struct file *file)
goto end;
}
}
- if (p->open) {
+ old_fops = file->f_op;
+ file->f_op = fops_get(p->f_op);
+ if (p->open)
err = p->open(p, file); /* Tell the device it is open */
- if (err)
- goto end;
+ if (err) {
+ fops_put(file->f_op);
+ file->f_op = fops_get(old_fops);
}
- file->f_op = p->f_op;
+ fops_put(old_fops);
end:
up(&phone_lock);
return err;
@@ -129,6 +133,7 @@ void phone_unregister_device(struct phone_device *pfd)
static struct file_operations phone_fops =
{
+ owner: THIS_MODULE,
open: phone_open,
};
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index b1d164d3578c2a..10ac2eec303c1a 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -30,7 +30,6 @@ u_int zorro_num_autocon = 0;
struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO];
-#if 0
/*
* Zorro Bus Resources
* Order _does_ matter! (see code below)
@@ -42,8 +41,9 @@ static struct resource zorro_res[4] = {
{ "Zorro III exp", 0xff000000, 0xffffffff },
{ "Zorro III cfg", 0x40000000, 0x7fffffff }
};
-#endif
-
+
+static u_int __init zorro_num_res = 0;
+
/*
* Find Zorro Devices
@@ -107,6 +107,18 @@ static void __init mark_region(unsigned long start, unsigned long end,
}
+static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z)
+{
+ int i;
+
+ for (i = 0; i < zorro_num_res; i++)
+ if (z->resource.start >= zorro_res[i].start &&
+ z->resource.end <= zorro_res[i].end)
+ return &zorro_res[i];
+ return &iomem_resource;
+}
+
+
/*
* Initialization
*/
@@ -123,10 +135,9 @@ void __init zorro_init(void)
zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s");
/* Request the resources */
-#if 0
- for (i = 0; i < (AMIGAHW_PRESENT(ZORRO3) ? 4 : 2); i++)
+ zorro_num_res = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
+ for (i = 0; i < zorro_num_res; i++)
request_resource(&iomem_resource, &zorro_res[i]);
-#endif
for (i = 0; i < zorro_num_autocon; i++) {
dev = &zorro_autocon[i];
dev->id = (dev->rom.er_Manufacturer<<16) | (dev->rom.er_Product<<8);
@@ -137,7 +148,7 @@ void __init zorro_init(void)
}
dev->resource.name = dev->name;
zorro_namedevice(dev);
- if (request_resource(&iomem_resource, &dev->resource))
+ if (request_resource(zorro_find_parent_resource(dev), &dev->resource))
printk("zorro_init: cannot request resource for board %d\n", i);
}
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 040e0b79af3baa..9f1e8b06fd1c46 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -737,7 +737,8 @@ static struct file_operations devfsd_fops =
* @namelen: The number of characters in @name.
* @traverse_symlink: If %TRUE then the entry is traversed if it is a symlink.
*
- * Returns a pointer to the entry on success, else %NULL.
+ * Search for a devfs entry inside another devfs entry and returns a pointer
+ * to the entry on success, else %NULL.
*/
static struct devfs_entry *search_for_entry_in_dir (struct devfs_entry *parent,
@@ -902,6 +903,7 @@ static struct devfs_entry *search_for_entry (struct devfs_entry *dir,
/**
* find_by_dev - Find a devfs entry in a directory.
+ * @dir: The directory where to search
* @major: The major number to search for.
* @minor: The minor number to search for.
* @type: The type of special file to search for. This may be either
@@ -1746,8 +1748,8 @@ void *devfs_get_ops (devfs_handle_t de)
/**
* devfs_set_file_size - Set the file size for a devfs regular file.
- * de: The handle to the device entry.
- * size: The new file size.
+ * @de: The handle to the device entry.
+ * @size: The new file size.
*
* Returns 0 on success, else a negative error code.
*/
@@ -1788,6 +1790,7 @@ void *devfs_get_info (devfs_handle_t de)
/**
* devfs_set_info - Set the info pointer written to private_data upon open.
* @de: The handle to the device entry.
+ * @info: pointer to the data
*
* Returns 0 on success, else a negative error code.
*/
@@ -1940,8 +1943,8 @@ int devfs_register_blkdev (unsigned int major, const char *name,
/**
* devfs_unregister_chrdev - Optionally unregister a conventional character driver.
- * major: The major number for the driver.
- * name: The name of the driver (as seen in /proc/devices).
+ * @major: The major number for the driver.
+ * @name: The name of the driver (as seen in /proc/devices).
*
* This function will unregister a character driver provided the "devfs=only"
* option was not provided at boot time.
@@ -1976,7 +1979,6 @@ int devfs_unregister_blkdev (unsigned int major, const char *name)
/**
* devfs_setup - Process kernel boot options.
* @str: The boot options after the "devfs=".
- * @unused: Unused.
*/
SETUP_STATIC int __init devfs_setup (char *str)
@@ -2404,7 +2406,7 @@ static void devfs_read_inode (struct inode *inode)
#endif
} /* End Function devfs_read_inode */
-static void devfs_write_inode (struct inode *inode)
+static void devfs_write_inode (struct inode *inode, int unused)
{
int index;
struct devfs_inode *di;
@@ -2638,7 +2640,7 @@ static int devfs_open (struct inode *inode, struct file *file)
file->f_op = &def_blk_fops;
if (df->ops) inode->i_bdev->bd_op = df->ops;
}
- else file->f_op = df->ops;
+ else file->f_op = fops_get((struct file_operations*)df->ops);
if (file->f_op)
err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0;
else
diff --git a/fs/devices.c b/fs/devices.c
index 2c53934b90010c..d119b1c75f620e 100644
--- a/fs/devices.c
+++ b/fs/devices.c
@@ -17,6 +17,7 @@
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/errno.h>
+#include <linux/module.h>
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
@@ -142,8 +143,9 @@ int chrdev_open(struct inode * inode, struct file * filp)
{
int ret = -ENODEV;
- filp->f_op = get_chrfops(MAJOR(inode->i_rdev), MINOR(inode->i_rdev));
- if (filp->f_op != NULL){
+ filp->f_op = fops_get(get_chrfops(MAJOR(inode->i_rdev),
+ MINOR(inode->i_rdev)));
+ if (filp->f_op) {
ret = 0;
if (filp->f_op->open != NULL)
ret = filp->f_op->open(inode,filp);
diff --git a/fs/file_table.c b/fs/file_table.c
index 7d5bd9e01d1d58..ecaa4689677f23 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -9,6 +9,7 @@
#include <linux/slab.h>
#include <linux/file.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <linux/smp_lock.h>
/* SLAB cache for filp's. */
@@ -127,6 +128,7 @@ static void __fput(struct file *filp)
if (filp->f_op && filp->f_op->release)
filp->f_op->release(inode, filp);
+ fops_put(filp->f_op);
filp->f_dentry = NULL;
filp->f_vfsmnt = NULL;
if (filp->f_mode & FMODE_WRITE)
diff --git a/fs/open.c b/fs/open.c
index e23e48194e7dcd..9135f0e30138dd 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -10,6 +10,7 @@
#include <linux/file.h>
#include <linux/smp_lock.h>
#include <linux/quotaops.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
@@ -653,7 +654,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
f->f_vfsmnt = mnt;
f->f_pos = 0;
f->f_reada = 0;
- f->f_op = inode->i_fop;
+ f->f_op = fops_get(inode->i_fop);
if (inode->i_sb)
file_move(f, &inode->i_sb->s_files);
if (f->f_op && f->f_op->open) {
@@ -666,6 +667,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
return f;
cleanup_all:
+ fops_put(f->f_op);
if (f->f_mode & FMODE_WRITE)
put_write_access(inode);
f->f_dentry = NULL;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ecb8a29919d545..fb63722d523a1f 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -160,6 +160,24 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
if (len > PAGE_SIZE)
len = PAGE_SIZE;
res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+ // If the nul at the end of args has been overwritten, then
+ // assume application is using setproctitle(3).
+ if ( res > 0 && buffer[res-1] != '\0' )
+ {
+ len = strnlen( buffer, res );
+ if ( len < res )
+ {
+ res = len;
+ }
+ else
+ {
+ len = mm->env_end - mm->env_start;
+ if (len > PAGE_SIZE - res)
+ len = PAGE_SIZE - res;
+ res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
+ res = strnlen( buffer, res );
+ }
+ }
mmput(mm);
}
return res;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 1585657a2d7b06..dc6f96b17f46cf 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -14,6 +14,8 @@
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#define __NO_VERSION__
+#include <linux/module.h>
#include <asm/bitops.h>
static ssize_t proc_file_read(struct file * file, char * buf,
@@ -397,13 +399,14 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
continue;
if (inode->u.generic_ip != de)
continue;
+ fops_put(filp->f_op);
filp->f_op = NULL;
}
file_list_unlock();
}
struct proc_dir_entry *proc_symlink(const char *name,
- struct proc_dir_entry *parent, char *dest)
+ struct proc_dir_entry *parent, const char *dest)
{
struct proc_dir_entry *ent = NULL;
const char *fn = name;
@@ -535,7 +538,7 @@ void free_proc_entry(struct proc_dir_entry *de)
{
int ino = de->low_ino;
- if (ino < PROC_DYNAMIC_FIRST &&
+ if (ino < PROC_DYNAMIC_FIRST ||
ino >= PROC_DYNAMIC_FIRST+PROC_NDYNAMIC)
return;
if (S_ISLNK(de->mode) && de->data)
diff --git a/fs/read_write.c b/fs/read_write.c
index 4569ee18aca6f8..3d3519146bc73e 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -199,9 +199,19 @@ static ssize_t do_readv_writev(int type, struct file *file,
if (copy_from_user(iov, vector, count*sizeof(*vector)))
goto out;
+ /* BSD readv/writev returns EINVAL if one of the iov_len
+ values < 0 or tot_len overflowed a 32-bit integer. -ink */
tot_len = 0;
- for (i = 0 ; i < count ; i++)
- tot_len += iov[i].iov_len;
+ ret = -EINVAL;
+ for (i = 0 ; i < count ; i++) {
+ size_t tmp = tot_len;
+ int len = iov[i].iov_len;
+ if (len < 0)
+ goto out;
+ (u32)tot_len += len;
+ if (tot_len < tmp || tot_len < (u32)len)
+ goto out;
+ }
inode = file->f_dentry->d_inode;
/* VERIFY_WRITE actually means a read, as we write to user space */
diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h
index 81f463cd584a7f..f4468611ef1d5a 100644
--- a/include/linux/ac97_codec.h
+++ b/include/linux/ac97_codec.h
@@ -32,7 +32,7 @@
#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */
#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */
#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */
+#define AC97_PCM_LR_DAC_RATE 0x0032 /* PCM LR DAC Rate */
#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */
#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */
#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */
@@ -133,7 +133,7 @@
SOUND_MASK_LINE1| SOUND_MASK_LINE|\
SOUND_MASK_PHONEIN)
-#define supported_mixer(CODEC,FOO) ( CODEC->supported_mixers & (1<<FOO) )
+#define supported_mixer(CODEC,FOO) ((CODEC)->supported_mixers & (1<<FOO) )
struct ac97_codec {
/* AC97 controller connected with */
@@ -150,6 +150,9 @@ struct ac97_codec {
u16 (*codec_read) (struct ac97_codec *codec, u8 reg);
void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
+ /* Wait for codec-ready. Ok to sleep here. */
+ void (*codec_wait) (struct ac97_codec *codec);
+
/* OSS mixer masks */
int modcnt;
int supported_mixers;
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 8804c9777f9185..13876daf5ca300 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -58,6 +58,10 @@ void cmd640_dump_regs (void);
#endif
#endif /* CONFIG_BLK_DEV_CMD640 */
+#ifndef DISABLE_IRQ_NOSYNC
+#define DISABLE_IRQ_NOSYNC 0
+#endif
+
/*
* IDE_DRIVE_CMD is used to implement many features of the hdparm utility
*/
@@ -181,6 +185,32 @@ typedef unsigned char byte; /* used everywhere */
OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \
}
+#define SELECT_INTERRUPT(hwif,drive) \
+{ \
+ if (hwif->intrproc) \
+ hwif->intrproc(drive); \
+ else \
+ OUT_BYTE((drive)->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]); \
+}
+
+#define SELECT_MASK(hwif,drive,mask) \
+{ \
+ if (hwif->maskproc) \
+ hwif->maskproc(drive,mask); \
+}
+
+#define SELECT_READ_WRITE(hwif,drive,func) \
+{ \
+ if (hwif->rwproc) \
+ hwif->rwproc(drive,func); \
+}
+
+#define QUIRK_LIST(hwif,drive) \
+{ \
+ if (hwif->quirkproc) \
+ (drive)->quirk_list = hwif->quirkproc(drive); \
+}
+
/*
* Check for an interrupt and acknowledge the interrupt status
*/
@@ -309,6 +339,8 @@ typedef struct ide_drive_s {
int last_lun; /* last logical unit */
int forced_lun; /* if hdxlun was given at boot */
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 init_speed; /* transfer rate set at boot */
byte current_speed; /* current transfer rate set */
byte dn; /* now wide spread use */
@@ -354,6 +386,10 @@ typedef int (ide_speedproc_t) (ide_drive_t *, byte);
*/
typedef void (ide_selectproc_t) (ide_drive_t *);
typedef void (ide_resetproc_t) (ide_drive_t *);
+typedef int (ide_quirkproc_t) (ide_drive_t *);
+typedef void (ide_intrproc_t) (ide_drive_t *);
+typedef void (ide_maskproc_t) (ide_drive_t *, int);
+typedef void (ide_rw_proc_t) (ide_drive_t *, ide_dma_action_t);
/*
* hwif_chipset_t is used to keep track of the specific hardware
@@ -388,6 +424,10 @@ typedef struct hwif_s {
ide_speedproc_t *speedproc; /* routine to retune DMA modes for drives */
ide_selectproc_t *selectproc; /* tweaks hardware to select drive */
ide_resetproc_t *resetproc; /* routine to reset controller after a disk reset */
+ ide_intrproc_t *intrproc; /* special interrupt handling for shared pci interrupts */
+ ide_maskproc_t *maskproc; /* special host masking for drive selection */
+ ide_quirkproc_t *quirkproc; /* check host's drive quirk list */
+ ide_rw_proc_t *rwproc; /* adjust timing based upon rq->cmd direction */
ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */
unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */
dma_addr_t dmatable_dma; /* dma physical region descriptor table (dma view) */
@@ -424,6 +464,7 @@ typedef struct hwif_s {
void *hwif_data; /* extra hwif data */
} ide_hwif_t;
+
/*
* Status returned from various ide_ functions
*/
@@ -614,12 +655,14 @@ void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup);
/*
* This is used for (nearly) all data transfers from/to the IDE interface
+ * FIXME for 2.5, to a pointer pass verses memcpy........
*/
void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
/*
* This is used for (nearly) all ATAPI data transfers from/to the IDE interface
+ * FIXME for 2.5, to a pointer pass verses memcpy........
*/
void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
@@ -750,6 +793,7 @@ byte ide_auto_reduce_xfer (ide_drive_t *drive);
int ide_driveid_update (ide_drive_t *drive);
int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature);
int ide_config_drive_speed (ide_drive_t *drive, byte speed);
+byte eighty_ninty_three (ide_drive_t *drive);
int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature);
/*
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index a8d79a50e508f8..ac6f029b99b529 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -55,6 +55,7 @@ extern int sprintf(char * buf, const char * fmt, ...);
extern int vsprintf(char *buf, const char *, va_list);
extern int get_option(char **str, int *pint);
extern char *get_options(char *str, int nints, int *ints);
+extern unsigned long memparse(char *ptr, char **retptr);
extern int session_of_pgrp(int pgrp);
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index d0487c3df455d8..28bf3daa02aaa2 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -127,7 +127,7 @@ extern void proc_tty_unregister_driver(struct tty_driver *driver);
extern void proc_device_tree_init(void);
extern struct proc_dir_entry *proc_symlink(const char *,
- struct proc_dir_entry *,char *);
+ struct proc_dir_entry *, const char *);
extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
struct proc_dir_entry *,kdev_t);
extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
index 283e816950bd9f..680069a4472df7 100644
--- a/include/scsi/sg.h
+++ b/include/scsi/sg.h
@@ -11,9 +11,18 @@ Original driver (sg.h):
Version 2 and 3 extensions to driver:
* Copyright (C) 1998 - 2000 Douglas Gilbert
- Version: 3.1.13 (20000323)
+ Version: 3.1.15 (20000528)
This version is for 2.3/2.4 series kernels.
+ Changes since 3.1.14 (20000503)
+ - fix aha1542 odd length buffer problem
+ - make multiple readers on same fd safe
+ Changes since 3.1.13 (20000324)
+ - revert change so sg_header interface doesn't send _UNKNOWN
+ - "discon" and "tq" in /proc/scsi/sg/devices replaced with
+ "bopens" and "busy"; correct duration output in procfs
+ - provision for SG_RESET
+ - lock file descriptor and request lists
Changes since 3.1.12 (20000222)
- make sg_header interface use SCSI_DATA_UNKNOWN
- add SG_DXFER_UNKNOWN define to sg interface
@@ -49,10 +58,9 @@ Map of SG verions to the Linux kernels in which they appear:
2.1.31 2.2.6 and 2.2.7
2.1.32 2.2.8 and 2.2.9
2.1.34 2.2.10 to 2.2.13
- 2.1.36 2.2.14
- 2.3.35 2.3.x development series kernels (starting 2.3.20)
+ 2.1.36 2.2.14 and 2.2.15
3.0.x optional version 3 sg driver for 2.2 series
- 3.1.x candidate version 3 sg driver for 2.3 series
+ 3.1.x first appeared in lk 2.3.43
Major new features in SG 3.x driver (cf SG 2.x drivers)
- SG_IO ioctl() combines function if write() and read()
@@ -100,10 +108,10 @@ Major features in SG 2.x driver (cf original SG driver)
The main documents are still based on 2.x versions:
http://www.torque.net/sg/p/scsi-generic.txt
http://www.torque.net/sg/p/scsi-generic_long.txt
- The first document can also be found in the kernel source tree, probably at:
- /usr/src/linux/Documentation/scsi-generic.txt .
Documentation on the changes and additions in 3.x version of the sg driver
can be found at: http://www.torque.net/sg/p/scsi-generic_v3.txt
+ This document can also be found in the kernel source tree, probably at:
+ /usr/src/linux/Documentation/scsi-generic.txt .
Utility and test programs are also available at that web site.
*/
diff --git a/lib/Makefile b/lib/Makefile
index f5858795438976..fb090afcd88c06 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -8,5 +8,6 @@
L_TARGET := lib.a
L_OBJS := errno.o ctype.o string.o vsprintf.o brlock.o
+LX_OBJS := cmdline.o
include $(TOPDIR)/Rules.make
diff --git a/lib/cmdline.c b/lib/cmdline.c
new file mode 100644
index 00000000000000..e147bc0b1d279a
--- /dev/null
+++ b/lib/cmdline.c
@@ -0,0 +1,117 @@
+/*
+ * linux/lib/cmdline.c
+ * Helper functions generally used for parsing kernel command line
+ * and module options.
+ *
+ * Code and copyrights come from init/main.c and arch/i386/kernel/setup.c.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ *
+ * GNU Indent formatting options for this file: -kr -i8 -npsl -pcs
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+
+/**
+ * get_option - Parse integer from an option string
+ * @str: option string
+ * @pint: (output) integer value parsed from @str
+ *
+ * Read an int from an option string; if available accept a subsequent
+ * comma as well.
+ *
+ * Return values:
+ * 0 : no int in string
+ * 1 : int found, no subsequent comma
+ * 2 : int found including a subsequent comma
+ */
+
+int get_option (char **str, int *pint)
+{
+ char *cur = *str;
+
+ if (!cur || !(*cur))
+ return 0;
+ *pint = simple_strtol (cur, str, 0);
+ if (cur == *str)
+ return 0;
+ if (**str == ',') {
+ (*str)++;
+ return 2;
+ }
+
+ return 1;
+}
+
+/**
+ * get_options - Parse a string into a list of integers
+ * @str: String to be parsed
+ * @nints: size of integer array
+ * @ints: integer array
+ *
+ * This function parses a string containing a comma-separated
+ * list of integers. The parse halts when the array is
+ * full, or when no more numbers can be retrieved from the
+ * string.
+ *
+ * Return value is the character in the string which caused
+ * the parse to end (typically a null terminator, if @str is
+ * completely parseable).
+ */
+
+char *get_options (char *str, int nints, int *ints)
+{
+ int res, i = 1;
+
+ while (i < nints) {
+ res = get_option (&str, ints + i);
+ if (res == 0)
+ break;
+ i++;
+ if (res == 1)
+ break;
+ }
+ ints[0] = i - 1;
+ return (str);
+}
+
+/**
+ * memparse - parse a string with mem suffixes into a number
+ * @ptr: Where parse begins
+ * @retptr: (output) Pointer to next char after parse completes
+ *
+ * Parses a string into a number. The number stored
+ * at @ptr is potentially suffixed with %K (for
+ * kilobytes, or 1024 bytes) or suffixed with %M (for
+ * megabytes, or 1048576 bytes). If the number is suffixed
+ * with K or M, then the return value is the number
+ * multiplied by one kilobyte, or one megabyte, respectively.
+ */
+
+unsigned long memparse (char *ptr, char **retptr)
+{
+ unsigned long ret = simple_strtoul (ptr, retptr, 0);
+
+ switch (**retptr) {
+ case 'M':
+ case 'm':
+ ret <<= 10;
+ case 'K':
+ case 'k':
+ ret <<= 10;
+ (*retptr)++;
+ default:
+ break;
+ }
+ return ret;
+}
+
+
+EXPORT_SYMBOL(memparse);
+EXPORT_SYMBOL(get_option);
+EXPORT_SYMBOL(get_options);