]> git.neil.brown.name Git - history.git/commitdiff
Import 2.4.0-test2pre3 2.4.0-test2pre3
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:26 +0000 (15:35 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:26 +0000 (15:35 -0500)
140 files changed:
Documentation/md.txt
Documentation/powerpc/00-INDEX
Documentation/sound/README.ymfsb [new file with mode: 0644]
Documentation/sound/via82cxxx.txt
Documentation/video4linux/bttv/CARDLIST
Documentation/video4linux/bttv/Insmod-options
arch/i386/kernel/setup.c
arch/mips/config.in
arch/mips/kernel/irixelf.c
arch/mips/kernel/sysirix.c
arch/mips64/config.in
arch/mips64/kernel/syscall.c
arch/mips64/sgi-ip27/ip27-rtc.c
drivers/acorn/char/Makefile
drivers/acorn/char/keyb_arc.c
drivers/acorn/char/mouse_rpc.c
drivers/acorn/net/etherh.c
drivers/atm/Config.in
drivers/atm/Makefile
drivers/block/acsi_slm.c
drivers/block/amiflop.c
drivers/block/ll_rw_blk.c
drivers/block/nbd.c
drivers/block/paride/paride.c
drivers/block/paride/pd.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/swim3.c
drivers/block/xd.c
drivers/block/z2ram.c
drivers/char/acquirewdt.c
drivers/char/adbmouse.c
drivers/char/agp/agpgart_fe.c
drivers/char/atarimouse.c
drivers/char/bttv.c
drivers/char/bttv.h
drivers/char/busmouse.c
drivers/char/cyclades.c
drivers/char/ds1620.c
drivers/char/dsp56k.c
drivers/char/dtlk.c
drivers/char/efirtc.c
drivers/char/epca.c
drivers/char/generic_serial.c
drivers/char/hp600_keyb.c [new file with mode: 0644]
drivers/char/ip2main.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/joystick/joystick.c
drivers/char/lp.c
drivers/char/misc.c
drivers/char/mixcomwd.c
drivers/char/msp3400.c
drivers/char/nvram.c
drivers/char/nwbutton.c
drivers/char/nwflash.c
drivers/char/pc110pad.c
drivers/char/pc_keyb.c
drivers/char/pcwd.c
drivers/char/ppdev.c
drivers/char/rio/rio_linux.c
drivers/char/rtc.c
drivers/char/stallion.c
drivers/char/sx.c
drivers/char/tpqic02.c
drivers/char/tuner.c
drivers/char/tvmixer.c [new file with mode: 0644]
drivers/char/wdt.c
drivers/char/wdt_pci.c
drivers/ide/aec62xx.c
drivers/ide/alim15x3.c
drivers/ide/amd7409.c
drivers/ide/cmd64x.c
drivers/ide/cs5530.c
drivers/ide/cy82c693.c
drivers/ide/gayle.c
drivers/ide/hd.c
drivers/ide/hpt34x.c
drivers/ide/hpt366.c
drivers/ide/icside.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-features.c
drivers/ide/ide-geometry.c
drivers/ide/ide-pci.c
drivers/ide/ide-pmac.c
drivers/ide/ide-probe.c
drivers/ide/ide.c
drivers/ide/ns87415.c
drivers/ide/pdc202xx.c
drivers/ide/piix.c
drivers/ide/qd6580.c
drivers/ide/sis5513.c
drivers/ide/trm290.c
drivers/ide/via82cxxx.c
drivers/pnp/isapnp.c
drivers/scsi/sg.c
drivers/sgi/char/graphics.c
drivers/sgi/char/shmiq.c
drivers/sound/724hwmcode.h [new file with mode: 0644]
drivers/sound/Config.in
drivers/sound/Hwmcode.h [new file with mode: 0644]
drivers/sound/Makefile
drivers/sound/ac97_codec.c
drivers/sound/cmpci.c
drivers/sound/dmasound/dmasound_awacs.c
drivers/sound/dmasound/dmasound_core.c
drivers/sound/emu10k1/audio.c
drivers/sound/emu10k1/main.c
drivers/sound/emu10k1/midi.c
drivers/sound/emu10k1/mixer.c
drivers/sound/es1370.c
drivers/sound/es1371.c
drivers/sound/esssolo1.c
drivers/sound/i810_audio.c
drivers/sound/maestro.c
drivers/sound/sonicvibes.c
drivers/sound/sound_core.c
drivers/sound/soundcard.c
drivers/sound/trident.c
drivers/sound/via82cxxx_audio.c
drivers/sound/wavfront.c
drivers/sound/ymf_sb.c [new file with mode: 0644]
drivers/telephony/phonedev.c
drivers/zorro/zorro.c
fs/devfs/base.c
fs/devices.c
fs/file_table.c
fs/open.c
fs/proc/base.c
fs/proc/generic.c
fs/read_write.c
include/linux/ac97_codec.h
include/linux/ide.h
include/linux/kernel.h
include/linux/proc_fs.h
include/scsi/sg.h
lib/Makefile
lib/cmdline.c [new file with mode: 0644]

index 0107ca5d870d34a83d311b464f58f868c587fa18..7e894fd977cfd7e03d3993edebafb124e84b1ced 100644 (file)
@@ -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>
index d4ed9cabeecb27d62b2de613a236f7ceaaafdd68..2a46c07a84a99e001b3a66dfe007e1bca4e18e6a 100644 (file)
@@ -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 (file)
index 0000000..feda779
--- /dev/null
@@ -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>
+
index af963c3b4be400f911f2b823dcd6198ae403d1a4..bfaf99b643202e745644fb829a415bdb9150ecc5 100644 (file)
@@ -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.
+
+
index 02ec58baac5616516201c93dc501202365871fcd..28f11aeac08ec1a434fd6344941d33c596ff63d0 100644 (file)
@@ -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
index 5d1774a32ecdd6f195a60cccade708ba1e0f0044..b6d4c5a6cb23c7210c43e94037ed74784a80efd7 100644 (file)
@@ -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
-
index c59951cd18e331db4e292f2ef37ee0f092774ba7..03bee2e69326f902fa973a2c22e1bfe09283fcae 100644 (file)
@@ -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)
 {
index 9e6e664d2ea69d7c6c2b3053a4fe3ef31d610bfe..950f665b6225c69688e0f9dadf8f0dcf92687810 100644 (file)
@@ -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"
 
index ddf2340450f4371f97e726431100b2d52dc649c1..1b9774a3de0df701b5c40981492900e3389715d7 100644 (file)
@@ -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);
index 847acadd99aeae2eba8c4ffd68ba2677eb26c48d..3293fa6c2cb37b5e8567b5eb73126ce929cff0c1 100644 (file)
@@ -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);
 
