diff options
| author | Linus Torvalds <torvalds@linuxfoundation.org> | 2007-11-23 15:35:26 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linuxfoundation.org> | 2007-11-23 15:35:26 -0500 |
| commit | f68565831e7269e49b20f201ddef99f136a8c348 (patch) | |
| tree | 0e05cc22e5f1fea08113fd08549bf1e875abce9a | |
| parent | bdd9c8e5286db0c47362e34a29fa1343fa83a4a6 (diff) | |
| download | linux-f68565831e72.tar.gz | |
Import 2.4.0-test2pre3
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
140 files changed, 6566 insertions, 1654 deletions
diff --git a/Documentation/md.txt b/Documentation/md.txt index 0107ca5d870d34..7e894fd977cfd7 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt @@ -1,15 +1,17 @@ -Tools that manage md devices can be found at sweet-smoke.ufr-info-p7.ibp.fr -in public/Linux/md035.tar.gz. +Tools that manage md devices can be found at + http://www.<country>.kernel.org/pub/linux/daemons/raid/.... - Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr> --- You can boot (if you selected boot support in the configuration) with your md -device with the following kernel command line: +device with the following kernel command lines: -md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn +for old raid arrays without persistant superblocks: + md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn +for raid arrays with persistant superblocks + md=<md device no.>,dev0,dev1,...,devn + md device no. = the number of the md device ... 0 means md0, 1 md1, @@ -19,19 +21,16 @@ md device no. = the number of the md device ... raid level = -1 linear mode 0 striped mode - other modes are currently unsupported. + other modes are only supported with persistant super blocks chunk size factor = (raid-0 and raid-1 only) - Set the chunk size as PAGE_SIZE << n. + Set the chunk size as 4k << n. -fault level = (raid-1 only) - Set the maximum fault number as n. - Currently unsupported due to lack of boot support for raid1. +fault level = totally ignored dev0-devn: e.g. /dev/hda1,/dev/hdc1,/dev/sda1,/dev/sdb1 -my loadlin line looks like this: +A possible loadlin line (Harald Hoyer <HarryH@Royal.Net>) looks like this: e:\loadlin\loadlin e:\zimage root=/dev/md0 md=0,0,4,0,/dev/hdb2,/dev/hdc3 ro - Harald Hoyer <HarryH@Royal.Net> diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX index d4ed9cabeecb27..2a46c07a84a99e 100644 --- a/Documentation/powerpc/00-INDEX +++ b/Documentation/powerpc/00-INDEX @@ -1,7 +1,7 @@ Index of files in Documentation/powerpc. If you think something about Linux/PPC needs an entry here, needs correction or you've written one please mail me. - Cort Dougan (cort@cs.nmt.edu) + Cort Dougan (cort@fsmlabs.com) 00-INDEX - this file @@ -9,6 +9,8 @@ ppc_htab.txt - info about the Linux/PPC /proc/ppc_htab entry smp.txt - use and state info about Linux/PPC on MP machines +SBC8260_memory_mapping.txt + - EST SBC8260 board info sound.txt - info on sound support under Linux/PPC zImage_layout.txt diff --git a/Documentation/sound/README.ymfsb b/Documentation/sound/README.ymfsb new file mode 100644 index 00000000000000..feda77915b1869 --- /dev/null +++ b/Documentation/sound/README.ymfsb @@ -0,0 +1,107 @@ +Legacy audio driver for YMF7xx PCI cards. + + +FIRST OF ALL +============ + + This code references YAMAHA's sample codes and data sheets. + I respect and thank for all people they made open the informations + about YMF7xx cards. + + And this codes heavily based on Jeff Garzik <jgarzik@pobox.com>'s + old VIA 82Cxxx driver (via82cxxx.c). I also respect him. + + +DISCLIMER +========= + + This driver is currently at early ALPHA stage. It may cause serious + damage to your computer when used. + PLEASE USE IT AT YOUR OWN RISK. + + +ABOUT THIS DRIVER +================= + + This code enables you to use your YMF724[A-F], YMF740[A-C], YMF744, YMF754 + cards. When enabled, your card acts as "SoundBlaster Pro" compatible card. + It can only play 22.05kHz / 8bit / Stereo samples, control external MIDI + port. + If you want to use your card as recent "16-bit" card, you should use + Alsa or OSS/Linux driver. Ofcource you can write native PCI driver for + your cards :) + + +USAGE +===== + + # modprobe ymfsb (options) + + +OPTIONS FOR MODULE +================== + + io : SB base address (0x220, 0x240, 0x260, 0x280) + synth_io : OPL3 base address (0x388, 0x398, 0x3a0, 0x3a8) + dma : DMA number (0,1,3) + master_volume: AC'97 PCM out Vol (0-100) + spdif_out : SPDIF-out flag (0:disable 1:enable) + + These options will change in future... + + +FREQUENCY +========= + + When playing sounds via this driver, you will hear its pitch is slightly + lower than original sounds. Since this driver recognizes your card acts + with 21.739kHz sample rates rather than 22.050kHz (I think it must be + hardware restriction). So many players become tone deafness. + To prevent this, you should express some options to your sound player + that specify correct sample frequency. For example, to play your MP3 file + correctly with mpg123, specify the frequency like following: + + % mpg123 -r 21739 foo.mp3 + + +SPDIF OUT +========= + + With installing modules with option 'spdif_out=1', you can enjoy your + sounds from SPDIF-out of your card (if it had). + Its Fs is fixed to 48kHz (It never means the sample frequency become + up to 48kHz. All sounds via SPDIF-out also 22kHz samples). So your + digital-in capable components has to be able to handle 48kHz Fs. + + +COPYING +======= + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +TODO +==== + * support for multiple cards + (set the different SB_IO,MPU_IO,OPL_IO for each cards) + + * support for OPL (dmfm) : There will be no requirements... :-< + + +AUTHOR +====== + + Daisuke Nagano <breeze.nagano@nifty.ne.jp> + diff --git a/Documentation/sound/via82cxxx.txt b/Documentation/sound/via82cxxx.txt index af963c3b4be400..bfaf99b643202e 100644 --- a/Documentation/sound/via82cxxx.txt +++ b/Documentation/sound/via82cxxx.txt @@ -48,6 +48,15 @@ be added to your /etc/conf.modules (or /etc/modules.conf) file: Driver notes ------------------------------------------------------------------------ +Two /proc pseudo-files provide diagnostic information. This is generally +not useful to most users. Power users can disable VIA_PROC_FS macro in the +driver source code, and remove the /proc support code. In any case, once +version 2.0.0 is released, the /proc support code will be disabled by +default. Available /proc pseudo-files: + + /proc/driver/via/0/info + /proc/driver/via/0/ac97 + This driver by default supports all PCI audio devices which report a vendor id of 0x1106, and a device id of 0x3058. Subsystem vendor and device ids are not examined. @@ -110,7 +119,8 @@ Known bugs (patches/suggestions welcome) 1) Volume too low on many systems. Workaround: use mixer program such as xmixer to increase volume. -2) RealPlayer output very scratchy. +2) RealPlayer output very scratchy. Workaround: use esd, and +configure RealPlayer to output to esd. 3) Applications which attempt to open the sound device in read/write mode (O_RDWR) will fail. This is incorrect OSS behavior, but since @@ -139,3 +149,28 @@ change the LOG_BUF_LEN macro at the top of linux/kernel/printk.c, recompile your kernel, and pass the "-s <size>" option to 'dmesg'. + +Change history +------------------------------------------------------------------------ +Version 1.1.7: +* Fix module unload bug where mixer device left registered + after driver exit + +Version 1.1.6: +* Rewrite via_set_rate to mimic ALSA basic AC97 rate setting +* Remove much dead code +* Complete spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl +* Fix build problem in via_dsp_ioctl +* Optimize included headers to eliminate headers found in linux/drivers/sound + +Version 1.1.5: +* Disable some overly-verbose debugging code +* Remove unnecessary sound locks +* Fix some ioctls for better time resolution +* Begin spin_lock_irqsave -> spin_lock_irq conversion in via_dsp_ioctl + +Version 1.1.4: +* Completed rewrite of driver. Eliminated SoundBlaster compatibility + completely, and now uses the much-faster scatter-gather DMA engine. + + diff --git a/Documentation/video4linux/bttv/CARDLIST b/Documentation/video4linux/bttv/CARDLIST index 02ec58baac5616..28f11aeac08ec1 100644 --- a/Documentation/video4linux/bttv/CARDLIST +++ b/Documentation/video4linux/bttv/CARDLIST @@ -42,6 +42,8 @@ bttv.o card=40 - STB2 card=41 - AVerMedia TVPhone 98 card=42 - ProVideo PV951 + card=43 - Little OnAir TV + card=44 - Sigma TVII-FM tuner.o type=0 - Temic PAL diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options index 5d1774a32ecdd6..b6d4c5a6cb23c7 100644 --- a/Documentation/video4linux/bttv/Insmod-options +++ b/Documentation/video4linux/bttv/Insmod-options @@ -3,7 +3,7 @@ bttv.o the bt848 (grabber chip) driver insmod args: - card=n card type, see cardlist for a list. + card=n card type, see CARDLIST for a list. radio=0/1 card supports radio pll=0/1/2 pll settings 0: don't use PLL @@ -31,6 +31,29 @@ bttv.o remap, card, radio and pll accept up to four comma-separated arguments (for multiple boards). +tuner.o + The tuner driver. You need this unless you want to use only + with a camera or external tuner ... + + insmod args: + debug=1 print some debug info to the syslog + type=n type of the tuner chip. n as follows: + see CARDLIST for a complete list. + +tvmixer.o + registers a mixer device for the TV card's volume/bass/treble + controls (requires a i2c audio control chip like the msp3400). + + insmod args: + debug=1 print some debug info to the syslog. + devnr=n allocate device #n (0 == /dev/mixer, + 1 = /dev/mixer1, ...), default is to + use the first free one. + +tvaudio.o + new, experimental module which is supported to provide a single + driver for all simple i2c audio control chips (tda/tea*). + msp3400.o The driver for the msp34xx sound processor chips. If you have a stereo card, you probably want to insmod this one. @@ -47,8 +70,6 @@ msp3400.o amsound=1 Audio carrier is AM/NICAM at 6.5 Mhz. This should improve things for french people, the carrier autoscan seems to work with FM only... - mixer=n allocate mixer device #n. Default is the - first free slot. tea6300.o The driver for the tea6300 fader chip. If you have a stereo @@ -73,20 +94,3 @@ tda985x.o insmod args: debug=1 print some debug info to the syslog. chip=9850/9855 set the chip type. - -tuner.o - The tuner driver. You need this unless you want to use only - with a camera or external tuner ... - - insmod args: - debug=1 print some debug info to the syslog - type=n type of the tuner chip. n as follows: - 0: Temic PAL tuner - 1: Philips PAL_I tuner - 2: Philips NTSC tuner - 3: Philips SECAM tuner - 4: no tuner - 5: Philips PAL tuner - 6: Temic NTSC tuner - 7: Temic PAL tuner - diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index c59951cd18e331..03bee2e69326f9 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -373,24 +373,6 @@ static void __init probe_roms(void) } } -unsigned long __init memparse(char *ptr, char **retptr) -{ - unsigned long ret; - - ret = simple_strtoul(ptr, retptr, 0); - - if (**retptr == 'K' || **retptr == 'k') { - ret <<= 10; - (*retptr)++; - } - else if (**retptr == 'M' || **retptr == 'm') { - ret <<= 20; - (*retptr)++; - } - return ret; -} /* memparse */ - - void __init add_memory_region(unsigned long start, unsigned long size, int type) { diff --git a/arch/mips/config.in b/arch/mips/config.in index 9e6e664d2ea69d..950f665b6225c6 100644 --- a/arch/mips/config.in +++ b/arch/mips/config.in @@ -1,6 +1,6 @@ # $Id: config.in,v 1.46 2000/03/26 22:59:01 ralf Exp $ # For a description of the syntax of this configuration file, -# see the Configure script. +# see Documentation/kbuild/config-language.txt. # mainmenu_name "Linux Kernel Configuration" diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index ddf2340450f437..1b9774a3de0df7 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -315,10 +315,12 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex, (unsigned long) elf_prot, (unsigned long) elf_type, (unsigned long) (eppnt->p_offset & 0xfffff000)); #endif + down(¤t->mm->mmap_sem); error = do_mmap(interpreter, vaddr, eppnt->p_filesz + (eppnt->p_vaddr & 0xfff), elf_prot, elf_type, eppnt->p_offset & 0xfffff000); + up(¤t->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(¤t->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(¤t->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(¤t->mm->mmap_sem); (void) do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); + up(¤t->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(¤t->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(¤t->mm->mmap_sem); if(retval != (hp->p_vaddr & 0xfffff000)) { printk("irix_mapelf: do_mmap fails with %d!\n", retval); diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 847acadd99aeae..3293fa6c2cb37b 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -1099,7 +1099,9 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + down(¤t->mm->mmap_sem); retval = do_mmap(file, addr, len, prot, flags, offset); + up(¤t->mm->mmap_sem); if (file) fput(file); diff --git a/arch/mips64/config.in b/arch/mips64/config.in index b2454b8cc3015d..57b54865200786 100644 --- a/arch/mips64/config.in +++ b/arch/mips64/config.in @@ -1,7 +1,7 @@ # $Id: config.in,v 1.19 2000/03/27 01:44:45 ralf Exp $ # # For a description of the syntax of this configuration file, -# see the Configure script. +# see Documentation/kbuild/config-language.txt. # mainmenu_name "Linux Kernel Configuration" diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c index f791806d606f32..8f90aad889952c 100644 --- a/arch/mips64/kernel/syscall.c +++ b/arch/mips64/kernel/syscall.c @@ -56,7 +56,6 @@ sys_mmap(unsigned long addr, size_t len, unsigned long prot, struct file * file = NULL; unsigned long error = -EFAULT; - down(¤t->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(¤t->mm->mmap_sem); error = do_mmap(file, addr, len, prot, flags, offset); + up(¤t->mm->mmap_sem); if (file) fput(file); out: unlock_kernel(); - up(¤t->mm->mmap_sem); return error; } diff --git a/arch/mips64/sgi-ip27/ip27-rtc.c b/arch/mips64/sgi-ip27/ip27-rtc.c index e5f174ab10d74e..0e3987296e62e7 100644 --- a/arch/mips64/sgi-ip27/ip27-rtc.c +++ b/arch/mips64/sgi-ip27/ip27-rtc.c @@ -168,8 +168,6 @@ static int rtc_open(struct inode *inode, struct file *file) if(rtc_status & RTC_IS_OPEN) return -EBUSY; - MOD_INC_USE_COUNT; - rtc_status |= RTC_IS_OPEN; return 0; } @@ -181,8 +179,6 @@ static int rtc_release(struct inode *inode, struct file *file) * in use, and clear the data. */ - MOD_DEC_USE_COUNT; - rtc_status &= ~RTC_IS_OPEN; return 0; } @@ -192,6 +188,7 @@ static int rtc_release(struct inode *inode, struct file *file) */ static struct file_operations rtc_fops = { + owner: THIS_MODULE, ioctl: rtc_ioctl, open: rtc_open, release: rtc_release, diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile index 24bab45a94288e..316af0d4e71b34 100644 --- a/drivers/acorn/char/Makefile +++ b/drivers/acorn/char/Makefile @@ -18,7 +18,7 @@ MX_OBJS := # Object file lists. -obj-y := i2c.o pcf8583.o +obj-y := obj-m := obj-n := obj- := @@ -34,7 +34,8 @@ obj-$(CONFIG_RPCMOUSE) += mouse_rpc.o obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o -obj-y += $(obj-$(MACHINE)) +# Do the i2c and rtc last +obj-y += $(obj-$(MACHINE)) i2c.o pcf8583.o O_OBJS := $(filter-out $(export-objs), $(obj-y)) OX_OBJS := $(filter $(export-objs), $(obj-y)) diff --git a/drivers/acorn/char/keyb_arc.c b/drivers/acorn/char/keyb_arc.c index 44395fd97ef574..4e37bb9d0115b9 100644 --- a/drivers/acorn/char/keyb_arc.c +++ b/drivers/acorn/char/keyb_arc.c @@ -415,7 +415,7 @@ static void a5kkbd_tx(int irq, void *dev_id, struct pt_regs *regs) #ifdef CONFIG_KBDMOUSE static struct busmouse a5kkbd_mouse = { - 6, "kbdmouse", NULL, NULL, 7 + 6, "kbdmouse", NULL, NULL, NULL, 7 }; #endif diff --git a/drivers/acorn/char/mouse_rpc.c b/drivers/acorn/char/mouse_rpc.c index 68b1b9642c4fef..fb6e4537362f52 100644 --- a/drivers/acorn/char/mouse_rpc.c +++ b/drivers/acorn/char/mouse_rpc.c @@ -46,7 +46,7 @@ mouse_rpc_irq(int irq, void *dev_id, struct pt_regs *regs) } static struct busmouse rpcmouse = { - 6, "arcmouse", NULL, NULL, 7 + 6, "arcmouse", NULL, NULL, NULL, 7 }; static int __init mouse_rpc_init(void) diff --git a/drivers/acorn/net/etherh.c b/drivers/acorn/net/etherh.c index 96f51c68eba67a..5134f6f15ddef8 100644 --- a/drivers/acorn/net/etherh.c +++ b/drivers/acorn/net/etherh.c @@ -621,8 +621,6 @@ static int __init etherh_init(void) if (load_8390_module("etherh.c")) return -ENOSYS; - lock_8390_module(); - ecard_startfind(); for (i = 0; i < MAX_ECARDS; i++) { @@ -643,7 +641,7 @@ static int __init etherh_init(void) } if (ret) - unlock_8390_module(); + unload_8390_module(); return ret; } @@ -665,7 +663,7 @@ static void __exit etherh_exit(void) e_card[i] = NULL; } } - unlock_8390_module(); + unload_8390_module(); } module_init(etherh_init); diff --git a/drivers/atm/Config.in b/drivers/atm/Config.in index c603f71affd71c..b04a354bc14007 100644 --- a/drivers/atm/Config.in +++ b/drivers/atm/Config.in @@ -59,7 +59,7 @@ if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then if [ "$CONFIG_ATM_FORE200E_PCA" = "y" ]; then bool ' Use default PCA-200E firmware (normally enabled)' CONFIG_ATM_FORE200E_PCA_DEFAULT_FW if [ "$CONFIG_ATM_FORE200E_PCA_DEFAULT_FW" = "n" ]; then - string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW + string ' Pathname of user-supplied binary firmware' CONFIG_ATM_FORE200E_PCA_FW "" fi fi fi diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index 330d5d1c37b28d..b41bc415a4c3e4 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -45,7 +45,7 @@ else NEED_SUNI_MX = suni.o endif ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y) - NEED_SUNI_MX = idt77105.o + NEED_IDT77105_MX = idt77105.o endif endif endif diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c index 88fa04ac668e1e..51bb6b1a3aa9e6 100644 --- a/drivers/block/acsi_slm.c +++ b/drivers/block/acsi_slm.c @@ -272,6 +272,7 @@ static int slm_get_pagesize( int device, int *w, int *h ); static struct timer_list slm_timer = { NULL, NULL, 0, 0, slm_test_ready }; static struct file_operations slm_fops = { + owner: THIS_MODULE, read: slm_read, write: slm_write, ioctl: slm_ioctl, diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 095fc0870606d1..d33bda6419cbb4 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -70,6 +70,7 @@ #include <linux/init.h> #include <linux/amifdreg.h> #include <linux/amifd.h> +#include <linux/ioport.h> #include <asm/setup.h> #include <asm/uaccess.h> @@ -127,11 +128,6 @@ MODULE_PARM(fd_def_df0,"l"); #define DESELECT(mask) (ciab.prb |= mask) #define SELMASK(drive) (1 << (3 + (drive & 3))) -#define DRIVE(x) ((x) & 3) -#define PROBE(x) ((x) >> 2) & 1) -#define TYPE(x) ((x) >> 3) & 2) -#define DATA(x) ((x) >> 5) & 3) - static struct fd_drive_type drive_types[] = { /* code name tr he rdsz wrsz sm pc1 pc2 sd st st*/ /* warning: times are now in milliseconds (ms) */ @@ -1794,17 +1790,26 @@ int __init amiga_floppy_init(void) printk("fd: Unable to get major %d for floppy\n",MAJOR_NR); return -EBUSY; } - + /* + * We request DSKPTR, DSKLEN and DSKDATA only, because the other + * floppy registers are too spreaded over the custom register space + */ + if (!request_mem_region(CUSTOM_PHYSADDR+0x20, 8, "amiflop [Paula]")) { + printk("fd: cannot get floppy registers\n"); + unregister_blkdev(MAJOR_NR,"fd"); + return -EBUSY; + } if ((raw_buf = (char *)amiga_chip_alloc (RAW_BUF_SIZE, "Floppy")) == NULL) { printk("fd: cannot get chip mem buffer\n"); + release_mem_region(CUSTOM_PHYSADDR+0x20, 8); unregister_blkdev(MAJOR_NR,"fd"); return -ENOMEM; } - if (request_irq(IRQ_AMIGA_DSKBLK, fd_block_done, 0, "floppy_dma", NULL)) { printk("fd: cannot get irq for dma\n"); amiga_chip_free(raw_buf); + release_mem_region(CUSTOM_PHYSADDR+0x20, 8); unregister_blkdev(MAJOR_NR,"fd"); return -EBUSY; } @@ -1812,6 +1817,7 @@ int __init amiga_floppy_init(void) printk("fd: cannot get irq for timer\n"); free_irq(IRQ_AMIGA_DSKBLK, NULL); amiga_chip_free(raw_buf); + release_mem_region(CUSTOM_PHYSADDR+0x20, 8); unregister_blkdev(MAJOR_NR,"fd"); return -EBUSY; } @@ -1819,6 +1825,7 @@ int __init amiga_floppy_init(void) free_irq(IRQ_AMIGA_CIAA_TB, NULL); free_irq(IRQ_AMIGA_DSKBLK, NULL); amiga_chip_free(raw_buf); + release_mem_region(CUSTOM_PHYSADDR+0x20, 8); unregister_blkdev(MAJOR_NR,"fd"); return -ENXIO; } @@ -1889,6 +1896,7 @@ void cleanup_module(void) blk_size[MAJOR_NR] = NULL; blksize_size[MAJOR_NR] = NULL; blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); + release_mem_region(CUSTOM_PHYSADDR+0x20, 8); unregister_blkdev(MAJOR_NR, "fd"); } #endif diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index afb9e7bc4b3e3f..18c7dc1faf6de2 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -411,6 +411,7 @@ static inline void add_request(request_queue_t * q, struct request * req, drive_stat_acct(req->rq_dev, req->cmd, req->nr_sectors, 1); + elevator_account_request(&q->elevator, req); if (list_empty(head)) { req->elevator_sequence = elevator_sequence(&q->elevator, latency); list_add(&req->queue, &q->queue_head); @@ -748,7 +749,6 @@ get_rq: req->bhtail = bh; req->q = q; add_request(q, req, head, orig_latency); - elevator_account_request(elevator, req); spin_unlock_irqrestore(&io_request_lock, flags); return; diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index b21be6bd261f42..8256c57bd0b003 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -38,6 +38,8 @@ #include <linux/ioctl.h> #include <net/sock.h> +#include <linux/devfs_fs_kernel.h> + #include <asm/segment.h> #include <asm/uaccess.h> #include <asm/types.h> @@ -53,6 +55,7 @@ static int nbd_sizes[MAX_NBD]; static u64 nbd_bytesizes[MAX_NBD]; static struct nbd_device nbd_dev[MAX_NBD]; +static devfs_handle_t devfs_handle = NULL; #define DEBUG( s ) /* #define DEBUG( s ) printk( s ) @@ -514,12 +517,20 @@ int nbd_init(void) register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &nbd_fops, nbd_bytesizes[i]>>9); } + devfs_handle = devfs_mk_dir (NULL, "nbd", 0, NULL); + devfs_register_series (devfs_handle, "%u", MAX_NBD, + DEVFS_FL_DEFAULT, MAJOR_NR, 0, + S_IFBLK | S_IRUSR | S_IWUSR, 0, 0, + &nbd_fops, NULL); + return 0; } #ifdef MODULE void cleanup_module(void) { + devfs_unregister (devfs_handle); + if (unregister_blkdev(MAJOR_NR, "nbd") != 0) printk("nbd: cleanup_module failed\n"); else diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c index 9c4cabbbffc871..2315e1d300c0cc 100644 --- a/drivers/block/paride/paride.c +++ b/drivers/block/paride/paride.c @@ -120,8 +120,8 @@ static void pi_claim( PIA *pi) pi->claimed = 1; #ifdef CONFIG_PARPORT if (pi->pardev) - while (parport_claim((struct pardevice *)(pi->pardev))) - sleep_on(&(pi->parq)); + wait_event (pi->parq, + !parport_claim ((struct pardevice *)pi->pardev)); #endif } diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 6c5a87e5c4c6ea..9b1ff3a32fe6d6 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -487,7 +487,7 @@ static int pd_open (struct inode *inode, struct file *file) MOD_INC_USE_COUNT; - while (!pd_valid) sleep_on(&pd_wait_open); + wait_event (pd_wait_open, pd_valid); PD.access++; diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index b4e36726c49fa1..3cb11286da1d6c 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -261,6 +261,7 @@ static char pg_scratch[512]; /* scratch block buffer */ /* kernel glue structures */ static struct file_operations pg_fops = { + owner: THIS_MODULE, read: pg_read, write: pg_write, open: pg_open, @@ -578,8 +579,6 @@ static int pg_open (struct inode *inode, struct file *file) return -EBUSY; } - MOD_INC_USE_COUNT; - if (PG.busy) { pg_reset(unit); PG.busy = 0; @@ -591,7 +590,6 @@ static int pg_open (struct inode *inode, struct file *file) PG.bufptr = kmalloc(PG_MAX_DATA,GFP_KERNEL); if (PG.bufptr == NULL) { PG.access--; - MOD_DEC_USE_COUNT; printk("%s: buffer allocation failed\n",PG.name); return -ENOMEM; } @@ -611,8 +609,6 @@ static int pg_release (struct inode *inode, struct file *file) kfree(PG.bufptr); PG.bufptr = NULL; - MOD_DEC_USE_COUNT; - return 0; } diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 459ef7237ab537..739755a93787ad 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -263,6 +263,7 @@ static char pt_scratch[512]; /* scratch block buffer */ /* kernel glue structures */ static struct file_operations pt_fops = { + owner: THIS_MODULE, read: pt_read, write: pt_write, ioctl: pt_ioctl, @@ -701,19 +702,15 @@ static int pt_open (struct inode *inode, struct file *file) return -EBUSY; } - MOD_INC_USE_COUNT; - pt_identify(unit); if (!PT.flags & PT_MEDIA) { PT.access--; - MOD_DEC_USE_COUNT; return -ENODEV; } if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) { PT.access--; - MOD_DEC_USE_COUNT; return -EROFS; } @@ -723,7 +720,6 @@ static int pt_open (struct inode *inode, struct file *file) PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL); if (PT.bufptr == NULL) { PT.access--; - MOD_DEC_USE_COUNT; printk("%s: buffer allocation failed\n",PT.name); return -ENOMEM; } @@ -786,8 +782,6 @@ static int pt_release (struct inode *inode, struct file *file) kfree(PT.bufptr); PT.bufptr = NULL; - MOD_DEC_USE_COUNT; - return 0; } diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index f38e102093bf83..802b04e89d7204 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -801,6 +801,16 @@ static int fd_eject(struct floppy_state *fs) return err; } +int swim3_fd_eject(int devnum) +{ + if (devnum >= floppy_count) + return -ENODEV; + /* Do not check this - this function should ONLY be called early + * in the boot process! */ + /* if (floppy_states[devnum].ref_count != 1) return -EBUSY; */ + return fd_eject(&floppy_states[devnum]); +} + static struct floppy_struct floppy_type = { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 74df1096ef0824..5ac2a16a6fc8fa 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -258,20 +258,19 @@ static int xd_open (struct inode *inode,struct file *file) { int dev = DEVICE_NR(inode->i_rdev); + MOD_INC_USE_COUNT; + if (dev < xd_drives) { while (!xd_valid[dev]) sleep_on(&xd_wait_open); -#ifdef MODULE - MOD_INC_USE_COUNT; -#endif /* MODULE */ - xd_access[dev]++; return (0); } - else - return -ENXIO; + + MOD_DEC_USE_COUNT; + return -ENXIO; } /* do_xd_request: handle an incoming request */ diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index e585bb34c4c2a6..74ea30a41ebcb2 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -165,12 +165,16 @@ z2_open( struct inode *inode, struct file *filp ) sizeof( z2ram_map[0] ); int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) * sizeof( z2ram_map[0] ); + int rc = -ENOMEM; + + MOD_INC_USE_COUNT; device = DEVICE_NR( inode->i_rdev ); if ( current_device != -1 && current_device != device ) { - return -EBUSY; + rc = -EBUSY; + goto err_out; } if ( current_device == -1 ) @@ -188,7 +192,7 @@ z2_open( struct inode *inode, struct file *filp ) if (index >= m68k_realnum_memory) { printk( KERN_ERR DEVICE_NAME ": no such entry in z2ram_map\n" ); - return -ENOMEM; + goto err_out; } paddr = m68k_memory[index].addr; @@ -215,7 +219,7 @@ z2_open( struct inode *inode, struct file *filp ) { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } while (size) { @@ -240,7 +244,7 @@ z2_open( struct inode *inode, struct file *filp ) { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } get_z2ram(); @@ -261,7 +265,7 @@ z2_open( struct inode *inode, struct file *filp ) { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } get_z2ram(); @@ -279,7 +283,7 @@ z2_open( struct inode *inode, struct file *filp ) { printk( KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n" ); - return -ENOMEM; + goto err_out; } get_chipram(); @@ -292,15 +296,17 @@ z2_open( struct inode *inode, struct file *filp ) break; default: - return -ENODEV; + rc = -ENODEV; + goto err_out; + + break; } if ( z2ram_size == 0 ) { - kfree( z2ram_map ); printk( KERN_NOTICE DEVICE_NAME ": no unused ZII/Chip RAM found\n" ); - return -ENOMEM; + goto err_out_kfree; } current_device = device; @@ -309,9 +315,13 @@ z2_open( struct inode *inode, struct file *filp ) blk_size[ MAJOR_NR ] = z2_sizes; } - MOD_INC_USE_COUNT; - return 0; + +err_out_kfree: + kfree( z2ram_map ); +err_out: + MOD_DEC_USE_COUNT; + return rc; } static int diff --git a/drivers/char/acquirewdt.c b/drivers/char/acquirewdt.c index 9d86479dc1ee13..eaa9e6bae6d6b7 100644 --- a/drivers/char/acquirewdt.c +++ b/drivers/char/acquirewdt.c @@ -125,7 +125,6 @@ static int acq_open(struct inode *inode, struct file *file) spin_unlock(&acq_lock); return -EBUSY; } - MOD_INC_USE_COUNT; /* * Activate */ @@ -150,7 +149,6 @@ static int acq_close(struct inode *inode, struct file *file) acq_is_open=0; spin_unlock(&acq_lock); } - MOD_DEC_USE_COUNT; return 0; } @@ -175,6 +173,7 @@ static int acq_notify_sys(struct notifier_block *this, unsigned long code, static struct file_operations acq_fops = { + owner: THIS_MODULE, read: acq_read, write: acq_write, ioctl: acq_ioctl, diff --git a/drivers/char/adbmouse.c b/drivers/char/adbmouse.c index a33693c1497dc1..a4108cf0ec42a9 100644 --- a/drivers/char/adbmouse.c +++ b/drivers/char/adbmouse.c @@ -132,20 +132,22 @@ static void adb_mouse_interrupt(unsigned char *buf, int nb) static int release_mouse(struct inode *inode, struct file *file) { adb_mouse_interrupt_hook = NULL; - MOD_DEC_USE_COUNT; + /* + * FIXME?: adb_mouse_interrupt_hook may still be executing + * on another CPU. + */ return 0; } static int open_mouse(struct inode *inode, struct file *file) { - MOD_INC_USE_COUNT; adb_mouse_interrupt_hook = adb_mouse_interrupt; return 0; } static struct busmouse adb_mouse = { - ADB_MOUSE_MINOR, "adbmouse", open_mouse, release_mouse, 7 + ADB_MOUSE_MINOR, "adbmouse", THIS_MODULE, open_mouse, release_mouse, 7 }; static int __init adb_mouse_init(void) diff --git a/drivers/char/agp/agpgart_fe.c b/drivers/char/agp/agpgart_fe.c index 66ec50b9f2e263..e67beef382a01f 100644 --- a/drivers/char/agp/agpgart_fe.c +++ b/drivers/char/agp/agpgart_fe.c @@ -1061,6 +1061,7 @@ ioctl_out: static struct file_operations agp_fops = { + owner: THIS_MODULE, llseek: agp_lseek, read: agp_read, write: agp_write, diff --git a/drivers/char/atarimouse.c b/drivers/char/atarimouse.c index a188320c2f7b02..ce084372596084 100644 --- a/drivers/char/atarimouse.c +++ b/drivers/char/atarimouse.c @@ -39,53 +39,50 @@ extern int atari_mouse_buttons; static void atari_mouse_interrupt(char *buf) { - int buttons; + int buttons; -/* ikbd_mouse_disable(); */ +/* ikbd_mouse_disable(); */ - buttons = ((buf[0] & 1) + buttons = ((buf[0] & 1) | ((buf[0] & 2) << 1) | (atari_mouse_buttons & 2)); - atari_mouse_buttons = buttons; + atari_mouse_buttons = buttons; - busmouse_add_movementbuttons(msedev, buf[1], -buf[2], buttons ^ 7); -/* ikbd_mouse_rel_pos(); */ + busmouse_add_movementbuttons(msedev, buf[1], -buf[2], buttons ^ 7); +/* ikbd_mouse_rel_pos(); */ } static int release_mouse(struct inode *inode, struct file *file) { - ikbd_mouse_disable(); - - atari_mouse_interrupt_hook = NULL; - MOD_DEC_USE_COUNT; - return 0; + ikbd_mouse_disable(); + atari_mouse_interrupt_hook = NULL; + return 0; } static int open_mouse(struct inode *inode, struct file *file) { - atari_mouse_buttons = 0; - ikbd_mouse_y0_top (); - ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]); - ikbd_mouse_rel_pos(); - MOD_INC_USE_COUNT; - atari_mouse_interrupt_hook = atari_mouse_interrupt; - return 0; + atari_mouse_buttons = 0; + ikbd_mouse_y0_top (); + ikbd_mouse_thresh (mouse_threshold[0], mouse_threshold[1]); + ikbd_mouse_rel_pos(); + atari_mouse_interrupt_hook = atari_mouse_interrupt; + return 0; } static struct busmouse atarimouse = { - ATARIMOUSE_MINOR, "atarimouse", open_mouse, release_mouse, 0 + ATARIMOUSE_MINOR, "atarimouse", THIS_MODULE, open_mouse, release_mouse, 0 }; static int __init atari_mouse_init(void) { - if (!MACH_IS_ATARI) - return -ENODEV; - msedev = register_busmouse(&atarimouse); - if (msedev < 0) - printk(KERN_WARNING "Unable to register Atari mouse driver.\n"); - else - printk(KERN_INFO "Atari mouse installed.\n"); - return msedev < 0 ? msedev : 0; + if (!MACH_IS_ATARI) + return -ENODEV; + msedev = register_busmouse(&atarimouse); + if (msedev < 0) + printk(KERN_WARNING "Unable to register Atari mouse driver.\n"); + else + printk(KERN_INFO "Atari mouse installed.\n"); + return msedev < 0 ? msedev : 0; } diff --git a/drivers/char/bttv.c b/drivers/char/bttv.c index dd9ca78c6fb7c9..e1cc54e3bd2490 100644 --- a/drivers/char/bttv.c +++ b/drivers/char/bttv.c @@ -64,7 +64,6 @@ static struct bttv bttvs[BTTV_MAX]; /* insmod args */ MODULE_PARM(triton1,"i"); -MODULE_PARM(remap,"1-4i"); MODULE_PARM(radio,"1-4i"); MODULE_PARM(card,"1-4i"); MODULE_PARM(pll,"1-4i"); @@ -76,6 +75,7 @@ MODULE_PARM(autoload,"i"); MODULE_PARM(gbuffers,"i"); MODULE_PARM(gbufsize,"i"); +EXPORT_SYMBOL(bttv_get_cardinfo); EXPORT_SYMBOL(bttv_get_id); EXPORT_SYMBOL(bttv_gpio_enable); EXPORT_SYMBOL(bttv_read_gpio); @@ -91,7 +91,6 @@ static unsigned int bigendian=1; static unsigned int bigendian=0; #endif static int triton1=0; -static unsigned long remap[BTTV_MAX]; static unsigned int radio[BTTV_MAX]; static unsigned int card[BTTV_MAX] = { 0, 0, 0, 0 }; static unsigned int pll[BTTV_MAX] = { -1, -1, -1, -1}; @@ -123,8 +122,19 @@ static unsigned int autoload = 0; /* gpio ports (IR for example) */ /* see bttv.h for comments */ +int bttv_get_cardinfo(unsigned int card, int *type, int *cardid) +{ + if (card >= bttv_num) { + return -1; + } + *type = bttvs[card].type; + *cardid = bttvs[card].cardid; + return 0; +} + int bttv_get_id(unsigned int card) { + printk("bttv_get_id is obsolete, use bttv_get_cardinfo instead\n"); if (card >= bttv_num) { return -1; } @@ -180,7 +190,7 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data) return 0; } -WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card) +wait_queue_head_t* bttv_get_gpio_queue(unsigned int card) { struct bttv *btv; @@ -467,7 +477,7 @@ static struct i2c_client i2c_client_template = { NULL }; -static int __init init_bttv_i2c(struct bttv *btv) +static int __devinit init_bttv_i2c(struct bttv *btv) { /* i2c bit_adapter */ memcpy(&btv->i2c_adap, &i2c_adap_template, sizeof(struct i2c_adapter)); @@ -489,7 +499,7 @@ static int __init init_bttv_i2c(struct bttv *btv) } /* read I2C */ -static int __init I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) +static int I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) { unsigned char buffer = 0; @@ -514,7 +524,7 @@ static int __init I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) } /* write I2C */ -static int __init I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, +static int I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, unsigned char b2, int both) { unsigned char buffer[2]; @@ -531,7 +541,7 @@ static int __init I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b } /* read EEPROM */ -static void __init readee(struct bttv *btv, unsigned char *eedata, int addr) +static void __devinit readee(struct bttv *btv, unsigned char *eedata, int addr) { int i; @@ -558,7 +568,7 @@ static struct HAUPPAUGE_TUNER int id; char *name; } -hauppauge_tuner[] __initdata = +hauppauge_tuner[] __devinitdata = { { TUNER_ABSENT, "" }, { TUNER_ABSENT, "External" }, @@ -606,7 +616,7 @@ hauppauge_tuner[] __initdata = { TUNER_ABSENT, "Temic 4046FM5" }, }; -static void __init hauppauge_eeprom(struct bttv *btv) +static void __devinit hauppauge_eeprom(struct bttv *btv) { if (eeprom_data[9] < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { @@ -615,11 +625,9 @@ static void __init hauppauge_eeprom(struct bttv *btv) printk("bttv%d: Hauppauge eeprom: tuner=%s (%d)\n",btv->nr, hauppauge_tuner[eeprom_data[9]].name,btv->tuner_type); } - - return; } -static void __init hauppauge_boot_msp34xx(struct bttv *btv) +static void __devinit hauppauge_boot_msp34xx(struct bttv *btv) { int i; @@ -655,7 +663,7 @@ static void __init hauppauge_boot_msp34xx(struct bttv *btv) /* This is basically the same procedure as * used by Alessandro Rubini in his pxc200 * driver, but using BTTV functions */ -static void __init init_PXC200(struct bttv *btv) +static void __devinit init_PXC200(struct bttv *btv) { static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, @@ -705,7 +713,7 @@ static struct CARD { unsigned id; int cardnr; char *name; -} cards[] __initdata = { +} cards[] __devinitdata = { { 0x00011002, BTTV_HAUPPAUGE878, "ATI TV Wonder" }, { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, @@ -813,7 +821,7 @@ static struct tvcard tvcards[] = /* 0x10 */ { "Pixelview PlayTV (bt878)", - 3, 1, 0, 2, 0x01fe00, { 2, 0, 1, 1}, + 3, 1, 0, 2, 0x01fe00, { 2, 3, 1, 1}, { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },0, 1,1,1,1,0,0,0,1, PLL_28, -1 }, { "Leadtek WinView 601", @@ -910,10 +918,18 @@ static struct tvcard tvcards[] = { "ProVideo PV951", /* pic16c54 */ 3, 1, 0, 2, 0, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0},0, 0,0,0,0,0,0,0,0, PLL_28, 1 }, + { "Little OnAir TV", + 3, 1, 0, 2, 0xe00b, {2, 3, 1, 1}, + {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},0, + 0,0,0,0,0,0,0,0, PLL_NONE, -1 }, + + { "Sigma TVII-FM", + 2, 1, 0, -1, 3, {2, 3, 1, 1}, {1, 1, 0, 2, 3},0, + 0,0,0,0,0,0,0,0, PLL_NONE, -1 }, }; #define TVCARDS (sizeof(tvcards)/sizeof(struct tvcard)) -static void __init dump_eeprom(struct bttv *btv,int addr) +static void __devinit dump_eeprom(struct bttv *btv,int addr) { int i; @@ -930,7 +946,7 @@ static void __init dump_eeprom(struct bttv *btv,int addr) } } -static int __init idcard_eeprom(struct bttv *btv) +static int __devinit idcard_eeprom(struct bttv *btv) { unsigned id; int i,n; @@ -943,6 +959,7 @@ static int __init idcard_eeprom(struct bttv *btv) return -1; /* look for the card */ + btv->cardid = id; for (n = -1, i = 0; cards[i].id != 0; i++) if (cards[i].id == id) n = i; @@ -1203,7 +1220,7 @@ static void make_vbitab(struct bttv *btv) unsigned int *po=(unsigned int *) btv->vbi_odd; unsigned int *pe=(unsigned int *) btv->vbi_even; - if (debug) + if (debug > 1) printk("bttv%d: vbi1: po=%08lx pe=%08lx\n", btv->nr,virt_to_bus(po), virt_to_bus(pe)); @@ -1225,7 +1242,7 @@ static void make_vbitab(struct bttv *btv) *(pe++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(0x01<<16)); *(pe++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+10)); - if (debug) + if (debug > 1) printk("bttv%d: vbi2: po=%08lx pe=%08lx\n", btv->nr,virt_to_bus(po), virt_to_bus(pe)); } @@ -1302,7 +1319,7 @@ static int make_prisctab(struct bttv *btv, unsigned int *ro, unsigned long vadr=(unsigned long) vbuf; int shift, csize; - if (debug) + if (debug > 1) printk("bttv%d: prisc1: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1399,7 +1416,7 @@ static int make_prisctab(struct bttv *btv, unsigned int *ro, *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16)); *(re++)=cpu_to_le32(btv->bus_vbi_odd); - if (debug) + if (debug > 1) printk("bttv%d: prisc2: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1424,7 +1441,7 @@ static int make_vrisctab(struct bttv *btv, unsigned int *ro, if (palette>=VIDEO_PALETTE_PLANAR) return make_prisctab(btv, ro, re, vbuf, width, height, palette); - if (debug) + if (debug > 1) printk("bttv%d: vrisc1: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1476,7 +1493,7 @@ static int make_vrisctab(struct bttv *btv, unsigned int *ro, *(re++)=cpu_to_le32(BT848_RISC_JUMP|BT848_RISC_IRQ|(2<<16)); *(re++)=cpu_to_le32(btv->bus_vbi_odd); - if (debug) + if (debug > 1) printk("bttv%d: vrisc2: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); @@ -1494,7 +1511,7 @@ static void clip_draw_rectangle(unsigned char *clipmap, int x, int y, int w, int int W, l, r; int i; - if (debug) + if (debug > 1) printk("bttv clip: %dx%d+%d+%d\n",w,h,x,y); /* bitmap is fixed width, 128 bytes (1024 pixels represented) */ @@ -1559,7 +1576,7 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr) inter=(btv->win.interlace&1)^1; width=btv->win.width; height=btv->win.height; - if (debug) + if (debug > 1) printk("bttv%d: clip1: pal=%d size=%dx%d, bpl=%d bpp=%d\n", btv->nr,btv->picture.palette,width,height,bpl,bpp); if(width > 1023) @@ -1573,7 +1590,7 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr) printk("bttv%d: clip: ro=%08lx re=%08lx\n", btv->nr,virt_to_bus(ro), virt_to_bus(re)); - if ((clipmap=vmalloc(VIDEO_CLIPMAP_SIZE))==NULL) { + if ((clipmap=vmalloc_32(VIDEO_CLIPMAP_SIZE))==NULL) { /* can't clip, don't generate any risc code */ *(ro++)=cpu_to_le32(BT848_RISC_JUMP); *(ro++)=cpu_to_le32(btv->bus_vbi_even); @@ -1668,7 +1685,7 @@ static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr) *(re++)=cpu_to_le32(BT848_RISC_JUMP); *(re++)=cpu_to_le32(btv->bus_vbi_odd); - if (debug) + if (debug > 1) printk("bttv%d: clip2: pal=%d size=%dx%d, bpl=%d bpp=%d\n", btv->nr,btv->picture.palette,width,height,bpl,bpp); } @@ -1734,9 +1751,6 @@ static void bt848_set_geo(struct bttv *btv, u16 ewidth, eheight, owidth, oheight; u16 format, bswap; struct tvnorm *tvn; - unsigned long flags; - - spin_lock_irqsave(&btv->s_lock, flags); tvn=&tvnorms[btv->win.norm]; @@ -1789,8 +1803,6 @@ static void bt848_set_geo(struct bttv *btv, btwrite(format, BT848_COLOR_FMT); btwrite(bswap | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); - - spin_unlock_irqrestore(&btv->s_lock, flags); } @@ -1847,7 +1859,6 @@ static void bt848_set_winsize(struct bttv *btv) /* * Grab into virtual memory. - * Currently only does double buffering. Do we need more? */ static int vgrab(struct bttv *btv, struct video_mmap *mp) @@ -1904,16 +1915,16 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp) btv->gbuf[mp->frame].ro = 0; #endif - if (btv->gq_in == btv->gq_out) { + if (-1 == btv->gq_grab && btv->gq_in == btv->gq_out) { btv->gq_start = 1; btv->risc_jmp[12]=cpu_to_le32(BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ); } btv->gqueue[btv->gq_in++] = mp->frame; btv->gq_in = btv->gq_in % MAX_GBUFFERS; - spin_unlock_irqrestore(&btv->s_lock, flags); btor(3, BT848_CAP_CTL); btor(3, BT848_GPIO_DMA_CTL); + spin_unlock_irqrestore(&btv->s_lock, flags); return 0; } @@ -1927,39 +1938,43 @@ static long bttv_read(struct video_device *v, char *buf, unsigned long count, in { struct bttv *btv= (struct bttv *)v; int q,todo; + DECLARE_WAITQUEUE(wait, current); /* BROKEN: RETURNS VBI WHEN IT SHOULD RETURN GRABBED VIDEO FRAME */ todo=count; while (todo && todo>(q=VBIBUF_SIZE-btv->vbip)) { - unsigned long flags; - if(copy_to_user((void *) buf, (void *) btv->vbibuf+btv->vbip, q)) return -EFAULT; todo-=q; buf+=q; - spin_lock_irqsave(&btv->s_lock, flags); + add_wait_queue(&btv->vbiq, &wait); + current->state = TASK_INTERRUPTIBLE; if (todo && q==VBIBUF_SIZE-btv->vbip) { if(nonblock) { - spin_unlock_irqrestore(&btv->s_lock, flags); + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; if(count==todo) return -EWOULDBLOCK; return count-todo; } - spin_unlock_irqrestore(&btv->s_lock, flags); - interruptible_sleep_on(&btv->vbiq); + schedule(); if(signal_pending(current)) { + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; + if(todo==count) return -EINTR; else return count-todo; } - } else - spin_unlock_irqrestore(&btv->s_lock, flags); + } + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; } if (todo) { @@ -1980,9 +1995,11 @@ static inline void burst(int on) static void bt848_restart(struct bttv *btv) { + unsigned long irq_flags; + if (verbose) printk("bttv%d: resetting chip\n",btv->nr); - btwrite(~0x0UL, BT848_INT_STAT); + btwrite(0xfffffUL, BT848_INT_STAT); btand(~15, BT848_GPIO_DMA_CTL); btwrite(0, BT848_SRESET); btwrite(virt_to_bus(btv->risc_jmp+2), @@ -1994,8 +2011,10 @@ static void bt848_restart(struct bttv *btv) btv->errors = 0; btv->needs_restart = 0; + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_geo(btv,0); bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } /* @@ -2042,13 +2061,16 @@ static int bttv_open(struct video_device *dev, int flags) static void bttv_close(struct video_device *dev) { struct bttv *btv=(struct bttv *)dev; + unsigned long irq_flags; down(&btv->lock); btv->user--; + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->scr_on = 0; btv->risc_cap_odd = 0; btv->risc_cap_even = 0; bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); /* * A word of warning. At this point the chip @@ -2133,9 +2155,11 @@ static inline void bt848_sat_v(struct bttv *btv, unsigned long data) static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) { struct bttv *btv=(struct bttv *)dev; + unsigned long irq_flags; int i,ret = 0; - if (debug) printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd); + if (debug > 1) + printk("bttv%d: ioctl 0x%x\n",btv->nr,cmd); switch (cmd) { case VIDIOCGCAP: @@ -2206,7 +2230,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) if (btv->win.norm != v.norm) { btv->win.norm = v.norm; make_vbitab(btv); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_winsize(btv); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } up(&btv->lock); return 0; @@ -2248,7 +2274,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) down(&btv->lock); set_pll(btv); make_vbitab(btv); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_winsize(btv); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); up(&btv->lock); } return 0; @@ -2289,12 +2317,13 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) if(copy_from_user(&vw,arg,sizeof(vw))) return -EFAULT; + down(&btv->lock); if(vw.flags || vw.width < 16 || vw.height < 16) { - down(&btv->lock); + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->scr_on = 0; bt848_set_risc_jmps(btv,-1); - up(&btv->lock); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); return -EINVAL; } if (btv->win.bpp < 4) @@ -2302,18 +2331,17 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) vw.x = (vw.x + 3) & ~3; vw.width &= ~3; } - down(&btv->lock); if (btv->needs_restart) bt848_restart(btv); btv->win.x=vw.x; btv->win.y=vw.y; btv->win.width=vw.width; btv->win.height=vw.height; - + + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_risc_jmps(btv,0); - bt848_set_winsize(btv); - up(&btv->lock); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); /* * Do any clips. @@ -2337,11 +2365,12 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) return -EFAULT; } } - down(&btv->lock); make_clip_tab(btv, vcp, vw.clipcount); if (vw.clipcount != 0) vfree(vcp); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); up(&btv->lock); return 0; } @@ -2370,13 +2399,13 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) return -EINVAL; if (btv->win.width==0 || btv->win.height==0) return -EINVAL; - down(&btv->lock); + spin_lock_irqsave(&btv->s_lock, irq_flags); if (v == 1 && btv->win.vidadr != 0) btv->scr_on = 1; if (v == 0) btv->scr_on = 0; bt848_set_risc_jmps(btv,-1); - up(&btv->lock); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); return 0; } case VIDIOCGFBUF: @@ -2500,9 +2529,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) if(!(v.flags&VIDEO_AUDIO_MUTE)) audio(btv, AUDIO_UNMUTE, 1); - up(&btv->lock); call_i2c_clients(btv,cmd,&v); - down(&btv->lock); if (btv->type == BTTV_TERRATV) { unsigned int con = 0; @@ -2554,6 +2581,9 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) } case VIDIOCSYNC: + { + DECLARE_WAITQUEUE(wait, current); + if(copy_from_user((void *)&i,arg,sizeof(int))) return -EFAULT; if (i < 0 || i >= gbuffers) @@ -2563,13 +2593,20 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) ret = -EINVAL; break; case GBUFFER_GRABBING: + add_wait_queue(&btv->capq, &wait); + current->state = TASK_INTERRUPTIBLE; while(btv->gbuf[i].stat==GBUFFER_GRABBING) { if (debug) printk("bttv%d: cap sync: sleep on %d\n",btv->nr,i); - interruptible_sleep_on(&btv->capq); - if(signal_pending(current)) + schedule(); + if(signal_pending(current)) { + remove_wait_queue(&btv->capq, &wait); + current->state = TASK_RUNNING; return -EINTR; + } } + remove_wait_queue(&btv->capq, &wait); + current->state = TASK_RUNNING; /* fall throuth */ case GBUFFER_DONE: case GBUFFER_ERROR: @@ -2584,6 +2621,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) up(&btv->lock); } return ret; + } case BTTV_FIELDNR: if(copy_to_user((void *) arg, (void *) &btv->last_field, @@ -2602,7 +2640,6 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg) btv->pll.pll_ofreq = p.pll_ofreq; btv->pll.pll_crystal = p.pll_crystal; up(&btv->lock); - break; } @@ -2749,12 +2786,11 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count, { struct bttv *btv=(struct bttv *)(v-2); int q,todo; + DECLARE_WAITQUEUE(wait, current); todo=count; while (todo && todo>(q=VBIBUF_SIZE-btv->vbip)) { - unsigned long flags; - if (btv->needs_restart) { down(&btv->lock); bt848_restart(btv); @@ -2765,27 +2801,31 @@ static long vbi_read(struct video_device *v, char *buf, unsigned long count, todo-=q; buf+=q; - spin_lock_irqsave(&btv->s_lock, flags); + add_wait_queue(&btv->vbiq, &wait); + current->state = TASK_INTERRUPTIBLE; if (todo && q==VBIBUF_SIZE-btv->vbip) { if(nonblock) { - spin_unlock_irqrestore(&btv->s_lock, flags); + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; if(count==todo) return -EWOULDBLOCK; return count-todo; } - spin_unlock_irqrestore(&btv->s_lock, flags); - interruptible_sleep_on(&btv->vbiq); + schedule(); if(signal_pending(current)) { + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; if(todo==count) return -EINTR; else return count-todo; } - } else - spin_unlock_irqrestore(&btv->s_lock, flags); + } + remove_wait_queue(&btv->vbiq, &wait); + current->state = TASK_RUNNING; } if (todo) { @@ -2813,15 +2853,18 @@ static unsigned int vbi_poll(struct video_device *dev, struct file *file, static int vbi_open(struct video_device *dev, int flags) { struct bttv *btv=(struct bttv *)(dev-2); + unsigned long irq_flags; MOD_INC_USE_COUNT; - down(&btv->lock); if (btv->needs_restart) bt848_restart(btv); + set_pll(btv); btv->vbip=VBIBUF_SIZE; + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->vbi_on = 1; bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); up(&btv->lock); return 0; @@ -2830,12 +2873,12 @@ static int vbi_open(struct video_device *dev, int flags) static void vbi_close(struct video_device *dev) { struct bttv *btv=(struct bttv *)(dev-2); + unsigned long irq_flags; - down(&btv->lock); + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->vbi_on = 0; bt848_set_risc_jmps(btv,-1); - up(&btv->lock); - + spin_unlock_irqrestore(&btv->s_lock, irq_flags); MOD_DEC_USE_COUNT; } @@ -3018,7 +3061,7 @@ static struct video_device radio_template= #define TRITON_PEER_CONCURRENCY (1<<3) -static void __init handle_chipset(void) +static void __devinit handle_chipset(void) { struct pci_dev *dev = NULL; @@ -3050,7 +3093,7 @@ static void __init handle_chipset(void) /* can tda9855.c handle this too maybe? */ -static void __init init_tda9840(struct bttv *btv) +static void __devinit init_tda9840(struct bttv *btv) { /* Horrible Hack */ I2CWrite(btv, I2C_TDA9840, TDA9840_SW, 0x2a, 1); /* sound mode switching */ @@ -3066,12 +3109,11 @@ static void __init init_tda9840(struct bttv *btv) /* Figure out card and tuner type */ -static void __init idcard(struct bttv *btv) +static void __devinit idcard(struct bttv *btv) { int type,eeprom = 0; btwrite(0, BT848_GPIO_OUT_EN); - DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", btv->nr, btread(BT848_GPIO_DATA))); /* Default the card to the user-selected one. */ if (card[btv->nr] >= 0 && card[btv->nr] < TVCARDS) @@ -3114,7 +3156,6 @@ static void __init idcard(struct bttv *btv) (btv->id==848 && btv->revision==0x12) ? "A" : "", tvcards[btv->type].name); printk(KERN_INFO "bttv%d: model: %s\n",btv->nr,btv->video_dev.name); - /* board specific initialisations */ if (btv->type == BTTV_MIRO || btv->type == BTTV_MIROPRO) { @@ -3228,10 +3269,6 @@ static void __init idcard(struct bttv *btv) static void bt848_set_risc_jmps(struct bttv *btv, int flags) { - unsigned long irq_flags; - - spin_lock_irqsave(&btv->s_lock, irq_flags); - if (-1 == flags) { /* defaults */ flags = 0; @@ -3241,8 +3278,9 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags) flags |= 0x0c; } - if (debug) printk("bttv%d: set_risc_jmp %08lx:", - btv->nr,virt_to_bus(btv->risc_jmp)); + if (debug > 1) + printk("bttv%d: set_risc_jmp %08lx:", + btv->nr,virt_to_bus(btv->risc_jmp)); /* Sync to start of odd field */ btv->risc_jmp[0]=cpu_to_le32(BT848_RISC_SYNC|BT848_RISC_RESYNC @@ -3252,24 +3290,29 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags) /* Jump to odd vbi sub */ btv->risc_jmp[2]=cpu_to_le32(BT848_RISC_JUMP|(0xd<<20)); if (flags&8) { - if (debug) printk(" ev=%08lx",virt_to_bus(btv->vbi_odd)); + if (debug > 1) + printk(" ev=%08lx",virt_to_bus(btv->vbi_odd)); btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->vbi_odd)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[3]=cpu_to_le32(virt_to_bus(btv->risc_jmp+4)); } /* Jump to odd sub */ btv->risc_jmp[4]=cpu_to_le32(BT848_RISC_JUMP|(0xe<<20)); if (0 != btv->risc_cap_odd) { - if (debug) printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd); + if (debug > 1) + printk(" e%d=%08x",btv->gq_grab,btv->risc_cap_odd); flags |= 3; btv->risc_jmp[5]=cpu_to_le32(btv->risc_cap_odd); } else if (flags&2) { - if (debug) printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd)); + if (debug > 1) + printk(" eo=%08lx",virt_to_bus(btv->risc_scr_odd)); btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_scr_odd)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[5]=cpu_to_le32(virt_to_bus(btv->risc_jmp+6)); } @@ -3282,24 +3325,29 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags) /* Jump to even vbi sub */ btv->risc_jmp[8]=cpu_to_le32(BT848_RISC_JUMP); if (flags&4) { - if (debug) printk(" ov=%08lx",virt_to_bus(btv->vbi_even)); + if (debug > 1) + printk(" ov=%08lx",virt_to_bus(btv->vbi_even)); btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->vbi_even)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[9]=cpu_to_le32(virt_to_bus(btv->risc_jmp+10)); } /* Jump to even sub */ btv->risc_jmp[10]=cpu_to_le32(BT848_RISC_JUMP|(8<<20)); if (0 != btv->risc_cap_even) { - if (debug) printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even); + if (debug > 1) + printk(" o%d=%08x",btv->gq_grab,btv->risc_cap_even); flags |= 3; btv->risc_jmp[11]=cpu_to_le32(btv->risc_cap_even); } else if (flags&1) { - if (debug) printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even)); + if (debug > 1) + printk(" oo=%08lx",virt_to_bus(btv->risc_scr_even)); btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_scr_even)); } else { - if (debug) printk(" -----------"); + if (debug > 1) + printk(" -----------"); btv->risc_jmp[11]=cpu_to_le32(virt_to_bus(btv->risc_jmp+12)); } @@ -3311,18 +3359,17 @@ static void bt848_set_risc_jmps(struct bttv *btv, int flags) btv->risc_jmp[13]=cpu_to_le32(virt_to_bus(btv->risc_jmp)); /* enable cpaturing and DMA */ - if (debug) printk(" flags=0x%x dma=%s\n", - flags,(flags&0x0f) ? "on" : "off"); + if (debug > 1) + printk(" flags=0x%x dma=%s\n", + flags,(flags&0x0f) ? "on" : "off"); btaor(flags, ~0x0f, BT848_CAP_CTL); if (flags&0x0f) bt848_dma(btv, 3); else bt848_dma(btv, 0); - - spin_unlock_irqrestore(&btv->s_lock, irq_flags); } -static int __init init_video_dev(struct bttv *btv) +static int __devinit init_video_dev(struct bttv *btv) { memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template)); memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template)); @@ -3349,9 +3396,10 @@ static int __init init_video_dev(struct bttv *btv) return 1; } -static int __init init_bt848(struct bttv *btv) +static int __devinit init_bt848(struct bttv *btv) { int j; + unsigned long irq_flags; btv->user=0; init_MUTEX(&btv->lock); @@ -3412,14 +3460,13 @@ static int __init init_bt848(struct bttv *btv) return -1; if (!(btv->risc_jmp =(unsigned int *) kmalloc(2048, GFP_KERNEL))) return -1; - DEBUG(printk(KERN_DEBUG "risc_jmp: %p\n",btv->risc_jmp)); btv->vbi_odd=btv->risc_jmp+16; btv->vbi_even=btv->vbi_odd+256; btv->bus_vbi_odd=virt_to_bus(btv->risc_jmp+12); btv->bus_vbi_even=virt_to_bus(btv->risc_jmp+6); btwrite(virt_to_bus(btv->risc_jmp+2), BT848_RISC_STRT_ADD); - btv->vbibuf=(unsigned char *) vmalloc(VBIBUF_SIZE); + btv->vbibuf=(unsigned char *) vmalloc_32(VBIBUF_SIZE); if (!btv->vbibuf) return -1; if (!(btv->gbuf = kmalloc(sizeof(struct bttv_gbuf)*gbuffers,GFP_KERNEL))) @@ -3475,7 +3522,7 @@ static int __init init_bt848(struct bttv *btv) btwrite(0x00, BT848_O_SCLOOP); /* clear interrupt status */ - btwrite(~0x0UL, BT848_INT_STAT); + btwrite(0xfffffUL, BT848_INT_STAT); /* set interrupt mask */ btwrite(btv->triton1| @@ -3489,8 +3536,10 @@ static int __init init_bt848(struct bttv *btv) BT848_INT_MASK); make_vbitab(btv); + spin_lock_irqsave(&btv->s_lock, irq_flags); bt848_set_risc_jmps(btv,-1); - + spin_unlock_irqrestore(&btv->s_lock, irq_flags); + /* * Now add the template and register the device unit. */ @@ -3505,7 +3554,8 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) u32 dstat; int count,i; struct bttv *btv; - + unsigned long irq_flags; + btv=(struct bttv *)dev_id; count=0; while (1) @@ -3515,6 +3565,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) astat=stat&btread(BT848_INT_MASK); if (!astat) return; + btwrite(astat,BT848_INT_STAT); IDEBUG(printk ("bttv%d: astat=%08x\n", btv->nr, astat)); IDEBUG(printk ("bttv%d: stat=%08x\n", btv->nr, stat)); @@ -3550,15 +3601,18 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) btread(BT848_RISC_COUNT)); btv->errors++; if (btv->errors < BTTV_ERRORS) { + spin_lock_irqsave(&btv->s_lock, irq_flags); btand(~15, BT848_GPIO_DMA_CTL); btwrite(virt_to_bus(btv->risc_jmp+2), BT848_RISC_STRT_ADD); bt848_set_geo(btv,0); bt848_set_risc_jmps(btv,-1); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } else { if (verbose) printk("bttv%d: aiee: error loops\n",btv->nr); /* cancel all outstanding grab requests */ + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->gq_in = 0; btv->gq_out = 0; btv->gq_grab = -1; @@ -3569,8 +3623,9 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) btv->risc_cap_odd = 0; btv->risc_cap_even = 0; bt848_set_risc_jmps(btv,0); - btv->needs_restart = 1; + spin_unlock_irqrestore(&btv->s_lock, irq_flags); + wake_up_interruptible(&btv->vbiq); wake_up_interruptible(&btv->capq); } @@ -3596,6 +3651,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) if (debug) printk("bttv%d: cap irq: done %d\n",btv->nr,btv->gq_grab); do_gettimeofday(&btv->gbuf[btv->gq_grab].tv); + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->gbuf[btv->gq_grab].stat = GBUFFER_DONE; btv->gq_grab = -1; if (btv->gq_in != btv->gq_out) @@ -3618,22 +3674,25 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) btwrite(btv->fb_color_ctl | BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); } + spin_unlock_irqrestore(&btv->s_lock, irq_flags); wake_up_interruptible(&btv->capq); break; } if (stat&(8<<28)) { + spin_lock_irqsave(&btv->s_lock, irq_flags); btv->gq_start = 0; btv->gq_grab = btv->gqueue[btv->gq_out++]; btv->gq_out = btv->gq_out % MAX_GBUFFERS; if (debug) - printk("bttv%d: cap irq: capture %d\n",btv->nr,btv->gq_grab); + printk("bttv%d: cap irq: capture %d [start]\n",btv->nr,btv->gq_grab); btv->risc_cap_odd = btv->gbuf[btv->gq_grab].ro; btv->risc_cap_even = btv->gbuf[btv->gq_grab].re; bt848_set_risc_jmps(btv,-1); bt848_set_geo(btv,0); btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); + spin_unlock_irqrestore(&btv->s_lock, irq_flags); } } if (astat&BT848_INT_OCERR) @@ -3676,9 +3735,6 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) { IDEBUG(printk ("bttv%d: IRQ_I2CDONE\n", btv->nr)); } - - btwrite(astat,BT848_INT_STAT); - count++; if (count > 10) printk (KERN_WARNING "bttv%d: irq loop %d\n", @@ -3698,11 +3754,11 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs) * Scan for a Bt848 card, request the irq and map the io memory */ -static void __init bttv_remove(struct pci_dev *pci_dev) +static void __devinit bttv_remove(struct pci_dev *pci_dev) { u8 command; int j; - struct bttv *btv = pci_dev->driver_data; + struct bttv *btv = PCI_GET_DRIVER_DATA(pci_dev); /* unregister i2c_bus */ i2c_bit_del_bus(&btv->i2c_adap); @@ -3767,7 +3823,7 @@ static void __init bttv_remove(struct pci_dev *pci_dev) } -static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) +static int __devinit bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { int result; unsigned char command; @@ -3788,20 +3844,17 @@ static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pc btv->vbi_even=NULL; init_waitqueue_head(&btv->vbiq); init_waitqueue_head(&btv->capq); - init_waitqueue_head(&btv->capqo); - init_waitqueue_head(&btv->capqe); btv->vbip=VBIBUF_SIZE; - - init_waitqueue_head(&btv->gpioq); btv->s_lock = SPIN_LOCK_UNLOCKED; + init_waitqueue_head(&btv->gpioq); btv->shutdown=0; btv->id=dev->device; btv->irq=dev->irq; - btv->bt848_adr=pci_resource_start(dev, 0); + btv->bt848_adr=pci_resource_start(dev,0); if (pci_enable_device(dev)) return -EIO; - if (!request_mem_region(btv->bt848_adr, + if (!request_mem_region(pci_resource_start(dev,0), pci_resource_len(dev,0), "bttv")) { return -EBUSY; @@ -3871,24 +3924,23 @@ static int __init bttv_probe(struct pci_dev *dev, const struct pci_device_id *pc } } - dev->driver_data = btv; + PCI_SET_DRIVER_DATA(dev,btv); if(init_bt848(btv) < 0) { bttv_remove(dev); return -EIO; } - bttv_num++; return 0; fail: - release_mem_region(btv->bt848_adr, + release_mem_region(pci_resource_start(btv->dev,0), pci_resource_len(btv->dev,0)); return result; } -static struct pci_device_id bttv_pci_tbl[] __initdata = { +static struct pci_device_id bttv_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, @@ -3903,13 +3955,13 @@ static struct pci_device_id bttv_pci_tbl[] __initdata = { MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); static struct pci_driver bttv_pci_driver = { - name:"bttv", - id_table:bttv_pci_tbl, - probe:bttv_probe, - remove:bttv_remove, + name: "bttv", + id_table: bttv_pci_tbl, + probe: bttv_probe, + remove: bttv_remove, }; -static int __init bttv_init_module(void) +int bttv_init_module(void) { bttv_num = 0; @@ -3930,10 +3982,10 @@ static int __init bttv_init_module(void) return pci_module_init(&bttv_pci_driver); } -static void __exit bttv_cleanup_module(void) +void bttv_cleanup_module(void) { pci_unregister_driver(&bttv_pci_driver); - return; + return; } module_init(bttv_init_module); diff --git a/drivers/char/bttv.h b/drivers/char/bttv.h index 3f4229fe89ce69..9189bfa777d6dc 100644 --- a/drivers/char/bttv.h +++ b/drivers/char/bttv.h @@ -21,7 +21,12 @@ #ifndef _BTTV_H_ #define _BTTV_H_ -#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,28) +#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,31) + +#ifndef PCI_GET_DRIVER_DATA +# define PCI_GET_DRIVER_DATA(pdev) ((pdev)->driver_data) +# define PCI_SET_DRIVER_DATA(pdev,data) (((pdev)->driver_data) = (data)) +#endif /* PCI_GET_DRIVER_DATA */ #include <linux/types.h> #include <linux/wait.h> @@ -32,12 +37,13 @@ #include "audiochip.h" #include "bt848.h" -#define WAIT_QUEUE wait_queue_head_t - -/* returns card type, +/* returns card type + card ID (for bt878-based ones) for possible values see lines below beginning with #define BTTV_UNKNOWN returns negative value if error ocurred */ +extern int bttv_get_cardinfo(unsigned int card, int *type, int *cardid); + +/* obsolete, use bttv_get_cardinfo instead */ extern int bttv_get_id(unsigned int card); /* sets GPOE register (BT848_GPIO_OUT_EN) to new value: @@ -68,7 +74,7 @@ extern int bttv_write_gpio(unsigned int card, WARNING: because there is no buffer for GPIO data, one MUST process data ASAP */ -extern WAIT_QUEUE* bttv_get_gpio_queue(unsigned int card); +extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card); #ifndef O_NONCAP @@ -130,6 +136,7 @@ struct bttv { struct video_picture picture; /* Current picture params */ struct video_audio audio_dev; /* Current audio params */ + spinlock_t s_lock; struct semaphore lock; int user; int capuser; @@ -143,8 +150,6 @@ struct bttv { int tuner_type; int channel; - - spinlock_t s_lock; unsigned int nr; unsigned short id; @@ -160,6 +165,7 @@ struct bttv { struct bttv_window win; int fb_color_ctl; int type; /* card type */ + int cardid; int audio; /* audio mode */ int audio_chip; /* set to one of the chips supported by bttv.c */ int radio; @@ -169,10 +175,8 @@ struct bttv { u32 *vbi_even; u32 bus_vbi_even; u32 bus_vbi_odd; - WAIT_QUEUE vbiq; - WAIT_QUEUE capq; - WAIT_QUEUE capqo; - WAIT_QUEUE capqe; + wait_queue_head_t vbiq; + wait_queue_head_t capq; int vbip; u32 *risc_scr_odd; @@ -198,7 +202,7 @@ struct bttv { int errors; int needs_restart; - WAIT_QUEUE gpioq; + wait_queue_head_t gpioq; int shutdown; }; #endif @@ -277,6 +281,8 @@ extern __inline__ void io_st_le32(volatile unsigned *addr, unsigned val) #define BTTV_STB2 0x28 #define BTTV_AVPHONE98 0x29 #define BTTV_PV951 0x2a +#define BTTV_ONAIR_TV 0x2b +#define BTTV_SIGMA_TVII_FM 0x2c #define PLL_NONE 0 #define PLL_28 1 diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c index 1b09081c119f3a..5051e80baf17e1 100644 --- a/drivers/char/busmouse.c +++ b/drivers/char/busmouse.c @@ -171,13 +171,13 @@ static int busmouse_release(struct inode *inode, struct file *file) busmouse_fasync(-1, file, 0); if (--mse->active == 0) { - if (mse->ops && - mse->ops->release) - ret = mse->ops->release(inode, file); - + if (mse->ops) { + if (mse->ops->release) + ret = mse->ops->release(inode, file); + if (mse->ops->owner) + __MOD_DEC_USE_COUNT(mse->ops->owner); + } mse->ready = 0; - - MOD_DEC_USE_COUNT; } return ret; @@ -192,16 +192,20 @@ static int busmouse_open(struct inode *inode, struct file *file) mousedev = DEV_TO_MOUSE(inode->i_rdev); if (mousedev >= NR_MICE) return -EINVAL; - + down(&mouse_sem); mse = busmouse_data[mousedev]; if (!mse) /* shouldn't happen, but... */ goto end; - if (mse->ops && - mse->ops->open) + if (mse->ops && mse->ops->owner) + __MOD_INC_USE_COUNT(mse->ops->owner); + if (mse->ops && mse->ops->open) { ret = mse->ops->open(inode, file); + if (ret && mse->ops->owner) + __MOD_DEC_USE_COUNT(mse->ops->owner); + } if (ret) goto end; @@ -211,8 +215,6 @@ static int busmouse_open(struct inode *inode, struct file *file) if (mse->active++) goto end; - MOD_INC_USE_COUNT; - spin_lock_irq(&mse->lock); mse->ready = 0; @@ -333,6 +335,7 @@ static unsigned int busmouse_poll(struct file *file, poll_table *wait) struct file_operations busmouse_fops= { + owner: THIS_MODULE, read: busmouse_read, write: busmouse_write, poll: busmouse_poll, diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 48047a637509d8..cf4bb1f8381a70 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -1,7 +1,8 @@ #undef BLOCKMOVE #define Z_WAKE +#undef Z_EXT_CHARS_IN_BUFFER static char rcsid[] = -"$Revision: 2.3.2.6 $$Date: 2000/05/05 13:56:05 $"; +"$Revision: 2.3.2.7 $$Date: 2000/06/01 18:26:34 $"; /* * linux/drivers/char/cyclades.c @@ -24,6 +25,12 @@ static char rcsid[] = * This version supports shared IRQ's (only for PCI boards). * * $Log: cyclades.c,v $ + * Revision 2.3.2.7 2000/06/01 18:26:34 ivan + * Request PLX I/O region, although driver doesn't use it, to avoid + * problems with other drivers accessing it. + * Removed count for on-board buffer characters in cy_chars_in_buffer + * (Cyclades-Z only). + * * Revision 2.3.2.6 2000/05/05 13:56:05 ivan * Driver now reports physical instead of virtual memory addresses. * Masks were added to some Cyclades-Z read accesses. @@ -636,6 +643,7 @@ static char rcsid[] = #include <linux/ptrace.h> #include <linux/cyclades.h> #include <linux/mm.h> +#include <linux/ioport.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/spinlock.h> @@ -882,9 +890,8 @@ static void cyz_poll(unsigned long); static long cyz_polling_cycle = CZ_DEF_POLL; static int cyz_timeron = 0; -static struct timer_list -cyz_timerlist = { - NULL, NULL, 0, 0, cyz_poll +static struct timer_list cyz_timerlist = { + function: cyz_poll }; #else /* CONFIG_CYZ_INTR */ static void cyz_rx_restart(unsigned long); @@ -3122,12 +3129,15 @@ cy_chars_in_buffer(struct tty_struct *tty) card = info->card; channel = (info->line) - (cy_card[card].first_line); +#ifdef Z_EXT_CHARS_IN_BUFFER if (!IS_CYC_Z(cy_card[card])) { +#endif /* Z_EXT_CHARS_IN_BUFFER */ #ifdef CY_DEBUG_IO printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */ #endif return info->xmit_cnt; +#ifdef Z_EXT_CHARS_IN_BUFFER } else { static volatile struct FIRM_ID *firm_id; static volatile struct ZFW_CTRL *zfw_ctrl; @@ -3156,6 +3166,7 @@ cy_chars_in_buffer(struct tty_struct *tty) #endif return (info->xmit_cnt + char_count); } +#endif /* Z_EXT_CHARS_IN_BUFFER */ } /* cy_chars_in_buffer */ @@ -4856,7 +4867,7 @@ cy_detect_pci(void) struct pci_dev *pdev = NULL; unsigned char cyy_rev_id; unsigned char cy_pci_irq = 0; - uclong cy_pci_phys0, cy_pci_phys2; + uclong cy_pci_phys0, cy_pci_phys1, cy_pci_phys2; uclong cy_pci_addr0, cy_pci_addr2; unsigned short i,j,cy_pci_nchan, plx_ver; unsigned short device_id,dev_index = 0; @@ -4885,6 +4896,7 @@ cy_detect_pci(void) /* read PCI configuration area */ cy_pci_irq = pdev->irq; cy_pci_phys0 = pci_resource_start(pdev, 0); + cy_pci_phys1 = pci_resource_start(pdev, 1); cy_pci_phys2 = pci_resource_start(pdev, 2); pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id); @@ -4907,6 +4919,11 @@ cy_detect_pci(void) pdev->resource[2].flags &= ~IORESOURCE_IO; } + /* Although we don't use this I/O region, we should + request it from the kernel anyway, to avoid problems + with other drivers accessing it. */ + request_region(cy_pci_phys1, CyPCI_Yctl, "Cyclom-Y"); + #if defined(__alpha__) if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", @@ -5054,6 +5071,12 @@ cy_detect_pci(void) "Ignoring it...\n"); pdev->resource[2].flags &= ~IORESOURCE_IO; } + + /* Although we don't use this I/O region, we should + request it from the kernel anyway, to avoid problems + with other drivers accessing it. */ + request_region(cy_pci_phys1, CyPCI_Zctl, "Cyclades-Z"); + if (mailbox == ZE_V1) { #if !defined(__alpha__) cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win); diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 5a89e008a16305..f0c76181ba39ac 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -311,22 +311,6 @@ ds1620_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned return 0; } -static int -ds1620_open(struct inode *inode, struct file *file) -{ - MOD_INC_USE_COUNT; - - return 0; -} - -static int -ds1620_release(struct inode *inode, struct file *file) -{ - MOD_DEC_USE_COUNT; - - return 0; -} - #ifdef THERM_USE_PROC static int proc_therm_ds1620_read(char *buf, char **start, off_t offset, @@ -352,10 +336,9 @@ static struct proc_dir_entry *proc_therm_ds1620; #endif static struct file_operations ds1620_fops = { + owner: THIS_MODULE, read: ds1620_read, ioctl: ds1620_ioctl, - open: ds1620_open, - release: ds1620_release, }; static struct miscdevice ds1620_miscdev = { diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index ac27c9e0e9ef0b..dc076dd5a400a3 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -472,10 +472,6 @@ static int dsp56k_open(struct inode *inode, struct file *file) return -ENXIO; } -#ifdef MODULE - MOD_INC_USE_COUNT; -#endif /* MODULE */ - return 0; } @@ -495,13 +491,11 @@ static int dsp56k_release(struct inode *inode, struct file *file) return -ENXIO; } -#ifdef MODULE - MOD_DEC_USE_COUNT; -#endif return 0; } static struct file_operations dsp56k_fops = { + owner: THIS_MODULE, read: dsp56k_read, write: dsp56k_write, ioctl: dsp56k_ioctl, diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 542ad99bf6ba69..730b69b1773dd5 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c @@ -102,6 +102,7 @@ static int dtlk_ioctl(struct inode *inode, struct file *file, static struct file_operations dtlk_fops = { + owner: THIS_MODULE, read: dtlk_read, write: dtlk_write, poll: dtlk_poll, @@ -306,7 +307,6 @@ static int dtlk_ioctl(struct inode *inode, static int dtlk_open(struct inode *inode, struct file *file) { - MOD_INC_USE_COUNT; TRACE_TEXT("(dtlk_open"); switch (MINOR(inode->i_rdev)) { @@ -322,7 +322,6 @@ static int dtlk_open(struct inode *inode, struct file *file) static int dtlk_release(struct inode *inode, struct file *file) { - MOD_DEC_USE_COUNT; TRACE_TEXT("(dtlk_release"); switch (MINOR(inode->i_rdev)) { diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index 103e60eef5f397..9ad85c68797810 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c @@ -281,6 +281,7 @@ efi_rtc_close(struct inode *inode, struct file *file) */ static struct file_operations efi_rtc_fops = { + owner: THIS_MODULE, ioctl: efi_rtc_ioctl, open: efi_rtc_open, release: efi_rtc_close, diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 9238ae3eb214ce..13656af4bd7edd 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c @@ -4007,6 +4007,9 @@ static int __init epca_init_one (struct pci_dev *pdev, int board_idx, info_idx = ent->driver_data; unsigned long addr; + if (pci_enable_device(pdev)) + return -EIO; + board_num++; board_idx = board_num + num_cards; if (board_idx >= MAXBOARDS) diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index dfe89b9707b641..01eb20e9202fb0 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c @@ -330,7 +330,7 @@ int gs_chars_in_buffer(struct tty_struct *tty) int gs_real_chars_in_buffer(struct tty_struct *tty) { - struct gs_port *port = tty->driver_data; + struct gs_port *port; func_enter (); if (!tty) return 0; diff --git a/drivers/char/hp600_keyb.c b/drivers/char/hp600_keyb.c new file mode 100644 index 00000000000000..52f66ba5fbf54c --- /dev/null +++ b/drivers/char/hp600_keyb.c @@ -0,0 +1,119 @@ +/* + * $Id: hp600_keyb.c,v 1.1 2000/06/10 21:45:30 yaegashi Exp $ + * Copyright (C) 2000 YAEGASHI Takeshi + * HP600 keyboard scan routine and translate table + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <asm/io.h> +#include "scan_keyb.h" + +#define PCDR 0xa4000124 +#define PDDR 0xa4000126 +#define PEDR 0xa4000128 +#define PFDR 0xa400012a +#define PGDR 0xa400012c +#define PHDR 0xa400012e + +static const unsigned char hp690_japanese_table[]={ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x29, 0x70, 0x3a, + 0x3f, 0x3e, 0x40, 0x41, 0x42, 0x3d, 0x3c, 0x3b, + + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x1c, 0x28, 0x35, + 0x31, 0x30, 0x32, 0x33, 0x34, 0x2f, 0x2e, 0x2d, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x50, + 0x7b, 0x38, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf9, 0x73, 0x53, 0x39, 0x00, 0x1d, + + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x2b, 0x1b, 0x27, + 0x23, 0x22, 0x24, 0x25, 0x26, 0x21, 0x20, 0x1f, + + 0x00, 0x00, 0x00, 0x0f, 0x00, 0x36, 0x7d, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, + + 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x1a, 0x19, + 0x15, 0x14, 0x16, 0x17, 0x18, 0x13, 0x12, 0x11, + + 0x00, 0x00, 0x00, 0x02, 0x00, 0x0d, 0x0c, 0x0b, + 0x07, 0x06, 0x08, 0x09, 0x0a, 0x05, 0x04, 0x03, + + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + +static void hp690_japanese_scan_kbd(unsigned char *s) +{ + ctrl_outb(0xfd, PDDR); ctrl_outb(0xff, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + ctrl_outb(0xdf, PDDR); ctrl_outb(0xff, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + ctrl_outb(0x7f, PDDR); ctrl_outb(0xff, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + ctrl_outb(0xff, PDDR); ctrl_outb(0xfe, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + ctrl_outb(0xff, PDDR); ctrl_outb(0xfd, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + ctrl_outb(0xff, PDDR); ctrl_outb(0xf7, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + ctrl_outb(0xff, PDDR); ctrl_outb(0xbf, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + ctrl_outb(0xff, PDDR); ctrl_outb(0x7f, PEDR); + *s++=ctrl_inb(PCDR); *s++=ctrl_inb(PFDR); + *s++=ctrl_inb(PGDR); *s++=ctrl_inb(PHDR); +} + + +void __init hp600_kbd_init_hw(void) +{ + scan_kbd_init(); + register_scan_keyboard(hp690_japanese_scan_kbd, + hp690_japanese_table, 18); + printk(KERN_INFO "HP600 matrix scan keyboard registered\n"); +} + + +/**************************************************************** +HP Jornada 690(Japanese version) keyboard scan matrix + + PTC7 PTC6 PTC5 PTC4 PTC3 PTC2 PTC1 PTC0 +PTD1 REC Escape on/off Han/Zen Hira Eisu +PTD5 REC Z on/off Enter : / +PTD7 REC Right Down +PTE0 REC Windows on/off +PTE1 REC A on/off ] [ ; +PTE3 REC Tab on/off ShirtR \ Up +PTE6 REC Q on/off BS @ P +PTE7 REC 1 on/off ^ - 0 + + + PTF7 PTF6 PTF5 PTF4 PTF3 PTF2 PTF1 PTF0 +PTD1 F5 F4 F6 F7 F8 F3 F2 F1 +PTD5 N B M , . V C X +PTD7 Muhen Alt Left +PTE0 Henkan _ Del Space Ctrl +PTE1 H G J K L F D S +PTE3 ShiftL +PTE6 Y T U I O R E W +PTE7 6 5 7 8 9 4 3 2 + + PTG5 PTG4 PTG3 PTG0 PTH0 +* REC REW FWW Cover on/off + + + 7 6 5 4 3 2 1 0 +C: 0xffff 0xdf IP IP IP IP IP IP IP IP +D: 0x6786 0x59 O I O IP I F O I +E: 0x5045 0x00 O O F F O F O O +F: 0xffff 0xff IP IP IP IP IP IP IP IP +G: 0xaffe 0xfd I I IP IP IP IP IP I +H: 0x70f2 0x49 O IP F F IP IP F I +J: 0x0704 0x22 F F O IP F F O F +K: 0x0100 0x10 F F F O F F F F +L: 0x0c3c 0x26 F F IP F F IP IP F + +****************************************************************/ diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index 6b42c7f63caccc..033eb9aafe7239 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c @@ -311,6 +311,7 @@ static struct termios * TermiosLocked[IP2_MAX_PORTS]; * download the loadware to the boards. */ static struct file_operations ip2_ipl = { + owner: THIS_MODULE, read: ip2_ipl_read, write: ip2_ipl_write, ioctl: ip2_ipl_ioctl, @@ -3202,8 +3203,6 @@ ip2_ipl_open( struct inode *pInode, struct file *pFile ) printk (KERN_DEBUG "IP2IPL: open\n" ); #endif - //MOD_INC_USE_COUNT; // Needs close entry with decrement. - switch(iplminor) { // These are the IPL devices case 0: diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 958fbf77638274..52c6b5f1950ed0 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c @@ -86,8 +86,6 @@ static char re_schedule = 1; static unsigned long tx_count = 0; #endif -static int ISILoad_open(struct inode *inode, struct file *filp); -static int ISILoad_release(struct inode *inode, struct file *filp); static int ISILoad_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); static void isicom_tx(unsigned long _data); @@ -109,9 +107,8 @@ static signed char linuxb_to_isib[] = { */ static struct file_operations ISILoad_fops = { + owner: THIS_MODULE, ioctl: ISILoad_ioctl, - open: ISILoad_open, - release: ISILoad_release, }; struct miscdevice isiloader_device = { @@ -129,24 +126,6 @@ extern inline int WaitTillCardIsFree(unsigned short base) return 1; } -static int ISILoad_open(struct inode *inode, struct file *filp) -{ -#ifdef ISICOM_DEBUG - printk(KERN_DEBUG "ISILoad:Firmware loader Opened!!!\n"); -#endif - MOD_INC_USE_COUNT; - return 0; -} - -static int ISILoad_release(struct inode *inode, struct file *filp) -{ -#ifdef ISICOM_DEBUG - printk(KERN_DEBUG "ISILoad:Firmware loader Close(Release)d\n",); -#endif - MOD_DEC_USE_COUNT; - return 0; -} - static int ISILoad_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 5733fac43c1757..8d16c9daf1adcc 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -687,8 +687,6 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p static int stli_brdinit(stlibrd_t *brdp); static int stli_startbrd(stlibrd_t *brdp); -static int stli_memopen(struct inode *ip, struct file *fp); -static int stli_memclose(struct inode *ip, struct file *fp); static ssize_t stli_memread(struct file *fp, char *buf, size_t count, loff_t *offp); static ssize_t stli_memwrite(struct file *fp, const char *buf, size_t count, loff_t *offp); static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); @@ -780,11 +778,10 @@ static inline int stli_initpcibrd(int brdtype, struct pci_dev *devp); * board. This is also a very useful debugging tool. */ static struct file_operations stli_fsiomem = { + owner: THIS_MODULE, read: stli_memread, write: stli_memwrite, ioctl: stli_memioctl, - open: stli_memopen, - release: stli_memclose, }; /*****************************************************************************/ @@ -5183,27 +5180,6 @@ static int stli_getbrdstruct(unsigned long arg) /*****************************************************************************/ /* - * Memory device open code. Need to keep track of opens and close - * for module handling. - */ - -static int stli_memopen(struct inode *ip, struct file *fp) -{ - MOD_INC_USE_COUNT; - return(0); -} - -/*****************************************************************************/ - -static int stli_memclose(struct inode *ip, struct file *fp) -{ - MOD_DEC_USE_COUNT; - return(0); -} - -/*****************************************************************************/ - -/* * The "staliomem" device is also required to do some special operations on * the board. We need to be able to send an interrupt to the board, * reset it, and start/stop it. diff --git a/drivers/char/joystick/joystick.c b/drivers/char/joystick/joystick.c index 81ec240ba4c43e..c9bd56ce361dec 100644 --- a/drivers/char/joystick/joystick.c +++ b/drivers/char/joystick/joystick.c @@ -752,6 +752,7 @@ void js_unregister_device(struct js_dev *dev) static struct file_operations js_fops = { + owner: THIS_MODULE, read: js_read, poll: js_poll, ioctl: js_ioctl, diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 90f0343966bc15..c2df7ea1858c0c 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -371,8 +371,6 @@ static int lp_open(struct inode * inode, struct file * file) if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor))) return -EBUSY; - MOD_INC_USE_COUNT; - /* If ABORTOPEN is set and the printer is offline or out of paper, we may still want to open it to perform ioctl()s. Therefore we have commandeered O_NONBLOCK, even though it is being used in @@ -385,24 +383,20 @@ static int lp_open(struct inode * inode, struct file * file) parport_release (lp_table[minor].dev); if (status & LP_POUTPA) { printk(KERN_INFO "lp%d out of paper\n", minor); - MOD_DEC_USE_COUNT; LP_F(minor) &= ~LP_BUSY; return -ENOSPC; } else if (!(status & LP_PSELECD)) { printk(KERN_INFO "lp%d off-line\n", minor); - MOD_DEC_USE_COUNT; LP_F(minor) &= ~LP_BUSY; return -EIO; } else if (!(status & LP_PERRORP)) { printk(KERN_ERR "lp%d printer error\n", minor); - MOD_DEC_USE_COUNT; LP_F(minor) &= ~LP_BUSY; return -EIO; } } lp_table[minor].lp_buffer = (char *) kmalloc(LP_BUFFER_SIZE, GFP_KERNEL); if (!lp_table[minor].lp_buffer) { - MOD_DEC_USE_COUNT; LP_F(minor) &= ~LP_BUSY; return -ENOMEM; } @@ -415,7 +409,6 @@ static int lp_release(struct inode * inode, struct file * file) kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE); lp_table[minor].lp_buffer = NULL; - MOD_DEC_USE_COUNT; LP_F(minor) &= ~LP_BUSY; return 0; } @@ -526,6 +519,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, } static struct file_operations lp_fops = { + owner: THIS_MODULE, write: lp_write, ioctl: lp_ioctl, open: lp_open, diff --git a/drivers/char/misc.c b/drivers/char/misc.c index ca084211855876..cecf896168d0cc 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -111,8 +111,7 @@ static int misc_open(struct inode * inode, struct file * file) int minor = MINOR(inode->i_rdev); struct miscdevice *c; int err = -ENODEV; - - file->f_op = NULL; + struct file_operations *old_fops; down(&misc_sem); @@ -133,14 +132,22 @@ static int misc_open(struct inode * inode, struct file * file) goto fail; } - if ((file->f_op = c->fops) && file->f_op->open) + old_fops = file->f_op; + file->f_op = fops_get(c->fops); + if (file->f_op && file->f_op->open) err=file->f_op->open(inode,file); + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } + fops_put(old_fops); fail: up(&misc_sem); return err; } static struct file_operations misc_fops = { + owner: THIS_MODULE, open: misc_open, }; diff --git a/drivers/char/mixcomwd.c b/drivers/char/mixcomwd.c index 5894353e380ab7..6352d6f73e7665 100644 --- a/drivers/char/mixcomwd.c +++ b/drivers/char/mixcomwd.c @@ -94,8 +94,6 @@ static int mixcomwd_open(struct inode *inode, struct file *file) mixcomwd_timer_alive=0; } #endif - MOD_INC_USE_COUNT; - return 0; } @@ -114,7 +112,6 @@ static int mixcomwd_release(struct inode *inode, struct file *file) mixcomwd_timer_alive=1; add_timer(&mixcomwd_timer); #endif - MOD_DEC_USE_COUNT; clear_bit(0,&mixcomwd_opened); return 0; @@ -171,6 +168,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file, static struct file_operations mixcomwd_fops= { + owner: THIS_MODULE, write: mixcomwd_write, ioctl: mixcomwd_ioctl, open: mixcomwd_open, diff --git a/drivers/char/msp3400.c b/drivers/char/msp3400.c index f4252a07122cd6..d6fa8314bfc172 100644 --- a/drivers/char/msp3400.c +++ b/drivers/char/msp3400.c @@ -1,7 +1,7 @@ /* * programming the msp34* sound processor family * - * (c) 1997,1998 Gerd Knorr <kraxel@goldbach.in-berlin.de> + * (c) 1997-2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> * * what works and what doesn't: * @@ -46,6 +46,7 @@ #include <linux/i2c.h> #include <linux/videodev.h> #include <asm/semaphore.h> +#include <linux/init.h> #ifdef CONFIG_SMP #include <asm/pgtable.h> @@ -57,16 +58,14 @@ #include "audiochip.h" -#define WAIT_QUEUE wait_queue_head_t - /* sound mixer stuff */ -#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE) +#if 0 /* defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE) */ # define REGISTER_MIXER 1 #endif /* Addresses to scan */ static unsigned short normal_i2c[] = {I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {0x40,0x44,I2C_CLIENT_END}; +static unsigned short normal_i2c_range[] = {0x40,0x40,I2C_CLIENT_END}; static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; @@ -102,7 +101,7 @@ struct msp3400c { /* thread */ struct task_struct *thread; - WAIT_QUEUE wq; + wait_queue_head_t wq; struct semaphore *notify; int active,restart,rmmod; @@ -680,10 +679,10 @@ static int msp3400c_thread(void *data) #endif exit_mm(current); + exit_fs(current); current->session = 1; current->pgrp = 1; sigfillset(¤t->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(¤t->blocked); - current->fs->umask = 0; strcpy(current->comm,"msp3410 [auto]"); msp->thread = current; @@ -1256,7 +1255,6 @@ msp3400c_mixer_open(struct inode *inode, struct file *file) if (client->adapter->inc_use) client->adapter->inc_use(client->adapter); - MOD_INC_USE_COUNT; return 0; } @@ -1267,7 +1265,6 @@ msp3400c_mixer_release(struct inode *inode, struct file *file) if (client->adapter->dec_use) client->adapter->dec_use(client->adapter); - MOD_DEC_USE_COUNT; return 0; } @@ -1278,6 +1275,7 @@ msp3400c_mixer_llseek(struct file *file, loff_t offset, int origin) } static struct file_operations msp3400c_mixer_fops = { + owner: THIS_MODULE, llseek: msp3400c_mixer_llseek, ioctl: msp3400c_mixer_ioctl, open: msp3400c_mixer_open, @@ -1370,7 +1368,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, if (simple == -1) { /* default mode */ - msp->simple = 0; + msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; } else { /* use insmod option */ msp->simple = simple; @@ -1632,22 +1630,19 @@ static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg) /* ----------------------------------------------------------------------- */ -#ifdef MODULE -int init_module(void) -#else -int msp3400c_init(void) -#endif +int msp3400_init_module(void) { i2c_add_driver(&driver); return 0; } -#ifdef MODULE -void cleanup_module(void) +void msp3400_cleanup_module(void) { i2c_del_driver(&driver); } -#endif + +module_init(msp3400_init_module); +module_exit(msp3400_cleanup_module); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index c5be675c72ce52..42063cefaa988a 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c @@ -332,7 +332,6 @@ static int nvram_open( struct inode *inode, struct file *file ) if (file->f_mode & 2) nvram_open_mode |= NVRAM_WRITE; nvram_open_cnt++; - MOD_INC_USE_COUNT; return( 0 ); } @@ -344,7 +343,6 @@ static int nvram_release( struct inode *inode, struct file *file ) if (file->f_mode & 2) nvram_open_mode &= ~NVRAM_WRITE; - MOD_DEC_USE_COUNT; return( 0 ); } @@ -393,6 +391,7 @@ static int nvram_read_proc( char *buffer, char **start, off_t offset, #endif /* CONFIG_PROC_FS */ static struct file_operations nvram_fops = { + owner: THIS_MODULE, llseek: nvram_llseek, read: nvram_read, write: nvram_write, diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index 34d99658283800..8cf8a15a7cd33c 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c @@ -172,34 +172,6 @@ static int button_read (struct file *filp, char *buffer, ? -EFAULT : bcount; } -/* - * This function is called when a user space process attempts to open the - * device. If the driver is compiled into the kernel it does nothing but - * succeed, but if it is compiled in as a module it also increments the - * module usage count to prevent the module from being removed whilst a - * process has the device open. - */ - -static int button_open (struct inode *inode, struct file *filp) -{ - MOD_INC_USE_COUNT; - return 0; -} - -/* - * This function is called when a user space process attempts to close the - * device. If the driver is compiled into the kernel it does nothing at all, - * but if it is compiled in as a module it also decrements the module usage - * count so that it will be possible to unload the module again once all the - * user processes have closed the device. - */ - -static int button_release (struct inode *inode, struct file *filp) -{ - MOD_DEC_USE_COUNT; - return 0; -} - /* * This structure is the file operations structure, which specifies what * callbacks functions the kernel should call when a user mode process @@ -207,9 +179,8 @@ static int button_release (struct inode *inode, struct file *filp) */ static struct file_operations button_fops = { + owner: THIS_MODULE, read: button_read, - open: button_open, - release: button_release, }; /* diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index 579e970d4a1fec..5be07b7696a160 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -39,7 +39,6 @@ MSTATIC int get_flash_id(void); MSTATIC int erase_block(int nBlock); MSTATIC int write_block(unsigned long p, const char *buf, int count); static int open_flash(struct inode *inodep, struct file *filep); -static int release_flash(struct inode *inodep, struct file *filep); static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg); static ssize_t flash_read(struct file *file, char *buf, size_t count, loff_t * ppos); static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos); @@ -60,12 +59,12 @@ extern spinlock_t gpio_lock; static struct file_operations flash_fops = { + owner: THIS_MODULE, llseek: flash_llseek, read: flash_read, write: flash_write, ioctl: flash_ioctl, open: open_flash, - release: release_flash, }; static struct miscdevice flash_miscdev = @@ -128,19 +127,10 @@ static int open_flash(struct inode *inodep, struct file *filep) printk("Flash: incorrect ID 0x%04X.\n", id); return -ENXIO; } - MOD_INC_USE_COUNT; return 0; } - -static int release_flash(struct inode *inodep, struct file *filep) -{ - MOD_DEC_USE_COUNT; - return 0; -} - - static int flash_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg) { // printk("Flash_ioctl: cmd = 0x%X.\n",cmd); diff --git a/drivers/char/pc110pad.c b/drivers/char/pc110pad.c index e0b6205969c052..b2370ed7154b63 100644 --- a/drivers/char/pc110pad.c +++ b/drivers/char/pc110pad.c @@ -588,7 +588,6 @@ static int close_pad(struct inode * inode, struct file * file) if (--active) return 0; outb(0x30, current_params.io+2); /* switch off digitiser */ - MOD_DEC_USE_COUNT; return 0; } @@ -610,7 +609,6 @@ static int open_pad(struct inode * inode, struct file * file) if (active++) return 0; - MOD_INC_USE_COUNT; save_flags(flags); cli(); @@ -772,6 +770,7 @@ static int pad_ioctl(struct inode *inode, struct file * file, static struct file_operations pad_fops = { + owner: THIS_MODULE, read: read_pad, write: write_pad, poll: pad_poll, diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c index 8226b50309f94f..f215b9dd3ef535 100644 --- a/drivers/char/pc_keyb.c +++ b/drivers/char/pc_keyb.c @@ -452,7 +452,9 @@ static unsigned char handle_kbd_event(void) scancode = kbd_read_input(); -#if 0 + /* Error bytes must be ignored to make the + Synaptics touchpads compaq use work */ +#if 1 /* Ignore error bytes */ if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) #endif diff --git a/drivers/char/pcwd.c b/drivers/char/pcwd.c index 2e2d391fa1d34f..b85a168de36b96 100644 --- a/drivers/char/pcwd.c +++ b/drivers/char/pcwd.c @@ -414,7 +414,6 @@ static int pcwd_open(struct inode *ino, struct file *filep) is_open = 1; return(0); case TEMP_MINOR: - MOD_INC_USE_COUNT; return(0); default: return (-ENODEV); @@ -450,7 +449,6 @@ static ssize_t pcwd_read(struct file *file, char *buf, size_t count, static int pcwd_close(struct inode *ino, struct file *filep) { - MOD_DEC_USE_COUNT; if (MINOR(ino->i_rdev)==WATCHDOG_MINOR) { is_open = 0; @@ -543,6 +541,7 @@ static void debug_off(void) } static struct file_operations pcwd_fops = { + owner: THIS_MODULE, read: pcwd_read, write: pcwd_write, ioctl: pcwd_ioctl, diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 19224560203661..819ed0b1a8bda8 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -639,6 +639,7 @@ static unsigned int pp_poll (struct file * file, poll_table * wait) } static struct file_operations pp_fops = { + owner: THIS_MODULE, llseek: pp_lseek, read: pp_read, write: pp_write, diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 625f7022bea0a9..01865a09d3fe0f 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c @@ -201,8 +201,6 @@ static void rio_close (void *ptr); static int rio_chars_in_buffer (void * ptr); static int rio_fw_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -static int rio_fw_open(struct inode *inode, struct file *filp); -static INT rio_fw_release(struct inode *inode, struct file *filp); static int rio_init_drivers(void); @@ -277,9 +275,8 @@ static struct real_driver rio_real_driver = { */ static struct file_operations rio_fw_fops = { + owner: THIS_MODULE, ioctl: rio_fw_ioctl, - open: rio_fw_open, - release: rio_fw_release, }; struct miscdevice rio_fw_device = { @@ -634,32 +631,6 @@ static void rio_shutdown_port (void * ptr) func_exit(); } - - -/* ********************************************************************** * - * Here are the routines that actually * - * interface with the rest of the system * - * ********************************************************************** */ - - -static int rio_fw_open(struct inode *inode, struct file *filp) -{ - func_enter (); - rio_inc_mod_count (); - func_exit (); - return 0; -} - - -static INT rio_fw_release(struct inode *inode, struct file *filp) -{ - func_enter (); - rio_dec_mod_count (); - func_exit (); - return NO_ERROR; -} - - /* I haven't the foggiest why the decrement use count has to happen here. The whole linux serial drivers stuff needs to be redesigned. My guess is that this is a hack to minimize the impact of a bug @@ -1149,6 +1120,7 @@ int rio_init(void) while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { + if (pci_enable_device(pdev)) continue; #else for (i=0;i< RIO_NBOARDS;i++) { if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, @@ -1234,6 +1206,7 @@ int rio_init(void) while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { + if (pci_enable_device(pdev)) continue; #else for (i=0;i< RIO_NBOARDS;i++) { if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index d62e02017ac78f..4aca69903185b8 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -514,8 +514,6 @@ static int rtc_open(struct inode *inode, struct file *file) if(rtc_status & RTC_IS_OPEN) return -EBUSY; - MOD_INC_USE_COUNT; - rtc_status |= RTC_IS_OPEN; spin_lock_irq (&rtc_lock); @@ -559,7 +557,6 @@ static int rtc_release(struct inode *inode, struct file *file) } #endif - MOD_DEC_USE_COUNT; spin_lock_irq (&rtc_lock); rtc_irq_data = 0; @@ -591,6 +588,7 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait) */ static struct file_operations rtc_fops = { + owner: THIS_MODULE, llseek: rtc_llseek, read: rtc_read, #ifndef __alpha__ diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 1898849d865ccb..fdaeeaea063e9f 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -511,8 +511,6 @@ static void stl_breakctl(struct tty_struct *tty, int state); static void stl_waituntilsent(struct tty_struct *tty, int timeout); static void stl_sendxchar(struct tty_struct *tty, char ch); static void stl_hangup(struct tty_struct *tty); -static int stl_memopen(struct inode *ip, struct file *fp); -static int stl_memclose(struct inode *ip, struct file *fp); static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); static int stl_portinfo(stlport_t *portp, int portnr, char *pos); static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data); @@ -744,9 +742,8 @@ static unsigned int sc26198_baudtable[] = { * to get at port stats - only not using the port device itself. */ static struct file_operations stl_fsiomem = { + owner: THIS_MODULE, ioctl: stl_memioctl, - open: stl_memopen, - release: stl_memclose, }; /*****************************************************************************/ @@ -2795,8 +2792,8 @@ static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp) */ #if DEBUG printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__, - devp->resource[0].start, devp->resource[1].start, - devp->resource[2].start, devp->resource[3].start, devp->irq); + pci_resource_start(devp, 0), pci_resource_start(devp, 1), + pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq); #endif /* @@ -2805,22 +2802,16 @@ static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp) */ switch (brdtype) { case BRD_ECHPCI: - brdp->ioaddr2 = (devp->resource[0].start & - PCI_BASE_ADDRESS_IO_MASK); - brdp->ioaddr1 = (devp->resource[1].start & - PCI_BASE_ADDRESS_IO_MASK); + brdp->ioaddr2 = pci_resource_start(devp, 0); + brdp->ioaddr1 = pci_resource_start(devp, 1); break; case BRD_ECH64PCI: - brdp->ioaddr2 = (devp->resource[2].start & - PCI_BASE_ADDRESS_IO_MASK); - brdp->ioaddr1 = (devp->resource[1].start & - PCI_BASE_ADDRESS_IO_MASK); + brdp->ioaddr2 = pci_resource_start(devp, 2); + brdp->ioaddr1 = pci_resource_start(devp, 1); break; case BRD_EASYIOPCI: - brdp->ioaddr1 = (devp->resource[2].start & - PCI_BASE_ADDRESS_IO_MASK); - brdp->ioaddr2 = (devp->resource[1].start & - PCI_BASE_ADDRESS_IO_MASK); + brdp->ioaddr1 = pci_resource_start(devp, 2); + brdp->ioaddr2 = pci_resource_start(devp, 1); break; default: printk("STALLION: unknown PCI board type=%d\n", brdtype); @@ -3123,27 +3114,6 @@ static int stl_getbrdstruct(unsigned long arg) /*****************************************************************************/ /* - * Memory device open code. Need to keep track of opens and close - * for module handling. - */ - -static int stl_memopen(struct inode *ip, struct file *fp) -{ - MOD_INC_USE_COUNT; - return(0); -} - -/*****************************************************************************/ - -static int stl_memclose(struct inode *ip, struct file *fp) -{ - MOD_DEC_USE_COUNT; - return(0); -} - -/*****************************************************************************/ - -/* * The "staliomem" device is also required to do some special operations * on the board and/or ports. In this driver it is mostly used for stats * collection. diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 15a24851f8f6d1..82e3cae1ec4d43 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -304,8 +304,6 @@ static int sx_init_board (struct sx_board *board); static int sx_init_portstructs (int nboards, int nports); static int sx_fw_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -static int sx_fw_open(struct inode *inode, struct file *filp); -static INT sx_fw_release(struct inode *inode, struct file *filp); static int sx_init_drivers(void); @@ -419,9 +417,8 @@ static struct real_driver sx_real_driver = { */ static struct file_operations sx_fw_fops = { + owner: THIS_MODULE, ioctl: sx_fw_ioctl, - open: sx_fw_open, - release: sx_fw_release, }; struct miscdevice sx_fw_device = { @@ -1418,25 +1415,6 @@ static void sx_shutdown_port (void * ptr) * interface with the rest of the system * * ********************************************************************** */ - -static int sx_fw_open(struct inode *inode, struct file *filp) -{ - func_enter (); - MOD_INC_USE_COUNT; - func_exit (); - return 0; -} - - -static INT sx_fw_release(struct inode *inode, struct file *filp) -{ - func_enter (); - MOD_DEC_USE_COUNT; - func_exit (); - return NO_ERROR; -} - - static int sx_open (struct tty_struct * tty, struct file * filp) { struct sx_port *port; diff --git a/drivers/char/tpqic02.c b/drivers/char/tpqic02.c index d29c634079836a..133f19aac06014 100644 --- a/drivers/char/tpqic02.c +++ b/drivers/char/tpqic02.c @@ -2177,10 +2177,6 @@ static int qic02_tape_open(struct inode * inode, struct file * filp) int open_error; open_error = qic02_tape_open_no_use_count(inode, filp); - if (!open_error) - { - MOD_INC_USE_COUNT; - } return open_error; } @@ -2440,9 +2436,6 @@ static int qic02_tape_release(struct inode * inode, struct file * filp) (void) do_qic_cmd(QCMD_REWIND, TIM_R); } } -#ifdef MODULE - MOD_DEC_USE_COUNT; -#endif return 0; } /* qic02_tape_release */ @@ -2766,6 +2759,7 @@ static int qic02_tape_ioctl(struct inode * inode, struct file * filp, /* These are (most) of the interface functions: */ static struct file_operations qic02_tape_fops = { + owner: THIS_MODULE, llseek: qic02_tape_lseek, /* not allowed */ read: qic02_tape_read, write: qic02_tape_write, diff --git a/drivers/char/tuner.c b/drivers/char/tuner.c index 0ed55b715399a6..81e19a4abda713 100644 --- a/drivers/char/tuner.c +++ b/drivers/char/tuner.c @@ -10,6 +10,7 @@ #include <linux/i2c.h> #include <linux/types.h> #include <linux/videodev.h> +#include <linux/init.h> #include "tuner.h" #include "audiochip.h" @@ -428,22 +429,19 @@ static struct i2c_client client_template = EXPORT_NO_SYMBOLS; -#ifdef MODULE -int init_module(void) -#else -int i2c_tuner_init(void) -#endif +int tuner_init_module(void) { i2c_add_driver(&driver); return 0; } -#ifdef MODULE -void cleanup_module(void) +void tuner_cleanup_module(void) { i2c_del_driver(&driver); } -#endif + +module_init(tuner_init_module); +module_exit(tuner_cleanup_module); /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/drivers/char/tvmixer.c b/drivers/char/tvmixer.c new file mode 100644 index 00000000000000..0ef5bbd0300f3c --- /dev/null +++ b/drivers/char/tvmixer.c @@ -0,0 +1,351 @@ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> +#include <linux/timer.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/malloc.h> +#include <linux/i2c.h> +#include <linux/videodev.h> +#include <asm/semaphore.h> +#include <linux/init.h> + +#include <linux/sound.h> +#include <linux/soundcard.h> +#include <asm/uaccess.h> + +#include "audiochip.h" + +#define DEV_MAX 4 + +static int debug = 0; +static int devnr = -1; + +MODULE_PARM(debug,"i"); +MODULE_PARM(devnr,"i"); + +/* ----------------------------------------------------------------------- */ + +struct TVMIXER { + struct i2c_client *dev; + int minor; + int count; +}; + +static struct TVMIXER devices[DEV_MAX]; + +static int tvmixer_adapters(struct i2c_adapter *adap); +static int tvmixer_clients(struct i2c_client *client); + +static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +static int tvmixer_open(struct inode *inode, struct file *file); +static int tvmixer_release(struct inode *inode, struct file *file); +static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin); + + +static struct i2c_driver driver = { + "tv card mixer driver", + 42 /* I2C_DRIVERID_FIXME */, + I2C_DF_DUMMY, + tvmixer_adapters, + tvmixer_clients, +}; + +static struct file_operations tvmixer_fops = { + owner: THIS_MODULE, + llseek: tvmixer_llseek, + ioctl: tvmixer_ioctl, + open: tvmixer_open, + release: tvmixer_release, +}; + +/* ----------------------------------------------------------------------- */ + +static int mix_to_v4l(int i) +{ + int r; + + r = ((i & 0xff) * 65536 + 50) / 100; + if (r > 65535) r = 65535; + if (r < 0) r = 0; + return r; +} + +static int v4l_to_mix(int i) +{ + int r; + + r = (i * 100 + 32768) / 65536; + if (r > 100) r = 100; + if (r < 0) r = 0; + return r | (r << 8); +} + +static int v4l_to_mix2(int l, int r) +{ + r = (r * 100 + 32768) / 65536; + if (r > 100) r = 100; + if (r < 0) r = 0; + l = (l * 100 + 32768) / 65536; + if (l > 100) l = 100; + if (l < 0) l = 0; + return (r << 8) | l; +} + +static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct video_audio va; + int left,right,ret,val = 0; + struct TVMIXER *mix = file->private_data; + struct i2c_client *client = mix->dev; + + if (NULL == client) + return -ENODEV; + + if (cmd == SOUND_MIXER_INFO) { + mixer_info info; + strncpy(info.id, "tv card", sizeof(info.id)); + strncpy(info.name, client->name, sizeof(info.name)); + info.modify_counter = 42 /* FIXME */; + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == SOUND_OLD_MIXER_INFO) { + _old_mixer_info info; + strncpy(info.id, "tv card", sizeof(info.id)); + strncpy(info.name, client->name, sizeof(info.name)); + if (copy_to_user((void *)arg, &info, sizeof(info))) + return -EFAULT; + return 0; + } + if (cmd == OSS_GETVERSION) + return put_user(SOUND_VERSION, (int *)arg); + + if (_SIOC_DIR(cmd) & _SIOC_WRITE) + if (get_user(val, (int *)arg)) + return -EFAULT; + + /* read state */ + memset(&va,0,sizeof(va)); + client->driver->command(client,VIDIOCGAUDIO,&va); + + switch (cmd) { + case MIXER_READ(SOUND_MIXER_RECMASK): + case MIXER_READ(SOUND_MIXER_CAPS): + case MIXER_READ(SOUND_MIXER_RECSRC): + case MIXER_WRITE(SOUND_MIXER_RECSRC): + ret = 0; + break; + + case MIXER_READ(SOUND_MIXER_STEREODEVS): + ret = SOUND_MASK_VOLUME; + break; + case MIXER_READ(SOUND_MIXER_DEVMASK): + ret = SOUND_MASK_VOLUME; + if (va.flags & VIDEO_AUDIO_BASS) + ret |= SOUND_MASK_BASS; + if (va.flags & VIDEO_AUDIO_TREBLE) + ret |= SOUND_MASK_TREBLE; + break; + + case MIXER_WRITE(SOUND_MIXER_VOLUME): + left = mix_to_v4l(val); + right = mix_to_v4l(val >> 8); + va.volume = MAX(left,right); + va.balance = (32768*MIN(left,right)) / (va.volume ? va.volume : 1); + va.balance = (left<right) ? (65535-va.balance) : va.balance; + client->driver->command(client,VIDIOCSAUDIO,&va); + client->driver->command(client,VIDIOCGAUDIO,&va); + /* fall throuth */ + case MIXER_READ(SOUND_MIXER_VOLUME): + left = (MIN(65536 - va.balance,32768) * + va.volume) / 32768; + right = (MIN(va.balance,32768) * + va.volume) / 32768; + ret = v4l_to_mix2(left,right); + break; + + case MIXER_WRITE(SOUND_MIXER_BASS): + va.bass = mix_to_v4l(val); + client->driver->command(client,VIDIOCSAUDIO,&va); + client->driver->command(client,VIDIOCGAUDIO,&va); + /* fall throuth */ + case MIXER_READ(SOUND_MIXER_BASS): + ret = v4l_to_mix(va.bass); + break; + + case MIXER_WRITE(SOUND_MIXER_TREBLE): + va.treble = mix_to_v4l(val); + client->driver->command(client,VIDIOCSAUDIO,&va); + client->driver->command(client,VIDIOCGAUDIO,&va); + /* fall throuth */ + case MIXER_READ(SOUND_MIXER_TREBLE): + ret = v4l_to_mix(va.treble); + break; + + default: + return -EINVAL; + } + if (put_user(ret, (int *)arg)) + return -EFAULT; + return 0; +} + +static int tvmixer_open(struct inode *inode, struct file *file) +{ + int i, minor = MINOR(inode->i_rdev); + struct TVMIXER *mix = NULL; + struct i2c_client *client = NULL; + + for (i = 0; i < DEV_MAX; i++) { + if (devices[i].minor == minor) { + mix = devices+i; + client = mix->dev; + break; + } + } + + if (NULL == client) + return -ENODEV; + + /* lock bttv in memory while the mixer is in use */ + file->private_data = mix; + if (client->adapter->inc_use) + client->adapter->inc_use(client->adapter); + return 0; +} + +static int tvmixer_release(struct inode *inode, struct file *file) +{ + struct TVMIXER *mix = file->private_data; + struct i2c_client *client = mix->dev; + + if (NULL == client) + return -ENODEV; + + if (client->adapter->dec_use) + client->adapter->dec_use(client->adapter); + return 0; +} + +static loff_t tvmixer_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +/* ----------------------------------------------------------------------- */ + +static int tvmixer_adapters(struct i2c_adapter *adap) +{ + return 0; +} + +static int tvmixer_clients(struct i2c_client *client) +{ + struct video_audio va; + int i,minor; + + /* TV card ??? */ + if (client->adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848)) { + if (debug) + printk("tvmixer: %s is not a tv card\n", + client->adapter->name); + return -1; + } + printk("tvmixer: debug: %s\n",client->name); + + /* unregister ?? */ + for (i = 0; i < DEV_MAX; i++) { + if (devices[i].dev == client) { + /* unregister */ + unregister_sound_mixer(devices[i].minor); + devices[i].dev = NULL; + devices[i].minor = -1; + printk("tvmixer: %s unregistered (#1)\n",client->name); + return 0; + } + } + + /* look for a free slot */ + for (i = 0; i < DEV_MAX; i++) + if (NULL == devices[i].dev) + break; + if (i == DEV_MAX) { + printk(KERN_WARNING "tvmixer: DEV_MAX too small\n"); + return -1; + } + + /* audio chip with mixer ??? */ + if (NULL == client->driver->command) { + if (debug) + printk("tvmixer: %s: driver->command is NULL\n", + client->driver->name); + return -1; + } + memset(&va,0,sizeof(va)); + if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) { + if (debug) + printk("tvmixer: %s: VIDIOCGAUDIO failed\n", + client->name); + return -1; + } + if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) { + if (debug) + printk("tvmixer: %s: has no volume control\n", + client->name); + return -1; + } + + /* everything is fine, register */ + if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) { + printk(KERN_ERR "tvmixer: cannot allocate mixer device\n"); + return -1; + } + + devices[i].minor = minor; + devices[i].count = 0; + devices[i].dev = client; + printk("tvmixer: %s (%s) registered with minor %d\n", + client->name,client->adapter->name,minor); + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +int tvmixer_init_module(void) +{ + int i; + + for (i = 0; i < DEV_MAX; i++) + devices[i].minor = -1; + i2c_add_driver(&driver); + return 0; +} + +void tvmixer_cleanup_module(void) +{ + int i; + + i2c_del_driver(&driver); + for (i = 0; i < DEV_MAX; i++) { + if (devices[i].minor != -1) { + unregister_sound_mixer(devices[i].minor); + printk("tvmixer: %s unregistered (#2)\n", + devices[i].dev->name); + } + } +} + +module_init(tvmixer_init_module); +module_exit(tvmixer_cleanup_module); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/drivers/char/wdt.c b/drivers/char/wdt.c index 0ce42945d0e42b..3ac86bf3ae5075 100644 --- a/drivers/char/wdt.c +++ b/drivers/char/wdt.c @@ -337,7 +337,6 @@ static int wdt_open(struct inode *inode, struct file *file) case WATCHDOG_MINOR: if(wdt_is_open) return -EBUSY; - MOD_INC_USE_COUNT; /* * Activate */ @@ -353,7 +352,6 @@ static int wdt_open(struct inode *inode, struct file *file) outb_p(0, WDT_DC); /* Enable */ return 0; case TEMP_MINOR: - MOD_INC_USE_COUNT; return 0; default: return -ENODEV; @@ -382,7 +380,6 @@ static int wdt_release(struct inode *inode, struct file *file) #endif wdt_is_open=0; } - MOD_DEC_USE_COUNT; return 0; } @@ -416,6 +413,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code, static struct file_operations wdt_fops = { + owner: THIS_MODULE, llseek: wdt_llseek, read: wdt_read, write: wdt_write, diff --git a/drivers/char/wdt_pci.c b/drivers/char/wdt_pci.c index 6e99a72ac04cf5..2bd09930a14a2c 100644 --- a/drivers/char/wdt_pci.c +++ b/drivers/char/wdt_pci.c @@ -28,6 +28,7 @@ * Parameterized timeout * JP Nollmann : Added support for PCI wdt501p * Alan Cox : Split ISA and PCI cards into two drivers + * Jeff Garzik : PCI cleanups */ #include <linux/config.h> @@ -53,6 +54,8 @@ #include <linux/pci.h> +#define PFX "wdt_pci: " + /* * Until Access I/O gets their application for a PCI vendor ID approved, * I don't think that it's appropriate to move these constants into the @@ -487,12 +490,86 @@ static struct notifier_block wdtpci_notifier= 0 }; -#ifdef MODULE -#define wdtpci_init init_module +static int __init wdtpci_init_one (struct pci_dev *dev, + const struct pci_device_id *ent) +{ + static int dev_count = 0; + + dev_count++; + if (dev_count > 1) { + printk (KERN_ERR PFX + "this driver only supports 1 device\n"); + return -ENODEV; + } + + irq = dev->irq; + io = pci_resource_start (dev, 2); + printk ("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X " + "(Interrupt %d)\n", io, irq); + + if (pci_enable_device (dev)) + goto err_out; + + if (request_region (io, 16, "wdt-pci") == NULL) { + printk (KERN_ERR PFX "I/O %d is not free.\n", io); + goto err_out; + } + + if (request_irq (irq, wdtpci_interrupt, SA_INTERRUPT | SA_SHIRQ, + "wdt-pci", &wdtpci_miscdev)) { + printk (KERN_ERR PFX "IRQ %d is not free.\n", irq); + goto err_out_free_res; + } + + misc_register (&wdtpci_miscdev); + +#ifdef CONFIG_WDT_501 + misc_register (&temp_miscdev); +#endif + + register_reboot_notifier (&wdtpci_notifier); + + return 0; + +err_out_free_res: + release_region (io, 16); +err_out: + return -EIO; +} + + +static void __exit wdtpci_remove_one (struct pci_dev *pdev) +{ + /* here we assume only one device will ever have + * been picked up and registered by probe function */ + unregister_reboot_notifier(&wdtpci_notifier); +#ifdef CONFIG_WDT_501_PCI + misc_deregister(&temp_miscdev); +#endif + misc_deregister(&wdtpci_miscdev); + free_irq(irq, &wdtpci_miscdev); + release_region(io, 16); +} + + +static struct pci_device_id wdtpci_pci_tbl[] __initdata = { + { PCI_VENDOR_ID_ACCESSIO, PCI_DEVICE_ID_WDG_CSM, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, }, /* terminate list */ +}; +MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl); + + +static struct pci_driver wdtpci_driver = { + name: "wdt-pci", + id_table: wdtpci_pci_tbl, + probe: wdtpci_init_one, + remove: wdtpci_remove_one, +}; + /** - * cleanup_module: + * wdtpci_cleanup: * * Unload the watchdog. You cannot do this with any file handles open. * If your watchdog is set to continue ticking on close and you unload @@ -501,18 +578,11 @@ static struct notifier_block wdtpci_notifier= * module in 60 seconds or reboot. */ -void cleanup_module(void) +static void __exit wdtpci_cleanup(void) { - misc_deregister(&wdtpci_miscdev); -#ifdef CONFIG_WDT_501_PCI - misc_deregister(&temp_miscdev); -#endif - unregister_reboot_notifier(&wdtpci_notifier); - release_region(io,16); - free_irq(irq, &wdtpci_miscdev); + pci_unregister_driver (&wdtpci_driver); } -#endif /** * wdtpci_init: @@ -522,37 +592,16 @@ void cleanup_module(void) * The open() function will actually kick the board off. */ -int __init wdtpci_init(void) +static int __init wdtpci_init(void) { - struct pci_dev *dev = NULL; - - if (pci_present()) - { - while ((dev = pci_find_device(PCI_VENDOR_ID_ACCESSIO, - PCI_DEVICE_ID_WDG_CSM, dev))) { - /* See if we can do this device */ - irq = dev->irq; - io = dev->resource[2].start; - printk("WDT501-P(PCI-WDG-CSM) driver 0.07 at %X " - "(Interrupt %d)\n", io, irq); - } - } - if(request_region(io, 16, "wdt-pci")==NULL) - { - printk(KERN_ERR "I/O %d is not free.\n", io); - return -EIO; - } - if(request_irq(irq, wdtpci_interrupt, SA_INTERRUPT|SA_SHIRQ, "wdt-pci", &wdtpci_miscdev)) - { - printk(KERN_ERR "IRQ %d is not free.\n", irq); - release_region(io, 16); - return -EIO; - } - misc_register(&wdtpci_miscdev); -#ifdef CONFIG_WDT_501 - misc_register(&temp_miscdev); -#endif - register_reboot_notifier(&wdtpci_notifier); + int rc = pci_register_driver (&wdtpci_driver); + + if (rc < 1) + return -ENODEV; + return 0; } + +module_init(wdtpci_init); +module_exit(wdtpci_cleanup); diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index 75b3153b7ad150..2f3d2fc3a83d09 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/aec62xx.c Version 0.08 Mar. 28, 2000 + * linux/drivers/ide/aec62xx.c Version 0.09 June. 9, 2000 * - * Copyright (C) 2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick (andre@linux-ide.org) * May be copied or modified under the terms of the GNU General Public License * */ @@ -55,7 +55,7 @@ static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; u8 art = 0, uart = 0; @@ -358,7 +358,7 @@ static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra) byte unit = (drive->select.b.unit & 0x01); unsigned long dma_base = hwif->dma_base; byte speed = -1; - byte ultra66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte ultra66 = eighty_ninty_three(drive); if (drive->media != ide_disk) return ((int) ide_dma_off_quietly); @@ -497,6 +497,23 @@ int aec62xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_lostirq: + case ide_dma_timeout: + switch(HWIF(drive)->pci_dev->device) { + case PCI_DEVICE_ID_ARTOP_ATP860: + case PCI_DEVICE_ID_ARTOP_ATP860R: +// { +// int i = 0; +// byte reg49h = 0; +// pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, ®49h); +// for (i=0;i<256;i++) +// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10); +// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10); +// } +// return 0; + default: + break; + } default: break; } @@ -529,9 +546,6 @@ unsigned int __init ata66_aec62xx (ide_hwif_t *hwif) byte ata66 = 0; pci_read_config_byte(hwif->pci_dev, 0x49, &ata66); -#if 1 - printk("AEC6260: reg49h=0x%02x ATA-%s Cable Port%d\n", ata66, (ata66 & mask) ? "33" : "66", hwif->channel); -#endif return ((ata66 & mask) ? 0 : 1); } diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 02af0a0f801a10..41768bb908863f 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -1,17 +1,15 @@ /* - * linux/drivers/ide/alim15x3.c Version 0.09 Mar. 18, 2000 + * linux/drivers/ide/alim15x3.c Version 0.10 Jun. 9, 2000 * * Copyright (C) 1998-2000 Michel Aubry, Maintainer * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer + * Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) * May be copied or modified under the terms of the GNU General Public License * * (U)DMA capable version of ali 1533/1543(C), 1535(D) * - * version: 1.0 beta2 (Sep. 2, 1999) - * e-mail your problems to cjtsai@ali.com.tw - * ********************************************************************** * 9/7/99 --Parts from the above author are included and need to be * converted into standard interface, once I finish the thought. @@ -237,7 +235,6 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count) static byte m5229_revision = 0; static byte chip_is_1543c_e = 0; -static byte cable_80_pin[2] = { 0, 0 }; byte ali_proc = 0; static struct pci_dev *isa_dev; @@ -346,7 +343,7 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, byte speed) /* * enable ultra dma and set timing */ - tmpbyte |= ((0x08 | (4-speed)) << (unit << 2)); + tmpbyte |= ((0x08 | ((4-speed)&0x07)) << (unit << 2)); pci_write_config_byte(dev, m5229_udma, tmpbyte); if (speed >= XFER_UDMA_3) { pci_read_config_byte(dev, 0x4b, &tmpbyte); @@ -370,12 +367,14 @@ static void config_chipset_for_pio (ide_drive_t *drive) static int config_chipset_for_dma (ide_drive_t *drive, byte ultra33) { struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); byte speed = 0x00; - byte ultra66 = ((hwif->udma_four) && (id->hw_config & 0x2000)) ? 1 : 0; + byte ultra66 = eighty_ninty_three(drive); + byte ultra100 = (m5229_revision>=0xc4) ? 1 : 0; int rval; - if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) { + if ((id->dma_ultra & 0x0020) && (ultra100) && (ultra66) && (ultra33)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (ultra66) && (ultra33)) { speed = XFER_UDMA_3; @@ -454,7 +453,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, can_ultra_dma); if ((id->field_valid & 2) && @@ -508,13 +507,13 @@ static int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive) unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name) { - unsigned long fixdma_base = dev->resource[4].start; + unsigned long fixdma_base = pci_resource_start(dev, 4); pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); - if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) { + if (!fixdma_base) { /* * */ @@ -539,11 +538,16 @@ unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name) return 0; } +/* + * This checks if the controller and the cable are capable + * of UDMA66 transfers. It doesn't check the drives. + * But see note 2 below! + */ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - byte ata66mask = hwif->channel ? 0x02 : 0x01; unsigned int ata66 = 0; + byte cable_80_pin[2] = { 0, 0 }; unsigned long flags; byte tmpbyte; @@ -575,7 +579,7 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) * 1543C-B0 (m1533, 0x79, bit 2) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04); - } else if (m5229_revision == 0xC3) { + } else if (m5229_revision >= 0xC3) { /* * 1553/1535 (m1533, 0x79, bit 1) */ @@ -596,6 +600,10 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) * has 80-pin (from host view) */ if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1; + /* + * Allow ata66 if cable of current channel has 80 pins + */ + ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0]; } else { /* * revision 0x20 (1543-E, 1543-F) @@ -625,18 +633,6 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) pci_write_config_byte(dev, 0x53, tmpbyte); - /* - * Ultra66 cable detection (from Host View) - * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin - * - * 0x4a, bit0 is 0 => primary channel - * has 80-pin (from host view) - * - * 0x4a, bit1 is 0 => secondary channel - * has 80-pin (from host view) - */ - pci_read_config_byte(dev, 0x4a, &tmpbyte); - ata66 = (!(tmpbyte & ata66mask)) ? 1 : 0; __restore_flags(flags); return(ata66); diff --git a/drivers/ide/amd7409.c b/drivers/ide/amd7409.c index d54a240d4c931c..ca23d3af456338 100644 --- a/drivers/ide/amd7409.c +++ b/drivers/ide/amd7409.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/amd7409.c Version 0.04 Mar. 18, 2000 + * linux/drivers/ide/amd7409.c Version 0.05 June 9, 2000 * - * Copyright (C) 2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * */ @@ -40,7 +40,7 @@ static struct pci_dev *bmide_dev; static int amd7409_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* @@ -71,6 +71,20 @@ byte amd7409_proc = 0; extern char *ide_xfer_verbose (byte xfer_rate); +static unsigned int amd7409_swdma_check (struct pci_dev *dev) +{ + unsigned int class_rev; + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + return ((int) (class_rev >= 7) ? 1 : 0); +} + +static int amd7409_swdma_error(ide_drive_t *drive) +{ + printk("%s: single-word DMA not support (revision < C4)\n", drive->name); + return 0; +} + /* * Here is where all the hard work goes to program the chipset. * @@ -122,64 +136,68 @@ static int amd7409_tune_chipset (ide_drive_t *drive, byte speed) case XFER_UDMA_4: ultra_timing |= 0x45; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_3: ultra_timing |= 0x44; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_2: ultra_timing |= 0x40; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_1: ultra_timing |= 0x41; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_0: ultra_timing |= 0x42; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_MW_DMA_2: dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_MW_DMA_1: dma_pio_timing |= 0x21; - pio_timing |= (0x03 << drive->dn); break; case XFER_MW_DMA_0: dma_pio_timing |= 0x77; - pio_timing |= (0x03 << drive->dn); + break; + case XFER_SW_DMA_2: + if (!amd7409_swdma_check(dev)) + return amd7409_swdma_error(drive); + dma_pio_timing |= 0x42; + break; + case XFER_SW_DMA_1: + if (!amd7409_swdma_check(dev)) + return amd7409_swdma_error(drive); + dma_pio_timing |= 0x65; + break; + case XFER_SW_DMA_0: + if (!amd7409_swdma_check(dev)) + return amd7409_swdma_error(drive); + dma_pio_timing |= 0xA8; break; #endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_3: dma_pio_timing |= 0x22; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_2: dma_pio_timing |= 0x42; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_1: dma_pio_timing |= 0x65; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_0: default: dma_pio_timing |= 0xA8; - pio_timing |= (0x03 << drive->dn); break; } + pio_timing |= (0x03 << drive->dn); + if (!drive->init_speed) drive->init_speed = speed; @@ -268,12 +286,14 @@ static void amd7409_tune_drive (ide_drive_t *drive, byte pio) static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - byte udma_66 = ((id->hw_config & 0x2000) && - (HWIF(drive)->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); + byte udma_100 = 0; byte speed = 0x00; int rval; - if ((id->dma_ultra & 0x0010) && (udma_66)) { + if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (udma_66)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (udma_66)) { speed = XFER_UDMA_3; @@ -318,7 +338,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && @@ -327,12 +347,15 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } } else if (id->field_valid & 2) { try_dma_modes: - if (id->dma_mword & 0x0007) { + if ((id->dma_mword & 0x0007) || + ((id->dma_1word & 0x007) && + (amd7409_swdma_check(HWIF(drive)->pci_dev)))) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) goto no_dma_set; } + } else if (ide_dmaproc(ide_dma_good_drive, drive)) { if (id->eide_dma_time > 150) { goto no_dma_set; @@ -372,9 +395,14 @@ int amd7409_dmaproc (ide_dma_action_t func, ide_drive_t *drive) unsigned int __init pci_init_amd7409 (struct pci_dev *dev, const char *name) { - unsigned long fixdma_base = dev->resource[4].start; + unsigned long fixdma_base = pci_resource_start(dev, 4); + +#ifdef CONFIG_BLK_DEV_IDEDMA + if (!amd7409_swdma_check(dev)) + printk("%s: disabling single-word DMA support (revision < C4)\n", name); +#endif /* CONFIG_BLK_DEV_IDEDMA */ - if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) { + if (!fixdma_base) { /* * */ diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 7e9f0c7eecb9a4..6e45bf0e0fa5d9 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -1,6 +1,6 @@ /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 * - * linux/drivers/ide/cmd64x.c Version 1.21 Mar. 18, 2000 + * linux/drivers/ide/cmd64x.c Version 1.22 June 9, 2000 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Note, this driver is not used at all on other systems because @@ -10,7 +10,7 @@ * * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1998 David S. Miller (davem@redhat.com) - * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> */ #include <linux/config.h> @@ -41,6 +41,8 @@ * CMD64x specific registers definition. */ +#define CFR 0x50 +#define CFR_INTR_CH0 0x02 #define CNTRL 0x51 #define CNTRL_DIS_RA0 0x40 #define CNTRL_DIS_RA1 0x80 @@ -52,6 +54,7 @@ #define ARTTIM1 0x55 #define DRWTIM1 0x56 #define ARTTIM23 0x57 +#define ARTTIM23_INTR_CH1 0x04 #define ARTTIM23_DIS_RA2 0x04 #define ARTTIM23_DIS_RA3 0x08 #define ARTTIM2 0x57 @@ -63,6 +66,10 @@ #define BMIDECR0 0x70 #define MRDMODE 0x71 +#define MRDMODE_INTR_CH0 0x04 +#define MRDMODE_INTR_CH1 0x08 +#define MRDMODE_BLK_CH0 0x10 +#define MRDMODE_BLK_CH1 0x20 #define BMIDESR0 0x72 #define UDIDETCR0 0x73 #define DTPR0 0x74 @@ -90,9 +97,13 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) u8 reg57 = 0, reg58 = 0, reg5b; /* secondary */ u8 reg72 = 0, reg73 = 0; /* primary */ u8 reg7a = 0, reg7b = 0; /* secondary */ + u8 reg50 = 0, reg71 = 0; /* extra */ u8 hi_byte = 0, lo_byte = 0; switch(bmide_dev->device) { + case PCI_DEVICE_ID_CMD_649: + p += sprintf(p, "\n CMD649 Chipset.\n"); + break; case PCI_DEVICE_ID_CMD_648: p += sprintf(p, "\n CMD648 Chipset.\n"); break; @@ -106,6 +117,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, "\n CMD64? Chipse.\n"); break; } + (void) pci_read_config_byte(bmide_dev, CFR, ®50); (void) pci_read_config_byte(bmide_dev, ARTTIM0, ®53); (void) pci_read_config_byte(bmide_dev, DRWTIM0, ®54); (void) pci_read_config_byte(bmide_dev, ARTTIM1, ®55); @@ -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, ®57); (void) pci_read_config_byte(bmide_dev, DRWTIM2, ®58); (void) pci_read_config_byte(bmide_dev, DRWTIM3, ®5b); + (void) pci_read_config_byte(bmide_dev, MRDMODE, ®71); (void) pci_read_config_byte(bmide_dev, BMIDESR0, ®72); (void) pci_read_config_byte(bmide_dev, UDIDETCR0, ®73); (void) pci_read_config_byte(bmide_dev, BMIDESR1, ®7a); @@ -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, ®D); (void) pci_read_config_byte(dev, pciU, ®U); switch(speed) { + case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break; @@ -383,7 +397,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed) #else int err = 0; - switch(speed) { + switch(speed) { #endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; @@ -394,6 +408,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed) default: return 1; } + #ifdef CONFIG_BLK_DEV_IDEDMA (void) pci_write_config_byte(dev, pciU, regU); #endif /* CONFIG_BLK_DEV_IDEDMA */ @@ -420,10 +435,12 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul byte speed = 0x00; byte set_pio = 0x00; byte udma_33 = ((rev >= 0x05) || (ultra_66)) ? 1 : 0; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); + byte udma_100 = 0; int rval; switch(dev->device) { + case PCI_DEVICE_ID_CMD_649: udma_100 = 1; break; case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_646: case PCI_DEVICE_ID_CMD_643: @@ -446,7 +463,9 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul * in the 646U2. * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. */ - if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) { + if ((id->dma_ultra & 0x0020) && (udma_100) && (udma_66) && (udma_33)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) { speed = XFER_UDMA_3; @@ -483,7 +502,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul if (cmd64x_tune_chipset(drive, speed)) return ((int) ide_dma_off); - rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ((id->dma_1word >> 8) & 7) ? ide_dma_on : @@ -500,12 +519,15 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) unsigned int class_rev = 0; byte can_ultra_33 = 0; byte can_ultra_66 = 0; + byte can_ultra_100 = 0; ide_dma_action_t dma_func = ide_dma_on; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; switch(dev->device) { + case PCI_DEVICE_ID_CMD_649: + can_ultra_100 = 1; case PCI_DEVICE_ID_CMD_648: can_ultra_66 = 1; case PCI_DEVICE_ID_CMD_643: @@ -514,6 +536,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) case PCI_DEVICE_ID_CMD_646: can_ultra_33 = (class_rev >= 0x05) ? 1 : 0; can_ultra_66 = 0; + can_ultra_100 = 0; break; default: return hwif->dmaproc(ide_dma_off, drive); @@ -528,7 +551,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if ((id->field_valid & 4) && (can_ultra_33)) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, class_rev, can_ultra_66); if ((id->field_valid & 2) && @@ -636,6 +659,7 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) printk("\n"); break; case PCI_DEVICE_ID_CMD_648: + case PCI_DEVICE_ID_CMD_649: break; default: break; @@ -714,6 +738,7 @@ void __init ide_init_cmd64x (ide_hwif_t *hwif) #ifdef CONFIG_BLK_DEV_IDEDMA switch(dev->device) { + case PCI_DEVICE_ID_CMD_649: case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_643: hwif->dmaproc = &cmd64x_dmaproc; diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c index b160d7716361a2..fb531e81336e78 100644 --- a/drivers/ide/cs5530.c +++ b/drivers/ide/cs5530.c @@ -1,7 +1,7 @@ /* * linux/drivers/ide/cs5530.c Version 0.6 Mar. 18, 2000 * - * Copyright (C) 2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * Ditto of GNU General Public License. * * Copyright (C) 2000 Mark Lord <mlord@pobox.com> @@ -43,7 +43,7 @@ static struct pci_dev *bmide_dev; static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 3ecaa31ece2c54..3e4961cbe2ee1f 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -1,8 +1,8 @@ /* * linux/drivers/ide/cy82c693.c Version 0.34 Dec. 13, 1999 * - * Copyright (C) 1998-99 Andreas S. Krebs (akrebs@altavista.net), Maintainer - * Copyright (C) 1998-99 Andre Hedrick, Integrater + * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>, Integrater * * CYPRESS CY82C693 chipset IDE controller * diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index 74806824219b9b..2011b6a266ff34 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c @@ -67,11 +67,13 @@ static int __init gayle_offsets[IDE_NR_PORTS] = { #define GAYLE_NUM_HWIFS 1 #define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS #define GAYLE_HAS_CONTROL_REG 1 +#define GAYLE_IDEREG_SIZE 0x2000 #else /* CONFIG_BLK_DEV_IDEDOUBLER */ #define GAYLE_NUM_HWIFS 2 #define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \ GAYLE_NUM_HWIFS-1) #define GAYLE_HAS_CONTROL_REG (!ide_doubler) +#define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) int ide_doubler = 0; /* support IDE doublers? */ #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ @@ -121,23 +123,27 @@ void __init gayle_init(void) ide_ack_intr_t *ack_intr; hw_regs_t hw; int index; + unsigned long phys_base, res_start, res_n; if (a4000) { - base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_4000); + phys_base = GAYLE_BASE_4000; irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000); ack_intr = gayle_ack_intr_a4000; } else { - base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_1200); + phys_base = GAYLE_BASE_1200; irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200); ack_intr = gayle_ack_intr_a1200; } + phys_base += i*GAYLE_NEXT_PORT; - if (GAYLE_HAS_CONTROL_REG) - ctrlport = base + GAYLE_CONTROL; - else - ctrlport = 0; + res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); + res_n = GAYLE_IDEREG_SIZE; - base += i*GAYLE_NEXT_PORT; + if (!request_mem_region(res_start, res_n, "IDE")) + continue; + + base = (ide_ioreg_t)ZTWO_VADDR(phys_base); + ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; ide_setup_ports(&hw, base, gayle_offsets, ctrlport, irqport, ack_intr, IRQ_AMIGA_PORTS); @@ -155,7 +161,9 @@ void __init gayle_init(void) break; #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ } - } + } else + release_mem_region(res_start, res_n); + #if 1 /* TESTING */ if (i == 1) { volatile u_short *addr = (u_short *)base; diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c index eb73c24456c88c..6fd109c83230a9 100644 --- a/drivers/ide/hd.c +++ b/drivers/ide/hd.c @@ -889,7 +889,7 @@ static int parse_hd_setup (char *line) { (void) get_options(line, ARRAY_SIZE(ints), ints); hd_setup(NULL, ints); - return 0; + return 1; } __setup("hd=", parse_hd_setup); diff --git a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c index 911068f7846139..cbd71e60ae852f 100644 --- a/drivers/ide/hpt34x.c +++ b/drivers/ide/hpt34x.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/hpt34x.c Version 0.30 Mar. 18, 2000 + * linux/drivers/ide/hpt34x.c Version 0.31 June. 9, 2000 * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * @@ -62,7 +62,7 @@ static struct pci_dev *bmide_dev; static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* @@ -360,7 +360,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive) unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name) { int i = 0; - unsigned long hpt34xIoBase = dev->resource[4].start; + unsigned long hpt34xIoBase = pci_resource_start(dev, 4); unsigned short cmd; unsigned long flags; @@ -371,7 +371,7 @@ unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name) pci_read_config_word(dev, PCI_COMMAND, &cmd); if (cmd & PCI_COMMAND_MEMORY) { - if (dev->resource[PCI_ROM_RESOURCE].start) { + if (pci_resource_start(dev, PCI_ROM_RESOURCE)) { pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", dev->resource[PCI_ROM_RESOURCE].start); } diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index 28232b5768dc51..74d3018c522686 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -1,13 +1,16 @@ /* - * linux/drivers/ide/hpt366.c Version 0.17 Mar. 18, 2000 + * linux/drivers/ide/hpt366.c Version 0.18 June. 9, 2000 * - * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * Thanks to HighPoint Technologies for their assistance, and hardware. * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his * donation of an ABit BP6 mainboard, processor, and memory acellerated * development and support. + * + * Note that final HPT370 support was done by force extraction of GPL. + * */ #include <linux/config.h> @@ -30,13 +33,26 @@ #include "ide_modes.h" -#undef DISPLAY_HPT366_TIMINGS +#define DISPLAY_HPT366_TIMINGS #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) #include <linux/stat.h> #include <linux/proc_fs.h> #endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ +extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); + +const char *quirk_drives[] = { + "QUANTUM FIREBALLlct08 08", + "QUANTUM FIREBALLP KA6.4", + "QUANTUM FIREBALLP LM20.5", + NULL +}; + +const char *bad_ata100_5[] = { + NULL +}; + const char *bad_ata66_4[] = { "WDC AC310200R", NULL @@ -60,70 +76,92 @@ const char *bad_ata33[] = { struct chipset_bus_clock_list_entry { byte xfer_speed; - unsigned int chipset_settings; + unsigned int chipset_settings_write; + unsigned int chipset_settings_read; }; struct chipset_bus_clock_list_entry forty_base [] = { - { XFER_UDMA_4 , 0x900fd943 }, - { XFER_UDMA_3 , 0x900ad943 }, - { XFER_UDMA_2 , 0x900bd943 }, - { XFER_UDMA_1 , 0x9008d943 }, - { XFER_UDMA_0 , 0x9008d943 }, - - { XFER_MW_DMA_2 , 0xa008d943 }, - { XFER_MW_DMA_1 , 0xa010d955 }, - { XFER_MW_DMA_0 , 0xa010d9fc }, - - { XFER_PIO_4 , 0xc008d963 }, - { XFER_PIO_3 , 0xc010d974 }, - { XFER_PIO_2 , 0xc010d997 }, - { XFER_PIO_1 , 0xc010d9c7 }, - { XFER_PIO_0 , 0xc018d9d9 }, - { 0 , 0x0120d9d9 } + { XFER_UDMA_4, 0x900fd943, 0x900fd943 }, + { XFER_UDMA_3, 0x900ad943, 0x900ad943 }, + { XFER_UDMA_2, 0x900bd943, 0x900bd943 }, + { XFER_UDMA_1, 0x9008d943, 0x9008d943 }, + { XFER_UDMA_0, 0x9008d943, 0x9008d943 }, + + { XFER_MW_DMA_2, 0xa008d943, 0xa008d943 }, + { XFER_MW_DMA_1, 0xa010d955, 0xa010d955 }, + { XFER_MW_DMA_0, 0xa010d9fc, 0xa010d9fc }, + + { XFER_PIO_4, 0xc008d963, 0xc008d963 }, + { XFER_PIO_3, 0xc010d974, 0xc010d974 }, + { XFER_PIO_2, 0xc010d997, 0xc010d997 }, + { XFER_PIO_1, 0xc010d9c7, 0xc010d9c7 }, + { XFER_PIO_0, 0xc018d9d9, 0xc018d9d9 }, + { 0, 0x0120d9d9, 0x0120d9d9 } }; struct chipset_bus_clock_list_entry thirty_three_base [] = { - { XFER_UDMA_4 , 0x90c9a731 }, - { XFER_UDMA_3 , 0x90cfa731 }, - { XFER_UDMA_2 , 0x90caa731 }, - { XFER_UDMA_1 , 0x90cba731 }, - { XFER_UDMA_0 , 0x90c8a731 }, - - { XFER_MW_DMA_2 , 0xa0c8a731 }, - { XFER_MW_DMA_1 , 0xa0c8a732 }, /* 0xa0c8a733 */ - { XFER_MW_DMA_0 , 0xa0c8a797 }, - - { XFER_PIO_4 , 0xc0c8a731 }, - { XFER_PIO_3 , 0xc0c8a742 }, - { XFER_PIO_2 , 0xc0d0a753 }, - { XFER_PIO_1 , 0xc0d0a7a3 }, /* 0xc0d0a793 */ - { XFER_PIO_0 , 0xc0d0a7aa }, /* 0xc0d0a7a7 */ - { 0 , 0x0120a7a7 } + { XFER_UDMA_4, 0x90c9a731, 0x90c9a731 }, + { XFER_UDMA_3, 0x90cfa731, 0x90cfa731 }, + { XFER_UDMA_2, 0x90caa731, 0x90caa731 }, + { XFER_UDMA_1, 0x90cba731, 0x90cba731 }, + { XFER_UDMA_0, 0x90c8a731, 0x90c8a731 }, + + { XFER_MW_DMA_2, 0xa0c8a731, 0xa0c8a731 }, + { XFER_MW_DMA_1, 0xa0c8a732, 0xa0c8a732 }, /* 0xa0c8a733 */ + { XFER_MW_DMA_0, 0xa0c8a797, 0xa0c8a797 }, + + { XFER_PIO_4, 0xc0c8a731, 0xc0c8a731 }, + { XFER_PIO_3, 0xc0c8a742, 0xc0c8a742 }, + { XFER_PIO_2, 0xc0d0a753, 0xc0d0a753 }, + { XFER_PIO_1, 0xc0d0a7a3, 0xc0d0a7a3 }, /* 0xc0d0a793 */ + { XFER_PIO_0, 0xc0d0a7aa, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ + { 0, 0x0120a7a7, 0x0120a7a7 } }; struct chipset_bus_clock_list_entry twenty_five_base [] = { - { XFER_UDMA_4 , 0x90c98521 }, - { XFER_UDMA_3 , 0x90cf8521 }, - { XFER_UDMA_2 , 0x90cf8521 }, - { XFER_UDMA_1 , 0x90cb8521 }, - { XFER_UDMA_0 , 0x90cb8521 }, - - { XFER_MW_DMA_2 , 0xa0ca8521 }, - { XFER_MW_DMA_1 , 0xa0ca8532 }, - { XFER_MW_DMA_0 , 0xa0ca8575 }, - - { XFER_PIO_4 , 0xc0ca8521 }, - { XFER_PIO_3 , 0xc0ca8532 }, - { XFER_PIO_2 , 0xc0ca8542 }, - { XFER_PIO_1 , 0xc0d08572 }, - { XFER_PIO_0 , 0xc0d08585 }, - { 0 , 0x01208585 } + { XFER_UDMA_4, 0x90c98521, 0x90c98521 }, + { XFER_UDMA_3, 0x90cf8521, 0x90cf8521 }, + { XFER_UDMA_2, 0x90cf8521, 0x90cf8521 }, + { XFER_UDMA_1, 0x90cb8521, 0x90cb8521 }, + { XFER_UDMA_0, 0x90cb8521, 0x90cb8521 }, + + { XFER_MW_DMA_2, 0xa0ca8521, 0xa0ca8521 }, + { XFER_MW_DMA_1, 0xa0ca8532, 0xa0ca8532 }, + { XFER_MW_DMA_0, 0xa0ca8575, 0xa0ca8575 }, + + { XFER_PIO_4, 0xc0ca8521, 0xc0ca8521 }, + { XFER_PIO_3, 0xc0ca8532, 0xc0ca8532 }, + { XFER_PIO_2, 0xc0ca8542, 0xc0ca8542 }, + { XFER_PIO_1, 0xc0d08572, 0xc0d08572 }, + { XFER_PIO_0, 0xc0d08585, 0xc0d08585 }, + { 0, 0x01208585, 0x01208585 } +}; + +struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = { + { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, + { XFER_UDMA_4, 0x16454e31, 0x16454e31 }, + { XFER_UDMA_3, 0x166d4e31, 0x166d4e31 }, + { XFER_UDMA_2, 0x16494e31, 0x16494e31 }, + { XFER_UDMA_1, 0x164d4e31, 0x164d4e31 }, + { XFER_UDMA_0, 0x16514e31, 0x16514e31 }, + + { XFER_MW_DMA_2, 0x26514e21, 0x26514e21 }, + { XFER_MW_DMA_1, 0x26514e33, 0x26514e33 }, + { XFER_MW_DMA_0, 0x26514e97, 0x26514e97 }, + + { XFER_PIO_4, 0x06514e21, 0x06514e21 }, + { XFER_PIO_3, 0x06514e22, 0x06514e22 }, + { XFER_PIO_2, 0x06514e33, 0x06514e33 }, + { XFER_PIO_1, 0x06914e43, 0x06914e43 }, + { XFER_PIO_0, 0x06914e57, 0x06914e57 }, + { 0, 0x06514e57, 0x06514e57 } }; #define HPT366_DEBUG_DRIVE_INFO 0 +#define HPT370_ALLOW_ATA100_5 1 #define HPT366_ALLOW_ATA66_4 1 #define HPT366_ALLOW_ATA66_3 1 @@ -139,7 +177,12 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) char *p = buffer; u32 bibma = bmide_dev->resource[4].start; u32 bibma2 = bmide2_dev->resource[4].start; + char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"}; u8 c0 = 0, c1 = 0; + u32 class_rev; + + pci_read_config_dword(bmide_dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; /* * at that point bibma+0x2 et bibma+0xa are byte registers @@ -149,7 +192,7 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) if (bmide2_dev) c1 = inb_p((unsigned short)bibma2 + 0x02); - p += sprintf(p, "\n HPT366 Chipset.\n"); + p += sprintf(p, "\n %s Chipset.\n", chipset_names[class_rev]); p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); p += sprintf(p, " %sabled %sabled\n", (c0&0x80) ? "dis" : " en", @@ -173,74 +216,74 @@ extern char *ide_xfer_verbose (byte xfer_rate); byte hpt363_shared_irq = 0; byte hpt363_shared_pin = 0; -static unsigned int pci_rev_check_hpt366 (struct pci_dev *dev) +static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev) { unsigned int class_rev; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; - return ((int) (class_rev == 0x03) ? 1 : 0); + return ((int) (class_rev > 0x02) ? 1 : 0); } static int check_in_drive_lists (ide_drive_t *drive, const char **list) { struct hd_driveid *id = drive->id; -#if HPT366_DEBUG_DRIVE_INFO - printk("check_in_drive_lists(%s, %p)\n", drive->name, list); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - while (*list) { - if (!strcmp(*list++,id->model)) { -#ifdef DEBUG - printk("%s: Broken ASIC, BackSpeeding (U)DMA for %s\n", drive->name, id->model); -#endif /* DEBUG */ - return 1; + if (quirk_drives == list) { + while (*list) { + if (strstr(id->model, *list++)) { + return 1; + } + } + } else { + while (*list) { + if (!strcmp(*list++,id->model)) { + return 1; + } } } return 0; } -static unsigned int pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table) +static unsigned int pci_bus_clock_list (byte speed, int direction, struct chipset_bus_clock_list_entry * chipset_table) { -#if HPT366_DEBUG_DRIVE_INFO - printk("pci_bus_clock_list(speed=0x%02x, table=%p)\n", speed, chipset_table); -#endif /* HPT366_DEBUG_DRIVE_INFO */ for ( ; chipset_table->xfer_speed ; chipset_table++) if (chipset_table->xfer_speed == speed) { -#if HPT366_DEBUG_DRIVE_INFO - printk("pci_bus_clock_list: found match: 0x%08x\n", chipset_table->chipset_settings); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - return chipset_table->chipset_settings; + return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read; } -#if HPT366_DEBUG_DRIVE_INFO - printk("pci_bus_clock_list: using default: 0x%08x\n", 0x01208585); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - return 0x01208585; + return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read; } -static int hpt366_tune_chipset (ide_drive_t *drive, byte speed) +static void hpt366_tune_chipset (ide_drive_t *drive, byte speed, int direction) { - int err; byte regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40; + byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; + /* + * since the channel is always 0 it does not matter. + */ + unsigned int reg1 = 0; unsigned int reg2 = 0; + byte drive_fast = 0; -#if HPT366_DEBUG_DRIVE_INFO - printk("hpt366_tune_chipset(%s, speed=0x%02x)\n", drive->name, speed); -#endif /* HPT366_DEBUG_DRIVE_INFO */ + /* + * Disable the "fast interrupt" prediction. + */ + pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast); + if (drive_fast & 0x02) + pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x20); pci_read_config_dword(HWIF(drive)->pci_dev, regtime, ®1); /* 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, ®51h); + (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, ®5a); + 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, ®50h); - pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0x03); pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); - /* ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); */ -#endif + pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, ®52h); + pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5ah); + 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, ®5ah); + if (reg5ah & 0x10) /* interrupt force enable */ + pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10); + hwif->dmaproc = &hpt370_dmaproc; + hwif->rwproc = &hpt370_rw_proc; + } else { + hwif->dmaproc = &hpt366_dmaproc; + } hwif->autodma = 1; } else { hwif->autodma = 0; @@ -571,19 +680,16 @@ void ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase) { byte masterdma = 0, slavedma = 0; byte dma_new = 0, dma_old = inb(dmabase+2); + byte primary = hwif->channel ? 0x4b : 0x43; + byte secondary = hwif->channel ? 0x4f : 0x47; unsigned long flags; - if (pci_rev_check_hpt366(hwif->pci_dev)) { - ide_setup_dma(hwif, dmabase, 8); - return; - } - __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ dma_new = dma_old; - pci_read_config_byte(hwif->pci_dev, 0x43, &masterdma); - pci_read_config_byte(hwif->pci_dev, 0x47, &slavedma); + pci_read_config_byte(hwif->pci_dev, primary, &masterdma); + pci_read_config_byte(hwif->pci_dev, secondary, &slavedma); if (masterdma & 0x30) dma_new |= 0x20; if (slavedma & 0x30) dma_new |= 0x40; diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index dcc50362faae8c..7d5bfaedffbc19 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -351,7 +351,7 @@ icside_config_if(ide_drive_t *drive, int xfer_mode) static int icside_set_speed(ide_drive_t *drive, byte speed) { - return ((int) icside_config_if(drive, (int) speed)); + return icside_config_if(drive, speed); } static int @@ -508,9 +508,9 @@ icside_setup_dma(ide_hwif_t *hwif, int autodma) goto failed; } - hwif->dmaproc = &icside_dmaproc; + hwif->speedproc = icside_set_speed; + hwif->dmaproc = icside_dmaproc; hwif->autodma = autodma; - hwif->speedproc = &icside_set_speed; printk(" capable%s\n", autodma ? ", auto-enable" : ""); diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d209c29fff0885..ab4d3afbb9e158 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -426,11 +426,13 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, while (hi > lo) { mid = (lo + hi) / 2; - if (packet_command_texts[mid].packet_command == failed_command->c[0]) { + if (packet_command_texts[mid].packet_command == + failed_command->c[0]) { s = packet_command_texts[mid].text; break; } - else if (packet_command_texts[mid].packet_command > failed_command->c[0]) + if (packet_command_texts[mid].packet_command > + failed_command->c[0]) hi = mid; else lo = mid+1; @@ -1524,7 +1526,7 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense) memset(&pc, 0, sizeof(pc)); pc.sense = sense; pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; - pc.c[4] = lockflag ? 3 : 0; + pc.c[4] = lockflag ? 1 : 0; stat = cdrom_queue_packet_command (drive, &pc); } @@ -1624,7 +1626,8 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, /* Try to read the entire TOC for the disk into our internal buffer. */ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) { - int stat, ntracks, i; + int minor, stat, ntracks, i; + kdev_t dev; struct cdrom_info *info = drive->driver_data; struct atapi_toc *toc = info->toc; struct { @@ -1663,8 +1666,10 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) #endif /* not STANDARD_ATAPI */ ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; - if (ntracks <= 0) return -EIO; - if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS; + if (ntracks <= 0) + return -EIO; + if (ntracks > MAX_TRACKS) + ntracks = MAX_TRACKS; /* Now read the whole schmeer. */ stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0, @@ -1755,13 +1760,13 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track); /* Now try to get the total cdrom capacity. */ -#if 0 - stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor), - (long *)&toc->capacity); + minor = (drive->select.b.unit) << PARTN_BITS; + dev = MKDEV(HWIF(drive)->major, minor); + stat = cdrom_get_last_written(dev, (long *)&toc->capacity); if (stat) -#endif - stat = cdrom_read_capacity(drive, &toc->capacity, sense); - if (stat) toc->capacity = 0x1fffff; + stat = cdrom_read_capacity(drive, &toc->capacity, sense); + if (stat) + toc->capacity = 0x1fffff; /* Remember that we've read this stuff. */ CDROM_STATE_FLAGS (drive)->toc_valid = 1; @@ -2552,7 +2557,8 @@ unsigned long ide_cdrom_capacity (ide_drive_t *drive) { unsigned capacity; - return cdrom_read_capacity(drive, &capacity, NULL) ? 0 : capacity * SECTORS_PER_FRAME; + return cdrom_read_capacity(drive, &capacity, NULL) + ? 0 : capacity * SECTORS_PER_FRAME; } static diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 4e29520180495d..ae9f62768c5593 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1,14 +1,13 @@ /* - * linux/drivers/ide/ide-disk.c Version 1.09 April 23, 1999 + * linux/drivers/ide/ide-disk.c Version 1.10 June 9, 2000 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ /* * Mostly written by Mark Lord <mlord@pobox.com> - * and Gadi Oxman <gadio@netvision.net.il> - * - * See linux/MAINTAINERS for address of current maintainer. + * and Gadi Oxman <gadio@netvision.net.il> + * and Andre Hedrick <andre@linux-ide.org> * * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c. * @@ -27,9 +26,10 @@ * the entire disk. * Version 1.09 added increment of rq->sector in ide_multwrite * added UDMA 3/4 reporting + * Version 1.10 request queue changes, Ultra DMA 100 */ -#define IDEDISK_VERSION "1.09" +#define IDEDISK_VERSION "1.10" #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -140,11 +140,8 @@ static ide_startstop_t read_intr (ide_drive_t *drive) int i; unsigned int msect, nsect; struct request *rq; -#if 0 - if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { - return ide_error(drive, "read_intr", stat); - } -#else /* new way for dealing with premature shared PCI interrupts */ + + /* new way for dealing with premature shared PCI interrupts */ if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { return ide_error(drive, "read_intr", stat); @@ -153,7 +150,6 @@ static ide_startstop_t read_intr (ide_drive_t *drive) ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); return ide_started; } -#endif msect = drive->mult_count; read_next: @@ -688,7 +684,6 @@ static int set_nowerr(ide_drive_t *drive, int arg) { if (ide_spin_wait_hwgroup(drive)) return -EBUSY; - drive->nowerr = arg; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; spin_unlock_irq(&io_request_lock); diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 835fa91e34e465..e9a34afc1a7203 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/ide-dma.c Version 4.09 April 23, 1999 + * linux/drivers/ide/ide-dma.c Version 4.10 June 9, 2000 * - * Copyright (c) 1999 Andre Hedrick + * Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License */ @@ -70,12 +70,11 @@ * * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports. * - * ACARD ATP850UF Chipset "Modified SCSI Class" with other names - * AEC6210 U/UF - * SIIG's UltraIDE Pro CN-2449 - * TTI HPT343 Chipset "Modified SCSI Class" but reports as an - * unknown storage device. - * NEW check_drive_lists(ide_drive_t *drive, int good_bad) + * check_drive_lists(ide_drive_t *drive, int good_bad) + * + * ATA-66/100 and recovery functions, I forgot the rest...... + * SELECT_READ_WRITE(hwif,drive,func) for active tuning based on IO direction. + * */ #include <linux/config.h> @@ -358,10 +357,11 @@ int report_drive_dmaing (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - if ((id->field_valid & 4) && (id->hw_config & 0x2000) && - (HWIF(drive)->udma_four) && - (id->dma_ultra & (id->dma_ultra >> 11) & 3)) { - if ((id->dma_ultra >> 12) & 1) { + if ((id->field_valid & 4) && (eighty_ninty_three(drive)) && + (id->dma_ultra & (id->dma_ultra >> 11) & 7)) { + if ((id->dma_ultra >> 13) & 1) { + printk(", UDMA(100)"); /* UDMA BIOS-enabled! */ + } else if ((id->dma_ultra >> 12) & 1) { printk(", UDMA(66)"); /* UDMA BIOS-enabled! */ } else { printk(", UDMA(44)"); /* UDMA BIOS-enabled! */ @@ -393,9 +393,9 @@ static int config_drive_for_dma (ide_drive_t *drive) if (ide_dmaproc(ide_dma_bad_drive, drive)) return hwif->dmaproc(ide_dma_off, drive); - /* Enable DMA on any drive that has UltraDMA (mode 3/4) enabled */ - if ((id->field_valid & 4) && (hwif->udma_four) && (id->hw_config & 0x2000)) - if ((id->dma_ultra & (id->dma_ultra >> 11) & 3)) + /* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */ + if ((id->field_valid & 4) && (eighty_ninty_three(drive))) + if ((id->dma_ultra & (id->dma_ultra >> 11) & 7)) return hwif->dmaproc(ide_dma_on, drive); /* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */ if (id->field_valid & 4) /* UltraDMA */ @@ -413,6 +413,22 @@ static int config_drive_for_dma (ide_drive_t *drive) } /* + * 1 dmaing, 2 error, 4 intr + */ +static int dma_timer_expiry (ide_drive_t *drive) +{ + byte dma_stat = inb(HWIF(drive)->dma_base+2); + +#ifdef DEBUG + printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat); +#endif /* DEBUG */ + + if (dma_stat & 1) /* DMAing */ + return WAIT_CMD; + return 0; +} + +/* * ide_dmaproc() initiates/aborts DMA read/write operations on a drive. * * The caller is assumed to have selected the drive and programmed the drive's @@ -451,6 +467,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) case ide_dma_read: reading = 1 << 3; case ide_dma_write: + SELECT_READ_WRITE(hwif,drive,func); if (!(count = ide_build_dmatable(drive, func))) return 1; /* try PIO instead of DMA */ outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ @@ -459,7 +476,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ + ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); case ide_dma_begin: /* Note that this is done *after* the cmd has @@ -570,8 +587,8 @@ unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const if (hwif->mate && hwif->mate->dma_base) { dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8); } else { - dma_base = dev->resource[4].start; - if (!dma_base || dma_base == PCI_BASE_ADDRESS_IO_MASK) { + dma_base = pci_resource_start(dev, 4); + if (!dma_base) { printk("%s: dma_base is invalid (0x%04lx)\n", name, dma_base); dma_base = 0; } diff --git a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c index cb3790fa62f4f5..967b91e55c199f 100644 --- a/drivers/ide/ide-features.c +++ b/drivers/ide/ide-features.c @@ -1,14 +1,16 @@ /* - * linux/drivers/block/ide-features.c Version 0.03 Feb. 10, 2000 + * linux/drivers/block/ide-features.c Version 0.04 June 9, 2000 * * Copyright (C) 1999-2000 Linus Torvalds & authors (see below) * - * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * * Extracts if ide.c to address the evolving transfer rate code for * the SETFEATURES_XFER callouts. Various parts of any given function * are credited to previous ATA-IDE maintainers. * + * Auto-CRC downgrade for Ultra DMA(ing) + * * May be copied or modified under the terms of the GNU General Public License */ @@ -115,6 +117,10 @@ char *ide_dmafunc_verbose (ide_dma_action_t dmafunc) */ byte ide_auto_reduce_xfer (ide_drive_t *drive) { + if (!drive->crc_count) + return drive->current_speed; + drive->crc_count = 0; + switch(drive->current_speed) { case XFER_UDMA_7: return XFER_UDMA_6; case XFER_UDMA_6: return XFER_UDMA_5; @@ -164,6 +170,7 @@ int ide_driveid_update (ide_drive_t *drive) probe_irq_off(probe_irq_on()); irqs = probe_irq_on(); + SELECT_MASK(HWIF(drive), drive, 1); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); ide_delay_50ms(); @@ -173,17 +180,20 @@ int ide_driveid_update (ide_drive_t *drive) if (0 < (signed long)(jiffies - timeout)) { if (irqs) (void) probe_irq_off(irqs); + SELECT_MASK(HWIF(drive), drive, 0); return 0; /* drive timed-out */ } ide_delay_50ms(); /* give drive a breather */ } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT); ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { + SELECT_MASK(HWIF(drive), drive, 0); printk("%s: CHECK for good STATUS\n", drive->name); return 0; } __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only; some systems need this */ + SELECT_MASK(HWIF(drive), drive, 0); id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); ide_input_data(drive, id, SECTOR_WORDS); (void) GET_STAT(); /* clear drive IRQ */ @@ -214,11 +224,15 @@ int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature) (nsect > XFER_UDMA_2) && (feature == SETFEATURES_XFER)) { if (!HWIF(drive)->udma_four) { - printk("%s: Speed warnings UDMA 3/4 is not functional.\n", HWIF(drive)->name); + printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name); return 1; } +#ifndef CONFIG_IDEDMA_IVB + if ((drive->id->hw_config & 0x6000) == 0) { +#else /* !CONFIG_IDEDMA_IVB */ if ((drive->id->hw_config & 0x2000) == 0) { - printk("%s: Speed warnings UDMA 3/4 is not functional.\n", drive->name); +#endif /* CONFIG_IDEDMA_IVB */ + printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name); return 1; } } @@ -244,6 +258,18 @@ int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature) } /* + * All hosts that use the 80c ribbon mus use! + */ +byte eighty_ninty_three (ide_drive_t *drive) +{ + return ((byte) ((HWIF(drive)->udma_four) && +#ifndef CONFIG_IDEDMA_IVB + (drive->id->hw_config & 0x4000) && +#endif /* CONFIG_IDEDMA_IVB */ + (drive->id->hw_config & 0x2000)) ? 1 : 0); +} + +/* * Similar to ide_wait_stat(), except it never calls ide_error internally. * This is a kludge to handle the new ide_config_drive_speed() function, * and should not otherwise be used anywhere. Eventually, the tuneproc's @@ -260,10 +286,11 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) int i, error = 1; byte stat; -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) byte unit = (drive->select.b.unit & 0x01); outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ + /* * Don't use ide_wait_cmd here - it will * attempt to set_geometry and recalibrate, @@ -276,6 +303,7 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) disable_irq(hwif->irq); /* disable_irq_nosync ?? */ udelay(1); SELECT_DRIVE(HWIF(drive), drive); + SELECT_MASK(HWIF(drive), drive, 0); udelay(1); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); @@ -315,6 +343,8 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) } } + SELECT_MASK(HWIF(drive), drive, 0); + enable_irq(hwif->irq); if (error) { @@ -326,13 +356,13 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) drive->id->dma_mword &= ~0x0F00; drive->id->dma_1word &= ~0x0F00; -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (speed > XFER_PIO_4) { outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); } else { outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); } -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ switch(speed) { case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break; @@ -358,5 +388,5 @@ EXPORT_SYMBOL(ide_auto_reduce_xfer); EXPORT_SYMBOL(ide_driveid_update); EXPORT_SYMBOL(ide_ata66_check); EXPORT_SYMBOL(set_transfer); +EXPORT_SYMBOL(eighty_ninty_three); EXPORT_SYMBOL(ide_config_drive_speed); - diff --git a/drivers/ide/ide-geometry.c b/drivers/ide/ide-geometry.c index a291785971cf52..639d4c6f1c07ae 100644 --- a/drivers/ide/ide-geometry.c +++ b/drivers/ide/ide-geometry.c @@ -3,7 +3,7 @@ */ #include <linux/config.h> -#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD) +#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD_ONLY) #include <linux/ide.h> #include <asm/io.h> @@ -211,4 +211,4 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg) drive->bios_cyl, drive->bios_head, drive->bios_sect); return ret; } -#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD) */ +#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD_ONLY) */ diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c index c10ae4b51cbf91..8c935439491718 100644 --- a/drivers/ide/ide-pci.c +++ b/drivers/ide/ide-pci.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-pci.c Version 1.04 July 27, 1999 + * linux/drivers/ide/ide-pci.c Version 1.05 June 9, 2000 * * Copyright (c) 1998-2000 Andre Hedrick <andre@linux-ide.org> * @@ -33,10 +33,13 @@ #define DEVID_PIIX4E2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1}) #define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1}) #define DEVID_PIIX4U2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1}) +#define DEVID_PIIX4NX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX}) +#define DEVID_PIIX4U3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82820FW_5}) #define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561}) #define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1}) #define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246}) #define DEVID_PDC20262 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262}) +#define DEVID_PDC20267 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267}) #define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000}) #define DEVID_RZ1001 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001}) #define DEVID_SAMURAI ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE}) @@ -44,6 +47,7 @@ #define DEVID_CMD643 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643}) #define DEVID_CMD646 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646}) #define DEVID_CMD648 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648}) +#define DEVID_CMD649 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649}) #define DEVID_SIS5513 ((ide_pci_devid_t){PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513}) #define DEVID_OPTI621 ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621}) #define DEVID_OPTI621V ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558}) @@ -65,6 +69,7 @@ #define DEVID_CY82C693 ((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693}) #define DEVID_HINT ((ide_pci_devid_t){0x3388, 0x8013}) #define DEVID_CS5530 ((ide_pci_devid_t){PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE}) +#define DEVID_AMD7403 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7403}) #define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409}) #define IDE_IGNORE ((void *)-1) @@ -288,7 +293,7 @@ typedef struct ide_pci_enablebit_s { typedef struct ide_pci_device_s { ide_pci_devid_t devid; - const char *name; + char *name; unsigned int (*init_chipset)(struct pci_dev *dev, const char *name); unsigned int (*ata66_check)(ide_hwif_t *hwif); void (*init_hwif)(ide_hwif_t *hwif); @@ -307,10 +312,13 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_PIIX4E2, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4U, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4U2, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIX4NX, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIX4U3, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, + {DEVID_PDC20267,"PDC20267", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, {DEVID_RZ1000, "RZ1000", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_RZ1001, "RZ1001", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_SAMURAI, "SAMURAI", NULL, NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, @@ -320,6 +328,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_CMD643, "CMD643", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_CMD646, "CMD646", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_CMD648, "CMD648", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_CMD649, "CMD649", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HT6565, "HT6565", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_OPTI621, "OPTI621", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, {DEVID_OPTI621X,"OPTI621X", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, @@ -338,6 +347,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_CY82C693,"CY82C693", PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_CS5530, "CS5530", PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_AMD7403, "AMD7403", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AMD7409, "AMD7409", PCI_AMD7409, ATA66_AMD7409, INIT_AMD7409, DMA_AMD7409, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; @@ -352,6 +362,7 @@ static unsigned int __init ide_special_settings (struct pci_dev *dev, const char case PCI_DEVICE_ID_TTI_HPT366: case PCI_DEVICE_ID_PROMISE_20246: case PCI_DEVICE_ID_PROMISE_20262: + case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_ARTOP_ATP850UF: case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860R: @@ -510,6 +521,14 @@ check_if_enabled: pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; + + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) { + /* see comments in hpt34x.c on why..... */ + char *chipset_names[] = {"HPT343", "HPT345"}; + strcpy(d->name, chipset_names[(pcicmd & PCI_COMMAND_MEMORY)]); + d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; + } + printk("%s: chipset revision %d\n", d->name, class_rev); /* @@ -541,10 +560,7 @@ check_if_enabled: printk("%s: 100%% native mode on irq %d\n", d->name, pciirq); #endif } - if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) { - /* see comments in hpt34x.c on why..... */ - d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; - } + /* * Set up the IDE ports */ @@ -553,14 +569,14 @@ check_if_enabled: ide_pci_enablebit_t *e = &(d->enablebits[port]); if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val)) continue; /* port not enabled */ - if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev != 0x03)) + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev < 0x03)) return; if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE || (dev->class & (port ? 4 : 1)) != 0) { ctl = dev->resource[(2*port)+1].start; base = dev->resource[2*port].start; if (!(ctl & PCI_BASE_ADDRESS_IO_MASK) || !(base & PCI_BASE_ADDRESS_IO_MASK)) { - printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@suse.com>.\n", d->name); + printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@linux-ide.org>.\n", d->name); #if 0 /* FIXME! This really should check that it really gets the IO/MEM part right! */ continue; @@ -603,19 +619,21 @@ check_if_enabled: goto bypass_umc_dma; } if (hwif->udma_four) { - printk("%s: ATA-66 forced bit set (WARNING)!!\n", d->name); + printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name); } else { hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0; } #ifdef CONFIG_BLK_DEV_IDEDMA if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_PIIX4NX) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) autodma = 0; if (autodma) hwif->autodma = 1; if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) || @@ -625,6 +643,7 @@ check_if_enabled: IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name); if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { @@ -665,6 +684,7 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic ide_pci_device_t *d2; unsigned char pin1 = 0, pin2 = 0; unsigned int class_rev; + char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"}; if (PCI_FUNC(dev->devfn) & 1) return; @@ -672,8 +692,13 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; + strcpy(d->name, chipset_names[class_rev]); + switch(class_rev) { - case 3: return; + case 4: + case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); + ide_setup_pci_device(dev, d); + return; default: break; } @@ -700,15 +725,6 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic return; d2 = d; printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn); - if (hpt363_shared_pin && !hpt363_shared_irq) { - printk("%s: IDE controller run unsupported mode three!!!\n", d2->name); -#ifndef CONFIG_HPT366_MODE3 - printk("%s: IDE controller report to <andre@suse.com>\n", d->name); - return; -#else /* CONFIG_HPT366_MODE3 */ - printk("%s: OVERRIDE IDE controller not advisable this mode!!!\n", d2->name); -#endif /* CONFIG_HPT366_MODE3 */ - } ide_setup_pci_device(dev2, d2); } diff --git a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c index 45bbe77ac13096..83cea6ba2bd615 100644 --- a/drivers/ide/ide-pmac.c +++ b/drivers/ide/ide-pmac.c @@ -813,12 +813,6 @@ pmac_ide_dma_onoff(ide_drive_t *drive, int enable) return 0; } -static int -pmac_ide_tune_chipset(ide_drive_t *drive, byte speed) -{ - return 0; -} - int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index ddf6c8daefa78e..dd5f660fecc88d 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-probe.c Version 1.05 July 3, 1999 + * linux/drivers/ide/ide-probe.c Version 1.06 June 9, 2000 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -7,6 +7,7 @@ /* * Mostly written by Mark Lord <mlord@pobox.com> * and Gadi Oxman <gadio@netvision.net.il> + * and Andre Hedrick <andre@linux-ide.org> * * See linux/MAINTAINERS for address of current maintainer. * @@ -23,6 +24,7 @@ * added ide6/7/8/9 * allowed for secondary flash card to be detectable * with new flag : drive->ata_flash : 1; + * Version 1.06 stream line request queue and prep for cascade project. */ #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -41,6 +43,7 @@ #include <linux/malloc.h> #include <linux/delay.h> #include <linux/ide.h> +#include <linux/spinlock.h> #include <asm/byteorder.h> #include <asm/irq.h> @@ -167,6 +170,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) } drive->media = ide_disk; printk("ATA DISK drive\n"); + QUIRK_LIST(HWIF(drive),drive); return; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index a3394807b16684..932c6f1142f2f9 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide.c Version 6.30 Dec 28, 1999 + * linux/drivers/ide/ide.c Version 6.31 June 9, 2000 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -7,6 +7,7 @@ /* * Mostly written by Mark Lord <mlord@pobox.com> * and Gadi Oxman <gadio@netvision.net.il> + * and Andre Hedrick <andre@linux-ide.org> * * See linux/MAINTAINERS for address of current maintainer. * @@ -109,6 +110,9 @@ * Version 6.21 Fixing/Fixed SMP spinlock issue with insight from an old * hat that clarified original low level driver design. * Version 6.30 Added SMP support; fixed multmode issues. -ml + * Version 6.31 Debug Share INTR's and request queue streaming + * Native ATA-100 support + * Prep for Cascades Project * * Some additional driver compile-time options are in ./include/linux/ide.h * @@ -117,8 +121,8 @@ * */ -#define REVISION "Revision: 6.30" -#define VERSION "Id: ide.c 6.30 1999/12/28" +#define REVISION "Revision: 6.31" +#define VERSION "Id: ide.c 6.31 2000/06/09" #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -482,7 +486,8 @@ static inline int drive_is_ready (ide_drive_t *drive) #if 0 udelay(1); /* need to guarantee 400ns since last command was issued */ #endif - if (GET_STAT() & BUSY_STAT) /* Note: this may clear a pending IRQ!! */ +// if (GET_STAT() & BUSY_STAT) /* Note: this may clear a pending IRQ!! */ + if (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT) return 0; /* drive busy: definitely not interrupting */ return 1; /* drive ready: *might* be interrupting */ } @@ -651,6 +656,19 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) return ide_stopped; } +static void check_dma_crc (ide_drive_t *drive) +{ + if (drive->crc_count) { + (void) HWIF(drive)->dmaproc(ide_dma_off_quietly, drive); + if ((HWIF(drive)->speedproc) != NULL) + HWIF(drive)->speedproc(drive, ide_auto_reduce_xfer(drive)); + if (drive->current_speed >= XFER_SW_DMA_0) + (void) HWIF(drive)->dmaproc(ide_dma_on, drive); + } else { + (void) HWIF(drive)->dmaproc(ide_dma_off, drive); + } +} + static void pre_reset (ide_drive_t *drive) { if (drive->driver != NULL) @@ -658,12 +676,15 @@ static void pre_reset (ide_drive_t *drive) if (!drive->keep_settings) { if (drive->using_dma) { - (void) HWIF(drive)->dmaproc(ide_dma_off, drive); + check_dma_crc(drive); } else { drive->unmask = 0; drive->io_32bit = 0; } + return; } + if (drive->using_dma) + check_dma_crc(drive); } /* @@ -902,9 +923,9 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat) if (err == ABRT_ERR) { if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY) return ide_stopped; /* some newer drives don't support WIN_SPECIFY */ - } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) - ; /* UDMA crc error -- just retry the operation */ - else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */ + } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) { + drive->crc_count++; /* UDMA crc error -- just retry the operation */ + } else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */ rq->errors = ERROR_MAX; else if (err & TRK0_ERR) /* help it find track zero */ rq->errors |= ERROR_RECAL; @@ -941,6 +962,7 @@ void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) ide_set_handler (drive, handler, WAIT_CMD, NULL); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ + SELECT_MASK(HWIF(drive),drive,0); OUT_BYTE(nsect,IDE_NSECTOR_REG); OUT_BYTE(cmd,IDE_COMMAND_REG); } @@ -1298,7 +1320,7 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) hwif = HWIF(drive); if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && hwif->io_ports[IDE_CONTROL_OFFSET]) { /* set nIEN for previous hwif */ - OUT_BYTE(hwgroup->drive->ctl|2, hwgroup->hwif->io_ports[IDE_CONTROL_OFFSET]); + SELECT_INTERRUPT(hwif, drive); } hwgroup->hwif = hwif; hwgroup->drive = drive; @@ -1316,13 +1338,13 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) * happens anyway when any interrupt comes in, IDE or otherwise * -- the kernel masks the IRQ while it is being handled. */ - if (hwif->irq != masked_irq) + if (masked_irq && hwif->irq != masked_irq) disable_irq_nosync(hwif->irq); spin_unlock(&io_request_lock); ide__sti(); /* allow other IRQs while we start this request */ startstop = start_request(drive); spin_lock_irq(&io_request_lock); - if (hwif->irq != masked_irq) + if (masked_irq && hwif->irq != masked_irq) enable_irq(hwif->irq); if (startstop == ide_stopped) hwgroup->busy = 0; @@ -1404,7 +1426,11 @@ void ide_timer_expiry (unsigned long data) */ spin_unlock(&io_request_lock); hwif = HWIF(drive); +#if DISABLE_IRQ_NOSYNC + disable_irq_nosync(hwif->irq); +#else disable_irq(hwif->irq); /* disable_irq_nosync ?? */ +#endif /* DISABLE_IRQ_NOSYNC */ __cli(); /* local CPU only, as if we were handling an interrupt */ if (hwgroup->poll_timeout != 0) { startstop = handler(drive); @@ -2008,12 +2034,12 @@ void ide_unregister (unsigned int index) else hwgroup->hwif = HWIF(hwgroup->drive); -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (hwif->dma_base) { (void) ide_release_dma(hwif); hwif->dma_base = 0; } -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ /* * Remove us from the kernel's knowledge @@ -2048,6 +2074,10 @@ void ide_unregister (unsigned int index) hwif->speedproc = old_hwif.speedproc; hwif->selectproc = old_hwif.selectproc; hwif->resetproc = old_hwif.resetproc; + hwif->intrproc = old_hwif.intrproc; + hwif->maskproc = old_hwif.maskproc; + hwif->quirkproc = old_hwif.quirkproc; + hwif->rwproc = old_hwif.rwproc; hwif->dmaproc = old_hwif.dmaproc; hwif->dma_base = old_hwif.dma_base; hwif->dma_extra = old_hwif.dma_extra; @@ -2275,17 +2305,18 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive) unsigned long timeout = jiffies + (3 * HZ); spin_lock_irq(&io_request_lock); + while (hwgroup->busy) { - unsigned long flags; + unsigned long lflags; spin_unlock_irq(&io_request_lock); - __save_flags(flags); /* local CPU only */ + __save_flags(lflags); /* local CPU only */ __sti(); /* local CPU only; needed for jiffies */ if (0 < (signed long)(jiffies - timeout)) { - __restore_flags(flags); + __restore_flags(lflags); /* local CPU only */ printk("%s: channel busy\n", drive->name); return -EBUSY; } - __restore_flags(flags); /* local CPU only */ + __restore_flags(lflags); /* local CPU only */ spin_lock_irq(&io_request_lock); } return 0; @@ -2422,13 +2453,13 @@ int ide_wait_cmd_task (ide_drive_t *drive, byte *buf) */ void ide_delay_50ms (void) { -#if 0 +#ifndef CONFIG_BLK_DEV_IDECS unsigned long timeout = jiffies + ((HZ + 19)/20) + 1; while (0 < (signed long)(timeout - jiffies)); #else __set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(HZ/20); -#endif +#endif /* CONFIG_BLK_DEV_IDECS */ } int system_bus_clock (void) @@ -2576,7 +2607,6 @@ static int ide_ioctl (struct inode *inode, struct file *file, err = -EFAULT; return err; } - case HDIO_SCAN_HWIF: { int args[3]; @@ -3266,6 +3296,7 @@ void __init ide_init_builtin_drivers (void) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { ide_get_lock(&ide_lock, NULL, NULL); /* for atari only */ disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */ +// disable_irq_nosync(ide_hwifs[0].irq); } #endif /* __mc68000__ || CONFIG_APUS */ @@ -3619,10 +3650,10 @@ void cleanup_module (void) for (index = 0; index < MAX_HWIFS; ++index) { ide_unregister(index); -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (ide_hwifs[index].dma_base) (void) ide_release_dma(&ide_hwifs[index]); -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ } #ifdef CONFIG_PROC_FS @@ -3636,6 +3667,7 @@ void cleanup_module (void) static int parse_ide_setup (char *line) { parse_options(line); + /* We MUST return 0 as otherwise no subsequent __setup option works... */ return 0; } __setup("", parse_ide_setup); diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 70f1851088d0b4..1837f01e0edff1 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c @@ -3,7 +3,7 @@ * * Copyright (C) 1997-1998 Mark Lord <mlord@pobox.com> * Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be> - * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * * Inspired by an earlier effort from David S. Miller <davem@redhat.com> */ diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c index f16d3392143590..66a12384133ba4 100644 --- a/drivers/ide/pdc202xx.c +++ b/drivers/ide/pdc202xx.c @@ -1,7 +1,7 @@ /* * linux/drivers/ide/pdc202xx.c Version 0.30 Mar. 18, 2000 * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this @@ -12,6 +12,8 @@ * Promise Ultra66 cards with BIOS v1.11 this * compiled into the kernel if you have more than one card installed. * + * Promise Ultra100 cards. + * * The latest chipset code will support the following :: * Three Ultra33 controllers and 12 drives. * 8 are UDMA supported and 4 are limited to DMA mode 2 multi-word. @@ -51,6 +53,10 @@ #define DISPLAY_PDC202XX_TIMINGS +#ifndef SPLIT_BYTE +#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) +#endif + #if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) #include <linux/stat.h> #include <linux/proc_fs.h> @@ -99,10 +105,25 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0; u16 reg50h = 0, pmask = (1<<10), smask = (1<<11); - u8 c0 = 0, c1 = 0; + u8 hi = 0, lo = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + u8 c0 = inb_p((unsigned short)bibma + 0x02); + u8 c1 = inb_p((unsigned short)bibma + 0x0a); + + u8 sc11 = inb_p((unsigned short)bibma + 0x11); + u8 sc1a = inb_p((unsigned short)bibma + 0x1a); + u8 sc1b = inb_p((unsigned short)bibma + 0x1b); + u8 sc1c = inb_p((unsigned short)bibma + 0x1c); + u8 sc1d = inb_p((unsigned short)bibma + 0x1d); + u8 sc1e = inb_p((unsigned short)bibma + 0x1e); + u8 sc1f = inb_p((unsigned short)bibma + 0x1f); pci_read_config_word(bmide_dev, 0x50, ®50h); pci_read_config_dword(bmide_dev, 0x60, ®60h); @@ -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, ®68h); pci_read_config_dword(bmide_dev, 0x6c, ®6ch); - /* - * at that point bibma+0x2 et bibma+0xa are byte registers - * to investigate: - */ - c0 = inb_p((unsigned short)bibma + 0x02); - c1 = inb_p((unsigned short)bibma + 0x0a); - - switch(bmide_dev->device) { + switch(bmide_dev->device) { + case PCI_DEVICE_ID_PROMISE_20267: + p += sprintf(p, "\n PDC20267 Chipset.\n"); + break; case PCI_DEVICE_ID_PROMISE_20262: p += sprintf(p, "\n PDC20262 Chipset.\n"); break; @@ -130,9 +147,40 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count break; } + p += sprintf(p, "------------------------------- General Status ---------------------------------\n"); + p += sprintf(p, "Burst Mode : %sabled\n", (sc1f & 0x01) ? "en" : "dis"); + p += sprintf(p, "Host Mode : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal"); + p += sprintf(p, "Bus Clocking : %s\n", + ((sc1f & 0xC0) == 0xC0) ? "100 External" : + ((sc1f & 0x80) == 0x80) ? "66 External" : + ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal"); + p += sprintf(p, "IO pad select : %s mA\n", + ((sc1c & 0x03) == 0x03) ? "10" : + ((sc1c & 0x02) == 0x02) ? "8" : + ((sc1c & 0x01) == 0x01) ? "6" : + ((sc1c & 0x00) == 0x00) ? "4" : "??"); + SPLIT_BYTE(sc1e, hi, lo); + p += sprintf(p, "Status Polling Period : %d\n", hi); + p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); - p += sprintf(p, " %sabled %sabled\n", - (c0&0x80)?"dis":" en",(c1&0x80)?"dis":" en"); + p += sprintf(p, " %s %s\n", + (c0&0x80)?"disabled":"enabled ", + (c1&0x80)?"disabled":"enabled "); + p += sprintf(p, "66 Clocking %s %s\n", + (sc11&0x02)?"enabled ":"disabled", + (sc11&0x08)?"enabled ":"disabled"); + p += sprintf(p, " Mode %s Mode %s\n", + (sc1a & 0x01) ? "MASTER" : "PCI ", + (sc1b & 0x01) ? "MASTER" : "PCI "); + p += sprintf(p, " %s %s\n", + (sc1d & 0x08) ? "Error " : + (sc1d & 0x04) ? "Interrupting" : + (sc1d & 0x02) ? "FIFO Full " : + (sc1d & 0x01) ? "FIFO Empty " : "????????????", + (sc1d & 0x80) ? "Error " : + (sc1d & 0x40) ? "Interrupting" : + (sc1d & 0x20) ? "FIFO Full " : + (sc1d & 0x10) ? "FIFO Empty " : "????????????"); p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n"); p += sprintf(p, "DMA enabled: %s %s %s %s\n", (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no "); @@ -141,9 +189,13 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)), pdc202xx_ultra_verbose(reg68h, (reg50h & smask)), pdc202xx_ultra_verbose(reg6ch, (reg50h & smask))); - p += sprintf(p, " PIO Mode: %s %s %s %s\n", + p += sprintf(p, "PIO Mode: %s %s %s %s\n", pdc202xx_pio_verbose(reg60h),pdc202xx_pio_verbose(reg64h), pdc202xx_pio_verbose(reg68h),pdc202xx_pio_verbose(reg6ch)); +#if 0 + p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n"); +#endif + return p-buffer; /* => must be less than 4k! */ } #endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */ @@ -324,6 +376,7 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed) switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA + case XFER_UDMA_5: case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; /* speed 8 == UDMA mode 4 */ case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; /* speed 7 == UDMA mode 3 */ case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; /* speed 6 == UDMA mode 2 */ @@ -408,7 +461,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); @@ -418,8 +471,9 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte AP; unsigned short EP; byte CLKSPD = IN_BYTE(high_16 + 0x11); - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; byte udma_33 = ultra ? (inb(high_16 + 0x001f) & 1) : 0; + byte udma_66 = ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0; + byte udma_100 = ((dev->device == PCI_DEVICE_ID_PROMISE_20267) && udma_66) ? 1 : 0; /* * Set the control register to use the 66Mhz system @@ -436,11 +490,15 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte mask = hwif->channel ? 0x08 : 0x02; unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10); - byte ultra_66 = ((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008)) ? 1 : 0; + byte ultra_66 = ((id->dma_ultra & 0x0010) || + (id->dma_ultra & 0x0008)) ? 1 : 0; + byte ultra_100 = ((id->dma_ultra & 0x0020) || + (id->dma_ultra & 0x0010) || + (id->dma_ultra & 0x0008)) ? 1 : 0; pci_read_config_word(dev, 0x50, &EP); - if ((ultra_66) && (EP & c_mask)) { + if (((ultra_66) || (ultra_100)) && (EP & c_mask)) { #ifdef DEBUG printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary", "Primary"); printk(" Switching to Ultra33 mode.\n"); @@ -449,13 +507,14 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) /* Secondary : zero out fourth bit */ OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); } else { - if (ultra_66) { + if ((ultra_66) || (ultra_100)) { /* * check to make sure drive on same channel * is u66 capable */ if (hwif->drives[!(drive->dn%2)].id) { - if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || + if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) || + (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) { OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); } else { @@ -517,17 +576,18 @@ chipset_is_set: if (drive->media == ide_disk) /* PREFETCH_EN */ pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); - if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) speed = XFER_UDMA_4; - else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) speed = XFER_UDMA_3; - else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2; - else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1; - else if ((id->dma_ultra & 0x0001) && (udma_33)) speed = XFER_UDMA_0; - else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2; - else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1; - else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0; - else if (id->dma_1word & 0x0004) speed = XFER_SW_DMA_2; - else if (id->dma_1word & 0x0002) speed = XFER_SW_DMA_1; - else if (id->dma_1word & 0x0001) speed = XFER_SW_DMA_0; + if ((id->dma_ultra & 0x0020) && (udma_100)) speed = XFER_UDMA_5; + else if ((id->dma_ultra & 0x0010) && (udma_66)) speed = XFER_UDMA_4; + else if ((id->dma_ultra & 0x0008) && (udma_66)) speed = XFER_UDMA_3; + else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2; + else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1; + else if ((id->dma_ultra & 0x0001) && (udma_33)) speed = XFER_UDMA_0; + else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2; + else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1; + else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0; + else if (id->dma_1word & 0x0004) speed = XFER_SW_DMA_2; + else if (id->dma_1word & 0x0002) speed = XFER_SW_DMA_1; + else if (id->dma_1word & 0x0001) speed = XFER_SW_DMA_0; else { /* restore original pci-config space */ pci_write_config_dword(dev, drive_pci, drive_conf); @@ -537,7 +597,7 @@ chipset_is_set: outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); (void) pdc202xx_tune_chipset(drive, speed); - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ((id->dma_1word >> 8) & 7) ? ide_dma_on : @@ -558,7 +618,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, 1); if ((id->field_valid & 2) && @@ -603,6 +663,10 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_lostirq: + case ide_dma_timeout: + if (HWIF(drive)->resetproc != NULL) + HWIF(drive)->resetproc(drive); default: break; } @@ -610,14 +674,29 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) } #endif /* CONFIG_BLK_DEV_IDEDMA */ +void pdc202xx_reset (ide_drive_t *drive) +{ + unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4); + byte udma_speed_flag = inb(high_16 + 0x001f); + int i = 0; + + OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f); + ide_delay_50ms(); + ide_delay_50ms(); + OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f); + for (i = 0; i < 40; i++) + ide_delay_50ms(); +} + unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) { - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); byte udma_speed_flag = inb(high_16 + 0x001f); byte primary_mode = inb(high_16 + 0x001a); byte secondary_mode = inb(high_16 + 0x001b); - if (dev->device == PCI_DEVICE_ID_PROMISE_20262) { + if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) || + (dev->device == PCI_DEVICE_ID_PROMISE_20267)) { int i = 0; /* * software reset - this is required because the bios @@ -646,7 +725,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) byte irq = 0, irq2 = 0; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ - if (irq != irq2) { + if ((irq != irq2) && (dev->device != PCI_DEVICE_ID_PROMISE_20267)) { pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ printk("%s: pci-config space interrupt mirror fixed.\n", name); } @@ -705,8 +784,12 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif) void __init ide_init_pdc202xx (ide_hwif_t *hwif) { - hwif->tuneproc = &pdc202xx_tune_drive; - hwif->speedproc = &pdc202xx_tune_chipset; + hwif->tuneproc = &pdc202xx_tune_drive; + hwif->speedproc = &pdc202xx_tune_chipset; + + if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) || + (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) + hwif->resetproc = &pdc202xx_reset; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 56c1852361d43b..0dbb8d88382bf5 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -1,8 +1,8 @@ /* - * linux/drivers/ide/piix.c Version 0.31 Mar. 18, 2000 + * linux/drivers/ide/piix.c Version 0.32 June 9, 2000 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * PIO mode setting function for Intel chipsets. @@ -83,7 +83,7 @@ static struct pci_dev *bmide_dev; static int piix_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0; u8 c0 = 0, c1 = 0; u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0; @@ -108,10 +108,14 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count) c1 = inb_p((unsigned short)bibma + 0x0a); switch(bmide_dev->device) { + case PCI_DEVICE_ID_INTEL_82820FW_5: + p += sprintf(p, "\n Intel PIIX4 Ultra 100 Chipset.\n"); + break; case PCI_DEVICE_ID_INTEL_82372FB_1: case PCI_DEVICE_ID_INTEL_82801AA_1: p += sprintf(p, "\n Intel PIIX4 Ultra 66 Chipset.\n"); break; + case PCI_DEVICE_ID_INTEL_82451NX: case PCI_DEVICE_ID_INTEL_82801AB_1: case PCI_DEVICE_ID_INTEL_82443MX_1: case PCI_DEVICE_ID_INTEL_82371AB: @@ -142,21 +146,25 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count) (reg48&0x04) ? "yes" : "no ", (reg48&0x08) ? "yes" : "no " ); p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + ((reg54&0x11) && (reg55&0x10) && (reg4a&0x01)) ? "5" : ((reg54&0x11) && (reg4a&0x02)) ? "4" : ((reg54&0x11) && (reg4a&0x01)) ? "3" : (reg4a&0x02) ? "2" : (reg4a&0x01) ? "1" : (reg4a&0x00) ? "0" : "X", + ((reg54&0x22) && (reg55&0x20) && (reg4a&0x10)) ? "5" : ((reg54&0x22) && (reg4a&0x20)) ? "4" : ((reg54&0x22) && (reg4a&0x10)) ? "3" : (reg4a&0x20) ? "2" : (reg4a&0x10) ? "1" : (reg4a&0x00) ? "0" : "X", + ((reg54&0x44) && (reg55&0x40) && (reg4b&0x03)) ? "5" : ((reg54&0x44) && (reg4b&0x02)) ? "4" : ((reg54&0x44) && (reg4b&0x01)) ? "3" : (reg4b&0x02) ? "2" : (reg4b&0x01) ? "1" : (reg4b&0x00) ? "0" : "X", + ((reg54&0x88) && (reg55&0x80) && (reg4b&0x30)) ? "5" : ((reg54&0x88) && (reg4b&0x20)) ? "4" : ((reg54&0x88) && (reg4b&0x10)) ? "3" : (reg4b&0x20) ? "2" : @@ -188,6 +196,7 @@ extern char *ide_xfer_verbose (byte xfer_rate); */ static byte piix_dma_2_pio (byte xfer_rate) { switch(xfer_rate) { + case XFER_UDMA_5: case XFER_UDMA_4: case XFER_UDMA_3: case XFER_UDMA_2: @@ -286,6 +295,7 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed) switch(speed) { case XFER_UDMA_4: case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; + case XFER_UDMA_5: case XFER_UDMA_3: case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; @@ -298,7 +308,11 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed) if (speed >= XFER_UDMA_0) { if (!(reg48 & u_flag)) pci_write_config_word(dev, 0x48, reg48|u_flag); - pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag); + if (speed == XFER_UDMA_5) { + pci_write_config_byte(dev, 0x55, (byte) reg55|w_flag); + } else { + pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag); + } if (!(reg4a & u_speed)) { pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); pci_write_config_word(dev, 0x4a, reg4a|u_speed); @@ -341,15 +355,20 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) struct pci_dev *dev = hwif->pci_dev; byte speed; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; - int ultra66 = ((dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || + byte udma_66 = eighty_ninty_three(drive); + int ultra100 = ((dev->device == PCI_DEVICE_ID_INTEL_82820FW_5)) ? 1 : 0; + int ultra66 = ((ultra100) || + (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0; int ultra = ((ultra66) || (dev->device == PCI_DEVICE_ID_INTEL_82371AB) || (dev->device == PCI_DEVICE_ID_INTEL_82443MX_1) || + (dev->device == PCI_DEVICE_ID_INTEL_82451NX) || (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0; - if ((id->dma_ultra & 0x0010) && (ultra)) { + if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra)) { speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; } else if ((id->dma_ultra & 0x0008) && (ultra)) { speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; @@ -371,7 +390,7 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) (void) piix_tune_chipset(drive, speed); - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ((id->dma_1word >> 8) & 7) ? ide_dma_on : diff --git a/drivers/ide/qd6580.c b/drivers/ide/qd6580.c index 4c00de5042f13e..5787b73f21a470 100644 --- a/drivers/ide/qd6580.c +++ b/drivers/ide/qd6580.c @@ -1,16 +1,19 @@ /* - * linux/drivers/ide/qd6580.c Version 0.03 May 13, 2000 + * linux/drivers/ide/qd6580.c Version 0.04 June 4, 2000 * * Copyright (C) 1996-2000 Linus Torvalds & author (see below) */ /* * Version 0.03 Cleaned auto-tune, added probe - * + * Version 0.04 Added second channel tuning + * * QDI QD6580 EIDE controller fast support - * + * * To activate controller support use kernel parameter "ide0=qd6580" * To enable tuning use kernel parameter "ide0=autotune" + * To enable tuning second channel (not really tested), + * use parameter "ide1=autotune" */ /* @@ -36,146 +39,254 @@ #include "ide_modes.h" /* - * I/O ports are 0xb0 0xb1 0xb2 and 0xb3 - * or 0x30 0x31 0x32 and 0x33 + * I/O ports are 0xb0-0xb3 + * or 0x30-0x33 * -- this is a dual IDE interface with I/O chips * * More research on qd6580 being done by willmore@cig.mot.com (David) + * More Information given by Petr Sourcek (petr@ryston.cz) + * http://www.ryston.cz/petr/vlb */ -/* +/* * 0xb0: Timer1 * - * - * 0xb1: Status * - * && 0xf0 is either 0b1010000 or 0b01010000, or else it isn't a qd6580 - * bit 3 & 2: unknown (useless ?) I have 0 & 1, respectively - * bit 1: 1 if qd6580 baseport is 0xb0 - * 0 if qd6580 baseport is 0x30 - * bit 0: 1 if ide baseport is 0x1f0 - * 0 if ide baseport is 0x170 + * 0xb1: Config + * + * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170 * (? Strange: the Dos driver uses it, and then forces baseport to 0x1f0 ?) - * - * + * bit 1: qd baseport: 1 = 0xb0 ; 0 = 0x30 + * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz + * bit 3: 1 for qd6580 + * upper nibble is either 1010 or 0101, or else it isn't a qd6580 + * + * * 0xb2: Timer2 * - * + * * 0xb3: Control * - * bits 0-3 are always set 1 - * bit 6 : if 1, must be set 1 - * bit 1 : if 1, bit 7 must be set 1 - * bit 0 : if 1, drives are independant, we can have two different timers for - * the two drives. - * if 0, we have to take the slowest drive into account, - * but we may tune the second hwif ? + * bits 0-3 must always be set 1 + * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock + * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb + * 0 = Primary and Secondary ports enabled : channel 0 for hda & hdb + * channel 1 for hdc & hdd + * bit 1 : 1 = only disks on primary port + * 0 = disks & ATAPI devices on primary port + * bit 2-4 : always 0 + * bit 5 : status, but of what ? + * bit 6 : always set 1 by dos driver + * bit 7 : set 1 for non-ATAPI devices (read-ahead and post-write buffer ?) */ +/* truncates a in [b,c] */ +#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) ) + typedef struct ide_hd_timings_s { int active_time; /* Active pulse (ns) minimum */ int recovery_time; /* Recovery pulse (ns) minimum */ } ide_hd_timings_t; static int basePort; /* base port address (0x30 or 0xb0) */ -static byte status; /* status register of qd6580 */ +static byte config; /* config register of qd6580 */ static byte control; /* control register of qd6580 */ -/* truncates a in [b,c] */ -#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) ) - static int bus_clock; /* Vesa local bus clock (ns) */ static int tuned=0; /* to remember whether we've already been tuned */ +static int snd_tuned=0; /* to remember whether we've already been tuned */ +static int nb_disks_prim=0; /* number of disk drives on primary port */ + +/* + * write_reg + * + * writes the specified byte on the specified register + */ + +static void write_reg ( byte content, byte reg ) +{ + unsigned long flags; + + save_flags(flags); /* all CPUs */ + cli(); /* all CPUs */ + outb_p(content,reg); + inb(0x3f6); + restore_flags(flags); /* all CPUs */ +} /* * tune_drive * - * Finds timings for the specified drive, returns it in struc t + * Finds timings for the specified drive, returns it in struct t */ -static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t) +static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t ) { ide_pio_data_t d; - t->active_time = 0xaf; - t->recovery_time = 0x19f; /* worst cases values from the dos driver */ + t->active_time = 175; + t->recovery_time = 415; /* worst cases values from the dos driver */ - if (drive->present == 0) { /* not present : free to give any timing */ - t->active_time = 0x0; - t->recovery_time = 0x0; + if (!drive->present) { /* not present : free to give any timing */ + t->active_time = 0; + t->recovery_time = 0; return; } - - pio = ide_get_best_pio_mode(drive, pio, 4, &d); - - if (pio) { - - switch (pio) { - case 0: break; - case 3: t->active_time = 0x56; - t->recovery_time = d.cycle_time-0x66; - break; - case 4: t->active_time = 0x46; - t->recovery_time = d.cycle_time-0x3d; - break; - default: if (d.cycle_time >= 0xb4) { - t->active_time = 0x6e; - t->recovery_time = d.cycle_time - 0x78; - } else { - t->active_time = ide_pio_timings[pio].active_time; - t->recovery_time = d.cycle_time - -t->active_time - -ide_pio_timings[pio].setup_time; - } - } - } + + pio = ide_get_best_pio_mode(drive, pio, 255, &d); + pio = IDE_MIN(pio,4); + + switch (pio) { + case 0: break; + case 3: + if (d.cycle_time >= 110) { + t->active_time = 86; + t->recovery_time = d.cycle_time-102; + } else { + printk("%s: Strange recovery time !\n",drive->name); + return; + } + break; + case 4: + if (d.cycle_time >= 69) { + t->active_time = 70; + t->recovery_time = d.cycle_time-61; + } else { + printk("%s: Strange recovery time !\n",drive->name); + return; + } + break; + default: + if (d.cycle_time >= 180) { + t->active_time = 110; + t->recovery_time = d.cycle_time - 120; + } else { + t->active_time = ide_pio_timings[pio].active_time; + t->recovery_time = d.cycle_time + -t->active_time; + } + } printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time); + + if (drive->media == ide_disk) + nb_disks_prim++; + else { +/* need to disable read-ahead FIFO and post-write buffer for ATAPI drives*/ + write_reg(0x5f,basePort+0x03); + printk("%s: Warning: please try to connect this drive to secondary IDE port\nto improve data transfer rate on primary IDE port.\n",drive->name); + } } -/* +/* + * tune_snd_drive + * + * Finds timings for the specified drive, using second channel rules + */ + +static void tune_snd_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t ) +{ + ide_pio_data_t d; + + t->active_time = 175; + t->recovery_time = 415; + + if (!drive->present) { /* not present : free to give any timing */ + t->active_time = 0; + t->recovery_time = 0; + return; + } + + pio = ide_get_best_pio_mode(drive, pio, 255, &d); + + if ((pio) && (d.cycle_time >= 180)) { + t->active_time = 115; + t->recovery_time = d.cycle_time - 115; + } + printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time); + + if ((drive->media == ide_disk) && (nb_disks_prim<2)) { +/* a disk drive on secondary port while there's room on primary, which is the + * only one that has read-ahead fifo and post-write buffer ? What a waste !*/ + printk("%s: Warning: please try to connect this drive to primary IDE port\nto improve data transfer rate.\n",drive->name); + } +} + +/* + * compute_timing + * + * computes the timing value where + * lower nibble is active time, in count of VLB clocks, 17-(from 2 to 17) + * upper nibble is recovery time, in count of VLB clocks, 15-(from 2 to 15) + */ + +static byte compute_timing ( char name[6], ide_hd_timings_t *t ) +{ + byte active_cycle; + byte recovery_cycle; + byte parameter; + + active_cycle = 17-IDE_IN(t->active_time / bus_clock + 1, 2, 17); + recovery_cycle = 15-IDE_IN(t->recovery_time / bus_clock + 1, 2, 15); + + parameter = active_cycle | (recovery_cycle<<4); + + printk("%s: tim1=%dns tim2=%dns => %#x\n", name, t[0].active_time, t[0].recovery_time, parameter); + return(parameter); +} + +/* * tune_ide * - * Tunes the whole ide, ie tunes each drives, and takes the worst timings - * to tune qd6580 + * Tunes the whole hwif, ie tunes each drives, and in case we have to share, + * takes the worse timings to tune qd6580 */ static void tune_ide ( ide_hwif_t *hwif, byte pio ) { unsigned long flags; ide_hd_timings_t t[2]={{0,0},{0,0}}; - - byte active_cycle; - byte recovery_cycle; - byte parameter; int bus_speed = ide_system_bus_speed (); - + bus_clock = 1000 / bus_speed; - + save_flags(flags); /* all CPUs */ cli(); /* all CPUs */ outb( (bus_clock<30) ? 0x0 : 0x0a, basePort + 0x02); outb( 0x40 | ((control & 0x02) ? 0x9f:0x1f), basePort+0x03); - restore_flags(flags); + restore_flags(flags); tune_drive (&hwif->drives[0], pio, &t[0]); tune_drive (&hwif->drives[1], pio, &t[1]); + if (control & 0x01) { /* only primary port enabled, can tune separately */ + write_reg(compute_timing (hwif->drives[0].name, &t[0]),basePort); + write_reg(compute_timing (hwif->drives[1].name, &t[1]),basePort+0x02); + } else { /* both ports enabled, we have to share */ + + t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time); + t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time); + write_reg(compute_timing (hwif->name, &t[0]),basePort); + } +} + +/* + * tune_snd_ide + * + * Tunes the whole secondary hwif, ie tunes each drives, and takes the worse + * timings to tune qd6580 + */ + +static void tune_snd_ide ( ide_hwif_t *hwif, byte pio ) +{ + ide_hd_timings_t t[2]={{0,0},{0,0}}; + + tune_snd_drive (&hwif->drives[0], pio, &t[0]); + tune_snd_drive (&hwif->drives[1], pio, &t[1]); + t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time); t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time); - - active_cycle = 17-IDE_IN(t[0].active_time / bus_clock + 1, 2, 17); - recovery_cycle = 15-IDE_IN(t[0].recovery_time / bus_clock + 1, 2, 15); - - parameter=active_cycle | (recovery_cycle<<4); - - printk("%s: tim1=%dns tim2=%dns => %#x\n", hwif->name, t[0].active_time, t[0].recovery_time, parameter); - - save_flags(flags); /* all CPUs */ - cli(); /* all CPUs */ - outb_p(parameter,0xb0); - inb(0x3f6); - restore_flags(flags); /* all CPUs */ - + + write_reg(compute_timing (hwif->name, &t[0]),basePort+0x02); } /* @@ -193,6 +304,20 @@ static void tune_qd6580 (ide_drive_t *drive, byte pio) } /* + * tune_snd_qd6580 + * + * tunes the second hwif if not tuned + */ + +static void tune_snd_qd6580 (ide_drive_t *drive, byte pio) +{ + if (! snd_tuned) { + tune_snd_ide(HWIF(drive), pio); + snd_tuned = 1; + } +} + +/* * testreg * * tests if the given port is a register @@ -203,7 +328,7 @@ static int __init testreg(int port) byte savereg; byte readreg; unsigned long flags; - + save_flags(flags); /* all CPUs */ cli(); /* all CPUs */ savereg = inb(port); @@ -214,14 +339,15 @@ static int __init testreg(int port) if (savereg == 0x15) { printk("Outch ! the probe for qd6580 isn't reliable !\n"); - printk("Please contact samuel.thibault@fnac.net to tell about your hardware\n"); - printk("Assuming qd6580 is present"); + printk("Please contact maintainers to tell about your hardware\n"); + printk("Assuming qd6580 is not present.\n"); + return 0; } return (readreg == 0x15); } -/* +/* * trybase: * * tries to find a qd6580 at the given base and save it if found @@ -233,20 +359,20 @@ static int __init trybase (int base) save_flags(flags); /* all CPUs */ cli(); /* all CPUs */ - status = inb(base+0x01); + config = inb(base+0x01); control = inb(base+0x03); restore_flags(flags); /* all CPUs */ - if (((status & 0xf0) != 0x50) && ((status & 0xf0) != 0xa0)) return(0); - if (! ( ((status & 0x02) == 0x0) == (base == 0x30) ) ) return (0); + if (((config & 0xf0) != 0x50) && ((config & 0xf0) != 0xa0)) return(0); + if (! ( ((config & 0x02) == 0x0) == (base == 0x30) ) ) return (0); /* Seems to be OK, let's use it */ - + basePort = base; return(testreg(base)); } -/* +/* * probe: * * probes qd6580 at 0xb0 (the default) or 0x30 @@ -257,6 +383,11 @@ static int __init probe (void) return (trybase(0xb0) ? 1 : trybase(0x30)); } +/* + * init_qd6580: + * + * called at the very beginning of initialization ; should just probe and link + */ void __init init_qd6580 (void) { @@ -264,13 +395,16 @@ void __init init_qd6580 (void) printk("qd6580: not found\n"); return; } - - printk("qd6580: base=%#x, status=%#x, control=%#x\n", basePort, status, control); - + + printk("qd6580: base=%#x, config=%#x, control=%#x\n", basePort, config, control); + ide_hwifs[0].chipset = ide_qd6580; - ide_hwifs[1].chipset = ide_qd6580; ide_hwifs[0].tuneproc = &tune_qd6580; - ide_hwifs[0].mate = &ide_hwifs[1]; - ide_hwifs[1].mate = &ide_hwifs[0]; - ide_hwifs[1].channel = 1; + if (!(control & 0x01)) { + ide_hwifs[1].chipset = ide_qd6580; + ide_hwifs[1].tuneproc = &tune_snd_qd6580; + ide_hwifs[0].mate = &ide_hwifs[1]; + ide_hwifs[1].mate = &ide_hwifs[0]; + ide_hwifs[1].channel = 1; + } } diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c index be56a7f2489ac4..4f0a330863e618 100644 --- a/drivers/ide/sis5513.c +++ b/drivers/ide/sis5513.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/sis5513.c Version 0.10 Mar. 18, 2000 + * linux/drivers/ide/sis5513.c Version 0.11 June 9, 2000 * - * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * Thanks to SIS Taiwan for direct support and hardware. @@ -111,12 +111,12 @@ static int sis_get_info(char *, char **, off_t, int); extern int (*sis_display_info)(char *, char **, off_t, int); /* ide-proc.c */ static struct pci_dev *bmide_dev; -static char *cable_type[] __initdata = { +static char *cable_type[] = { "80 pins", "40 pins" }; -static char *recovery_time [] __initdata ={ +static char *recovery_time [] ={ "12 PCICLK", "1 PCICLK", "2 PCICLK", "3 PCICLK", "4 PCICLK", "5 PCICLCK", @@ -127,14 +127,14 @@ static char *recovery_time [] __initdata ={ "15 PCICLK", "15 PCICLK" }; -static char * cycle_time [] __initdata = { +static char * cycle_time [] = { "Undefined", "2 CLCK", "3 CLK", "4 CLK", "5 CLK", "6 CLK", "7 CLK", "8 CLK" }; -static char * active_time [] __initdata = { +static char * active_time [] = { "8 PCICLK", "1 PCICLCK", "2 PCICLK", "2 PCICLK", "4 PCICLK", "5 PCICLK", @@ -185,7 +185,7 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]); p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n", - active_time[(reg & 0x07)], active_time[(reg &0x07)] ); + active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); rc = pci_read_config_byte(bmide_dev, 0x40, ®); rc = pci_read_config_byte(bmide_dev, 0x44, ®1); @@ -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, ®); rc = pci_read_config_byte(bmide_dev, 0x46, ®1); @@ -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, ®52h); if (!(reg52h & 0x04)) { - /* set IDE controller to operate in Compabitility mode obly */ + /* set IDE controller to operate in Compabitility mode only */ pci_write_config_byte(dev, 0x52, reg52h|0x04); } #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c index e7ee2e9777b224..c1aa3fb4eddcaa 100644 --- a/drivers/ide/trm290.c +++ b/drivers/ide/trm290.c @@ -224,10 +224,10 @@ void __init ide_init_trm290 (ide_hwif_t *hwif) struct pci_dev *dev = hwif->pci_dev; hwif->chipset = ide_trm290; - cfgbase = dev->resource[4].start; + cfgbase = pci_resource_start(dev, 4); if ((dev->class & 5) && cfgbase) { - hwif->config_data = cfgbase & PCI_BASE_ADDRESS_IO_MASK; + hwif->config_data = cfgbase; printk("TRM290: chip config base at 0x%04lx\n", hwif->config_data); } else { hwif->config_data = 0x3df0; diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 6c201599f81f84..3ab29859669473 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -1,10 +1,10 @@ /* - * linux/drivers/ide/via82cxxx.c Version 0.09 Apr. 02, 2000 + * linux/drivers/ide/via82cxxx.c Version 0.10 June 9, 2000 * * Copyright (C) 1998-99 Michel Aubry, Maintainer * Copyright (C) 1999 Jeff Garzik, MVP4 Support * (jgarzik@mandrakesoft.com) - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * The VIA MVP-4 is reported OK with UDMA. @@ -101,19 +101,19 @@ static struct pci_dev *isa_dev = NULL; struct chipset_bus_clock_list_entry { byte xfer_speed; - byte chipset_settings_25; byte ultra_settings_25; - byte chipset_settings_33; + byte chipset_settings_25; byte ultra_settings_33; - byte chipset_settings_37; + byte chipset_settings_33; byte ultra_settings_37; - byte chipset_settings_41; + byte chipset_settings_37; byte ultra_settings_41; + byte chipset_settings_41; }; static struct chipset_bus_clock_list_entry * via82cxxx_table = NULL; -struct chipset_bus_clock_list_entry via82cxxx_type_one [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_one [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -134,7 +134,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_one [] = { { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xA9, 0x00, 0x00 } }; -struct chipset_bus_clock_list_entry via82cxxx_type_two [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_two [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -155,7 +155,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_two [] = { { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE } }; -struct chipset_bus_clock_list_entry via82cxxx_type_three [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_three [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -176,7 +176,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_three [] = { { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE } }; -struct chipset_bus_clock_list_entry via82cxxx_type_four [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_four [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0xE0, 0x20, 0xE1, 0x31, 0x00, 0x00 }, @@ -243,20 +243,20 @@ static const struct { #define arraysize(x) (sizeof(x)/sizeof(*(x))) -#undef DISPLAY_VIA_TIMINGS +#define DISPLAY_VIA_TIMINGS #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) #include <linux/stat.h> #include <linux/proc_fs.h> -static char *FIFO_str[] __initdata = { +static char *FIFO_str[] = { " 1 ", "3/4", "1/2", "1/4" }; -static char *control3_str[] __initdata = { +static char *control3_str[] = { "No limitation", "64", "128", @@ -760,11 +760,15 @@ static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; byte speed = 0x00; + byte ultra66 = eighty_ninty_three(drive); + byte ultra100 = 0; int rval; - if ((id->dma_ultra & 0x0010) && (HWIF(drive)->udma_four)) { + if ((id->dma_ultra & 0x0020) && (ultra66) && (ultra100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra66)) { speed = XFER_UDMA_4; - } else if ((id->dma_ultra & 0x0008) && (HWIF(drive)->udma_four)) { + } else if ((id->dma_ultra & 0x0008) && (ultra66)) { speed = XFER_UDMA_3; } else if (id->dma_ultra & 0x0004) { speed = XFER_UDMA_2; @@ -778,12 +782,6 @@ static int config_chipset_for_dma (ide_drive_t *drive) speed = XFER_MW_DMA_1; } else if (id->dma_mword & 0x0001) { speed = XFER_MW_DMA_0; - } else if (id->dma_1word & 0x0004) { - speed = XFER_SW_DMA_2; - } else if (id->dma_1word & 0x0002) { - speed = XFER_SW_DMA_1; - } else if (id->dma_1word & 0x0001) { - speed = XFER_SW_DMA_0; } else { return ((int) ide_dma_off_quietly); } @@ -793,7 +791,6 @@ static int config_chipset_for_dma (ide_drive_t *drive) rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : - ((id->dma_1word >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); return rval; } @@ -811,7 +808,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && @@ -820,8 +817,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } } else if (id->field_valid & 2) { try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { + if (id->dma_mword & 0x0007) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) @@ -870,7 +866,7 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name) byte revision = 0; for (i = 0; i < arraysize (ApolloHostChipInfo) && !host_dev; i++) { - host = pci_find_device (PCI_VENDOR_ID_VIA, + host = pci_find_device (ApolloHostChipInfo[i].vendor_id, ApolloHostChipInfo[i].host_id, NULL); if (!host) diff --git a/drivers/pnp/isapnp.c b/drivers/pnp/isapnp.c index 06bf946645abf2..497879619cbd5f 100644 --- a/drivers/pnp/isapnp.c +++ b/drivers/pnp/isapnp.c @@ -2059,14 +2059,14 @@ static void isapnp_free_all_resources(void) if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) release_resource(isapnp_rdp_res); #ifdef MODULE +#ifdef CONFIG_PROC_FS + isapnp_proc_done(); +#endif while (!list_empty(&isapnp_cards)) { struct list_head *list = isapnp_cards.next; list_del(list); isapnp_free_card(pci_bus_b(list)); } -#ifdef CONFIG_PROC_FS - isapnp_proc_done(); -#endif #endif } diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4fca4d14db5103..71b93e379a70cb 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -17,8 +17,8 @@ * any later version. * */ - static char * sg_version_str = "Version: 3.1.13 (20000323)"; - static int sg_version_num = 30113; /* 2 digits for each component */ + static char * sg_version_str = "Version: 3.1.15 (20000528)"; + static int sg_version_num = 30115; /* 2 digits for each component */ /* * D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes: * - scsi logging is available via SCSI_LOG_TIMEOUT macros. First @@ -113,7 +113,8 @@ static void sg_detach(Scsi_Device *); static Scsi_Cmnd * dummy_cmdp = 0; /* only used for sizeof */ -static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; +static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; /* Also used to lock + file descriptor list for device */ struct Scsi_Device_Template sg_template = { @@ -155,7 +156,7 @@ typedef struct sg_request /* SG_MAX_QUEUE requests outstanding per file */ char res_used; /* 1 -> using reserve buffer, 0 -> not ... */ char orphan; /* 1 -> drop on sight, 0 -> normal */ char sg_io_owned; /* 1 -> packet belongs to SG_IO */ - char done; /* 1 -> bh handler done, 0 -> prior to bh */ + char done; /* 0->before bh, 1->before read, 2->read */ } Sg_request; /* 168 bytes long on i386 */ typedef struct sg_fd /* holds the state of a file descriptor */ @@ -163,6 +164,7 @@ typedef struct sg_fd /* holds the state of a file descriptor */ struct sg_fd * nextfp; /* NULL when last opened fd on this device */ struct sg_device * parentdp; /* owning device */ wait_queue_head_t read_wait; /* queue read until command done */ + rwlock_t rq_list_lock; /* protect access to list in req_arr */ int timeout; /* defaults to SG_DEFAULT_TIMEOUT */ Sg_scatter_hold reserve; /* buffer held for this file descriptor */ unsigned save_scat_len; /* original length of trunc. scat. element */ @@ -176,7 +178,7 @@ typedef struct sg_fd /* holds the state of a file descriptor */ char cmd_q; /* 1 -> allow command queuing, 0 -> don't */ char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */ char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */ -} Sg_fd; /* 2760 bytes long on i386 */ +} Sg_fd; /* 2768 bytes long on i386 */ typedef struct sg_device /* holds the state of each scsi generic device */ { @@ -189,7 +191,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */ char exclude; /* opened for exclusive access */ char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */ char detached; /* 0->attached, 1->detached pending removal */ -} Sg_device; /* 40 bytes long on i386 */ +} Sg_device; /* 44 bytes long on i386 */ static int sg_fasync(int fd, struct file * filp, int mode); @@ -222,11 +224,11 @@ static char * sg_low_malloc(int rqSz, int lowDma, int mem_src, static void sg_low_free(char * buff, int size, int mem_src); static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev); static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp); -static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id); +static Sg_request * sg_get_rq_mark(Sg_fd * sfp, int pack_id); static Sg_request * sg_add_request(Sg_fd * sfp); static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); -static int sg_res_in_use(const Sg_fd * sfp); -static int sg_dio_in_use(const Sg_fd * sfp); +static int sg_res_in_use(Sg_fd * sfp); +static int sg_dio_in_use(Sg_fd * sfp); static void sg_clr_scpnt(Scsi_Cmnd * SCpnt); static void sg_shorten_timeout(Scsi_Cmnd * scpnt); static int sg_ms_to_jif(unsigned int msecs); @@ -364,7 +366,7 @@ static ssize_t sg_read(struct file * filp, char * buf, else req_pack_id = old_hdr.pack_id; } - srp = sg_get_request(sfp, req_pack_id); + srp = sg_get_rq_mark(sfp, req_pack_id); if (! srp) { /* now wait on packet to arrive */ if (filp->f_flags & O_NONBLOCK) return -EAGAIN; @@ -372,7 +374,7 @@ static ssize_t sg_read(struct file * filp, char * buf, int dio = sg_dio_in_use(sfp); res = 0; /* following is a macro that beats race condition */ __wait_event_interruptible(sfp->read_wait, - (srp = sg_get_request(sfp, req_pack_id)), + (srp = sg_get_rq_mark(sfp, req_pack_id)), res); if (0 == res) break; @@ -550,7 +552,7 @@ static ssize_t sg_write(struct file * filp, const char * buf, hp->cmd_len = (unsigned char)cmd_size; hp->iovec_count = 0; hp->mx_sb_len = 0; -#if 1 +#if 0 hp->dxfer_direction = SG_DXFER_UNKNOWN; #else if (input_size > 0) @@ -686,7 +688,7 @@ static int sg_common_write(Sg_fd * sfp, Sg_request * srp, srp->data.sglist_len = 0; srp->data.bufflen = 0; srp->data.buffer = NULL; - hp->duration = jiffies; + hp->duration = jiffies; /* unit jiffies now, millisecs after done */ /* Now send everything of to mid-level. The next time we hear about this packet is when sg_cmd_done_bh() is called (i.e. a callback). */ scsi_do_cmd(SCpnt, (void *)cmnd, @@ -703,6 +705,7 @@ static int sg_ioctl(struct inode * inode, struct file * filp, Sg_device * sdp; Sg_fd * sfp; Sg_request * srp; + unsigned long iflags; if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp))) return -ENXIO; @@ -740,6 +743,7 @@ static int sg_ioctl(struct inode * inode, struct file * filp, return result; /* -ERESTARTSYS because signal hit process */ } } + srp->done = 2; result = sg_new_read(sfp, (char *)arg, size_sg_io_hdr, srp); return (result < 0) ? result : 0; } @@ -794,24 +798,24 @@ static int sg_ioctl(struct inode * inode, struct file * filp, case SG_GET_PACK_ID: result = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int)); if (result) return result; - srp = sfp->headrp; - while (srp) { - if (srp->done && (! srp->sg_io_owned)) { + read_lock_irqsave(&sfp->rq_list_lock, iflags); + for (srp = sfp->headrp; srp; srp = srp->nextrp) { + if ((1 == srp->done) && (! srp->sg_io_owned)) { + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); __put_user(srp->header.pack_id, (int *)arg); return 0; } - srp = srp->nextrp; } + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); __put_user(-1, (int *)arg); return 0; case SG_GET_NUM_WAITING: - srp = sfp->headrp; - val = 0; - while (srp) { - if (srp->done && (! srp->sg_io_owned)) + read_lock_irqsave(&sfp->rq_list_lock, iflags); + for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) { + if ((1 == srp->done) && (! srp->sg_io_owned)) ++val; - srp = srp->nextrp; } + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); return put_user(val, (int *)arg); case SG_GET_SG_TABLESIZE: return put_user(sdp->sg_tablesize, (int *)arg); @@ -855,16 +859,17 @@ static int sg_ioctl(struct inode * inode, struct file * filp, if (result) return result; else { sg_req_info_t rinfo[SG_MAX_QUEUE]; - Sg_request * srp = sfp->headrp; - for (val = 0; val < SG_MAX_QUEUE; + Sg_request * srp; + read_lock_irqsave(&sfp->rq_list_lock, iflags); + for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE; ++val, srp = srp ? srp->nextrp : srp) { memset(&rinfo[val], 0, size_sg_req_info); if (srp) { - rinfo[val].req_state = srp->done ? 2 : 1; + rinfo[val].req_state = srp->done + 1; rinfo[val].problem = srp->header.masked_status & srp->header.host_status & srp->header.driver_status; rinfo[val].duration = srp->done ? - sg_jif_to_ms(srp->header.duration) : + srp->header.duration : sg_jif_to_ms(jiffies - srp->header.duration); rinfo[val].orphan = srp->orphan; rinfo[val].sg_io_owned = srp->sg_io_owned; @@ -872,6 +877,7 @@ static int sg_ioctl(struct inode * inode, struct file * filp, rinfo[val].usr_ptr = srp->header.usr_ptr; } } + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); __copy_to_user((void *)arg, rinfo, size_sg_req_info * SG_MAX_QUEUE); return 0; } @@ -882,8 +888,29 @@ static int sg_ioctl(struct inode * inode, struct file * filp, return -EBUSY; result = get_user(val, (int *)arg); if (result) return result; - /* Don't do anything till scsi mid level visibility */ - return 0; + if (SG_SCSI_RESET_NOTHING == val) + return 0; +#ifdef SCSI_TRY_RESET_DEVICE + switch (val) + { + case SG_SCSI_RESET_DEVICE: + val = SCSI_TRY_RESET_DEVICE; + break; + case SG_SCSI_RESET_BUS: + val = SCSI_TRY_RESET_BUS; + break; + case SG_SCSI_RESET_HOST: + val = SCSI_TRY_RESET_HOST; + break; + default: + return -EINVAL; + } + if(! capable(CAP_SYS_ADMIN)) return -EACCES; + return (scsi_reset_provider(sdp->device, val) == SUCCESS) ? 0 : -EIO; +#else + SCSI_LOG_TIMEOUT(1, printk("sg_ioctl: SG_RESET_SCSI not supported\n")); + result = -EINVAL; +#endif case SCSI_IOCTL_SEND_COMMAND: if (read_only) { unsigned char opcode = WRITE_6; @@ -918,17 +945,19 @@ static unsigned int sg_poll(struct file * filp, poll_table * wait) Sg_fd * sfp; Sg_request * srp; int count = 0; + unsigned long iflags; if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp))) return POLLERR; poll_wait(filp, &sfp->read_wait, wait); - srp = sfp->headrp; - while (srp) { /* if any read waiting, flag it */ - if ((0 == res) && srp->done && (! srp->sg_io_owned)) + read_lock_irqsave(&sfp->rq_list_lock, iflags); + for (srp = sfp->headrp; srp; srp = srp->nextrp) { + /* if any read waiting, flag it */ + if ((0 == res) && (1 == srp->done) && (! srp->sg_io_owned)) res = POLLIN | POLLRDNORM; ++count; - srp = srp->nextrp; } + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); if (! sfp->cmd_q) { if (0 == count) res |= POLLOUT | POLLWRNORM; @@ -960,11 +989,17 @@ static int sg_fasync(int fd, struct file * filp, int mode) static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt) { int dev = MINOR(SCpnt->request.rq_dev); - Sg_device * sdp; + Sg_device * sdp = NULL; Sg_fd * sfp; Sg_request * srp = NULL; - if (NULL == (sdp = sg_get_dev(dev))) { + read_lock(&sg_dev_arr_lock); + if (sg_dev_arr && (dev >= 0)) { + if (dev < sg_template.dev_max) + sdp = sg_dev_arr[dev]; + } + if (NULL == sdp) { + read_unlock(&sg_dev_arr_lock); SCSI_LOG_TIMEOUT(1, printk("sg...bh: bad args dev=%d\n", dev)); scsi_release_command(SCpnt); SCpnt = NULL; @@ -972,16 +1007,17 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt) } sfp = sdp->headfp; while (sfp) { - srp = sfp->headrp; - while (srp) { + read_lock(&sfp->rq_list_lock); + for (srp = sfp->headrp; srp; srp = srp->nextrp) { if (SCpnt == srp->my_cmdp) break; - srp = srp->nextrp; } + read_unlock(&sfp->rq_list_lock); if (srp) break; sfp = sfp->nextfp; } + read_unlock(&sg_dev_arr_lock); if (! srp) { SCSI_LOG_TIMEOUT(1, printk("sg...bh: req missing, dev=%d\n", dev)); scsi_release_command(SCpnt); @@ -1001,6 +1037,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt) dev, srp->header.pack_id, (int)SCpnt->result)); srp->header.resid = SCpnt->resid; /* sg_unmap_and(&srp->data, 0); */ /* unmap locked pages a.s.a.p. */ + /* N.B. unit of duration changes here from jiffies to millisecs */ srp->header.duration = sg_jif_to_ms(jiffies - (int)srp->header.duration); if (0 != SCpnt->result) { memcpy(srp->sense_b, SCpnt->sense_buffer, sizeof(srp->sense_b)); @@ -1052,8 +1089,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt) if (sfp && srp) { /* Now wake up any sg_read() that is waiting for this packet. */ wake_up_interruptible(&sfp->read_wait); - if (sfp->async_qp) - kill_fasync(sfp->async_qp, SIGPOLL, POLL_IN); + kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN); } } @@ -1091,18 +1127,18 @@ static int sg_detect(Scsi_Device * scsidp) static int sg_init() { static int sg_registered = 0; - unsigned long flags = 0; + unsigned long iflags; if ((sg_template.dev_noticed == 0) || sg_dev_arr) return 0; - write_lock_irqsave(&sg_dev_arr_lock, flags); + write_lock_irqsave(&sg_dev_arr_lock, iflags); if(!sg_registered) { if (devfs_register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops)) { printk("Unable to get major %d for generic SCSI device\n", SCSI_GENERIC_MAJOR); - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); return 1; } sg_registered++; @@ -1114,11 +1150,11 @@ static int sg_init() sizeof(Sg_device *), GFP_ATOMIC); if (NULL == sg_dev_arr) { printk("sg_init: no space for sg_dev_arr\n"); - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); return 1; } memset(sg_dev_arr, 0, sg_template.dev_max * sizeof(Sg_device *)); - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); #ifdef CONFIG_PROC_FS sg_proc_init(); #endif /* CONFIG_PROC_FS */ @@ -1149,10 +1185,10 @@ __setup("sg_def_reserved_size=", sg_def_reserved_size_setup); static int sg_attach(Scsi_Device * scsidp) { Sg_device * sdp; - unsigned long flags = 0; + unsigned long iflags; int k; - write_lock_irqsave(&sg_dev_arr_lock, flags); + write_lock_irqsave(&sg_dev_arr_lock, iflags); if (sg_template.nr_dev >= sg_template.dev_max) { /* try to resize */ Sg_device ** tmp_da; int tmp_dev_max = sg_template.nr_dev + SG_DEV_ARR_LUMP; @@ -1161,7 +1197,7 @@ static int sg_attach(Scsi_Device * scsidp) sizeof(Sg_device *), GFP_ATOMIC); if (NULL == tmp_da) { scsidp->attached--; - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); printk("sg_attach: device array cannot be resized\n"); return 1; } @@ -1180,7 +1216,7 @@ static int sg_attach(Scsi_Device * scsidp) sdp = NULL; if (NULL == sdp) { scsidp->attached--; - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); printk("sg_attach: Sg_device cannot be allocated\n"); return 1; } @@ -1200,7 +1236,7 @@ static int sg_attach(Scsi_Device * scsidp) &sg_fops, NULL); sg_template.nr_dev++; sg_dev_arr[k] = sdp; - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); return 0; } @@ -1214,37 +1250,36 @@ static void sg_finish(void) static void sg_detach(Scsi_Device * scsidp) { Sg_device * sdp; - unsigned long flags = 0; + unsigned long iflags; Sg_fd * sfp; Sg_request * srp; int k; if (NULL == sg_dev_arr) return; - write_lock_irqsave(&sg_dev_arr_lock, flags); -/* Need to stop sg_cmd_done_bh() playing with this list during this loop */ + write_lock_irqsave(&sg_dev_arr_lock, iflags); for (k = 0; k < sg_template.dev_max; k++) { sdp = sg_dev_arr[k]; if ((NULL == sdp) || (sdp->device != scsidp)) continue; /* dirty but lowers nesting */ if (sdp->headfp) { - sfp = sdp->headfp; - while (sfp) { - srp = sfp->headrp; - while (srp) { - if (! srp->done) + for (sfp = sdp->headfp; sfp; sfp = sfp->nextfp) { + /* no lock on request list here */ + for (srp = sfp->headrp; srp; srp = srp->nextrp) { + if (! srp->done) { + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); sg_shorten_timeout(srp->my_cmdp); - srp = srp->nextrp; + write_lock_irqsave(&sg_dev_arr_lock, iflags); } - sfp = sfp->nextfp; } - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + } + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty, sleep(3)\n", k)); scsi_sleep(3); /* sleep 3 jiffies, hoping for timeout to go off */ devfs_unregister (sdp->de); sdp->de = NULL; sdp->detached = 1; - write_lock_irqsave(&sg_dev_arr_lock, flags); + write_lock_irqsave(&sg_dev_arr_lock, iflags); } else { SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d\n", k)); @@ -1259,7 +1294,7 @@ static void sg_detach(Scsi_Device * scsidp) sg_template.dev_noticed--; break; } - write_unlock_irqrestore(&sg_dev_arr_lock, flags); + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); return; } @@ -1277,12 +1312,11 @@ int init_module(void) { void cleanup_module( void) { - scsi_unregister_module(MODULE_SCSI_DEV, &sg_template); - devfs_unregister_chrdev(SCSI_GENERIC_MAJOR, "sg"); - #ifdef CONFIG_PROC_FS sg_proc_cleanup(); #endif /* CONFIG_PROC_FS */ + scsi_unregister_module(MODULE_SCSI_DEV, &sg_template); + devfs_unregister_chrdev(SCSI_GENERIC_MAJOR, "sg"); if(sg_dev_arr != NULL) { /* Really worrying situation of writes still pending and get here */ /* Strategy: shorten timeout on release + wait on detach ... */ @@ -1301,7 +1335,7 @@ extern void scsi_old_times_out (Scsi_Cmnd * SCpnt); /* Can't see clean way to abort a command so shorten timeout to 1 jiffy */ static void sg_shorten_timeout(Scsi_Cmnd * scpnt) -{ /* assumed to be called with sg_dev_arr_lock held */ +{ #if 0 /* scsi_syms.c is very miserly about exported functions */ scsi_delete_timer(scpnt); if (! scpnt) @@ -1313,11 +1347,7 @@ static void sg_shorten_timeout(Scsi_Cmnd * scpnt) scsi_add_timer(scpnt, scpnt->timeout_per_command, scsi_old_times_out); #else - unsigned long flags = 0; - - write_unlock_irqrestore(&sg_dev_arr_lock, flags); scsi_sleep(HZ); /* just sleep 1 second and hope ... */ - write_lock_irqsave(&sg_dev_arr_lock, flags); #endif } @@ -1859,6 +1889,8 @@ static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size) Sg_scatter_hold * rsv_schp = &sfp->reserve; SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size)); + /* round request up to next highest SG_SECTOR_SZ byte boundary */ + size = (size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK); if (rsv_schp->k_use_sg > 0) { int k, num; int rem = size; @@ -1921,17 +1953,35 @@ static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp) srp->res_used = 0; } -static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id) +static Sg_request * sg_get_rq_mark(Sg_fd * sfp, int pack_id) { - Sg_request * resp = NULL; + Sg_request * resp; + unsigned long iflags; - resp = sfp->headrp; - while (resp) { /* look for requests that are ready + not SG_IO owned */ - if (resp->done && (! resp->sg_io_owned) && - ((-1 == pack_id) || (resp->header.pack_id == pack_id))) - return resp; - resp = resp->nextrp; + write_lock_irqsave(&sfp->rq_list_lock, iflags); + for (resp = sfp->headrp; resp; resp = resp->nextrp) { + /* look for requests that are ready + not SG_IO owned */ + if ((1 == resp->done) && (! resp->sg_io_owned) && + ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { + resp->done = 2; /* guard against other readers */ + break; + } } + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return resp; +} + +static Sg_request * sg_get_nth_request(Sg_fd * sfp, int nth) +{ + Sg_request * resp; + unsigned long iflags; + int k; + + read_lock_irqsave(&sfp->rq_list_lock, iflags); + for (k = 0, resp = sfp->headrp; resp && (k < nth); + ++k, resp = resp->nextrp) + ; + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); return resp; } @@ -1939,46 +1989,45 @@ static Sg_request * sg_get_request(const Sg_fd * sfp, int pack_id) static Sg_request * sg_add_request(Sg_fd * sfp) { int k; - Sg_request * resp = NULL; - Sg_request * rp; + unsigned long iflags; + Sg_request * resp; + Sg_request * rp = sfp->req_arr; + write_lock_irqsave(&sfp->rq_list_lock, iflags); resp = sfp->headrp; - rp = sfp->req_arr; if (! resp) { - resp = rp; - sfp->headrp = resp; + memset(rp, 0, sizeof(Sg_request)); + rp->parentfp = sfp; + resp = rp; + sfp->headrp = resp; } else { if (0 == sfp->cmd_q) resp = NULL; /* command queuing disallowed */ else { - for (k = 0, rp; k < SG_MAX_QUEUE; ++k, ++rp) { + for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) { if (! rp->parentfp) break; } if (k < SG_MAX_QUEUE) { - while (resp->nextrp) resp = resp->nextrp; - resp->nextrp = rp; - resp = rp; + memset(rp, 0, sizeof(Sg_request)); + rp->parentfp = sfp; + while (resp->nextrp) + resp = resp->nextrp; + resp->nextrp = rp; + resp = rp; } else resp = NULL; } } if (resp) { - resp->parentfp = sfp; resp->nextrp = NULL; - resp->res_used = 0; - resp->orphan = 0; - resp->sg_io_owned = 0; - resp->done = 0; - memset(&resp->data, 0, sizeof(Sg_scatter_hold)); - memset(&resp->header, 0, size_sg_io_hdr); resp->header.duration = jiffies; resp->my_cmdp = NULL; resp->data.kiobp = NULL; - resp->data.mapped = 0; } + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); return resp; } @@ -1987,29 +2036,51 @@ static int sg_remove_request(Sg_fd * sfp, Sg_request * srp) { Sg_request * prev_rp; Sg_request * rp; + unsigned long iflags; + int res = 0; if ((! sfp) || (! srp) || (! sfp->headrp)) - return 0; + return res; + write_lock_irqsave(&sfp->rq_list_lock, iflags); prev_rp = sfp->headrp; if (srp == prev_rp) { - prev_rp->parentfp = NULL; sfp->headrp = prev_rp->nextrp; - return 1; + prev_rp->parentfp = NULL; + res = 1; } - while ((rp = prev_rp->nextrp)) { - if (srp == rp) { - rp->parentfp = NULL; - prev_rp->nextrp = rp->nextrp; - return 1; - } - prev_rp = rp; + else { + while ((rp = prev_rp->nextrp)) { + if (srp == rp) { + prev_rp->nextrp = rp->nextrp; + rp->parentfp = NULL; + res = 1; + break; + } + prev_rp = rp; + } } - return 0; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return res; +} + +static Sg_fd * sg_get_nth_sfp(Sg_device * sdp, int nth) +{ + Sg_fd * resp; + unsigned long iflags; + int k; + + read_lock_irqsave(&sg_dev_arr_lock, iflags); + for (k = 0, resp = sdp->headfp; resp && (k < nth); + ++k, resp = resp->nextfp) + ; + read_unlock_irqrestore(&sg_dev_arr_lock, iflags); + return resp; } static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev) { Sg_fd * sfp; + unsigned long iflags; sfp = (Sg_fd *)sg_low_malloc(sizeof(Sg_fd), 0, SG_HEAP_KMAL, 0); if (! sfp) @@ -2017,6 +2088,7 @@ static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev) memset(sfp, 0, sizeof(Sg_fd)); sfp->fd_mem_src = SG_HEAP_KMAL; init_waitqueue_head(&sfp->read_wait); + sfp->rq_list_lock = RW_LOCK_UNLOCKED; sfp->timeout = SG_DEFAULT_TIMEOUT; sfp->force_packid = SG_DEF_FORCE_PACK_ID; @@ -2025,14 +2097,16 @@ static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev) sfp->cmd_q = SG_DEF_COMMAND_Q; sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; sfp->parentdp = sdp; + write_lock_irqsave(&sg_dev_arr_lock, iflags); if (! sdp->headfp) sdp->headfp = sfp; else { /* add to tail of existing list */ - Sg_fd * pfp = sdp->headfp; - while (pfp->nextfp) - pfp = pfp->nextfp; - pfp->nextfp = sfp; + Sg_fd * pfp = sdp->headfp; + while (pfp->nextfp) + pfp = pfp->nextfp; + pfp->nextfp = sfp; } + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p, m_s=%d\n", sfp, (int)sfp->fd_mem_src)); sg_build_reserve(sfp, sg_big_buff); @@ -2048,36 +2122,41 @@ static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) int dirty = 0; int res = 0; + /* no lock since not expecting any parallel action on this fd */ srp = sfp->headrp; if (srp) { - while (srp) { - tsrp = srp->nextrp; + while (srp) { + tsrp = srp->nextrp; if (srp->done) sg_finish_rem_req(srp); - else - ++dirty; - srp = tsrp; - } + else + ++dirty; + srp = tsrp; + } } if (0 == dirty) { - Sg_fd * fp; - Sg_fd * prev_fp = sdp->headfp; - - if (sfp == prev_fp) - sdp->headfp = prev_fp->nextfp; - else { - while ((fp = prev_fp->nextfp)) { - if (sfp == fp) { - prev_fp->nextfp = fp->nextfp; - break; - } - prev_fp = fp; - } - } - if (sfp->reserve.bufflen > 0) { + Sg_fd * fp; + Sg_fd * prev_fp; + unsigned long iflags; + + write_lock_irqsave(&sg_dev_arr_lock, iflags); + prev_fp = sdp->headfp; + if (sfp == prev_fp) + sdp->headfp = prev_fp->nextfp; + else { + while ((fp = prev_fp->nextfp)) { + if (sfp == fp) { + prev_fp->nextfp = fp->nextfp; + break; + } + prev_fp = fp; + } + } + write_unlock_irqrestore(&sg_dev_arr_lock, iflags); + if (sfp->reserve.bufflen > 0) { SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", (int)sfp->reserve.bufflen, (int)sfp->reserve.k_use_sg)); - sg_remove_scat(&sfp->reserve); + sg_remove_scat(&sfp->reserve); } sfp->parentdp = NULL; SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: sfp=0x%p\n", sfp)); @@ -2104,28 +2183,28 @@ SCSI_LOG_TIMEOUT(6, printk("sg_remove_sfp: bufflen=%d, k_use_sg=%d\n", return res; } -static int sg_res_in_use(const Sg_fd * sfp) +static int sg_res_in_use(Sg_fd * sfp) { - const Sg_request * srp = sfp->headrp; + const Sg_request * srp; + unsigned long iflags; - while (srp) { - if (srp->res_used) - return 1; - srp = srp->nextrp; - } - return 0; + read_lock_irqsave(&sfp->rq_list_lock, iflags); + for (srp = sfp->headrp; srp; srp = srp->nextrp) + if (srp->res_used) break; + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return srp ? 1 : 0; } -static int sg_dio_in_use(const Sg_fd * sfp) +static int sg_dio_in_use(Sg_fd * sfp) { - const Sg_request * srp = sfp->headrp; + const Sg_request * srp; + unsigned long iflags; - while (srp) { - if ((! srp->done) && srp->data.kiobp) - return 1; - srp = srp->nextrp; - } - return 0; + read_lock_irqsave(&sfp->rq_list_lock, iflags); + for (srp = sfp->headrp; srp; srp = srp->nextrp) + if ((! srp->done) && srp->data.kiobp) break; + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return srp ? 1 : 0; } /* If retSzp==NULL want exact size or fail */ @@ -2314,7 +2393,8 @@ static unsigned sg_jif_to_ms(int jifs) } static unsigned char allow_ops[] = {TEST_UNIT_READY, INQUIRY, -READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12}; +READ_CAPACITY, READ_BUFFER, READ_6, READ_10, READ_12, +MODE_SENSE, MODE_SENSE_10}; static int sg_allow_access(unsigned char opcode, char dev_type) { @@ -2331,28 +2411,29 @@ static int sg_allow_access(unsigned char opcode, char dev_type) static int sg_last_dev() -{ /* assumed to be called with sg_dev_arr_lock held */ +{ int k; + unsigned long iflags; - for (k = sg_template.dev_max - 1; k >= 0; --k) { - if (sg_dev_arr[k] && sg_dev_arr[k]->device) - return k + 1; - } - return 0; /* origin 1 */ + read_lock_irqsave(&sg_dev_arr_lock, iflags); + for (k = sg_template.dev_max - 1; k >= 0; --k) + if (sg_dev_arr[k] && sg_dev_arr[k]->device) break; + read_unlock_irqrestore(&sg_dev_arr_lock, iflags); + return k + 1; /* origin 1 */ } static Sg_device * sg_get_dev(int dev) { - Sg_device * sdp; + Sg_device * sdp = NULL; + unsigned long iflags; - if ((NULL == sg_dev_arr) || (dev < 0)) - return NULL; - read_lock(&sg_dev_arr_lock); + if (sg_dev_arr && (dev >= 0)) + { + read_lock_irqsave(&sg_dev_arr_lock, iflags); if (dev < sg_template.dev_max) sdp = sg_dev_arr[dev]; - else - sdp = NULL; - read_unlock(&sg_dev_arr_lock); + read_unlock_irqrestore(&sg_dev_arr_lock, iflags); + } return sdp; } @@ -2429,8 +2510,7 @@ static write_proc_t * sg_proc_leaf_writes[] = { *eof = infofp(buffer, &len, &begin, offset, size); \ if (offset >= (begin + len)) \ return 0; \ - *start = buffer + ((begin > offset) ? \ - (begin - offset) : (offset - begin)); \ + *start = buffer + offset - begin; \ return (size < (begin + len - offset)) ? \ size : begin + len - offset; \ } while(0) @@ -2520,7 +2600,6 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin, PRINT_PROC("sg_dev_arr NULL, driver not initialized\n"); return 1; } - read_lock(&sg_dev_arr_lock); max_dev = sg_last_dev(); PRINT_PROC("dev_max(currently)=%d max_active_device=%d (origin 1)\n", sg_template.dev_max, max_dev); @@ -2528,11 +2607,11 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin, "def_reserved_size=%d\n", scsi_dma_free_sectors, sg_pool_secs_avail, sg_big_buff); for (j = 0; j < max_dev; ++j) { - if ((sdp = sg_dev_arr[j])) { + if ((sdp = sg_get_dev(j))) { Sg_fd * fp; Sg_request * srp; struct scsi_device * scsidp; - int dev, k, blen, usg; + int dev, k, m, blen, usg; if (! (scsidp = sdp->device)) { PRINT_PROC("device %d detached ??\n", j); @@ -2540,48 +2619,45 @@ static int sg_proc_debug_info(char * buffer, int * len, off_t * begin, } dev = MINOR(sdp->i_rdev); - if ((fp = sdp->headfp)) { - PRINT_PROC(" >>> device=%d(sg%d) ", dev, dev); + if (sg_get_nth_sfp(sdp, 0)) { + PRINT_PROC(" >>> device=sg%d ", dev); PRINT_PROC("scsi%d chan=%d id=%d lun=%d em=%d sg_tablesize=%d" " excl=%d\n", scsidp->host->host_no, scsidp->channel, scsidp->id, scsidp->lun, scsidp->host->hostt->emulated, sdp->sg_tablesize, sdp->exclude); } - for (k = 1; fp; fp = fp->nextfp, ++k) { - PRINT_PROC(" FD(%d): timeout=%d bufflen=%d " - "(res)sgat=%d low_dma=%d\n", - k, fp->timeout, fp->reserve.bufflen, + for (k = 0; (fp = sg_get_nth_sfp(sdp, k)); ++k) { + PRINT_PROC(" FD(%d): timeout=%dms bufflen=%d " + "(res)sgat=%d low_dma=%d\n", k + 1, + sg_jif_to_ms(fp->timeout), fp->reserve.bufflen, (int)fp->reserve.k_use_sg, (int)fp->low_dma); PRINT_PROC(" cmd_q=%d f_packid=%d k_orphan=%d closed=%d\n", (int)fp->cmd_q, (int)fp->force_packid, (int)fp->keep_orphan, (int)fp->closed); - srp = fp->headrp; - if (NULL == srp) - PRINT_PROC(" No requests active\n"); - while (srp) { + for (m = 0; (srp = sg_get_nth_request(fp, m)); ++m) { hp = &srp->header; /* stop indenting so far ... */ PRINT_PROC(srp->res_used ? " rb>> " : ((SG_INFO_DIRECT_IO_MASK & hp->info) ? " dio>> " : " ")); blen = srp->my_cmdp ? srp->my_cmdp->bufflen : srp->data.bufflen; usg = srp->my_cmdp ? srp->my_cmdp->use_sg : srp->data.k_use_sg; - PRINT_PROC(srp->done ? "rcv: id=%d" : (srp->my_cmdp ? "act: id=%d" : - "prior: id=%d"), srp->header.pack_id); - PRINT_PROC(" blen=%d", blen); + PRINT_PROC(srp->done ? ((1 == srp->done) ? "rcv:" : "fin:") + : (srp->my_cmdp ? "act:" : "prior:")); + PRINT_PROC(" id=%d blen=%d", srp->header.pack_id, blen); if (srp->done) - PRINT_PROC(" dur=%d", sg_jif_to_ms(hp->duration)); + PRINT_PROC(" dur=%d", hp->duration); else PRINT_PROC(" t_o/elap=%d/%d", ((hp->interface_id == '\0') ? sg_jif_to_ms(fp->timeout) : hp->timeout), sg_jif_to_ms(hp->duration ? (jiffies - hp->duration) : 0)); - PRINT_PROC(" sgat=%d op=0x%02x\n", usg, (int)srp->data.cmd_opcode); - srp = srp->nextrp; + PRINT_PROC("ms sgat=%d op=0x%02x\n", usg, (int)srp->data.cmd_opcode); /* reset indenting */ } + if (0 == m) + PRINT_PROC(" No requests active\n"); } } } - read_unlock(&sg_dev_arr_lock); return 1; } @@ -2596,19 +2672,17 @@ static int sg_proc_dev_info(char * buffer, int * len, off_t * begin, int j, max_dev; struct scsi_device * scsidp; - read_lock(&sg_dev_arr_lock); max_dev = sg_last_dev(); for (j = 0; j < max_dev; ++j) { - sdp = sg_dev_arr[j]; + sdp = sg_get_dev(j); if (sdp && (scsidp = sdp->device)) PRINT_PROC("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", scsidp->host->host_no, scsidp->channel, scsidp->id, - scsidp->lun, (int)scsidp->type, (int)scsidp->disconnect, - (int)scsidp->queue_depth, (int)scsidp->tagged_queue); + scsidp->lun, (int)scsidp->type, (int)scsidp->access_count, + (int)scsidp->queue_depth, (int)scsidp->device_busy); else PRINT_PROC("-1\t-1\t-1\t-1\t-1\t-1\t-1\t-1\n"); } - read_unlock(&sg_dev_arr_lock); return 1; } @@ -2619,7 +2693,7 @@ static int sg_proc_devhdr_read(char * buffer, char ** start, off_t offset, static int sg_proc_devhdr_info(char * buffer, int * len, off_t * begin, off_t offset, int size) { - PRINT_PROC("host\tchan\tid\tlun\ttype\tdiscon\tqdepth\ttq\n"); + PRINT_PROC("host\tchan\tid\tlun\ttype\tbopens\tqdepth\tbusy\n"); return 1; } @@ -2634,17 +2708,15 @@ static int sg_proc_devstrs_info(char * buffer, int * len, off_t * begin, int j, max_dev; struct scsi_device * scsidp; - read_lock(&sg_dev_arr_lock); max_dev = sg_last_dev(); for (j = 0; j < max_dev; ++j) { - sdp = sg_dev_arr[j]; + sdp = sg_get_dev(j); if (sdp && (scsidp = sdp->device)) PRINT_PROC("%8.8s\t%16.16s\t%4.4s\n", scsidp->vendor, scsidp->model, scsidp->rev); else PRINT_PROC("<no active device>\n"); } - read_unlock(&sg_dev_arr_lock); return 1; } diff --git a/drivers/sgi/char/graphics.c b/drivers/sgi/char/graphics.c index 352a210d4b4b3c..b0f3103e428abc 100644 --- a/drivers/sgi/char/graphics.c +++ b/drivers/sgi/char/graphics.c @@ -150,9 +150,11 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un * sgi_graphics_mmap */ disable_gconsole (); + down(¤t->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(¤t->mm->mmap_sem); if (r) return r; } diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c index 19d44b090be1e8..2d6a4b6f4fc9a9 100644 --- a/drivers/sgi/char/shmiq.c +++ b/drivers/sgi/char/shmiq.c @@ -118,8 +118,7 @@ shmiq_push_event (struct shmqevent *e) e->data.device, e->data.which, e->data.type, e->data.flags); s->tail = tail_next; shmiqs [device].tail = tail_next; - if (shmiqs [device].fasync) - kill_fasync (shmiqs [device].fasync, SIGIO, POLL_IN); + kill_fasync (&shmiqs [device].fasync, SIGIO, POLL_IN); wake_up_interruptible (&shmiqs [device].proc_list); } @@ -279,8 +278,10 @@ qcntl_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned return -EINVAL; } s = req.arg * sizeof (struct shmqevent) + sizeof (struct sharedMemoryInputQueue); - v = sys_munmap (vaddr, s); + down(¤t->mm->mmap_sem); + do_munmap (current->mm, vaddr, s); do_mmap (filp, vaddr, s, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 0); + up(¤t->mm->mmap_sem); shmiqs [minor].events = req.arg; shmiqs [minor].mapped = 1; return 0; diff --git a/drivers/sound/724hwmcode.h b/drivers/sound/724hwmcode.h new file mode 100644 index 00000000000000..75658352946582 --- /dev/null +++ b/drivers/sound/724hwmcode.h @@ -0,0 +1,1575 @@ +//============================================================================= +// Copyright (c) 1997-1999 Yamaha Corporation. All Rights Reserved. +// +// Title: +// hwmcode.c +// Desc: +// micro-code for CTRL & DSP +//============================================================================= +#ifndef _HWMCODE_ +#define _HWMCODE_ + +static unsigned long int DspInst[] = { + 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, + 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, + 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, + 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static unsigned long int CntrlInst[] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x001A82, 0x032D0D, 0x000810, 0x10043A, + 0x02D38D, 0x000810, 0x18043A, 0x00010D, + 0x020015, 0x0000FD, 0x000020, 0x038860, + 0x039060, 0x038060, 0x038040, 0x038040, + 0x038040, 0x018040, 0x000A7D, 0x038040, + 0x038040, 0x018040, 0x200402, 0x000882, + 0x08001A, 0x000904, 0x015986, 0x000007, + 0x260007, 0x000007, 0x000007, 0x018A06, + 0x000007, 0x030C8D, 0x000810, 0x18043A, + 0x260007, 0x00087D, 0x018042, 0x00160A, + 0x04A206, 0x000007, 0x00218D, 0x000810, + 0x08043A, 0x21C206, 0x000007, 0x0007FD, + 0x018042, 0x08000A, 0x000904, 0x029386, + 0x000195, 0x090D04, 0x000007, 0x000820, + 0x0000F5, 0x000B7D, 0x01F060, 0x0000FD, + 0x032206, 0x018040, 0x000A7D, 0x038042, + 0x13804A, 0x18000A, 0x001820, 0x059060, + 0x058860, 0x018040, 0x0000FD, 0x018042, + 0x70000A, 0x000115, 0x071144, 0x032386, + 0x030000, 0x007020, 0x034A06, 0x018040, + 0x00348D, 0x000810, 0x08043A, 0x21EA06, + 0x000007, 0x02D38D, 0x000810, 0x18043A, + 0x018206, 0x000007, 0x240007, 0x000F8D, + 0x000810, 0x00163A, 0x002402, 0x005C02, + 0x0028FD, 0x000020, 0x018040, 0x08000D, + 0x000815, 0x510984, 0x000007, 0x00004D, + 0x000E5D, 0x000E02, 0x00418D, 0x000810, + 0x08043A, 0x2C8A06, 0x000007, 0x00008D, + 0x000924, 0x000F02, 0x00458D, 0x000810, + 0x08043A, 0x2C8A06, 0x000007, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x018386, 0x000007, 0x01AA06, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x218086, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x055A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x034986, 0x000007, 0x002104, 0x034986, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x06C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00688D, 0x000810, 0x08043A, 0x288A06, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x060206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x215886, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x212086, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x07DA86, 0x00057D, 0x002820, + 0x03B060, 0x07F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x07FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x008D8D, 0x000810, + 0x08043A, 0x288A06, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x095186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x007FBD, 0x383DC4, + 0x000007, 0x001A7D, 0x001375, 0x018042, + 0x09004A, 0x10000A, 0x0B8D04, 0x139504, + 0x000007, 0x000820, 0x019060, 0x001104, + 0x212086, 0x010040, 0x0017FD, 0x018042, + 0x08000A, 0x000904, 0x212286, 0x000007, + 0x00197D, 0x038042, 0x09804A, 0x10000A, + 0x000924, 0x001664, 0x0011FD, 0x038042, + 0x2B804A, 0x19804A, 0x00008D, 0x218944, + 0x000007, 0x002244, 0x0AE186, 0x000007, + 0x001A64, 0x002A24, 0x00197D, 0x080102, + 0x100122, 0x000820, 0x039060, 0x018040, + 0x003DFD, 0x00008D, 0x000820, 0x018040, + 0x001375, 0x001A7D, 0x010042, 0x09804A, + 0x10000A, 0x00021D, 0x0189E4, 0x2992E4, + 0x309144, 0x000007, 0x00060D, 0x000A15, + 0x000C1D, 0x001025, 0x00A9E4, 0x012BE4, + 0x000464, 0x01B3E4, 0x0232E4, 0x000464, + 0x000464, 0x000464, 0x000464, 0x00040D, + 0x08B1C4, 0x000007, 0x000820, 0x000BF5, + 0x030040, 0x00197D, 0x038042, 0x09804A, + 0x000A24, 0x08000A, 0x080E64, 0x000007, + 0x100122, 0x000820, 0x031060, 0x010040, + 0x0064AC, 0x00027D, 0x000020, 0x018040, + 0x00107D, 0x018042, 0x0011FD, 0x3B804A, + 0x09804A, 0x20000A, 0x000095, 0x1A1144, + 0x00A144, 0x0D2086, 0x00040D, 0x00B984, + 0x0D2186, 0x0018FD, 0x018042, 0x0010FD, + 0x09804A, 0x28000A, 0x000095, 0x010924, + 0x002A64, 0x0D1186, 0x000007, 0x002904, + 0x0D2286, 0x000007, 0x0D2A06, 0x080002, + 0x00008D, 0x00387D, 0x000820, 0x018040, + 0x00127D, 0x018042, 0x10000A, 0x003904, + 0x0DD186, 0x00080D, 0x7FFFB5, 0x00B984, + 0x0DA186, 0x000025, 0x0E7A06, 0x00002D, + 0x000015, 0x00082D, 0x02C78D, 0x000820, + 0x0EC206, 0x00000D, 0x7F8035, 0x00B984, + 0x0E7186, 0x400025, 0x00008D, 0x110944, + 0x000007, 0x00018D, 0x109504, 0x000007, + 0x009164, 0x000424, 0x000424, 0x000424, + 0x100102, 0x280002, 0x02C68D, 0x000820, + 0x0EC206, 0x00018D, 0x00042D, 0x00008D, + 0x109504, 0x000007, 0x00020D, 0x109184, + 0x000007, 0x02C70D, 0x000820, 0x00008D, + 0x0038FD, 0x018040, 0x003BFD, 0x001020, + 0x03A860, 0x000815, 0x313184, 0x212184, + 0x000007, 0x03B060, 0x03A060, 0x018040, + 0x0022FD, 0x000095, 0x010924, 0x000424, + 0x000424, 0x001264, 0x100102, 0x000820, + 0x039060, 0x018040, 0x001924, 0x00FB8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x000424, + 0x000424, 0x00117D, 0x018042, 0x08000A, + 0x000A24, 0x280502, 0x280C02, 0x09800D, + 0x000820, 0x0002FD, 0x018040, 0x200007, + 0x0022FD, 0x018042, 0x08000A, 0x000095, + 0x280DC4, 0x011924, 0x00197D, 0x018042, + 0x0011FD, 0x09804A, 0x10000A, 0x0000B5, + 0x113144, 0x0A8D04, 0x000007, 0x080A44, + 0x129504, 0x000007, 0x0023FD, 0x001020, + 0x038040, 0x101244, 0x000007, 0x000820, + 0x039060, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x10FA86, 0x000007, + 0x003BFD, 0x000100, 0x000A10, 0x0B807A, + 0x13804A, 0x090984, 0x000007, 0x000095, + 0x013D04, 0x118086, 0x10000A, 0x100002, + 0x090984, 0x000007, 0x038042, 0x11804A, + 0x090D04, 0x000007, 0x10000A, 0x090D84, + 0x000007, 0x00257D, 0x000820, 0x018040, + 0x00010D, 0x000810, 0x28143A, 0x00127D, + 0x018042, 0x20000A, 0x00197D, 0x018042, + 0x00117D, 0x31804A, 0x10000A, 0x003124, + 0x01280D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x300102, 0x003124, 0x000424, 0x000424, + 0x001224, 0x280502, 0x001A4C, 0x130186, + 0x700002, 0x00002D, 0x030000, 0x00387D, + 0x018042, 0x10000A, 0x132A06, 0x002124, + 0x0000AD, 0x100002, 0x00010D, 0x000924, + 0x006B24, 0x01368D, 0x00397D, 0x000820, + 0x058040, 0x038042, 0x09844A, 0x000606, + 0x08040A, 0x003264, 0x00008D, 0x000A24, + 0x001020, 0x00227D, 0x018040, 0x013C0D, + 0x000810, 0x08043A, 0x29D206, 0x000007, + 0x002820, 0x00207D, 0x018040, 0x00117D, + 0x038042, 0x13804A, 0x33800A, 0x00387D, + 0x018042, 0x08000A, 0x000904, 0x163A86, + 0x000007, 0x00008D, 0x030964, 0x01478D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x380102, + 0x000424, 0x000424, 0x001224, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x14A286, + 0x000007, 0x280502, 0x001A4C, 0x163986, + 0x000007, 0x032164, 0x00632C, 0x003DFD, + 0x018042, 0x08000A, 0x000095, 0x090904, + 0x000007, 0x000820, 0x001A4C, 0x156186, + 0x018040, 0x030000, 0x157A06, 0x002124, + 0x00010D, 0x000924, 0x006B24, 0x015B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x003A64, + 0x000095, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x01628D, 0x000810, 0x08043A, 0x29D206, + 0x000007, 0x14D206, 0x000007, 0x007020, + 0x08010A, 0x10012A, 0x0020FD, 0x038860, + 0x039060, 0x018040, 0x00227D, 0x018042, + 0x003DFD, 0x08000A, 0x31844A, 0x000904, + 0x16D886, 0x18008B, 0x00008D, 0x189904, + 0x00312C, 0x17AA06, 0x000007, 0x00324C, + 0x173386, 0x000007, 0x001904, 0x173086, + 0x000007, 0x000095, 0x199144, 0x00222C, + 0x003124, 0x00636C, 0x000E3D, 0x001375, + 0x000BFD, 0x010042, 0x09804A, 0x10000A, + 0x038AEC, 0x0393EC, 0x00224C, 0x17A986, + 0x000007, 0x00008D, 0x189904, 0x00226C, + 0x00322C, 0x30050A, 0x301DAB, 0x002083, + 0x0018FD, 0x018042, 0x08000A, 0x018924, + 0x300502, 0x001083, 0x001875, 0x010042, + 0x10000A, 0x00008D, 0x010924, 0x001375, + 0x330542, 0x330CCB, 0x332CCB, 0x3334CB, + 0x333CCB, 0x3344CB, 0x334CCB, 0x3354CB, + 0x305C8B, 0x006083, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x187A86, 0x000007, + 0x001E2D, 0x0005FD, 0x018042, 0x08000A, + 0x028924, 0x280502, 0x00060D, 0x000810, + 0x280C3A, 0x00008D, 0x000810, 0x28143A, + 0x0A808D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x001275, 0x030042, 0x21004A, + 0x00008D, 0x1A0944, 0x000007, 0x01980D, + 0x000810, 0x08043A, 0x2B2206, 0x000007, + 0x0001F5, 0x030042, 0x0D004A, 0x10000A, + 0x089144, 0x000007, 0x000820, 0x010040, + 0x0025F5, 0x0A3144, 0x000007, 0x000820, + 0x032860, 0x030040, 0x00217D, 0x038042, + 0x0B804A, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x00008D, 0x000124, 0x00012C, + 0x000E64, 0x001A64, 0x00636C, 0x08010A, + 0x10012A, 0x000820, 0x031060, 0x030040, + 0x0020FD, 0x018042, 0x08000A, 0x00227D, + 0x018042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x00197D, 0x018042, 0x08000A, + 0x0022FD, 0x038042, 0x10000A, 0x000820, + 0x031060, 0x030040, 0x090D04, 0x000007, + 0x000820, 0x030040, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x038042, 0x13804A, 0x19804A, 0x110D04, + 0x198D04, 0x000007, 0x08000A, 0x001020, + 0x031860, 0x030860, 0x030040, 0x00008D, + 0x0B0944, 0x000007, 0x000820, 0x010040, + 0x0005F5, 0x030042, 0x08000A, 0x000820, + 0x010040, 0x0000F5, 0x010042, 0x08000A, + 0x000904, 0x1C6086, 0x001E75, 0x030042, + 0x01044A, 0x000C0A, 0x1C7206, 0x000007, + 0x000402, 0x000C02, 0x00177D, 0x001AF5, + 0x018042, 0x03144A, 0x031C4A, 0x03244A, + 0x032C4A, 0x03344A, 0x033C4A, 0x03444A, + 0x004C0A, 0x00043D, 0x0013F5, 0x001AFD, + 0x030042, 0x0B004A, 0x1B804A, 0x13804A, + 0x20000A, 0x089144, 0x19A144, 0x0389E4, + 0x0399EC, 0x005502, 0x005D0A, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x006502, 0x006D0A, 0x030042, 0x0B004A, + 0x19004A, 0x2B804A, 0x13804A, 0x21804A, + 0x30000A, 0x089144, 0x19A144, 0x2AB144, + 0x0389E4, 0x0399EC, 0x007502, 0x007D0A, + 0x03A9E4, 0x000702, 0x00107D, 0x000415, + 0x018042, 0x08000A, 0x0109E4, 0x000F02, + 0x002AF5, 0x0019FD, 0x010042, 0x09804A, + 0x10000A, 0x000934, 0x001674, 0x0029F5, + 0x010042, 0x10000A, 0x00917C, 0x002075, + 0x010042, 0x08000A, 0x000904, 0x1ED286, + 0x0026F5, 0x0027F5, 0x030042, 0x09004A, + 0x10000A, 0x000A3C, 0x00167C, 0x001A75, + 0x000BFD, 0x010042, 0x51804A, 0x48000A, + 0x160007, 0x001075, 0x010042, 0x282C0A, + 0x281D12, 0x282512, 0x001F32, 0x1E0007, + 0x0E0007, 0x001975, 0x010042, 0x002DF5, + 0x0D004A, 0x10000A, 0x009144, 0x1FB286, + 0x010042, 0x28340A, 0x000E5D, 0x00008D, + 0x000375, 0x000820, 0x010040, 0x05D2F4, + 0x54D104, 0x00735C, 0x205386, 0x000007, + 0x0C0007, 0x080007, 0x0A0007, 0x02040D, + 0x000810, 0x08043A, 0x332206, 0x000007, + 0x205A06, 0x000007, 0x080007, 0x002275, + 0x010042, 0x20000A, 0x002104, 0x212086, + 0x001E2D, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x209286, 0x000007, 0x002010, + 0x30043A, 0x00057D, 0x0180C3, 0x08000A, + 0x028924, 0x280502, 0x280C02, 0x0A810D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x0004FD, 0x018042, 0x70000A, 0x030000, + 0x007020, 0x06FA06, 0x018040, 0x02180D, + 0x000810, 0x08043A, 0x2B2206, 0x000007, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x218A86, 0x000007, 0x01F206, 0x000007, + 0x000875, 0x0009FD, 0x00010D, 0x220A06, + 0x000295, 0x000B75, 0x00097D, 0x00000D, + 0x000515, 0x010042, 0x18000A, 0x001904, + 0x287886, 0x0006F5, 0x001020, 0x010040, + 0x0004F5, 0x000820, 0x010040, 0x000775, + 0x010042, 0x09804A, 0x10000A, 0x001124, + 0x000904, 0x22BA86, 0x000815, 0x080102, + 0x101204, 0x22DA06, 0x000575, 0x081204, + 0x000007, 0x100102, 0x000575, 0x000425, + 0x021124, 0x100102, 0x000820, 0x031060, + 0x010040, 0x001924, 0x287886, 0x00008D, + 0x000464, 0x009D04, 0x278886, 0x180102, + 0x000575, 0x010042, 0x28040A, 0x00018D, + 0x000924, 0x280D02, 0x00000D, 0x000924, + 0x281502, 0x10000D, 0x000820, 0x0002F5, + 0x010040, 0x200007, 0x001175, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x23C286, + 0x000007, 0x000100, 0x080B20, 0x130B60, + 0x1B0B60, 0x030A60, 0x010040, 0x050042, + 0x3D004A, 0x35004A, 0x2D004A, 0x20000A, + 0x0006F5, 0x010042, 0x28140A, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x24CA86, 0x004015, 0x000095, 0x010D04, + 0x24B886, 0x100022, 0x10002A, 0x24E206, + 0x000007, 0x333104, 0x2AA904, 0x000007, + 0x032124, 0x280502, 0x001124, 0x000424, + 0x000424, 0x003224, 0x00292C, 0x00636C, + 0x25F386, 0x000007, 0x02B164, 0x000464, + 0x000464, 0x00008D, 0x000A64, 0x280D02, + 0x10008D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x00008D, 0x38B904, 0x000007, + 0x03296C, 0x30010A, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x25BA86, 0x000007, + 0x02312C, 0x28050A, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x267A86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x26C086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x26CA86, 0x000007, 0x003124, 0x300502, + 0x003924, 0x300583, 0x000883, 0x0005F5, + 0x010042, 0x28040A, 0x00008D, 0x008124, + 0x280D02, 0x00008D, 0x008124, 0x281502, + 0x10018D, 0x000820, 0x0002F5, 0x010040, + 0x220007, 0x001025, 0x000575, 0x030042, + 0x09004A, 0x10000A, 0x0A0904, 0x121104, + 0x000007, 0x001020, 0x050860, 0x050040, + 0x0006FD, 0x018042, 0x09004A, 0x10000A, + 0x0000A5, 0x0A0904, 0x121104, 0x000007, + 0x000820, 0x019060, 0x010040, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x284286, + 0x000007, 0x230A06, 0x000007, 0x000606, + 0x000007, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x289286, 0x000007, 0x000100, + 0x080B20, 0x138B60, 0x1B8B60, 0x238B60, + 0x2B8B60, 0x338B60, 0x3B8B60, 0x438B60, + 0x4B8B60, 0x538B60, 0x5B8B60, 0x638B60, + 0x6B8B60, 0x738B60, 0x7B8B60, 0x038F60, + 0x0B8F60, 0x138F60, 0x1B8F60, 0x238F60, + 0x2B8F60, 0x338F60, 0x3B8F60, 0x438F60, + 0x4B8F60, 0x538F60, 0x5B8F60, 0x638F60, + 0x6B8F60, 0x738F60, 0x7B8F60, 0x038A60, + 0x000606, 0x018040, 0x00008D, 0x000A64, + 0x280D02, 0x000A24, 0x00027D, 0x018042, + 0x10000A, 0x001224, 0x0003FD, 0x018042, + 0x08000A, 0x000904, 0x2A8286, 0x000007, + 0x00018D, 0x000A24, 0x000464, 0x000464, + 0x080102, 0x000924, 0x000424, 0x000424, + 0x100102, 0x02000D, 0x009144, 0x2AD986, + 0x000007, 0x0001FD, 0x018042, 0x08000A, + 0x000A44, 0x2ABB86, 0x018042, 0x0A000D, + 0x000820, 0x0002FD, 0x018040, 0x200007, + 0x00027D, 0x001020, 0x000606, 0x018040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x2B2A86, 0x000007, 0x00037D, 0x018042, + 0x08000A, 0x000904, 0x2B5A86, 0x000007, + 0x000075, 0x002E7D, 0x010042, 0x0B804A, + 0x000020, 0x000904, 0x000686, 0x010040, + 0x31844A, 0x30048B, 0x000883, 0x00008D, + 0x000810, 0x28143A, 0x00008D, 0x000810, + 0x280C3A, 0x000675, 0x010042, 0x08000A, + 0x003815, 0x010924, 0x280502, 0x0B000D, + 0x000820, 0x0002F5, 0x010040, 0x000606, + 0x220007, 0x000464, 0x000464, 0x000606, + 0x000007, 0x000134, 0x007F8D, 0x00093C, + 0x281D12, 0x282512, 0x001F32, 0x0E0007, + 0x00010D, 0x00037D, 0x000820, 0x018040, + 0x05D2F4, 0x000007, 0x080007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2D0286, + 0x000007, 0x000606, 0x000007, 0x000007, + 0x000012, 0x100007, 0x320007, 0x600007, + 0x100080, 0x48001A, 0x004904, 0x2D6186, + 0x000007, 0x001210, 0x58003A, 0x000145, + 0x5C5D04, 0x000007, 0x000080, 0x48001A, + 0x004904, 0x2DB186, 0x000007, 0x001210, + 0x50003A, 0x005904, 0x2E0886, 0x000045, + 0x0000C5, 0x7FFFF5, 0x7FFF7D, 0x07D524, + 0x004224, 0x500102, 0x200502, 0x000082, + 0x40001A, 0x004104, 0x2E3986, 0x000007, + 0x003865, 0x40001A, 0x004020, 0x00104D, + 0x04C184, 0x301B86, 0x000040, 0x040007, + 0x000165, 0x000145, 0x004020, 0x000040, + 0x000765, 0x080080, 0x40001A, 0x004104, + 0x2EC986, 0x000007, 0x001210, 0x40003A, + 0x004104, 0x2F2286, 0x00004D, 0x0000CD, + 0x004810, 0x20043A, 0x000882, 0x40001A, + 0x004104, 0x2F3186, 0x000007, 0x004820, + 0x005904, 0x300886, 0x000040, 0x0007E5, + 0x200480, 0x2816A0, 0x3216E0, 0x3A16E0, + 0x4216E0, 0x021260, 0x000040, 0x000032, + 0x400075, 0x00007D, 0x07D574, 0x200512, + 0x000082, 0x40001A, 0x004104, 0x2FE186, + 0x000007, 0x037206, 0x640007, 0x060007, + 0x0000E5, 0x000020, 0x000040, 0x000A65, + 0x000020, 0x020040, 0x020040, 0x000040, + 0x000165, 0x000042, 0x70000A, 0x007104, + 0x30A286, 0x000007, 0x018206, 0x640007, + 0x050000, 0x007020, 0x000040, 0x037206, + 0x640007, 0x000007, 0x00306D, 0x028860, + 0x029060, 0x08000A, 0x028860, 0x008040, + 0x100012, 0x00100D, 0x009184, 0x314186, + 0x000E0D, 0x009184, 0x325186, 0x000007, + 0x300007, 0x001020, 0x003B6D, 0x008040, + 0x000080, 0x08001A, 0x000904, 0x316186, + 0x000007, 0x001220, 0x000DED, 0x008040, + 0x008042, 0x10000A, 0x40000D, 0x109544, + 0x000007, 0x001020, 0x000DED, 0x008040, + 0x008042, 0x20040A, 0x000082, 0x08001A, + 0x000904, 0x31F186, 0x000007, 0x003B6D, + 0x008042, 0x08000A, 0x000E15, 0x010984, + 0x329B86, 0x600007, 0x08001A, 0x000C15, + 0x010984, 0x328386, 0x000020, 0x1A0007, + 0x0002ED, 0x008040, 0x620007, 0x00306D, + 0x028042, 0x0A804A, 0x000820, 0x0A804A, + 0x000606, 0x10804A, 0x000007, 0x282512, + 0x001F32, 0x05D2F4, 0x54D104, 0x00735C, + 0x000786, 0x000007, 0x0C0007, 0x0A0007, + 0x1C0007, 0x003465, 0x020040, 0x004820, + 0x025060, 0x40000A, 0x024060, 0x000040, + 0x454944, 0x000007, 0x004020, 0x003AE5, + 0x000040, 0x0028E5, 0x000042, 0x48000A, + 0x004904, 0x386886, 0x002C65, 0x000042, + 0x40000A, 0x0000D5, 0x454104, 0x000007, + 0x000655, 0x054504, 0x34F286, 0x0001D5, + 0x054504, 0x34F086, 0x002B65, 0x000042, + 0x003AE5, 0x50004A, 0x40000A, 0x45C3D4, + 0x000007, 0x454504, 0x000007, 0x0000CD, + 0x444944, 0x000007, 0x454504, 0x000007, + 0x00014D, 0x554944, 0x000007, 0x045144, + 0x34E986, 0x002C65, 0x000042, 0x48000A, + 0x4CD104, 0x000007, 0x04C144, 0x34F386, + 0x000007, 0x160007, 0x002CE5, 0x040042, + 0x40000A, 0x004020, 0x000040, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x356086, + 0x000007, 0x002402, 0x36A206, 0x005C02, + 0x0025E5, 0x000042, 0x40000A, 0x004274, + 0x002AE5, 0x000042, 0x40000A, 0x004274, + 0x500112, 0x0029E5, 0x000042, 0x40000A, + 0x004234, 0x454104, 0x000007, 0x004020, + 0x000040, 0x003EE5, 0x000020, 0x000040, + 0x002DE5, 0x400152, 0x50000A, 0x045144, + 0x364A86, 0x0000C5, 0x003EE5, 0x004020, + 0x000040, 0x002BE5, 0x000042, 0x40000A, + 0x404254, 0x000007, 0x002AE5, 0x004020, + 0x000040, 0x500132, 0x040134, 0x005674, + 0x0029E5, 0x020042, 0x42000A, 0x000042, + 0x50000A, 0x05417C, 0x0028E5, 0x000042, + 0x48000A, 0x0000C5, 0x4CC144, 0x371086, + 0x0026E5, 0x0027E5, 0x020042, 0x40004A, + 0x50000A, 0x00423C, 0x00567C, 0x0028E5, + 0x004820, 0x000040, 0x281D12, 0x282512, + 0x001F72, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x37AA86, 0x0E0007, 0x160007, + 0x1E0007, 0x003EE5, 0x000042, 0x40000A, + 0x004104, 0x37E886, 0x002D65, 0x000042, + 0x28340A, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x50004A, 0x05D2F4, + 0x54D104, 0x00735C, 0x385186, 0x000007, + 0x000606, 0x080007, 0x0C0007, 0x080007, + 0x0A0007, 0x0001E5, 0x020045, 0x004020, + 0x000060, 0x000365, 0x000040, 0x002E65, + 0x001A20, 0x0A1A60, 0x000040, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x000606, 0x50004A, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; + +// -------------------------------------------- +// DS-1E Controller InstructionRAM Code +// 1999/06/21 +// Buf441 slot is Enabled. +// -------------------------------------------- +// 04/09?@creat +// 04/12 stop nise fix +// 06/21?@WorkingOff timming +static unsigned long int CntrlInst1E[] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x00800D, 0x000810, 0x20043A, 0x001A82, + 0x03460D, 0x000810, 0x10043A, 0x02EC0D, + 0x000810, 0x18043A, 0x00010D, 0x020015, + 0x0000FD, 0x000020, 0x038860, 0x039060, + 0x038060, 0x038040, 0x038040, 0x038040, + 0x018040, 0x000A7D, 0x038040, 0x038040, + 0x018040, 0x200402, 0x000882, 0x08001A, + 0x000904, 0x017186, 0x000007, 0x260007, + 0x400007, 0x000007, 0x03258D, 0x000810, + 0x18043A, 0x260007, 0x284402, 0x00087D, + 0x018042, 0x00160A, 0x05A206, 0x000007, + 0x440007, 0x00230D, 0x000810, 0x08043A, + 0x22FA06, 0x000007, 0x0007FD, 0x018042, + 0x08000A, 0x000904, 0x02AB86, 0x000195, + 0x090D04, 0x000007, 0x000820, 0x0000F5, + 0x000B7D, 0x01F060, 0x0000FD, 0x033A06, + 0x018040, 0x000A7D, 0x038042, 0x13804A, + 0x18000A, 0x001820, 0x059060, 0x058860, + 0x018040, 0x0000FD, 0x018042, 0x70000A, + 0x000115, 0x071144, 0x033B86, 0x030000, + 0x007020, 0x036206, 0x018040, 0x00360D, + 0x000810, 0x08043A, 0x232206, 0x000007, + 0x02EC0D, 0x000810, 0x18043A, 0x019A06, + 0x000007, 0x240007, 0x000F8D, 0x000810, + 0x00163A, 0x002402, 0x005C02, 0x0028FD, + 0x000020, 0x018040, 0x08000D, 0x000815, + 0x510984, 0x000007, 0x00004D, 0x000E5D, + 0x000E02, 0x00430D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x00008D, 0x000924, + 0x000F02, 0x00470D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x480480, 0x001210, + 0x28043A, 0x00778D, 0x000810, 0x280C3A, + 0x00068D, 0x000810, 0x28143A, 0x284402, + 0x03258D, 0x000810, 0x18043A, 0x07FF8D, + 0x000820, 0x0002FD, 0x018040, 0x260007, + 0x200007, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x051286, 0x000007, 0x240007, + 0x02EC0D, 0x000810, 0x18043A, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x019B86, 0x000007, 0x01B206, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x22B886, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x065A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x036186, 0x000007, 0x002104, 0x036186, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x07C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00788D, 0x000810, 0x08043A, 0x2A1206, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x070206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x229086, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x225886, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x08DA86, 0x00057D, 0x002820, + 0x03B060, 0x08F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x08FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x009D8D, 0x000810, + 0x08043A, 0x2A1206, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x0A5186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x00107D, 0x018042, + 0x08000A, 0x000215, 0x010984, 0x3A8186, + 0x000007, 0x007FBD, 0x383DC4, 0x000007, + 0x001A7D, 0x001375, 0x018042, 0x09004A, + 0x10000A, 0x0B8D04, 0x139504, 0x000007, + 0x000820, 0x019060, 0x001104, 0x225886, + 0x010040, 0x0017FD, 0x018042, 0x08000A, + 0x000904, 0x225A86, 0x000007, 0x00197D, + 0x038042, 0x09804A, 0x10000A, 0x000924, + 0x001664, 0x0011FD, 0x038042, 0x2B804A, + 0x19804A, 0x00008D, 0x218944, 0x000007, + 0x002244, 0x0C1986, 0x000007, 0x001A64, + 0x002A24, 0x00197D, 0x080102, 0x100122, + 0x000820, 0x039060, 0x018040, 0x003DFD, + 0x00008D, 0x000820, 0x018040, 0x001375, + 0x001A7D, 0x010042, 0x09804A, 0x10000A, + 0x00021D, 0x0189E4, 0x2992E4, 0x309144, + 0x000007, 0x00060D, 0x000A15, 0x000C1D, + 0x001025, 0x00A9E4, 0x012BE4, 0x000464, + 0x01B3E4, 0x0232E4, 0x000464, 0x000464, + 0x000464, 0x000464, 0x00040D, 0x08B1C4, + 0x000007, 0x000820, 0x000BF5, 0x030040, + 0x00197D, 0x038042, 0x09804A, 0x000A24, + 0x08000A, 0x080E64, 0x000007, 0x100122, + 0x000820, 0x031060, 0x010040, 0x0064AC, + 0x00027D, 0x000020, 0x018040, 0x00107D, + 0x018042, 0x0011FD, 0x3B804A, 0x09804A, + 0x20000A, 0x000095, 0x1A1144, 0x00A144, + 0x0E5886, 0x00040D, 0x00B984, 0x0E5986, + 0x0018FD, 0x018042, 0x0010FD, 0x09804A, + 0x28000A, 0x000095, 0x010924, 0x002A64, + 0x0E4986, 0x000007, 0x002904, 0x0E5A86, + 0x000007, 0x0E6206, 0x080002, 0x00008D, + 0x00387D, 0x000820, 0x018040, 0x00127D, + 0x018042, 0x10000A, 0x003904, 0x0F0986, + 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986, + 0x000025, 0x0FB206, 0x00002D, 0x000015, + 0x00082D, 0x02E00D, 0x000820, 0x0FFA06, + 0x00000D, 0x7F8035, 0x00B984, 0x0FA986, + 0x400025, 0x00008D, 0x110944, 0x000007, + 0x00018D, 0x109504, 0x000007, 0x009164, + 0x000424, 0x000424, 0x000424, 0x100102, + 0x280002, 0x02DF0D, 0x000820, 0x0FFA06, + 0x00018D, 0x00042D, 0x00008D, 0x109504, + 0x000007, 0x00020D, 0x109184, 0x000007, + 0x02DF8D, 0x000820, 0x00008D, 0x0038FD, + 0x018040, 0x003BFD, 0x001020, 0x03A860, + 0x000815, 0x313184, 0x212184, 0x000007, + 0x03B060, 0x03A060, 0x018040, 0x0022FD, + 0x000095, 0x010924, 0x000424, 0x000424, + 0x001264, 0x100102, 0x000820, 0x039060, + 0x018040, 0x001924, 0x010F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x000424, 0x000424, + 0x00117D, 0x018042, 0x08000A, 0x000A24, + 0x280502, 0x280C02, 0x09800D, 0x000820, + 0x0002FD, 0x018040, 0x200007, 0x0022FD, + 0x018042, 0x08000A, 0x000095, 0x280DC4, + 0x011924, 0x00197D, 0x018042, 0x0011FD, + 0x09804A, 0x10000A, 0x0000B5, 0x113144, + 0x0A8D04, 0x000007, 0x080A44, 0x129504, + 0x000007, 0x0023FD, 0x001020, 0x038040, + 0x101244, 0x000007, 0x000820, 0x039060, + 0x018040, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x123286, 0x000007, 0x003BFD, + 0x000100, 0x000A10, 0x0B807A, 0x13804A, + 0x090984, 0x000007, 0x000095, 0x013D04, + 0x12B886, 0x10000A, 0x100002, 0x090984, + 0x000007, 0x038042, 0x11804A, 0x090D04, + 0x000007, 0x10000A, 0x090D84, 0x000007, + 0x00257D, 0x000820, 0x018040, 0x00010D, + 0x000810, 0x28143A, 0x00127D, 0x018042, + 0x20000A, 0x00197D, 0x018042, 0x00117D, + 0x31804A, 0x10000A, 0x003124, 0x013B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x300102, + 0x003124, 0x000424, 0x000424, 0x001224, + 0x280502, 0x001A4C, 0x143986, 0x700002, + 0x00002D, 0x030000, 0x00387D, 0x018042, + 0x10000A, 0x146206, 0x002124, 0x0000AD, + 0x100002, 0x00010D, 0x000924, 0x006B24, + 0x014A0D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x003264, 0x00008D, 0x000A24, 0x001020, + 0x00227D, 0x018040, 0x014F8D, 0x000810, + 0x08043A, 0x2B5A06, 0x000007, 0x002820, + 0x00207D, 0x018040, 0x00117D, 0x038042, + 0x13804A, 0x33800A, 0x00387D, 0x018042, + 0x08000A, 0x000904, 0x177286, 0x000007, + 0x00008D, 0x030964, 0x015B0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x380102, 0x000424, + 0x000424, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x280502, 0x001A4C, 0x177186, 0x000007, + 0x032164, 0x00632C, 0x003DFD, 0x018042, + 0x08000A, 0x000095, 0x090904, 0x000007, + 0x000820, 0x001A4C, 0x169986, 0x018040, + 0x030000, 0x16B206, 0x002124, 0x00010D, + 0x000924, 0x006B24, 0x016F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x003A64, 0x000095, + 0x001224, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x171286, 0x000007, 0x01760D, + 0x000810, 0x08043A, 0x2B5A06, 0x000007, + 0x160A06, 0x000007, 0x007020, 0x08010A, + 0x10012A, 0x0020FD, 0x038860, 0x039060, + 0x018040, 0x00227D, 0x018042, 0x003DFD, + 0x08000A, 0x31844A, 0x000904, 0x181086, + 0x18008B, 0x00008D, 0x189904, 0x00312C, + 0x18E206, 0x000007, 0x00324C, 0x186B86, + 0x000007, 0x001904, 0x186886, 0x000007, + 0x000095, 0x199144, 0x00222C, 0x003124, + 0x00636C, 0x000E3D, 0x001375, 0x000BFD, + 0x010042, 0x09804A, 0x10000A, 0x038AEC, + 0x0393EC, 0x00224C, 0x18E186, 0x000007, + 0x00008D, 0x189904, 0x00226C, 0x00322C, + 0x30050A, 0x301DAB, 0x002083, 0x0018FD, + 0x018042, 0x08000A, 0x018924, 0x300502, + 0x001083, 0x001875, 0x010042, 0x10000A, + 0x00008D, 0x010924, 0x001375, 0x330542, + 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB, + 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B, + 0x006083, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x19B286, 0x000007, 0x001E2D, + 0x0005FD, 0x018042, 0x08000A, 0x028924, + 0x280502, 0x00060D, 0x000810, 0x280C3A, + 0x00008D, 0x000810, 0x28143A, 0x0A808D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x001275, 0x030042, 0x21004A, 0x00008D, + 0x1A0944, 0x000007, 0x01AB8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0001F5, + 0x030042, 0x0D004A, 0x10000A, 0x089144, + 0x000007, 0x000820, 0x010040, 0x0025F5, + 0x0A3144, 0x000007, 0x000820, 0x032860, + 0x030040, 0x00217D, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00008D, 0x000124, 0x00012C, 0x000E64, + 0x001A64, 0x00636C, 0x08010A, 0x10012A, + 0x000820, 0x031060, 0x030040, 0x0020FD, + 0x018042, 0x08000A, 0x00227D, 0x018042, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00197D, 0x018042, 0x08000A, 0x0022FD, + 0x038042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x090D04, 0x000007, 0x000820, + 0x030040, 0x038042, 0x0B804A, 0x10000A, + 0x000820, 0x031060, 0x030040, 0x038042, + 0x13804A, 0x19804A, 0x110D04, 0x198D04, + 0x000007, 0x08000A, 0x001020, 0x031860, + 0x030860, 0x030040, 0x00008D, 0x0B0944, + 0x000007, 0x000820, 0x010040, 0x0005F5, + 0x030042, 0x08000A, 0x000820, 0x010040, + 0x0000F5, 0x010042, 0x08000A, 0x000904, + 0x1D9886, 0x001E75, 0x030042, 0x01044A, + 0x000C0A, 0x1DAA06, 0x000007, 0x000402, + 0x000C02, 0x00177D, 0x001AF5, 0x018042, + 0x03144A, 0x031C4A, 0x03244A, 0x032C4A, + 0x03344A, 0x033C4A, 0x03444A, 0x004C0A, + 0x00043D, 0x0013F5, 0x001AFD, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x005502, 0x005D0A, 0x030042, 0x0B004A, + 0x1B804A, 0x13804A, 0x20000A, 0x089144, + 0x19A144, 0x0389E4, 0x0399EC, 0x006502, + 0x006D0A, 0x030042, 0x0B004A, 0x19004A, + 0x2B804A, 0x13804A, 0x21804A, 0x30000A, + 0x089144, 0x19A144, 0x2AB144, 0x0389E4, + 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4, + 0x000702, 0x00107D, 0x000415, 0x018042, + 0x08000A, 0x0109E4, 0x000F02, 0x002AF5, + 0x0019FD, 0x010042, 0x09804A, 0x10000A, + 0x000934, 0x001674, 0x0029F5, 0x010042, + 0x10000A, 0x00917C, 0x002075, 0x010042, + 0x08000A, 0x000904, 0x200A86, 0x0026F5, + 0x0027F5, 0x030042, 0x09004A, 0x10000A, + 0x000A3C, 0x00167C, 0x001A75, 0x000BFD, + 0x010042, 0x51804A, 0x48000A, 0x160007, + 0x001075, 0x010042, 0x282C0A, 0x281D12, + 0x282512, 0x001F32, 0x1E0007, 0x0E0007, + 0x001975, 0x010042, 0x002DF5, 0x0D004A, + 0x10000A, 0x009144, 0x20EA86, 0x010042, + 0x28340A, 0x000E5D, 0x00008D, 0x000375, + 0x000820, 0x010040, 0x05D2F4, 0x54D104, + 0x00735C, 0x218B86, 0x000007, 0x0C0007, + 0x080007, 0x0A0007, 0x02178D, 0x000810, + 0x08043A, 0x34B206, 0x000007, 0x219206, + 0x000007, 0x080007, 0x002275, 0x010042, + 0x20000A, 0x002104, 0x225886, 0x001E2D, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x21CA86, 0x000007, 0x002010, 0x30043A, + 0x00057D, 0x0180C3, 0x08000A, 0x028924, + 0x280502, 0x280C02, 0x0A810D, 0x000820, + 0x0002F5, 0x010040, 0x220007, 0x0004FD, + 0x018042, 0x70000A, 0x030000, 0x007020, + 0x07FA06, 0x018040, 0x022B8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x22C286, + 0x000007, 0x020206, 0x000007, 0x000875, + 0x0009FD, 0x00010D, 0x234206, 0x000295, + 0x000B75, 0x00097D, 0x00000D, 0x000515, + 0x010042, 0x18000A, 0x001904, 0x2A0086, + 0x0006F5, 0x001020, 0x010040, 0x0004F5, + 0x000820, 0x010040, 0x000775, 0x010042, + 0x09804A, 0x10000A, 0x001124, 0x000904, + 0x23F286, 0x000815, 0x080102, 0x101204, + 0x241206, 0x000575, 0x081204, 0x000007, + 0x100102, 0x000575, 0x000425, 0x021124, + 0x100102, 0x000820, 0x031060, 0x010040, + 0x001924, 0x2A0086, 0x00008D, 0x000464, + 0x009D04, 0x291086, 0x180102, 0x000575, + 0x010042, 0x28040A, 0x00018D, 0x000924, + 0x280D02, 0x00000D, 0x000924, 0x281502, + 0x10000D, 0x000820, 0x0002F5, 0x010040, + 0x200007, 0x001175, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x24FA86, 0x000007, + 0x000100, 0x080B20, 0x130B60, 0x1B0B60, + 0x030A60, 0x010040, 0x050042, 0x3D004A, + 0x35004A, 0x2D004A, 0x20000A, 0x0006F5, + 0x010042, 0x28140A, 0x0004F5, 0x010042, + 0x08000A, 0x000315, 0x010D04, 0x260286, + 0x004015, 0x000095, 0x010D04, 0x25F086, + 0x100022, 0x10002A, 0x261A06, 0x000007, + 0x333104, 0x2AA904, 0x000007, 0x032124, + 0x280502, 0x284402, 0x001124, 0x400102, + 0x000424, 0x000424, 0x003224, 0x00292C, + 0x00636C, 0x277386, 0x000007, 0x02B164, + 0x000464, 0x000464, 0x00008D, 0x000A64, + 0x280D02, 0x10008D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x00008D, 0x38B904, + 0x000007, 0x03296C, 0x30010A, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x270286, + 0x000007, 0x00212C, 0x28050A, 0x00316C, + 0x00046C, 0x00046C, 0x28450A, 0x001124, + 0x006B64, 0x100102, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x004124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x27FA86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x284086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x284A86, 0x000007, 0x284402, 0x003124, + 0x300502, 0x003924, 0x300583, 0x000883, + 0x0005F5, 0x010042, 0x28040A, 0x00008D, + 0x008124, 0x280D02, 0x00008D, 0x008124, + 0x281502, 0x10018D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001025, 0x000575, + 0x030042, 0x09004A, 0x10000A, 0x0A0904, + 0x121104, 0x000007, 0x001020, 0x050860, + 0x050040, 0x0006FD, 0x018042, 0x09004A, + 0x10000A, 0x0000A5, 0x0A0904, 0x121104, + 0x000007, 0x000820, 0x019060, 0x010040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x29CA86, 0x000007, 0x244206, 0x000007, + 0x000606, 0x000007, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x2A1A86, 0x000007, + 0x000100, 0x080B20, 0x138B60, 0x1B8B60, + 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60, + 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60, + 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60, + 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60, + 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60, + 0x038A60, 0x000606, 0x018040, 0x00008D, + 0x000A64, 0x280D02, 0x000A24, 0x00027D, + 0x018042, 0x10000A, 0x001224, 0x0003FD, + 0x018042, 0x08000A, 0x000904, 0x2C0A86, + 0x000007, 0x00018D, 0x000A24, 0x000464, + 0x000464, 0x080102, 0x000924, 0x000424, + 0x000424, 0x100102, 0x02000D, 0x009144, + 0x2C6186, 0x000007, 0x0001FD, 0x018042, + 0x08000A, 0x000A44, 0x2C4386, 0x018042, + 0x0A000D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00027D, 0x001020, 0x000606, + 0x018040, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x2CB286, 0x000007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2CE286, + 0x000007, 0x000075, 0x002E7D, 0x010042, + 0x0B804A, 0x000020, 0x000904, 0x000686, + 0x010040, 0x31844A, 0x30048B, 0x000883, + 0x00008D, 0x000810, 0x28143A, 0x00008D, + 0x000810, 0x280C3A, 0x000675, 0x010042, + 0x08000A, 0x003815, 0x010924, 0x280502, + 0x0B000D, 0x000820, 0x0002F5, 0x010040, + 0x000606, 0x220007, 0x000464, 0x000464, + 0x000606, 0x000007, 0x000134, 0x007F8D, + 0x00093C, 0x281D12, 0x282512, 0x001F32, + 0x0E0007, 0x00010D, 0x00037D, 0x000820, + 0x018040, 0x05D2F4, 0x000007, 0x080007, + 0x00037D, 0x018042, 0x08000A, 0x000904, + 0x2E8A86, 0x000007, 0x000606, 0x000007, + 0x000007, 0x000012, 0x100007, 0x320007, + 0x600007, 0x460007, 0x100080, 0x48001A, + 0x004904, 0x2EF186, 0x000007, 0x001210, + 0x58003A, 0x000145, 0x5C5D04, 0x000007, + 0x000080, 0x48001A, 0x004904, 0x2F4186, + 0x000007, 0x001210, 0x50003A, 0x005904, + 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5, + 0x7FFF7D, 0x07D524, 0x004224, 0x500102, + 0x200502, 0x000082, 0x40001A, 0x004104, + 0x2FC986, 0x000007, 0x003865, 0x40001A, + 0x004020, 0x00104D, 0x04C184, 0x31AB86, + 0x000040, 0x040007, 0x000165, 0x000145, + 0x004020, 0x000040, 0x000765, 0x080080, + 0x40001A, 0x004104, 0x305986, 0x000007, + 0x001210, 0x40003A, 0x004104, 0x30B286, + 0x00004D, 0x0000CD, 0x004810, 0x20043A, + 0x000882, 0x40001A, 0x004104, 0x30C186, + 0x000007, 0x004820, 0x005904, 0x319886, + 0x000040, 0x0007E5, 0x200480, 0x2816A0, + 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260, + 0x000040, 0x000032, 0x400075, 0x00007D, + 0x07D574, 0x200512, 0x000082, 0x40001A, + 0x004104, 0x317186, 0x000007, 0x038A06, + 0x640007, 0x0000E5, 0x000020, 0x000040, + 0x000A65, 0x000020, 0x020040, 0x020040, + 0x000040, 0x000165, 0x000042, 0x70000A, + 0x007104, 0x323286, 0x000007, 0x060007, + 0x019A06, 0x640007, 0x050000, 0x007020, + 0x000040, 0x038A06, 0x640007, 0x000007, + 0x00306D, 0x028860, 0x029060, 0x08000A, + 0x028860, 0x008040, 0x100012, 0x00100D, + 0x009184, 0x32D186, 0x000E0D, 0x009184, + 0x33E186, 0x000007, 0x300007, 0x001020, + 0x003B6D, 0x008040, 0x000080, 0x08001A, + 0x000904, 0x32F186, 0x000007, 0x001220, + 0x000DED, 0x008040, 0x008042, 0x10000A, + 0x40000D, 0x109544, 0x000007, 0x001020, + 0x000DED, 0x008040, 0x008042, 0x20040A, + 0x000082, 0x08001A, 0x000904, 0x338186, + 0x000007, 0x003B6D, 0x008042, 0x08000A, + 0x000E15, 0x010984, 0x342B86, 0x600007, + 0x08001A, 0x000C15, 0x010984, 0x341386, + 0x000020, 0x1A0007, 0x0002ED, 0x008040, + 0x620007, 0x00306D, 0x028042, 0x0A804A, + 0x000820, 0x0A804A, 0x000606, 0x10804A, + 0x000007, 0x282512, 0x001F32, 0x05D2F4, + 0x54D104, 0x00735C, 0x000786, 0x000007, + 0x0C0007, 0x0A0007, 0x1C0007, 0x003465, + 0x020040, 0x004820, 0x025060, 0x40000A, + 0x024060, 0x000040, 0x454944, 0x000007, + 0x004020, 0x003AE5, 0x000040, 0x0028E5, + 0x000042, 0x48000A, 0x004904, 0x39F886, + 0x002C65, 0x000042, 0x40000A, 0x0000D5, + 0x454104, 0x000007, 0x000655, 0x054504, + 0x368286, 0x0001D5, 0x054504, 0x368086, + 0x002B65, 0x000042, 0x003AE5, 0x50004A, + 0x40000A, 0x45C3D4, 0x000007, 0x454504, + 0x000007, 0x0000CD, 0x444944, 0x000007, + 0x454504, 0x000007, 0x00014D, 0x554944, + 0x000007, 0x045144, 0x367986, 0x002C65, + 0x000042, 0x48000A, 0x4CD104, 0x000007, + 0x04C144, 0x368386, 0x000007, 0x160007, + 0x002CE5, 0x040042, 0x40000A, 0x004020, + 0x000040, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x36F086, 0x000007, 0x002402, + 0x383206, 0x005C02, 0x0025E5, 0x000042, + 0x40000A, 0x004274, 0x002AE5, 0x000042, + 0x40000A, 0x004274, 0x500112, 0x0029E5, + 0x000042, 0x40000A, 0x004234, 0x454104, + 0x000007, 0x004020, 0x000040, 0x003EE5, + 0x000020, 0x000040, 0x002DE5, 0x400152, + 0x50000A, 0x045144, 0x37DA86, 0x0000C5, + 0x003EE5, 0x004020, 0x000040, 0x002BE5, + 0x000042, 0x40000A, 0x404254, 0x000007, + 0x002AE5, 0x004020, 0x000040, 0x500132, + 0x040134, 0x005674, 0x0029E5, 0x020042, + 0x42000A, 0x000042, 0x50000A, 0x05417C, + 0x0028E5, 0x000042, 0x48000A, 0x0000C5, + 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5, + 0x020042, 0x40004A, 0x50000A, 0x00423C, + 0x00567C, 0x0028E5, 0x004820, 0x000040, + 0x281D12, 0x282512, 0x001F72, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x393A86, + 0x0E0007, 0x160007, 0x1E0007, 0x003EE5, + 0x000042, 0x40000A, 0x004104, 0x397886, + 0x002D65, 0x000042, 0x28340A, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x50004A, 0x05D2F4, 0x54D104, 0x00735C, + 0x39E186, 0x000007, 0x000606, 0x080007, + 0x0C0007, 0x080007, 0x0A0007, 0x0001E5, + 0x020045, 0x004020, 0x000060, 0x000365, + 0x000040, 0x002E65, 0x001A20, 0x0A1A60, + 0x000040, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x000606, 0x50004A, + 0x0017FD, 0x018042, 0x08000A, 0x000904, + 0x225A86, 0x000007, 0x00107D, 0x018042, + 0x0011FD, 0x33804A, 0x19804A, 0x20000A, + 0x000095, 0x2A1144, 0x01A144, 0x3B9086, + 0x00040D, 0x00B184, 0x3B9186, 0x0018FD, + 0x018042, 0x0010FD, 0x09804A, 0x38000A, + 0x000095, 0x010924, 0x003A64, 0x3B8186, + 0x000007, 0x003904, 0x3B9286, 0x000007, + 0x3B9A06, 0x00000D, 0x00008D, 0x000820, + 0x00387D, 0x018040, 0x700002, 0x00117D, + 0x018042, 0x00197D, 0x29804A, 0x30000A, + 0x380002, 0x003124, 0x000424, 0x000424, + 0x002A24, 0x280502, 0x00068D, 0x000810, + 0x28143A, 0x00750D, 0x00B124, 0x002264, + 0x3D0386, 0x284402, 0x000810, 0x280C3A, + 0x0B800D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00758D, 0x00B124, 0x100102, + 0x012144, 0x3E4986, 0x001810, 0x10003A, + 0x00387D, 0x018042, 0x08000A, 0x000904, + 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD, + 0x00008D, 0x023164, 0x000A64, 0x280D02, + 0x0B808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00387D, 0x018042, 0x08000A, + 0x000904, 0x3E3286, 0x030000, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x3D8286, + 0x000007, 0x002810, 0x28043A, 0x00750D, + 0x030924, 0x002264, 0x280D02, 0x02316C, + 0x28450A, 0x0B810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x00008D, 0x000A24, + 0x3E4A06, 0x100102, 0x001810, 0x10003A, + 0x0000BD, 0x003810, 0x30043A, 0x00187D, + 0x018042, 0x0018FD, 0x09804A, 0x20000A, + 0x0000AD, 0x028924, 0x07212C, 0x001010, + 0x300583, 0x300D8B, 0x3014BB, 0x301C83, + 0x002083, 0x00137D, 0x038042, 0x33844A, + 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB, + 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083, + 0x001E0D, 0x0005FD, 0x018042, 0x20000A, + 0x020924, 0x00068D, 0x00A96C, 0x00009D, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x3F6A86, 0x000007, 0x280502, 0x280D0A, + 0x284402, 0x001810, 0x28143A, 0x0C008D, + 0x000820, 0x0002FD, 0x018040, 0x220007, + 0x003904, 0x225886, 0x001E0D, 0x00057D, + 0x018042, 0x20000A, 0x020924, 0x0000A5, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x402A86, 0x000007, 0x280502, 0x280C02, + 0x002010, 0x28143A, 0x0C010D, 0x000820, + 0x0002FD, 0x018040, 0x225A06, 0x220007, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; + +#endif //_HWMCODE_ + + diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in index eea182f5e67579..640d9b21912aa7 100644 --- a/drivers/sound/Config.in +++ b/drivers/sound/Config.in @@ -3,9 +3,6 @@ # 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net> # More hacking for modularisation. # -# See drivers/sound/README.CONFIG for more information. - - # Prompt user for primary drivers. @@ -27,7 +24,7 @@ if [ "$CONFIG_VISWS" = "y" ]; then dep_tristate ' SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND fi -dep_tristate ' Trident 4DWave DX/NX or SiS 7018 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND +dep_tristate ' Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND dep_tristate ' Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND if [ "$CONFIG_SOUND_MSNDCLAS" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "m" ]; then @@ -79,7 +76,7 @@ if [ "$CONFIG_SOUND_MSNDPIN" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "y" ]; then int 'MSND buffer size (kB)' CONFIG_MSND_FIFOSIZE 128 fi -tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX +dep_tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_PCI dep_tristate ' OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND @@ -149,6 +146,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then dep_tristate ' Yamaha FM synthesizer (YM3812/OPL-3) support' CONFIG_SOUND_YM3812 $CONFIG_SOUND_OSS dep_tristate ' Yamaha OPL3-SA1 audio controller' CONFIG_SOUND_OPL3SA1 $CONFIG_SOUND_OSS dep_tristate ' Yamaha OPL3-SA2, SA3, and SAx based PnP cards' CONFIG_SOUND_OPL3SA2 $CONFIG_SOUND_OSS + dep_tristate ' Yamaha PCI legacy mode support' CONFIG_SOUND_YMPCI $CONFIG_SOUND_OSS $CONFIG_PCI dep_tristate ' 6850 UART support' CONFIG_SOUND_UART6850 $CONFIG_SOUND_OSS dep_tristate ' Gallant Audio Cards (SC-6000 and SC-6600 based)' CONFIG_SOUND_AEDSP16 $CONFIG_SOUND_OSS @@ -181,3 +179,4 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then fi +dep_tristate ' TV card (bt848) mixer support' CONFIG_SOUND_TVMIXER $CONFIG_SOUND $CONFIG_I2C diff --git a/drivers/sound/Hwmcode.h b/drivers/sound/Hwmcode.h new file mode 100644 index 00000000000000..e4d9a68fa6a88a --- /dev/null +++ b/drivers/sound/Hwmcode.h @@ -0,0 +1,804 @@ +//============================================================================= +// Copyright (c) 1997 Yamaha Corporation. All Rights Reserved. +// +// Title: +// hwmcode.c +// Desc: +// micro-code for CTRL & DSP +// HISTORY: +// April 03, 1997: 1st try by M. Mukojima +//============================================================================= +#define YDSXG_DSPLENGTH 0x0080 +#define YDSXG_CTRLLENGTH 0x3000 + + +static unsigned long int gdwDSPCode[YDSXG_DSPLENGTH >> 2] = { + 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, + 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, + 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, + 0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + + +// -------------------------------------------- +// DS-1E Controller InstructionRAM Code +// 1999/06/21 +// Buf441 slot is Enabled. +// -------------------------------------------- +// 04/09?@creat +// 04/12 stop nise fix +// 06/21?@WorkingOff timming +static unsigned long gdwCtrl1eCode[YDSXG_CTRLLENGTH >> 2] = { + 0x000007, 0x240007, 0x0C0007, 0x1C0007, + 0x060007, 0x700002, 0x000020, 0x030040, + 0x007104, 0x004286, 0x030040, 0x000F0D, + 0x000810, 0x20043A, 0x000282, 0x00020D, + 0x000810, 0x20043A, 0x001282, 0x200E82, + 0x00800D, 0x000810, 0x20043A, 0x001A82, + 0x03460D, 0x000810, 0x10043A, 0x02EC0D, + 0x000810, 0x18043A, 0x00010D, 0x020015, + 0x0000FD, 0x000020, 0x038860, 0x039060, + 0x038060, 0x038040, 0x038040, 0x038040, + 0x018040, 0x000A7D, 0x038040, 0x038040, + 0x018040, 0x200402, 0x000882, 0x08001A, + 0x000904, 0x017186, 0x000007, 0x260007, + 0x400007, 0x000007, 0x03258D, 0x000810, + 0x18043A, 0x260007, 0x284402, 0x00087D, + 0x018042, 0x00160A, 0x05A206, 0x000007, + 0x440007, 0x00230D, 0x000810, 0x08043A, + 0x22FA06, 0x000007, 0x0007FD, 0x018042, + 0x08000A, 0x000904, 0x02AB86, 0x000195, + 0x090D04, 0x000007, 0x000820, 0x0000F5, + 0x000B7D, 0x01F060, 0x0000FD, 0x033A06, + 0x018040, 0x000A7D, 0x038042, 0x13804A, + 0x18000A, 0x001820, 0x059060, 0x058860, + 0x018040, 0x0000FD, 0x018042, 0x70000A, + 0x000115, 0x071144, 0x033B86, 0x030000, + 0x007020, 0x036206, 0x018040, 0x00360D, + 0x000810, 0x08043A, 0x232206, 0x000007, + 0x02EC0D, 0x000810, 0x18043A, 0x019A06, + 0x000007, 0x240007, 0x000F8D, 0x000810, + 0x00163A, 0x002402, 0x005C02, 0x0028FD, + 0x000020, 0x018040, 0x08000D, 0x000815, + 0x510984, 0x000007, 0x00004D, 0x000E5D, + 0x000E02, 0x00430D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x00008D, 0x000924, + 0x000F02, 0x00470D, 0x000810, 0x08043A, + 0x2E1206, 0x000007, 0x480480, 0x001210, + 0x28043A, 0x00778D, 0x000810, 0x280C3A, + 0x00068D, 0x000810, 0x28143A, 0x284402, + 0x03258D, 0x000810, 0x18043A, 0x07FF8D, + 0x000820, 0x0002FD, 0x018040, 0x260007, + 0x200007, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x051286, 0x000007, 0x240007, + 0x02EC0D, 0x000810, 0x18043A, 0x00387D, + 0x018042, 0x08000A, 0x001015, 0x010984, + 0x019B86, 0x000007, 0x01B206, 0x000007, + 0x0008FD, 0x018042, 0x18000A, 0x001904, + 0x22B886, 0x280007, 0x001810, 0x28043A, + 0x280C02, 0x00000D, 0x000810, 0x28143A, + 0x08808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00020D, 0x189904, 0x000007, + 0x00402D, 0x0000BD, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x065A86, 0x000007, + 0x000100, 0x000A20, 0x00047D, 0x018040, + 0x018042, 0x20000A, 0x003015, 0x012144, + 0x036186, 0x000007, 0x002104, 0x036186, + 0x000007, 0x000F8D, 0x000810, 0x280C3A, + 0x023944, 0x07C986, 0x000007, 0x001810, + 0x28043A, 0x08810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x002810, 0x78003A, + 0x00788D, 0x000810, 0x08043A, 0x2A1206, + 0x000007, 0x00400D, 0x001015, 0x189904, + 0x292904, 0x393904, 0x000007, 0x070206, + 0x000007, 0x0004F5, 0x00007D, 0x000020, + 0x00008D, 0x010860, 0x018040, 0x00047D, + 0x038042, 0x21804A, 0x18000A, 0x021944, + 0x229086, 0x000007, 0x004075, 0x71F104, + 0x000007, 0x010042, 0x28000A, 0x002904, + 0x225886, 0x000007, 0x003C0D, 0x30A904, + 0x000007, 0x00077D, 0x018042, 0x08000A, + 0x000904, 0x08DA86, 0x00057D, 0x002820, + 0x03B060, 0x08F206, 0x018040, 0x003020, + 0x03A860, 0x018040, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x08FA86, 0x000007, + 0x00057D, 0x018042, 0x28040A, 0x000E8D, + 0x000810, 0x280C3A, 0x00000D, 0x000810, + 0x28143A, 0x09000D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x003DFD, 0x000020, + 0x018040, 0x00107D, 0x009D8D, 0x000810, + 0x08043A, 0x2A1206, 0x000007, 0x000815, + 0x08001A, 0x010984, 0x0A5186, 0x00137D, + 0x200500, 0x280F20, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x038A60, 0x018040, 0x00107D, 0x018042, + 0x08000A, 0x000215, 0x010984, 0x3A8186, + 0x000007, 0x007FBD, 0x383DC4, 0x000007, + 0x001A7D, 0x001375, 0x018042, 0x09004A, + 0x10000A, 0x0B8D04, 0x139504, 0x000007, + 0x000820, 0x019060, 0x001104, 0x225886, + 0x010040, 0x0017FD, 0x018042, 0x08000A, + 0x000904, 0x225A86, 0x000007, 0x00197D, + 0x038042, 0x09804A, 0x10000A, 0x000924, + 0x001664, 0x0011FD, 0x038042, 0x2B804A, + 0x19804A, 0x00008D, 0x218944, 0x000007, + 0x002244, 0x0C1986, 0x000007, 0x001A64, + 0x002A24, 0x00197D, 0x080102, 0x100122, + 0x000820, 0x039060, 0x018040, 0x003DFD, + 0x00008D, 0x000820, 0x018040, 0x001375, + 0x001A7D, 0x010042, 0x09804A, 0x10000A, + 0x00021D, 0x0189E4, 0x2992E4, 0x309144, + 0x000007, 0x00060D, 0x000A15, 0x000C1D, + 0x001025, 0x00A9E4, 0x012BE4, 0x000464, + 0x01B3E4, 0x0232E4, 0x000464, 0x000464, + 0x000464, 0x000464, 0x00040D, 0x08B1C4, + 0x000007, 0x000820, 0x000BF5, 0x030040, + 0x00197D, 0x038042, 0x09804A, 0x000A24, + 0x08000A, 0x080E64, 0x000007, 0x100122, + 0x000820, 0x031060, 0x010040, 0x0064AC, + 0x00027D, 0x000020, 0x018040, 0x00107D, + 0x018042, 0x0011FD, 0x3B804A, 0x09804A, + 0x20000A, 0x000095, 0x1A1144, 0x00A144, + 0x0E5886, 0x00040D, 0x00B984, 0x0E5986, + 0x0018FD, 0x018042, 0x0010FD, 0x09804A, + 0x28000A, 0x000095, 0x010924, 0x002A64, + 0x0E4986, 0x000007, 0x002904, 0x0E5A86, + 0x000007, 0x0E6206, 0x080002, 0x00008D, + 0x00387D, 0x000820, 0x018040, 0x00127D, + 0x018042, 0x10000A, 0x003904, 0x0F0986, + 0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986, + 0x000025, 0x0FB206, 0x00002D, 0x000015, + 0x00082D, 0x02E00D, 0x000820, 0x0FFA06, + 0x00000D, 0x7F8035, 0x00B984, 0x0FA986, + 0x400025, 0x00008D, 0x110944, 0x000007, + 0x00018D, 0x109504, 0x000007, 0x009164, + 0x000424, 0x000424, 0x000424, 0x100102, + 0x280002, 0x02DF0D, 0x000820, 0x0FFA06, + 0x00018D, 0x00042D, 0x00008D, 0x109504, + 0x000007, 0x00020D, 0x109184, 0x000007, + 0x02DF8D, 0x000820, 0x00008D, 0x0038FD, + 0x018040, 0x003BFD, 0x001020, 0x03A860, + 0x000815, 0x313184, 0x212184, 0x000007, + 0x03B060, 0x03A060, 0x018040, 0x0022FD, + 0x000095, 0x010924, 0x000424, 0x000424, + 0x001264, 0x100102, 0x000820, 0x039060, + 0x018040, 0x001924, 0x010F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x000424, 0x000424, + 0x00117D, 0x018042, 0x08000A, 0x000A24, + 0x280502, 0x280C02, 0x09800D, 0x000820, + 0x0002FD, 0x018040, 0x200007, 0x0022FD, + 0x018042, 0x08000A, 0x000095, 0x280DC4, + 0x011924, 0x00197D, 0x018042, 0x0011FD, + 0x09804A, 0x10000A, 0x0000B5, 0x113144, + 0x0A8D04, 0x000007, 0x080A44, 0x129504, + 0x000007, 0x0023FD, 0x001020, 0x038040, + 0x101244, 0x000007, 0x000820, 0x039060, + 0x018040, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x123286, 0x000007, 0x003BFD, + 0x000100, 0x000A10, 0x0B807A, 0x13804A, + 0x090984, 0x000007, 0x000095, 0x013D04, + 0x12B886, 0x10000A, 0x100002, 0x090984, + 0x000007, 0x038042, 0x11804A, 0x090D04, + 0x000007, 0x10000A, 0x090D84, 0x000007, + 0x00257D, 0x000820, 0x018040, 0x00010D, + 0x000810, 0x28143A, 0x00127D, 0x018042, + 0x20000A, 0x00197D, 0x018042, 0x00117D, + 0x31804A, 0x10000A, 0x003124, 0x013B8D, + 0x00397D, 0x000820, 0x058040, 0x038042, + 0x09844A, 0x000606, 0x08040A, 0x300102, + 0x003124, 0x000424, 0x000424, 0x001224, + 0x280502, 0x001A4C, 0x143986, 0x700002, + 0x00002D, 0x030000, 0x00387D, 0x018042, + 0x10000A, 0x146206, 0x002124, 0x0000AD, + 0x100002, 0x00010D, 0x000924, 0x006B24, + 0x014A0D, 0x00397D, 0x000820, 0x058040, + 0x038042, 0x09844A, 0x000606, 0x08040A, + 0x003264, 0x00008D, 0x000A24, 0x001020, + 0x00227D, 0x018040, 0x014F8D, 0x000810, + 0x08043A, 0x2B5A06, 0x000007, 0x002820, + 0x00207D, 0x018040, 0x00117D, 0x038042, + 0x13804A, 0x33800A, 0x00387D, 0x018042, + 0x08000A, 0x000904, 0x177286, 0x000007, + 0x00008D, 0x030964, 0x015B0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x380102, 0x000424, + 0x000424, 0x001224, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x15DA86, 0x000007, + 0x280502, 0x001A4C, 0x177186, 0x000007, + 0x032164, 0x00632C, 0x003DFD, 0x018042, + 0x08000A, 0x000095, 0x090904, 0x000007, + 0x000820, 0x001A4C, 0x169986, 0x018040, + 0x030000, 0x16B206, 0x002124, 0x00010D, + 0x000924, 0x006B24, 0x016F0D, 0x00397D, + 0x000820, 0x058040, 0x038042, 0x09844A, + 0x000606, 0x08040A, 0x003A64, 0x000095, + 0x001224, 0x0002FD, 0x018042, 0x08000A, + 0x000904, 0x171286, 0x000007, 0x01760D, + 0x000810, 0x08043A, 0x2B5A06, 0x000007, + 0x160A06, 0x000007, 0x007020, 0x08010A, + 0x10012A, 0x0020FD, 0x038860, 0x039060, + 0x018040, 0x00227D, 0x018042, 0x003DFD, + 0x08000A, 0x31844A, 0x000904, 0x181086, + 0x18008B, 0x00008D, 0x189904, 0x00312C, + 0x18E206, 0x000007, 0x00324C, 0x186B86, + 0x000007, 0x001904, 0x186886, 0x000007, + 0x000095, 0x199144, 0x00222C, 0x003124, + 0x00636C, 0x000E3D, 0x001375, 0x000BFD, + 0x010042, 0x09804A, 0x10000A, 0x038AEC, + 0x0393EC, 0x00224C, 0x18E186, 0x000007, + 0x00008D, 0x189904, 0x00226C, 0x00322C, + 0x30050A, 0x301DAB, 0x002083, 0x0018FD, + 0x018042, 0x08000A, 0x018924, 0x300502, + 0x001083, 0x001875, 0x010042, 0x10000A, + 0x00008D, 0x010924, 0x001375, 0x330542, + 0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB, + 0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B, + 0x006083, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x19B286, 0x000007, 0x001E2D, + 0x0005FD, 0x018042, 0x08000A, 0x028924, + 0x280502, 0x00060D, 0x000810, 0x280C3A, + 0x00008D, 0x000810, 0x28143A, 0x0A808D, + 0x000820, 0x0002F5, 0x010040, 0x220007, + 0x001275, 0x030042, 0x21004A, 0x00008D, + 0x1A0944, 0x000007, 0x01AB8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0001F5, + 0x030042, 0x0D004A, 0x10000A, 0x089144, + 0x000007, 0x000820, 0x010040, 0x0025F5, + 0x0A3144, 0x000007, 0x000820, 0x032860, + 0x030040, 0x00217D, 0x038042, 0x0B804A, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00008D, 0x000124, 0x00012C, 0x000E64, + 0x001A64, 0x00636C, 0x08010A, 0x10012A, + 0x000820, 0x031060, 0x030040, 0x0020FD, + 0x018042, 0x08000A, 0x00227D, 0x018042, + 0x10000A, 0x000820, 0x031060, 0x030040, + 0x00197D, 0x018042, 0x08000A, 0x0022FD, + 0x038042, 0x10000A, 0x000820, 0x031060, + 0x030040, 0x090D04, 0x000007, 0x000820, + 0x030040, 0x038042, 0x0B804A, 0x10000A, + 0x000820, 0x031060, 0x030040, 0x038042, + 0x13804A, 0x19804A, 0x110D04, 0x198D04, + 0x000007, 0x08000A, 0x001020, 0x031860, + 0x030860, 0x030040, 0x00008D, 0x0B0944, + 0x000007, 0x000820, 0x010040, 0x0005F5, + 0x030042, 0x08000A, 0x000820, 0x010040, + 0x0000F5, 0x010042, 0x08000A, 0x000904, + 0x1D9886, 0x001E75, 0x030042, 0x01044A, + 0x000C0A, 0x1DAA06, 0x000007, 0x000402, + 0x000C02, 0x00177D, 0x001AF5, 0x018042, + 0x03144A, 0x031C4A, 0x03244A, 0x032C4A, + 0x03344A, 0x033C4A, 0x03444A, 0x004C0A, + 0x00043D, 0x0013F5, 0x001AFD, 0x030042, + 0x0B004A, 0x1B804A, 0x13804A, 0x20000A, + 0x089144, 0x19A144, 0x0389E4, 0x0399EC, + 0x005502, 0x005D0A, 0x030042, 0x0B004A, + 0x1B804A, 0x13804A, 0x20000A, 0x089144, + 0x19A144, 0x0389E4, 0x0399EC, 0x006502, + 0x006D0A, 0x030042, 0x0B004A, 0x19004A, + 0x2B804A, 0x13804A, 0x21804A, 0x30000A, + 0x089144, 0x19A144, 0x2AB144, 0x0389E4, + 0x0399EC, 0x007502, 0x007D0A, 0x03A9E4, + 0x000702, 0x00107D, 0x000415, 0x018042, + 0x08000A, 0x0109E4, 0x000F02, 0x002AF5, + 0x0019FD, 0x010042, 0x09804A, 0x10000A, + 0x000934, 0x001674, 0x0029F5, 0x010042, + 0x10000A, 0x00917C, 0x002075, 0x010042, + 0x08000A, 0x000904, 0x200A86, 0x0026F5, + 0x0027F5, 0x030042, 0x09004A, 0x10000A, + 0x000A3C, 0x00167C, 0x001A75, 0x000BFD, + 0x010042, 0x51804A, 0x48000A, 0x160007, + 0x001075, 0x010042, 0x282C0A, 0x281D12, + 0x282512, 0x001F32, 0x1E0007, 0x0E0007, + 0x001975, 0x010042, 0x002DF5, 0x0D004A, + 0x10000A, 0x009144, 0x20EA86, 0x010042, + 0x28340A, 0x000E5D, 0x00008D, 0x000375, + 0x000820, 0x010040, 0x05D2F4, 0x54D104, + 0x00735C, 0x218B86, 0x000007, 0x0C0007, + 0x080007, 0x0A0007, 0x02178D, 0x000810, + 0x08043A, 0x34B206, 0x000007, 0x219206, + 0x000007, 0x080007, 0x002275, 0x010042, + 0x20000A, 0x002104, 0x225886, 0x001E2D, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x21CA86, 0x000007, 0x002010, 0x30043A, + 0x00057D, 0x0180C3, 0x08000A, 0x028924, + 0x280502, 0x280C02, 0x0A810D, 0x000820, + 0x0002F5, 0x010040, 0x220007, 0x0004FD, + 0x018042, 0x70000A, 0x030000, 0x007020, + 0x07FA06, 0x018040, 0x022B8D, 0x000810, + 0x08043A, 0x2CAA06, 0x000007, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x22C286, + 0x000007, 0x020206, 0x000007, 0x000875, + 0x0009FD, 0x00010D, 0x234206, 0x000295, + 0x000B75, 0x00097D, 0x00000D, 0x000515, + 0x010042, 0x18000A, 0x001904, 0x2A0086, + 0x0006F5, 0x001020, 0x010040, 0x0004F5, + 0x000820, 0x010040, 0x000775, 0x010042, + 0x09804A, 0x10000A, 0x001124, 0x000904, + 0x23F286, 0x000815, 0x080102, 0x101204, + 0x241206, 0x000575, 0x081204, 0x000007, + 0x100102, 0x000575, 0x000425, 0x021124, + 0x100102, 0x000820, 0x031060, 0x010040, + 0x001924, 0x2A0086, 0x00008D, 0x000464, + 0x009D04, 0x291086, 0x180102, 0x000575, + 0x010042, 0x28040A, 0x00018D, 0x000924, + 0x280D02, 0x00000D, 0x000924, 0x281502, + 0x10000D, 0x000820, 0x0002F5, 0x010040, + 0x200007, 0x001175, 0x0002FD, 0x018042, + 0x08000A, 0x000904, 0x24FA86, 0x000007, + 0x000100, 0x080B20, 0x130B60, 0x1B0B60, + 0x030A60, 0x010040, 0x050042, 0x3D004A, + 0x35004A, 0x2D004A, 0x20000A, 0x0006F5, + 0x010042, 0x28140A, 0x0004F5, 0x010042, + 0x08000A, 0x000315, 0x010D04, 0x260286, + 0x004015, 0x000095, 0x010D04, 0x25F086, + 0x100022, 0x10002A, 0x261A06, 0x000007, + 0x333104, 0x2AA904, 0x000007, 0x032124, + 0x280502, 0x284402, 0x001124, 0x400102, + 0x000424, 0x000424, 0x003224, 0x00292C, + 0x00636C, 0x277386, 0x000007, 0x02B164, + 0x000464, 0x000464, 0x00008D, 0x000A64, + 0x280D02, 0x10008D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x00008D, 0x38B904, + 0x000007, 0x03296C, 0x30010A, 0x0002F5, + 0x010042, 0x08000A, 0x000904, 0x270286, + 0x000007, 0x00212C, 0x28050A, 0x00316C, + 0x00046C, 0x00046C, 0x28450A, 0x001124, + 0x006B64, 0x100102, 0x00008D, 0x01096C, + 0x280D0A, 0x10010D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x004124, 0x000424, + 0x000424, 0x003224, 0x300102, 0x032944, + 0x27FA86, 0x000007, 0x300002, 0x0004F5, + 0x010042, 0x08000A, 0x000315, 0x010D04, + 0x284086, 0x003124, 0x000464, 0x300102, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x284A86, 0x000007, 0x284402, 0x003124, + 0x300502, 0x003924, 0x300583, 0x000883, + 0x0005F5, 0x010042, 0x28040A, 0x00008D, + 0x008124, 0x280D02, 0x00008D, 0x008124, + 0x281502, 0x10018D, 0x000820, 0x0002F5, + 0x010040, 0x220007, 0x001025, 0x000575, + 0x030042, 0x09004A, 0x10000A, 0x0A0904, + 0x121104, 0x000007, 0x001020, 0x050860, + 0x050040, 0x0006FD, 0x018042, 0x09004A, + 0x10000A, 0x0000A5, 0x0A0904, 0x121104, + 0x000007, 0x000820, 0x019060, 0x010040, + 0x0002F5, 0x010042, 0x08000A, 0x000904, + 0x29CA86, 0x000007, 0x244206, 0x000007, + 0x000606, 0x000007, 0x0002F5, 0x010042, + 0x08000A, 0x000904, 0x2A1A86, 0x000007, + 0x000100, 0x080B20, 0x138B60, 0x1B8B60, + 0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60, + 0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60, + 0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60, + 0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60, + 0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60, + 0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60, + 0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60, + 0x038A60, 0x000606, 0x018040, 0x00008D, + 0x000A64, 0x280D02, 0x000A24, 0x00027D, + 0x018042, 0x10000A, 0x001224, 0x0003FD, + 0x018042, 0x08000A, 0x000904, 0x2C0A86, + 0x000007, 0x00018D, 0x000A24, 0x000464, + 0x000464, 0x080102, 0x000924, 0x000424, + 0x000424, 0x100102, 0x02000D, 0x009144, + 0x2C6186, 0x000007, 0x0001FD, 0x018042, + 0x08000A, 0x000A44, 0x2C4386, 0x018042, + 0x0A000D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00027D, 0x001020, 0x000606, + 0x018040, 0x0002F5, 0x010042, 0x08000A, + 0x000904, 0x2CB286, 0x000007, 0x00037D, + 0x018042, 0x08000A, 0x000904, 0x2CE286, + 0x000007, 0x000075, 0x002E7D, 0x010042, + 0x0B804A, 0x000020, 0x000904, 0x000686, + 0x010040, 0x31844A, 0x30048B, 0x000883, + 0x00008D, 0x000810, 0x28143A, 0x00008D, + 0x000810, 0x280C3A, 0x000675, 0x010042, + 0x08000A, 0x003815, 0x010924, 0x280502, + 0x0B000D, 0x000820, 0x0002F5, 0x010040, + 0x000606, 0x220007, 0x000464, 0x000464, + 0x000606, 0x000007, 0x000134, 0x007F8D, + 0x00093C, 0x281D12, 0x282512, 0x001F32, + 0x0E0007, 0x00010D, 0x00037D, 0x000820, + 0x018040, 0x05D2F4, 0x000007, 0x080007, + 0x00037D, 0x018042, 0x08000A, 0x000904, + 0x2E8A86, 0x000007, 0x000606, 0x000007, + 0x000007, 0x000012, 0x100007, 0x320007, + 0x600007, 0x460007, 0x100080, 0x48001A, + 0x004904, 0x2EF186, 0x000007, 0x001210, + 0x58003A, 0x000145, 0x5C5D04, 0x000007, + 0x000080, 0x48001A, 0x004904, 0x2F4186, + 0x000007, 0x001210, 0x50003A, 0x005904, + 0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5, + 0x7FFF7D, 0x07D524, 0x004224, 0x500102, + 0x200502, 0x000082, 0x40001A, 0x004104, + 0x2FC986, 0x000007, 0x003865, 0x40001A, + 0x004020, 0x00104D, 0x04C184, 0x31AB86, + 0x000040, 0x040007, 0x000165, 0x000145, + 0x004020, 0x000040, 0x000765, 0x080080, + 0x40001A, 0x004104, 0x305986, 0x000007, + 0x001210, 0x40003A, 0x004104, 0x30B286, + 0x00004D, 0x0000CD, 0x004810, 0x20043A, + 0x000882, 0x40001A, 0x004104, 0x30C186, + 0x000007, 0x004820, 0x005904, 0x319886, + 0x000040, 0x0007E5, 0x200480, 0x2816A0, + 0x3216E0, 0x3A16E0, 0x4216E0, 0x021260, + 0x000040, 0x000032, 0x400075, 0x00007D, + 0x07D574, 0x200512, 0x000082, 0x40001A, + 0x004104, 0x317186, 0x000007, 0x038A06, + 0x640007, 0x0000E5, 0x000020, 0x000040, + 0x000A65, 0x000020, 0x020040, 0x020040, + 0x000040, 0x000165, 0x000042, 0x70000A, + 0x007104, 0x323286, 0x000007, 0x060007, + 0x019A06, 0x640007, 0x050000, 0x007020, + 0x000040, 0x038A06, 0x640007, 0x000007, + 0x00306D, 0x028860, 0x029060, 0x08000A, + 0x028860, 0x008040, 0x100012, 0x00100D, + 0x009184, 0x32D186, 0x000E0D, 0x009184, + 0x33E186, 0x000007, 0x300007, 0x001020, + 0x003B6D, 0x008040, 0x000080, 0x08001A, + 0x000904, 0x32F186, 0x000007, 0x001220, + 0x000DED, 0x008040, 0x008042, 0x10000A, + 0x40000D, 0x109544, 0x000007, 0x001020, + 0x000DED, 0x008040, 0x008042, 0x20040A, + 0x000082, 0x08001A, 0x000904, 0x338186, + 0x000007, 0x003B6D, 0x008042, 0x08000A, + 0x000E15, 0x010984, 0x342B86, 0x600007, + 0x08001A, 0x000C15, 0x010984, 0x341386, + 0x000020, 0x1A0007, 0x0002ED, 0x008040, + 0x620007, 0x00306D, 0x028042, 0x0A804A, + 0x000820, 0x0A804A, 0x000606, 0x10804A, + 0x000007, 0x282512, 0x001F32, 0x05D2F4, + 0x54D104, 0x00735C, 0x000786, 0x000007, + 0x0C0007, 0x0A0007, 0x1C0007, 0x003465, + 0x020040, 0x004820, 0x025060, 0x40000A, + 0x024060, 0x000040, 0x454944, 0x000007, + 0x004020, 0x003AE5, 0x000040, 0x0028E5, + 0x000042, 0x48000A, 0x004904, 0x39F886, + 0x002C65, 0x000042, 0x40000A, 0x0000D5, + 0x454104, 0x000007, 0x000655, 0x054504, + 0x368286, 0x0001D5, 0x054504, 0x368086, + 0x002B65, 0x000042, 0x003AE5, 0x50004A, + 0x40000A, 0x45C3D4, 0x000007, 0x454504, + 0x000007, 0x0000CD, 0x444944, 0x000007, + 0x454504, 0x000007, 0x00014D, 0x554944, + 0x000007, 0x045144, 0x367986, 0x002C65, + 0x000042, 0x48000A, 0x4CD104, 0x000007, + 0x04C144, 0x368386, 0x000007, 0x160007, + 0x002CE5, 0x040042, 0x40000A, 0x004020, + 0x000040, 0x002965, 0x000042, 0x40000A, + 0x004104, 0x36F086, 0x000007, 0x002402, + 0x383206, 0x005C02, 0x0025E5, 0x000042, + 0x40000A, 0x004274, 0x002AE5, 0x000042, + 0x40000A, 0x004274, 0x500112, 0x0029E5, + 0x000042, 0x40000A, 0x004234, 0x454104, + 0x000007, 0x004020, 0x000040, 0x003EE5, + 0x000020, 0x000040, 0x002DE5, 0x400152, + 0x50000A, 0x045144, 0x37DA86, 0x0000C5, + 0x003EE5, 0x004020, 0x000040, 0x002BE5, + 0x000042, 0x40000A, 0x404254, 0x000007, + 0x002AE5, 0x004020, 0x000040, 0x500132, + 0x040134, 0x005674, 0x0029E5, 0x020042, + 0x42000A, 0x000042, 0x50000A, 0x05417C, + 0x0028E5, 0x000042, 0x48000A, 0x0000C5, + 0x4CC144, 0x38A086, 0x0026E5, 0x0027E5, + 0x020042, 0x40004A, 0x50000A, 0x00423C, + 0x00567C, 0x0028E5, 0x004820, 0x000040, + 0x281D12, 0x282512, 0x001F72, 0x002965, + 0x000042, 0x40000A, 0x004104, 0x393A86, + 0x0E0007, 0x160007, 0x1E0007, 0x003EE5, + 0x000042, 0x40000A, 0x004104, 0x397886, + 0x002D65, 0x000042, 0x28340A, 0x003465, + 0x020042, 0x42004A, 0x004020, 0x4A004A, + 0x50004A, 0x05D2F4, 0x54D104, 0x00735C, + 0x39E186, 0x000007, 0x000606, 0x080007, + 0x0C0007, 0x080007, 0x0A0007, 0x0001E5, + 0x020045, 0x004020, 0x000060, 0x000365, + 0x000040, 0x002E65, 0x001A20, 0x0A1A60, + 0x000040, 0x003465, 0x020042, 0x42004A, + 0x004020, 0x4A004A, 0x000606, 0x50004A, + 0x0017FD, 0x018042, 0x08000A, 0x000904, + 0x225A86, 0x000007, 0x00107D, 0x018042, + 0x0011FD, 0x33804A, 0x19804A, 0x20000A, + 0x000095, 0x2A1144, 0x01A144, 0x3B9086, + 0x00040D, 0x00B184, 0x3B9186, 0x0018FD, + 0x018042, 0x0010FD, 0x09804A, 0x38000A, + 0x000095, 0x010924, 0x003A64, 0x3B8186, + 0x000007, 0x003904, 0x3B9286, 0x000007, + 0x3B9A06, 0x00000D, 0x00008D, 0x000820, + 0x00387D, 0x018040, 0x700002, 0x00117D, + 0x018042, 0x00197D, 0x29804A, 0x30000A, + 0x380002, 0x003124, 0x000424, 0x000424, + 0x002A24, 0x280502, 0x00068D, 0x000810, + 0x28143A, 0x00750D, 0x00B124, 0x002264, + 0x3D0386, 0x284402, 0x000810, 0x280C3A, + 0x0B800D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00758D, 0x00B124, 0x100102, + 0x012144, 0x3E4986, 0x001810, 0x10003A, + 0x00387D, 0x018042, 0x08000A, 0x000904, + 0x3E4886, 0x030000, 0x3E4A06, 0x0000BD, + 0x00008D, 0x023164, 0x000A64, 0x280D02, + 0x0B808D, 0x000820, 0x0002FD, 0x018040, + 0x200007, 0x00387D, 0x018042, 0x08000A, + 0x000904, 0x3E3286, 0x030000, 0x0002FD, + 0x018042, 0x08000A, 0x000904, 0x3D8286, + 0x000007, 0x002810, 0x28043A, 0x00750D, + 0x030924, 0x002264, 0x280D02, 0x02316C, + 0x28450A, 0x0B810D, 0x000820, 0x0002FD, + 0x018040, 0x200007, 0x00008D, 0x000A24, + 0x3E4A06, 0x100102, 0x001810, 0x10003A, + 0x0000BD, 0x003810, 0x30043A, 0x00187D, + 0x018042, 0x0018FD, 0x09804A, 0x20000A, + 0x0000AD, 0x028924, 0x07212C, 0x001010, + 0x300583, 0x300D8B, 0x3014BB, 0x301C83, + 0x002083, 0x00137D, 0x038042, 0x33844A, + 0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB, + 0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083, + 0x001E0D, 0x0005FD, 0x018042, 0x20000A, + 0x020924, 0x00068D, 0x00A96C, 0x00009D, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x3F6A86, 0x000007, 0x280502, 0x280D0A, + 0x284402, 0x001810, 0x28143A, 0x0C008D, + 0x000820, 0x0002FD, 0x018040, 0x220007, + 0x003904, 0x225886, 0x001E0D, 0x00057D, + 0x018042, 0x20000A, 0x020924, 0x0000A5, + 0x0002FD, 0x018042, 0x08000A, 0x000904, + 0x402A86, 0x000007, 0x280502, 0x280C02, + 0x002010, 0x28143A, 0x0C010D, 0x000820, + 0x0002FD, 0x018040, 0x225A06, 0x220007, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000 +}; diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index ec43a1d2662148..10fbd5871e5803 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_SOUND_ACI_MIXER) += aci.o obj-$(CONFIG_SOUND_AWE32_SYNTH) += awe_wave.o obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o ac97_codec.o +obj-$(CONFIG_SOUND_YMPCI) += ymf_sb.o sb_lib.o uart401.o obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o obj-$(CONFIG_SOUND_VWSND) += vwsnd.o diff --git a/drivers/sound/ac97_codec.c b/drivers/sound/ac97_codec.c index b26c3a8d5d3f61..23e94845a0bcaa 100644 --- a/drivers/sound/ac97_codec.c +++ b/drivers/sound/ac97_codec.c @@ -21,7 +21,7 @@ * * History * v0.4 Mar 15 2000 Ollie Lho - * dual codec support verified with 4 channel output + * dual codecs support verified with 4 channels output * v0.3 Feb 22 2000 Ollie Lho * bug fix for record mask setting * v0.2 Feb 10 2000 Ollie Lho @@ -332,9 +332,10 @@ static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask) /* else, write the first set in the mask as the output */ /* clear out current set value first (AC97 supports only 1 input!) */ - val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT)&0x07]); - if (mask != val) mask &= ~val; - + val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT) & 0x07]); + if (mask != val) + mask &= ~val; + val = ffs(mask); val = ac97_oss_rm[val-1]; val |= val << 8; /* set both channels */ @@ -423,7 +424,7 @@ static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned switch (_IOC_NR(cmd)) { case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ if (!codec->recmask_io) return -EINVAL; - if(!val) return 0; + if (!val) return 0; if (!(val &= codec->record_sources)) return -EINVAL; codec->recmask_io(codec, 0, val); @@ -449,6 +450,7 @@ int ac97_read_proc (char *page, char **start, off_t off, { int len = 0, cap, extid, val, id1, id2; struct ac97_codec *codec; + int is_ac97_20 = 0; if ((codec = data) == NULL) return -ENODEV; @@ -462,6 +464,7 @@ int ac97_read_proc (char *page, char **start, off_t off, extid &= ~((1<<2)|(1<<4)|(1<<5)|(1<<10)|(1<<11)|(1<<12)|(1<<13)); len += sprintf (page+len, "AC97 Version : %s\n", extid ? "2.0 or later" : "1.0"); + if (extid) is_ac97_20 = 1; cap = codec->codec_read(codec, AC97_RESET); len += sprintf (page+len, "Capabilities :%s%s%s%s%s%s\n", @@ -500,6 +503,7 @@ int ac97_read_proc (char *page, char **start, off_t off, val & 0x0100 ? "MIC2" : "MIC1", val & 0x0080 ? "on" : "off"); + extid = codec->codec_read(codec, AC97_EXTENDED_ID); cap = extid; len += sprintf (page+len, "Ext Capabilities :%s%s%s%s%s%s%s\n", cap & 0x0001 ? " -var rate PCM audio-" : "", @@ -509,10 +513,37 @@ int ac97_read_proc (char *page, char **start, off_t off, cap & 0x0080 ? " -PCM surround DAC-" : "", cap & 0x0100 ? " -PCM LFE DAC-" : "", cap & 0x0200 ? " -slot/DAC mappings-" : ""); + if (is_ac97_20) { + len += sprintf (page+len, "Front DAC rate : %d\n", + codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)); + } return len; } +/** + * ac97_probe_codec - Initialize and setup AC97-compatible codec + * @codec: (in/out) Kernel info for a single AC97 codec + * + * Reset the AC97 codec, then initialize the mixer and + * the rest of the @codec structure. + * + * The codec_read and codec_write fields of @codec are + * required to be setup and working when this function + * is called. All other fields are set by this function. + * + * codec_wait field of @codec can optionally be provided + * when calling this function. If codec_wait is not %NULL, + * this function will call codec_wait any time it is + * necessary to wait for the audio chip to reach the + * codec-ready state. If codec_wait is %NULL, then + * the default behavior is to call schedule_timeout. + * Currently codec_wait is used to wait for AC97 codec + * reset to complete. + * + * Returns 1 (true) on success, or 0 (false) on failure. + */ + int ac97_probe_codec(struct ac97_codec *codec) { u16 id1, id2; @@ -520,8 +551,19 @@ int ac97_probe_codec(struct ac97_codec *codec) int i; /* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should - be read zero. Probing of AC97 in this way is not reliable, it is not even SAFE !! */ + * be read zero. + * + * FIXME: is the following comment outdated? -jgarzik + * Probing of AC97 in this way is not reliable, it is not even SAFE !! + */ codec->codec_write(codec, AC97_RESET, 0L); + + /* also according to spec, we wait for codec-ready state */ + if (codec->codec_wait) + codec->codec_wait(codec); + else + schedule_timeout(5); + if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) { printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n", codec->id ? "Secondary" : "Primary"); @@ -546,8 +588,8 @@ int ac97_probe_codec(struct ac97_codec *codec) } if (codec->name == NULL) codec->name = "Unknown"; - printk(KERN_INFO "ac97_codec: AC97 %s codec, vendor id1: 0x%04x, " - "id2: 0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""), + printk(KERN_INFO "ac97_codec: AC97%s codec, id: 0x%04x:0x%04x (%s)\n", + audio ? " audio" : (modem ? " modem" : ""), id1, id2, codec->name); return ac97_init_mixer(codec); @@ -597,11 +639,6 @@ static int ac97_init_mixer(struct ac97_codec *codec) return 1; } -static int ac97_init_modem(struct ac97_codec *codec) -{ - return 0; -} - static int sigmatel_init(struct ac97_codec * codec) { codec->codec_write(codec, AC97_SURROUND_MASTER, 0L); diff --git a/drivers/sound/cmpci.c b/drivers/sound/cmpci.c index df05c9b64bde8a..527d570cfbe931 100644 --- a/drivers/sound/cmpci.c +++ b/drivers/sound/cmpci.c @@ -1161,7 +1161,6 @@ static int cm_open_mixdev(struct inode *inode, struct file *file) return -ENODEV; VALIDATE_STATE(s); file->private_data = s; - MOD_INC_USE_COUNT; return 0; } @@ -1170,7 +1169,6 @@ static int cm_release_mixdev(struct inode *inode, struct file *file) struct cm_state *s = (struct cm_state *)file->private_data; VALIDATE_STATE(s); - MOD_DEC_USE_COUNT; return 0; } @@ -1180,6 +1178,7 @@ static int cm_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int } static /*const*/ struct file_operations cm_mixer_fops = { + owner: THIS_MODULE, llseek: cm_llseek, ioctl: cm_ioctl_mixdev, open: cm_open_mixdev, @@ -1765,7 +1764,6 @@ static int cm_open(struct inode *inode, struct file *file) set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -1788,11 +1786,11 @@ static int cm_release(struct inode *inode, struct file *file) s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations cm_audio_fops = { + owner: THIS_MODULE, llseek: cm_llseek, read: cm_read, write: cm_write, @@ -2012,7 +2010,6 @@ static int cm_midi_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2062,11 +2059,11 @@ static int cm_midi_release(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations cm_midi_fops = { + owner: THIS_MODULE, llseek: cm_llseek, read: cm_midi_read, write: cm_midi_write, @@ -2207,7 +2204,6 @@ static int cm_dmfm_open(struct inode *inode, struct file *file) outb(1, s->iosynth+3); /* enable OPL3 */ s->open_mode |= FMODE_DMFM; up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2227,11 +2223,11 @@ static int cm_dmfm_release(struct inode *inode, struct file *file) } up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations cm_dmfm_fops = { + owner: THIS_MODULE, llseek: cm_llseek, ioctl: cm_dmfm_ioctl, open: cm_dmfm_open, @@ -2321,6 +2317,8 @@ int __init init_cmpci(void) (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)) || (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, pcidev)) || (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) { + if (pci_enable_device(pcidev)) + continue; if (pcidev->irq == 0) continue; if (!(s = kmalloc(sizeof(struct cm_state), GFP_KERNEL))) { @@ -2345,7 +2343,7 @@ int __init init_cmpci(void) init_MUTEX(&s->open_sem); spin_lock_init(&s->lock); s->magic = CM_MAGIC; - s->iobase = pcidev->resource[0].start; + s->iobase = pci_resource_start(pcidev, 0); s->iosynth = 0x388; s->iomidi = 0x330; spin_lock_init(&s->lock); diff --git a/drivers/sound/dmasound/dmasound_awacs.c b/drivers/sound/dmasound/dmasound_awacs.c index 3893f9b58dee41..f80ada7fd4a33e 100644 --- a/drivers/sound/dmasound/dmasound_awacs.c +++ b/drivers/sound/dmasound/dmasound_awacs.c @@ -1184,7 +1184,7 @@ static void awacs_nosound(unsigned long xx) } static struct timer_list beep_timer = { - NULL, NULL, 0, 0, awacs_nosound + function: awacs_nosound }; static void awacs_mksound(unsigned int hz, unsigned int ticks) @@ -1703,14 +1703,14 @@ static int awacs_mixer_ioctl(u_int cmd, u_long arg) case SOUND_MIXER_READ_RECLEV: data = awacs_get_volume(awacs_reg[0], 4); return IOCTL_OUT(arg, data); - case MIXER_WRITE(SOUND_MASK_MONITOR): + case MIXER_WRITE(SOUND_MIXER_MONITOR): IOCTL_IN(arg, data); awacs_reg[1] &= ~MASK_LOOPTHRU; if ((data & 0xff) >= 50) awacs_reg[1] |= MASK_LOOPTHRU; awacs_write(MASK_ADDR1 | awacs_reg[1]); /* fall through */ - case MIXER_READ(SOUND_MASK_MONITOR): + case MIXER_READ(SOUND_MIXER_MONITOR): data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0; return IOCTL_OUT(arg, data); } diff --git a/drivers/sound/dmasound/dmasound_core.c b/drivers/sound/dmasound/dmasound_core.c index 4aed3953e859af..da60c783b70b69 100644 --- a/drivers/sound/dmasound/dmasound_core.c +++ b/drivers/sound/dmasound/dmasound_core.c @@ -494,7 +494,6 @@ static struct { static int mixer_open(struct inode *inode, struct file *file) { - MOD_INC_USE_COUNT; dmasound.mach.open(); mixer.busy = 1; return 0; @@ -504,7 +503,6 @@ static int mixer_release(struct inode *inode, struct file *file) { mixer.busy = 0; dmasound.mach.release(); - MOD_DEC_USE_COUNT; return 0; } static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, @@ -533,6 +531,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd, static struct file_operations mixer_fops = { + owner: THIS_MODULE, llseek: sound_lseek, ioctl: mixer_ioctl, open: mixer_open, @@ -843,11 +842,9 @@ static int sq_open(struct inode *inode, struct file *file) { int rc; - MOD_INC_USE_COUNT; dmasound.mach.open(); if ((rc = write_sq_open(file)) || (rc = read_sq_open(file))) { dmasound.mach.release(); - MOD_DEC_USE_COUNT; return rc; } @@ -917,7 +914,6 @@ static int sq_release(struct inode *inode, struct file *file) write_sq_release_buffers(); read_sq_release_buffers(); dmasound.mach.release(); - MOD_DEC_USE_COUNT; /* There is probably a DOS atack here. They change the mode flag. */ /* XXX add check here */ @@ -1029,6 +1025,7 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, static struct file_operations sq_fops = { + owner: THIS_MODULE, llseek: sound_lseek, write: sq_write, ioctl: sq_ioctl, @@ -1088,7 +1085,6 @@ static int state_open(struct inode *inode, struct file *file) if (state.busy) return -EBUSY; - MOD_INC_USE_COUNT; dmasound.mach.open(); state.ptr = 0; state.busy = 1; @@ -1147,7 +1143,6 @@ static int state_release(struct inode *inode, struct file *file) { state.busy = 0; dmasound.mach.release(); - MOD_DEC_USE_COUNT; return 0; } @@ -1165,8 +1160,8 @@ static ssize_t state_read(struct file *file, char *buf, size_t count, return n; } -static struct file_operations state_fops = -{ +static struct file_operations state_fops = { + owner: THIS_MODULE, llseek: sound_lseek, read: state_read, open: state_open, diff --git a/drivers/sound/emu10k1/audio.c b/drivers/sound/emu10k1/audio.c index a682879844930c..06f84dfc3ee621 100644 --- a/drivers/sound/emu10k1/audio.c +++ b/drivers/sound/emu10k1/audio.c @@ -969,12 +969,9 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file) if (entry == &emu10k1_devs) return -ENODEV; - MOD_INC_USE_COUNT; - if ((wave_dev = (struct emu10k1_wavedevice *) kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL)) == NULL) { ERROR(); - MOD_DEC_USE_COUNT; return -EINVAL; } @@ -988,7 +985,6 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file) if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) { ERROR(); - MOD_DEC_USE_COUNT; return -ENODEV; } @@ -1055,7 +1051,6 @@ static int emu10k1_audio_open(struct inode *inode, struct file *file) if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) { ERROR(); - MOD_DEC_USE_COUNT; return -ENODEV; } @@ -1176,7 +1171,6 @@ static int emu10k1_audio_release(struct inode *inode, struct file *file) kfree(wave_dev); wake_up_interruptible(&card->open_wait); - MOD_DEC_USE_COUNT; return 0; } @@ -1430,6 +1424,7 @@ void emu10k1_waveout_bh(unsigned long refdata) } struct file_operations emu10k1_audio_fops = { + owner:THIS_MODULE, llseek:emu10k1_audio_llseek, read:emu10k1_audio_read, write:emu10k1_audio_write, diff --git a/drivers/sound/emu10k1/main.c b/drivers/sound/emu10k1/main.c index bce892fe33ce96..acb65d7e56de5a 100644 --- a/drivers/sound/emu10k1/main.c +++ b/drivers/sound/emu10k1/main.c @@ -622,7 +622,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev pci_set_master(pci_dev); - card->iobase = pci_dev->resource[0].start; + card->iobase = pci_resource_start(pci_dev, 0); if (request_region(card->iobase, EMU10K1_EXTENT, card_names[pci_id->driver_data]) == NULL) { printk(KERN_ERR "emu10k1: IO space in use\n"); diff --git a/drivers/sound/emu10k1/midi.c b/drivers/sound/emu10k1/midi.c index 497e4811311693..04b1424a8a15e2 100644 --- a/drivers/sound/emu10k1/midi.c +++ b/drivers/sound/emu10k1/midi.c @@ -98,14 +98,11 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file) if (entry == &emu10k1_devs) return -ENODEV; - MOD_INC_USE_COUNT; - /* Wait for device to become free */ down(&card->open_sem); while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { if (file->f_flags & O_NONBLOCK) { up(&card->open_sem); - MOD_DEC_USE_COUNT; return -EBUSY; } @@ -113,7 +110,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file) interruptible_sleep_on(&card->open_wait); if (signal_pending(current)) { - MOD_DEC_USE_COUNT; return -ERESTARTSYS; } @@ -121,7 +117,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file) } if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) { - MOD_DEC_USE_COUNT; return -EINVAL; } @@ -145,14 +140,12 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file) != CTSTATUS_SUCCESS) { ERROR(); kfree(midi_dev); - MOD_DEC_USE_COUNT; return -ENODEV; } /* Add two buffers to receive sysex buffer */ if (midiin_add_buffer(midi_dev, &midihdr1) != CTSTATUS_SUCCESS) { kfree(midi_dev); - MOD_DEC_USE_COUNT; return -ENODEV; } @@ -161,7 +154,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file) kfree(midihdr1->data); kfree(midihdr1); kfree(midi_dev); - MOD_DEC_USE_COUNT; return -ENODEV; } } @@ -175,7 +167,6 @@ static int emu10k1_midi_open(struct inode *inode, struct file *file) != CTSTATUS_SUCCESS) { ERROR(); kfree(midi_dev); - MOD_DEC_USE_COUNT; return -ENODEV; } } @@ -237,8 +228,6 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file) up(&card->open_sem); wake_up_interruptible(&card->open_wait); - MOD_DEC_USE_COUNT; - return 0; } @@ -438,6 +427,7 @@ int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned lon /* MIDI file operations */ struct file_operations emu10k1_midi_fops = { + owner:THIS_MODULE, read:emu10k1_midi_read, write:emu10k1_midi_write, poll:emu10k1_midi_poll, diff --git a/drivers/sound/emu10k1/mixer.c b/drivers/sound/emu10k1/mixer.c index fa54ca435f0a44..62796146f49b09 100644 --- a/drivers/sound/emu10k1/mixer.c +++ b/drivers/sound/emu10k1/mixer.c @@ -803,8 +803,6 @@ static int emu10k1_mixer_open(struct inode *inode, struct file *file) if (entry == &emu10k1_devs) return -ENODEV; - MOD_INC_USE_COUNT; - file->private_data = card; return 0; } @@ -812,11 +810,11 @@ static int emu10k1_mixer_open(struct inode *inode, struct file *file) static int emu10k1_mixer_release(struct inode *inode, struct file *file) { DPF(3, "emu10k1_mixer_release()\n"); - MOD_DEC_USE_COUNT; return 0; } struct file_operations emu10k1_mixer_fops = { + owner:THIS_MODULE, llseek:emu10k1_mixer_llseek, ioctl:emu10k1_mixer_ioctl, open:emu10k1_mixer_open, diff --git a/drivers/sound/es1370.c b/drivers/sound/es1370.c index ec3849a748b72b..47d1d875f5321d 100644 --- a/drivers/sound/es1370.c +++ b/drivers/sound/es1370.c @@ -1030,7 +1030,6 @@ static int es1370_open_mixdev(struct inode *inode, struct file *file) } VALIDATE_STATE(s); file->private_data = s; - MOD_INC_USE_COUNT; return 0; } @@ -1039,7 +1038,6 @@ static int es1370_release_mixdev(struct inode *inode, struct file *file) struct es1370_state *s = (struct es1370_state *)file->private_data; VALIDATE_STATE(s); - MOD_DEC_USE_COUNT; return 0; } @@ -1049,6 +1047,7 @@ static int es1370_ioctl_mixdev(struct inode *inode, struct file *file, unsigned } static /*const*/ struct file_operations es1370_mixer_fops = { + owner: THIS_MODULE, llseek: es1370_llseek, ioctl: es1370_ioctl_mixdev, open: es1370_open_mixdev, @@ -1710,7 +1709,6 @@ static int es1370_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -1734,11 +1732,11 @@ static int es1370_release(struct inode *inode, struct file *file) s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations es1370_audio_fops = { + owner: THIS_MODULE, llseek: es1370_llseek, read: es1370_read, write: es1370_write, @@ -1975,7 +1973,7 @@ static int es1370_ioctl_dac(struct inode *inode, struct file *file, unsigned int return 0; case SNDCTL_DSP_GETOSPACE: - if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac1(s)) != 0) + if (!(s->ctrl & CTRL_DAC1_EN) && (val = prog_dmabuf_dac1(s)) != 0) return val; spin_lock_irqsave(&s->lock, flags); es1370_update_ptr(s); @@ -2116,7 +2114,6 @@ static int es1370_open_dac(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= FMODE_DAC; up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2132,11 +2129,11 @@ static int es1370_release_dac(struct inode *inode, struct file *file) s->open_mode &= ~FMODE_DAC; wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations es1370_dac_fops = { + owner: THIS_MODULE, llseek: es1370_llseek, write: es1370_write_dac, poll: es1370_poll_dac, @@ -2357,7 +2354,6 @@ static int es1370_midi_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2403,11 +2399,11 @@ static int es1370_midi_release(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations es1370_midi_fops = { + owner: THIS_MODULE, llseek: es1370_llseek, read: es1370_midi_read, write: es1370_midi_write, diff --git a/drivers/sound/es1371.c b/drivers/sound/es1371.c index 44189f010c0b45..109ac71c022420 100644 --- a/drivers/sound/es1371.c +++ b/drivers/sound/es1371.c @@ -168,6 +168,7 @@ #define CT5880REV_CT5880_C 0x02 #define ES1371REV_ES1371_B 0x09 #define EV1938REV_EV1938_A 0x00 +#define ES1371REV_ES1373_8 0x08 #define ES1371_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371) @@ -1216,7 +1217,6 @@ static int es1371_open_mixdev(struct inode *inode, struct file *file) } VALIDATE_STATE(s); file->private_data = s; - MOD_INC_USE_COUNT; return 0; } @@ -1225,7 +1225,6 @@ static int es1371_release_mixdev(struct inode *inode, struct file *file) struct es1371_state *s = (struct es1371_state *)file->private_data; VALIDATE_STATE(s); - MOD_DEC_USE_COUNT; return 0; } @@ -1238,6 +1237,7 @@ static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned } static /*const*/ struct file_operations es1371_mixer_fops = { + owner: THIS_MODULE, llseek: es1371_llseek, ioctl: es1371_ioctl_mixdev, open: es1371_open_mixdev, @@ -1895,7 +1895,6 @@ static int es1371_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -1918,11 +1917,11 @@ static int es1371_release(struct inode *inode, struct file *file) s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations es1371_audio_fops = { + owner: THIS_MODULE, llseek: es1371_llseek, read: es1371_read, write: es1371_write, @@ -2150,7 +2149,7 @@ static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int return 0; case SNDCTL_DSP_GETOSPACE: - if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac1(s)) != 0) + if (!(s->ctrl & CTRL_DAC1_EN) && (val = prog_dmabuf_dac1(s)) != 0) return val; spin_lock_irqsave(&s->lock, flags); es1371_update_ptr(s); @@ -2290,7 +2289,6 @@ static int es1371_open_dac(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= FMODE_DAC; up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2306,11 +2304,11 @@ static int es1371_release_dac(struct inode *inode, struct file *file) s->open_mode &= ~FMODE_DAC; up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations es1371_dac_fops = { + owner: THIS_MODULE, llseek: es1371_llseek, write: es1371_write_dac, poll: es1371_poll_dac, @@ -2531,7 +2529,6 @@ static int es1371_midi_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2576,11 +2573,11 @@ static int es1371_midi_release(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations es1371_midi_fops = { + owner: THIS_MODULE, llseek: es1371_llseek, read: es1371_midi_read, write: es1371_midi_write, @@ -2778,7 +2775,8 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic /* if we are a 5880 turn on the AC97 */ if (s->vendor == PCI_VENDOR_ID_ENSONIQ && ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev == CT5880REV_CT5880_C) || - (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A))) { + (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) || + (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) { cssr |= CSTAT_5880_AC97_RST; outl(cssr, s->io+ES1371_REG_STATUS); /* need to delay around 20ms(bleech) to give diff --git a/drivers/sound/esssolo1.c b/drivers/sound/esssolo1.c index 2d7e15f5132bf9..930e58f463fa4a 100644 --- a/drivers/sound/esssolo1.c +++ b/drivers/sound/esssolo1.c @@ -909,7 +909,6 @@ static int solo1_open_mixdev(struct inode *inode, struct file *file) } VALIDATE_STATE(s); file->private_data = s; - MOD_INC_USE_COUNT; return 0; } @@ -918,7 +917,6 @@ static int solo1_release_mixdev(struct inode *inode, struct file *file) struct solo1_state *s = (struct solo1_state *)file->private_data; VALIDATE_STATE(s); - MOD_DEC_USE_COUNT; return 0; } @@ -928,6 +926,7 @@ static int solo1_ioctl_mixdev(struct inode *inode, struct file *file, unsigned i } static /*const*/ struct file_operations solo1_mixer_fops = { + owner: THIS_MODULE, llseek: solo1_llseek, ioctl: solo1_ioctl_mixdev, open: solo1_open_mixdev, @@ -1526,7 +1525,6 @@ static int solo1_release(struct inode *inode, struct file *file) s->open_mode &= ~(FMODE_READ | FMODE_WRITE); wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } @@ -1572,12 +1570,12 @@ static int solo1_open(struct inode *inode, struct file *file) s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0; s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; prog_codec(s); return 0; } static /*const*/ struct file_operations solo1_audio_fops = { + owner: THIS_MODULE, llseek: solo1_llseek, read: solo1_read, write: solo1_write, @@ -1869,7 +1867,6 @@ static int solo1_midi_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -1915,11 +1912,11 @@ static int solo1_midi_release(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations solo1_midi_fops = { + owner: THIS_MODULE, llseek: solo1_llseek, read: solo1_midi_read, write: solo1_midi_write, @@ -2075,7 +2072,6 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file) outb(1, s->sbbase+3); /* enable OPL3 */ s->open_mode |= FMODE_DMFM; up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2096,11 +2092,11 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file) release_region(s->sbbase, FMSYNTH_EXTENT); wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations solo1_dmfm_fops = { + owner: THIS_MODULE, llseek: solo1_llseek, ioctl: solo1_dmfm_ioctl, open: solo1_dmfm_open, diff --git a/drivers/sound/i810_audio.c b/drivers/sound/i810_audio.c index 76bfcc3c058098..1ac21c429ac50c 100644 --- a/drivers/sound/i810_audio.c +++ b/drivers/sound/i810_audio.c @@ -46,6 +46,18 @@ * There is no midi support, no synth support. Use timidity. To get * esd working you need to use esd -r 48000 as it won't probe 48KHz * by default. mpg123 can't handle 48Khz only audio so use xmms. + * + * Fix The Sound On Dell + * + * Not everyone uses 48KHz. We know of no way to detect this reliably + * and certainly not to get the right data. If your i810 audio sounds + * stupid you may need to investigate other speeds. According to Analog + * they tend to use a 14.318MHz clock which gives you a base rate of + * 41194Hz. + * + * This is available via the 'ftsodell=1' option. + * + * If you need to force a specific rate set the clocking= option */ #include <linux/module.h> @@ -74,10 +86,17 @@ #ifndef PCI_DEVICE_ID_INTEL_82901 #define PCI_DEVICE_ID_INTEL_82901 0x2425 #endif +#ifndef PCI_DEVICE_ID_INTEL_ICH2 +#define PCI_DEVICE_ID_INTEL_ICH2 0x2445 +#endif #ifndef PCI_DEVICE_ID_INTEL_440MX #define PCI_DEVICE_ID_INTEL_440MX 0x7195 #endif +static int ftsodell=0; +static int clocking=48000; + + #define ADC_RUNNING 1 #define DAC_RUNNING 2 @@ -180,13 +199,15 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 }; enum { ICH82801AA = 0, ICH82901AB, - INTEL440MX + INTEL440MX, + INTELICH2, }; static char * card_names[] = { "Intel ICH 82801AA", "Intel ICH 82901AB", - "Intel 440MX" + "Intel 440MX", + "Intel ICH2" }; static struct pci_device_id i810_pci_tbl [] __initdata = { @@ -196,6 +217,8 @@ static struct pci_device_id i810_pci_tbl [] __initdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82901AB}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_440MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTEL440MX}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH2}, {0,} }; @@ -295,7 +318,6 @@ struct i810_card { static struct i810_card *devs = NULL; static int i810_open_mixdev(struct inode *inode, struct file *file); -static int i810_release_mixdev(struct inode *inode, struct file *file); static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static loff_t i810_llseek(struct file *file, loff_t offset, int origin); @@ -363,12 +385,27 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra struct ac97_codec *codec=state->card->ac97_codec[0]; if(!(state->card->ac97_features&0x0001)) - return 48000; + { + dmabuf->rate = clocking; + return clocking; + } if (rate > 48000) rate = 48000; - if (rate < 4000) - rate = 4000; + if (rate < 8000) + rate = 8000; + + /* + * Adjust for misclocked crap + */ + + rate = ( rate * clocking)/48000; + + /* Analog codecs can go lower via magic registers but others + might not */ + + if(rate < 8000) + rate = 8000; /* Power down the DAC */ dacp=i810_ac97_get(codec, AC97_POWER_CONTROL); @@ -378,10 +415,10 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate); rp=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE); - printk("DAC rate set to %d Returned %d\n", - rate, (int)rp); +// printk("DAC rate set to %d Returned %d\n", +// rate, (int)rp); - rate=rp; + rate=(rp * 48000) / clocking; /* Power it back up */ i810_ac97_set(codec, AC97_POWER_CONTROL, dacp); @@ -402,25 +439,41 @@ static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int ra struct ac97_codec *codec=state->card->ac97_codec[0]; if(!(state->card->ac97_features&0x0001)) - return 48000; + { + dmabuf->rate = clocking; + return clocking; + } if (rate > 48000) rate = 48000; - if (rate < 4000) - rate = 4000; + if (rate < 8000) + rate = 8000; + + /* + * Adjust for misclocked crap + */ + + rate = ( rate * clocking)/48000; + + /* Analog codecs can go lower via magic registers but others + might not */ + + if(rate < 8000) + rate = 8000; + /* Power down the ADC */ dacp=i810_ac97_get(codec, AC97_POWER_CONTROL); i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100); /* Load the rate and read the effective rate */ - i810_ac97_set(codec, AC97_PCM_LR_ADC_RATE, rate); - rp=i810_ac97_get(codec, AC97_PCM_LR_ADC_RATE); + i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate); + rp=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE); - printk("ADC rate set to %d Returned %d\n", - rate, (int)rp); +// printk("ADC rate set to %d Returned %d\n", +// rate, (int)rp); - rate=rp; + rate = (rp * 48000) / clocking; /* Power it back up */ i810_ac97_set(codec, AC97_POWER_CONTROL, dacp); @@ -1547,7 +1600,6 @@ static int i810_open(struct inode *inode, struct file *file) state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); up(&state->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -1582,11 +1634,11 @@ static int i810_release(struct inode *inode, struct file *file) /* we're covered by the open_sem */ up(&state->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations i810_audio_fops = { + owner: THIS_MODULE, llseek: i810_llseek, read: i810_read, write: i810_write, @@ -1640,13 +1692,6 @@ static int i810_open_mixdev(struct inode *inode, struct file *file) match: file->private_data = card->ac97_codec[i]; - MOD_INC_USE_COUNT; - return 0; -} - -static int i810_release_mixdev(struct inode *inode, struct file *file) -{ - MOD_DEC_USE_COUNT; return 0; } @@ -1659,10 +1704,10 @@ static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned in } static /*const*/ struct file_operations i810_mixer_fops = { + owner: THIS_MODULE, llseek: i810_llseek, ioctl: i810_ioctl_mixdev, open: i810_open_mixdev, - release: i810_release_mixdev, }; /* AC97 codec initialisation. */ @@ -1828,8 +1873,11 @@ static void __exit i810_remove(struct pci_dev *pci_dev) kfree(card); } + MODULE_AUTHOR(""); MODULE_DESCRIPTION("Intel 810 audio support"); +MODULE_PARM(ftsodell, "i"); +MODULE_PARM(clocking, "i"); #define I810_MODULE_NAME "intel810_audio" @@ -1845,6 +1893,9 @@ static int __init i810_init_module (void) if (!pci_present()) /* No PCI bus in this machine! */ return -ENODEV; + if(ftsodell==1) + clocking=41194; + printk(KERN_INFO "Intel 810 + AC97 Audio, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n"); diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c index 81a7d21d25f762..cd5a2bc2719e57 100644 --- a/drivers/sound/maestro.c +++ b/drivers/sound/maestro.c @@ -236,6 +236,7 @@ #include <linux/reboot.h> #include <asm/uaccess.h> #include <asm/hardirq.h> +#include <linux/bitops.h> #include <linux/pm.h> static int maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d); @@ -2081,7 +2082,6 @@ static int ess_open_mixdev(struct inode *inode, struct file *file) return -ENODEV; file->private_data = card; - MOD_INC_USE_COUNT; return 0; } @@ -2091,7 +2091,6 @@ static int ess_release_mixdev(struct inode *inode, struct file *file) VALIDATE_CARD(card); - MOD_DEC_USE_COUNT; return 0; } @@ -2105,6 +2104,7 @@ static int ess_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int } static /*const*/ struct file_operations ess_mixer_fops = { + owner: THIS_MODULE, llseek: ess_llseek, ioctl: ess_ioctl_mixdev, open: ess_open_mixdev, @@ -2976,7 +2976,6 @@ ess_open(struct inode *inode, struct file *file) s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -3007,11 +3006,11 @@ ess_release(struct inode *inode, struct file *file) } up(&s->open_sem); wake_up(&s->open_wait); - MOD_DEC_USE_COUNT; return 0; } static struct file_operations ess_audio_fops = { + owner: THIS_MODULE, llseek: ess_llseek, read: ess_read, write: ess_write, @@ -3447,11 +3446,7 @@ maestro_install(struct pci_dev *pcidev, int card_type) return 1; } -#ifdef MODULE -int init_module(void) -#else -int SILLY_MAKE_INIT(init_maestro(void)) -#endif +int __init init_maestro(void) { struct pci_dev *pcidev = NULL; int foundone = 0; @@ -3558,8 +3553,6 @@ void cleanup_module(void) { nuke_maestros(); } -#else /* MODULE */ -__initcall(init_maestro); #endif /* --------------------------------------------------------------------- */ @@ -3718,3 +3711,5 @@ maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) out: return 0; } + +module_init(init_maestro); diff --git a/drivers/sound/sonicvibes.c b/drivers/sound/sonicvibes.c index 7a8a7117b4730e..0d50924d8e2f2e 100644 --- a/drivers/sound/sonicvibes.c +++ b/drivers/sound/sonicvibes.c @@ -1240,7 +1240,6 @@ static int sv_open_mixdev(struct inode *inode, struct file *file) } VALIDATE_STATE(s); file->private_data = s; - MOD_INC_USE_COUNT; return 0; } @@ -1249,7 +1248,6 @@ static int sv_release_mixdev(struct inode *inode, struct file *file) struct sv_state *s = (struct sv_state *)file->private_data; VALIDATE_STATE(s); - MOD_DEC_USE_COUNT; return 0; } @@ -1259,6 +1257,7 @@ static int sv_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int } static /*const*/ struct file_operations sv_mixer_fops = { + owner: THIS_MODULE, llseek: sv_llseek, ioctl: sv_ioctl_mixdev, open: sv_open_mixdev, @@ -1900,7 +1899,6 @@ static int sv_open(struct inode *inode, struct file *file) set_fmt(s, fmtm, fmts); s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -1923,11 +1921,11 @@ static int sv_release(struct inode *inode, struct file *file) s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations sv_audio_fops = { + owner: THIS_MODULE, llseek: sv_llseek, read: sv_read, write: sv_write, @@ -2157,7 +2155,6 @@ static int sv_midi_open(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2203,11 +2200,11 @@ static int sv_midi_release(struct inode *inode, struct file *file) spin_unlock_irqrestore(&s->lock, flags); wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations sv_midi_fops = { + owner: THIS_MODULE, llseek: sv_llseek, read: sv_midi_read, write: sv_midi_write, @@ -2357,7 +2354,6 @@ static int sv_dmfm_open(struct inode *inode, struct file *file) outb(1, s->iosynth+3); /* enable OPL3 */ s->open_mode |= FMODE_DMFM; up(&s->open_sem); - MOD_INC_USE_COUNT; return 0; } @@ -2377,11 +2373,11 @@ static int sv_dmfm_release(struct inode *inode, struct file *file) } wake_up(&s->open_wait); up(&s->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations sv_dmfm_fops = { + owner: THIS_MODULE, llseek: sv_llseek, ioctl: sv_dmfm_ioctl, open: sv_dmfm_open, diff --git a/drivers/sound/sound_core.c b/drivers/sound/sound_core.c index 053b43160f4ff4..da0cfe51c4c2f0 100644 --- a/drivers/sound/sound_core.c +++ b/drivers/sound/sound_core.c @@ -456,6 +456,7 @@ static int soundcore_open(struct inode *, struct file *); static struct file_operations soundcore_fops= { + owner: THIS_MODULE, open: soundcore_open, }; @@ -508,12 +509,25 @@ int soundcore_open(struct inode *inode, struct file *file) s = __look_for_unit(chain, unit); } if (s) { - file->f_op=s->unit_fops; + /* + * We rely upon the fact that we can't be unloaded while the + * subdriver is there, so if ->open() is successful we can + * safely drop the reference counter and if it is not we can + * revert to old ->f_op. Ugly, indeed, but that's the cost of + * switching ->f_op in the first place. + */ + int err = 0; + struct file_operations *old_fops = file->f_op; + file->f_op = fops_get(s->unit_fops); spin_unlock(&sound_loader_lock); if(file->f_op->open) - return file->f_op->open(inode,file); - else - return 0; + err = file->f_op->open(inode,file); + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } + fops_put(old_fops); + return err; } spin_unlock(&sound_loader_lock); return -ENODEV; diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c index 0bf2b8e0fa4975..5018ad1e774671 100644 --- a/drivers/sound/soundcard.c +++ b/drivers/sound/soundcard.c @@ -495,8 +495,8 @@ static int sound_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -struct file_operations oss_sound_fops = -{ +struct file_operations oss_sound_fops = { + owner: THIS_MODULE, llseek: sound_lseek, read: sound_read, write: sound_write, diff --git a/drivers/sound/trident.c b/drivers/sound/trident.c index 6a3b8b4d6c1de3..2eb45827448822 100644 --- a/drivers/sound/trident.c +++ b/drivers/sound/trident.c @@ -1,6 +1,6 @@ /* * - * Trident 4D-Wave/SiS 7018 OSS driver for Linux 2.2.x + * Trident 4D-Wave/SiS 7018/ALi 5451 OSS driver for Linux 2.2.x * * Driver: Alan Cox <alan@redhat.com> * @@ -12,6 +12,7 @@ * Hacked up by: * Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support + * Ching Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support * * * This program is free software; you can redistribute it and/or modify @@ -29,10 +30,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * History - * v0.14.3 May 20 2000 Aaron Holtzman - * Fix kfree'd memory access in release - * Fix race in open while looking for a free virtual channel slot - * remove open_wait wq (which appears to be unused) + * v0.14.5 May 23 2000 Ollie Lho + * Misc bug fix from the Net + * v0.14.4 May 20 2000 Aaron Holtzman + * Fix kfree'd memory access in release + * Fix race in open while looking for a free virtual channel slot + * remove open_wait wq (which appears to be unused) + * v0.14.3 May 10 2000 Ollie Lho + * fixed a small bug in trident_update_ptr, xmms 1.0.1 no longer uses 100% CPU * v0.14.2 Mar 29 2000 Ching Ling Lee * Add clear to silence advance in trident_update_ptr * fix invalid data of the end of the sound @@ -109,13 +114,13 @@ #include "trident.h" -#define DRIVER_VERSION "0.14" +#define DRIVER_VERSION "0.14.5" /* magic numbers to protect our data structures */ #define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */ #define TRIDENT_STATE_MAGIC 0x63657373 /* "cess" */ -#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */ +#define TRIDENT_DMA_MASK 0x3fffffff /* DMA buffer mask for pci_alloc_consist */ #define NR_HW_CH 32 @@ -151,7 +156,7 @@ static char * card_names[] = { "ALi Audio Accelerator" }; -static struct pci_device_id trident_pci_tbl [] __initdata = { +static struct pci_device_id trident_pci_tbl [] __devinitdata = { {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX}, {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX, @@ -314,7 +319,6 @@ static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val); static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg); static int trident_open_mixdev(struct inode *inode, struct file *file); -static int trident_release_mixdev(struct inode *inode, struct file *file); static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static loff_t trident_llseek(struct file *file, loff_t offset, int origin); @@ -438,16 +442,14 @@ static void trident_stop_voice(struct trident_card * card, unsigned int channel) #endif } -static u32 trident_get_interrupt_mask (struct trident_card * card, - unsigned int b) +static u32 trident_get_interrupt_mask (struct trident_card * card, unsigned int channel) { - struct trident_pcm_bank *bank = &card->banks[b]; + struct trident_pcm_bank *bank = &card->banks[channel]; u32 addr = bank->addresses->aint; return inl(TRID_REG(card, addr)); } -static int trident_check_channel_interrupt(struct trident_card * card, - unsigned int channel) +static int trident_check_channel_interrupt(struct trident_card * card, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); u32 reg = trident_get_interrupt_mask (card, channel >> 5); @@ -460,8 +462,7 @@ static int trident_check_channel_interrupt(struct trident_card * card, return (reg & mask) ? TRUE : FALSE; } -static void trident_ack_channel_interrupt(struct trident_card * card, - unsigned int channel) +static void trident_ack_channel_interrupt(struct trident_card * card, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); struct trident_pcm_bank *bank = &card->banks[channel >> 5]; @@ -537,8 +538,7 @@ static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *ca } -static void trident_free_pcm_channel(struct trident_card *card, - unsigned int channel) +static void trident_free_pcm_channel(struct trident_card *card, int channel) { int bank; @@ -551,7 +551,7 @@ static void trident_free_pcm_channel(struct trident_card *card, card->banks[bank].bitmap &= ~(1 << (channel)); } -static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel) +static void ali_free_pcm_channel(struct trident_card *card, int channel) { int bank; @@ -574,18 +574,16 @@ static int trident_load_channel_registers(struct trident_card *card, u32 *data, if (channel > 63) return FALSE; - /* select hardware channel to write */ + /* select hardware channel to write */ outb(channel, TRID_REG(card, T4D_LFO_GC_CIR)); /* Output the channel registers, but don't write register three to an ALI chip. */ - for (i = 0; i < CHANNEL_REGS; i++) { if (i == 3 && card->pci_id == PCI_DEVICE_ID_ALI_5451) continue; outl(data[i], TRID_REG(card, CHANNEL_START + 4*i)); } - return TRUE; } @@ -1141,7 +1139,7 @@ static void trident_update_ptr(struct trident_state *state) dmabuf->hwptr = hwptr; dmabuf->total_bytes += diff; - /* error handling and process wake up for DAC */ + /* error handling and process wake up for ADC */ if (dmabuf->enable == ADC_RUNNING) { if (dmabuf->mapped) { dmabuf->count -= diff; @@ -1171,7 +1169,10 @@ static void trident_update_ptr(struct trident_state *state) //there is invalid data in the end of half buffer if ((clear_cnt = half_dmasize - swptr) < 0) clear_cnt += half_dmasize; - memset (dmabuf->rawbuf + swptr, silence, clear_cnt); //clear the invalid data + //clear the invalid data + memset (dmabuf->rawbuf + swptr, + silence, clear_cnt); + dmabuf->endcleared = 1; } } else if (dmabuf->count < (signed) dmabuf->fragsize) { @@ -1181,12 +1182,15 @@ static void trident_update_ptr(struct trident_state *state) memset (dmabuf->rawbuf + swptr, silence, clear_cnt); dmabuf->endcleared = 1; } - } - /* since dma machine only interrupts at ESO and ESO/2, we sure have at - least half of dma buffer free, so wake up the process unconditionally */ - wake_up(&dmabuf->wait); + } + /* trident_update_ptr is called by interrupt handler or by process via + ioctl/poll, we only wake up the waiting process when we have more + than 1/2 buffer of data to process (always true for interrupt handler) */ + if (dmabuf->count > (signed)dmabuf->dmasize/2) + wake_up(&dmabuf->wait); } } + /* error handling and process wake up for DAC */ if (dmabuf->enable == DAC_RUNNING) { if (dmabuf->mapped) { @@ -1203,9 +1207,11 @@ static void trident_update_ptr(struct trident_state *state) __stop_dac(state); dmabuf->error++; } - /* since dma machine only interrupts at ESO and ESO/2, we sure have at - least half of dma buffer free, so wake up the process unconditionally */ - wake_up(&dmabuf->wait); + /* trident_update_ptr is called by interrupt handler or by process via + ioctl/poll, we only wake up the waiting process when we have more + than 1/2 buffer free (always true for interrupt handler) */ + if (dmabuf->count < (signed)dmabuf->dmasize/2) + wake_up(&dmabuf->wait); } } dmabuf->update_flag &= ~ALI_ADDRESS_INT_UPDATE; @@ -1336,7 +1342,8 @@ static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_ ret = 0; if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) - outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) | ALI_PCM_IN_ENABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL)); + outl(inl(TRID_REG (state->card, ALI_GLOBAL_CONTROL)) | ALI_PCM_IN_ENABLE, + TRID_REG (state->card, ALI_GLOBAL_CONTROL)); while (count > 0) { spin_lock_irqsave(&state->card->lock, flags); @@ -1439,7 +1446,8 @@ static ssize_t trident_write(struct file *file, const char *buffer, size_t count if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) if (dmabuf->channel->num == ALI_PCM_IN_CHANNEL) - outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) & ALI_PCM_IN_DISABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL)); + outl ( inl (TRID_REG (state->card, ALI_GLOBAL_CONTROL)) & + ALI_PCM_IN_DISABLE, TRID_REG (state->card, ALI_GLOBAL_CONTROL)); while (count > 0) { spin_lock_irqsave(&state->card->lock, flags); @@ -1912,8 +1920,9 @@ static int trident_open(struct inode *inode, struct file *file) if (card->states[i] == NULL) { state = card->states[i] = (struct trident_state *) kmalloc(sizeof(struct trident_state), GFP_KERNEL); - if (state == NULL) + if (state == NULL) { return -ENOMEM; + } memset(state, 0, sizeof(struct trident_state)); dmabuf = &state->dmabuf; goto found_virt; @@ -1923,9 +1932,9 @@ static int trident_open(struct inode *inode, struct file *file) card = card->next; } /* no more virtual channel avaiable */ - if (!state) + if (!state) { return -ENODEV; - + } found_virt: /* found a free virtual channel, allocate hardware channels */ if(file->f_mode & FMODE_READ) @@ -1946,7 +1955,6 @@ static int trident_open(struct inode *inode, struct file *file) init_waitqueue_head(&dmabuf->wait); file->private_data = state; - /* set default sample format. According to OSS Programmer's Guide /dev/dsp should be default to unsigned 8-bits, mono, with sample rate 8kHz and /dev/dspW will accept 16-bits sample */ @@ -1991,11 +1999,10 @@ static int trident_open(struct inode *inode, struct file *file) up(&card->open_sem); #ifdef DEBUG - printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n", - state->virt, - dmabuf->channel->num); + printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n", + state->virt, dmabuf->channel->num); #endif - MOD_INC_USE_COUNT; + return 0; } @@ -2020,7 +2027,6 @@ static int trident_release(struct inode *inode, struct file *file) dealloc_dmabuf(state); state->card->free_pcm_channel(state->card, dmabuf->channel->num); } - if (file->f_mode & FMODE_READ) { stop_adc(state); dealloc_dmabuf(state); @@ -2033,11 +2039,11 @@ static int trident_release(struct inode *inode, struct file *file) /* we're covered by the open_sem */ up(&card->open_sem); - MOD_DEC_USE_COUNT; return 0; } static /*const*/ struct file_operations trident_audio_fops = { + owner: THIS_MODULE, llseek: trident_llseek, read: trident_read, write: trident_write, @@ -2261,19 +2267,13 @@ static int trident_open_mixdev(struct inode *inode, struct file *file) card->ac97_codec[i]->dev_mixer == minor) goto match; - if (!card) + if (!card) { return -ENODEV; - + } match: file->private_data = card->ac97_codec[i]; - MOD_INC_USE_COUNT; - return 0; -} -static int trident_release_mixdev(struct inode *inode, struct file *file) -{ - MOD_DEC_USE_COUNT; return 0; } @@ -2286,10 +2286,10 @@ static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned } static /*const*/ struct file_operations trident_mixer_fops = { + owner: THIS_MODULE, llseek: trident_llseek, ioctl: trident_ioctl_mixdev, open: trident_open_mixdev, - release: trident_release_mixdev, }; /* AC97 codec initialisation. */ @@ -2385,7 +2385,7 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device } pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision); - iobase = pci_resource_start (pci_dev, 0); + iobase = pci_resource_start(pci_dev, 0); if (check_region(iobase, 256)) { printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n", iobase); @@ -2393,7 +2393,7 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device } if (pci_enable_device(pci_dev)) - return -ENODEV; + return -ENODEV; if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) { printk(KERN_ERR "trident: out of memory\n"); @@ -2421,20 +2421,19 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device printk(KERN_INFO "trident: %s found at IO 0x%04lx, IRQ %d\n", card_names[pci_id->driver_data], card->iobase, card->irq); - if(card->pci_id == PCI_DEVICE_ID_ALI_5451) - { + if(card->pci_id == PCI_DEVICE_ID_ALI_5451) { card->alloc_pcm_channel = ali_alloc_pcm_channel; card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel; card->free_pcm_channel = ali_free_pcm_channel; card->address_interrupt = ali_address_interrupt; } - else - { + else { card->alloc_pcm_channel = trident_alloc_pcm_channel; card->alloc_rec_pcm_channel = trident_alloc_pcm_channel; card->free_pcm_channel = trident_free_pcm_channel; card->address_interrupt = trident_address_interrupt; } + /* claim our iospace and irq */ request_region(card->iobase, 256, card_names[pci_id->driver_data]); if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ, @@ -2462,12 +2461,12 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device } outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL)); - if (card->pci_id == PCI_DEVICE_ID_ALI_5451) - { + if (card->pci_id == PCI_DEVICE_ID_ALI_5451) { /* edited by HMSEO for GT sound */ #ifdef CONFIG_ALPHA_NAUTILUS - ac97_data = trident_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL); - trident_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, ac97_data | ALI_EAPD_POWER_DOWN); + u16 ac97_data = trident_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL); + trident_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, + ac97_data | ALI_EAPD_POWER_DOWN); #endif /* edited by HMSEO for GT sound*/ } diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c index e4403d9664ab73..ab14427d637533 100644 --- a/drivers/sound/via82cxxx_audio.c +++ b/drivers/sound/via82cxxx_audio.c @@ -6,12 +6,16 @@ * See the "COPYING" file distributed with this software for more info. * * For a list of known bugs (errata) and documentation, - * see via82cxxx.txt in linux/Documentation/sound. + * see via-audio.pdf in linux/Documentation/DocBook. + * If this documentation does not exist, run "make pdfdocs". + * If "make pdfdocs" fails, obtain the documentation from + * the driver's Website at + * http://gtf.org/garzik/drivers/via82cxxx/ * */ -#define VIA_VERSION "1.1.6" +#define VIA_VERSION "1.1.8" #include <linux/config.h> @@ -304,7 +308,7 @@ static void via_chan_pcm_fmt (struct via_info *card, static struct pci_device_id via_pci_tbl[] __initdata = { - { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, }, { 0, } }; MODULE_DEVICE_TABLE(pci,via_pci_tbl); @@ -325,12 +329,40 @@ static struct pci_driver via_driver = { * */ +/** + * via_chan_stop - Terminate DMA on specified PCM channel + * @iobase: PCI base address for SGD channel registers + * + * Terminate scatter-gather DMA operation for given + * channel (derived from @iobase), if DMA is active. + * + * Note that @iobase is not the PCI base address, + * but the PCI base address plus an offset to + * one of three PCM channels supported by the chip. + * + */ + static inline void via_chan_stop (int iobase) { if (inb (iobase + VIA_PCM_STATUS) & VIA_SGD_ACTIVE) outb (VIA_SGD_TERMINATE, iobase + VIA_PCM_CONTROL); } + +/** + * via_chan_status_clear - Clear status flags on specified DMA channel + * @iobase: PCI base address for SGD channel registers + * + * Clear any pending status flags for the given + * DMA channel (derived from @iobase), if any + * flags are asserted. + * + * Note that @iobase is not the PCI base address, + * but the PCI base address plus an offset to + * one of three PCM channels supported by the chip. + * + */ + static inline void via_chan_status_clear (int iobase) { u8 tmp = inb (iobase + VIA_PCM_STATUS); @@ -339,12 +371,33 @@ static inline void via_chan_status_clear (int iobase) outb (tmp, iobase + VIA_PCM_STATUS); } + +/** + * sg_begin - Begin recording or playback on a PCM channel + * @chan: Channel for which DMA operation shall begin + * + * Start scatter-gather DMA for the given channel. + * + */ + static inline void sg_begin (struct via_channel *chan) { outb (VIA_SGD_START, chan->iobase + VIA_PCM_CONTROL); } +/** + * via_chan_bufs_in_use - Number of buffers waiting to be consumed + * @chan: Channel for which DMA buffers will be counted + * + * Count the number of buffers waiting to be consumed. For a + * playback operation, this is the number of buffers which have + * yet to be sent to the DAC. For a recording operation, this + * is the number of buffers waiting to be consumed by software + * calling read() system call. + * + */ + static inline int via_chan_bufs_in_use (struct via_channel *chan) { return atomic_read(&chan->next_buf) - @@ -352,12 +405,31 @@ static inline int via_chan_bufs_in_use (struct via_channel *chan) } +/** + * via_chan_full - Check for no-free-buffers condition + * @chan: Channel for which DMA full condition will be checked + * + * Count the number of buffers waiting to be consumed, and return + * true (non-zero) if no buffers are available to be filled on the + * given DMA channel. + * + */ + static inline int via_chan_full (struct via_channel *chan) { return (via_chan_bufs_in_use (chan) == VIA_DMA_BUFFERS); } +/** + * via_chan_empty - Check for no-buffers-in-use condition + * @chan: Channel for which DMA empty condition will be checked + * + * Count the number of buffers waiting to be consumed, and return + * true (non-zero) if no buffers are currently in use. + * + */ + static inline int via_chan_empty (struct via_channel *chan) { return (atomic_read(&chan->next_buf) == @@ -372,6 +444,15 @@ static inline int via_chan_empty (struct via_channel *chan) * */ + +/** + * via_stop_everything - Stop all audio operations + * @card: Private info for specified board + * + * Stops all DMA operations and interrupts, and clear + * any pending status bits resulting from those operations. + */ + static void via_stop_everything (struct via_info *card) { DPRINTK ("ENTER\n"); @@ -402,6 +483,24 @@ static void via_stop_everything (struct via_info *card) } +/** + * via_set_rate - Set PCM rate for given channel + * @card: Private info for specified board + * @rate: Desired PCM sample rate, in Khz + * @inhale_deeply: Boolean. If non-zero (true), the recording sample rate + * is set. If zero (false), the playback sample rate + * is set. + * + * Sets the PCM sample rate for a channel. + * + * Values for @rate are clamped to a range of 4000 Khz through 48000 Khz, + * due to hardware constraints. + * + * FIXME: @inhale_deeply argument is ignored, and %AC97_PCM_FRONT_DAC_RATE + * is the only rate which is really set. This needs to be fixed when + * recording support is added. + */ + static int via_set_rate (struct via_info *card, unsigned rate, int inhale_deeply) { @@ -423,12 +522,32 @@ static int via_set_rate (struct via_info *card, unsigned rate, int inhale_deeply } +/** + * via_set_adc_rate - Set PCM rate for recording channel + * @card: Private info for specified board + * @rate: Desired PCM sample rate, in Khz + * + * Sets the PCM sample rate for a recording channel. + * + * FIXME: @inhale_deeply argument to via_set_rate is ignored, and %AC97_PCM_FRONT_DAC_RATE + * is the only rate which is really set. Thus, this function will + * not work until via_set_rate is fixed. + */ + static inline int via_set_adc_rate (struct via_info *card, int rate) { return via_set_rate (card, rate, 1); } +/** + * via_set_dac_rate - Set PCM rate for playback channel + * @card: Private info for specified board + * @rate: Desired PCM sample rate, in Khz + * + * Sets the PCM sample rate for a playback channel. + */ + static inline int via_set_dac_rate (struct via_info *card, int rate) { return via_set_rate (card, rate, 0); @@ -442,6 +561,27 @@ static inline int via_set_dac_rate (struct via_info *card, int rate) * */ +/** + * via_chan_init - Initialize PCM channel + * @card: Private audio chip info + * @chan: Channel to be initialized + * @chan_ofs: Offset from PCI address, which determines the + * set of SGD registers to use. + * + * Performs all the preparations necessary to begin + * using a PCM channel. + * + * Currently the preparations include allocating the + * scatter-gather DMA table and buffers, setting the + * PCM channel to a known state, and passing the + * address of the DMA table to the hardware. + * + * Note that special care is taken when passing the + * DMA table address to hardware, because it was found + * during driver development that the hardware did not + * always "take" the address. + */ + static int via_chan_init (struct via_info *card, struct via_channel *chan, long chan_ofs) { @@ -533,6 +673,20 @@ err_out_nomem: } +/** + * via_chan_free - Release a PCM channel + * @card: Private audio chip info + * @chan: Channel to be released + * + * Performs all the functions necessary to clean up + * an initialized channel. + * + * Currently these functions include disabled any + * active DMA operations, setting the PCM channel + * back to a known state, and releasing any allocated + * sound buffers. + */ + static void via_chan_free (struct via_info *card, struct via_channel *chan) { int i; @@ -575,6 +729,22 @@ static void via_chan_free (struct via_info *card, struct via_channel *chan) } +/** + * via_chan_pcm_fmt - Update PCM channel settings + * @card: Private audio chip info + * @chan: Channel to be updated + * @reset: Boolean. If non-zero, channel will be reset + * to 8-bit mono mode. + * + * Stores the settings of the current PCM format, + * 8-bit or 16-bit, and mono/stereo, into the + * hardware settings for the specified channel. + * If @reset is non-zero, the channel is reset + * to 8-bit mono mode. Otherwise, the channel + * is set to the values stored in the channel + * information struct @chan. + */ + static void via_chan_pcm_fmt (struct via_info *card, struct via_channel *chan, int reset) { @@ -603,6 +773,14 @@ static void via_chan_pcm_fmt (struct via_info *card, } +/** + * via_chan_clear - Stop DMA channel operation, and reset pointers + * @chan: Channel to be cleared + * + * Call via_chan_stop to halt DMA operations, and then resets + * all software pointers which track DMA operation. + */ + static void via_chan_clear (struct via_channel *chan) { via_chan_stop (chan->iobase); @@ -612,6 +790,21 @@ static void via_chan_clear (struct via_channel *chan) } +/** + * via_chan_set_speed - Set PCM sample rate for given channel + * @card: Private info for specified board + * @chan: Channel whose sample rate will be adjusted + * @val: New sample rate, in Khz + * + * Helper function for the %SNDCTL_DSP_SPEED ioctl. OSS semantics + * demand that all audio operations halt (if they are not already + * halted) when the %SNDCTL_DSP_SPEED is given. + * + * This function halts all audio operations for the given channel + * @chan, and then calls via_set_rate to set the audio hardware + * to the new rate. + */ + static int via_chan_set_speed (struct via_info *card, struct via_channel *chan, int val) { @@ -626,6 +819,21 @@ static int via_chan_set_speed (struct via_info *card, } +/** + * via_chan_set_fmt - Set PCM sample size for given channel + * @card: Private info for specified board + * @chan: Channel whose sample size will be adjusted + * @val: New sample size, use the %AFMT_xxx constants + * + * Helper function for the %SNDCTL_DSP_SETFMT ioctl. OSS semantics + * demand that all audio operations halt (if they are not already + * halted) when the %SNDCTL_DSP_SETFMT is given. + * + * This function halts all audio operations for the given channel + * @chan, and then calls via_chan_pcm_fmt to set the audio hardware + * to the new sample size, either 8-bit or 16-bit. + */ + static int via_chan_set_fmt (struct via_info *card, struct via_channel *chan, int val) { @@ -656,6 +864,21 @@ static int via_chan_set_fmt (struct via_info *card, } +/** + * via_chan_set_stereo - Enable or disable stereo for a DMA channel + * @card: Private info for specified board + * @chan: Channel whose stereo setting will be adjusted + * @val: New sample size, use the %AFMT_xxx constants + * + * Helper function for the %SNDCTL_DSP_CHANNELS and %SNDCTL_DSP_STEREO ioctls. OSS semantics + * demand that all audio operations halt (if they are not already + * halted) when %SNDCTL_DSP_CHANNELS or SNDCTL_DSP_STEREO is given. + * + * This function halts all audio operations for the given channel + * @chan, and then calls via_chan_pcm_fmt to set the audio hardware + * to enable or disable stereo. + */ + static int via_chan_set_stereo (struct via_info *card, struct via_channel *chan, int val) { @@ -690,6 +913,14 @@ static int via_chan_set_stereo (struct via_info *card, #if 0 +/** + * via_chan_dump_bufs - Display DMA table contents + * @chan: Channel whose DMA table will be displayed + * + * Debugging function which displays the contents of the + * scatter-gather DMA table for the given channel @chan. + */ + static void via_chan_dump_bufs (struct via_channel *chan) { int i; @@ -715,6 +946,15 @@ static void via_chan_dump_bufs (struct via_channel *chan) * */ +/** + * via_ac97_wait_idle - Wait until AC97 codec is not busy + * @card: Private info for specified board + * + * Sleep until the AC97 codec is no longer busy. + * Returns the final value read from the SGD + * register being polled. + */ + static u8 via_ac97_wait_idle (struct via_info *card) { u8 tmp8; @@ -740,6 +980,21 @@ static u8 via_ac97_wait_idle (struct via_info *card) } +/** + * via_ac97_read_reg - Read AC97 standard register + * @codec: Pointer to generic AC97 codec info + * @reg: Index of AC97 register to be read + * + * Read the value of a single AC97 codec register, + * as defined by the Intel AC97 specification. + * + * Defines the standard AC97 read-register operation + * required by the kernel's ac97_codec interface. + * + * Returns the 16-bit value stored in the specified + * register. + */ + static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg) { u32 data; @@ -788,6 +1043,19 @@ err_out: } +/** + * via_ac97_write_reg - Write AC97 standard register + * @codec: Pointer to generic AC97 codec info + * @reg: Index of AC97 register to be written + * @value: Value to be written to AC97 register + * + * Write the value of a single AC97 codec register, + * as defined by the Intel AC97 specification. + * + * Defines the standard AC97 write-register operation + * required by the kernel's ac97_codec interface. + */ + static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value) { u32 data; @@ -829,8 +1097,6 @@ static int via_mixer_open (struct inode *inode, struct file *file) DPRINTK ("ENTER\n"); - MOD_INC_USE_COUNT; - pci_for_each_dev(pdev) { drvr = pci_dev_driver (pdev); if (drvr == &via_driver) { @@ -843,7 +1109,6 @@ static int via_mixer_open (struct inode *inode, struct file *file) } DPRINTK ("EXIT, returning -ENODEV\n"); - MOD_DEC_USE_COUNT; return -ENODEV; match: @@ -853,18 +1118,6 @@ match: return 0; } - -static int via_mixer_release (struct inode *inode, struct file *file) -{ - DPRINTK ("ENTER\n"); - - MOD_DEC_USE_COUNT; - - DPRINTK ("EXIT, returning 0\n"); - return 0; -} - - static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -889,8 +1142,8 @@ static loff_t via_llseek(struct file *file, loff_t offset, int origin) static struct file_operations via_mixer_fops = { + owner: THIS_MODULE, open: via_mixer_open, - release: via_mixer_release, llseek: via_llseek, ioctl: via_mixer_ioctl, }; @@ -971,9 +1224,11 @@ static int __init via_ac97_reset (struct via_info *card) VIA_CR41_VRA | VIA_CR41_AC97_RESET); udelay (100); +#if 0 /* this breaks on K7M */ /* disable legacy stuff */ pci_write_config_byte (pdev, 0x42, 0x00); udelay(10); +#endif /* route FM trap to IRQ, disable FM trap */ pci_write_config_byte (pdev, 0x48, 0x05); @@ -1097,50 +1352,36 @@ static void via_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct via_info *card = dev_id; struct via_channel *chan; u8 status; - int unhandled = 1; - static long intcount = 0; - assert (irq == card->pdev->irq); - - intcount++; - status = inb (card->baseaddr + 0x00); if (status) { assert (card->open_mode & FMODE_WRITE); chan = &card->ch_out; - unhandled = 0; if (status & VIA_SGD_FLAG) { assert ((status & VIA_SGD_EOL) == 0); outb (VIA_SGD_FLAG, chan->iobase + 0x00); - DPRINTK("FLAG intr, status=0x%02X, intcount=%ld\n", - status, intcount); + DPRINTK("FLAG intr, status=0x%02X\n", status); via_interrupt_write (chan); } if (status & VIA_SGD_EOL) { assert ((status & VIA_SGD_FLAG) == 0); outb (VIA_SGD_EOL, chan->iobase + 0x00); - DPRINTK("EOL intr, status=0x%02X, intcount=%ld\n", - status, intcount); + DPRINTK("EOL intr, status=0x%02X\n", status); via_interrupt_write (chan); } if (status & VIA_SGD_STOPPED) { outb (VIA_SGD_STOPPED, chan->iobase + 0x00); - DPRINTK("STOPPED intr, status=0x%02X, intcount=%ld\n", - status, intcount); + DPRINTK("STOPPED intr, status=0x%02X\n", status); } #if 0 via_chan_dump_bufs (&card->ch_out); #endif } - - if (unhandled) - printk (KERN_WARNING PFX "unhandled interrupt, st=%02x, st32=%08x\n", - status, inl (card->baseaddr + 0x84)); } @@ -1229,6 +1470,7 @@ static void via_interrupt_cleanup (struct via_info *card) */ static struct file_operations via_dsp_fops = { + owner: THIS_MODULE, open: via_dsp_open, release: via_dsp_release, read: via_dsp_read, @@ -1860,8 +2102,6 @@ static int via_dsp_open (struct inode *inode, struct file *file) DPRINTK ("ENTER, minor=%d, file->f_mode=0x%x\n", minor, file->f_mode); - MOD_INC_USE_COUNT; - if (file->f_mode & FMODE_READ) /* no input ATM */ goto err_out; @@ -1951,7 +2191,6 @@ err_out_clear_mode: card->open_mode &= ~file->f_mode; spin_unlock_irqrestore (&card->lock, flags); err_out: - MOD_DEC_USE_COUNT; DPRINTK("ERROR EXIT, returning %d\n", rc); return rc; } @@ -1981,7 +2220,6 @@ static int via_dsp_release(struct inode *inode, struct file *file) spin_unlock_irqrestore (&card->lock, flags); wake_up (&card->open_wait); - MOD_DEC_USE_COUNT; DPRINTK("EXIT, returning 0\n"); return 0; @@ -2331,6 +2569,7 @@ static void __exit via_remove_one (struct pci_dev *pdev) via_interrupt_cleanup (card); via_card_cleanup_proc (card); via_dsp_cleanup (card); + via_ac97_cleanup (card); release_region (pci_resource_start (pdev, 0), pci_resource_len (pdev, 0)); @@ -2360,12 +2599,9 @@ static int __init init_via82cxxx_audio(void) int rc; DPRINTK ("ENTER\n"); - - MOD_INC_USE_COUNT; rc = via_init_proc (); if (rc) { - MOD_DEC_USE_COUNT; DPRINTK ("EXIT, returning %d\n", rc); return rc; } @@ -2375,13 +2611,10 @@ static int __init init_via82cxxx_audio(void) if (rc == 0) pci_unregister_driver (&via_driver); via_cleanup_proc (); - MOD_DEC_USE_COUNT; DPRINTK ("EXIT, returning -ENODEV\n"); return -ENODEV; } - MOD_DEC_USE_COUNT; - DPRINTK ("EXIT, returning 0\n"); return 0; } diff --git a/drivers/sound/wavfront.c b/drivers/sound/wavfront.c index 4bf595f86afd73..a8f826031b71f9 100644 --- a/drivers/sound/wavfront.c +++ b/drivers/sound/wavfront.c @@ -1953,7 +1953,6 @@ wavefront_open (struct inode *inode, struct file *file) { /* XXX fix me */ dev.opened = file->f_flags; - MOD_INC_USE_COUNT; return 0; } @@ -1962,7 +1961,6 @@ wavefront_release(struct inode *inode, struct file *file) { dev.opened = 0; dev.debug = 0; - MOD_DEC_USE_COUNT; return 0; } @@ -1996,6 +1994,7 @@ wavefront_ioctl(struct inode *inode, struct file *file, } static /*const*/ struct file_operations wavefront_fops = { + owner: THIS_MODULE, llseek: wavefront_llseek, ioctl: wavefront_ioctl, open: wavefront_open, diff --git a/drivers/sound/ymf_sb.c b/drivers/sound/ymf_sb.c new file mode 100644 index 00000000000000..a221a05d0d30e1 --- /dev/null +++ b/drivers/sound/ymf_sb.c @@ -0,0 +1,867 @@ +/* + Legacy audio driver for YMF724, 740, 744, 754 series. + Copyright 2000 Daisuke Nagano <breeze.nagano@nifty.ne.jp> + + Based on the VIA 82Cxxx driver by Jeff Garzik <jgarzik@pobox.com> + And ported to 2.3.x by Jeff Garzik too :) My it is a small world. + + Distribued under the GNU PUBLIC LICENSE (GPL) Version 2. + See the "COPYING" file distributed with kernel source tree for more info. + + ------------------------------------------------------------------------- + + It only supports SBPro compatible function of YMF7xx series s.t. + * 22.05kHz, 8-bit and stereo sample + * OPL3-compatible FM synthesizer + * MPU-401 compatible "external" MIDI interface + + ------------------------------------------------------------------------- + + Revision history + + Tue May 14 19:00:00 2000 0.0.1 + * initial release + + Tue May 16 19:29:29 2000 0.0.2 + + * add a little delays for reset devices. + * fixed addressing bug. + + Sun May 21 15:14:37 2000 0.0.3 + + * Add 'master_vol' module parameter to change 'PCM out Vol' of AC'97. + * remove native UART401 support. External MIDI port should be supported + by sb_midi driver. + * add support for SPDIF OUT. Module parameter 'spdif_out' is now available. + + Wed May 31 00:13:57 2000 0.0.4 + + * remove entries in Hwmcode.h. Now YMF744 / YMF754 sets instructions + in 724hwmcode.h. + * fixed wrong legacy_io setting on YMF744/YMF754 . + + */ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/ac97_codec.h> + +#include <asm/io.h> + +#include "sound_config.h" +#include "soundmodule.h" +#include "sb.h" + +#include "724hwmcode.h" + +#undef YMF_DEBUG +#define SUPPORT_UART401_MIDI 1 + +/* ---------------------------------------------------------------------- */ + +#ifndef SOUND_LOCK +#define SOUND_LOCK do {} while (0) +#define SOUND_LOCK_END do {} while (0) +#endif + +#ifndef PCI_VENDOR_ID_YAMAHA +#define PCI_VENDOR_ID_YAMAHA 0x1073 +#endif +#ifndef PCI_DEVICE_ID_YMF724 +#define PCI_DEVICE_ID_YMF724 0x0004 +#endif +#ifndef PCI_DEVICE_ID_YMF740 +#define PCI_DEVICE_ID_YMF740 0x000A +#endif +#ifndef PCI_DEVICE_ID_YMF740C +#define PCI_DEVICE_ID_YMF740C 0x000C +#endif +#ifndef PCI_DEVICE_ID_YMF724F +#define PCI_DEVICE_ID_YMF724F 0x000D +#endif +#ifndef PCI_DEVICE_ID_YMF744 +#define PCI_DEVICE_ID_YMF744 0x0010 +#endif +#ifndef PCI_DEVICE_ID_YMF754 +#define PCI_DEVICE_ID_YMF754 0x0012 +#endif + +/* ---------------------------------------------------------------------- */ + +#define YMFSB_RESET_DELAY 5 + +#define YMFSB_REGSIZE 0x8000 + +#define YMFSB_AC97TIMEOUT 2000 + +#define YMFSB_WORKBITTIMEOUT 250000 + +#define YMFSB_DSPLENGTH 0x0080 +#define YMFSB_CTRLLENGTH 0x3000 + +#define YMFSB_PCIR_VENDORID 0x00 +#define YMFSB_PCIR_DEVICEID 0x02 +#define YMFSB_PCIR_CMD 0x04 +#define YMFSB_PCIR_REVISIONID 0x08 +#define YMFSB_PCIR_BASEADDR 0x10 +#define YMFSB_PCIR_IRQ 0x3c + +#define YMFSB_PCIR_LEGCTRL 0x40 +#define YMFSB_PCIR_ELEGCTRL 0x42 +#define YMFSB_PCIR_DSXGCTRL 0x48 +#define YMFSB_PCIR_OPLADR 0x60 +#define YMFSB_PCIR_SBADR 0x62 +#define YMFSB_PCIR_MPUADR 0x64 + +#define YMFSB_INTFLAG 0x0004 +#define YMFSB_ACTIVITY 0x0006 +#define YMFSB_GLOBALCTRL 0x0008 +#define YMFSB_ZVCTRL 0x000A +#define YMFSB_TIMERCTRL 0x0010 +#define YMFSB_TIMERCOUNT 0x0012 +#define YMFSB_SPDIFOUTCTRL 0x0018 +#define YMFSB_SPDIFOUTSTATUS 0x001C +#define YMFSB_EEPROMCTRL 0x0020 +#define YMFSB_SPDIFINCTRL 0x0034 +#define YMFSB_SPDIFINSTATUS 0x0038 +#define YMFSB_DSPPROGRAMDL 0x0048 +#define YMFSB_DLCNTRL 0x004C +#define YMFSB_GPIOININTFLAG 0x0050 +#define YMFSB_GPIOININTENABLE 0x0052 +#define YMFSB_GPIOINSTATUS 0x0054 +#define YMFSB_GPIOOUTCTRL 0x0056 +#define YMFSB_GPIOFUNCENABLE 0x0058 +#define YMFSB_GPIOTYPECONFIG 0x005A +#define YMFSB_AC97CMDDATA 0x0060 +#define YMFSB_AC97CMDADR 0x0062 +#define YMFSB_PRISTATUSDATA 0x0064 +#define YMFSB_PRISTATUSADR 0x0066 +#define YMFSB_SECSTATUSDATA 0x0068 +#define YMFSB_SECSTATUSADR 0x006A +#define YMFSB_SECCONFIG 0x0070 +#define YMFSB_LEGACYOUTVOL 0x0080 +#define YMFSB_LEGACYOUTVOLL 0x0080 +#define YMFSB_LEGACYOUTVOLR 0x0082 +#define YMFSB_NATIVEDACOUTVOL 0x0084 +#define YMFSB_NATIVEDACOUTVOLL 0x0084 +#define YMFSB_NATIVEDACOUTVOLR 0x0086 +#define YMFSB_SPDIFOUTVOL 0x0088 +#define YMFSB_SPDIFOUTVOLL 0x0088 +#define YMFSB_SPDIFOUTVOLR 0x008A +#define YMFSB_AC3OUTVOL 0x008C +#define YMFSB_AC3OUTVOLL 0x008C +#define YMFSB_AC3OUTVOLR 0x008E +#define YMFSB_PRIADCOUTVOL 0x0090 +#define YMFSB_PRIADCOUTVOLL 0x0090 +#define YMFSB_PRIADCOUTVOLR 0x0092 +#define YMFSB_LEGACYLOOPVOL 0x0094 +#define YMFSB_LEGACYLOOPVOLL 0x0094 +#define YMFSB_LEGACYLOOPVOLR 0x0096 +#define YMFSB_NATIVEDACLOOPVOL 0x0098 +#define YMFSB_NATIVEDACLOOPVOLL 0x0098 +#define YMFSB_NATIVEDACLOOPVOLR 0x009A +#define YMFSB_SPDIFLOOPVOL 0x009C +#define YMFSB_SPDIFLOOPVOLL 0x009E +#define YMFSB_SPDIFLOOPVOLR 0x009E +#define YMFSB_AC3LOOPVOL 0x00A0 +#define YMFSB_AC3LOOPVOLL 0x00A0 +#define YMFSB_AC3LOOPVOLR 0x00A2 +#define YMFSB_PRIADCLOOPVOL 0x00A4 +#define YMFSB_PRIADCLOOPVOLL 0x00A4 +#define YMFSB_PRIADCLOOPVOLR 0x00A6 +#define YMFSB_NATIVEADCINVOL 0x00A8 +#define YMFSB_NATIVEADCINVOLL 0x00A8 +#define YMFSB_NATIVEADCINVOLR 0x00AA +#define YMFSB_NATIVEDACINVOL 0x00AC +#define YMFSB_NATIVEDACINVOLL 0x00AC +#define YMFSB_NATIVEDACINVOLR 0x00AE +#define YMFSB_BUF441OUTVOL 0x00B0 +#define YMFSB_BUF441OUTVOLL 0x00B0 +#define YMFSB_BUF441OUTVOLR 0x00B2 +#define YMFSB_BUF441LOOPVOL 0x00B4 +#define YMFSB_BUF441LOOPVOLL 0x00B4 +#define YMFSB_BUF441LOOPVOLR 0x00B6 +#define YMFSB_SPDIFOUTVOL2 0x00B8 +#define YMFSB_SPDIFOUTVOL2L 0x00B8 +#define YMFSB_SPDIFOUTVOL2R 0x00BA +#define YMFSB_SPDIFLOOPVOL2 0x00BC +#define YMFSB_SPDIFLOOPVOL2L 0x00BC +#define YMFSB_SPDIFLOOPVOL2R 0x00BE +#define YMFSB_ADCSLOTSR 0x00C0 +#define YMFSB_RECSLOTSR 0x00C4 +#define YMFSB_ADCFORMAT 0x00C8 +#define YMFSB_RECFORMAT 0x00CC +#define YMFSB_P44SLOTSR 0x00D0 +#define YMFSB_STATUS 0x0100 +#define YMFSB_CTRLSELECT 0x0104 +#define YMFSB_MODE 0x0108 +#define YMFSB_SAMPLECOUNT 0x010C +#define YMFSB_NUMOFSAMPLES 0x0110 +#define YMFSB_CONFIG 0x0114 +#define YMFSB_PLAYCTRLSIZE 0x0140 +#define YMFSB_RECCTRLSIZE 0x0144 +#define YMFSB_EFFCTRLSIZE 0x0148 +#define YMFSB_WORKSIZE 0x014C +#define YMFSB_MAPOFREC 0x0150 +#define YMFSB_MAPOFEFFECT 0x0154 +#define YMFSB_PLAYCTRLBASE 0x0158 +#define YMFSB_RECCTRLBASE 0x015C +#define YMFSB_EFFCTRLBASE 0x0160 +#define YMFSB_WORKBASE 0x0164 +#define YMFSB_DSPINSTRAM 0x1000 +#define YMFSB_CTRLINSTRAM 0x4000 + + +/* ---------------------------------------------------------------------- */ + +#define MAX_CARDS 4 + +#define PFX "ymf_sb: " + +#define YMFSB_VERSION "0.0.4" +#define YMFSB_CARD_NAME "YMF7xx Legacy Audio driver " YMFSB_VERSION + +#ifdef SUPPORT_UART401_MIDI +#if 0 +# define ymf7xxsb_probe_midi probe_uart401 +# define ymf7xxsb_attach_midi attach_uart401 +# define ymf7xxsb_unload_midi unload_uart401 +#else +# define ymf7xxsb_probe_midi probe_sbmpu +# define ymf7xxsb_attach_midi attach_sbmpu +# define ymf7xxsb_unload_midi unload_sbmpu +#endif +#endif + +/* ---------------------------------------------------------------------- */ + +static struct address_info sb_data[MAX_CARDS]; +static struct address_info opl3_data[MAX_CARDS]; +#ifdef SUPPORT_UART401_MIDI +static struct address_info mpu_data[MAX_CARDS]; +#endif +static unsigned cards = 0; +static unsigned short *ymfbase[MAX_CARDS]; + +/* ---------------------------------------------------------------------- */ + +#ifdef MODULE +#ifdef SUPPORT_UART401_MIDI +static int mpu_io = 0; +#endif +static int synth_io = 0; +static int io = 0; +static int dma = 0; +static int master_vol = -1; +static int spdif_out = 0; +#ifdef SUPPORT_UART401_MIDI +MODULE_PARM(mpu_io, "i"); +#endif +MODULE_PARM(synth_io, "i"); +MODULE_PARM(io,"i"); +MODULE_PARM(dma,"i"); +MODULE_PARM(master_vol,"i"); +MODULE_PARM(spdif_out,"i"); +#else +#ifdef SUPPORT_UART401_MIDI +static int mpu_io = 0x330; +#endif +static int synth_io = 0x388; +static int io = 0x220; +static int dma = 1; +static int master_vol = 80; +static int spdif_out = 0; +#endif + +/* ---------------------------------------------------------------------- */ + +static int readRegWord( int adr ) { + + if (ymfbase[cards]==NULL) return 0; + + return readw(ymfbase[cards]+adr/2); +} + +static void writeRegWord( int adr, int val ) { + + if (ymfbase[cards]==NULL) return; + + writew((unsigned short)(val&0xffff), ymfbase[cards] + adr/2); + + return; +} + +static int readRegDWord( int adr ) { + + if (ymfbase[cards]==NULL) return 0; + + return (readl(ymfbase[cards]+adr/2)); +} + +static void writeRegDWord( int adr, int val ) { + + if (ymfbase[cards]==NULL) return; + + writel((unsigned int)(val&0xffffffff), ymfbase[cards]+adr/2); + + return; +} + +/* ---------------------------------------------------------------------- */ + +static int checkPrimaryBusy( void ) +{ + int timeout=0; + + while ( timeout++ < YMFSB_AC97TIMEOUT ) + { + if ( (readRegWord(YMFSB_PRISTATUSADR) & 0x8000) == 0x0000 ) + return 0; + } + return -1; +} + +static int writeAc97( int adr, unsigned short val ) +{ + + if ( adr > 0x7f || adr < 0x00 ) return -1; + + if ( checkPrimaryBusy() ) return -1; + +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "AC97 0x%0x = 0x%0x\n",adr,val); +#endif + + writeRegWord( YMFSB_AC97CMDADR, 0x0000 | adr ); + writeRegWord( YMFSB_AC97CMDDATA, val ); + + return 0; +} + +static int checkCodec( struct pci_dev *pcidev ) +{ + u8 tmp8; + + pci_read_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, &tmp8); + if ( tmp8 & 0x03 ) { + pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc); + mdelay(YMFSB_RESET_DELAY); + pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8|0x03); + mdelay(YMFSB_RESET_DELAY); + pci_write_config_byte(pcidev, YMFSB_PCIR_DSXGCTRL, tmp8&0xfc); + mdelay(YMFSB_RESET_DELAY); + } + + if ( checkPrimaryBusy() ) return -1; + + return 0; +} + +static int setupLegacyIO( struct pci_dev *pcidev ) +{ + int v; + int sbio=0,mpuio=0,oplio=0,dma=0; + + switch(sb_data[cards].io_base) { + case 0x220: + sbio = 0; + break; + case 0x240: + sbio = 1; + break; + case 0x260: + sbio = 2; + break; + case 0x280: + sbio = 3; + break; + default: + return -1; + break; + } +#ifdef YMF_DEBUG + printk(PFX "set SBPro I/O at 0x%x\n",sb_data[cards].io_base); +#endif + +#ifdef SUPPORT_UART401_MIDI + switch(mpu_data[cards].io_base) { + case 0x330: + mpuio = 0; + break; + case 0x300: + mpuio = 1; + break; + case 0x332: + mpuio = 2; + break; + case 0x334: + mpuio = 3; + break; + default: + mpuio = 0; + break; + } +# ifdef YMF_DEBUG + printk(PFX "set MPU401 I/O at 0x%x\n",mpu_data[cards].io_base); +# endif +#endif + + switch(opl3_data[cards].io_base) { + case 0x388: + oplio = 0; + break; + case 0x398: + oplio = 1; + break; + case 0x3a0: + oplio = 2; + break; + case 0x3a8: + oplio = 3; + break; + default: + return -1; + break; + } +#ifdef YMF_DEBUG + printk(PFX "set OPL3 I/O at 0x%x\n",opl3_data[cards].io_base); +#endif + + dma = sb_data[cards].dma; +#ifdef YMF_DEBUG + printk(PFX "set DMA address at 0x%x\n",sb_data[cards].dma); +#endif + + v = 0x0000 | ((dma<<6)&0x03) | 0x003f; + pci_write_config_word(pcidev, YMFSB_PCIR_LEGCTRL, v); +#ifdef YMF_DEBUG + printk(PFX "LEGCTRL: 0x%x\n",v); +#endif + switch( pcidev->device ) { + case PCI_DEVICE_ID_YMF724: + case PCI_DEVICE_ID_YMF740: + case PCI_DEVICE_ID_YMF724F: + case PCI_DEVICE_ID_YMF740C: + v = 0x8800 | ((mpuio<<4)&0x03) | ((sbio<<2)&0x03) | (oplio&0x03); + pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v); +#ifdef YMF_DEBUG + printk(PFX "ELEGCTRL: 0x%x\n",v); +#endif + break; + + case PCI_DEVICE_ID_YMF744: + case PCI_DEVICE_ID_YMF754: + v = 0x8800; + pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v); +#ifdef YMF_DEBUG + printk(PFX "ELEGCTRL: 0x%x\n",v); +#endif + pci_write_config_word(pcidev, YMFSB_PCIR_OPLADR, opl3_data[cards].io_base); + pci_write_config_word(pcidev, YMFSB_PCIR_SBADR, sb_data[cards]. +io_base); +#ifdef SUPPORT_UART401_MIDI + pci_write_config_word(pcidev, YMFSB_PCIR_MPUADR, mpu_data[cards].io_base); +#endif + break; + + default: + printk(KERN_ERR PFX "Invalid device ID: %d\n",pcidev->device); + return -1; + break; + } + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static void enableDSP( void ) +{ + writeRegDWord( YMFSB_CONFIG, 0x00000001 ); + return; +} + +static void disableDSP( void ) +{ + int val; + int i; + + val = readRegDWord( YMFSB_CONFIG ); + if ( val ) { + writeRegDWord( YMFSB_CONFIG, 0 ); + } + + i=0; + while( ++i < YMFSB_WORKBITTIMEOUT ) { + val = readRegDWord(YMFSB_STATUS); + if ( (val & 0x00000002) == 0x00000000 ) break; + } + + return; +} + +static int setupInstruction( struct pci_dev *pcidev ) +{ + int i; + int val; + + writeRegDWord( YMFSB_NATIVEDACOUTVOL, 0 ); /* mute dac */ + disableDSP(); + + writeRegDWord( YMFSB_MODE, 0x00010000 ); + + /* DS-XG Software Reset */ + writeRegDWord( YMFSB_MODE, 0x00000000 ); + writeRegDWord( YMFSB_MAPOFREC, 0x00000000 ); + writeRegDWord( YMFSB_MAPOFEFFECT, 0x00000000 ); + writeRegDWord( YMFSB_PLAYCTRLBASE, 0x00000000 ); + writeRegDWord( YMFSB_RECCTRLBASE, 0x00000000 ); + writeRegDWord( YMFSB_EFFCTRLBASE, 0x00000000 ); + + val = readRegWord( YMFSB_GLOBALCTRL ); + writeRegWord( YMFSB_GLOBALCTRL, (val&~0x0007) ); + + /* setup DSP instruction code */ + for ( i=0 ; i<YMFSB_DSPLENGTH ; i+=4 ) { + writeRegDWord( YMFSB_DSPINSTRAM+i, DspInst[i>>2] ); + } + + switch( pcidev->device ) { + case PCI_DEVICE_ID_YMF724: + case PCI_DEVICE_ID_YMF740: + /* setup Control instruction code */ + for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) { + writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst[i>>2] ); + } + break; + + case PCI_DEVICE_ID_YMF724F: + case PCI_DEVICE_ID_YMF740C: + case PCI_DEVICE_ID_YMF744: + case PCI_DEVICE_ID_YMF754: + /* setup Control instruction code */ + for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) { + writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst1E[i>>2] ); + } + break; + + default: + return -1; + } + + enableDSP(); + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static int __init ymf7xx_init(struct pci_dev *pcidev) +{ + unsigned short v; + + /* Read hardware information */ +#ifdef YMF_DEBUG + unsigned int dv; + pci_read_config_word(pcidev, YMFSB_PCIR_VENDORID, &v); + printk(KERN_INFO PFX "Vendor ID = 0x%x\n",v); + pci_read_config_word(pcidev, YMFSB_PCIR_DEVICEID, &v); + printk(KERN_INFO PFX "Device ID = 0x%x\n",v); + pci_read_config_word(pcidev, YMFSB_PCIR_REVISIONID, &v); + printk(KERN_INFO PFX "Revision ID = 0x%x\n",v&0xff); + pci_read_config_dword(pcidev, YMFSB_PCIR_BASEADDR, &dv); + printk(KERN_INFO PFX "Base address = 0x%x\n",dv); + pci_read_config_word(pcidev, YMFSB_PCIR_IRQ, &v); + printk(KERN_INFO PFX "IRQ line = 0x%x\n",v&0xff); +#endif + + /* enables memory space access / bus mastering */ + pci_read_config_word(pcidev, YMFSB_PCIR_CMD, &v); + pci_write_config_word(pcidev, YMFSB_PCIR_CMD, v|0x06); + + /* check codec */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "check codec...\n"); +#endif + if (checkCodec(pcidev)) return -1; + + /* setup legacy I/O */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup legacy I/O...\n"); +#endif + if (setupLegacyIO(pcidev)) return -1; + + /* setup instruction code */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup instructions...\n"); +#endif + if (setupInstruction(pcidev)) return -1; + + /* AC'97 setup */ +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup AC'97...\n"); +#endif + if ( writeAc97(AC97_RESET ,0x0000) ) /* Reset */ + return -1; + if ( writeAc97(AC97_MASTER_VOL_STEREO,0x0000) ) /* Master Volume */ + return -1; + + v = 31*(100-master_vol)/100; + v = (v<<8 | v)&0x7fff; + if ( writeAc97(AC97_PCMOUT_VOL ,v ) ) /* PCM out Volume */ + return -1; + +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup Legacy Volume...\n"); +#endif + /* Legacy Audio Output Volume L & R ch */ + writeRegDWord( YMFSB_LEGACYOUTVOL, 0x3fff3fff ); + +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "setup SPDIF output control...\n"); +#endif + /* SPDIF Output control */ + v = spdif_out != 0 ? 0x0001 : 0x0000; + writeRegWord( YMFSB_SPDIFOUTCTRL, v ); + /* no copyright protection, + sample-rate converted, + re-recorded software comercially available (the 1st generation), + original */ + writeRegWord( YMFSB_SPDIFOUTSTATUS, 0x9a04 ); + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static void __init ymf7xxsb_attach_sb(struct address_info *hw_config) +{ + if(!sb_dsp_init(hw_config)) + hw_config->slots[0] = -1; +} + +static int __init ymf7xxsb_probe_sb(struct address_info *hw_config) +{ + if (check_region(hw_config->io_base, 16)) + { + printk(KERN_DEBUG PFX "SBPro port 0x%x is already in use\n", + hw_config->io_base); + return 0; + } + return sb_dsp_detect(hw_config, SB_PCI_YAMAHA, 0, NULL); +} + + +static void ymf7xxsb_unload_sb(struct address_info *hw_config, int unload_mpu) +{ + if(hw_config->slots[0]!=-1) + sb_dsp_unload(hw_config, unload_mpu); +} + +/* ---------------------------------------------------------------------- */ + +enum chip_types { + CH_YMF724 = 0, + CH_YMF724F, + CH_YMF740, + CH_YMF740C, + CH_YMF744, + CH_YMF754, +}; + +/* directly indexed by chip_types enum above */ +/* note we keep this a struct to ease adding + * other per-board or per-chip info here */ +struct { + const char *devicename; +} devicetable[] __initdata = +{ + { "YMF724A-E" }, + { "YMF724F" }, + { "YMF740A-B" }, + { "YMF740C" }, + { "YMF744" }, + { "YMF754" }, +}; + +static struct pci_device_id ymf7xxsb_pci_tbl[] __initdata = { + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724 }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724F }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740 }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740C }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF744 }, + { PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF754 }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, ymf7xxsb_pci_tbl); + +static int __init ymf7xxsb_init_one (struct pci_dev *pcidev, const struct pci_device_id *ent) +{ + + const char *devicename; + unsigned long iobase; + + if (cards == MAX_CARDS) { + printk (KERN_DEBUG PFX "maximum number of cards reached\n"); + return -ENODEV; + } + + if ( pcidev->irq == 0 ) return -ENODEV; + iobase = pci_resource_start (pcidev, 0); + if ( iobase == 0x00000000 ) return -ENODEV; + + devicename = devicetable[ent->driver_data].devicename; + + /* remap memory mapped I/O onto kernel virtual memory */ + if ( (ymfbase[cards] = ioremap_nocache(iobase, YMFSB_REGSIZE)) == 0 ) + { + printk(KERN_ERR PFX "ioremap (0x%lx) returns zero\n", iobase); + return -ENODEV; + } + printk(KERN_INFO PFX "found %s at 0x%lx\n", devicename, iobase); +#ifdef YMF_DEBUG + printk(KERN_INFO PFX "remappling to 0x%p\n", ymfbase[cards]); +#endif + + memset (&sb_data[cards], 0, sizeof (struct address_info)); + memset (&opl3_data[cards], 0, sizeof (struct address_info)); +#ifdef SUPPORT_UART401_MIDI + memset (&mpu_data[cards], 0, sizeof (struct address_info)); +#endif + + sb_data[cards].name = YMFSB_CARD_NAME; + opl3_data[cards].name = YMFSB_CARD_NAME; +#ifdef SUPPORT_UART401_MIDI + mpu_data[cards].name = YMFSB_CARD_NAME; +#endif + + sb_data[cards].card_subtype = MDL_YMPCI; + + if ( io == 0 ) io = 0x220; + sb_data[cards].io_base = io; + sb_data[cards].irq = pcidev->irq; + sb_data[cards].dma = dma; + + if ( synth_io == 0 ) synth_io = 0x388; + opl3_data[cards].io_base = synth_io; + opl3_data[cards].irq = -1; + +#ifdef SUPPORT_UART401_MIDI + if ( mpu_io == 0 ) mpu_io = 0x330; + mpu_data[cards].io_base = mpu_io; + mpu_data[cards].irq = -1; +#endif + + if ( ymf7xx_init(pcidev) ) { + printk (KERN_ERR PFX + "Cannot initialize %s, aborting\n", + devicename); + return -ENODEV; + } + + /* register legacy SoundBlaster Pro */ + if (!ymf7xxsb_probe_sb(&sb_data[cards])) { + printk (KERN_ERR PFX + "SB probe at 0x%X failed, aborting\n", + io); + return -ENODEV; + } + ymf7xxsb_attach_sb (&sb_data[cards]); + +#ifdef SUPPORT_UART401_MIDI + /* register legacy MIDI */ + if ( mpu_io > 0 && 0) + { + if (!ymf7xxsb_probe_midi (&mpu_data[cards])) { + printk (KERN_ERR PFX + "MIDI probe @ 0x%X failed, aborting\n", + mpu_io); + ymf7xxsb_unload_sb (&sb_data[cards], 0); + return -ENODEV; + } + ymf7xxsb_attach_midi (&mpu_data[cards]); + } +#endif + + /* register legacy OPL3 */ + + cards++; + return 0; +} + +static struct pci_driver ymf7xxsb_driver = { + name: "ymf7xxsb", + id_table: ymf7xxsb_pci_tbl, + probe: ymf7xxsb_init_one, +}; + +static int __init init_ymf7xxsb_module(void) +{ + int i; + + /* + * Binds us to the sound subsystem + */ + SOUND_LOCK; + + if ( master_vol < 0 ) master_vol = 50; + if ( master_vol > 100 ) master_vol = 100; + + for (i=0 ; i<MAX_CARDS ; i++ ) + ymfbase[i] = NULL; + + i = pci_module_init (&ymf7xxsb_driver); + if (i < 0) { + SOUND_LOCK_END; + return i; + } + + printk (KERN_INFO PFX YMFSB_CARD_NAME " loaded\n"); + + return 0; +} + +static void __exit free_iomaps( void ) +{ + int i; + + for ( i=0 ; i<MAX_CARDS ; i++ ) { + if ( ymfbase[i]!=NULL ) + iounmap(ymfbase[i]); + } + + return; +} + +static void __exit cleanup_ymf7xxsb_module(void) +{ + int i; + + for (i = 0; i < cards; i++) { +#ifdef SUPPORT_UART401_MIDI + ymf7xxsb_unload_sb (&sb_data[i], 0); + ymf7xxsb_unload_midi (&mpu_data[i]); +#else + ymf7xxsb_unload_sb (&sb_data[i], 1); +#endif + } + + free_iomaps(); + + /* + * Final clean up with the sound layer + */ + SOUND_LOCK_END; +} + +MODULE_AUTHOR("Daisuke Nagano, breeze.nagano@nifty.ne.jp"); +MODULE_DESCRIPTION("YMF7xx Legacy Audio Driver"); + +module_init(init_ymf7xxsb_module); +module_exit(cleanup_ymf7xxsb_module); + diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index fc4f61b34eb820..3fde30bfad8af3 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c @@ -49,6 +49,7 @@ static int phone_open(struct inode *inode, struct file *file) unsigned int minor = MINOR(inode->i_rdev); int err = 0; struct phone_device *p; + struct file_operations *old_fops; if (minor >= PHONE_NUM_DEVICES) return -ENODEV; @@ -69,12 +70,15 @@ static int phone_open(struct inode *inode, struct file *file) goto end; } } - if (p->open) { + old_fops = file->f_op; + file->f_op = fops_get(p->f_op); + if (p->open) err = p->open(p, file); /* Tell the device it is open */ - if (err) - goto end; + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); } - file->f_op = p->f_op; + fops_put(old_fops); end: up(&phone_lock); return err; @@ -129,6 +133,7 @@ void phone_unregister_device(struct phone_device *pfd) static struct file_operations phone_fops = { + owner: THIS_MODULE, open: phone_open, }; diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index b1d164d3578c2a..10ac2eec303c1a 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c @@ -30,7 +30,6 @@ u_int zorro_num_autocon = 0; struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; -#if 0 /* * Zorro Bus Resources * Order _does_ matter! (see code below) @@ -42,8 +41,9 @@ static struct resource zorro_res[4] = { { "Zorro III exp", 0xff000000, 0xffffffff }, { "Zorro III cfg", 0x40000000, 0x7fffffff } }; -#endif - + +static u_int __init zorro_num_res = 0; + /* * Find Zorro Devices @@ -107,6 +107,18 @@ static void __init mark_region(unsigned long start, unsigned long end, } +static struct resource __init *zorro_find_parent_resource(struct zorro_dev *z) +{ + int i; + + for (i = 0; i < zorro_num_res; i++) + if (z->resource.start >= zorro_res[i].start && + z->resource.end <= zorro_res[i].end) + return &zorro_res[i]; + return &iomem_resource; +} + + /* * Initialization */ @@ -123,10 +135,9 @@ void __init zorro_init(void) zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); /* Request the resources */ -#if 0 - for (i = 0; i < (AMIGAHW_PRESENT(ZORRO3) ? 4 : 2); i++) + zorro_num_res = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2; + for (i = 0; i < zorro_num_res; i++) request_resource(&iomem_resource, &zorro_res[i]); -#endif for (i = 0; i < zorro_num_autocon; i++) { dev = &zorro_autocon[i]; dev->id = (dev->rom.er_Manufacturer<<16) | (dev->rom.er_Product<<8); @@ -137,7 +148,7 @@ void __init zorro_init(void) } dev->resource.name = dev->name; zorro_namedevice(dev); - if (request_resource(&iomem_resource, &dev->resource)) + if (request_resource(zorro_find_parent_resource(dev), &dev->resource)) printk("zorro_init: cannot request resource for board %d\n", i); } diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 040e0b79af3baa..9f1e8b06fd1c46 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c @@ -737,7 +737,8 @@ static struct file_operations devfsd_fops = * @namelen: The number of characters in @name. * @traverse_symlink: If %TRUE then the entry is traversed if it is a symlink. * - * Returns a pointer to the entry on success, else %NULL. + * Search for a devfs entry inside another devfs entry and returns a pointer + * to the entry on success, else %NULL. */ static struct devfs_entry *search_for_entry_in_dir (struct devfs_entry *parent, @@ -902,6 +903,7 @@ static struct devfs_entry *search_for_entry (struct devfs_entry *dir, /** * find_by_dev - Find a devfs entry in a directory. + * @dir: The directory where to search * @major: The major number to search for. * @minor: The minor number to search for. * @type: The type of special file to search for. This may be either @@ -1746,8 +1748,8 @@ void *devfs_get_ops (devfs_handle_t de) /** * devfs_set_file_size - Set the file size for a devfs regular file. - * de: The handle to the device entry. - * size: The new file size. + * @de: The handle to the device entry. + * @size: The new file size. * * Returns 0 on success, else a negative error code. */ @@ -1788,6 +1790,7 @@ void *devfs_get_info (devfs_handle_t de) /** * devfs_set_info - Set the info pointer written to private_data upon open. * @de: The handle to the device entry. + * @info: pointer to the data * * Returns 0 on success, else a negative error code. */ @@ -1940,8 +1943,8 @@ int devfs_register_blkdev (unsigned int major, const char *name, /** * devfs_unregister_chrdev - Optionally unregister a conventional character driver. - * major: The major number for the driver. - * name: The name of the driver (as seen in /proc/devices). + * @major: The major number for the driver. + * @name: The name of the driver (as seen in /proc/devices). * * This function will unregister a character driver provided the "devfs=only" * option was not provided at boot time. @@ -1976,7 +1979,6 @@ int devfs_unregister_blkdev (unsigned int major, const char *name) /** * devfs_setup - Process kernel boot options. * @str: The boot options after the "devfs=". - * @unused: Unused. */ SETUP_STATIC int __init devfs_setup (char *str) @@ -2404,7 +2406,7 @@ static void devfs_read_inode (struct inode *inode) #endif } /* End Function devfs_read_inode */ -static void devfs_write_inode (struct inode *inode) +static void devfs_write_inode (struct inode *inode, int unused) { int index; struct devfs_inode *di; @@ -2638,7 +2640,7 @@ static int devfs_open (struct inode *inode, struct file *file) file->f_op = &def_blk_fops; if (df->ops) inode->i_bdev->bd_op = df->ops; } - else file->f_op = df->ops; + else file->f_op = fops_get((struct file_operations*)df->ops); if (file->f_op) err = file->f_op->open ? (*file->f_op->open) (inode, file) : 0; else diff --git a/fs/devices.c b/fs/devices.c index 2c53934b90010c..d119b1c75f620e 100644 --- a/fs/devices.c +++ b/fs/devices.c @@ -17,6 +17,7 @@ #include <linux/stat.h> #include <linux/fcntl.h> #include <linux/errno.h> +#include <linux/module.h> #ifdef CONFIG_KMOD #include <linux/kmod.h> @@ -142,8 +143,9 @@ int chrdev_open(struct inode * inode, struct file * filp) { int ret = -ENODEV; - filp->f_op = get_chrfops(MAJOR(inode->i_rdev), MINOR(inode->i_rdev)); - if (filp->f_op != NULL){ + filp->f_op = fops_get(get_chrfops(MAJOR(inode->i_rdev), + MINOR(inode->i_rdev))); + if (filp->f_op) { ret = 0; if (filp->f_op->open != NULL) ret = filp->f_op->open(inode,filp); diff --git a/fs/file_table.c b/fs/file_table.c index 7d5bd9e01d1d58..ecaa4689677f23 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -9,6 +9,7 @@ #include <linux/slab.h> #include <linux/file.h> #include <linux/init.h> +#include <linux/module.h> #include <linux/smp_lock.h> /* SLAB cache for filp's. */ @@ -127,6 +128,7 @@ static void __fput(struct file *filp) if (filp->f_op && filp->f_op->release) filp->f_op->release(inode, filp); + fops_put(filp->f_op); filp->f_dentry = NULL; filp->f_vfsmnt = NULL; if (filp->f_mode & FMODE_WRITE) diff --git a/fs/open.c b/fs/open.c index e23e48194e7dcd..9135f0e30138dd 100644 --- a/fs/open.c +++ b/fs/open.c @@ -10,6 +10,7 @@ #include <linux/file.h> #include <linux/smp_lock.h> #include <linux/quotaops.h> +#include <linux/module.h> #include <asm/uaccess.h> @@ -653,7 +654,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) f->f_vfsmnt = mnt; f->f_pos = 0; f->f_reada = 0; - f->f_op = inode->i_fop; + f->f_op = fops_get(inode->i_fop); if (inode->i_sb) file_move(f, &inode->i_sb->s_files); if (f->f_op && f->f_op->open) { @@ -666,6 +667,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) return f; cleanup_all: + fops_put(f->f_op); if (f->f_mode & FMODE_WRITE) put_write_access(inode); f->f_dentry = NULL; diff --git a/fs/proc/base.c b/fs/proc/base.c index ecb8a29919d545..fb63722d523a1f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -160,6 +160,24 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer) if (len > PAGE_SIZE) len = PAGE_SIZE; res = access_process_vm(task, mm->arg_start, buffer, len, 0); + // If the nul at the end of args has been overwritten, then + // assume application is using setproctitle(3). + if ( res > 0 && buffer[res-1] != '\0' ) + { + len = strnlen( buffer, res ); + if ( len < res ) + { + res = len; + } + else + { + len = mm->env_end - mm->env_start; + if (len > PAGE_SIZE - res) + len = PAGE_SIZE - res; + res += access_process_vm(task, mm->env_start, buffer+res, len, 0); + res = strnlen( buffer, res ); + } + } mmput(mm); } return res; diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 1585657a2d7b06..dc6f96b17f46cf 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -14,6 +14,8 @@ #include <linux/sched.h> #include <linux/proc_fs.h> #include <linux/stat.h> +#define __NO_VERSION__ +#include <linux/module.h> #include <asm/bitops.h> static ssize_t proc_file_read(struct file * file, char * buf, @@ -397,13 +399,14 @@ static void proc_kill_inodes(struct proc_dir_entry *de) continue; if (inode->u.generic_ip != de) continue; + fops_put(filp->f_op); filp->f_op = NULL; } file_list_unlock(); } struct proc_dir_entry *proc_symlink(const char *name, - struct proc_dir_entry *parent, char *dest) + struct proc_dir_entry *parent, const char *dest) { struct proc_dir_entry *ent = NULL; const char *fn = name; @@ -535,7 +538,7 @@ void free_proc_entry(struct proc_dir_entry *de) { int ino = de->low_ino; - if (ino < PROC_DYNAMIC_FIRST && + if (ino < PROC_DYNAMIC_FIRST || ino >= PROC_DYNAMIC_FIRST+PROC_NDYNAMIC) return; if (S_ISLNK(de->mode) && de->data) diff --git a/fs/read_write.c b/fs/read_write.c index 4569ee18aca6f8..3d3519146bc73e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -199,9 +199,19 @@ static ssize_t do_readv_writev(int type, struct file *file, if (copy_from_user(iov, vector, count*sizeof(*vector))) goto out; + /* BSD readv/writev returns EINVAL if one of the iov_len + values < 0 or tot_len overflowed a 32-bit integer. -ink */ tot_len = 0; - for (i = 0 ; i < count ; i++) - tot_len += iov[i].iov_len; + ret = -EINVAL; + for (i = 0 ; i < count ; i++) { + size_t tmp = tot_len; + int len = iov[i].iov_len; + if (len < 0) + goto out; + (u32)tot_len += len; + if (tot_len < tmp || tot_len < (u32)len) + goto out; + } inode = file->f_dentry->d_inode; /* VERIFY_WRITE actually means a read, as we write to user space */ diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h index 81f463cd584a7f..f4468611ef1d5a 100644 --- a/include/linux/ac97_codec.h +++ b/include/linux/ac97_codec.h @@ -32,7 +32,7 @@ #define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */ #define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */ #define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */ -#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */ +#define AC97_PCM_LR_DAC_RATE 0x0032 /* PCM LR DAC Rate */ #define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */ #define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */ #define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */ @@ -133,7 +133,7 @@ SOUND_MASK_LINE1| SOUND_MASK_LINE|\ SOUND_MASK_PHONEIN) -#define supported_mixer(CODEC,FOO) ( CODEC->supported_mixers & (1<<FOO) ) +#define supported_mixer(CODEC,FOO) ((CODEC)->supported_mixers & (1<<FOO) ) struct ac97_codec { /* AC97 controller connected with */ @@ -150,6 +150,9 @@ struct ac97_codec { u16 (*codec_read) (struct ac97_codec *codec, u8 reg); void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val); + /* Wait for codec-ready. Ok to sleep here. */ + void (*codec_wait) (struct ac97_codec *codec); + /* OSS mixer masks */ int modcnt; int supported_mixers; diff --git a/include/linux/ide.h b/include/linux/ide.h index 8804c9777f9185..13876daf5ca300 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -58,6 +58,10 @@ void cmd640_dump_regs (void); #endif #endif /* CONFIG_BLK_DEV_CMD640 */ +#ifndef DISABLE_IRQ_NOSYNC +#define DISABLE_IRQ_NOSYNC 0 +#endif + /* * IDE_DRIVE_CMD is used to implement many features of the hdparm utility */ @@ -181,6 +185,32 @@ typedef unsigned char byte; /* used everywhere */ OUT_BYTE((drive)->select.all, hwif->io_ports[IDE_SELECT_OFFSET]); \ } +#define SELECT_INTERRUPT(hwif,drive) \ +{ \ + if (hwif->intrproc) \ + hwif->intrproc(drive); \ + else \ + OUT_BYTE((drive)->ctl|2, hwif->io_ports[IDE_CONTROL_OFFSET]); \ +} + +#define SELECT_MASK(hwif,drive,mask) \ +{ \ + if (hwif->maskproc) \ + hwif->maskproc(drive,mask); \ +} + +#define SELECT_READ_WRITE(hwif,drive,func) \ +{ \ + if (hwif->rwproc) \ + hwif->rwproc(drive,func); \ +} + +#define QUIRK_LIST(hwif,drive) \ +{ \ + if (hwif->quirkproc) \ + (drive)->quirk_list = hwif->quirkproc(drive); \ +} + /* * Check for an interrupt and acknowledge the interrupt status */ @@ -309,6 +339,8 @@ typedef struct ide_drive_s { int last_lun; /* last logical unit */ int forced_lun; /* if hdxlun was given at boot */ int lun; /* logical unit */ + int crc_count; /* crc counter to reduce drive speed */ + byte quirk_list; /* drive is considered quirky if set for a specific host */ byte init_speed; /* transfer rate set at boot */ byte current_speed; /* current transfer rate set */ byte dn; /* now wide spread use */ @@ -354,6 +386,10 @@ typedef int (ide_speedproc_t) (ide_drive_t *, byte); */ typedef void (ide_selectproc_t) (ide_drive_t *); typedef void (ide_resetproc_t) (ide_drive_t *); +typedef int (ide_quirkproc_t) (ide_drive_t *); +typedef void (ide_intrproc_t) (ide_drive_t *); +typedef void (ide_maskproc_t) (ide_drive_t *, int); +typedef void (ide_rw_proc_t) (ide_drive_t *, ide_dma_action_t); /* * hwif_chipset_t is used to keep track of the specific hardware @@ -388,6 +424,10 @@ typedef struct hwif_s { ide_speedproc_t *speedproc; /* routine to retune DMA modes for drives */ ide_selectproc_t *selectproc; /* tweaks hardware to select drive */ ide_resetproc_t *resetproc; /* routine to reset controller after a disk reset */ + ide_intrproc_t *intrproc; /* special interrupt handling for shared pci interrupts */ + ide_maskproc_t *maskproc; /* special host masking for drive selection */ + ide_quirkproc_t *quirkproc; /* check host's drive quirk list */ + ide_rw_proc_t *rwproc; /* adjust timing based upon rq->cmd direction */ ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */ unsigned int *dmatable_cpu; /* dma physical region descriptor table (cpu view) */ dma_addr_t dmatable_dma; /* dma physical region descriptor table (dma view) */ @@ -424,6 +464,7 @@ typedef struct hwif_s { void *hwif_data; /* extra hwif data */ } ide_hwif_t; + /* * Status returned from various ide_ functions */ @@ -614,12 +655,14 @@ void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup); /* * This is used for (nearly) all data transfers from/to the IDE interface + * FIXME for 2.5, to a pointer pass verses memcpy........ */ void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount); void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); /* * This is used for (nearly) all ATAPI data transfers from/to the IDE interface + * FIXME for 2.5, to a pointer pass verses memcpy........ */ void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount); @@ -750,6 +793,7 @@ byte ide_auto_reduce_xfer (ide_drive_t *drive); int ide_driveid_update (ide_drive_t *drive); int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature); int ide_config_drive_speed (ide_drive_t *drive, byte speed); +byte eighty_ninty_three (ide_drive_t *drive); int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature); /* diff --git a/include/linux/kernel.h b/include/linux/kernel.h index a8d79a50e508f8..ac6f029b99b529 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -55,6 +55,7 @@ extern int sprintf(char * buf, const char * fmt, ...); extern int vsprintf(char *buf, const char *, va_list); extern int get_option(char **str, int *pint); extern char *get_options(char *str, int nints, int *ints); +extern unsigned long memparse(char *ptr, char **retptr); extern int session_of_pgrp(int pgrp); diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index d0487c3df455d8..28bf3daa02aaa2 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -127,7 +127,7 @@ extern void proc_tty_unregister_driver(struct tty_driver *driver); extern void proc_device_tree_init(void); extern struct proc_dir_entry *proc_symlink(const char *, - struct proc_dir_entry *,char *); + struct proc_dir_entry *, const char *); extern struct proc_dir_entry *proc_mknod(const char *,mode_t, struct proc_dir_entry *,kdev_t); extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *); diff --git a/include/scsi/sg.h b/include/scsi/sg.h index 283e816950bd9f..680069a4472df7 100644 --- a/include/scsi/sg.h +++ b/include/scsi/sg.h @@ -11,9 +11,18 @@ Original driver (sg.h): Version 2 and 3 extensions to driver: * Copyright (C) 1998 - 2000 Douglas Gilbert - Version: 3.1.13 (20000323) + Version: 3.1.15 (20000528) This version is for 2.3/2.4 series kernels. + Changes since 3.1.14 (20000503) + - fix aha1542 odd length buffer problem + - make multiple readers on same fd safe + Changes since 3.1.13 (20000324) + - revert change so sg_header interface doesn't send _UNKNOWN + - "discon" and "tq" in /proc/scsi/sg/devices replaced with + "bopens" and "busy"; correct duration output in procfs + - provision for SG_RESET + - lock file descriptor and request lists Changes since 3.1.12 (20000222) - make sg_header interface use SCSI_DATA_UNKNOWN - add SG_DXFER_UNKNOWN define to sg interface @@ -49,10 +58,9 @@ Map of SG verions to the Linux kernels in which they appear: 2.1.31 2.2.6 and 2.2.7 2.1.32 2.2.8 and 2.2.9 2.1.34 2.2.10 to 2.2.13 - 2.1.36 2.2.14 - 2.3.35 2.3.x development series kernels (starting 2.3.20) + 2.1.36 2.2.14 and 2.2.15 3.0.x optional version 3 sg driver for 2.2 series - 3.1.x candidate version 3 sg driver for 2.3 series + 3.1.x first appeared in lk 2.3.43 Major new features in SG 3.x driver (cf SG 2.x drivers) - SG_IO ioctl() combines function if write() and read() @@ -100,10 +108,10 @@ Major features in SG 2.x driver (cf original SG driver) The main documents are still based on 2.x versions: http://www.torque.net/sg/p/scsi-generic.txt http://www.torque.net/sg/p/scsi-generic_long.txt - The first document can also be found in the kernel source tree, probably at: - /usr/src/linux/Documentation/scsi-generic.txt . Documentation on the changes and additions in 3.x version of the sg driver can be found at: http://www.torque.net/sg/p/scsi-generic_v3.txt + This document can also be found in the kernel source tree, probably at: + /usr/src/linux/Documentation/scsi-generic.txt . Utility and test programs are also available at that web site. */ diff --git a/lib/Makefile b/lib/Makefile index f5858795438976..fb090afcd88c06 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -8,5 +8,6 @@ L_TARGET := lib.a L_OBJS := errno.o ctype.o string.o vsprintf.o brlock.o +LX_OBJS := cmdline.o include $(TOPDIR)/Rules.make diff --git a/lib/cmdline.c b/lib/cmdline.c new file mode 100644 index 00000000000000..e147bc0b1d279a --- /dev/null +++ b/lib/cmdline.c @@ -0,0 +1,117 @@ +/* + * linux/lib/cmdline.c + * Helper functions generally used for parsing kernel command line + * and module options. + * + * Code and copyrights come from init/main.c and arch/i386/kernel/setup.c. + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + * + * GNU Indent formatting options for this file: -kr -i8 -npsl -pcs + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/string.h> + + +/** + * get_option - Parse integer from an option string + * @str: option string + * @pint: (output) integer value parsed from @str + * + * Read an int from an option string; if available accept a subsequent + * comma as well. + * + * Return values: + * 0 : no int in string + * 1 : int found, no subsequent comma + * 2 : int found including a subsequent comma + */ + +int get_option (char **str, int *pint) +{ + char *cur = *str; + + if (!cur || !(*cur)) + return 0; + *pint = simple_strtol (cur, str, 0); + if (cur == *str) + return 0; + if (**str == ',') { + (*str)++; + return 2; + } + + return 1; +} + +/** + * get_options - Parse a string into a list of integers + * @str: String to be parsed + * @nints: size of integer array + * @ints: integer array + * + * This function parses a string containing a comma-separated + * list of integers. The parse halts when the array is + * full, or when no more numbers can be retrieved from the + * string. + * + * Return value is the character in the string which caused + * the parse to end (typically a null terminator, if @str is + * completely parseable). + */ + +char *get_options (char *str, int nints, int *ints) +{ + int res, i = 1; + + while (i < nints) { + res = get_option (&str, ints + i); + if (res == 0) + break; + i++; + if (res == 1) + break; + } + ints[0] = i - 1; + return (str); +} + +/** + * memparse - parse a string with mem suffixes into a number + * @ptr: Where parse begins + * @retptr: (output) Pointer to next char after parse completes + * + * Parses a string into a number. The number stored + * at @ptr is potentially suffixed with %K (for + * kilobytes, or 1024 bytes) or suffixed with %M (for + * megabytes, or 1048576 bytes). If the number is suffixed + * with K or M, then the return value is the number + * multiplied by one kilobyte, or one megabyte, respectively. + */ + +unsigned long memparse (char *ptr, char **retptr) +{ + unsigned long ret = simple_strtoul (ptr, retptr, 0); + + switch (**retptr) { + case 'M': + case 'm': + ret <<= 10; + case 'K': + case 'k': + ret <<= 10; + (*retptr)++; + default: + break; + } + return ret; +} + + +EXPORT_SYMBOL(memparse); +EXPORT_SYMBOL(get_option); +EXPORT_SYMBOL(get_options); |
