From 5aa2eae520a6f20e7892737b6df61b34fb509d55 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:34:00 -0500 Subject: [PATCH] Import 2.3.99pre6-3 --- CREDITS | 13 +- Documentation/Changes | 35 +- Documentation/Configure.help | 30 +- Documentation/networking/fore200e.txt | 45 +- Documentation/networking/tulip.txt | 4 + MAINTAINERS | 9 +- Makefile | 2 + arch/alpha/kernel/irq.c | 4 +- arch/arm/defconfig | 4 +- arch/i386/config.in | 30 +- arch/i386/defconfig | 4 +- arch/ia64/defconfig | 4 +- arch/ppc/defconfig | 4 +- arch/sparc/kernel/sun4d_smp.c | 38 +- arch/sparc/kernel/sun4m_smp.c | 25 +- arch/sparc/kernel/sys_sunos.c | 2 +- arch/sparc/kernel/systbls.S | 2 +- arch/sparc/kernel/time.c | 38 +- arch/sparc/lib/atomic.S | 6 + arch/sparc/lib/bitops.S | 6 + arch/sparc/lib/copy_user.S | 6 + arch/sparc64/defconfig | 4 +- arch/sparc64/kernel/ioctl32.c | 8 +- arch/sparc64/kernel/power.c | 5 +- arch/sparc64/kernel/sbus.c | 16 +- arch/sparc64/kernel/signal32.c | 8 +- arch/sparc64/kernel/smp.c | 35 +- arch/sparc64/kernel/sparc64_ksyms.c | 6 +- arch/sparc64/kernel/sys_sparc.c | 30 +- arch/sparc64/kernel/sys_sparc32.c | 29 +- arch/sparc64/kernel/sys_sunos32.c | 2 +- arch/sparc64/kernel/systbls.S | 10 +- arch/sparc64/kernel/time.c | 34 +- arch/sparc64/lib/blockops.S | 14 +- arch/sparc64/mm/fault.c | 5 +- arch/sparc64/mm/init.c | 223 +- arch/sparc64/solaris/misc.c | 2 +- drivers/atm/Config.in | 12 +- drivers/atm/Makefile | 56 +- drivers/atm/ambassador.c | 8 +- drivers/atm/ambassador.h | 2 +- drivers/atm/atmdev_init.c | 20 +- drivers/atm/eni.c | 190 +- drivers/atm/eni.h | 5 +- drivers/atm/fore200e.c | 80 +- drivers/atm/fore200e.h | 15 +- drivers/atm/horizon.c | 13 +- drivers/atm/uPD98402.c | 2 +- drivers/cdrom/cdrom.c | 28 +- drivers/char/sx.c | 66 +- drivers/ide/Config.in | 10 +- drivers/ide/Makefile | 4 +- drivers/ide/aec6210.c | 376 ---- drivers/ide/aec62xx.c | 553 +++++ drivers/ide/ali14xx.c | 3 +- drivers/ide/alim15x3.c | 7 +- drivers/ide/amd7409.c | 1 + drivers/ide/buddha.c | 1 + drivers/ide/cmd640.c | 3 +- drivers/ide/cmd64x.c | 7 +- drivers/ide/cy82c693.c | 4 +- drivers/ide/dtc2278.c | 1 + drivers/ide/falconide.c | 1 + drivers/ide/gayle.c | 1 + drivers/ide/ht6560b.c | 5 +- drivers/ide/icside.c | 1 + drivers/ide/ide-cd.c | 392 ++-- drivers/ide/ide-cd.h | 4 +- drivers/ide/ide-disk.c | 8 + drivers/ide/ide-dma.c | 8 +- drivers/ide/ide-floppy.c | 11 + drivers/ide/ide-pci.c | 34 +- drivers/ide/ide-pnp.c | 2 + drivers/ide/ide-probe.c | 4 + drivers/ide/ide-proc.c | 24 +- drivers/ide/ide-tape.c | 1 + drivers/ide/ide.c | 31 +- drivers/ide/macide.c | 1 + drivers/ide/ns87415.c | 1 + drivers/ide/opti621.c | 5 +- drivers/ide/pdc4030.c | 1 + drivers/ide/piix.c | 1 + drivers/ide/qd6580.c | 1 + drivers/ide/rapide.c | 1 + drivers/ide/rz1000.c | 1 + drivers/ide/umc8672.c | 1 + drivers/ide/via82cxxx.c | 270 ++- drivers/isdn/avmb1/b1pcmcia.c | 1 - drivers/isdn/avmb1/capi.c | 1 + drivers/isdn/avmb1/capifs.c | 3 - drivers/net/8139too.c | 2 +- drivers/net/Space.c | 40 + drivers/net/cs89x0.c | 82 +- drivers/net/ppp_generic.c | 36 +- drivers/net/tulip/21142.c | 11 +- drivers/net/tulip/timer.c | 15 +- drivers/net/tulip/tulip_core.c | 2 +- drivers/pci/pci.ids | 2 + drivers/sbus/char/sab82532.c | 77 +- drivers/scsi/ide-scsi.c | 1 + drivers/scsi/sd.c | 31 + drivers/sound/Makefile | 2 +- drivers/sound/sb_card.c | 118 +- drivers/video/aty128fb.c | 12 +- drivers/video/fbcon-iplan2p2.c | 3 + drivers/video/fbcon-iplan2p4.c | 3 + drivers/video/fbcon-iplan2p8.c | 3 + drivers/video/tdfxfb.c | 10 +- fs/Config.in | 2 +- fs/affs/Changes | 6 + fs/affs/file.c | 4 +- fs/devfs/base.c | 2 +- fs/partitions/acorn.c | 8 +- fs/partitions/msdos.c | 16 +- fs/stat.c | 8 +- include/asm-sparc/elf.h | 2 +- include/asm-sparc/io.h | 3 +- include/asm-sparc/namei.h | 2 +- include/asm-sparc64/delay.h | 3 +- include/asm-sparc64/elf.h | 2 +- include/asm-sparc64/io.h | 3 +- include/asm-sparc64/namei.h | 2 +- include/asm-sparc64/page.h | 14 +- include/asm-sparc64/pgalloc.h | 10 +- include/asm-sparc64/pgtable.h | 13 +- include/asm-sparc64/sab82532.h | 4 +- include/asm-sparc64/vga.h | 2 + include/linux/atmdev.h | 3 +- include/linux/hdreg.h | 2 + include/linux/hdsmart.h | 182 +- include/linux/ide.h | 12 +- include/linux/kernel.h | 6 + include/linux/mm.h | 2 + .../netfilter_ipv4/ip_conntrack_protocol.h | 8 +- include/linux/netfilter_ipv4/ipt_state.h | 3 +- include/linux/pci_ids.h | 2 + include/linux/timer.h | 6 +- include/linux/x25.h | 21 +- include/net/sock.h | 2 +- include/net/x25.h | 11 +- ipc/shm.c | 2 +- kernel/fork.c | 2 + kernel/sys.c | 2 +- kernel/sysctl.c | 6 +- net/802/tr.c | 2 +- net/atm/clip.c | 20 +- net/atm/common.c | 6 +- net/atm/common.h | 5 +- net/atm/lane_mpoa_init.c | 2 - net/atm/lec.c | 14 +- net/atm/lec.h | 1 - net/atm/mpc.c | 1988 +++++++++-------- net/atm/mpoa_caches.c | 794 +++---- net/atm/mpoa_caches.h | 52 +- net/atm/raw.c | 2 +- net/bridge/br.c | 6 +- net/core/netfilter.c | 14 +- net/core/skbuff.c | 2 +- net/core/sock.c | 4 +- net/econet/af_econet.c | 2 +- net/ipv4/arp.c | 9 +- net/ipv4/fib_rules.c | 3 +- net/ipv4/icmp.c | 11 +- net/ipv4/ip_fragment.c | 9 +- net/ipv4/ip_input.c | 12 +- net/ipv4/ipconfig.c | 27 +- net/ipv4/netfilter/ip_conntrack_core.c | 54 +- .../netfilter/ip_conntrack_proto_generic.c | 5 +- net/ipv4/netfilter/ip_conntrack_proto_icmp.c | 6 +- net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 12 +- net/ipv4/netfilter/ip_conntrack_proto_udp.c | 6 +- net/ipv4/netfilter/ip_conntrack_standalone.c | 20 +- net/ipv4/netfilter/ip_nat_standalone.c | 22 +- net/ipv4/netfilter/ip_queue.c | 2 +- net/ipv4/netfilter/ip_tables.c | 24 +- net/ipv4/netfilter/ipchains_core.c | 14 +- net/ipv4/netfilter/ipfwadm_core.c | 5 +- net/ipv4/netfilter/ipt_LOG.c | 15 +- net/ipv4/route.c | 43 +- net/ipv4/tcp.c | 10 +- net/ipv4/tcp_ipv4.c | 7 +- net/sched/sch_gred.c | 2 +- net/sunrpc/pmap_clnt.c | 4 +- net/sunrpc/svcsock.c | 12 +- net/x25/af_x25.c | 6 +- net/x25/x25_facilities.c | 27 +- net/x25/x25_in.c | 10 +- net/x25/x25_link.c | 11 +- net/x25/x25_subr.c | 10 +- 189 files changed, 3985 insertions(+), 3179 deletions(-) delete mode 100644 drivers/ide/aec6210.c create mode 100644 drivers/ide/aec62xx.c diff --git a/CREDITS b/CREDITS index d7b04cbde9db..6fde4afc1d2d 100644 --- a/CREDITS +++ b/CREDITS @@ -941,17 +941,13 @@ E: ajh@primag.co.uk D: Selection mechanism N: Andre Hedrick +E: andre@linux-ide.org E: andre@suse.com D: Random SMP kernel hacker... D: Uniform Multi-Platform E-IDE driver -D: AEC6210UF Ultra33 -D: Aladdin 1533/1543(C) chipset -D: Active-Chipset maddness.......... -D: HighPoint HPT343/5 Ultra/33 & HPT366 Ultra/66 chipsets -D: Intel PIIX chipset -D: Promise PDC20246/20247 & PDC20262 chipsets -D: SiS5513 Ultra/66/33 chipsets -D: VIA 82C586/596/686 chipsets +D: Active-ATA-Chipset maddness.......... +D: Ultra DMA 66/33 +D: ATA-Smart Kernel Daemon S: 580 Second Street, Suite 2 S: Oakland, CA S: USA @@ -1173,6 +1169,7 @@ E: djones2@glam.ac.uk W: http://linux.powertweak.com D: Moved PCI bridge tuning to userspace (Powertweak). D: Centaur/IDT Winchip/Winchip 2 tweaks. +D: AFFS fixes for 2.3.x D: Misc clean ups and other random hacking. S: 28, Laura Street, S: Treforest, Pontypridd, diff --git a/Documentation/Changes b/Documentation/Changes index ce2c77a9be09..f5c4d516f410 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -62,7 +62,7 @@ running, the suggested command should tell you. - Bash 1.14.7 ; bash -version - Ncpfs 2.2.0 ; ncpmount -v - Pcmcia-cs 3.1.2 ; cardmgr -V -- PPP 2.3.11 ; pppd --version +- PPP 2.4.0b1 ; pppd --version - Util-linux 2.9i ; chsh -v - isdn4k-utils v3.1beta7 ; isdnctrl 2>&1|grep version @@ -391,22 +391,33 @@ support utils to the latest release of pcmcia-cs. PPP === - Due to changes in the PPP driver and routing code, those of you + The PPP driver has been restructured to support multilink and +to enable it to operate over diverse kinds of media. Those of you using PPP networking will need to upgrade your pppd to at least -version 2.3.11. See ftp://cs.anu.edu.au/pub/software/ppp/ for newest -versions. +version 2.4.0b1. See ftp://linuxcare.com.au/pub/ppp/ for the latest +version. - You must make sure that the special device file /dev/ppp exists. -It can be made by executing this command as root: + If you are not using devfs, you must make sure that the special +device file /dev/ppp exists. It can be made by executing this command +as root: mknod /dev/ppp c 108 0 If you have built ppp support as modules, you should put the lines -below in your /etc/modules.conf file. I assume you want asynchronous -ppp; replace ppp_async by ppp_synctty if you want synchronous ppp. +below in your /etc/modules.conf file. - alias char-major-108 ppp_generic - alias tty-ldisc-3 ppp_async + alias char-major-108 ppp_generic + alias /dev/ppp ppp_generic + alias tty-ldisc-3 ppp_async + alias tty-ldisc-14 ppp_synctty + alias ppp-compress-21 bsd_comp + alias ppp-compress-24 ppp_deflate + alias ppp-compress-26 ppp_deflate + +If you are using devfsd and you have ppp_generic as a module, put the +following line in your /etc/devfsd.conf: + + LOOKUP ppp MODLOAD iBCS ==== @@ -723,8 +734,8 @@ ftp://metalab.unc.edu/pub/Linux/system/serial/setserial-2.15.tar.gz PPP === -The 2.3.11 release: -ftp://cs.anu.edu.au/pub/software/ppp/ppp-2.3.11.tar.gz +The 2.4.0b1 release: +ftp://linuxcare.com.au/pub/ppp/ppp-2.4.0b1.tar.gz IP Chains ========= diff --git a/Documentation/Configure.help b/Documentation/Configure.help index fd656f58bcf7..4d2034c7672a 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -718,21 +718,25 @@ CONFIG_BLK_DEV_3W_XXXX_RAID Please read the comments at the top of drivers/scsi/3w-xxxx.c -AEC6210 chipset support -CONFIG_BLK_DEV_AEC6210 +AEC62XX chipset support +CONFIG_BLK_DEV_AEC62XX This driver adds up to 4 more EIDE devices sharing a single interrupt. This add-on card is a bootable PCI UDMA controller. In order to get this card to initialize correctly in some cases, you should say Y here, and preferably also to "Use DMA by default when available". - Please read the comments at the top of drivers/ide/aec6210.c If - you say Y here, then say Y to "Use DMA by default when available" as + The ATP850U/UF is an UltraDMA 33 chipset base. + The ATP860 is an UltraDMA 66 chipset base. + The ATP860M(acintosh) version is an UltraDMA 66 chipset base. + + Please read the comments at the top of drivers/ide/aec62xx.c + If you say Y here, then say Y to "Use DMA by default when available" as well. -AEC6210 Tuning support (WIP) -CONFIG_AEC6210_TUNING - Please read the comments at the top of drivers/ide/aec6210.c +AEC62XX Tuning support (WIP) +CONFIG_AEC62XX_TUNING + Please read the comments at the top of drivers/ide/aec62xx.c If unsure, say N. ALI M15x3 chipset support @@ -972,6 +976,12 @@ CONFIG_BLK_DEV_VIA82CXXX If unsure, say N. +VIA82CXXX Tuning support (WIP) +CONFIG_VIA82CXXX_TUNING + Please read the comments at the top of drivers/ide/via82cxxx.c + + If unsure, say N. + Other IDE chipset support CONFIG_IDE_CHIPSETS Say Y here if you want to include enhanced support for various IDE @@ -4844,12 +4854,16 @@ CONFIG_PHONE_IXJ say N here. FORE Systems 200E-series -CONFIG_ATM_FORE200E +CONFIG_ATM_FORE200E_MAYBE This is a driver for the FORE Systems 200E-series ATM adapter cards. It simultaneously supports PCA-200E and SBA-200E models on PCI and SBUS hosts. Say Y (or M to compile as a module named fore_200e.o) here if you have one of these ATM adapters. + Note that the driver will actually be compiled only if you + additionally enable the support for PCA-200E and/or SBA-200E + cards. + See the file Documentation/networking/fore200e.txt for further details. diff --git a/Documentation/networking/fore200e.txt b/Documentation/networking/fore200e.txt index 13ee5327eca6..b1f337f0f4ca 100644 --- a/Documentation/networking/fore200e.txt +++ b/Documentation/networking/fore200e.txt @@ -1,6 +1,26 @@ -Fore PCA-200E/SBA-200E ATM NIC Firmware Copyright Notice --------------------------------------------------------- +FORE Systems PCA-200E/SBA-200E ATM NIC driver +--------------------------------------------- + +This driver adds support for the FORE Systems 200E-series ATM adapters +to the Linux operating system. It is based on the earlier PCA-200E driver +written by Uwe Dannowski. + +The driver simultaneously supports PCA-200E and SBA-200E adapters on +i386, alpha (untested), powerpc, sparc and sparc64 archs. + +The intent is to enable the use of different models of FORE adapters at the +same time, by hosts that have several bus interfaces (such as PCI+SBUS, +PCI+MCA or PCI+EISA). + +Only PCI and SBUS devices are currently supported by the driver, but support +for other bus interfaces such as EISA should not be too hard to add (this may +be more tricky for the MCA bus, though, as FORE made some MCA-specific +modifications to the adapter's AALI interface). + + +Firmware Copyright Notice +------------------------- Please read the fore200e_firmware_copyright file present in the linux/drivers/atm directory for details and restrictions. @@ -13,26 +33,22 @@ The FORE Systems 200E-series driver is shipped with firmware data being uploaded to the ATM adapters at system boot time or at module loading time. The supplied firmware images should work with all adapters. -However, if you encounter problems (firmware doesn't start or the driver -is unable to read PROM data), you may consider trying another firmware +However, if you encounter problems (the firmware doesn't start or the driver +is unable to read the PROM data), you may consider trying another firmware version. Alternative binary firmware images can be found somewhere on the -ForeThough CD-ROM supplied with your adapter by FORE Systems. +ForeThought CD-ROM supplied with your adapter by FORE Systems. You can also get the latest firmware images from FORE Systems at http://www.fore.com. Register TACTics Online and go to the 'software updates' pages. The firmware binaries are part of -the various ForeThough software distributions. +the various ForeThought software distributions. Notice that different versions of the PCA-200E firmware exist, depending on the endianess of the host architecture. The driver is shipped with both little and big endian PCA firmware images. Name and location of the new firmware images can be set at kernel -configuration time. - - -Driver Rebuilding ------------------ +configuration time: 1. Copy the new firmware binary files (with .bin, .bin1 or .bin2 suffix) to some directory, such as linux/drivers/atm. @@ -40,11 +56,7 @@ Driver Rebuilding 2. Reconfigure your kernel to set the new firmware name and location. Expected pathnames are absolute or relative to the drivers/atm directory. -3. Delete the files drivers/atm/fore200e_pca_fw.[co] and/or fore200e_sba_fw.[co] - to ensure that the new firmware will be used when rebuilding the kernel or - the module. - -4. Rebuild and re-install your kernel or your module. +3. Rebuild and re-install your kernel or your module. Feedback @@ -52,4 +64,3 @@ Feedback Feedback is welcome. Please send success stories/bug reports/ patches/improvement/comments/flames to . - diff --git a/Documentation/networking/tulip.txt b/Documentation/networking/tulip.txt index f4b553705f0f..be41c4031198 100644 --- a/Documentation/networking/tulip.txt +++ b/Documentation/networking/tulip.txt @@ -142,6 +142,10 @@ tulip_core.c - Driver core (a.k.a. where "everything else" goes) Version history =============== +0.9.4.3 (April 14, 2000): +* mod_timer fix (Hal Murray) +* PNIC2 resusitation (Chris Smith) + 0.9.4.2 (March 21, 2000): * Fix 21041 CSR7, CSR13/14/15 handling * Merge some PCI ids from tulip 0.91x diff --git a/MAINTAINERS b/MAINTAINERS index ed1b09e33b80..43e375cf781f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -474,9 +474,11 @@ S: Supported IDE DRIVER [GENERAL] P: Andre Hedrick +M: andre@linux-ide.org M: andre@suse.com L: linux-kernel@vger.rutgers.edu -W: http://linux.kernel.org/pub/linux/kernel/people/hedrick/ +W: http://www.kernel.org/pub/linux/kernel/people/hedrick/ +W: http://www.linux-ide.org/ S: Supported IDE/ATAPI CDROM DRIVER @@ -611,9 +613,8 @@ S: Maintained MAESTRO PCI SOUND DRIVER P: Zach Brown -M: zab@redhat.com -W: http://people.redhat.com/zab/maestro/ -S: Supported +M: zab@zabbo.net +S: Odd Fixes M68K P: Jes Sorensen diff --git a/Makefile b/Makefile index 790887c5a5ee..0fcc720279e4 100644 --- a/Makefile +++ b/Makefile @@ -370,6 +370,7 @@ clean: archclean rm -f drivers/char/conmakehash rm -f drivers/pci/devlist.h drivers/pci/classlist.h drivers/pci/gen-devlist rm -f drivers/sound/bin2hex drivers/sound/hex2hex + rm -f drivers/atm/fore200e_mkfirm drivers/atm/{pca,sba}*{.bin,.bin1,.bin2} rm -f net/khttpd/make_times_h rm -f net/khttpd/times.h rm -f submenu* @@ -388,6 +389,7 @@ mrproper: clean archmrproper rm -f drivers/sound/msndperm.c rm -f drivers/sound/pndsperm.c rm -f drivers/sound/pndspini.c + rm -f drivers/atm/fore200e_*_fw.c drivers/atm/.fore200e_*.fw rm -f .version .config* config.in config.old rm -f scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp rm -f scripts/lxdialog/*.o scripts/lxdialog/lxdialog diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 1f454cf48cf6..e47fcd3caa7e 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -373,7 +373,7 @@ register_irq_proc (unsigned int irq) #ifdef CONFIG_SMP /* create /proc/irq/1234/smp_affinity */ - entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]); + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); entry->nlink = 1; entry->data = (void *)(long)irq; @@ -397,7 +397,7 @@ init_irq_proc (void) #ifdef CONFIG_SMP /* create /proc/irq/prof_cpu_mask */ - entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir); + entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); entry->nlink = 1; entry->data = (void *)&prof_cpu_mask; diff --git a/arch/arm/defconfig b/arch/arm/defconfig index c5b38947644e..077eef8b3f5d 100644 --- a/arch/arm/defconfig +++ b/arch/arm/defconfig @@ -536,8 +536,8 @@ CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC6210 is not set -# CONFIG_AEC6210_TUNING is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set diff --git a/arch/i386/config.in b/arch/i386/config.in index f652df3331df..fbf8dc50073f 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -28,45 +28,51 @@ choice 'Processor family' \ # # Define implied options from the CPU selection here # -if [ "$CONFIG_M386" != "y" ]; then +if [ "$CONFIG_M386" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 16 +else define_bool CONFIG_X86_WP_WORKS_OK y define_bool CONFIG_X86_INVLPG y define_bool CONFIG_X86_CMPXCHG y define_bool CONFIG_X86_BSWAP y define_bool CONFIG_X86_POPAD_OK y fi -if [ "$CONFIG_M386" = "y" -o "$CONFIG_M486" = "y" ]; then - define_int CONFIG_X86_L1_CACHE_BYTES 16 -else - define_int CONFIG_X86_L1_CACHE_BYTES 32 -fi -if [ "$CONFIG_M486" = "y" -o "$CONFIG_M586" = "y" ]; then +if [ "$CONFIG_M486" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 16 define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_ALIGNMENT_16 y fi -if [ "$CONFIG_M586TSC" = "y" ]; then +if [ "$CONFIG_M586" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 32 define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_ALIGNMENT_16 y - define_bool CONFIG_X86_TSC y fi -if [ "$CONFIG_MK6" = "y" ]; then +if [ "$CONFIG_M586TSC" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_bool CONFIG_X86_USE_STRING_486 y define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_TSC y - define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi if [ "$CONFIG_M686" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 32 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y fi +if [ "$CONFIG_MK6" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 32 + define_bool CONFIG_X86_ALIGNMENT_16 y + define_bool CONFIG_X86_TSC y + define_bool CONFIG_X86_USE_PPRO_CHECKSUM y +fi if [ "$CONFIG_MK7" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_BYTES 64 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_USE_3DNOW y define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y - define_int CONFIG_X86_L1_CACHE_BYTES 64 fi tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 9fa79dff9934..26f859887dab 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -190,8 +190,8 @@ CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_IDEDMA_PCI_EXPERIMENTAL is not set # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC6210 is not set -# CONFIG_AEC6210_TUNING is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig index 12854f121721..00a0e05b7c03 100644 --- a/arch/ia64/defconfig +++ b/arch/ia64/defconfig @@ -115,8 +115,8 @@ CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC6210 is not set -# CONFIG_AEC6210_TUNING is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 8717bc055f8f..229768b9bdc0 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -184,8 +184,8 @@ CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC6210 is not set -# CONFIG_AEC6210_TUNING is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index b589712aaee1..5cd8f7235983 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -443,38 +443,14 @@ void smp4d_message_pass(int target, int msg, unsigned long data, int wait) panic("Bogon SMP message pass."); } -/* Protects counters touched during level14 ticker */ -static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED; - -#ifdef CONFIG_PROFILE - -/* 32-bit Sparc specific profiling function. */ -static inline void sparc_do_profile(unsigned long pc) -{ - if(prof_buffer && current->pid) { - extern int _stext; - - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - - spin_lock(&ticker_lock); - if(pc < prof_len) - prof_buffer[pc]++; - else - prof_buffer[prof_len - 1]++; - spin_unlock(&ticker_lock); - } -} - -#endif - extern unsigned int prof_multiplier[NR_CPUS]; extern unsigned int prof_counter[NR_CPUS]; extern void update_one_process(struct task_struct *p, unsigned long ticks, unsigned long user, unsigned long system, int cpu); - + +extern void sparc_do_profile(unsigned long pc, unsigned long o7); void smp4d_percpu_timer_interrupt(struct pt_regs *regs) { @@ -493,12 +469,13 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) show_leds(cpu); } -#ifdef CONFIG_PROFILE if(!user_mode(regs)) - sparc_do_profile(regs->pc); -#endif + sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]); + if(!--prof_counter[cpu]) { int user = user_mode(regs); + + irq_enter(cpu, 0); if(current->pid) { update_one_process(current, 1, user, !user, cpu); @@ -507,7 +484,6 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) current->need_resched = 1; } - spin_lock(&ticker_lock); if(user) { if(current->priority < DEF_PRIORITY) { kstat.cpu_nice++; @@ -520,9 +496,9 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) kstat.cpu_system++; kstat.per_cpu_system[cpu]++; } - spin_unlock(&ticker_lock); } prof_counter[cpu] = prof_multiplier[cpu]; + irq_exit(cpu, 0); } } diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 36c3d3c259d9..f0e046db367c 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -440,27 +440,6 @@ void smp4m_cross_call_irq(void) ccall_info.processors_out[i] = 1; } -/* Protects counters touched during level14 ticker */ -static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED; - -/* 32-bit Sparc specific profiling function. */ -static inline void sparc_do_profile(unsigned long pc) -{ - if(prof_buffer && current->pid) { - extern int _stext; - - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - - spin_lock(&ticker_lock); - if(pc < prof_len) - prof_buffer[pc]++; - else - prof_buffer[prof_len - 1]++; - spin_unlock(&ticker_lock); - } -} - extern unsigned int prof_multiplier[NR_CPUS]; extern unsigned int prof_counter[NR_CPUS]; @@ -468,6 +447,8 @@ extern void update_one_process(struct task_struct *p, unsigned long ticks, unsigned long user, unsigned long system, int cpu); +extern void sparc_do_profile(unsigned long pc, unsigned long o7); + void smp4m_percpu_timer_interrupt(struct pt_regs *regs) { int cpu = smp_processor_id(); @@ -475,7 +456,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs) clear_profile_irq(mid_xlate[cpu]); if(!user_mode(regs)) - sparc_do_profile(regs->pc); + sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]); if(!--prof_counter[cpu]) { int user = user_mode(regs); diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 675ac5890d4e..dfb28aab1c90 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos.c,v 1.120 2000/04/08 08:32:14 davem Exp $ +/* $Id: sys_sunos.c,v 1.121 2000/04/13 00:55:48 davem Exp $ * sys_sunos.c: SunOS specific syscall compatibility support. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index de3e68560612..5bb551a46ba2 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.96 2000/03/15 02:43:32 davem Exp $ +/* $Id: systbls.S,v 1.97 2000/04/13 00:55:49 davem Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 5a03e646b032..68105c4216a0 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.53 2000/02/09 21:11:04 davem Exp $ +/* $Id: time.c,v 1.54 2000/04/13 08:14:30 anton Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -70,6 +70,37 @@ struct intersil *intersil_clock; #endif +static spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED; + +/* 32-bit Sparc specific profiling function. */ +void sparc_do_profile(unsigned long pc, unsigned long o7) +{ + if(prof_buffer && current->pid) { + extern int _stext; + extern int __copy_user_begin, __copy_user_end; + extern int __atomic_begin, __atomic_end; + extern int __bitops_begin, __bitops_end; + + if ((pc >= (unsigned long) &__copy_user_begin && + pc < (unsigned long) &__copy_user_end) || + (pc >= (unsigned long) &__atomic_begin && + pc < (unsigned long) &__atomic_end) || + (pc >= (unsigned long) &__bitops_begin && + pc < (unsigned long) &__bitops_end)) + pc = o7; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + + spin_lock(&ticker_lock); + if(pc < prof_len) + prof_buffer[pc]++; + else + prof_buffer[prof_len - 1]++; + spin_unlock(&ticker_lock); + } +} + __volatile__ unsigned int *master_l10_counter; __volatile__ unsigned int *master_l10_limit; @@ -82,6 +113,11 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) /* last time the cmos clock got updated */ static long last_rtc_update=0; +#ifndef __SMP__ + if(!user_mode(regs)) + sparc_do_profile(regs->pc, regs->u_regs[UREG_RETPC]); +#endif + #ifdef CONFIG_SUN4 if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) || (idprom->id_machtype == (SM_SUN4 | SM_4_110))) { diff --git a/arch/sparc/lib/atomic.S b/arch/sparc/lib/atomic.S index c57e61574c77..76c4d8164cfe 100644 --- a/arch/sparc/lib/atomic.S +++ b/arch/sparc/lib/atomic.S @@ -10,6 +10,9 @@ .text .align 4 + .globl __atomic_begin +__atomic_begin: + #ifndef __SMP__ .globl ___xchg32_sun4c ___xchg32_sun4c: @@ -92,3 +95,6 @@ ___atomic_sub: nop; nop; nop; ! Let the bits set jmpl %o7, %g0 ! NOTE: not + 8, see callers in atomic.h mov %g4, %o7 ! Restore %o7 + + .globl __atomic_end +__atomic_end: diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S index ea9ed5a6cf8c..10fc427389ab 100644 --- a/arch/sparc/lib/bitops.S +++ b/arch/sparc/lib/bitops.S @@ -10,6 +10,9 @@ .text .align 4 + .globl __bitops_begin +__bitops_begin: + /* Take bits in %g2 and set them in word at %g1, * return whether bits were set in original value * in %g2. %g4 holds value to restore into %o7 @@ -159,3 +162,6 @@ ___clear_le_bit: nop; nop; nop jmpl %o7, %g0 mov %g4, %o7 + + .globl __bitops_end +__bitops_end: diff --git a/arch/sparc/lib/copy_user.S b/arch/sparc/lib/copy_user.S index 97c55f02d733..239ec762ddfc 100644 --- a/arch/sparc/lib/copy_user.S +++ b/arch/sparc/lib/copy_user.S @@ -112,6 +112,9 @@ .text .align 4 + .globl __copy_user_begin +__copy_user_begin: + .globl C_LABEL(__copy_user) dword_align: andcc %o1, 1, %g0 @@ -482,3 +485,6 @@ fixupretl: sub %o0, %g3, %o0 ba fixupretl add %g3, %o2, %g3 + + .globl __copy_user_end +__copy_user_end: diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 3ceeb634b255..ace71569b767 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -223,8 +223,8 @@ CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC6210 is not set -# CONFIG_AEC6210_TUNING is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index ef07fca85ebc..c7e2fecfbe70 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.87 2000/03/30 02:09:07 davem Exp $ +/* $Id: ioctl32.c,v 1.88 2000/04/14 10:10:34 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -1816,6 +1816,7 @@ struct atm_iobuf32 { #define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32) #define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32) #define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32) +#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32) static struct { unsigned int cmd32; @@ -1836,7 +1837,8 @@ static struct { { ATM_GETSTAT32, ATM_GETSTAT }, { ATM_GETSTATZ32, ATM_GETSTATZ }, { ATM_GETLOOP32, ATM_GETLOOP }, - { ATM_SETLOOP32, ATM_SETLOOP } + { ATM_SETLOOP32, ATM_SETLOOP }, + { ATM_QUERYLOOP32, ATM_QUERYLOOP } }; #define NR_ATM_IOCTL (sizeof(atm_ioctl_map)/sizeof(atm_ioctl_map[0])) @@ -1996,6 +1998,7 @@ static int do_atm_ioctl(unsigned int fd, unsigned int cmd32, unsigned long arg) case ATM_GETSTATZ: case ATM_GETLOOP: case ATM_SETLOOP: + case ATM_QUERYLOOP: return do_atmif_sioc(fd, cmd, arg); } @@ -3110,6 +3113,7 @@ HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl) HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl) HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl) HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl) +HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl) HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl) HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl) HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl) diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index e612d0200122..ccf0c03bf35a 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -1,4 +1,4 @@ -/* $Id: power.c,v 1.5 1999/12/19 23:28:00 davem Exp $ +/* $Id: power.c,v 1.6 2000/04/13 00:59:59 davem Exp $ * power.c: Power management driver. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -55,8 +55,7 @@ static int powerd(void *__unused) static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL }; char *argv[] = { "/usr/bin/shutdown", "-h", "now", NULL }; - current->session = 1; - current->pgrp = 1; + daemonize(); sprintf(current->comm, "powerd"); again: diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index c9a0d4a59b61..602ee9ca2b3c 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c @@ -1,4 +1,4 @@ -/* $Id: sbus.c,v 1.10 2000/03/10 07:52:08 davem Exp $ +/* $Id: sbus.c,v 1.11 2000/04/14 09:13:04 davem Exp $ * sbus.c: UltraSparc SBUS controller support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -315,7 +315,7 @@ void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_add dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int dir) { struct sbus_iommu *iommu = sdev->bus->iommu; - unsigned long npages, phys_base, flags; + unsigned long npages, pbase, flags; iopte_t *iopte; u32 dma_base, offset; unsigned long iopte_bits; @@ -323,10 +323,10 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int di if (dir == SBUS_DMA_NONE) BUG(); - phys_base = (unsigned long) ptr; - offset = (u32) (phys_base & ~PAGE_MASK); - size = (PAGE_ALIGN(phys_base + size) - (phys_base & PAGE_MASK)); - phys_base = (unsigned long) __pa(phys_base & PAGE_MASK); + pbase = (unsigned long) ptr; + offset = (u32) (pbase & ~PAGE_MASK); + size = (PAGE_ALIGN(pbase + size) - (pbase & PAGE_MASK)); + pbase = (unsigned long) __pa(pbase & PAGE_MASK); spin_lock_irqsave(&iommu->lock, flags); npages = size >> PAGE_SHIFT; @@ -337,8 +337,8 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t size, int di if (dir != SBUS_DMA_TODEVICE) iopte_bits |= IOPTE_WRITE; while (npages--) { - *iopte++ = __iopte(iopte_bits | (phys_base & IOPTE_PAGE)); - phys_base += PAGE_SIZE; + *iopte++ = __iopte(iopte_bits | (pbase & IOPTE_PAGE)); + pbase += PAGE_SIZE; } npages = size >> PAGE_SHIFT; spin_unlock_irqrestore(&iommu->lock, flags); diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 273643db6bf1..1f5c03716102 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1,4 +1,4 @@ -/* $Id: signal32.c,v 1.61 2000/04/08 02:11:46 davem Exp $ +/* $Id: signal32.c,v 1.62 2000/04/12 08:10:19 davem Exp $ * arch/sparc64/kernel/signal32.c * * Copyright (C) 1991, 1992 Linus Torvalds @@ -750,8 +750,7 @@ static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *reg goto sigsegv; if(pte_present(*ptep)) { - unsigned long page = (unsigned long) - __va(pte_pagenr(*ptep) << PAGE_SHIFT); + unsigned long page = page_address(pte_page(*ptep)); __asm__ __volatile__(" membar #StoreStore @@ -1176,8 +1175,7 @@ static inline void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs goto sigsegv; if(pte_present(*ptep)) { - unsigned long page = (unsigned long) - __va(pte_pagenr(*ptep) << PAGE_SHIFT); + unsigned long page = page_address(pte_page(*ptep)); __asm__ __volatile__(" membar #StoreStore diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index e9a180d2a340..9964a78268e2 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -627,33 +627,7 @@ void smp_promstop_others(void) smp_cross_call(&xcall_promstop, 0, 0, 0); } -static inline void sparc64_do_profile(unsigned long pc, unsigned long o7) -{ - if (prof_buffer && current->pid) { - extern int _stext; - extern int rwlock_impl_begin, rwlock_impl_end; - extern int atomic_impl_begin, atomic_impl_end; - extern int __memcpy_begin, __memcpy_end; - extern int __bitops_begin, __bitops_end; - - if ((pc >= (unsigned long) &atomic_impl_begin && - pc < (unsigned long) &atomic_impl_end) || - (pc >= (unsigned long) &rwlock_impl_begin && - pc < (unsigned long) &rwlock_impl_end) || - (pc >= (unsigned long) &__memcpy_begin && - pc < (unsigned long) &__memcpy_end) || - (pc >= (unsigned long) &__bitops_begin && - pc < (unsigned long) &__bitops_end)) - pc = o7; - - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - - if(pc >= prof_len) - pc = prof_len - 1; - atomic_inc((atomic_t *)&prof_buffer[pc]); - } -} +extern void sparc64_do_profile(unsigned long pc, unsigned long o7); static unsigned long current_tick_offset; @@ -862,7 +836,7 @@ cycles_t cacheflush_time; static void __init smp_tune_scheduling (void) { - unsigned long flush_base, flags, *p; + unsigned long orig_flush_base, flush_base, flags, *p; unsigned int ecache_size, order; cycles_t tick1, tick2, raw; @@ -881,7 +855,8 @@ static void __init smp_tune_scheduling (void) "ecache-size", (512 * 1024)); if (ecache_size > (4 * 1024 * 1024)) ecache_size = (4 * 1024 * 1024); - flush_base = __get_free_pages(GFP_KERNEL, order = get_order(ecache_size)); + orig_flush_base = flush_base = + __get_free_pages(GFP_KERNEL, order = get_order(ecache_size)); if (flush_base != 0UL) { __save_and_cli(flags); @@ -923,7 +898,7 @@ static void __init smp_tune_scheduling (void) */ cacheflush_time = (raw - (raw >> 2)); - free_pages(flush_base, order); + free_pages(orig_flush_base, order); } else { cacheflush_time = ((ecache_size << 2) + (ecache_size << 1)); diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index fc7a8cfe57fd..9a1158fcdcc4 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.80 2000/03/27 10:38:47 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.81 2000/04/13 04:45:58 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -297,8 +297,8 @@ EXPORT_SYMBOL(move_addr_to_user); /* Special internal versions of library functions. */ EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memset); -EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(copy_page); +EXPORT_SYMBOL(_clear_page); +EXPORT_SYMBOL(_copy_page); EXPORT_SYMBOL(clear_user_page); EXPORT_SYMBOL(copy_user_page); EXPORT_SYMBOL(__bzero); diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 82aedbb08102..067dac553fc0 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.37 2000/03/17 05:48:46 anton Exp $ +/* $Id: sys_sparc.c,v 1.38 2000/04/13 07:30:34 jj Exp $ * linux/arch/sparc64/kernel/sys_sparc.c * * This file contains various random system calls that @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -182,6 +183,33 @@ out: return err; } +extern asmlinkage int sys_newuname(struct new_utsname * name); + +asmlinkage int sparc64_newuname(struct new_utsname * name) +{ + int ret = sys_newuname(name); + + if (current->personality == PER_LINUX32 && !ret) { + ret = copy_to_user(name->machine, "sparc\0\0", 8); + } + return ret; +} + +extern asmlinkage long sys_personality(unsigned long); + +asmlinkage int sparc64_personality(unsigned long personality) +{ + int ret; + lock_kernel(); + if (current->personality == PER_LINUX32 && personality == PER_LINUX) + personality = PER_LINUX32; + ret = sys_personality(personality); + unlock_kernel(); + if (ret == PER_LINUX32) + ret = PER_LINUX; + return ret; +} + /* Linux version of mmap */ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 06258d9b27b8..7bb75f4aedda 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc32.c,v 1.144 2000/04/08 02:11:47 davem Exp $ +/* $Id: sys_sparc32.c,v 1.145 2000/04/13 07:30:34 jj Exp $ * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -3980,18 +3980,6 @@ asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5) } -extern asmlinkage int sys_newuname(struct new_utsname * name); - -asmlinkage int sys32_newuname(struct new_utsname * name) -{ - int ret = sys_newuname(name); - - if (current->personality == PER_LINUX32 && !ret) { - ret = copy_to_user(name->machine, "sparc\0\0", 8); - } - return ret; -} - extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf, size_t count, loff_t pos); @@ -4013,21 +4001,6 @@ asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf, } -extern asmlinkage long sys_personality(unsigned long); - -asmlinkage int sys32_personality(unsigned long personality) -{ - int ret; - lock_kernel(); - if (current->personality == PER_LINUX32 && personality == PER_LINUX) - personality = PER_LINUX32; - ret = sys_personality(personality); - unlock_kernel(); - if (ret == PER_LINUX32) - ret = PER_LINUX; - return ret; -} - extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count); asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count) diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 7b44226da1a8..9c8b4fbe1d9b 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.44 2000/04/08 02:11:50 davem Exp $ +/* $Id: sys_sunos32.c,v 1.45 2000/04/13 00:55:49 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index d86649bf76e8..eb02486f5a52 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.71 2000/03/15 02:43:36 davem Exp $ +/* $Id: systbls.S,v 1.72 2000/04/13 07:30:34 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -56,8 +56,8 @@ sys_call_table32: /*170*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getdents .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*180*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_sigpending, sys32_query_module - .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_newuname -/*190*/ .word sys32_init_module, sys32_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall + .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname +/*190*/ .word sys32_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask /*200*/ .word sys_ssetmask, sys_sigsuspend, sys32_newlstat, sys_uselib, old32_readdir .word sys_nis_syscall, sys32_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall @@ -115,8 +115,8 @@ sys_call_table: /*170*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getdents .word sys_setsid, sys_fchdir, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*180*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_query_module - .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_newuname -/*190*/ .word sys_init_module, sys_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall + .word sys_setpgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sparc64_newuname +/*190*/ .word sys_init_module, sparc64_personality, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall .word sys_nis_syscall, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall .word sys_nis_syscall, sys_socketcall, sys_syslog, sys_nis_syscall, sys_nis_syscall diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index e599b48cbbd6..a955e75df3bb 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.24 2000/03/02 02:00:25 davem Exp $ +/* $Id: time.c,v 1.25 2000/04/13 05:29:44 davem Exp $ * time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -67,6 +67,34 @@ static __inline__ void timer_check_rtc(void) } } +void sparc64_do_profile(unsigned long pc, unsigned long o7) +{ + if (prof_buffer && current->pid) { + extern int _stext; + extern int rwlock_impl_begin, rwlock_impl_end; + extern int atomic_impl_begin, atomic_impl_end; + extern int __memcpy_begin, __memcpy_end; + extern int __bitops_begin, __bitops_end; + + if ((pc >= (unsigned long) &atomic_impl_begin && + pc < (unsigned long) &atomic_impl_end) || + (pc >= (unsigned long) &rwlock_impl_begin && + pc < (unsigned long) &rwlock_impl_end) || + (pc >= (unsigned long) &__memcpy_begin && + pc < (unsigned long) &__memcpy_end) || + (pc >= (unsigned long) &__bitops_begin && + pc < (unsigned long) &__bitops_end)) + pc = o7; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + + if(pc >= prof_len) + pc = prof_len - 1; + atomic_inc((atomic_t *)&prof_buffer[pc]); + } +} + static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) { unsigned long ticks, pstate; @@ -74,6 +102,10 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) write_lock(&xtime_lock); do { +#ifndef __SMP__ + if ((regs->tstate & TSTATE_PRIV) != 0) + sparc64_do_profile(regs->tpc, regs->u_regs[UREG_RETPC]); +#endif do_timer(regs); /* Guarentee that the following sequences execute diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S index 9c6a8beba3fa..9668f86d8bc5 100644 --- a/arch/sparc64/lib/blockops.S +++ b/arch/sparc64/lib/blockops.S @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.24 2000/03/27 10:38:41 davem Exp $ +/* $Id: blockops.S,v 1.25 2000/04/13 04:45:58 davem Exp $ * blockops.S: UltraSparc block zero optimized routines. * * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com) @@ -26,9 +26,9 @@ .text .align 32 - .globl copy_page - .type copy_page,@function -copy_page: /* %o0=dest, %o1=src */ + .globl _copy_page + .type _copy_page,@function +_copy_page: /* %o0=dest, %o1=src */ VISEntry membar #LoadStore | #StoreStore | #StoreLoad ldda [%o1] ASI_BLK_P, %f0 @@ -205,9 +205,9 @@ copy_page_using_blkcommit: stda %f16, [%o0] ASI_BLK_COMMIT_P .align 32 - .globl clear_page - .type clear_page,@function -clear_page: /* %o0=dest */ + .globl _clear_page + .type _clear_page,@function +_clear_page: /* %o0=dest */ VISEntryHalf ba,pt %xcc, clear_page_common clr %o4 diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index 0d8152887dce..a3d46e027722 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.45 2000/03/27 10:38:51 davem Exp $ +/* $Id: fault.c,v 1.46 2000/04/12 08:10:23 davem Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -110,7 +110,8 @@ static unsigned int get_user_insn(unsigned long tpc) if(!pte_present(pte)) goto out; - pa = (pte_pagenr(pte) << PAGE_SHIFT) + (tpc & ~PAGE_MASK); + pa = phys_base + (pte_pagenr(pte) << PAGE_SHIFT); + pa += (tpc & ~PAGE_MASK); /* Use phys bypass so we don't pollute dtlb/dcache. */ __asm__ __volatile__("lduwa [%1] %2, %0" diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 1d2049b5f9ff..63818e309ccb 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.149 2000/03/15 14:42:58 jj Exp $ +/* $Id: init.c,v 1.150 2000/04/12 08:10:22 davem Exp $ * arch/sparc64/mm/init.c * * Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu) @@ -738,22 +738,17 @@ pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset) */ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset, unsigned long color) { - unsigned long paddr = __get_free_pages(GFP_KERNEL, 1); + struct page *page = alloc_pages(GFP_KERNEL, 1); - if (paddr) { - struct page *page2 = mem_map + MAP_NR(paddr + PAGE_SIZE); + if (page) { unsigned long *to_free; + unsigned long paddr; pte_t *pte; - /* Set count of second page, so we can free it - * seperately later on. - */ - atomic_set(&page2->count, 1); - - /* Clear out both pages now. */ + set_page_count((page + 1), 1); + paddr = page_address(page); memset((char *)paddr, 0, (PAGE_SIZE << 1)); - /* Determine which page we give to this request. */ if (!color) { pte = (pte_t *) paddr; to_free = (unsigned long *) (paddr + PAGE_SIZE); @@ -804,50 +799,39 @@ void sparc_ultra_dump_dtlb(void) } } -#undef DEBUG_BOOTMEM - extern unsigned long cmdline_memory_size; -unsigned long __init bootmem_init(void) +unsigned long __init bootmem_init(unsigned long *pages_avail) { unsigned long bootmap_size, start_pfn, end_pfn; unsigned long end_of_phys_memory = 0UL; - unsigned long bootmap_pfn; + unsigned long bootmap_pfn, bytes_avail, size; int i; - /* XXX It is a bit ambiguous here, whether we should - * XXX treat the user specified mem=xxx as total wanted - * XXX physical memory, or as a limit to the upper - * XXX physical address we allow. For now it is the - * XXX latter. -DaveM - */ -#ifdef DEBUG_BOOTMEM - prom_printf("bootmem_init: Scan sp_banks, "); -#endif + + bytes_avail = 0UL; for (i = 0; sp_banks[i].num_bytes != 0; i++) { end_of_phys_memory = sp_banks[i].base_addr + sp_banks[i].num_bytes; + bytes_avail += sp_banks[i].num_bytes; if (cmdline_memory_size) { - if (end_of_phys_memory > cmdline_memory_size) { - if (cmdline_memory_size < sp_banks[i].base_addr) { - end_of_phys_memory = - sp_banks[i-1].base_addr + - sp_banks[i-1].num_bytes; + if (bytes_avail > cmdline_memory_size) { + unsigned long slack = bytes_avail - cmdline_memory_size; + + bytes_avail -= slack; + end_of_phys_memory -= slack; + + sp_banks[i].num_bytes -= slack; + if (sp_banks[i].num_bytes == 0) sp_banks[i].base_addr = 0xdeadbeef; - sp_banks[i].num_bytes = 0; - } else { - sp_banks[i].num_bytes -= - (end_of_phys_memory - - cmdline_memory_size); - end_of_phys_memory = cmdline_memory_size; - sp_banks[++i].base_addr = 0xdeadbeef; - sp_banks[i].num_bytes = 0; - } + break; } } } + *pages_avail = bytes_avail >> PAGE_SHIFT; + /* Start with page aligned address of last symbol in kernel * image. The kernel is hard mapped below PAGE_OFFSET in a * 4MB locked TLB translation. @@ -886,50 +870,40 @@ unsigned long __init bootmem_init(void) } #endif /* Initialize the boot-time allocator. */ -#ifdef DEBUG_BOOTMEM - prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],epfn[%lx])\n", - start_pfn, bootmap_pfn, end_pfn); -#endif - bootmap_size = init_bootmem(bootmap_pfn, end_pfn); + bootmap_size = init_bootmem_node(0, bootmap_pfn, phys_base>>PAGE_SHIFT, end_pfn); /* Now register the available physical memory with the * allocator. */ - for (i = 0; sp_banks[i].num_bytes != 0; i++) { -#ifdef DEBUG_BOOTMEM - prom_printf("free_bootmem: base[%lx] size[%lx]\n", - sp_banks[i].base_addr, - sp_banks[i].num_bytes); -#endif + for (i = 0; sp_banks[i].num_bytes != 0; i++) free_bootmem(sp_banks[i].base_addr, sp_banks[i].num_bytes); - } - /* Reserve the kernel text/data/bss, the bootmem bootmap and initrd. */ -#ifdef DEBUG_BOOTMEM -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) - prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - initrd_start, initrd_end - initrd_start); -#endif - prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - phys_base, (start_pfn << PAGE_SHIFT) - phys_base); - prom_printf("reserve_bootmem: base[%lx] size[%lx]\n", - (bootmap_pfn << PAGE_SHIFT), bootmap_size); -#endif #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) { - reserve_bootmem(initrd_start, initrd_end - initrd_start); + size = initrd_end - initrd_start; + + /* Resert the initrd image area. */ + reserve_bootmem(initrd_start, size); + *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; + initrd_start += PAGE_OFFSET; initrd_end += PAGE_OFFSET; } #endif - reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base); - reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size); + /* Reserve the kernel text/data/bss. */ + size = (start_pfn << PAGE_SHIFT) - phys_base; + reserve_bootmem(phys_base, size); + *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; + + /* Reserve the bootmem map. We do not account for it + * in pages_avail because we will release that memory + * in free_all_bootmem. + */ + size = bootmap_size; + reserve_bootmem((bootmap_pfn << PAGE_SHIFT), size); + *pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT; -#ifdef DEBUG_BOOTMEM - prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn); -#endif return end_pfn; } @@ -946,7 +920,7 @@ void __init paging_init(void) extern unsigned int sparc64_vpte_patchme2[1]; unsigned long alias_base = phys_base + PAGE_OFFSET; unsigned long second_alias_page = 0; - unsigned long pt, flags, end_pfn; + unsigned long pt, flags, end_pfn, pages_avail; unsigned long shift = alias_base - ((unsigned long)&empty_zero_page); set_bit(0, mmu_context_bmap); @@ -1001,7 +975,8 @@ void __init paging_init(void) flushi((long)&sparc64_vpte_patchme1[0]); /* Setup bootmem... */ - last_valid_pfn = end_pfn = bootmem_init(); + pages_avail = 0; + last_valid_pfn = end_pfn = bootmem_init(&pages_avail); #ifdef CONFIG_SUN_SERIAL /* This does not logically belong here, but we need to @@ -1039,10 +1014,20 @@ void __init paging_init(void) flush_tlb_all(); { - unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0}; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + unsigned long npages; + int znum; + + for (znum = 0; znum < MAX_NR_ZONES; znum++) + zones_size[znum] = zholes_size[znum] = 0; + + npages = end_pfn - (phys_base >> PAGE_SHIFT); + zones_size[ZONE_DMA] = npages; + zholes_size[ZONE_DMA] = npages - pages_avail; - zones_size[ZONE_DMA] = end_pfn; - free_area_init(zones_size); + free_area_init_node(0, NULL, zones_size, + phys_base, zholes_size); } device_scan(); @@ -1139,9 +1124,6 @@ static void __init taint_real_pages(void) struct sparc_phys_banks saved_sp_banks[SPARC_PHYS_BANKS]; int i; -#ifdef DEBUG_BOOTMEM - prom_printf("taint_real_pages: Rescan sp_banks[].\n"); -#endif for (i = 0; i < SPARC_PHYS_BANKS; i++) { saved_sp_banks[i].base_addr = sp_banks[i].base_addr; @@ -1176,10 +1158,6 @@ static void __init taint_real_pages(void) goto do_next_page; } } -#ifdef DEBUG_BOOTMEM - prom_printf("taint: Page went away, reserve page %lx.\n", - old_start); -#endif reserve_bootmem(old_start, PAGE_SIZE); do_next_page: @@ -1188,70 +1166,6 @@ static void __init taint_real_pages(void) } } -void __init free_mem_map_range(struct page *first, struct page *last) -{ - first = (struct page *) PAGE_ALIGN((unsigned long)first); - last = (struct page *) ((unsigned long)last & PAGE_MASK); -#ifdef DEBUG_BOOTMEM - prom_printf("[%p,%p] ", first, last); -#endif - while (first < last) { - ClearPageReserved(mem_map + MAP_NR(first)); - set_page_count(mem_map + MAP_NR(first), 1); - free_page((unsigned long)first); - num_physpages++; - - first = (struct page *)((unsigned long)first + PAGE_SIZE); - } -} - -/* Walk through holes in sp_banks regions, if the mem_map array - * areas representing those holes consume a page or more, free - * up such pages. This helps a lot on machines where physical - * ram is configured such that it begins at some hugh value. - * - * The sp_banks array is sorted by base address. - */ -void __init free_unused_mem_map(void) -{ - int i; - -#ifdef DEBUG_BOOTMEM - prom_printf("free_unused_mem_map: "); -#endif - for (i = 0; sp_banks[i].num_bytes; i++) { - if (i == 0) { - struct page *first, *last; - - first = mem_map; - last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT]; - free_mem_map_range(first, last); - } else { - struct page *first, *last; - unsigned long prev_end; - - prev_end = sp_banks[i-1].base_addr + - sp_banks[i-1].num_bytes; - prev_end = PAGE_ALIGN(prev_end); - first = &mem_map[prev_end >> PAGE_SHIFT]; - last = &mem_map[sp_banks[i].base_addr >> PAGE_SHIFT]; - - free_mem_map_range(first, last); - - if (!sp_banks[i+1].num_bytes) { - prev_end = sp_banks[i].base_addr + - sp_banks[i].num_bytes; - first = &mem_map[prev_end >> PAGE_SHIFT]; - last = &mem_map[last_valid_pfn]; - free_mem_map_range(first, last); - } - } - } -#ifdef DEBUG_BOOTMEM - prom_printf("\n"); -#endif -} - void __init mem_init(void) { unsigned long codepages, datapages, initpages; @@ -1279,16 +1193,10 @@ void __init mem_init(void) taint_real_pages(); - max_mapnr = last_valid_pfn; + max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT); high_memory = __va(last_valid_pfn << PAGE_SHIFT); -#ifdef DEBUG_BOOTMEM - prom_printf("mem_init: Calling free_all_bootmem().\n"); -#endif num_physpages = free_all_bootmem(); -#if 0 - free_unused_mem_map(); -#endif codepages = (((unsigned long) &etext) - ((unsigned long)&_start)); codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT; datapages = (((unsigned long) &edata) - ((unsigned long)&etext)); @@ -1317,19 +1225,6 @@ void __init mem_init(void) datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10), PAGE_OFFSET, (last_valid_pfn << PAGE_SHIFT)); - - /* NOTE NOTE NOTE NOTE - * Please keep track of things and make sure this - * always matches the code in mm/page_alloc.c -DaveM - */ - i = nr_free_pages() >> 7; - if (i < 48) - i = 48; - if (i > 256) - i = 256; - freepages.min = i; - freepages.low = i << 1; - freepages.high = freepages.low + i; } void free_initmem (void) diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 2639d19776b5..ef4c9aa01350 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.24 2000/04/08 02:11:55 davem Exp $ +/* $Id: misc.c,v 1.26 2000/04/14 09:59:02 davem Exp $ * misc.c: Miscelaneous syscall emulation for Solaris * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) diff --git a/drivers/atm/Config.in b/drivers/atm/Config.in index 8fb55632a755..c603f71affd7 100644 --- a/drivers/atm/Config.in +++ b/drivers/atm/Config.in @@ -52,8 +52,8 @@ if [ "$CONFIG_PCI" = "y" ]; then fi fi if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then - tristate 'FORE Systems 200E-series' CONFIG_ATM_FORE200E - if [ "$CONFIG_ATM_FORE200E" != "n" ]; then + tristate 'FORE Systems 200E-series' CONFIG_ATM_FORE200E_MAYBE + if [ "$CONFIG_ATM_FORE200E_MAYBE" != "n" ]; then if [ "$CONFIG_PCI" = "y" ]; then bool ' PCA-200E support' CONFIG_ATM_FORE200E_PCA y if [ "$CONFIG_ATM_FORE200E_PCA" = "y" ]; then @@ -72,8 +72,16 @@ if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SBUS" = "y" ]; then fi fi fi + fi + if [ "$CONFIG_ATM_FORE200E_PCA" = "y" -o "$CONFIG_ATM_FORE200E_SBA" = "y" ]; \ + then int ' Maximum number of tx retries' CONFIG_ATM_FORE200E_TX_RETRY 16 int ' Debugging level (0-3)' CONFIG_ATM_FORE200E_DEBUG 0 + if [ "$CONFIG_ATM_FORE200E_MAYBE" = "y" ]; then + define_tristate CONFIG_ATM_FORE200E y + else + define_tristate CONFIG_ATM_FORE200E m + fi fi fi endmenu diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index 8dbf1364aa73..330d5d1c37b2 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -30,10 +30,6 @@ else endif endif -ifeq ($(CONFIG_ATM_TNETA1570),y) -O_OBJS += tneta1570.o suni.o -endif - ifeq ($(CONFIG_ATM_NICSTAR),y) O_OBJS += nicstar.o ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y) @@ -101,23 +97,29 @@ else endif ifeq ($(CONFIG_ATM_FORE200E_PCA),y) -FORE200E_FW_OBJS += fore200e_pca_fw.o + FORE200E_FW_OBJS += fore200e_pca_fw.o + ifeq ($(strip $(CONFIG_ATM_FORE200E_PCA_FW)),"") + CONFIG_ATM_FORE200E_PCA_DEFAULT_FW := y + endif ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) # guess the target endianess to choose the right PCA-200E firmware image CONFIG_ATM_FORE200E_PCA_FW := $(shell if test -n "`$(CC) -E -dM ../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo pca200e.bin; else echo pca200e_ecd.bin2; fi) endif endif ifeq ($(CONFIG_ATM_FORE200E_SBA),y) -FORE200E_FW_OBJS += fore200e_sba_fw.o + FORE200E_FW_OBJS += fore200e_sba_fw.o + ifeq ($(strip $(CONFIG_ATM_FORE200E_SBA_FW)),"") + CONFIG_ATM_FORE200E_SBA_DEFAULT_FW := y + endif ifeq ($(CONFIG_ATM_FORE200E_SBA_DEFAULT_FW),y) CONFIG_ATM_FORE200E_SBA_FW := sba200e_ecd.bin2 endif endif ifeq ($(CONFIG_ATM_FORE200E),y) -O_OBJS += fore200e.o $(FORE200E_FW_OBJS) + O_OBJS += fore200e.o $(FORE200E_FW_OBJS) else ifeq ($(CONFIG_ATM_FORE200E),m) - M_OBJS += fore_200e.o + M_OBJS += fore_200e.o endif endif @@ -125,33 +127,51 @@ EXTRA_CFLAGS=-g include $(TOPDIR)/Rules.make + # FORE Systems 200E-series firmware magic fore200e_pca_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_PCA_FW)) \ fore200e_mkfirm ./fore200e_mkfirm -k -b _fore200e_pca_fw \ -i $(CONFIG_ATM_FORE200E_PCA_FW) -o $@ + @ ( \ + echo 'ifeq ($(strip $(CONFIG_ATM_FORE200E_PCA_FW)), $$(CONFIG_ATM_FORE200E_PCA_FW))'; \ + echo 'FORE200E_FW_UP_TO_DATE += $@'; \ + echo 'endif' \ + ) >.$@.fw fore200e_sba_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_SBA_FW)) \ fore200e_mkfirm ./fore200e_mkfirm -k -b _fore200e_sba_fw \ -i $(CONFIG_ATM_FORE200E_SBA_FW) -o $@ + @ ( \ + echo 'ifeq ($(strip $(CONFIG_ATM_FORE200E_SBA_FW)), $$(CONFIG_ATM_FORE200E_SBA_FW))'; \ + echo 'FORE200E_FW_UP_TO_DATE += $@'; \ + echo 'endif' \ + ) >.$@.fw fore200e_mkfirm: fore200e_mkfirm.c $(HOSTCC) $(HOSTCFLAGS) $< -o $@ -# deal with the various suffixes of the firmware images -%.bin: %.data - objcopy -Iihex $< -Obinary $@.gz - gzip -df $@.gz - -%.bin1: %.data - objcopy -Iihex $< -Obinary $@.gz - gzip -df $@.gz - -%.bin2: %.data +# deal with the various suffixes of the binary firmware images +%.bin %.bin1 %.bin2: %.data objcopy -Iihex $< -Obinary $@.gz gzip -df $@.gz # module build fore_200e.o: fore200e.o $(FORE200E_FW_OBJS) $(LD) -r -o $@ $< $(FORE200E_FW_OBJS) + +# firmware dependency stuff taken from drivers/sound/Makefile +FORE200E_FW_UP_TO_DATE := + +FORE200E_FW_FILES := $(wildcard .fore200e_*.fw) +ifneq ($(FORE200E_FW_FILES),) +include $(FORE200E_FW_FILES) +endif + +FORE200E_FW_CHANGED := $(filter-out $(FORE200E_FW_UP_TO_DATE), \ + fore200e_pca_fw.c fore200e_sba_fw.c) + +ifneq ($(FORE200E_FW_CHANGED),) +$(FORE200E_FW_CHANGED): dummy +endif diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index a71884db7d89..151704c95f20 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -1251,10 +1251,15 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) { } } + // prevent module unload while sleeping (kmalloc/down) + // doing this any earlier would complicate more error return paths + MOD_INC_USE_COUNT; + // get space for our vcc stuff vcc = kmalloc (sizeof(amb_vcc), GFP_KERNEL); if (!vcc) { PRINTK (KERN_ERR, "out of memory!"); + MOD_DEC_USE_COUNT; return -ENOMEM; } atm_vcc->dev_data = (void *) vcc; @@ -1340,7 +1345,6 @@ static int amb_open (struct atm_vcc * atm_vcc, short vpi, int vci) { // indicate readiness set_bit(ATM_VF_READY,&atm_vcc->flags); - MOD_INC_USE_COUNT; return 0; } @@ -1420,7 +1424,9 @@ static void amb_close (struct atm_vcc * atm_vcc) { // say the VPI/VCI is free again clear_bit(ATM_VF_ADDR,&atm_vcc->flags); + MOD_DEC_USE_COUNT; + return; } /********** DebugIoctl **********/ diff --git a/drivers/atm/ambassador.h b/drivers/atm/ambassador.h index 11ce866dab48..e8c3456e3927 100644 --- a/drivers/atm/ambassador.h +++ b/drivers/atm/ambassador.h @@ -631,7 +631,7 @@ struct amb_dev { u32 iobase; u32 * membase; -#if 0 +#ifdef FILL_RX_POOLS_IN_BH struct tq_struct bh; #endif diff --git a/drivers/atm/atmdev_init.c b/drivers/atm/atmdev_init.c index 443831a82b8a..73c785fe05fa 100644 --- a/drivers/atm/atmdev_init.c +++ b/drivers/atm/atmdev_init.c @@ -1,21 +1,15 @@ /* drivers/atm/atmdev_init.c - ATM device driver initialization */ -/* Written 1995-1997 by Werner Almesberger, EPFL LRC */ +/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ #include #include -#ifdef CONFIG_ATM_ENI -extern int eni_detect(void); -#endif #ifdef CONFIG_ATM_ZATM extern int zatm_detect(void); #endif -#ifdef CONFIG_ATM_TNETA1570 -extern int tneta1570_detect(void); -#endif #ifdef CONFIG_ATM_NICSTAR extern int nicstar_detect(void); #endif @@ -33,20 +27,20 @@ extern int fore200e_detect(void); #endif +/* + * For historical reasons, atmdev_init returns the number of devices found. + * Note that some detections may not go via atmdev_init (e.g. eni.c), so this + * number is meaningless. + */ + int __init atmdev_init(void) { int devs; devs = 0; -#ifdef CONFIG_ATM_ENI -// devs += eni_detect(); -#endif #ifdef CONFIG_ATM_ZATM devs += zatm_detect(); #endif -#ifdef CONFIG_ATM_TNETA1570 - devs += tneta1570_detect(); -#endif #ifdef CONFIG_ATM_NICSTAR devs += nicstar_detect(); #endif diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index b3240d498957..df6ae2eda185 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -879,14 +879,13 @@ static void close_rx(struct atm_vcc *vcc) set_current_state(TASK_UNINTERRUPTIBLE); } for (;;) { - unsigned long flags; int at_end; u32 tmp; - spin_lock_irqsave(&eni_dev->lock,flags); + tasklet_disable(&eni_dev->task); tmp = readl(eni_dev->vci+vcc->vci*16+4) & MID_VCI_READ; at_end = eni_vcc->rx_pos == tmp >> MID_VCI_READ_SHIFT; - spin_unlock_irqrestore(&eni_dev->lock,flags); + tasklet_enable(&eni_dev->task); if (at_end) break; EVENT("drain discard (host 0x%lx, nic 0x%lx)\n", eni_vcc->rx_pos,tmp); @@ -972,8 +971,8 @@ static inline void put_dma(int chan,u32 *dma,int *j,dma_addr_t paddr, } #ifdef CONFIG_ATM_ENI_BURST_TX_16W /* may work with some PCI chipsets ... */ if (words & ~15) { - DPRINTK("put_dma: %lx DMA: %d*16/%d words\n",paddr,words >> 4, - words); + DPRINTK("put_dma: %lx DMA: %d*16/%d words\n", + (unsigned long) paddr,words >> 4,words); dma[(*j)++] = MID_DT_16W | ((words >> 4) << MID_DMA_COUNT_SHIFT) | (chan << MID_DMA_CHAN_SHIFT); dma[(*j)++] = paddr; @@ -994,8 +993,8 @@ static inline void put_dma(int chan,u32 *dma,int *j,dma_addr_t paddr, #endif #ifdef CONFIG_ATM_ENI_BURST_TX_4W /* probably useless if TX_8W or TX_16W */ if (words & ~3) { - DPRINTK("put_dma: %lx DMA: %d*4/%d words\n",paddr,words >> 2, - words); + DPRINTK("put_dma: %lx DMA: %d*4/%d words\n", + (unsigned long) paddr,words >> 2,words); dma[(*j)++] = MID_DT_4W | ((words >> 2) << MID_DMA_COUNT_SHIFT) | (chan << MID_DMA_CHAN_SHIFT); dma[(*j)++] = paddr; @@ -1005,8 +1004,8 @@ static inline void put_dma(int chan,u32 *dma,int *j,dma_addr_t paddr, #endif #ifdef CONFIG_ATM_ENI_BURST_TX_2W /* probably useless if TX_4W, TX_8W, ... */ if (words & ~1) { - DPRINTK("put_dma: %lx DMA: %d*2/%d words\n",paddr,words >> 1, - words); + DPRINTK("put_dma: %lx DMA: %d*2/%d words\n", + (unsigned long) paddr,words >> 1,words); dma[(*j)++] = MID_DT_2W | ((words >> 1) << MID_DMA_COUNT_SHIFT) | (chan << MID_DMA_CHAN_SHIFT); dma[(*j)++] = paddr; @@ -1188,7 +1187,7 @@ static void poll_tx(struct atm_dev *dev) if (tx->send) while ((skb = skb_dequeue(&tx->backlog))) { res = do_tx(skb); - if (res == enq_ok) tx->backlog_len--; + if (res == enq_ok) atomic_dec(&tx->backlog_len); else { DPRINTK("re-queuing TX PDU\n"); skb_queue_head(&tx->backlog,skb); @@ -1327,7 +1326,7 @@ static int reserve_or_set_tx(struct atm_vcc *vcc,struct atm_trafprm *txtp, tx->send = mem; tx->words = size >> 2; skb_queue_head_init(&tx->backlog); - tx->backlog_len = 0; + atomic_set(&tx->backlog_len,0); for (order = 0; size > (1 << (order+10)); order++); eni_out((order << MID_SIZE_SHIFT) | ((tx->send-eni_dev->ram) >> (MID_LOC_SKIP+2)), @@ -1399,12 +1398,11 @@ static void close_tx(struct atm_vcc *vcc) add_wait_queue(&eni_dev->tx_wait,&wait); set_current_state(TASK_UNINTERRUPTIBLE); for (;;) { - unsigned long flags; int txing; - spin_lock_irqsave(&eni_dev->lock,flags); + tasklet_disable(&eni_dev->task); txing = skb_peek(&eni_vcc->tx->backlog) || eni_vcc->txing; - spin_unlock_irqrestore(&eni_dev->lock,flags); + tasklet_enable(&eni_dev->task); if (!txing) break; DPRINTK("%d TX left\n",eni_vcc->txing); schedule(); @@ -1468,44 +1466,24 @@ if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost); #endif -static void misc_int(struct atm_dev *dev,unsigned long reason) +static void bug_int(struct atm_dev *dev,unsigned long reason) { struct eni_dev *eni_dev; - DPRINTK(">misc_int\n"); + DPRINTK(">bug_int\n"); eni_dev = ENI_DEV(dev); - if (reason & MID_STAT_OVFL) { - EVENT("stat overflow\n",0,0); - eni_dev->lost += eni_in(MID_STAT) & MID_OVFL_TRASH; - } - if (reason & MID_SUNI_INT) { - EVENT("SUNI int\n",0,0); - dev->phy->interrupt(dev); -#if 0 - foo(); -#endif - } - if (reason & MID_DMA_ERR_ACK) { + if (reason & MID_DMA_ERR_ACK) printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA " "error\n",dev->number); - EVENT("---dump ends here---\n",0,0); - printk(KERN_NOTICE "---recent events---\n"); - event_dump(); - } - if (reason & MID_TX_IDENT_MISM) { + if (reason & MID_TX_IDENT_MISM) printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - ident " "mismatch\n",dev->number); - EVENT("---dump ends here---\n",0,0); - printk(KERN_NOTICE "---recent events---\n"); - event_dump(); - } - if (reason & MID_TX_DMA_OVFL) { + if (reason & MID_TX_DMA_OVFL) printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA " "overflow\n",dev->number); - EVENT("---dump ends here---\n",0,0); - printk(KERN_NOTICE "---recent events---\n"); - event_dump(); - } + EVENT("---dump ends here---\n",0,0); + printk(KERN_NOTICE "---recent events---\n"); + event_dump(); } @@ -1513,54 +1491,78 @@ static void eni_int(int irq,void *dev_id,struct pt_regs *regs) { struct atm_dev *dev; struct eni_dev *eni_dev; - unsigned long reason; + u32 reason; DPRINTK(">eni_int\n"); dev = dev_id; eni_dev = ENI_DEV(dev); - while ((reason = eni_in(MID_ISA))) { - DPRINTK(DEV_LABEL ": int 0x%lx\n",reason); - if (reason & MID_RX_DMA_COMPLETE) { - EVENT("INT: RX DMA complete, starting dequeue_rx\n", - 0,0); - spin_lock(&eni_dev->lock); - dequeue_rx(dev); - EVENT("dequeue_rx done, starting poll_rx\n",0,0); - poll_rx(dev); - spin_unlock(&eni_dev->lock); - EVENT("poll_rx done\n",0,0); - /* poll_tx ? */ - } - if (reason & MID_SERVICE) { - EVENT("INT: service, starting get_service\n",0,0); - spin_lock(&eni_dev->lock); - get_service(dev); - EVENT("get_service done, starting poll_rx\n",0,0); - poll_rx(dev); - spin_unlock(&eni_dev->lock); - EVENT("poll_rx done\n",0,0); - } - if (reason & MID_TX_DMA_COMPLETE) { - EVENT("INT: TX DMA COMPLETE\n",0,0); - spin_lock(&eni_dev->lock); - dequeue_tx(dev); - spin_unlock(&eni_dev->lock); - } - if (reason & MID_TX_COMPLETE) { - EVENT("INT: TX COMPLETE\n",0,0); + reason = eni_in(MID_ISA); + DPRINTK(DEV_LABEL ": int 0x%lx\n",(unsigned long) reason); + /* + * Must handle these two right now, because reading ISA doesn't clear + * them, so they re-occur and we never make it to the tasklet. Since + * they're rare, we don't mind the occasional invocation of eni_tasklet + * with eni_dev->events == 0. + */ + if (reason & MID_STAT_OVFL) { + EVENT("stat overflow\n",0,0); + eni_dev->lost += eni_in(MID_STAT) & MID_OVFL_TRASH; + } + if (reason & MID_SUNI_INT) { + EVENT("SUNI int\n",0,0); + dev->phy->interrupt(dev); +#if 0 + foo(); +#endif + } + spin_lock(&eni_dev->lock); + eni_dev->events |= reason; + spin_unlock(&eni_dev->lock); + tasklet_schedule(&eni_dev->task); +} + + +static void eni_tasklet(unsigned long data) +{ + struct atm_dev *dev = (struct atm_dev *) data; + struct eni_dev *eni_dev = ENI_DEV(dev); + unsigned long flags; + u32 events; + + DPRINTK("eni_tasklet (dev %p)\n",dev); + spin_lock_irqsave(&eni_dev->lock,flags); + events = xchg(&eni_dev->events,0); + spin_unlock_irqrestore(&eni_dev->lock,flags); + if (events & MID_RX_DMA_COMPLETE) { + EVENT("INT: RX DMA complete, starting dequeue_rx\n",0,0); + dequeue_rx(dev); + EVENT("dequeue_rx done, starting poll_rx\n",0,0); + poll_rx(dev); + EVENT("poll_rx done\n",0,0); + /* poll_tx ? */ + } + if (events & MID_SERVICE) { + EVENT("INT: service, starting get_service\n",0,0); + get_service(dev); + EVENT("get_service done, starting poll_rx\n",0,0); + poll_rx(dev); + EVENT("poll_rx done\n",0,0); + } + if (events & MID_TX_DMA_COMPLETE) { + EVENT("INT: TX DMA COMPLETE\n",0,0); + dequeue_tx(dev); + } + if (events & MID_TX_COMPLETE) { + EVENT("INT: TX COMPLETE\n",0,0); tx_complete++; - spin_lock(&eni_dev->lock); - poll_tx(dev); - spin_unlock(&eni_dev->lock); - wake_up(&eni_dev->tx_wait); - /* poll_rx ? */ - } - if (reason & (MID_STAT_OVFL | MID_SUNI_INT | MID_DMA_ERR_ACK | - MID_TX_IDENT_MISM | MID_TX_DMA_OVFL)) { - EVENT("misc interrupt\n",0,0); - misc_int(dev,reason); - } + wake_up(&eni_dev->tx_wait); + /* poll_rx ? */ + } + if (events & (MID_DMA_ERR_ACK | MID_TX_IDENT_MISM | MID_TX_DMA_OVFL)) { + EVENT("bug interrupt\n",0,0); + bug_int(dev,events); } + poll_tx(dev); } @@ -1824,6 +1826,8 @@ static int __devinit eni_start(struct atm_dev *dev) eni_dev->vci,eni_dev->rx_dma,eni_dev->tx_dma, eni_dev->service,buf); spin_lock_init(&eni_dev->lock); + tasklet_init(&eni_dev->task,eni_tasklet,(unsigned long) dev); + eni_dev->events = 0; /* initialize memory management */ buffer_mem = eni_dev->mem-(buf-eni_dev->ram); eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2; @@ -1969,7 +1973,6 @@ static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs) struct eni_dev *eni_dev = ENI_DEV(vcc->dev); struct eni_tx *tx = ENI_VCC(vcc)->tx; struct sk_buff *skb; - unsigned long flags; int error,rate,rsv,shp; if (qos->txtp.traffic_class == ATM_NONE) return 0; @@ -1989,7 +1992,7 @@ static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs) * Walk through the send buffer and patch the rate information in all * segmentation buffer descriptors of this VCC. */ - spin_lock_irqsave(&eni_dev->lock,flags); + tasklet_disable(&eni_dev->task); for (skb = eni_dev->tx_queue.next; skb != (struct sk_buff *) &eni_dev->tx_queue; skb = skb->next) { unsigned long dsc; @@ -2000,7 +2003,7 @@ static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs) (tx->prescaler << MID_SEG_PR_SHIFT) | (tx->resolution << MID_SEG_RATE_SHIFT), dsc); } - spin_unlock_irqrestore(&eni_dev->lock,flags); + tasklet_enable(&eni_dev->task); return 0; } @@ -2061,8 +2064,6 @@ static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname, static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb) { - unsigned long flags; - DPRINTK(">eni_send\n"); if (!ENI_VCC(vcc)->tx) { if (vcc->pop) vcc->pop(vcc,skb); @@ -2084,13 +2085,10 @@ static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb) } submitted++; ATM_SKB(skb)->vcc = vcc; - spin_lock_irqsave(&ENI_DEV(vcc->dev)->lock,flags); /* brute force */ - if (skb_peek(&ENI_VCC(vcc)->tx->backlog) || do_tx(skb)) { - skb_queue_tail(&ENI_VCC(vcc)->tx->backlog,skb); - ENI_VCC(vcc)->tx->backlog_len++; + skb_queue_tail(&ENI_VCC(vcc)->tx->backlog,skb); + atomic_inc(&ENI_VCC(vcc)->tx->backlog_len); backlogged++; - } - spin_unlock_irqrestore(&ENI_DEV(vcc->dev)->lock,flags); + tasklet_schedule(&ENI_DEV(vcc->dev)->task); return 0; } @@ -2189,7 +2187,7 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page) } if (--left) continue; return sprintf(page,"%10sbacklog %d bytes\n","", - tx->backlog_len); + atomic_read(&tx->backlog_len)); } for (vcc = dev->vccs; vcc; vcc = vcc->next) { struct eni_vcc *eni_vcc = ENI_VCC(vcc); diff --git a/drivers/atm/eni.h b/drivers/atm/eni.h index 23ba60fb1e9e..12a3e196c5f7 100644 --- a/drivers/atm/eni.h +++ b/drivers/atm/eni.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "midway.h" @@ -46,7 +47,7 @@ struct eni_tx { int reserved; /* reserved peak cell rate */ int shaping; /* shaped peak cell rate */ struct sk_buff_head backlog; /* queue of waiting TX buffers */ - int backlog_len; /* length of backlog in bytes */ + atomic_t backlog_len; /* length of backlog in bytes */ }; struct eni_vcc { @@ -68,6 +69,8 @@ struct eni_vcc { struct eni_dev { /*-------------------------------- spinlock */ spinlock_t lock; /* sync with interrupt */ + struct tasklet_struct task; /* tasklet for interrupt work */ + u32 events; /* pending events */ /*-------------------------------- base pointers into Midway address space */ unsigned long phy; /* PHY interface chip registers */ diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 1fec6e0062c7..d9d5a66c548b 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -1,8 +1,8 @@ /* - $Id: fore200e.c,v 1.2 2000/03/21 21:19:24 davem Exp $ + $Id: fore200e.c,v 1.5 2000/04/14 10:10:34 davem Exp $ A FORE Systems 200E-series driver for ATM on Linux. - Christophe Lizzi (lizzi@cnam.fr), October 1999-February 2000. + Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2000. Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de). @@ -32,10 +32,11 @@ #include #include #include +#include +#include #include #include #include -#include #include #include #include @@ -66,7 +67,7 @@ #define FORE200E_52BYTE_AAL0_SDU #endif -#define FORE200E_VERSION "0.2b" +#define FORE200E_VERSION "0.2d" #define FORE200E "fore200e: " @@ -444,6 +445,7 @@ fore200e_shutdown(struct fore200e* fore200e) } + #ifdef CONFIG_ATM_FORE200E_PCA static u32 fore200e_pca_read(volatile u32* addr) @@ -477,7 +479,8 @@ fore200e_pca_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int d static void fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction) { - DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction); + DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d\n", + dma_addr, size, direction); pci_unmap_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction); } @@ -496,7 +499,8 @@ fore200e_pca_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size, int dir (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ static int -fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int nbr, int alignment) +fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, + int size, int nbr, int alignment) { #if defined(__sparc_v9__) /* returned chunks are page-aligned */ @@ -659,6 +663,7 @@ fore200e_pca_detect(const struct fore200e_bus* bus, int index) sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1); + pci_enable_device(pci_dev); pci_set_master(pci_dev); return fore200e; @@ -756,7 +761,8 @@ fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int d static void fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction) { - DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n", dma_addr, size, direction); + DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n", + dma_addr, size, direction); sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction); } @@ -775,7 +781,8 @@ fore200e_sba_dma_sync(struct fore200e* fore200e, u32 dma_addr, int size, int dir (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */ static int -fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int nbr, int alignment) +fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, + int size, int nbr, int alignment) { chunk->alloc_size = chunk->align_size = size * nbr; @@ -1234,15 +1241,25 @@ fore200e_interrupt(int irq, void* dev, struct pt_regs* regs) } DPRINTK(3, "valid interrupt on device %c\n", fore200e->name[9]); - fore200e_irq_rx(fore200e); + tasklet_schedule(&fore200e->tasklet); + + fore200e->bus->irq_ack(fore200e); +} + + +static void +fore200e_tasklet(unsigned long data) +{ + struct fore200e* fore200e = (struct fore200e*) data; + fore200e_irq_rx(fore200e); + if (fore200e->host_txq.txing) fore200e_irq_tx(fore200e); - - fore200e->bus->irq_ack(fore200e); } + static int fore200e_select_scheme(struct atm_vcc* vcc) { @@ -1400,7 +1417,7 @@ fore200e_open(struct atm_vcc *vcc, short vpi, int vci) if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) return 0; - set_bit(ATM_VF_ADDR,&vcc->flags); + set_bit(ATM_VF_ADDR, &vcc->flags); vcc->itf = vcc->dev->number; DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; " @@ -1463,7 +1480,7 @@ fore200e_open(struct atm_vcc *vcc, short vpi, int vci) fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = 65536; fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0; - clear_bit(ATM_VF_READY,&vcc->flags); + set_bit(ATM_VF_READY, &vcc->flags); return 0; } @@ -1489,6 +1506,8 @@ fore200e_close(struct atm_vcc* vcc) fore200e->available_cell_rate += vcc->qos.txtp.max_pcr; up(&fore200e->rate_sf); } + + clear_bit(ATM_VF_READY, &vcc->flags); } @@ -1506,7 +1525,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) struct host_txq_entry* entry; struct tpd* tpd; struct tpd_haddr tpd_haddr; - unsigned long flags; + //unsigned long flags; int retry = CONFIG_ATM_FORE200E_TX_RETRY; int tx_copy = 0; int tx_len = skb->len; @@ -1531,7 +1550,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) retry_here: - spin_lock_irqsave(&fore200e->tx_lock, flags); + tasklet_disable(&fore200e->tasklet); entry = &txq->host_entry[ txq->head ]; @@ -1542,7 +1561,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) if (*entry->status != STATUS_FREE) { - spin_unlock_irqrestore(&fore200e->tx_lock, flags); + tasklet_enable(&fore200e->tasklet); /* retry once again? */ if(--retry > 0) @@ -1582,7 +1601,7 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) entry->data = kmalloc(tx_len, GFP_ATOMIC | GFP_DMA); if (entry->data == NULL) { - spin_unlock_irqrestore(&fore200e->tx_lock, flags); + tasklet_enable(&fore200e->tasklet); if (vcc->pop) vcc->pop(vcc, skb); else @@ -1606,10 +1625,10 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb) FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX); txq->txing++; - spin_unlock_irqrestore(&fore200e->tx_lock, flags); - + tasklet_enable(&fore200e->tasklet); + /* ensure DMA synchronisation */ - fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length, FORE200E_DMA_TODEVICE); + fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length, FORE200E_DMA_TODEVICE); DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal), @@ -1934,8 +1953,7 @@ fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void* arg) return put_user(fore200e->loop_mode, (int*)arg) ? -EFAULT : 0; case ATM_QUERYLOOP: - return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int*)arg) ? - -EFAULT : 0; + return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int*)arg) ? -EFAULT : 0; } return -ENOSYS; /* not implemented */ @@ -1976,7 +1994,7 @@ fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags) /* update rate control parameters */ fore200e_rate_ctrl(qos, &fore200e_vcc->rate); - set_bit(ATM_VF_HASQOS,&vcc->flags); + set_bit(ATM_VF_HASQOS, &vcc->flags); return 0; } @@ -1997,6 +2015,8 @@ fore200e_irq_request(struct fore200e* fore200e) printk(FORE200E "IRQ %s reserved for device %s\n", fore200e_irq_itoa(fore200e->irq), fore200e->name); + tasklet_init(&fore200e->tasklet, fore200e_tasklet, (unsigned long)fore200e); + fore200e->state = FORE200E_STATE_IRQ; return 0; } @@ -2338,7 +2358,6 @@ fore200e_initialize(struct fore200e* fore200e) DPRINTK(2, "device %s being initialized\n", fore200e->name); - spin_lock_init(&fore200e->tx_lock); init_MUTEX(&fore200e->rate_sf); cpq = fore200e->cp_queues = (struct cp_queues*) (fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET); @@ -2714,7 +2733,7 @@ fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page) if (media_index < 0 || media_index > 4) media_index = 5; - switch(fore200e->loop_mode) { + switch (fore200e->loop_mode) { case ATM_LM_NONE: oc3_index = 0; break; case ATM_LM_LOC_PHY: oc3_index = 1; @@ -2900,21 +2919,24 @@ fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page) #ifdef MODULE -unsigned int -init_module(void) +static unsigned int __init +fore200e_module_init(void) { DPRINTK(1, "module loaded\n"); return fore200e_detect() == 0; } -void -cleanup_module(void) +static void __exit +fore200e_module_cleanup(void) { while (fore200e_boards) { fore200e_cleanup(&fore200e_boards); } DPRINTK(1, "module being removed\n"); } + +module_init(fore200e_module_init); +module_exit(fore200e_module_cleanup); #endif diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h index f29fbde97344..e56afd2b6462 100644 --- a/drivers/atm/fore200e.h +++ b/drivers/atm/fore200e.h @@ -1,3 +1,4 @@ +/* $Id: fore200e.h,v 1.4 2000/04/14 10:10:34 davem Exp $ */ #ifndef _FORE200E_H #define _FORE200E_H @@ -827,14 +828,18 @@ typedef struct fore200e_bus { # else /* in that case, we'll need to add an extra indirection, e.g. fore200e->bus->dma_direction[ fore200e_dma_direction ] */ -# error PCI and SBUS DMA direction flags differ! +# error PCI and SBUS DMA direction flags have different values! # endif # else -# define FORE200E_DMA_BIDIRECTIONAL SBA_DMA_BIDIRECTIONAL -# define FORE200E_DMA_TODEVICE SBA_DMA_TODEVICE -# define FORE200E_DMA_FROMDEVICE SBA_DMA_FROMDEVICE +# define FORE200E_DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL +# define FORE200E_DMA_TODEVICE SBUS_DMA_TODEVICE +# define FORE200E_DMA_FROMDEVICE SBUS_DMA_FROMDEVICE # endif #else +# ifndef CONFIG_ATM_FORE200E_PCA +# warning compiling the fore200e driver without any hardware support enabled! +# include +# endif # define FORE200E_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL # define FORE200E_DMA_TODEVICE PCI_DMA_TODEVICE # define FORE200E_DMA_FROMDEVICE PCI_DMA_FROMDEVICE @@ -874,7 +879,7 @@ typedef struct fore200e { struct stats* stats; /* last snapshot of the stats */ struct semaphore rate_sf; /* protects rate reservation ops */ - spinlock_t tx_lock; /* protects tx ops */ + struct tasklet_struct tasklet; /* performs interrupt work */ } fore200e_t; diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index f0dff701117b..f39845f853bf 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -2490,10 +2490,15 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { return -EINVAL; } + // prevent module unload while sleeping (kmalloc) + // doing this any earlier would complicate more error return paths + MOD_INC_USE_COUNT; + // get space for our vcc stuff and copy parameters into it vccp = kmalloc (sizeof(hrz_vcc), GFP_KERNEL); if (!vccp) { PRINTK (KERN_ERR, "out of memory!"); + MOD_DEC_USE_COUNT; return -ENOMEM; } *vccp = vcc; @@ -2525,6 +2530,7 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { if (error) { PRINTD (DBG_QOS|DBG_VCC, "insufficient cell rate resources"); kfree (vccp); + MOD_DEC_USE_COUNT; return error; } @@ -2537,11 +2543,13 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { if (rxtp->traffic_class != ATM_NONE) { if (dev->rxer[channel]) { PRINTD (DBG_ERR|DBG_VCC, "VC already open for RX"); - return -EBUSY; + error = -EBUSY; } - error = hrz_open_rx (dev, channel); + if (!error) + error = hrz_open_rx (dev, channel); if (error) { kfree (vccp); + MOD_DEC_USE_COUNT; return error; } // this link allows RX frames through @@ -2556,7 +2564,6 @@ static int hrz_open (struct atm_vcc * atm_vcc, short vpi, int vci) { // indicate readiness set_bit(ATM_VF_READY,&atm_vcc->flags); - MOD_INC_USE_COUNT; return 0; } diff --git a/drivers/atm/uPD98402.c b/drivers/atm/uPD98402.c index 7c5f5757935d..8f0613334294 100644 --- a/drivers/atm/uPD98402.c +++ b/drivers/atm/uPD98402.c @@ -141,7 +141,7 @@ static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) return fetch_stats(dev,(struct sonet_stats *) arg, cmd == SONET_GETSTATZ); case SONET_SETFRAMING: - return set_framing(dev,(int) arg); + return set_framing(dev,(int) (long) arg); case SONET_GETFRAMING: return put_user(PRIV(dev)->framing,(int *) arg) ? -EFAULT : 0; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index c66efc8c7f96..3ad5841a3425 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -465,10 +465,8 @@ int cdrom_open(struct inode *ip, struct file *fp) if ((cdi = cdrom_find_device(dev)) == NULL) return -ENODEV; - /* just CD-RW for now. DVD-RW will come soon, CD-R and DVD-R - * need to be handled differently. */ - if ((fp->f_mode & FMODE_WRITE) && !CDROM_CAN(CDC_CD_RW)) - return -EROFS; + if (fp->f_mode & FMODE_WRITE) + return -EROFS; /* if this was a O_NONBLOCK open and we should honor the flags, * do a quick open without drive/disc integrity checks. */ @@ -1648,7 +1646,7 @@ static int cdrom_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, if (tracks.data > 0) return CDS_DATA_1; /* Policy mode off */ - cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognise!\n"); + cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognize!\n"); return CDS_NO_INFO; } @@ -2529,33 +2527,31 @@ static void cdrom_sysctl_register(void) initialized = 1; } -#endif /* endif CONFIG_SYSCTL */ - -#ifdef MODULE static void cdrom_sysctl_unregister(void) { -#ifdef CONFIG_SYSCTL unregister_sysctl_table(cdrom_sysctl_header); -#endif } -int init_module(void) +#endif /* CONFIG_SYSCTL */ + +static int cdrom_init(void) { #ifdef CONFIG_SYSCTL cdrom_sysctl_register(); #endif - devfs_handle = devfs_mk_dir (NULL, "cdroms", 6, NULL); + devfs_handle = devfs_mk_dir(NULL, "cdroms", 6, NULL); return 0; } -void cleanup_module(void) +static void cdrom_exit(void) { printk(KERN_INFO "Uniform CD-ROM driver unloaded\n"); #ifdef CONFIG_SYSCTL cdrom_sysctl_unregister(); -#endif /* CONFIG_SYSCTL */ - devfs_unregister (devfs_handle); +#endif + devfs_unregister(devfs_handle); } -#endif /* endif MODULE */ +module_init(cdrom_init); +module_exit(cdrom_exit); diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 1b85830345ee..a5c94927a4eb 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c @@ -33,7 +33,12 @@ * * Revision history: * $Log: sx.c,v $ - * Revision 1.32 2000/03/07 90:00:00 wolff,pvdl + * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff + * - Fixed module and port counting + * - Fixed signal handling + * - Fixed an Ooops + * + * Revision 1.32 2000/03/07 09:00:00 wolff,pvdl * - Fixed some sx_dprintk typos * - added detection for an invalid board/module configuration * @@ -195,8 +200,8 @@ * */ -#define RCS_ID "$Id: sx.c,v 1.32 2000/03/07 17:01:02 wolff, pvdl Exp $" -#define RCS_REV "$Revision: 1.32 $" +#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $" +#define RCS_REV "$Revision: 1.33 $" #include @@ -231,8 +236,9 @@ #include "sxboards.h" #include "sxwindow.h" -#include + #include +#include #include "sx.h" @@ -241,11 +247,11 @@ if you want more than 4 boards. */ - /* Why the hell am I defining these here? */ #define SX_TYPE_NORMAL 1 #define SX_TYPE_CALLOUT 2 + #ifndef PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 #endif @@ -767,6 +773,7 @@ static void sx_setsignals (struct sx_port *port, int dtr, int rts) if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS); sx_write_channel_byte (port, hi_op, t); sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); + func_exit (); } @@ -882,6 +889,9 @@ static int sx_set_real_termios (void *ptr) func_enter2(); + if (!port->gs.tty) + return 0; + /* What is this doing here? -- REW Ha! figured it out. It is to allow you to get DTR active again if you've dropped it with stty 0. Moved to set_baud, where it @@ -1043,7 +1053,7 @@ void sx_transmit_chars (struct sx_port *port) sx_disable_tx_interrupts (port); } - if (port->gs.xmit_cnt <= port->gs.wakeup_chars) { + if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && port->gs.tty->ldisc.write_wakeup) (port->gs.tty->ldisc.write_wakeup)(port->gs.tty); @@ -1294,6 +1304,8 @@ static void sx_pollfunc (unsigned long data) sx_interrupt (0, board, NULL); + init_timer(&board->timer); + board->timer.expires = jiffies + sx_poll; add_timer (&board->timer); func_exit (); @@ -1389,7 +1401,7 @@ static void sx_shutdown_port (void * ptr) func_enter(); port->gs.flags &= ~ GS_ACTIVE; - if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) { + if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) { sx_setsignals (port, 0, 0); sx_reconfigure_port(port); } @@ -1452,6 +1464,8 @@ static int sx_open (struct tty_struct * tty, struct file * filp) tty->driver_data = port; port->gs.tty = tty; + if (!port->gs.count) + MOD_INC_USE_COUNT; port->gs.count++; sx_dprintk (SX_DEBUG_OPEN, "starting port\n"); @@ -1463,19 +1477,13 @@ static int sx_open (struct tty_struct * tty, struct file * filp) sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n"); if (retval) { port->gs.count--; + if (port->gs.count) MOD_DEC_USE_COUNT; return retval; } port->gs.flags |= GS_ACTIVE; sx_setsignals (port, 1,1); - sx_dprintk (SX_DEBUG_OPEN, "before inc_use_count (count=%d.\n", - port->gs.count); - if (port->gs.count == 1) { - MOD_INC_USE_COUNT; - } - sx_dprintk (SX_DEBUG_OPEN, "after inc_use_count\n"); - #if 0 if (sx_debug & SX_DEBUG_OPEN) my_hd ((unsigned char *)port, sizeof (*port)); @@ -1487,8 +1495,8 @@ static int sx_open (struct tty_struct * tty, struct file * filp) if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n"); - MOD_DEC_USE_COUNT; port->gs.count--; + if (!port->gs.count) MOD_DEC_USE_COUNT; return -EIO; } @@ -1497,8 +1505,10 @@ static int sx_open (struct tty_struct * tty, struct file * filp) retval, port->gs.count); if (retval) { - MOD_DEC_USE_COUNT; - port->gs.count--; + /* + * Don't lower gs.count here because sx_close() will be called later + */ + return retval; } /* tty->low_latency = 1; */ @@ -1530,7 +1540,21 @@ static int sx_open (struct tty_struct * tty, struct file * filp) exit minicom. I expect an "oops". -- REW */ static void sx_hungup (void *ptr) { + struct sx_port *port = ptr; func_enter (); + + sx_setsignals (port, 0, 0); + sx_reconfigure_port(port); + sx_send_command (port, HS_CLOSE, 0, 0); + + if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) { + if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) { + printk (KERN_ERR + "sx: sent the force_close command, but card didn't react\n"); + } else + sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n"); + } + MOD_DEC_USE_COUNT; func_exit (); } @@ -1543,6 +1567,9 @@ static void sx_close (void *ptr) int to = 5 * HZ; func_enter (); + + sx_setsignals (port, 0, 0); + sx_reconfigure_port(port); sx_send_command (port, HS_CLOSE, 0, 0); while (to-- && (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED)) { @@ -1563,6 +1590,11 @@ static void sx_close (void *ptr) sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 5 * HZ - to - 1, port->gs.count); + if(port->gs.count) { + sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count); + port->gs.count = 0; + } + MOD_DEC_USE_COUNT; func_exit (); } diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in index 15e1fd52b516..c1390b2f8267 100644 --- a/drivers/ide/Config.in +++ b/drivers/ide/Config.in @@ -35,8 +35,8 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then define_bool CONFIG_IDEDMA_PCI_EXPERIMENTAL $CONFIG_EXPERIMENTAL dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP - dep_bool ' AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_mbool ' AEC6210 Tuning support (WIP)' CONFIG_AEC6210_TUNING $CONFIG_BLK_DEV_AEC6210 $CONFIG_IDEDMA_PCI_WIP + dep_bool ' AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI + dep_mbool ' AEC62XX Tuning support (WIP)' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX $CONFIG_IDEDMA_PCI_WIP dep_bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3 dep_bool ' AMD Viper support' CONFIG_BLK_DEV_AMD7409 $CONFIG_BLK_DEV_IDEDMA_PCI @@ -62,6 +62,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86 dep_bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI + dep_mbool ' VIA82CXXX Tuning support (WIP)' CONFIG_VIA82CXXX_TUNING $CONFIG_BLK_DEV_VIA82CXXX $CONFIG_IDEDMA_PCI_WIP fi if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 @@ -122,7 +123,7 @@ else fi if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ - "$CONFIG_BLK_DEV_AEC6210" = "y" -o \ + "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \ "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \ "$CONFIG_BLK_DEV_AMD7409" = "y" -o \ "$CONFIG_BLK_DEV_CMD640" = "y" -o \ @@ -136,7 +137,8 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \ "$CONFIG_BLK_DEV_PIIX" = "y" -o \ "$CONFIG_BLK_DEV_SIS5513" = "y" -o \ - "$CONFIG_BLK_DEV_SL82C105" = "y" ]; then + "$CONFIG_BLK_DEV_SL82C105" = "y" -o \ + "$CONFIG_BLK_DEV_VIA82CXXX" = "y" ]; then define_bool CONFIG_BLK_DEV_IDE_MODES y else define_bool CONFIG_BLK_DEV_IDE_MODES n diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 699c48b82407..278ad7ab7038 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -25,8 +25,8 @@ MOD_LIST_NAME := IDE_MODULES LX_OBJS := MX_OBJS := -ifeq ($(CONFIG_BLK_DEV_AEC6210),y) -IDE_OBJS += aec6210.o +ifeq ($(CONFIG_BLK_DEV_AEC62XX),y) +IDE_OBJS += aec62xx.o endif ifeq ($(CONFIG_BLK_DEV_ALI14XX),y) diff --git a/drivers/ide/aec6210.c b/drivers/ide/aec6210.c deleted file mode 100644 index cf41fa3d0ad8..000000000000 --- a/drivers/ide/aec6210.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * linux/drivers/ide/aec6210.c Version 0.06 Mar. 18, 2000 - * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) - * May be copied or modified under the terms of the GNU General Public License - * - * pio 0 :: 40: 00 07 00 00 00 00 00 00 02 07 a6 04 00 02 00 02 - * pio 1 :: 40: 0a 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02 - * pio 2 :: 40: 08 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02 - * pio 3 :: 40: 03 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * pio 4 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * dma 0 :: 40: 0a 07 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * dma 1 :: 40: 02 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * dma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * 50: ff ff ff ff 00 06 04 00 00 00 00 00 00 00 00 00 - * - * udma 0 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00 - * - * udma 1 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00 - * - * udma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00 - * - * auto :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02 - * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00 - * - * auto :: 40: 01 04 01 04 01 04 01 04 02 05 a6 cf 00 02 00 02 - * 50: ff ff ff ff aa 06 04 00 00 00 00 00 00 00 00 00 - * - * NO-Devices - * 40: 00 00 00 00 00 00 00 00 02 05 a6 00 00 02 00 02 - * 50: ff ff ff ff 00 06 00 00 00 00 00 00 00 00 00 00 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "ide_modes.h" - -#define ACARD_DEBUG_DRIVE_INFO 0 - -#undef DISPLAY_AEC6210_TIMINGS - -#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) -#include -#include - -static int aec6210_get_info(char *, char **, off_t, int); -extern int (*aec6210_display_info)(char *, char **, off_t, int); /* ide-proc.c */ -extern char *ide_media_verbose(ide_drive_t *); -static struct pci_dev *bmide_dev; - -static int aec6210_get_info (char *buffer, char **addr, off_t offset, int count) -{ - char *p = buffer; - - u32 bibma = bmide_dev->resource[4].start; - u8 c0 = 0, c1 = 0; - - p += sprintf(p, "\n AEC6210 Chipset.\n"); - - /* - * 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); - - 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, "--------------- 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 " ); - - p += sprintf(p, "UDMA\n"); - p += sprintf(p, "DMA\n"); - p += sprintf(p, "PIO\n"); - return p-buffer;/* => must be less than 4k! */ -} -#endif /* defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) */ - -byte aec6210_proc = 0; - -#ifdef CONFIG_AEC6210_TUNING - -struct chipset_bus_clock_list_entry { - byte xfer_speed; - unsigned short chipset_settings; - byte ultra_settings; -}; - -struct chipset_bus_clock_list_entry aec6210_base [] = { - { XFER_UDMA_2, 0x0401, 0x02 }, - { XFER_UDMA_1, 0x0401, 0x01 }, - { XFER_UDMA_0, 0x0401, 0x01 }, - - { XFER_MW_DMA_2, 0x0401, 0x00 }, - { XFER_MW_DMA_1, 0x0402, 0x00 }, - { XFER_MW_DMA_0, 0x070a, 0x00 }, - - { XFER_PIO_4, 0x0401, 0x00 }, - { XFER_PIO_3, 0x0403, 0x00 }, - { XFER_PIO_2, 0x0708, 0x00 }, - { XFER_PIO_1, 0x070a, 0x00 }, - { XFER_PIO_0, 0x0700, 0x00 }, - { 0, 0x0000, 0x00 } -}; - -extern char *ide_xfer_verbose (byte xfer_rate); - -/* - * TO DO: active tuning and correction of cards without a bios. - */ - -static unsigned short pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table) -{ - for ( ; chipset_table->xfer_speed ; chipset_table++) - if (chipset_table->xfer_speed == speed) { - return chipset_table->chipset_settings; - } - return 0x0000; -} - -static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_entry * chipset_table) -{ - for ( ; chipset_table->xfer_speed ; chipset_table++) - if (chipset_table->xfer_speed == speed) { - return chipset_table->ultra_settings; - } - return 0x00; -} - -static int aec6210_tune_chipset (ide_drive_t *drive, byte speed) -{ - ide_hwif_t *hwif = HWIF(drive); - - int err; - byte drive_pci; - unsigned short drive_conf = 0x0000; - byte ultra = 0x00, ultra_conf = 0x00; - byte tmp1 = 0x00, tmp2 = 0x00; - - int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01)); - - switch(drive_number) { - case 0: drive_pci = 0x40; break; - case 1: drive_pci = 0x42; break; - case 2: drive_pci = 0x44; break; - case 3: drive_pci = 0x46; break; - default: return -1; - } - - pci_read_config_word(HWIF(drive)->pci_dev, drive_pci, &drive_conf); - drive_conf = pci_bus_clock_list(speed, aec6210_base); - pci_write_config_word(HWIF(drive)->pci_dev, drive_pci, drive_conf); - - pci_read_config_byte(HWIF(drive)->pci_dev, 0x54, &ultra); - tmp1 = ((0x00 << (2*drive_number)) | (ultra & ~(3 << (2*drive_number)))); - ultra_conf = pci_bus_clock_list_ultra(speed, aec6210_base); - tmp2 = ((ultra_conf << (2*drive_number)) | (tmp1 & ~(3 << (2*drive_number)))); - pci_write_config_byte(HWIF(drive)->pci_dev, 0x54, tmp2); - - err = ide_config_drive_speed(drive, speed); - -#if ACARD_DEBUG_DRIVE_INFO - printk("%s: %s drive%d 0x04%x 0x02%x 0x02%x 0x02%x 0x02%x\n", - drive->name, ide_xfer_verbose(speed), drive_number, - drive_conf, ultra, tmp1, ultra_conf, tmp2); -#endif /* ACARD_DEBUG_DRIVE_INFO */ - - return(err); -} - -#ifdef CONFIG_BLK_DEV_IDEDMA -static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) -{ - struct hd_driveid *id = drive->id; - byte speed = -1; - - if (drive->media != ide_disk) - return ((int) ide_dma_off_quietly); - - if (((id->dma_ultra & 0x0010) || - (id->dma_ultra & 0x0008) || - (id->dma_ultra & 0x0004)) && (ultra)) { - speed = XFER_UDMA_2; - } else if ((id->dma_ultra & 0x0002) && (ultra)) { - speed = XFER_UDMA_1; - } else if ((id->dma_ultra & 0x0001) && (ultra)) { - 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 { - return ((int) ide_dma_off_quietly); - } - (void) aec6210_tune_chipset(drive, speed); - - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off : - ((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); -} -#endif /* CONFIG_BLK_DEV_IDEDMA */ - -static void aec6210_tune_drive (ide_drive_t *drive, byte pio) -{ - byte speed; - - switch(pio) { - case 5: - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); - case 4: - speed = XFER_PIO_4; break; - case 3: - speed = XFER_PIO_3; break; - case 2: - speed = XFER_PIO_2; break; - case 1: - speed = XFER_PIO_1; break; - default: - speed = XFER_PIO_0; break; - } - (void) aec6210_tune_chipset(drive, speed); -} - -#ifdef CONFIG_BLK_DEV_IDEDMA -static int config_drive_xfer_rate (ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - ide_dma_action_t dma_func = ide_dma_on; - - if (id && (id->capability & 1) && HWIF(drive)->autodma) { - /* Consult the list of known "bad" drives */ - if (ide_dmaproc(ide_dma_bad_drive, drive)) { - dma_func = ide_dma_off; - goto fast_ata_pio; - } - dma_func = ide_dma_off_quietly; - if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { - /* Force if Capable UltraDMA */ - dma_func = config_chipset_for_dma(drive, 1); - if ((id->field_valid & 2) && - (dma_func != ide_dma_on)) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { - /* Force if Capable regular DMA modes */ - dma_func = config_chipset_for_dma(drive, 0); - 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; - } - /* Consult the list of known "good" drives */ - dma_func = config_chipset_for_dma(drive, 0); - if (dma_func != ide_dma_on) - goto no_dma_set; - } else { - goto fast_ata_pio; - } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - dma_func = ide_dma_off_quietly; -no_dma_set: - aec6210_tune_drive(drive, 5); - } - return HWIF(drive)->dmaproc(dma_func, drive); -} - -/* - * aec6210_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. - */ -int aec6210_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 */ -#endif /* CONFIG_AEC6210_TUNING */ - -unsigned int __init pci_init_aec6210 (struct pci_dev *dev, const char *name) -{ - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); - } - -#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) - aec6210_proc = 1; - bmide_dev = dev; - aec6210_display_info = &aec6210_get_info; -#endif /* DISPLAY_AEC6210_TIMINGS && CONFIG_PROC_FS */ - - return dev->irq; -} - -void __init ide_init_aec6210 (ide_hwif_t *hwif) -{ -#ifdef CONFIG_AEC6210_TUNING - hwif->tuneproc = &aec6210_tune_drive; - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - -#ifdef CONFIG_BLK_DEV_IDEDMA - if (hwif->dma_base) - hwif->dmaproc = &aec6210_dmaproc; -#endif /* CONFIG_BLK_DEV_IDEDMA */ -#endif /* CONFIG_AEC6210_TUNING */ -} - -void __init ide_dmacapable_aec6210 (ide_hwif_t *hwif, unsigned long dmabase) -{ - byte dma_new = 0; - byte dma_old = inb(dmabase+2); - byte reg54h = 0; - byte masterdma = hwif->channel ? 0x30 : 0x03; - byte slavedma = hwif->channel ? 0xc0 : 0x0c; - unsigned long flags; - - __save_flags(flags); /* local CPU only */ - __cli(); /* local CPU only */ - - dma_new = dma_old; - - pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); - - if (reg54h & masterdma) dma_new |= 0x20; - if (reg54h & slavedma) dma_new |= 0x40; - if (dma_new != dma_old) outb(dma_new, dmabase+2); - - __restore_flags(flags); /* local CPU only */ - - ide_setup_dma(hwif, dmabase, 8); -} diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c new file mode 100644 index 000000000000..0158b427975b --- /dev/null +++ b/drivers/ide/aec62xx.c @@ -0,0 +1,553 @@ +/* + * linux/drivers/ide/aec62xx.c Version 0.08 Mar. 28, 2000 + * + * Copyright (C) 2000 Andre Hedrick (andre@suse.com) + * May be copied or modified under the terms of the GNU General Public License + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "ide_modes.h" + +#define DISPLAY_AEC62XX_TIMINGS + +#ifndef HIGH_4 +#define HIGH_4(H) ((H)=(H>>4)) +#endif +#ifndef LOW_4 +#define LOW_4(L) ((L)=(L-((L>>4)<<4))) +#endif +#ifndef SPLIT_BYTE +#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) +#endif +#ifndef MAKE_WORD +#define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB)) +#endif + + +#if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS) +#include +#include + +static int aec62xx_get_info(char *, char **, off_t, int); +extern int (*aec62xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static struct pci_dev *bmide_dev; + +static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count) +{ + char *p = buffer; + + u32 bibma = bmide_dev->resource[4].start; + u8 c0 = 0, c1 = 0; + u8 art = 0, uart = 0; + + switch(bmide_dev->device) { + case PCI_DEVICE_ID_ARTOP_ATP850UF: + p += sprintf(p, "\n AEC6210 Chipset.\n"); + break; + case PCI_DEVICE_ID_ARTOP_ATP860: + p += sprintf(p, "\n AEC6260 No Bios Chipset.\n"); + break; + case PCI_DEVICE_ID_ARTOP_ATP860R: + p += sprintf(p, "\n AEC6260 Chipset.\n"); + break; + default: + p += sprintf(p, "\n AEC62?? Chipset.\n"); + break; + } + + /* + * 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); + + p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); + (void) pci_read_config_byte(bmide_dev, 0x4a, &art); + p += sprintf(p, " %sabled %sabled\n", + (art&0x02)?" en":"dis",(art&0x04)?" en":"dis"); + 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 "); + + switch(bmide_dev->device) { + case PCI_DEVICE_ID_ARTOP_ATP850UF: + (void) pci_read_config_byte(bmide_dev, 0x54, &art); + p += sprintf(p, "DMA Mode: %s(%s) %s(%s) %s(%s) %s(%s)\n", + (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO", + (art&0x02)?"2":(art&0x01)?"1":"0", + (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO", + (art&0x08)?"2":(art&0x04)?"1":"0", + (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO", + (art&0x20)?"2":(art&0x10)?"1":"0", + (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO", + (art&0x80)?"2":(art&0x40)?"1":"0"); + (void) pci_read_config_byte(bmide_dev, 0x40, &art); + p += sprintf(p, "Active: 0x%02x", art); + (void) pci_read_config_byte(bmide_dev, 0x42, &art); + p += sprintf(p, " 0x%02x", art); + (void) pci_read_config_byte(bmide_dev, 0x44, &art); + p += sprintf(p, " 0x%02x", art); + (void) pci_read_config_byte(bmide_dev, 0x46, &art); + p += sprintf(p, " 0x%02x\n", art); + (void) pci_read_config_byte(bmide_dev, 0x41, &art); + p += sprintf(p, "Recovery: 0x%02x", art); + (void) pci_read_config_byte(bmide_dev, 0x43, &art); + p += sprintf(p, " 0x%02x", art); + (void) pci_read_config_byte(bmide_dev, 0x45, &art); + p += sprintf(p, " 0x%02x", art); + (void) pci_read_config_byte(bmide_dev, 0x47, &art); + p += sprintf(p, " 0x%02x\n", art); + break; + case PCI_DEVICE_ID_ARTOP_ATP860: + case PCI_DEVICE_ID_ARTOP_ATP860R: + (void) pci_read_config_byte(bmide_dev, 0x44, &art); + p += sprintf(p, "DMA Mode: %s(%s) %s(%s)", + (c0&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", + ((art&0x06)==0x06)?"4":((art&0x05)==0x05)?"4":((art&0x04)==0x04)?"3":((art&0x03)==0x03)?"2":((art&0x02)==0x02)?"1":((art&0x01)==0x01)?"0":"?", + (c0&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", + ((art&0x60)==0x60)?"4":((art&0x50)==0x50)?"4":((art&0x40)==0x40)?"3":((art&0x30)==0x30)?"2":((art&0x20)==0x20)?"1":((art&0x10)==0x10)?"0":"?"); + (void) pci_read_config_byte(bmide_dev, 0x45, &art); + p += sprintf(p, " %s(%s) %s(%s)\n", + (c1&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO", + ((art&0x06)==0x06)?"4":((art&0x05)==0x05)?"4":((art&0x04)==0x04)?"3":((art&0x03)==0x03)?"2":((art&0x02)==0x02)?"1":((art&0x01)==0x01)?"0":"?", + (c1&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO", + ((art&0x60)==0x60)?"4":((art&0x50)==0x50)?"4":((art&0x40)==0x40)?"3":((art&0x30)==0x30)?"2":((art&0x20)==0x20)?"1":((art&0x10)==0x10)?"0":"?"); + (void) pci_read_config_byte(bmide_dev, 0x40, &art); + p += sprintf(p, "Active: 0x%02x", HIGH_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x41, &art); + p += sprintf(p, " 0x%02x", HIGH_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x42, &art); + p += sprintf(p, " 0x%02x", HIGH_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x43, &art); + p += sprintf(p, " 0x%02x\n", HIGH_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x40, &art); + p += sprintf(p, "Recovery: 0x%02x", LOW_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x41, &art); + p += sprintf(p, " 0x%02x", LOW_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x42, &art); + p += sprintf(p, " 0x%02x", LOW_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x43, &art); + p += sprintf(p, " 0x%02x\n", LOW_4(art)); + (void) pci_read_config_byte(bmide_dev, 0x49, &uart); + p += sprintf(p, "reg49h = 0x%02x ", uart); + (void) pci_read_config_byte(bmide_dev, 0x4a, &uart); + p += sprintf(p, "reg4ah = 0x%02x\n", uart); + break; + default: + break; + } + + return p-buffer;/* => must be less than 4k! */ +} +#endif /* defined(DISPLAY_AEC62xx_TIMINGS) && defined(CONFIG_PROC_FS) */ + +byte aec62xx_proc = 0; + +#ifdef CONFIG_AEC62XX_TUNING + +struct chipset_bus_clock_list_entry { + byte xfer_speed; + + byte chipset_settings_34; + byte ultra_settings_34; + + byte chipset_settings_33; + byte ultra_settings_33; +}; + +struct chipset_bus_clock_list_entry aec62xx_base [] = { + { XFER_UDMA_4, 0x41, 0x04, 0x31, 0x05 }, + { XFER_UDMA_3, 0x41, 0x03, 0x31, 0x04 }, + { XFER_UDMA_2, 0x41, 0x02, 0x31, 0x03 }, + { XFER_UDMA_1, 0x41, 0x01, 0x31, 0x02 }, + { XFER_UDMA_0, 0x41, 0x01, 0x31, 0x01 }, + + { XFER_MW_DMA_2, 0x41, 0x00, 0x31, 0x00 }, + { XFER_MW_DMA_1, 0x42, 0x00, 0x31, 0x00 }, + { XFER_MW_DMA_0, 0x7a, 0x00, 0x0a, 0x00 }, + + { XFER_PIO_4, 0x41, 0x00, 0x31, 0x00 }, + { XFER_PIO_3, 0x43, 0x00, 0x33, 0x00 }, + { XFER_PIO_2, 0x78, 0x00, 0x08, 0x00 }, + { XFER_PIO_1, 0x7a, 0x00, 0x0a, 0x00 }, + { XFER_PIO_0, 0x70, 0x00, 0x00, 0x00 }, + { 0, 0x00, 0x00, 0x00, 0x00 } +}; + +extern char *ide_xfer_verbose (byte xfer_rate); + +/* + * TO DO: active tuning and correction of cards without a bios. + */ + +static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table) +{ + for ( ; chipset_table->xfer_speed ; chipset_table++) + if (chipset_table->xfer_speed == speed) { + return ((byte) ((1) ? chipset_table->chipset_settings_33 : chipset_table->chipset_settings_34)); + } + return 0x00; +} + +static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_entry * chipset_table) +{ + for ( ; chipset_table->xfer_speed ; chipset_table++) + if (chipset_table->xfer_speed == speed) { + return ((byte) ((1) ? chipset_table->ultra_settings_33 : chipset_table->ultra_settings_34)); + } + return 0x00; +} + +static int aec6210_tune_chipset (ide_drive_t *drive, byte speed) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + byte unit = (drive->select.b.unit & 0x01); + int drive_number = ((hwif->channel ? 2 : 0) + unit); + int err = 0; + unsigned short d_conf = 0x0000; + byte ultra = 0x00; + byte ultra_conf = 0x00; + byte tmp0 = 0x00; + byte tmp1 = 0x00; + byte tmp2 = 0x00; + unsigned long flags; + + __save_flags(flags); /* local CPU only */ + __cli(); /* local CPU only */ + + pci_read_config_word(dev, 0x40|(2*drive_number), &d_conf); + tmp0 = pci_bus_clock_list(speed, aec62xx_base); + SPLIT_BYTE(tmp0,tmp1,tmp2); + MAKE_WORD(d_conf,tmp1,tmp2); + pci_write_config_word(dev, 0x40|(2*drive_number), d_conf); + + tmp1 = 0x00; + tmp2 = 0x00; + pci_read_config_byte(dev, 0x54, &ultra); + tmp1 = ((0x00 << (2*drive_number)) | (ultra & ~(3 << (2*drive_number)))); + ultra_conf = pci_bus_clock_list_ultra(speed, aec62xx_base); + tmp2 = ((ultra_conf << (2*drive_number)) | (tmp1 & ~(3 << (2*drive_number)))); + pci_write_config_byte(dev, 0x54, tmp2); + + __restore_flags(flags); /* local CPU only */ + + err = ide_config_drive_speed(drive, speed); + return(err); +} + +static int aec6260_tune_chipset (ide_drive_t *drive, byte speed) +{ + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + byte unit = (drive->select.b.unit & 0x01); + int drive_number = ((hwif->channel ? 2 : 0) + unit); + byte ultra_pci = hwif->channel ? 0x45 : 0x44; + int err = 0; + byte drive_conf = 0x00; + byte ultra_conf = 0x00; + byte ultra = 0x00; + byte tmp1 = 0x00; + byte tmp2 = 0x00; + + unsigned long flags; + + __save_flags(flags); /* local CPU only */ + __cli(); /* local CPU only */ + + pci_read_config_byte(dev, 0x40|drive_number, &drive_conf); + drive_conf = pci_bus_clock_list(speed, aec62xx_base); + pci_write_config_byte(dev, 0x40|drive_number, drive_conf); + + pci_read_config_byte(dev, ultra_pci, &ultra); + tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit)))); + ultra_conf = pci_bus_clock_list_ultra(speed, aec62xx_base); + tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); + pci_write_config_byte(dev, ultra_pci, tmp2); + __restore_flags(flags); /* local CPU only */ + + err = ide_config_drive_speed(drive, speed); + return(err); +} + +#ifdef CONFIG_BLK_DEV_IDEDMA +static int config_aec6210_chipset_for_dma (ide_drive_t *drive, byte ultra) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + byte unit = (drive->select.b.unit & 0x01); + unsigned long dma_base = hwif->dma_base; + byte speed = -1; + + if (drive->media != ide_disk) + return ((int) ide_dma_off_quietly); + + if (((id->dma_ultra & 0x0010) || + (id->dma_ultra & 0x0008) || + (id->dma_ultra & 0x0004)) && (ultra)) { + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (ultra)) { + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (ultra)) { + 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 { + return ((int) ide_dma_off_quietly); + } + + outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); + (void) aec6210_tune_chipset(drive, speed); + + return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off : + ((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); +} + +static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra) +{ + struct hd_driveid *id = drive->id; + ide_hwif_t *hwif = HWIF(drive); + 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; + + if (drive->media != ide_disk) + return ((int) ide_dma_off_quietly); + + if ((id->dma_ultra & 0x0010) && (ultra) && (ultra66)) { + speed = XFER_UDMA_4; + } else if ((id->dma_ultra & 0x0008) && (ultra) && (ultra66)) { + speed = XFER_UDMA_3; + } else if ((id->dma_ultra & 0x0004) && (ultra)) { + speed = XFER_UDMA_2; + } else if ((id->dma_ultra & 0x0002) && (ultra)) { + speed = XFER_UDMA_1; + } else if ((id->dma_ultra & 0x0001) && (ultra)) { + 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 { + return ((int) ide_dma_off_quietly); + } + + outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); + (void) aec6260_tune_chipset(drive, speed); + + return ((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); +} + +static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) +{ + switch(HWIF(drive)->pci_dev->device) { + case PCI_DEVICE_ID_ARTOP_ATP850UF: + return config_aec6210_chipset_for_dma(drive, ultra); + case PCI_DEVICE_ID_ARTOP_ATP860: + case PCI_DEVICE_ID_ARTOP_ATP860R: + return config_aec6260_chipset_for_dma(drive, ultra); + default: + return ((int) ide_dma_off_quietly); + } +} + +#endif /* CONFIG_BLK_DEV_IDEDMA */ + +static void aec62xx_tune_drive (ide_drive_t *drive, byte pio) +{ + byte speed; + byte new_pio = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + + switch(pio) { + case 5: speed = new_pio; break; + case 4: speed = XFER_PIO_4; break; + case 3: speed = XFER_PIO_3; break; + case 2: speed = XFER_PIO_2; break; + case 1: speed = XFER_PIO_1; break; + default: speed = XFER_PIO_0; break; + } + + switch(HWIF(drive)->pci_dev->device) { + case PCI_DEVICE_ID_ARTOP_ATP850UF: + (void) aec6210_tune_chipset(drive, speed); + case PCI_DEVICE_ID_ARTOP_ATP860: + case PCI_DEVICE_ID_ARTOP_ATP860R: + (void) aec6260_tune_chipset(drive, speed); + default: + break; + } +} + +#ifdef CONFIG_BLK_DEV_IDEDMA +static int config_drive_xfer_rate (ide_drive_t *drive) +{ + struct hd_driveid *id = drive->id; + ide_dma_action_t dma_func = ide_dma_on; + + if (id && (id->capability & 1) && HWIF(drive)->autodma) { + /* Consult the list of known "bad" drives */ + if (ide_dmaproc(ide_dma_bad_drive, drive)) { + dma_func = ide_dma_off; + goto fast_ata_pio; + } + dma_func = ide_dma_off_quietly; + if (id->field_valid & 4) { + if (id->dma_ultra & 0x001F) { + /* Force if Capable UltraDMA */ + dma_func = config_chipset_for_dma(drive, 1); + if ((id->field_valid & 2) && + (dma_func != ide_dma_on)) + goto try_dma_modes; + } + } else if (id->field_valid & 2) { +try_dma_modes: + if ((id->dma_mword & 0x0007) || + (id->dma_1word & 0x0007)) { + /* Force if Capable regular DMA modes */ + dma_func = config_chipset_for_dma(drive, 0); + 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; + } + /* Consult the list of known "good" drives */ + dma_func = config_chipset_for_dma(drive, 0); + if (dma_func != ide_dma_on) + goto no_dma_set; + } else { + goto fast_ata_pio; + } + } else if ((id->capability & 8) || (id->field_valid & 2)) { +fast_ata_pio: + dma_func = ide_dma_off_quietly; +no_dma_set: + aec62xx_tune_drive(drive, 5); + } + return HWIF(drive)->dmaproc(dma_func, drive); +} + +/* + * aec62xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. + */ +int aec62xx_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 */ +#endif /* CONFIG_AEC62XX_TUNING */ + +unsigned int __init pci_init_aec62xx (struct pci_dev *dev, const char *name) +{ + if (dev->resource[PCI_ROM_RESOURCE].start) { + pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); + printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); + } + +#if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS) + if (!aec62xx_proc) { + aec62xx_proc = 1; + bmide_dev = dev; + aec62xx_display_info = &aec62xx_get_info; + } +#endif /* DISPLAY_AEC62XX_TIMINGS && CONFIG_PROC_FS */ + + return dev->irq; +} + +unsigned int __init ata66_aec62xx (ide_hwif_t *hwif) +{ + byte mask = hwif->channel ? 0x02 : 0x01; + 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); +} + +void __init ide_init_aec62xx (ide_hwif_t *hwif) +{ +#ifdef CONFIG_AEC62XX_TUNING + hwif->tuneproc = &aec62xx_tune_drive; + +#ifdef CONFIG_BLK_DEV_IDEDMA + if (hwif->dma_base) + hwif->dmaproc = &aec62xx_dmaproc; +#else /* !CONFIG_BLK_DEV_IDEDMA */ + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; +#endif /* CONFIG_BLK_DEV_IDEDMA */ +#endif /* CONFIG_AEC62XX_TUNING */ +} + +void __init ide_dmacapable_aec62xx (ide_hwif_t *hwif, unsigned long dmabase) +{ +#ifdef CONFIG_AEC62XX_TUNING + unsigned long flags; + byte reg54h = 0; + + __save_flags(flags); /* local CPU only */ + __cli(); /* local CPU only */ + + pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); + pci_write_config_byte(hwif->pci_dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F)); + + __restore_flags(flags); /* local CPU only */ +#endif /* CONFIG_AEC62XX_TUNING */ + ide_setup_dma(hwif, dmabase, 8); +} diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c index ff87917c5c32..d3bf7b80119c 100644 --- a/drivers/ide/ali14xx.c +++ b/drivers/ide/ali14xx.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -118,7 +119,7 @@ static void ali14xx_tune_drive (ide_drive_t *drive, byte pio) byte param1, param2, param3, param4; unsigned long flags; ide_pio_data_t d; - int bus_speed = ide_system_bus_speed(); + int bus_speed = system_bus_clock(); pio = ide_get_best_pio_mode(drive, pio, ALI_MAX_PIO, &d); diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index b043d6774379..c5f570674a10 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -249,7 +250,7 @@ static void ali15x3_tune_drive (ide_drive_t *drive, byte pio) int s_time, a_time, c_time; byte s_clc, a_clc, r_clc; unsigned long flags; - int bus_speed = ide_system_bus_speed(); + int bus_speed = system_bus_clock(); int port = hwif->index ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; byte cd_dma_fifo = 0; @@ -409,14 +410,14 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra33) static byte ali15x3_can_ultra (ide_drive_t *drive) { -#ifdef CONFIG_WDC_ALI15X3 +#ifndef CONFIG_WDC_ALI15X3 struct hd_driveid *id = drive->id; #endif /* CONFIG_WDC_ALI15X3 */ if (m5229_revision <= 0x20) { return 0; } else if ((m5229_revision < 0xC2) && -#ifdef CONFIG_WDC_ALI15X3 +#ifndef CONFIG_WDC_ALI15X3 ((chip_is_1543c_e && strstr(id->model, "WDC ")) || (drive->media!=ide_disk))) { #else /* CONFIG_WDC_ALI15X3 */ diff --git a/drivers/ide/amd7409.c b/drivers/ide/amd7409.c index 2d44044dddde..14a8a83f15c7 100644 --- a/drivers/ide/amd7409.c +++ b/drivers/ide/amd7409.c @@ -17,6 +17,7 @@ #include #include +#include #include #include diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c index da53155c1816..710b6654d97d 100644 --- a/drivers/ide/buddha.c +++ b/drivers/ide/buddha.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index 7a094d497660..3bf1299320aa 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -111,6 +111,7 @@ #include #include #include +#include #include @@ -595,7 +596,7 @@ static void cmd640_set_mode (unsigned int index, byte pio_mode, unsigned int cyc { int setup_time, active_time, recovery_time, clock_time; byte setup_count, active_count, recovery_count, recovery_count2, cycle_count; - int bus_speed = ide_system_bus_speed(); + int bus_speed = system_bus_clock(); if (pio_mode > 5) pio_mode = 5; diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 2aaf83b2655b..8e100de3c20a 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -19,8 +19,10 @@ #include #include #include +#include #include + #include "ide_modes.h" #ifndef SPLIT_BYTE @@ -271,7 +273,7 @@ static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted) int setup_time, active_time, recovery_time, clock_time, pio_mode, cycle_time; byte recovery_count2, cycle_count; int setup_count, active_count, recovery_count; - int bus_speed = ide_system_bus_speed(); + int bus_speed = system_bus_clock(); /*byte b;*/ ide_pio_data_t d; @@ -645,6 +647,9 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) #endif (void) pci_write_config_byte(dev, DRWTIM23, 0x3f); (void) pci_write_config_byte(dev, DRWTIM3, 0x3f); +#ifdef CONFIG_PPC + (void) pci_write_config_byte(dev, UDIDETCR0, 0xf0); +#endif /* CONFIG_PPC */ #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) if (!cmd64x_proc) { diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 4498b754bc4e..3ecaa31ece2c 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -140,9 +141,8 @@ static int calc_clk (int time, int bus_speed) static void compute_clocks (byte pio, pio_clocks_t *p_pclk) { int clk1, clk2; - int bus_speed; + int bus_speed = system_bus_clock(); /* get speed of PCI bus */ - bus_speed = ide_system_bus_speed(); /* get speed of PCI bus */ /* we don't check against CY82C693's min and max speed, * so you can play with the idebus=xx parameter */ diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c index 28537d048826..16fbceac264f 100644 --- a/drivers/ide/dtc2278.c +++ b/drivers/ide/dtc2278.c @@ -15,6 +15,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c index 096d75fc042d..fa2e4b2ac2c6 100644 --- a/drivers/ide/falconide.c +++ b/drivers/ide/falconide.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index 170bf16f7b60..74806824219b 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c index 1c0b55dace0c..3ba8e55eee71 100644 --- a/drivers/ide/ht6560b.c +++ b/drivers/ide/ht6560b.c @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -203,9 +204,10 @@ static int __init try_to_init_ht6560b(void) static byte ht_pio2timings(ide_drive_t *drive, byte pio) { - int bus_speed, active_time, recovery_time; + int active_time, recovery_time; int active_cycles, recovery_cycles; ide_pio_data_t d; + int bus_speed = system_bus_clock(); if (pio) { pio = ide_get_best_pio_mode(drive, pio, 5, &d); @@ -215,7 +217,6 @@ static byte ht_pio2timings(ide_drive_t *drive, byte pio) * actual cycle time for recovery and activity * according system bus speed. */ - bus_speed = ide_system_bus_speed(); active_time = ide_pio_timings[pio].active_time; recovery_time = d.cycle_time - active_time diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 213ddbff0758..8ef0f9356e1b 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 17cc3eb88d4a..66397d93e71a 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -3,7 +3,7 @@ * * Copyright (C) 1994, 1995, 1996 scott snyder * Copyright (C) 1996-1998 Erik Andersen - * Copyright (C) 1998, 1999 Jens Axboe + * Copyright (C) 1998-2000 Jens Axboe * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. @@ -16,8 +16,8 @@ * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI * (SFF-8020i rev 2.6) standards. These documents can be obtained by * anonymous ftp from: - * ftp://fission.dt.wdc.com/pub/standards/SFF/specs/INF-8020.PDF - * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r01.pdf + * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps + * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf * * Drives that deviate from these standards will be accomodated as much * as possible via compile time or command-line options. Since I only have @@ -272,10 +272,19 @@ * - Fixed a problem with WPI CDS-32X drive - it * failed the capabilities * + * 4.57 Apr 7, 2000 - Fixed sense reporting. + * - Fixed possible oops in ide_cdrom_get_last_session() + * - Fix locking mania and make ide_cdrom_reset relock + * - Stop spewing errors to log when magicdev polls with + * TEST_UNIT_READY on some drives. + * - Various fixes from Tobias Ringstrom: + * tray if it was locked prior to the reset. + * - cdrom_read_capacity returns one frame too little. + * - Fix real capacity reporting. * *************************************************************************/ -#define IDECD_VERSION "4.56" +#define IDECD_VERSION "4.57" #include #include @@ -314,11 +323,12 @@ static void cdrom_saw_media_change (ide_drive_t *drive) static -void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf, - struct packet_command *failed_command) +void cdrom_analyze_sense_data(ide_drive_t *drive, + struct packet_command *failed_command, + struct request_sense *sense) { - if (reqbuf->sense_key == NOT_READY || - reqbuf->sense_key == UNIT_ATTENTION) { + if (sense->sense_key == NOT_READY || + sense->sense_key == UNIT_ATTENTION) { /* Make good and sure we've seen this potential media change. Some drives (i.e. Creative) fail to present the correct sense key in the error register. */ @@ -330,13 +340,14 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf, uses this command to poll the drive, and we don't want to fill the syslog with useless errors. */ if (failed_command && - failed_command->c[0] == GPCMD_READ_SUBCHANNEL) + (failed_command->c[0] == GPCMD_READ_SUBCHANNEL || + failed_command->c[0] == GPCMD_TEST_UNIT_READY)) return; } - if (reqbuf->error_code == 0x70 && reqbuf->sense_key == 0x02 - && ((reqbuf->asc == 0x3a && reqbuf->ascq == 0x00) || - (reqbuf->asc == 0x04 && reqbuf->ascq == 0x01))) + if (sense->error_code == 0x70 && sense->sense_key == 0x02 + && ((sense->asc == 0x3a && sense->ascq == 0x00) || + (sense->asc == 0x04 && sense->ascq == 0x01))) { /* * Suppress the following errors: @@ -353,30 +364,32 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf, char buf[80]; printk ("ATAPI device %s:\n", drive->name); - if (reqbuf->error_code==0x70) + if (sense->error_code==0x70) printk(" Error: "); - else if (reqbuf->error_code==0x71) + else if (sense->error_code==0x71) printk(" Deferred Error: "); + else if (sense->error_code == 0x7f) + printk(" Vendor-specific Error: "); else printk(" Unknown Error Type: "); - if ( reqbuf->sense_key < ARY_LEN (sense_key_texts)) - s = sense_key_texts[reqbuf->sense_key]; + if (sense->sense_key < ARY_LEN(sense_key_texts)) + s = sense_key_texts[sense->sense_key]; else s = "bad sense key!"; - printk ("%s -- (Sense key=0x%02x)\n", s, reqbuf->sense_key); + printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key); - if (reqbuf->asc == 0x40) { - sprintf (buf, "Diagnostic failure on component 0x%02x", - reqbuf->ascq); + if (sense->asc == 0x40) { + sprintf(buf, "Diagnostic failure on component 0x%02x", + sense->ascq); s = buf; } else { - int lo=0, mid, hi=ARY_LEN (sense_data_texts); - unsigned long key = (reqbuf->sense_key << 16); - key |= (reqbuf->asc << 8); - if ( ! (reqbuf->ascq >= 0x80 && reqbuf->ascq <= 0xdd) ) - key |= reqbuf->ascq; + int lo = 0, mid, hi = ARY_LEN(sense_data_texts); + unsigned long key = (sense->sense_key << 16); + key |= (sense->asc << 8); + if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd)) + key |= sense->ascq; s = NULL; while (hi > lo) { @@ -394,14 +407,14 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf, } if (s == NULL) { - if (reqbuf->asc > 0x80) + if (sense->asc > 0x80) s = "(vendor-specific error)"; else s = "(reserved error code)"; } - printk (" %s -- (asc=0x%02x, ascq=0x%02x)\n", - s, reqbuf->asc, reqbuf->ascq); + printk(" %s -- (asc=0x%02x, ascq=0x%02x)\n", + s, sense->asc, sense->ascq); if (failed_command != NULL) { @@ -431,21 +444,21 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf, * In the case of NOT_READY, if SKSV is set the drive can * give us nice ETA readings. */ - if (reqbuf->sense_key == NOT_READY && (reqbuf->sks[0] & 0x80)) { - int progress = (reqbuf->sks[1] << 8 | reqbuf->sks[2]) * 100; + if (sense->sense_key == NOT_READY && (sense->sks[0] & 0x80)) { + int progress = (sense->sks[1] << 8 | sense->sks[2]) * 100; printk(" Command is %02d%% complete\n", progress / 0xffff); } - if (reqbuf->sense_key == ILLEGAL_REQUEST && - (reqbuf->sks[0] & 0x80) != 0) { - printk (" Error in %s byte %d", - (reqbuf->sks[0] & 0x40) != 0 ? + if (sense->sense_key == ILLEGAL_REQUEST && + (sense->sks[0] & 0x80) != 0) { + printk(" Error in %s byte %d", + (sense->sks[0] & 0x40) != 0 ? "command packet" : "command data", - (reqbuf->sks[1] << 8) + reqbuf->sks[2]); + (sense->sks[1] << 8) + sense->sks[2]); - if ((reqbuf->sks[0] & 0x40) != 0) - printk (" bit %d", reqbuf->sks[0] & 0x07); + if ((sense->sks[0] & 0x40) != 0) + printk (" bit %d", sense->sks[0] & 0x07); printk ("\n"); } @@ -456,45 +469,43 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf, /* Suppress printing unit attention and `in progress of becoming ready' errors when we're not being verbose. */ - if (reqbuf->sense_key == UNIT_ATTENTION || - (reqbuf->sense_key == NOT_READY && (reqbuf->asc == 4 || - reqbuf->asc == 0x3a))) + if (sense->sense_key == UNIT_ATTENTION || + (sense->sense_key == NOT_READY && (sense->asc == 4 || + sense->asc == 0x3a))) return; - printk ("%s: error code: 0x%02x sense_key: 0x%02x asc: 0x%02x ascq: 0x%02x\n", + printk("%s: error code: 0x%02x sense_key: 0x%02x asc: 0x%02x ascq: 0x%02x\n", drive->name, - reqbuf->error_code, reqbuf->sense_key, - reqbuf->asc, reqbuf->ascq); + sense->error_code, sense->sense_key, + sense->asc, sense->ascq); #endif /* not VERBOSE_IDE_CD_ERRORS */ } -static void cdrom_queue_request_sense (ide_drive_t *drive, - struct semaphore *sem, - struct packet_command *failed_command) +static void cdrom_queue_request_sense(ide_drive_t *drive, + struct semaphore *sem, + struct request_sense *sense, + struct packet_command *failed_command) { struct cdrom_info *info = drive->driver_data; struct request *rq; - struct packet_command *pc; + struct packet_command *pc = &info->request_sense_pc; - /* Make up a new request to retrieve sense information. */ - pc = &info->request_sense_pc; - memset(pc, 0, sizeof (*pc)); + if (sense == NULL) + sense = &info->sense_data; + memset(pc, 0, sizeof(struct packet_command)); pc->c[0] = GPCMD_REQUEST_SENSE; - - /* just get the first 18 bytes of the sense info, there might not - * be more available */ pc->c[4] = pc->buflen = 18; - pc->buffer = (char *)&info->sense_data; - pc->sense_data = (struct request_sense *)failed_command; + pc->buffer = (char *) sense; + pc->sense = (struct request_sense *) failed_command; /* stuff the sense request in front of our current request */ rq = &info->request_sense_request; - ide_init_drive_cmd (rq); + ide_init_drive_cmd(rq); rq->cmd = REQUEST_SENSE_COMMAND; - rq->buffer = (char *)pc; + rq->buffer = (char *) pc; rq->sem = sem; - (void) ide_do_drive_cmd (drive, rq, ide_preempt); + (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -503,11 +514,10 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive) struct request *rq = HWGROUP(drive)->rq; if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) { - struct packet_command *pc = (struct packet_command *) - rq->buffer; - cdrom_analyze_sense_data (drive, - (struct request_sense *) (pc->buffer - pc->c[4]), - (struct packet_command *) pc->sense_data); + struct packet_command *pc = (struct packet_command *)rq->buffer; + cdrom_analyze_sense_data(drive, + (struct packet_command *) pc->sense, + (struct request_sense *) (pc->buffer - pc->c[4])); } if (rq->cmd == READ && !rq->current_nr_sectors) uptodate = 1; @@ -523,7 +533,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, { struct request *rq = HWGROUP(drive)->rq; int stat, cmd, err, sense_key; - struct packet_command *pc = (struct packet_command *) rq->buffer; + struct packet_command *pc; /* Check for errors. */ stat = GET_STAT(); @@ -547,6 +557,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, from the drive (probably while trying to recover from a former error). Just give up. */ + pc = (struct packet_command *) rq->buffer; pc->stat = 1; cdrom_end_request (1, drive); *startstop = ide_error (drive, "request sense failure", stat); @@ -556,6 +567,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, /* All other functions, except for READ. */ struct semaphore *sem = NULL; + pc = (struct packet_command *) rq->buffer; /* Check for tray open. */ if (sense_key == NOT_READY) { @@ -589,7 +601,8 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, cdrom_end_request (1, drive); if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense(drive, sem, pc); + cdrom_queue_request_sense(drive, sem, pc->sense, + pc); } else { /* Handle errors from READ requests. */ @@ -628,7 +641,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive, /* If we got a CHECK_CONDITION status, queue a request sense command. */ if ((stat & ERR_STAT) != 0) - cdrom_queue_request_sense(drive, NULL, NULL); + cdrom_queue_request_sense(drive, NULL, NULL, NULL); } } @@ -1062,11 +1075,11 @@ static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive) pc.c[0] = GPCMD_READ_10; pc.c[7] = (nframes >> 8); pc.c[8] = (nframes & 0xff); - put_unaligned(htonl (frame), (unsigned int *) &pc.c[2]); + put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]); /* Send the command to the drive and return. */ - return cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c), - &cdrom_read_intr); + return cdrom_transfer_packet_command(drive, pc.c, sizeof(pc.c), + &cdrom_read_intr); } @@ -1178,7 +1191,8 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block) */ /* Forward declarations. */ -static int cdrom_lockdoor(ide_drive_t *drive, int lockflag); +static int cdrom_lockdoor(ide_drive_t *drive, int lockflag, + struct request_sense *sense); /* Interrupt routine for packet command completion. */ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) @@ -1186,11 +1200,8 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) int ireason, len, stat, thislen; struct request *rq = HWGROUP(drive)->rq; struct packet_command *pc = (struct packet_command *)rq->buffer; - struct cdrom_info *info = drive->driver_data; ide_startstop_t startstop; - pc->sense_data = &info->sense_data; - /* Check for errors. */ if (cdrom_decode_status (&startstop, drive, 0, &stat)) return startstop; @@ -1320,8 +1331,12 @@ void cdrom_sleep (int time) static int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc) { - int retries = 10; + struct request_sense sense; struct request req; + int retries = 10; + + if (pc->sense == NULL) + pc->sense = &sense; /* Start of retry loop. */ do { @@ -1337,7 +1352,7 @@ int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc) /* The request failed. Retry if it was due to a unit attention status (usually means media was changed). */ - struct request_sense *reqbuf = pc->sense_data; + struct request_sense *reqbuf = pc->sense; if (reqbuf->sense_key == UNIT_ATTENTION) cdrom_saw_media_change (drive); @@ -1358,24 +1373,7 @@ int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc) } while (pc->stat != 0 && retries >= 0); /* Return an error if the command failed. */ - if (pc->stat) - return -EIO; - - /* The command succeeded. If it was anything other than - a request sense, eject, or door lock command, - and we think that the door is presently unlocked, lock it - again. (The door was probably unlocked via an explicit - CDROMEJECT ioctl.) */ - if (CDROM_STATE_FLAGS (drive)->door_locked == 0 && - (pc->c[0] != GPCMD_TEST_UNIT_READY && - pc->c[0] != GPCMD_REQUEST_SENSE && - pc->c[0] != GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL && - pc->c[0] != GPCMD_START_STOP_UNIT && - pc->c[0] != GPCMD_MODE_SENSE_10 && - pc->c[0] != GPCMD_MODE_SELECT_10)) { - (void) cdrom_lockdoor (drive, 1); - } - return 0; + return pc->stat ? -EIO : 0; } /**************************************************************************** @@ -1483,13 +1481,14 @@ int msf_to_lba (byte m, byte s, byte f) return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; } -static int cdrom_check_status (ide_drive_t *drive) +static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) { struct packet_command pc; struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = &info->devinfo; memset(&pc, 0, sizeof(pc)); + pc.sense = sense; pc.c[0] = GPCMD_TEST_UNIT_READY; @@ -1506,24 +1505,26 @@ static int cdrom_check_status (ide_drive_t *drive) /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ static int -cdrom_lockdoor(ide_drive_t *drive, int lockflag) +cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense) { - struct request_sense *sense; + struct request_sense my_sense; struct packet_command pc; int stat; + if (sense == NULL) + sense = &my_sense; + /* If the drive cannot lock the door, just pretend. */ - if (CDROM_CONFIG_FLAGS (drive)->no_doorlock) + if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) { stat = 0; - else { + } else { memset(&pc, 0, sizeof(pc)); + pc.sense = sense; pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; pc.c[4] = (lockflag != 0); stat = cdrom_queue_packet_command (drive, &pc); } - sense = pc.sense_data; - /* If we got an illegal field error, the drive probably cannot lock the door. */ if (stat != 0 && @@ -1548,7 +1549,8 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag) /* Eject the disk if EJECTFLAG is 0. If EJECTFLAG is 1, try to reload the disk. */ -static int cdrom_eject(ide_drive_t *drive, int ejectflag) +static int cdrom_eject(ide_drive_t *drive, int ejectflag, + struct request_sense *sense) { struct packet_command pc; @@ -1560,13 +1562,15 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag) return 0; memset(&pc, 0, sizeof (pc)); + pc.sense = sense; pc.c[0] = GPCMD_START_STOP_UNIT; pc.c[4] = 0x02 + (ejectflag != 0); return cdrom_queue_packet_command (drive, &pc); } -static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity) +static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity, + struct request_sense *sense) { struct { __u32 lba; @@ -1576,7 +1580,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity) int stat; struct packet_command pc; - memset(&pc, 0, sizeof (pc)); + memset(&pc, 0, sizeof(pc)); + pc.sense = sense; pc.c[0] = GPCMD_READ_CDVD_CAPACITY; pc.buffer = (char *)&capbuf; @@ -1584,17 +1589,19 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity) stat = cdrom_queue_packet_command(drive, &pc); if (stat == 0) - *capacity = be32_to_cpu(capbuf.lba); + *capacity = 1 + be32_to_cpu(capbuf.lba); return stat; } static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, - int format, char *buf, int buflen) + int format, char *buf, int buflen, + struct request_sense *sense) { struct packet_command pc; memset(&pc, 0, sizeof(pc)); + pc.sense = sense; pc.buffer = buf; pc.buflen = buflen; @@ -1612,12 +1619,11 @@ 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) +static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) { int stat, ntracks, i; struct cdrom_info *info = drive->driver_data; struct atapi_toc *toc = info->toc; - int minor = drive->select.b.unit << PARTN_BITS; struct { struct atapi_toc_header hdr; struct atapi_toc_entry ent; @@ -1637,13 +1643,13 @@ static int cdrom_read_toc (ide_drive_t *drive) /* Check to see if the existing data is still valid. If it is, just return. */ if (CDROM_STATE_FLAGS (drive)->toc_valid) - (void) cdrom_check_status(drive); + (void) cdrom_check_status(drive, sense); if (CDROM_STATE_FLAGS (drive)->toc_valid) return 0; /* First read just the header, so we know how long the TOC is. */ - stat = cdrom_read_tocentry (drive, 0, 1, 0, (char *)&toc->hdr, - sizeof (struct atapi_toc_header)); + stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr, + sizeof(struct atapi_toc_header), sense); if (stat) return stat; #if ! STANDARD_ATAPI @@ -1658,10 +1664,11 @@ static int cdrom_read_toc (ide_drive_t *drive) if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS; /* Now read the whole schmeer. */ - stat = cdrom_read_tocentry (drive, toc->hdr.first_track, 1, 0, (char *)&toc->hdr, - sizeof (struct atapi_toc_header) + - (ntracks + 1) * - sizeof (struct atapi_toc_entry)); + stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0, + (char *)&toc->hdr, + sizeof(struct atapi_toc_header) + + (ntracks + 1) * + sizeof(struct atapi_toc_entry), sense); if (stat && toc->hdr.first_track > 1) { /* Cds with CDI tracks only don't have any TOC entries, @@ -1674,11 +1681,12 @@ static int cdrom_read_toc (ide_drive_t *drive) the readable TOC is empty (CDI tracks are not included) and only holds the Leadout entry. Heiko Eißfeldt */ ntracks = 0; - stat = cdrom_read_tocentry (drive, CDROM_LEADOUT, 1, - 0, (char *)&toc->hdr, - sizeof (struct atapi_toc_header) + - (ntracks+1) * - sizeof (struct atapi_toc_entry)); + stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0, + (char *)&toc->hdr, + sizeof(struct atapi_toc_header) + + (ntracks + 1) * + sizeof(struct atapi_toc_entry), + sense); if (stat) { return stat; } @@ -1722,8 +1730,8 @@ static int cdrom_read_toc (ide_drive_t *drive) /* Read the multisession information. */ if (toc->hdr.first_track != CDROM_LEADOUT) { /* Read the multisession information. */ - stat = cdrom_read_tocentry (drive, 0, 1, 1, - (char *)&ms_tmp, sizeof (ms_tmp)); + stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp, + sizeof(ms_tmp), sense); if (stat) return stat; } else { ms_tmp.ent.addr.msf.minute = 0; @@ -1749,45 +1757,23 @@ static int cdrom_read_toc (ide_drive_t *drive) (long *)&toc->capacity); if (stat) #endif - stat = cdrom_read_capacity (drive, &toc->capacity); + stat = cdrom_read_capacity(drive, &toc->capacity, sense); if (stat) toc->capacity = 0x1fffff; - /* for general /dev/cdrom like mounting, one big disc */ - drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME; - HWIF(drive)->gd->sizes[minor] = (toc->capacity * SECTORS_PER_FRAME) >> - (BLOCK_SIZE_BITS - 9); - /* Remember that we've read this stuff. */ CDROM_STATE_FLAGS (drive)->toc_valid = 1; - /* should be "if multisession", but it does no harm. */ - if (ntracks == 1) - return 0; - - /* setup each minor to respond to a session */ - minor++; - i = toc->hdr.first_track; - while ((i <= ntracks) && ((minor & CD_PART_MASK) < CD_PART_MAX)) { - drive->part[minor & PARTN_MASK].start_sect = 0; - drive->part[minor & PARTN_MASK].nr_sects = - (toc->ent[i].addr.lba * - SECTORS_PER_FRAME) << (BLOCK_SIZE_BITS - 9); - HWIF(drive)->gd->sizes[minor] = (toc->ent[i].addr.lba * - SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9); - i++; - minor++; - } - return 0; } static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, - int buflen) + int buflen, struct request_sense *sense) { struct packet_command pc; memset(&pc, 0, sizeof(pc)); + pc.sense = sense; pc.buffer = buf; pc.buflen = buflen; @@ -1802,10 +1788,12 @@ static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, /* ATAPI cdrom drives are free to select the speed you request or any slower rate :-( Requesting too fast a speed will _not_ produce an error. */ -static int cdrom_select_speed (ide_drive_t *drive, int speed) +static int cdrom_select_speed(ide_drive_t *drive, int speed, + struct request_sense *sense) { struct packet_command pc; memset(&pc, 0, sizeof(pc)); + pc.sense = sense; if (speed == 0) speed = 0xffff; /* set to max */ @@ -1825,7 +1813,7 @@ static int cdrom_select_speed (ide_drive_t *drive, int speed) pc.c[5] = speed & 0xff; } - return cdrom_queue_packet_command (drive, &pc); + return cdrom_queue_packet_command(drive, &pc); } @@ -1869,10 +1857,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi, pc.buffer = cgc->buffer; pc.buflen = cgc->buflen; cgc->stat = cdrom_queue_packet_command(drive, &pc); - - /* There was an error, assign sense. */ - if (cgc->stat) - cgc->sense = pc.sense_data; + cgc->sense = pc.sense; return cgc->stat; } @@ -1938,7 +1923,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi, struct atapi_toc *toc; /* Make sure our saved TOC is valid. */ - stat = cdrom_read_toc(drive); + stat = cdrom_read_toc(drive, NULL); if (stat) return stat; toc = info->toc; @@ -1978,11 +1963,22 @@ static int ide_cdrom_reset (struct cdrom_device_info *cdi) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; + struct request_sense sense; struct request req; + int ret; ide_init_drive_cmd (&req); req.cmd = RESET_DRIVE_COMMAND; - return ide_do_drive_cmd (drive, &req, ide_wait); + ret = ide_do_drive_cmd(drive, &req, ide_wait); + + /* + * A reset will unlock the door. If it was previously locked, + * lock it again. + */ + if (CDROM_STATE_FLAGS(drive)->door_locked) + (void) cdrom_lockdoor(drive, 1, &sense); + + return ret; } @@ -1990,20 +1986,21 @@ static int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; + struct request_sense sense; if (position) { - int stat = cdrom_lockdoor (drive, 0); + int stat = cdrom_lockdoor(drive, 0, &sense); if (stat) return stat; } - return cdrom_eject(drive, !position); + return cdrom_eject(drive, !position, &sense); } static int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; - return cdrom_lockdoor (drive, lock); + return cdrom_lockdoor(drive, lock, NULL); } #undef __ACER50__ @@ -2060,21 +2057,20 @@ static int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) { #ifndef __ACER50__ - int stat, attempts = 3; - ide_drive_t *drive = (ide_drive_t*) cdi->handle; - struct cdrom_generic_command cgc; + int attempts = 3; struct { char pad[8]; struct atapi_capabilities_page cap; } buf; #else - int stat; - ide_drive_t *drive = (ide_drive_t*) cdi->handle; - struct cdrom_generic_command cgc; struct get_capabilities_buf buf; #endif /* __ACER50__ */ + ide_drive_t *drive = (ide_drive_t*) cdi->handle; + struct cdrom_generic_command cgc; + struct request_sense sense; + int stat; - if ((stat = cdrom_select_speed (drive, speed)) < 0) + if ((stat = cdrom_select_speed (drive, speed, &sense)) < 0) return stat; init_cdrom_command(&cgc, &buf, sizeof(buf), CGC_DATA_UNKNOWN); @@ -2112,19 +2108,18 @@ static int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; - struct cdrom_info *info = drive->driver_data; if (slot_nr == CDSL_CURRENT) { - struct request_sense *sense = &info->sense_data; - int stat = cdrom_check_status(drive); - if (stat == 0 || sense->sense_key == UNIT_ATTENTION) + struct request_sense sense; + int stat = cdrom_check_status(drive, &sense); + if (stat == 0 || sense.sense_key == UNIT_ATTENTION) return CDS_DISC_OK; - if (sense->sense_key == NOT_READY && sense->asc == 0x04 && - sense->ascq == 0x04) + if (sense.sense_key == NOT_READY && sense.asc == 0x04 && + sense.ascq == 0x04) return CDS_DISC_OK; - if (sense->sense_key == NOT_READY) { + if (sense.sense_key == NOT_READY) { /* ATAPI doesn't have anything that can help us decide whether the drive is really emtpy or the tray is just open. irk. */ @@ -2132,9 +2127,8 @@ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr) } return CDS_DRIVE_NOT_READY; - } else { - return -EINVAL; } + return -EINVAL; } static @@ -2144,8 +2138,14 @@ int ide_cdrom_get_last_session (struct cdrom_device_info *cdi, struct atapi_toc *toc; ide_drive_t *drive = (ide_drive_t*) cdi->handle; struct cdrom_info *info = drive->driver_data; + struct request_sense sense; + int ret; toc = info->toc; + if (!CDROM_STATE_FLAGS(drive)->toc_valid || toc == NULL) + if ((ret = cdrom_read_toc(drive, &sense))) + return ret; + ms_info->addr.lba = toc->last_session_lba; ms_info->xa_flag = toc->xa_flag; @@ -2161,7 +2161,7 @@ int ide_cdrom_get_mcn (struct cdrom_device_info *cdi, ide_drive_t *drive = (ide_drive_t*) cdi->handle; /* get MCN */ - if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf)))) + if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL))) return stat; memcpy (mcn_info->medium_catalog_number, mcnbuf+9, @@ -2183,11 +2183,13 @@ int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi, int slot_nr) { ide_drive_t *drive = (ide_drive_t*) cdi->handle; + int retval; if (slot_nr == CDSL_CURRENT) { - (void) cdrom_check_status(drive); + (void) cdrom_check_status(drive, NULL); + retval = CDROM_STATE_FLAGS (drive)->media_changed; CDROM_STATE_FLAGS (drive)->media_changed = 0; - return CDROM_STATE_FLAGS (drive)->media_changed; + return retval; } else { return -EINVAL; } @@ -2600,6 +2602,37 @@ int ide_cdrom_check_media_change (ide_drive_t *drive) (drive->select.b.unit)<driver_data; + struct atapi_toc *toc; + int minor = drive->select.b.unit << PARTN_BITS; + struct request_sense sense; + + cdrom_read_toc(drive, &sense); + + if (!CDROM_STATE_FLAGS(drive)->toc_valid) + return; + + toc = info->toc; + + /* for general /dev/cdrom like mounting, one big disc */ + drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME; + HWIF(drive)->gd->sizes[minor] = toc->capacity * BLOCKS_PER_FRAME; + + blk_size[HWIF(drive)->major] = HWIF(drive)->gd->sizes; +} + +static +unsigned long ide_cdrom_capacity (ide_drive_t *drive) +{ + unsigned capacity; + + capacity = cdrom_read_capacity(drive, &capacity, NULL); + return capacity ? 0 : capacity * SECTORS_PER_FRAME; +} + static int ide_cdrom_cleanup(ide_drive_t *drive) { @@ -2635,13 +2668,14 @@ static ide_driver_t ide_cdrom_driver = { ide_cdrom_open, /* open */ ide_cdrom_release, /* release */ ide_cdrom_check_media_change, /* media_change */ + ide_cdrom_revalidate, /* revalidate */ NULL, /* pre_reset */ - NULL, /* capacity */ + ide_cdrom_capacity, /* capacity */ NULL, /* special */ NULL /* proc */ }; -int ide_cdrom_init (void); +int ide_cdrom_init(void); static ide_module_t ide_cdrom_module = { IDE_DRIVER_MODULE, ide_cdrom_init, @@ -2670,7 +2704,7 @@ void __exit ide_cdrom_exit(void) } #endif /* MODULE */ -int ide_cdrom_init (void) +int ide_cdrom_init(void) { ide_drive_t *drive; struct cdrom_info *info; diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 77937dd4b983..3c685d5bfe57 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -43,6 +43,8 @@ #define SECTOR_BUFFER_SIZE (CD_FRAMESIZE * 32) #define SECTORS_BUFFER (SECTOR_BUFFER_SIZE / SECTOR_SIZE) +#define BLOCKS_PER_FRAME (CD_FRAMESIZE / BLOCK_SIZE) + #define MIN(a,b) ((a) < (b) ? (a) : (b)) /* special command codes for strategy routine. */ @@ -103,7 +105,7 @@ struct packet_command { char *buffer; int buflen; int stat; - struct request_sense *sense_data; + struct request_sense *sense; unsigned char c[12]; }; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index e8cfa5c7a767..66bf35a70c0d 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -512,6 +512,13 @@ static int idedisk_media_change (ide_drive_t *drive) return drive->removable; /* if removable, always assume it was changed */ } +static void idedisk_revalidate (ide_drive_t *drive) +{ + grok_partitions(HWIF(drive)->gd, drive->select.b.unit, + 1<capacity, the full capacity of the drive * Called with drive->id != NULL. @@ -726,6 +733,7 @@ static ide_driver_t idedisk_driver = { idedisk_open, /* open */ idedisk_release, /* release */ idedisk_media_change, /* media_change */ + idedisk_revalidate, /* revalidate */ idedisk_pre_reset, /* pre_reset */ idedisk_capacity, /* capacity */ idedisk_special, /* special */ diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 9caffd2f1d88..835fa91e34e4 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -368,7 +368,13 @@ int report_drive_dmaing (ide_drive_t *drive) } } else if ((id->field_valid & 4) && (id->dma_ultra & (id->dma_ultra >> 8) & 7)) { - printk(", UDMA(33)"); /* UDMA BIOS-enabled! */ + if ((id->dma_ultra >> 10) & 1) { + printk(", UDMA(33)"); /* UDMA BIOS-enabled! */ + } else if ((id->dma_ultra >> 9) & 1) { + printk(", UDMA(25)"); /* UDMA BIOS-enabled! */ + } else { + printk(", UDMA(16)"); /* UDMA BIOS-enabled! */ + } } else if (id->field_valid & 4) { printk(", (U)DMA"); /* Can be BIOS-enabled! */ } else { diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 55349e92aef5..1130bd3d5dbf 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -1375,6 +1375,16 @@ static int idefloppy_media_change (ide_drive_t *drive) return test_and_clear_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags); } +/* + * Revalidate the new media. Should set blk_size[] + */ +static void idefloppy_revalidate (ide_drive_t *drive) +{ + grok_partitions(HWIF(drive)->gd, drive->select.b.unit, + 1<irq; default: break; @@ -592,6 +601,7 @@ check_if_enabled: } #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_HPT34X)) autodma = 0; if (autodma) @@ -599,6 +609,8 @@ check_if_enabled: if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) || diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index d8edb89c5107..cf49e1a66c26 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c @@ -17,6 +17,8 @@ */ #include +#include + #include #ifndef PREPARE_FUNC diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 200204ee60fa..7c5130e77f5f 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -204,6 +204,10 @@ static int try_to_identify (ide_drive_t *drive, byte cmd) hd_status = IDE_STATUS_REG; } + /* set features register for atapi identify command to be sure of reply */ + if ((cmd == WIN_PIDENTIFY)) + OUT_BYTE(0,IDE_FEATURE_REG); /* disable dma & overlap */ + #if CONFIG_BLK_DEV_PDC4030 if (HWIF(drive)->chipset == ide_pdc4030) { /* DC4030 hosted drives need their own identify... */ diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index fd33e4e42c72..efc0ea717274 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -73,10 +73,10 @@ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif -#ifdef CONFIG_BLK_DEV_AEC6210 -extern byte aec6210_proc; -int (*aec6210_display_info)(char *, char **, off_t, int) = NULL; -#endif /* CONFIG_BLK_DEV_AEC6210 */ +#ifdef CONFIG_BLK_DEV_AEC62XX +extern byte aec62xx_proc; +int (*aec62xx_display_info)(char *, char **, off_t, int) = NULL; +#endif /* CONFIG_BLK_DEV_AEC62XX */ #ifdef CONFIG_BLK_DEV_ALI15X3 extern byte ali_proc; int (*ali_display_info)(char *, char **, off_t, int) = NULL; @@ -801,10 +801,10 @@ void proc_ide_create(void) create_proc_read_entry("drivers", 0, proc_ide_root, proc_ide_read_drivers, NULL); -#ifdef CONFIG_BLK_DEV_AEC6210 - if ((aec6210_display_info) && (aec6210_proc)) - create_proc_info_entry("aec6210", 0, proc_ide_root, aec6210_display_info); -#endif /* CONFIG_BLK_DEV_AEC6210 */ +#ifdef CONFIG_BLK_DEV_AEC62XX + if ((aec62xx_display_info) && (aec62xx_proc)) + create_proc_info_entry("aec62xx", 0, proc_ide_root, aec62xx_display_info); +#endif /* CONFIG_BLK_DEV_AEC62XX */ #ifdef CONFIG_BLK_DEV_ALI15X3 if ((ali_display_info) && (ali_proc)) create_proc_info_entry("ali", 0, proc_ide_root, ali_display_info); @@ -853,10 +853,10 @@ void proc_ide_destroy(void) * Mmmm.. does this free up all resources, * or do we need to do a more proper cleanup here ?? */ -#ifdef CONFIG_BLK_DEV_AEC6210 - if ((aec6210_display_info) && (aec6210_proc)) - remove_proc_entry("ide/aec6210",0); -#endif /* CONFIG_BLK_DEV_AEC6210 */ +#ifdef CONFIG_BLK_DEV_AEC62XX + if ((aec62xx_display_info) && (aec62xx_proc)) + remove_proc_entry("ide/aec62xx",0); +#endif /* CONFIG_BLK_DEV_AEC62XX */ #ifdef CONFIG_BLK_DEV_ALI15X3 if ((ali_display_info) && (ali_proc)) remove_proc_entry("ide/ali",0); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index c4424cf904a3..22fdcbfe5403 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -5900,6 +5900,7 @@ static ide_driver_t idetape_driver = { idetape_blkdev_open, /* open */ idetape_blkdev_release, /* release */ NULL, /* media_change */ + NULL, /* revalidate */ idetape_pre_reset, /* pre_reset */ NULL, /* capacity */ NULL, /* special */ diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index fb24fb0a526f..1abf214cc24f 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -343,7 +343,7 @@ int ide_system_bus_speed (void) system_bus_speed = idebus_parameter; /* user supplied value */ #ifdef CONFIG_PCI else if (pci_present()) - system_bus_speed = 40; /* safe default value for PCI */ + system_bus_speed = 33; /* safe default value for PCI */ #endif /* CONFIG_PCI */ else system_bus_speed = 50; /* safe default value for VESA and PCI */ @@ -1091,11 +1091,9 @@ static ide_startstop_t start_request (ide_drive_t *drive) #endif block = rq->sector; blockend = block + rq->nr_sectors; -#if 0 + if ((rq->cmd == READ || rq->cmd == WRITE) && - (drive->media == ide_disk || drive->media == ide_floppy)) -#endif - { + (drive->media == ide_disk || drive->media == ide_floppy)) { if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) { printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name, (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors); @@ -1777,10 +1775,7 @@ int ide_revalidate_disk (kdev_t i_rdev) drive->part[p].nr_sects = 0; }; - grok_partitions(HWIF(drive)->gd, drive->select.b.unit, - (drive->media != ide_disk && - drive->media != ide_floppy) ? 1 : 1<revalidate(drive); drive->busy = 0; wake_up(&drive->wqueue); @@ -2095,7 +2090,9 @@ void ide_unregister (unsigned int index) hwif->config_data = old_hwif.config_data; hwif->select_data = old_hwif.select_data; hwif->proc = old_hwif.proc; +#ifndef CONFIG_BLK_DEV_IDECS hwif->irq = old_hwif.irq; +#endif /* CONFIG_BLK_DEV_IDECS */ hwif->major = old_hwif.major; hwif->chipset = old_hwif.chipset; hwif->autodma = old_hwif.autodma; @@ -2447,8 +2444,18 @@ int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int secto */ void ide_delay_50ms (void) { +#if 0 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 +} + +int system_bus_clock (void) +{ + return((int) ((!system_bus_speed) ? ide_system_bus_speed() : system_bus_speed )); } static int ide_ioctl (struct inode *inode, struct file *file, @@ -3350,7 +3357,7 @@ static void default_pre_reset (ide_drive_t *drive) static unsigned long default_capacity (ide_drive_t *drive) { - return 0x7fffffff; /* cdrom or tape */ + return 0x7fffffff; } static ide_startstop_t default_special (ide_drive_t *drive) @@ -3578,6 +3585,8 @@ EXPORT_SYMBOL(hwif_unregister); EXPORT_SYMBOL(get_info_ptr); EXPORT_SYMBOL(current_capacity); +EXPORT_SYMBOL(system_bus_clock); + /* * This is gets invoked once during initialization, to set *everything* up */ @@ -3589,7 +3598,7 @@ int __init ide_init (void) if (!banner_printed) { printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); ide_devfs_handle = devfs_mk_dir (NULL, "ide", 3, NULL); - (void) ide_system_bus_speed(); + system_bus_speed = ide_system_bus_speed(); banner_printed = 1; } diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c index 46a14ba19930..26e4bfae0b2a 100644 --- a/drivers/ide/macide.c +++ b/drivers/ide/macide.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 7a24fce25fa9..70f1851088d0 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c index 277f2f490f60..f11c41d99b95 100644 --- a/drivers/ide/opti621.c +++ b/drivers/ide/opti621.c @@ -215,8 +215,9 @@ typedef struct pio_clocks_s { static void compute_clocks(int pio, pio_clocks_t *clks) { if (pio != PIO_NOT_EXIST) { - int adr_setup, data_pls, bus_speed; - bus_speed = ide_system_bus_speed(); + int adr_setup, data_pls; + int bus_speed = system_bus_clock(); + adr_setup = ide_pio_timings[pio].setup_time; data_pls = ide_pio_timings[pio].active_time; clks->address_time = cmpt_clk(adr_setup, bus_speed); diff --git a/drivers/ide/pdc4030.c b/drivers/ide/pdc4030.c index f42c4946f6dd..5fe8c06a811b 100644 --- a/drivers/ide/pdc4030.c +++ b/drivers/ide/pdc4030.c @@ -82,6 +82,7 @@ #include #include #include +#include #include #include diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index fa453e7d53a1..fafd0533feef 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -61,6 +61,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/qd6580.c b/drivers/ide/qd6580.c index bccf1eb6a181..ad56c295ceeb 100644 --- a/drivers/ide/qd6580.c +++ b/drivers/ide/qd6580.c @@ -20,6 +20,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/rapide.c b/drivers/ide/rapide.c index baa293467b7b..a842a3287466 100644 --- a/drivers/ide/rapide.c +++ b/drivers/ide/rapide.c @@ -13,6 +13,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/rz1000.c b/drivers/ide/rz1000.c index 5bd3db7d577e..244d15e27bb5 100644 --- a/drivers/ide/rz1000.c +++ b/drivers/ide/rz1000.c @@ -28,6 +28,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c index 5c1168972ecd..296d001f27a6 100644 --- a/drivers/ide/umc8672.c +++ b/drivers/ide/umc8672.c @@ -48,6 +48,7 @@ #include #include #include +#include #include diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index bf8e27640862..f9d96a86560e 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/via82cxxx.c Version 0.08 Mar. 18, 2000 + * linux/drivers/ide/via82cxxx.c Version 0.09 Apr. 02, 2000 * * Copyright (C) 1998-99 Michel Aubry, Maintainer * Copyright (C) 1999 Jeff Garzik, MVP4 Support @@ -93,27 +93,127 @@ #include +#include "ide_modes.h" + static struct pci_dev *host_dev = NULL; 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 ultra_settings_33; + byte chipset_settings_37; + byte ultra_settings_37; + byte chipset_settings_41; + byte ultra_settings_41; +}; + +static struct chipset_bus_clock_list_entry * via82cxxx_table = NULL; + +struct chipset_bus_clock_list_entry via82cxxx_type_one [] = { + /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ + { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { XFER_UDMA_3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { XFER_UDMA_2, 0x60, 0x20, 0x60, 0x20, 0x60, 0x21, 0x00, 0x00 }, + { XFER_UDMA_1, 0x61, 0x20, 0x61, 0x20, 0x61, 0x21, 0x00, 0x00 }, + { XFER_UDMA_0, 0x62, 0x20, 0x62, 0x20, 0x62, 0x21, 0x00, 0x00 }, + + { XFER_MW_DMA_2, 0x03, 0x20, 0x03, 0x20, 0x03, 0x21, 0x00, 0x00 }, + { XFER_MW_DMA_1, 0x03, 0x31, 0x03, 0x31, 0x03, 0x32, 0x00, 0x00 }, + { XFER_MW_DMA_0, 0x03, 0x31, 0x03, 0x31, 0x03, 0x32, 0x00, 0x00 }, + + { XFER_PIO_4, 0x03, 0x20, 0x03, 0x20, 0x03, 0x21, 0x00, 0x00 }, + { XFER_PIO_3, 0x03, 0x31, 0x03, 0x31, 0x03, 0x32, 0x00, 0x00 }, + { XFER_PIO_2, 0x03, 0x65, 0x03, 0x65, 0x03, 0x76, 0x00, 0x00 }, + { XFER_PIO_1, 0x03, 0x65, 0x03, 0x65, 0x03, 0x76, 0x00, 0x00 }, + { XFER_PIO_0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xA9, 0x00, 0x00 }, + { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xA9, 0x00, 0x00 } +}; + +struct chipset_bus_clock_list_entry via82cxxx_type_two [] = { + /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ + { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { XFER_UDMA_3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { XFER_UDMA_2, 0xE0, 0x20, 0xE0, 0x20, 0xE1, 0x31, 0xE1, 0x32 }, + { XFER_UDMA_1, 0xE1, 0x20, 0xE1, 0x20, 0xE2, 0x31, 0xE2, 0x32 }, + { XFER_UDMA_0, 0xE2, 0x20, 0xE2, 0x20, 0xE2, 0x31, 0xE2, 0x32 }, + + { XFER_MW_DMA_2, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 }, + { XFER_MW_DMA_1, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 }, + { XFER_MW_DMA_0, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 }, + + { XFER_PIO_4, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 }, + { XFER_PIO_3, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 }, + { XFER_PIO_2, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 }, + { XFER_PIO_1, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 }, + { XFER_PIO_0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE }, + { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE } +}; + +struct chipset_bus_clock_list_entry via82cxxx_type_three [] = { + /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ + { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { XFER_UDMA_3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { XFER_UDMA_2, 0xE0, 0x20, 0xE0, 0x20, 0xE1, 0x31, 0xE1, 0x32 }, + { XFER_UDMA_1, 0xE1, 0x20, 0xE1, 0x20, 0xE2, 0x31, 0xE2, 0x32 }, + { XFER_UDMA_0, 0xE2, 0x20, 0xE2, 0x20, 0xE2, 0x31, 0xE2, 0x32 }, + + { XFER_MW_DMA_2, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 }, + { XFER_MW_DMA_1, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 }, + { XFER_MW_DMA_0, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 }, + + { XFER_PIO_4, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 }, + { XFER_PIO_3, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 }, + { XFER_PIO_2, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 }, + { XFER_PIO_1, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 }, + { XFER_PIO_0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE }, + { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE } +}; + +struct chipset_bus_clock_list_entry via82cxxx_type_four [] = { + /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ + { XFER_UDMA_4, 0x00, 0x00, 0xE0, 0x20, 0xE1, 0x31, 0x00, 0x00 }, + { XFER_UDMA_3, 0x00, 0x00, 0xE1, 0x20, 0xE2, 0x31, 0x00, 0x00 }, + { XFER_UDMA_2, 0x00, 0x00, 0xE2, 0x20, 0xE4, 0x31, 0x00, 0x00 }, + { XFER_UDMA_1, 0x00, 0x00, 0xE4, 0x20, 0xE6, 0x31, 0x00, 0x00 }, + { XFER_UDMA_0, 0x00, 0x00, 0xE6, 0x20, 0xE6, 0x31, 0x00, 0x00 }, + + { XFER_MW_DMA_2, 0x00, 0x00, 0x03, 0x20, 0x03, 0x31, 0x00, 0x00 }, + { XFER_MW_DMA_1, 0x00, 0x00, 0x03, 0x31, 0x03, 0x42, 0x00, 0x00 }, + { XFER_MW_DMA_0, 0x00, 0x00, 0x03, 0x31, 0x03, 0x42, 0x00, 0x00 }, + + { XFER_PIO_4, 0x00, 0x00, 0x03, 0x20, 0x03, 0x31, 0x00, 0x00 }, + { XFER_PIO_3, 0x00, 0x00, 0x03, 0x31, 0x03, 0x42, 0x00, 0x00 }, + { XFER_PIO_2, 0x00, 0x00, 0x03, 0x65, 0x03, 0x87, 0x00, 0x00 }, + { XFER_PIO_1, 0x00, 0x00, 0x03, 0x65, 0x03, 0x87, 0x00, 0x00 }, + { XFER_PIO_0, 0x00, 0x00, 0x03, 0xA8, 0x03, 0xDB, 0x00, 0x00 }, + { 0, 0x00, 0x00, 0x03, 0xA8, 0x03, 0xDB, 0x00, 0x00 } +}; + static const struct { const char *name; + unsigned short vendor_id; unsigned short host_id; } ApolloHostChipInfo[] = { - { "VT 82C585 Apollo VP1/VPX", PCI_DEVICE_ID_VIA_82C585, }, - { "VT 82C595 Apollo VP2", PCI_DEVICE_ID_VIA_82C595, }, - { "VT 82C597 Apollo VP3", PCI_DEVICE_ID_VIA_82C597_0, }, - { "VT 82C598 Apollo MVP3", PCI_DEVICE_ID_VIA_82C598_0, }, - { "VT 82C598 Apollo MVP3", PCI_DEVICE_ID_VIA_82C598_0, }, - { "VT 82C680 Apollo P6", PCI_DEVICE_ID_VIA_82C680, }, - { "VT 82C691 Apollo Pro", PCI_DEVICE_ID_VIA_82C691, }, - { "VT 82C693 Apollo Pro Plus", PCI_DEVICE_ID_VIA_82C693, }, - { "Apollo MVP4", PCI_DEVICE_ID_VIA_8501_0, }, - { "VT 8371", PCI_DEVICE_ID_VIA_8371_0, }, - { "VT 8601", PCI_DEVICE_ID_VIA_8601_0, }, + { "VT 82C585 Apollo VP1/VPX", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C585, }, + { "VT 82C595 Apollo VP2", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C595, }, + { "VT 82C597 Apollo VP3", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, }, + { "VT 82C598 Apollo MVP3", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_0, }, + { "VT 82C598 Apollo MVP3", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_0, }, + { "VT 82C680 Apollo P6", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C680, }, + { "VT 82C691 Apollo Pro", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691, }, + { "VT 82C693 Apollo Pro Plus", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C693, }, + { "Apollo MVP4", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8501_0, }, + { "VT 8371", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_0, }, + { "VT 8601", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, }, + { "AMD IronGate", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7006, }, }; #define NUM_APOLLO_ISA_CHIP_DEVICES 2 +#define VIA_FLAG_NULL 0x00000000 #define VIA_FLAG_CHECK_REV 0x00000001 #define VIA_FLAG_ATA_66 0x00000002 @@ -121,18 +221,20 @@ static const struct { unsigned short host_id; unsigned short isa_id; unsigned int flags; + struct chipset_bus_clock_list_entry * chipset_table; } ApolloISAChipInfo[] = { - { PCI_DEVICE_ID_VIA_82C585, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV }, - { PCI_DEVICE_ID_VIA_82C595, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV }, - { PCI_DEVICE_ID_VIA_82C597_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV }, - { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV }, - { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C596, 0 }, - { PCI_DEVICE_ID_VIA_82C680, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV }, - { PCI_DEVICE_ID_VIA_82C691, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_ATA_66 }, - { PCI_DEVICE_ID_VIA_82C693, PCI_DEVICE_ID_VIA_82C596, 0 }, - { PCI_DEVICE_ID_VIA_8501_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66 }, - { PCI_DEVICE_ID_VIA_8371_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66 }, - { PCI_DEVICE_ID_VIA_8601_0, PCI_DEVICE_ID_VIA_8231, VIA_FLAG_ATA_66 }, + { PCI_DEVICE_ID_VIA_82C585, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one }, + { PCI_DEVICE_ID_VIA_82C595, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one }, + { PCI_DEVICE_ID_VIA_82C597_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one }, + { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one }, + { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_NULL, via82cxxx_type_one }, + { PCI_DEVICE_ID_VIA_82C680, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one }, + { PCI_DEVICE_ID_VIA_82C691, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_ATA_66, via82cxxx_type_two }, + { PCI_DEVICE_ID_VIA_82C693, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_NULL, via82cxxx_type_one }, + { PCI_DEVICE_ID_VIA_8501_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66, via82cxxx_type_two }, + { PCI_DEVICE_ID_VIA_8371_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66, via82cxxx_type_two }, + { PCI_DEVICE_ID_VIA_8601_0, PCI_DEVICE_ID_VIA_8231, VIA_FLAG_ATA_66, via82cxxx_type_two }, + { PCI_DEVICE_ID_AMD_FE_GATE_7006, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66, via82cxxx_type_two }, }; #define arraysize(x) (sizeof(x)/sizeof(*(x))) @@ -515,69 +617,40 @@ static int via_set_fifoconfig(ide_hwif_t *hwif) } #ifdef CONFIG_VIA82CXXX_TUNING +static byte pci_bus_clock_list (byte speed, int ide_clock, struct chipset_bus_clock_list_entry * chipset_table) +{ + for ( ; chipset_table->xfer_speed ; chipset_table++) + if (chipset_table->xfer_speed == speed) { + switch(ide_clock) { + case 25: return chipset_table->chipset_settings_25; + case 33: return chipset_table->chipset_settings_33; + case 37: return chipset_table->chipset_settings_37; + case 41: return chipset_table->chipset_settings_41; + default: break; + } + } + return 0x00; +} -struct chipset_bus_clock_list_entry { - unsigned short bus_speed; - byte xfer_speed; - byte chipset_settings; -}; - -PCI_DEVICE_ID_VIA_82C586_1 -PCI_DEVICE_ID_VIA_82C596 -PCI_DEVICE_ID_VIA_82C686 -PCI_DEVICE_ID_VIA_8231 - -PCI_DEVICE_ID_VIA_82C586_1 TYPE_1 -PCI_DEVICE_ID_VIA_82C596 TYPE_2 -PCI_DEVICE_ID_VIA_82C686 TYPE_2 -PCI_DEVICE_ID_VIA_82C596 TYPE_3 -PCI_DEVICE_ID_VIA_82C686 TYPE_3 -PCI_DEVICE_ID_VIA_8231 TYPE_4 - -struct chipset_bus_clock_list_entry ultra_33_base [] = { -{ TYPE_1,25,0x00,0x00,0x60,0x61,0x62,0x03,0x20,0x31,0x65,0x65,0xA8 }, -{ TYPE_1,33,0x00,0x00,0x60,0x61,0x62,0x03,0x20,0x31,0x65,0x65,0xA8 }, -{ TYPE_1,37,0x00,0x00,0x60,0x61,0x62,0x03,0x21,0x32,0x76,0x76,0xA9 }, -{ TYPE_2,25,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 }, -{ TYPE_2,33,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 }, -{ TYPE_2,37,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x31,0x42,0x87,0x87,0xDB }, -{ TYPE_2,41,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x32,0x53,0xA8,0xA8,0xFE }, -{ TYPE_3,25,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 }, -{ TYPE_3,33,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 }, -{ TYPE_3,37,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x31,0x42,0x87,0x87,0xDB }, -{ TYPE_3,41,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x32,0x53,0xA8,0xA8,0xFE }, -{ TYPE_4,0,0,0,0,0,0,0,0,0,0,0,0 }, -{ 0,0,0,0,0,0,0,0,0,0,0,0,0 } -}; - -struct chipset_bus_clock_list_entry timing_66_base [] = { - { 37, XFER_PIO_4, 0x21 }, - { 37, XFER_PIO_3, 0x32 }, - { 37, XFER_PIO_2, 0x76 }, - { 37, XFER_PIO_1, 0x76 }, - { 37, XFER_PIO_0, 0xA9 }, - { ANY, XFER_PIO_4, 0x20 }, - { ANY, XFER_PIO_3, 0x31 }, - { ANY, XFER_PIO_2, 0x65 }, - { ANY, XFER_PIO_1, 0x65 }, - { ANY, XFER_PIO_0, 0xA8 }, -}; - -static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table) +static byte pci_bus_clock_list_ultra (byte speed, int ide_clock, struct chipset_bus_clock_list_entry * chipset_table) { for ( ; chipset_table->xfer_speed ; chipset_table++) if (chipset_table->xfer_speed == speed) { - return chipset_table->chipset_settings; + switch(ide_clock) { + case 25: return chipset_table->ultra_settings_25; + case 33: return chipset_table->ultra_settings_33; + case 37: return chipset_table->ultra_settings_37; + case 41: return chipset_table->ultra_settings_41; + default: break; + } } - return 0x01208585; + return 0x00; } static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed) { - struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); int drive_number = ((hwif->channel ? 2 : 0) + unit); @@ -587,43 +660,23 @@ static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed) byte ultra = 0x00; int err; - int bus_speed = ide_system_bus_speed(); + int bus_speed = system_bus_clock(); switch(drive_number) { - case 0: ata2_pci = 0x48; ata3_pci = 0x50; break; - case 1: ata2_pci = 0x49; ata3_pci = 0x51; break; - case 2: ata2_pci = 0x4a; ata3_pci = 0x52; break; - case 3: ata2_pci = 0x4b; ata3_pci = 0x53; break; + case 0: ata2_pci = 0x4b; ata3_pci = 0x53; break; + case 1: ata2_pci = 0x4a; ata3_pci = 0x52; break; + case 2: ata2_pci = 0x49; ata3_pci = 0x51; break; + case 3: ata2_pci = 0x48; ata3_pci = 0x50; break; default: return -1; } pci_read_config_byte(dev, ata2_pci, &timing); - pci_read_config_byte(dev, ata3_pci, &ultra); - - switch(speed) { - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - case XFER_SW_DMA_2: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: - default: - break; - } - + timing = pci_bus_clock_list(speed, bus_speed, via82cxxx_table); pci_write_config_byte(dev, ata2_pci, timing); + + pci_read_config_byte(dev, ata3_pci, &ultra); + ultra = pci_bus_clock_list_ultra(speed, bus_speed, via82cxxx_table); pci_write_config_byte(dev, ata3_pci, ultra); err = ide_config_drive_speed(drive, speed); @@ -830,6 +883,8 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name) if (ata33 | ata66) printk(" Chipset Core ATA-%s", ata66 ? "66" : "33"); + + via82cxxx_table = ApolloISAChipInfo[j].chipset_table; } printk("\n"); } @@ -847,8 +902,11 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name) unsigned int __init ata66_via82cxxx (ide_hwif_t *hwif) { - /* (Jeff Garzik) FIXME!!! for MVP4 */ - return 0; + byte ata66 = 0; + byte ata66reg = hwif->channel ? 0x50 : 0x52; + pci_read_config_byte(hwif->pci_dev, ata66reg, &ata66); + + return ((ata66 & 0x04) ? 1 : 0); } void __init ide_init_via82cxxx (ide_hwif_t *hwif) diff --git a/drivers/isdn/avmb1/b1pcmcia.c b/drivers/isdn/avmb1/b1pcmcia.c index 2c749c69d718..5774080fe454 100644 --- a/drivers/isdn/avmb1/b1pcmcia.c +++ b/drivers/isdn/avmb1/b1pcmcia.c @@ -64,7 +64,6 @@ * */ -#include #include #include #include diff --git a/drivers/isdn/avmb1/capi.c b/drivers/isdn/avmb1/capi.c index c9b4c54dab88..b91df4a6d0dd 100644 --- a/drivers/isdn/avmb1/capi.c +++ b/drivers/isdn/avmb1/capi.c @@ -158,6 +158,7 @@ * */ +#include #include #include #include diff --git a/drivers/isdn/avmb1/capifs.c b/drivers/isdn/avmb1/capifs.c index 97f374fa6529..fcefa3d68502 100644 --- a/drivers/isdn/avmb1/capifs.c +++ b/drivers/isdn/avmb1/capifs.c @@ -48,15 +48,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include -#include #include #include #include diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 336a66949eda..ce573e312b65 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -439,7 +439,7 @@ static int __devinit rtl8139_init_pci (struct pci_dev *pdev, void **ioaddr_out) u8 tmp8; int rc; u32 pio_start, pio_end, pio_flags, pio_len; - u32 mmio_start, mmio_end, mmio_flags, mmio_len; + unsigned long mmio_start, mmio_end, mmio_flags, mmio_len; DPRINTK ("ENTER\n"); diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 04bfab3c8a35..466a83dbc416 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -683,6 +683,46 @@ static struct net_device tr0_dev = { #define NEXT_DEV (&sbni0_dev) #endif +/* S/390 channels */ +#ifdef CONFIG_CTC + extern int ctc_probe(struct net_device *dev); + static struct net_device ctc7_dev = + {"ctc7", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, ctc_probe}; + static struct net_device ctc6_dev = + {"ctc6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc7_dev, ctc_probe}; + static struct net_device ctc5_dev = + {"ctc5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc6_dev, ctc_probe}; + static struct net_device ctc4_dev = + {"ctc4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc5_dev, ctc_probe}; + static struct net_device ctc3_dev = + {"ctc3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc4_dev, ctc_probe}; + static struct net_device ctc2_dev = + {"ctc2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc3_dev, ctc_probe}; + static struct net_device ctc1_dev = + {"ctc1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc2_dev, ctc_probe}; + static struct net_device ctc0_dev = + {"ctc0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc1_dev, ctc_probe}; + + static struct net_device escon7_dev = + {"escon7", 0, 0, 0, 0, 0, 0, 0, 0, 0, &ctc0_dev, ctc_probe}; + static struct net_device escon6_dev = + {"escon6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon7_dev, ctc_probe}; + static struct net_device escon5_dev = + {"escon5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon6_dev, ctc_probe}; + static struct net_device escon4_dev = + {"escon4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon5_dev, ctc_probe}; + static struct net_device escon3_dev = + {"escon3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon4_dev, ctc_probe}; + static struct net_device escon2_dev = + {"escon2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon3_dev, ctc_probe}; + static struct net_device escon1_dev = + {"escon1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon2_dev, ctc_probe}; + static struct net_device escon0_dev = + {"escon0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &escon1_dev, ctc_probe}; + +#undef NEXT_DEV +#define NEXT_DEV (&escon0_dev) +#endif /* diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 5ef42cf9c62a..9fd9a275ee2a 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -48,10 +48,23 @@ : Don't call netif_wake_queue() in net_send_packet() : Fixed an out-of-mem bug in dma_rx() : Updated Documentation/cs89x0.txt + + Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre1 + : Use skb_reserve to longword align IP header (two places) + : Remove a delay loop from dma_rx() + : Replace '100' with HZ + : Clean up a couple of skb API abuses + : Added 'cs89x0_dma=N' kernel boot option + : Correctly initialise lp->lock in non-module compile + + Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre4-1 + : MOD_INC/DEC race fix (see + : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html) + */ static char *version = -"cs89x0.c: (kernel 2.3.48) Russell Nelson , Andrew Morton \n"; +"cs89x0.c: v2.3.99-pre1-2 Russell Nelson , Andrew Morton \n"; /* ======================= end of configuration ======================= */ @@ -121,7 +134,7 @@ static unsigned int netcard_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; #if DEBUGGING -static unsigned int net_debug = 5; +static unsigned int net_debug = DEBUGGING; #else #define net_debug 0 /* gcc will remove all the debug code for us */ #endif @@ -190,6 +203,21 @@ static void release_dma_buff(struct net_local *lp); /* Example routines you must write ;->. */ #define tx_done(dev) 1 +/* + * Permit 'cs89x0_dma=N' in the kernel boot environment + */ +#if !defined(MODULE) && (ALLOW_DMA != 0) +static int g_cs89x0_dma; + +static int __init dma_fn(char *str) +{ + g_cs89x0_dma = simple_strtol(str,NULL,0); + return 1; +} + +__setup("cs89x0_dma=", dma_fn); +#endif /* !defined(MODULE) && (ALLOW_DMA != 0) */ + /* Check for a network adaptor of this type, and return '0' iff one exists. If dev->base_addr == 0, probe all likely locations. @@ -318,7 +346,17 @@ cs89x0_probe1(struct net_device *dev, int ioaddr) retval = ENOMEM; goto out; } - memset(dev->priv, 0, sizeof(struct net_local)); + lp = (struct net_local *)dev->priv; + memset(lp, 0, sizeof(*lp)); + spin_lock_init(&lp->lock); +#if !defined(MODULE) && (ALLOW_DMA != 0) + if (g_cs89x0_dma) + { + lp->use_dma = 1; + lp->dma = g_cs89x0_dma; + lp->dmasize = 16; /* Could make this an option... */ + } +#endif } lp = (struct net_local *)dev->priv; @@ -612,12 +650,6 @@ dma_rx(struct net_device *dev) int status, length; unsigned char *bp = lp->rx_dma_ptr; - { - int i; - for (i = 0; i < 1000; i++) - ; - } - status = bp[0] + (bp[1]<<8); length = bp[2] + (bp[3]<<8); bp += 4; @@ -632,7 +664,7 @@ dma_rx(struct net_device *dev) } /* Malloc up new buffer. */ - skb = alloc_skb(length, GFP_ATOMIC); + skb = dev_alloc_skb(length + 2); if (skb == NULL) { if (net_debug) /* I don't think we want to do this to a stressed system */ printk("%s: Memory squeeze, dropping packet.\n", dev->name); @@ -645,8 +677,7 @@ skip_this_frame: lp->rx_dma_ptr = bp; return; } - - skb->len = length; + skb_reserve(skb, 2); /* longword align L3 header */ skb->dev = dev; if (bp + length > lp->end_dma_buff) { @@ -720,7 +751,7 @@ control_dc_dc(struct net_device *dev, int on_not_off) writereg(dev, PP_SelfCTL, selfcontrol); /* Wait for the DC/DC converter to power up - 500ms */ - while (jiffies - timenow < 100) + while (jiffies - timenow < HZ) ; } @@ -914,6 +945,9 @@ net_open(struct net_device *dev) struct net_local *lp = (struct net_local *)dev->priv; int result = 0; int i; + int ret; + + MOD_INC_USE_COUNT; if (dev->irq < 2) { /* Allow interrupts to be generated by the chip */ @@ -938,13 +972,15 @@ net_open(struct net_device *dev) writereg(dev, PP_BusCTL, 0); /* disable interrupts. */ if (net_debug) printk("cs89x0: can't get an interrupt\n"); - return -EAGAIN; + ret = -EAGAIN; + goto bad_out; } } else { if (((1 << dev->irq) & lp->irq_map) == 0) { printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", dev->name, dev->irq, lp->irq_map); - return -EAGAIN; + ret = -EAGAIN; + goto bad_out; } /* FIXME: Cirrus' release had this: */ writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL)|ENABLE_IRQ ); @@ -956,7 +992,8 @@ net_open(struct net_device *dev) if (request_irq(dev->irq, &net_interrupt, 0, "cs89x0", dev)) { if (net_debug) printk("cs89x0: request_irq(%d) failed\n", dev->irq); - return -EAGAIN; + ret = -EAGAIN; + goto bad_out; } } @@ -1032,7 +1069,8 @@ net_open(struct net_device *dev) #endif writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); free_irq(dev->irq, dev); - return -EAGAIN; + ret = -EAGAIN; + goto bad_out; } /* set the hardware to the configured choice */ @@ -1125,11 +1163,13 @@ net_open(struct net_device *dev) | dma_busctl(dev) #endif ); - MOD_INC_USE_COUNT; netif_start_queue(dev); if (net_debug) printk("cs89x0: net_open() succeeded\n"); return 0; +bad_out: + MOD_DEC_USE_COUNT; + return ret; } static void net_timeout(struct net_device *dev) @@ -1317,7 +1357,7 @@ net_rx(struct net_device *dev) } /* Malloc up new buffer. */ - skb = alloc_skb(length, GFP_ATOMIC); + skb = dev_alloc_skb(length + 2); if (skb == NULL) { #if 0 /* Again, this seems a cruel thing to do */ printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name); @@ -1325,10 +1365,10 @@ net_rx(struct net_device *dev) lp->stats.rx_dropped++; return; } - skb->len = length; + skb_reserve(skb, 2); /* longword align L3 header */ skb->dev = dev; - insw(ioaddr + RX_FRAME_PORT, skb->data, length >> 1); + insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1); if (length & 1) skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT); diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index a70c1a8db66f..c2cb4dbc62cb 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -19,7 +19,7 @@ * PPP driver, written by Michael Callahan and Al Longyear, and * subsequently hacked by Paul Mackerras. * - * ==FILEVERSION 20000406== + * ==FILEVERSION 20000412== */ #include @@ -206,7 +206,7 @@ static ssize_t ppp_file_write(struct ppp_file *pf, const char *buf, size_t count); static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file, unsigned int cmd, unsigned long arg); -static void ppp_xmit_process(struct ppp *ppp, int wakeup); +static void ppp_xmit_process(struct ppp *ppp); static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); static void ppp_push(struct ppp *ppp); static void ppp_channel_push(struct channel *pch); @@ -427,7 +427,7 @@ static ssize_t ppp_file_write(struct ppp_file *pf, const char *buf, switch (pf->kind) { case INTERFACE: - ppp_xmit_process(PF_TO_PPP(pf), 0); + ppp_xmit_process(PF_TO_PPP(pf)); break; case CHANNEL: ppp_channel_push(PF_TO_CHANNEL(pf)); @@ -774,7 +774,7 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); skb_queue_tail(&ppp->file.xq, skb); - ppp_xmit_process(ppp, 0); + ppp_xmit_process(ppp); return 0; outf: @@ -860,13 +860,12 @@ ppp_net_init(struct net_device *dev) * that can now be done. */ static void -ppp_xmit_process(struct ppp *ppp, int wakeup) +ppp_xmit_process(struct ppp *ppp) { struct sk_buff *skb; ppp_xmit_lock(ppp); - if (wakeup) - ppp_push(ppp); + ppp_push(ppp); while (ppp->xmit_pending == 0 && (skb = skb_dequeue(&ppp->file.xq)) != 0) ppp_send_frame(ppp, skb); @@ -1018,14 +1017,12 @@ ppp_push(struct ppp *ppp) spin_lock_bh(&pch->downl); if (pch->chan) { if (pch->chan->ops->start_xmit(pch->chan, skb)) - skb = 0; + ppp->xmit_pending = 0; } else { /* channel got unregistered */ kfree_skb(skb); - skb = 0; - } - if (skb_queue_len(&pch->file.xq) == 0 && skb == 0) ppp->xmit_pending = 0; + } spin_unlock_bh(&pch->downl); return; } @@ -1196,6 +1193,7 @@ static void ppp_channel_push(struct channel *pch) { struct sk_buff *skb; + struct ppp *ppp; spin_lock_bh(&pch->downl); if (pch->chan != 0) { @@ -1212,6 +1210,14 @@ ppp_channel_push(struct channel *pch) skb_queue_purge(&pch->file.xq); } spin_unlock_bh(&pch->downl); + /* see if there is anything from the attached unit to be sent */ + if (skb_queue_len(&pch->file.xq) == 0) { + read_lock_bh(&pch->upl); + ppp = pch->ppp; + if (ppp != 0) + ppp_xmit_process(ppp); + read_unlock_bh(&pch->upl); + } } /* @@ -1792,18 +1798,10 @@ void ppp_output_wakeup(struct ppp_channel *chan) { struct channel *pch = chan->ppp; - struct ppp *ppp; if (pch == 0) return; ppp_channel_push(pch); - if (skb_queue_len(&pch->file.xq) == 0) { - read_lock_bh(&pch->upl); - ppp = pch->ppp; - if (ppp != 0) - ppp_xmit_process(ppp, 1); - read_unlock_bh(&pch->upl); - } } /* diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index f244874e4d2e..2bc0a8652187 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c @@ -88,8 +88,10 @@ void t21142_timer(unsigned long data) next_tick = 3*HZ; } - tp->timer.expires = RUN_AT(next_tick); - add_timer(&tp->timer); + /* mod_timer synchronizes us with potential add_timer calls + * from interrupts. + */ + mod_timer(&tp->timer, RUN_AT(next_tick)); } @@ -108,7 +110,10 @@ void t21142_start_nway(struct net_device *dev) dev->name, csr14); outl(0x0001, ioaddr + CSR13); outl(csr14, ioaddr + CSR14); - tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); + if (tp->chip_id == PNIC2) + tp->csr6 = 0x01a80000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); + else + tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); tulip_outl_CSR6(tp, tp->csr6); if (tp->mtable && tp->mtable->csr15dir) { outl(tp->mtable->csr15dir, ioaddr + CSR15); diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c index 0a40abb48426..16e048b828ee 100644 --- a/drivers/net/tulip/timer.c +++ b/drivers/net/tulip/timer.c @@ -171,8 +171,10 @@ void tulip_timer(unsigned long data) } break; } - tp->timer.expires = RUN_AT(next_tick); - add_timer(&tp->timer); + /* mod_timer synchronizes us with potential add_timer calls + * from interrupts. + */ + mod_timer(&tp->timer, RUN_AT(next_tick)); } @@ -188,8 +190,7 @@ void mxic_timer(unsigned long data) inl(ioaddr + CSR12)); } if (next_tick) { - tp->timer.expires = RUN_AT(next_tick); - add_timer(&tp->timer); + mod_timer(&tp->timer, RUN_AT(next_tick)); } } @@ -205,7 +206,9 @@ void comet_timer(unsigned long data) printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability " "%4.4x.\n", dev->name, inl(ioaddr + 0xB8), inl(ioaddr + 0xC8)); - tp->timer.expires = RUN_AT(next_tick); - add_timer(&tp->timer); + /* mod_timer synchronizes us with potential add_timer calls + * from interrupts. + */ + mod_timer(&tp->timer, RUN_AT(next_tick)); } diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 196dcf7f6654..ca99883281d3 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -19,7 +19,7 @@ */ -static const char version[] = "Linux Tulip driver version 0.9.4.2 (Mar 21, 2000)\n"; +static const char version[] = "Linux Tulip driver version 0.9.4.3 (Apr 14, 2000)\n"; #include #include "tulip.h" diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index cdf4092fe0d6..9e11b6a82407 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids @@ -1859,6 +1859,8 @@ 1191 Artop Electronic Corp 0004 ATP8400 0005 ATP850UF + 0006 ATP860 NO-BIOS + 0007 ATP860 8002 AEC6710 SCSI-2 Host Adapter 8010 AEC6712UW SCSI 8020 AEC6712U SCSI diff --git a/drivers/sbus/char/sab82532.c b/drivers/sbus/char/sab82532.c index b2fc1ffc3e8f..eb2efac83308 100644 --- a/drivers/sbus/char/sab82532.c +++ b/drivers/sbus/char/sab82532.c @@ -1,4 +1,4 @@ -/* $Id: sab82532.c,v 1.41 2000/03/13 03:54:17 davem Exp $ +/* $Id: sab82532.c,v 1.42 2000/04/13 07:22:35 ecd Exp $ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -176,12 +176,22 @@ static struct ebrg_struct ebrg_table[] = { #define NR_EBRG_VALUES (sizeof(ebrg_table)/sizeof(struct ebrg_struct)) -#define SAB82532_MAX_TEC_DELAY 2000 /* 2 ms */ +#define SAB82532_MAX_TEC_TIMEOUT 200000 /* 1 character time (at 50 baud) */ +#define SAB82532_MAX_CEC_TIMEOUT 50000 /* 2.5 TX CLKs (at 50 baud) */ static __inline__ void sab82532_tec_wait(struct sab82532 *info) { - int count = SAB82532_MAX_TEC_DELAY; - while ((readb(&info->regs->r.star) & SAB82532_STAR_TEC) && --count) + int timeout = info->tec_timeout; + + while ((readb(&info->regs->r.star) & SAB82532_STAR_TEC) && --timeout) + udelay(1); +} + +static __inline__ void sab82532_cec_wait(struct sab82532 *info) +{ + int timeout = info->cec_timeout; + + while ((readb(&info->regs->r.star) & SAB82532_STAR_CEC) && --timeout) udelay(1); } @@ -209,8 +219,7 @@ static __inline__ void sab82532_start_tx(struct sab82532 *info) } /* Issue a Transmit Frame command. */ - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); writeb(SAB82532_CMDR_XF, &info->regs->w.cmdr); out: @@ -277,8 +286,7 @@ static void batten_down_hatches(struct sab82532 *info) tmp = readb(&info->regs->rw.rfc); tmp &= ~(SAB82532_RFC_RFDF); writeb(tmp, &info->regs->rw.rfc); - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr); #ifndef __sparc_v9__ @@ -293,8 +301,7 @@ static void batten_down_hatches(struct sab82532 *info) * Reset FIFO to character + status mode. */ writeb(saved_rfc, &info->regs->w.rfc); - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr); } @@ -345,16 +352,19 @@ static inline void receive_chars(struct sab82532 *info, free_fifo++; } - if (stat->sreg.isr0 & SAB82532_ISR0_TCD) { - count = readb(&info->regs->r.rbcl) & (info->recv_fifo_size - 1); - free_fifo++; - } - /* Issue a FIFO read command in case we where idle. */ if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); writeb(SAB82532_CMDR_RFRD, &info->regs->w.cmdr); + /* Wait for command execution, to catch the TCD below. */ + sab82532_cec_wait(info); + } + + if (stat->sreg.isr0 & SAB82532_ISR0_TCD) { + count = readb(&info->regs->r.rbcl) & (info->recv_fifo_size - 1); + if (count == 0) + count = info->recv_fifo_size; + free_fifo++; } if (stat->sreg.isr0 & SAB82532_ISR0_RFO) { @@ -370,8 +380,7 @@ static inline void receive_chars(struct sab82532 *info, /* Issue Receive Message Complete command. */ if (free_fifo) { - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); writeb(SAB82532_CMDR_RMC, &info->regs->w.cmdr); } @@ -451,8 +460,7 @@ static inline void transmit_chars(struct sab82532 *info, } /* Issue a Transmit Frame command. */ - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); writeb(SAB82532_CMDR_XF, &info->regs->w.cmdr); if (info->xmit_cnt < WAKEUP_CHARS) @@ -709,18 +717,14 @@ sab82532_init_line(struct sab82532 *info) /* * Wait for any commands or immediate characters */ - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); sab82532_tec_wait(info); /* * Clear the FIFO buffers. */ - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr); - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); writeb(SAB82532_CMDR_XRES, &info->regs->w.cmdr); /* @@ -997,10 +1001,15 @@ static void change_speed(struct sab82532 *info) ebrg |= (ebrg_table[i].m << 6); info->baud = ebrg_table[i].baud; - if (info->baud) + if (info->baud) { info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud; - else + info->tec_timeout = (10 * 1000000) / info->baud; + info->cec_timeout = info->tec_timeout >> 2; + } else { info->timeout = 0; + info->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; + info->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; + } info->timeout += HZ / 50; /* Add .02 seconds of slop */ /* CTS flow control flags */ @@ -1037,8 +1046,7 @@ static void change_speed(struct sab82532 *info) SAB82532_ISR0_TIME; save_flags(flags); cli(); - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); sab82532_tec_wait(info); writeb(dafo, &info->regs->w.dafo); writeb(ebrg & 0xff, &info->regs->w.bgr); @@ -2163,7 +2171,7 @@ static void __init sab82532_kgdb_hook(int line) static inline void __init show_serial_version(void) { - char *revision = "$Revision: 1.41 $"; + char *revision = "$Revision: 1.42 $"; char *version, *p; version = strchr(revision, ' '); @@ -2267,6 +2275,8 @@ int __init sab82532_init(void) info->custom_divisor = 16; info->close_delay = 5*HZ/10; info->closing_wait = 30*HZ; + info->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; + info->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; info->x_char = 0; info->event = 0; info->blocked_open = 0; @@ -2550,8 +2560,7 @@ sab82532_console_setup(struct console *con, char *options) info->flags |= ASYNC_CHECK_CD; save_flags(flags); cli(); - if (readb(&info->regs->r.star) & SAB82532_STAR_CEC) - udelay(1); + sab82532_cec_wait(info); sab82532_tec_wait(info); writeb(dafo, &info->regs->w.dafo); writeb(ebrg & 0xff, &info->regs->w.bgr); diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 1a209c14e5de..832a2d9f43c2 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -547,6 +547,7 @@ static ide_driver_t idescsi_driver = { idescsi_open, /* open */ idescsi_ide_release, /* release */ NULL, /* media_change */ + NULL, /* revalidate */ NULL, /* pre_reset */ NULL, /* capacity */ NULL, /* special */ diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ac162c564c7c..280cda345991 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -166,6 +166,37 @@ static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, return -EFAULT; return 0; } + case HDIO_GETGEO_BIG: + { + struct hd_big_geometry *loc = (struct hd_big_geometry *) arg; + + if(!loc) + return -EINVAL; + + host = rscsi_disks[DEVICE_NR(dev)].device->host; + + /* default to most commonly used values */ + + diskinfo[0] = 0x40; + diskinfo[1] = 0x20; + diskinfo[2] = rscsi_disks[DEVICE_NR(dev)].capacity >> 11; + + /* override with calculated, extended default, or driver values */ + + if(host->hostt->bios_param != NULL) + host->hostt->bios_param(&rscsi_disks[DEVICE_NR(dev)], + dev, + &diskinfo[0]); + else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)], + dev, &diskinfo[0]); + + if (put_user(diskinfo[0], &loc->heads) || + put_user(diskinfo[1], &loc->sectors) || + put_user(diskinfo[2], (unsigned int *) &loc->cylinders) || + put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start)) + return -EFAULT; + return 0; + } case BLKGETSIZE: /* Return device size */ if (!arg) return -EINVAL; diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile index 0ebdf61245bf..6350d96d4486 100644 --- a/drivers/sound/Makefile +++ b/drivers/sound/Makefile @@ -72,7 +72,7 @@ obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o obj-$(CONFIG_SOUND_VWSND) += vwsnd.o obj-$(CONFIG_SOUND_NM256) += nm256_audio.o ac97.o -obj-$(CONFIG_SOUND_NM256) += i810_audio.o ac97.o +obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97.o obj-$(CONFIG_SOUND_SONICVIBES) += sonicvibes.o obj-$(CONFIG_SOUND_CMPCI) += cmpci.o obj-$(CONFIG_SOUND_ES1370) += es1370.o diff --git a/drivers/sound/sb_card.c b/drivers/sound/sb_card.c index a0a12fc81430..13e45611173d 100644 --- a/drivers/sound/sb_card.c +++ b/drivers/sound/sb_card.c @@ -36,7 +36,7 @@ * 26-03-2000 Fixed acer, esstype and sm_games module options. * Alessandro Zummo * - * 27-03-2000 ISAPnP multiple card detection, cleanup, and reorg. + * 12-04-2000 ISAPnP cleanup, reorg, fixes, and multiple card support. * Thanks to Gaël Quéri and Alessandro Zummo for testing and fixes. * Paul E. Laufer * @@ -177,7 +177,8 @@ static struct address_info cfg[SB_CARDS_MAX]; static struct address_info cfg_mpu[SB_CARDS_MAX]; struct pci_dev *sb_dev[SB_CARDS_MAX] = {NULL}, - *mpu_dev[SB_CARDS_MAX] = {NULL}; + *mpu_dev[SB_CARDS_MAX] = {NULL}, + *opl_dev[SB_CARDS_MAX] = {NULL}; #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE @@ -189,6 +190,7 @@ static int uart401 = 0; static int audio_activated[SB_CARDS_MAX] = {0}; static int mpu_activated[SB_CARDS_MAX] = {0}; +static int opl_activated[SB_CARDS_MAX] = {0}; #else static int isapnp = 0; static int multiple = 1; @@ -234,193 +236,204 @@ MODULE_PARM_DESC(acer, "Set this to detect cards in some ACER notebooks"); /* Please add new entries at the end of the table */ static struct { char *name; - unsigned short card_vendor, card_device, audio_vendor, audio_function, mpu_vendor, mpu_function; + unsigned short card_vendor, card_device, + audio_vendor, audio_function, + mpu_vendor, mpu_function, + opl_vendor, opl_function; short dma, dma2, mpu_io, mpu_irq; /* see sb_init() */ } sb_isapnp_list[] __initdata = { {"Sound Blaster 16", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0024), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster 16", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0026), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster 16", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0027), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster 16", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0029), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster 16", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x002b), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster Vibra16S", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0051), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster Vibra16C", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0070), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster Vibra16CL", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0080), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster Vibra16X", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00F0), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0043), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0039), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0042), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0043), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0044), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0048), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0054), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 32", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009C), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0041), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 64", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009D), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 64 Gold", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x009E), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0044), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 64", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C1), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0042), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 64", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C3), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 64", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C5), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 64", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00C7), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"Sound Blaster AWE 64", ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x00E4), ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0045), - 0,0, + 0,0,0,0, 0,1,1,-1}, {"ESS 1868", ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868), ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1868), - 0,0, + 0,0,0,0, 0,1,2,-1}, {"ESS 1868", ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1868), ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x8611), - 0,0, + 0,0,0,0, 0,1,2,-1}, {"ESS 1869 PnP AudioDrive", ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x0003), ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), - 0,0, + 0,0,0,0, 0,1,2,-1}, {"ESS 1869", ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1869), ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1869), - 0,0, + 0,0,0,0, 0,1,2,-1}, {"ESS 1878", ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1878), ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1878), - 0,0, + 0,0,0,0, 0,1,2,-1}, {"ESS 1879", ISAPNP_VENDOR('E','S','S'), ISAPNP_DEVICE(0x1879), ISAPNP_VENDOR('E','S','S'), ISAPNP_FUNCTION(0x1879), - 0,0, + 0,0,0,0, 0,1,2,-1}, {"CMI 8330 SoundPRO", ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), + ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0,1,0,-1}, {"Diamond DT0197H", ISAPNP_VENDOR('R','W','B'), ISAPNP_DEVICE(0x1688), ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), + ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0,-1,0,0}, {"ALS007", ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0007), ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), + ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 0,-1,0,0}, {"ALS100", ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0001), ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0001), + ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 1,0,0,0}, {"ALS110", ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0110), ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x1001), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x1001), + ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 1,0,0,0}, {"ALS120", ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0120), ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), + ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 1,0,0,0}, {"ALS200", ISAPNP_VENDOR('A','L','S'), ISAPNP_DEVICE(0x0200), ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0020), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x0020), + ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 1,0,0,0}, {"RTL3000", ISAPNP_VENDOR('R','T','L'), ISAPNP_DEVICE(0x3000), ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x2001), ISAPNP_VENDOR('@','X','@'), ISAPNP_FUNCTION(0x2001), + ISAPNP_VENDOR('@','H','@'), ISAPNP_FUNCTION(0x0001), 1,0,0,0}, {0} }; @@ -478,13 +491,37 @@ static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_conf } else return(NULL); + /* Cards with separate OPL3 device (ALS, CMI, etc.) + * This is just to activate the device... */ + if(sb_isapnp_list[slot].opl_vendor || sb_isapnp_list[slot].opl_function) { + if((opl_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].opl_vendor, sb_isapnp_list[slot].opl_function, NULL))) { + int ret = opl_dev[card]->prepare(opl_dev[card]); + /* If device is active, assume configured with + * /proc/isapnp and use anyway */ + if(ret && ret != -EBUSY) { + printk(KERN_ERR "sb: OPL device could not be autoconfigured.\n"); + return(sb_dev[card]); + } + if(ret == -EBUSY) + opl_activated[card] = 1; + + /* Some have irq and dma for opl. the opl3 driver wont + * use 'em so don't configure 'em and hope it works -PEL */ + opl_dev[card]->irq_resource[0].flags = 0; + opl_dev[card]->dma_resource[0].flags = 0; + + opl_dev[card] = activate_dev(sb_isapnp_list[slot].name, "opl3", opl_dev[card]); + } else + printk(KERN_ERR "sb: %s isapnp panic: opl3 device not found\n", sb_isapnp_list[slot].name); + } + /* Cards with MPU as part of Audio device (CTL and ESS) */ if(!sb_isapnp_list[slot].mpu_vendor) { mpu_config->io_base = sb_dev[card]->resource[sb_isapnp_list[slot].mpu_io].start; return(sb_dev[card]); } - - /* Cards with separate MPU device (ALS, CMI, etc */ + + /* Cards with separate MPU device (ALS, CMI, etc.) */ if(!uart401) return(sb_dev[card]); if((mpu_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].mpu_vendor, sb_isapnp_list[slot].mpu_function, NULL))) @@ -499,7 +536,7 @@ static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_conf if(ret == -EBUSY) mpu_activated[card] = 1; - /* Some mpus use audio device irq? Need to test... -PEL */ + /* Some cards ask for irq but don't need them - azummo */ if(sb_isapnp_list[slot].mpu_irq == -1) mpu_dev[card]->irq_resource[0].flags = 0; @@ -510,7 +547,7 @@ static struct pci_dev *sb_init(struct pci_bus *bus, struct address_info *hw_conf } } else - printk(KERN_ERR "sb: %s panic: mpu not found\n", sb_isapnp_list[slot].name); + printk(KERN_ERR "sb: %s isapnp panic: mpu not found\n", sb_isapnp_list[slot].name); return(sb_dev[card]); } @@ -584,8 +621,9 @@ static int __init init_sb(void) for(card = 0; card < max; card++, sb_cards_num++) { #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE - /* Please remember that even with CONFIG_ISAPNP defined one should still be - able to disable PNP support for this single driver! */ + /* Please remember that even with CONFIG_ISAPNP defined one + * should still be able to disable PNP support for this + * single driver! */ if(isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) { if(!sb_cards_num) { printk(KERN_NOTICE "sb: No ISAPnP cards found, trying standard ones...\n"); @@ -646,6 +684,8 @@ static void __exit cleanup_sb(void) sb_dev[i]->deactivate(sb_dev[i]); if(!mpu_activated[i] && mpu_dev[i]) mpu_dev[i]->deactivate(mpu_dev[i]); + if(!opl_activated[i] && opl_dev[i]) + opl_dev[i]->deactivate(opl_dev[i]); #endif } SOUND_LOCK_END; @@ -657,7 +697,7 @@ module_exit(cleanup_sb); #ifndef MODULE static int __init setup_sb(char *str) { - /* io, irq, dma, dma2 */ + /* io, irq, dma, dma2 - just the basics */ int ints[5]; str = get_options(str, ARRAY_SIZE(ints), ints); diff --git a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c index 496363a6b420..551c36240242 100644 --- a/drivers/video/aty128fb.c +++ b/drivers/video/aty128fb.c @@ -180,7 +180,7 @@ static unsigned int initdepth __initdata = 8; #ifndef MODULE static const char *mode_option __initdata = NULL; #endif -#ifndef CONFIG_PPC +#if !defined(CONFIG_PPC) && !defined(__sparc__) static void *bios_seg = NULL; #endif @@ -336,7 +336,7 @@ static int aty128_pci_register(struct pci_dev *pdev, static struct fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128 *board_list, struct fb_info_aty128 *new_node); static int aty128find_ROM(struct fb_info_aty128 *info); -#ifndef CONFIG_PPC +#if !defined(CONFIG_PPC) && !defined(__sparc__) static void aty128_get_pllinfo(struct fb_info_aty128 *info); #endif static void aty128_timings(struct fb_info_aty128 *info); @@ -1940,7 +1940,7 @@ aty128_pci_register(struct pci_dev *pdev, printk(KERN_INFO "aty128fb: Rage128 BIOS not located. Guessing...\n"); aty128_timings(info); } -#ifndef CONFIG_PPC +#if !defined(CONFIG_PPC) && !defined(__sparc__) else aty128_get_pllinfo(info); @@ -1981,12 +1981,12 @@ unmap_out: #endif /* CONFIG_PCI */ -/* PPC cannot read video ROM, so we fail by default */ +/* PPC and Sparc cannot read video ROM, so we fail by default */ static int __init aty128find_ROM(struct fb_info_aty128 *info) { int flag = 0; -#ifndef CONFIG_PPC +#if !defined(CONFIG_PPC) && !defined(__sparc__) u32 segstart; char *rom_base; char *rom; @@ -2048,7 +2048,7 @@ aty128find_ROM(struct fb_info_aty128 *info) } -#ifndef CONFIG_PPC +#if !defined(CONFIG_PPC) && !defined(__sparc__) static void __init aty128_get_pllinfo(struct fb_info_aty128 *info) { diff --git a/drivers/video/fbcon-iplan2p2.c b/drivers/video/fbcon-iplan2p2.c index 8be58150755d..1a7e21cfe20a 100644 --- a/drivers/video/fbcon-iplan2p2.c +++ b/drivers/video/fbcon-iplan2p2.c @@ -17,7 +17,10 @@ #include #include + +#ifdef __mc68000__ #include +#endif #include