index b2454b8cc3015d6cb6af48d9272d2369c8cdb2ea..57b5486520078610e6c7b372698049ae4345729b 100644 (file)
@@ -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"
 
index f791806d606f32bce1110d8389233962368a6cdc..8f90aad889952c3714fe4672851d70f05cdb3efa 100644 (file)
@@ -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;
 }
index e5f174ab10d74e93c777c0622fa66e11f4c660b0..0e3987296e62e7958b423b9b33b53363e5888fad 100644 (file)
@@ -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,
index 24bab45a94288e8f72585d7ae45dfdfd6af15d08..316af0d4e71b342f776828f6023c594c9ed7ff9d 100644 (file)
@@ -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))
index 44395fd97ef574bf671d977ca3336b63616ba905..4e37bb9d0115b9baf75a9fb117cfa9c8add678e3 100644 (file)
@@ -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
 
index 68b1b9642c4fef85a2e646797ce7ca57b3585994..fb6e4537362f52a406267870d4fe50c5f82c7e27 100644 (file)
@@ -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)
index 96f51c68eba67a97a85223ab4177bc8b892d32bb..5134f6f15ddef8c4bd78590b418bc6fd88490e4f 100644 (file)
@@ -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);
index c603f71affd71c42bb8409090125081ff2d03f1d..b04a354bc14007ad54e9e26dc78022fc334e736a 100644 (file)
@@ -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
index 330d5d1c37b28d712ae2b2987c5ffcd848c2bb8b..b41bc415a4c3e49c248fe715ac6ecf6d08983be4 100644 (file)
@@ -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
index 88fa04ac668e1ec3c6fccbb5a41cd2a2e123aa77..51bb6b1a3aa9e64ccdfd31dcaf2cb7e1e80143f4 100644 (file)
@@ -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,
index 095fc0870606d1b3d5b77f562c66fad2d15f3234..d33bda6419cbb489e0d4b407d877415b4f818966 100644 (file)
@@ -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
index afb9e7bc4b3e3fb7a967541d061a50d74fa4476b..18c7dc1faf6de2654ba18051536f0f8276053fcc 100644 (file)
@@ -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;
index b21be6bd261f42467159007db13bee688a7abd61..8256c57bd0b0030396ead7100e5203b1a649298a 100644 (file)
@@ -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
index 9c4cabbbffc8711860a6b3e032e96c1d2f24ab02..2315e1d300c0cc866b12a9be0c0dfae3c89dc278 100644 (file)
@@ -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
 }
 
index 6c5a87e5c4c6ea59f3606ba160718eeff7ff365d..9b1ff3a32fe6d66704d3b49e4bd37e4b6e371d01 100644 (file)
@@ -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++;
 
index b4e36726c49fa17b44bea4fa15599187cf3feda0..3cb11286da1d6c9778c8c811ed40a3241f669717 100644 (file)
@@ -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;
 
 }
index 459ef7237ab5374b15060f7b5d553f02f4d38bc6..739755a93787ad1dab507acfc5d58735e6a22f37 100644 (file)
@@ -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;
 
 }
index f38e102093bf833dc55ccc21d12065f919f50105..802b04e89d7204aff0d3d7ff47ab80d166238c09 100644 (file)
@@ -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"   */
 
index 74df1096ef0824705236ab3ecf33e8ecd0c569fa..5ac2a16a6fc8faa2b49ead2fbf234389c44f7e2a 100644 (file)
@@ -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 */
index e585bb34c4c2a6e4c062d20a93bfc5af2a9a7728..74ea30a41ebcb205b7e0a57be8bc895e8ba85e4a 100644 (file)
@@ -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
index 9d86479dc1ee133715272928beef65e0357fe689..eaa9e6bae6d6b779ebb1d8ef018a697848b312c1 100644 (file)
@@ -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,
index a33693c1497dc1eda4fb050fd44dfca4c2bae642..a4108cf0ec42a94be0e0965e71b5ae69eae8e17a 100644 (file)
@@ -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)
index 66ec50b9f2e263395ec9b7cb368648eabe704759..e67beef382a01fbf2228efd1eb880ce1ff9e8b15 100644 (file)
@@ -1061,6 +1061,7 @@ ioctl_out:
 
 static struct file_operations agp_fops =
 {
+       owner:          THIS_MODULE,
        llseek:         agp_lseek,
        read:           agp_read,
        write:          agp_write,
index a188320c2f7b02a36443e272a7d63462edebc109..ce08437259608437d8a0f89306fe25739cb29adf 100644 (file)
@@ -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;
 }
 
 
index dd9ca78c6fb7c9133020acaee4eb1e87afc84002..e1cc54e3bd2490fc176a2c6c16df1966ffb69094 100644 (file)
@@ -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);
index 3f4229fe89ce69c21e12b53958a5ddfdd104acf5..9189bfa777d6dc5006f7f7a015b5cfb89557bfb7 100644 (file)
 #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>
 #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
index 1b09081c119f3a5fbc913243ca85a57b08035c1c..5051e80baf17e17e069b6b50b9feb93bc8070c4d 100644 (file)
@@ -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,
index 48047a637509d80bfdbc5ff421986b5f6fa3808f..cf4bb1f8381a70c38307891bdc74b43270a25762 100644 (file)
@@ -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);
index 5a89e008a1630547f420cc52c39566806e1a9eb8..f0c76181ba39ac95f03ea1f5668b6adbf339d299 100644 (file)
@@ -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 = {
index ac27c9e0e9ef0b88887e06d927bf6a9a633163eb..dc076dd5a400a34d8fbc1c2b51537dbc46fbb902 100644 (file)
@@ -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,
index 542ad99bf6ba69849d7a97fd627b68f5a2feb91e..730b69b1773dd5a59ee409c5a1d86dac594644d2 100644 (file)
@@ -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)) {
index 103e60eef5f397fbc9a4f52afaf0ae3db4a15f5f..9ad85c687978102e853ba369b16166d80ca19e52 100644 (file)
@@ -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,
index 9238ae3eb214ce35fa2f5727aed9e8e8c99f01ae..13656af4bd7edd4f72577f242656ed06b5f097c5 100644 (file)
@@ -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)
index dfe89b9707b6413d5bfffb16cb89d65cc66e7b2f..01eb20e9202fb067131df974f967bdf635b6936f 100644 (file)
@@ -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 (file)
index 0000000..52f66ba
--- /dev/null
@@ -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
+
+****************************************************************/
index 6b42c7f63caccc20fe0f028acc4ee7514a11c195..033eb9aafe72395f4a6ca063fed1c3641dcf6481 100644 (file)
@@ -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:
index 958fbf77638274e98704cafa9de1a597e3696277..52c6b5f1950ed0672d3aa4d09a08bc1db9d10aaa 100644 (file)
@@ -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)
 {
index 5733fac43c1757bdc61d18c8c1b017937ca6c90a..8d16c9daf1adcc738ba2da77c0a543029971cb12 100644 (file)
@@ -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,
 };
 
 /*****************************************************************************/
@@ -5182,27 +5179,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,
index 81ec240ba4c43edde2dafbec41c44e8030d53f3d..c9bd56ce361dec8e590efc57254f0e19bc4b5833 100644 (file)
@@ -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,
index 90f0343966bc1595877fd97606244438f6d01bda..c2df7ea1858c0c1d49a92bd20b77967d440f73cd 100644 (file)
@@ -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,
index ca084211855876d93f2ab22ee5e61f97a5b19244..cecf896168d0ccc4e09d3ad9d136b3cd6637af38 100644 (file)
@@ -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,
 };
 
index 5894353e380ab71fcb16b7113974894bc8ef7e0d..6352d6f73e7665020bd58b0323e65c4c0eef7b90 100644 (file)
@@ -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,
index f4252a07122cd64ea9f0cece536e99af0f377dff..d6fa8314bfc1728ddce343aca772bc68e1009170 100644 (file)
@@ -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>
 
 #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.
index c5be675c72ce52a752c333685a275cbdd488abbd..42063cefaa988a702da1f848219452e46ae60553 100644 (file)
@@ -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,
index 34d996582838001f14e9f1b8ab4e4d1e07a2a14e..8cf8a15a7cd33cc4d5897ac23ac6620cd54dc40f 100644 (file)
@@ -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,
 };
 
 /* 
index 579e970d4a1feceb0d69d75526ffc3e437452eb9..5be07b7696a16059ba87966a659ad657fc6136fe 100644 (file)
@@ -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);
index e0b6205969c0524b4184c39b52d8627d31d590bd..b2370ed7154b6320af81f8a756bba37233b23626 100644 (file)
@@ -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,
index 8226b50309f94f89246d28c078b4b16ad5e79d70..f215b9dd3ef535b1689b0775e728c66c56c0ea70 100644 (file)
@@ -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
index 2e2d391fa1d34f976e91c0b0c322e04140ff77da..b85a168de36b96d61a1566248d5d996fb09b8748 100644 (file)
@@ -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,
index 192245602036613541cd16776f56ebd8676658a8..819ed0b1a8bda85529dcd9ac3cf8cf71a5ae1a07 100644 (file)
@@ -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,
index 625f7022bea0a98ece1761b446f47665316475cf..01865a09d3fe0f5f2ea1da7b35393d40d2b5d6a6 100644 (file)
@@ -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, 
index d62e02017ac78f155c99455fcef312ea6dcb283b..4aca69903185b8a9c9c33708a109ad2ef7b7a1b6 100644 (file)
@@ -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__
index 1898849d865ccb1ee8a72aba6e130de4f49b715e..fdaeeaea063e9ff7a6f145520039e881f1004251 100644 (file)
@@ -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);
@@ -3122,27 +3113,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
index 15a24851f8f6d17fb3285aaf5940209858e64257..82e3cae1ec4d43b3537d907d99218be84a4e49ba 100644 (file)
@@ -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;
index d29c634079836ac693e8e8ade2f915bfe48d65cc..133f19aac06014df1c2d6ed5a824d51cdc6dc57d 100644 (file)
@@ -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,
index 0ed55b715399a60a26053f585c6a801d20e6b8bc..81e19a4abda7134fd189c071557e3c9b01ab3e2e 100644 (file)
@@ -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 (file)
index 0000000..0ef5bbd
--- /dev/null
@@ -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:
+ */
index 0ce42945d0e42b7e607012c9b0d497e3729c2e7a..3ac86bf3ae5075054c0b61032f4503e4eb14adce 100644 (file)
@@ -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,
index 6e99a72ac04cf52e37a9c83f3c88117f8db268ca..2bd09930a14a2c6604aad7a29b1036b059b2610a 100644 (file)
@@ -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);
index 75b3153b7ad15006495fed789fe35b6313b95ff7..2f3d2fc3a83d09935d2967f21e021accc79a99fa 100644 (file)
@@ -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);
 }
 
index 02af0a0f801a1080f15adf571f3a2c79b4e5466e..41768bb908863fa1f133c5371b7387bad5c0eca1 100644 (file)
@@ -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);
index d54a240d4c931c64632ccb1d1e3f8c2ee9b5a22c..ca23d3af45633884957611b63b7284b4f643c049 100644 (file)
@@ -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) {
                /*
                 *
                 */
index 7e9f0c7eecb9a4dfe339016d0730c921e2a67b63..6e45bf0e0fa5d90b15b51dc117faf6de7274b053 100644 (file)
@@ -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
 
 #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;
index b160d7716361a28fe867d04b33cf06c2b2064bc4..fb531e81336e783252494cbbe27fff248aaa11fa 100644 (file)
@@ -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;
 
        /*
index 3ecaa31ece2c54bbbaf409b16cfd994913dcb60e..3e4961cbe2ee1fb1734b3f6fc08166165b92924c 100644 (file)
@@ -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
  *
index 74806824219b9b5bde86b7e7ebe97945c56def58..2011b6a266ff340a7939d9d165104d09b8e85519 100644 (file)
@@ -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;
index eb73c24456c88cb18c7d51f919e57467133d4327..6fd109c83230a98ec36ee2a1676e86d8cecfdae2 100644 (file)
@@ -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);
 
index 911068f7846139fe4d00836066117a7ef8df1adc..cbd71e60ae852f4d8caad8ae8ef20b83b3114f90 100644 (file)
@@ -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);
                }
index 28232b5768dc51ebf1a45dd51a762d7242fe8ca5..74d3018c522686082eb23efa63aa93ccef327884 100644 (file)
@@ -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>
 
 #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;
index dcc50362faae8c4e5c100333b04fe45b78fb6219..7d5bfaedffbc19aba4cd5ff4d355b2a2d108a884 100644 (file)
@@ -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" : "");
index d209c29fff08850a82cb8f3bc58b41e8ba994127..ab4d3afbb9e158597f13b9008bb0539bca24db3f 100644 (file)
@@ -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
index 4e29520180495d621ff31d5338b24b5d4b1fc85b..ae9f62768c559372b60731a473d783e448aa5dec 100644 (file)
@@ -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.
  *
  *                     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);
index 835fa91e34e465e7ca456397215b855d89a9338c..e9a34afc1a720378a0e47c4a6e8e92910b2dc5df 100644 (file)
@@ -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
  */
 
  *
  * 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 */
@@ -412,6 +412,22 @@ static int config_drive_for_dma (ide_drive_t *drive)
        return hwif->dmaproc(ide_dma_off_quietly, 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.
  *
@@ -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;
                }
index cb3790fa62f4f5868f7635f0536c2d2e3be33a4b..967b91e55c199fe8a34143a9f8d6134ed91d7e4e 100644 (file)
@@ -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;
                }
        }
@@ -243,6 +257,18 @@ int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature)
        return 0;
 }
 
+/*
+ *  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,
@@ -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);
-
index a291785971cf521b089912a62f0ab9967bd37e83..639d4c6f1c07aed46227fd43018b4cbe06903a57 100644 (file)
@@ -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) */
index c10ae4b51cbf9144dde16c8050a4deff01a630f7..8c935439491718cb3022a90d76bdfbcbb40d3830 100644 (file)
@@ -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>
  *
 #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);
 }
 
index 45bbe77ac1309674433ed194f15b91eccf5d0b92..83cea6ba2bd6151ca6ff96371ce9759f2efcb7d2 100644 (file)
@@ -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);
index ddf6c8daefa78ebc0948017da4d75fe6c4c9d4ff..dd5f660fecc88d5c068104a62b32f1da53ec3186 100644 (file)
@@ -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;
 }
 
index a3394807b1668467048c525f40a1c09b8b24f1ab..932c6f1142f2f9f5aef31fdf55f8220091e5fda2 100644 (file)
@@ -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.
  *
  * 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
  *
  *
  */
 
-#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);
index 70f1851088d0b4a0a148c77d63334d2e21d79ee8..1837f01e0edff10b725ce98636f1752da80862ca 100644 (file)
@@ -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>
  */
index f16d3392143590d67ba598d6d30cce21b10a4ce2..66a12384133ba4b720a3f16b3ea8f77f61598c40 100644 (file)
@@ -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.
 
 #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) {
index 56c1852361d43b695ad34efd4460d51af96b3cc6..0dbb8d88382bf5d1d5f745de6de6db2ccfe25361 100644 (file)
@@ -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 :
index 4c00de5042f13ebdabfd5f61e2babfb9de94604b..5787b73f21a4703a4062895e75bdbb956a67e9be 100644 (file)
@@ -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"
  */
 
 /* 
 #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);
 }
 
 /*
@@ -192,6 +303,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
  *
@@ -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;
+       }
 }
index be56a7f2489ac4519a8f1ee696dd19f0afa655db..4f0a330863e618d499204f2a1b0f0f1da71684b4 100644 (file)
@@ -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)
index e7ee2e9777b224a155de4c6796e6e11e9805579e..c1aa3fb4eddcaa14062d583e28baf62f1275feea 100644 (file)
@@ -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;
index 6c201599f81f846729d4a7b250593a58ef996e58..3ab29859669473d109b1e7735c6a896708022ded 100644 (file)
@@ -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)
index 06bf946645abf258e97852db6cd49f1e6c131d6c..497879619cbd5f479595cfe27a0153a3bfae3f18 100644 (file)
@@ -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
 }
 
index 4fca4d14db51033a3d767a4685e32e8bcd8e5ac4..71b93e379a70cbc4dd37cc1ed9db9eba96d67dbd 100644 (file)
@@ -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;
 }
 
index 352a210d4b4b3c945890785550d6af90af2a79ba..b0f3103e428abc2a208009e9e9c17f6b868e822c 100644 (file)
@@ -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;
        }
index 19d44b090be1e8d0ce3125a4b6f6005b2f796324..2d6a4b6f4fc9a911a0266e9f48ed457f6c7f8b89 100644 (file)
@@ -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 (file)
index 0000000..7565835
--- /dev/null
@@ -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_
+
+
index eea182f5e67579bb88c88b05426505143099efc4..640d9b21912aa774e9c6c43638562b15f6bdab39 100644 (file)
@@ -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 (file)
index 0000000..e4d9a68
--- /dev/null
@@ -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
+};
index ec43a1d2662148f4287b76c1b86e30b57fec3af8..10fbd5871e5803790d0afa2160b9f60628498636 100644 (file)
@@ -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
index b26c3a8d5d3f61aedaf53fdd17c2b122dca25b27..23e94845a0bcaa17308a59be55f6fdf7480fbb8a 100644 (file)
@@ -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);
index df05c9b64bde8a7c4bd0f0cd082ffa80186dccb5..527d570cfbe9318697e5b3ee644a9c41f2dc1d82 100644 (file)
@@ -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);
index 3893f9b58dee41afecc5255301a79dad3814cf7b..f80ada7fd4a33e843d580f7c89d9f25615d8c342 100644 (file)
@@ -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);
        }
index 4aed3953e859af8481fb66b0b43ce053e03425ee..da60c783b70b69395183cd72ec4d9db79b52cc21 100644 (file)
@@ -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,
index a682879844930c1c6585e014f304e8b1116729ad..06f84dfc3ee621d4d5051aea4d0259be33269e89 100644 (file)
@@ -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,
index bce892fe33ce96cdaddbf147033c57d33277de24..acb65d7e56de5a1b22ba3957ae50c840d14c24f2 100644 (file)
@@ -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");
index 497e4811311693a360e4eb22a9dbf5ceb1a0ff99..04b1424a8a15e240601b9b13621a43793f88bddf 100644 (file)
@@ -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,
index fa54ca435f0a44f59e74635e6c9f7e89aacd7f58..62796146f49b0989fae97f0f9784b1e71e6f73cc 100644 (file)
@@ -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,
index ec3849a748b72b249279b99fcd91193ca0104a92..47d1d875f5321d2a9c41224441193e27404c86ad 100644 (file)
@@ -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,
index 44189f010c0b45371c399cf1b48ee4ac306d7aec..109ac71c0224207e668cfbefeeaec9e93783089e 100644 (file)
 #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
index 2d7e15f5132bf90926379923ea720d758afec642..930e58f463fa4ae095822bb4bc038b881c095e30 100644 (file)
@@ -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,
index 76bfcc3c058098387edc62ee60c60673ab2281d3..1ac21c429ac50c381dcaa8ccd0219170890fdf8f 100644 (file)
  *     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>
 #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");
 
index 81a7d21d25f76212329e051b8a6fb79c32e1016b..cd5a2bc2719e577368251a7afe66367b9b7272e1 100644 (file)
 #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);
index 7a8a7117b4730e3b0e7e013ff92c130cce3868ee..0d50924d8e2f2ed1980dce0167982e781e016291 100644 (file)
@@ -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,
index 053b43160f4ff4379d68bb1e77b2cb6f6c5d439a..da0cfe51c4c2f02f805cfd3f8f9575ca47c55928 100644 (file)
@@ -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;
index 0bf2b8e0fa4975f77eb6306db3b5bb9bd799d30f..5018ad1e774671290238761abbf40225a1f7786a 100644 (file)
@@ -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,
index 6a3b8b4d6c1de373a19ab569f24dc1cf8ed5937d..2eb45827448822fd6900c1559dd0030ffc4a2930 100644 (file)
@@ -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
  *     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
 
 #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*/
        }
index e4403d9664ab733de7a6b978ae68b7d3a11985a9..ab14427d637533e9f79d8459f0f178de7b8698ba 100644 (file)
@@ -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;
 }
index 4bf595f86afd73975eaf62b8f2f0861f333fd698..a8f826031b71f91bda7052c1905bde720a13b908 100644 (file)
@@ -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 (file)
index 0000000..a221a05
--- /dev/null
@@ -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);
+
index fc4f61b34eb8203819554b9be8c6997cb8523159..3fde30bfad8af399c2348a91d901393e4582550c 100644 (file)
@@ -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,
 };
 
index b1d164d3578c2a8e693947ddd9a882ab6eef07cf..10ac2eec303c1a802540faf6655e78496a95cac8 100644 (file)
@@ -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);
     }
 
index 040e0b79af3baa0c54f6e979355f1f01b9ab7db6..9f1e8b06fd1c46cbf8b4df163ea30589c8a8e32d 100644 (file)
@@ -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
index 2c53934b90010c35f60514deece04cc9a52e8855..d119b1c75f620e714980ea7d63ed8866b7a2bfbe 100644 (file)
@@ -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);
index 7d5bd9e01d1d58cf4cc161783ab29b121f3b006b..ecaa4689677f233efea5f039c53dc1550e330fdd 100644 (file)
@@ -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)
index e23e48194e7dcd1b6d9303675c5e9f3fb50d5e62..9135f0e30138ddcfa3dc3d99dbdb2bbf1344c075 100644 (file)
--- 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;
index ecb8a29919d5451f2ef5b4d3f304d59ce48830d2..fb63722d523a1f64117adcec0f6a18f009a2e701 100644 (file)
@@ -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;
index 1585657a2d7b0621f9244be8c4446edf7f243798..dc6f96b17f46cf36b88b6bc8404c42901d0031c2 100644 (file)
@@ -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)
index 4569ee18aca6f8ad3f325961acc2ee8e0ffd0f27..3d3519146bc73e1ef621ae5a2f6f61f9a982797f 100644 (file)
@@ -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 */
index 81f463cd584a7f87f1ea503fbbc260c2f6cf6074..f4468611ef1d5a3256192b5c8ee97cdcaad929b9 100644 (file)
@@ -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 */
        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;
index 8804c9777f91853a37eb4983e7ac98175f604468..13876daf5ca300328aef25d418d35a1e4806755c 100644 (file)
@@ -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);
 
 /*
index a8d79a50e508f8d13c26808b9ed9a3d3cca19cdc..ac6f029b99b529b35bd2d4356dcb76fe12a1f212 100644 (file)
@@ -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);
 
index d0487c3df455d8b9b785536eb3970bf8313f85c6..28bf3daa02aaa2ea6b37be27a1d37375188a3eac 100644 (file)
@@ -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 *);
index 283e816950bd9f7e3c6ffdc6395adefb7bbb7b93..680069a4472df75291da3fb07a5ff0a36270e2ff 100644 (file)
@@ -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.
 */
 
index f5858795438976d5325c497ae540ee482f0a2b3c..fb090afcd88c0653b32bd09bbdc030d084d0f1b3 100644 (file)
@@ -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 (file)
index 0000000..e147bc0
--- /dev/null
@@ -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);