From 0983223c442cbb42082dfe200410baf1613d8da4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:27:36 -0500 Subject: [PATCH] Import 2.3.21pre1 --- Documentation/Changes | 2 + Documentation/Configure.help | 19 +- Documentation/fb/clgenfb.txt | 4 +- Documentation/ioctl-number.txt | 6 +- Makefile | 14 +- arch/alpha/kernel/alpha_ksyms.c | 2 +- arch/alpha/lib/strlen_user.S | 30 +- arch/i386/config.in | 3 +- arch/i386/defconfig | 62 +- arch/i386/kernel/apm.c | 35 +- arch/i386/kernel/i386_ksyms.c | 10 +- arch/i386/lib/Makefile | 4 + arch/i386/lib/mmx.c | 236 +++ arch/i386/lib/usercopy.c | 53 +- arch/sh/config.in | 10 +- arch/sparc64/solaris/timod.c | 2 +- drivers/acorn/block/Config.in | 10 +- drivers/acorn/scsi/Config.in | 24 +- drivers/block/Config.in | 330 ++-- drivers/block/Makefile | 8 +- drivers/block/cmos-probe.c | 78 - drivers/block/cpqarray.c | 4 + drivers/block/ide-disk.c | 144 +- drivers/block/ide-dma.c | 12 +- drivers/block/ide-floppy.c | 2 +- drivers/block/ide-geometry.c | 225 +++ drivers/block/ide-pmac.c | 121 +- drivers/block/ide.c | 146 +- drivers/block/pdc202xx.c | 10 +- drivers/char/adbmouse.c | 2 +- drivers/char/busmouse.c | 7 +- drivers/char/console.c | 2 +- drivers/char/dn_keyb.c | 2 +- drivers/char/drm/fops.c | 2 +- drivers/char/ftape/Config.in | 26 +- drivers/char/joystick/Config.in | 22 +- drivers/char/keyboard.c | 2 +- drivers/char/misc.c | 6 + drivers/char/n_hdlc.c | 97 +- drivers/char/n_tty.c | 5 +- drivers/char/pc110pad.c | 19 +- drivers/char/pc_keyb.c | 126 +- drivers/char/ppdev.h | 4 +- drivers/char/tty_io.c | 60 +- drivers/fc4/Config.in | 32 +- drivers/net/Config.in | 398 ++-- drivers/net/Makefile | 229 +-- drivers/net/Space.c | 45 +- drivers/net/arcnet.c | 2 + drivers/net/ncr885_debug.h | 54 + drivers/net/ncr885e.c | 1458 ++++++++++++++ drivers/net/ncr885e.h | 367 ++++ drivers/net/sgiseeq.h | 2 +- drivers/net/sk_mca.c | 1 + drivers/net/tokenring/Config.in | 15 + drivers/net/tokenring/Makefile | 51 + drivers/net/{ => tokenring}/ibmtr.c | 48 +- drivers/net/{ => tokenring}/ibmtr.h | 2 +- drivers/net/{ => tokenring}/olympic.c | 0 drivers/net/{ => tokenring}/olympic.h | 0 drivers/net/{ => tokenring}/sktr.c | 168 +- drivers/net/{ => tokenring}/sktr.h | 7 +- drivers/net/{ => tokenring}/sktr_firmware.h | 0 drivers/net/wan/Config.in | 64 + drivers/net/wan/Makefile | 181 ++ drivers/net/{ => wan}/cosa.c | 0 drivers/net/{ => wan}/cosa.h | 0 drivers/net/{ => wan}/cycx_drv.c | 0 drivers/net/{ => wan}/cycx_main.c | 0 drivers/net/{ => wan}/cycx_x25.c | 0 drivers/net/{ => wan}/dlci.c | 0 drivers/net/{ => wan}/hostess_sv11.c | 2 +- drivers/net/{ => wan}/lapbether.c | 0 drivers/net/wan/sbni.c | 1533 +++++++++++++++ drivers/net/wan/sbni.h | 194 ++ drivers/net/{ => wan}/sdla.c | 0 drivers/net/{ => wan}/sdla_fr.c | 0 drivers/net/{ => wan}/sdla_ppp.c | 0 drivers/net/{ => wan}/sdla_x25.c | 0 drivers/net/{ => wan}/sdladrv.c | 1 + drivers/net/{ => wan}/sdlamain.c | 1 + drivers/net/{ => wan}/sealevel.c | 2 +- drivers/net/{ => wan}/syncppp.c | 0 drivers/net/{ => wan}/syncppp.h | 0 drivers/net/{ => wan}/x25_asy.c | 0 drivers/net/{ => wan}/x25_asy.h | 0 drivers/net/{ => wan}/z85230.c | 0 drivers/net/{ => wan}/z85230.h | 0 drivers/pnp/Config.in | 2 +- drivers/sbus/char/pcikbd.c | 2 +- drivers/sbus/char/sunkbd.c | 2 +- drivers/sbus/char/sunmouse.c | 4 +- drivers/sbus/char/uctrl.c | 2 +- drivers/scsi/sg.c | 2 +- drivers/sgi/char/shmiq.c | 2 +- drivers/usb/audio.c | 197 +- drivers/usb/mouse.c | 2 +- drivers/video/Config.in | 656 +++---- drivers/video/Makefile | 8 +- drivers/video/amifb.c | 1 + drivers/video/aty.h | 13 + drivers/video/atyfb.c | 216 ++- drivers/video/chipsfb.c | 40 +- drivers/video/controlfb.c | 50 +- drivers/video/fbcon-afb.c | 10 +- drivers/video/fbcon-cfb16.c | 75 +- drivers/video/fbcon-cfb2.c | 24 +- drivers/video/fbcon-cfb24.c | 45 +- drivers/video/fbcon-cfb32.c | 114 +- drivers/video/fbcon-cfb4.c | 24 +- drivers/video/fbcon-cfb8.c | 44 +- drivers/video/fbcon-ilbm.c | 10 +- drivers/video/fbcon-iplan2p2.c | 8 +- drivers/video/fbcon-iplan2p4.c | 8 +- drivers/video/fbcon-iplan2p8.c | 2 +- drivers/video/fbcon-mac.c | 12 +- drivers/video/fbcon-mfb.c | 30 +- drivers/video/fbcon.c | 54 +- drivers/video/fbmem.c | 5 + drivers/video/imsttfb.c | 31 +- drivers/video/modedb.c | 2 +- drivers/video/platinumfb.c | 147 +- drivers/video/sbusfb.c | 6 +- drivers/video/tdfxfb.c | 1891 +++++++++++++++++++ drivers/video/valkyriefb.c | 8 +- drivers/video/vesafb.c | 2 + drivers/video/virgefb.c | 2 +- fs/buffer.c | 40 +- fs/exec.c | 15 +- fs/fcntl.c | 42 +- fs/ncpfs/dir.c | 10 +- fs/partitions/msdos.c | 1 - fs/smbfs/cache.c | 79 +- fs/smbfs/file.c | 42 +- include/asm-i386/keyboard.h | 32 +- include/asm-i386/mmx.h | 14 + include/asm-i386/page.h | 18 + include/asm-i386/string-486.h | 88 +- include/asm-i386/string.h | 44 + include/asm-i386/uaccess.h | 3 +- include/asm-sparc/keyboard.h | 28 + include/linux/fb.h | 2 + include/linux/fs.h | 2 +- include/linux/ide.h | 2 +- include/linux/net.h | 2 +- {drivers/char => include/linux}/pc_keyb.h | 4 +- include/linux/synclink.h | 16 +- include/video/fbcon.h | 46 +- include/video/macmodes.h | 3 + kernel/signal.c | 12 +- mm/filemap.c | 4 + net/core/sock.c | 6 +- net/decnet/dn_nsp_in.c | 3 +- net/ipv4/tcp.c | 2 +- net/ipv4/tcp_input.c | 11 +- net/socket.c | 6 +- net/unix/af_unix.c | 2 +- net/x25/x25_in.c | 1 + 158 files changed, 8951 insertions(+), 2227 deletions(-) create mode 100644 arch/i386/lib/mmx.c delete mode 100644 drivers/block/cmos-probe.c create mode 100644 drivers/block/ide-geometry.c create mode 100644 drivers/net/ncr885_debug.h create mode 100644 drivers/net/ncr885e.c create mode 100644 drivers/net/ncr885e.h create mode 100644 drivers/net/tokenring/Config.in create mode 100644 drivers/net/tokenring/Makefile rename drivers/net/{ => tokenring}/ibmtr.c (97%) rename drivers/net/{ => tokenring}/ibmtr.h (99%) rename drivers/net/{ => tokenring}/olympic.c (100%) rename drivers/net/{ => tokenring}/olympic.h (100%) rename drivers/net/{ => tokenring}/sktr.c (95%) rename drivers/net/{ => tokenring}/sktr.h (99%) rename drivers/net/{ => tokenring}/sktr_firmware.h (100%) create mode 100644 drivers/net/wan/Config.in create mode 100644 drivers/net/wan/Makefile rename drivers/net/{ => wan}/cosa.c (100%) rename drivers/net/{ => wan}/cosa.h (100%) rename drivers/net/{ => wan}/cycx_drv.c (100%) rename drivers/net/{ => wan}/cycx_main.c (100%) rename drivers/net/{ => wan}/cycx_x25.c (100%) rename drivers/net/{ => wan}/dlci.c (100%) rename drivers/net/{ => wan}/hostess_sv11.c (99%) rename drivers/net/{ => wan}/lapbether.c (100%) create mode 100644 drivers/net/wan/sbni.c create mode 100644 drivers/net/wan/sbni.h rename drivers/net/{ => wan}/sdla.c (100%) rename drivers/net/{ => wan}/sdla_fr.c (100%) rename drivers/net/{ => wan}/sdla_ppp.c (100%) rename drivers/net/{ => wan}/sdla_x25.c (100%) rename drivers/net/{ => wan}/sdladrv.c (99%) rename drivers/net/{ => wan}/sdlamain.c (99%) rename drivers/net/{ => wan}/sealevel.c (99%) rename drivers/net/{ => wan}/syncppp.c (100%) rename drivers/net/{ => wan}/syncppp.h (100%) rename drivers/net/{ => wan}/x25_asy.c (100%) rename drivers/net/{ => wan}/x25_asy.h (100%) rename drivers/net/{ => wan}/z85230.c (100%) rename drivers/net/{ => wan}/z85230.h (100%) create mode 100644 drivers/video/tdfxfb.c create mode 100644 include/asm-i386/mmx.h rename {drivers/char => include/linux}/pc_keyb.h (98%) diff --git a/Documentation/Changes b/Documentation/Changes index d69f5130f8b3..c3c1cb7263a7 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -392,6 +392,8 @@ PPP Due to changes in the PPP driver and routing code, those of you using PPP networking will need to upgrade your pppd. +See ftp://cs.anu.edu.au/pub/software/ppp/ for newest versions. + iBCS ==== diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 8c00e9998b3f..cb15ef5240d4 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -1976,8 +1976,9 @@ CONFIG_M386 - "386" for the AMD/Cyrix/Intel 386DX/DXL/SL/SLC/SX, Cyrix/TI 486DLC/DLC2 and UMC 486SX-S. Only "386" kernels will run on a 386 class machine. - - "486" for the AMD/Cyrix/IBM/Intel DX4 or 486DX/DX2/SL/SX/SX2, - AMD/Cyrix 5x86, NexGen Nx586 and UMC U5D or U5S. + - "486" for the AMD/Cyrix/IBM/Intel 486DX/DX2/DX4 or + SL/SLC/SLC2/SLC3/SX/SX2, AMD/Cyrix 5x86, NexGen Nx586 and + UMC U5D or U5S. - "586" for generic Pentium CPUs, possibly lacking the TSC (time stamp counter) register. - "Pentium" for the Intel Pentium/Pentium MMX, AMD K5, K6 and @@ -2120,7 +2121,7 @@ CONFIG_FB_CLGEN Say N unless you have such a graphics board or plan to get one before you next recompile the kernel. -Permedia2 support (experimental) +Permedia2 support (EXPERIMENTAL) CONFIG_FB_PM2 Say Y here if this is your graphics board. @@ -8063,7 +8064,7 @@ CONFIG_NTFS_FS The module will be called ntfs.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. -NTFS read-write support (experimental) +NTFS read-write support (EXPERIMENTAL) CONFIG_NTFS_RW If you say Y here, you will (hopefully) be able to write to NTFS file systems as well as read from them. The read-write support @@ -8128,7 +8129,7 @@ CONFIG_AFFS_FS The module is called affs.o. If you want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say N. -Apple Macintosh filesystem support (experimental) +Apple Macintosh filesystem support (EXPERIMENTAL) CONFIG_HFS_FS If you say Y here, you will be able to mount Macintosh-formatted floppy disks and hard drive partitions with full read-write access. @@ -8192,7 +8193,7 @@ CONFIG_AUTOFS_FS If you are not a part of a fairly large, distributed network, you probably do not need an automounter, and can say N here. -EFS filesystem support (experimental) +EFS filesystem support (EXPERIMENTAL) CONFIG_EFS_FS EFS is an older filesystem used for non-ISO9660 CDROMs and hard disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer uses @@ -8202,7 +8203,7 @@ CONFIG_EFS_FS what all this is about, it's safe to say N. For more information about EFS see its home page at http://aeschi.ch.eu.org/efs/ . - If you want to compile the UFS filesystem support as a module ( = + If you want to compile the EFS filesystem support as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read Documentation/modules.txt. The module will be called efs.o. @@ -8242,7 +8243,7 @@ CONFIG_UFS_FS If you haven't heard about all of this before, it's safe to say N. -UFS filesystem write support (experimental) +UFS filesystem write support (EXPERIMENTAL) CONFIG_UFS_FS_WRITE Say Y here if you want to try writing to UFS partitions. This is experimental, so you should back up your UFS partitions beforehand. @@ -12593,7 +12594,7 @@ CONFIG_PPDEV If unsure, say N. -Kernel httpd acceleration (experimental) +Kernel httpd acceleration (EXPERIMENTAL) CONFIG_KHTTPD The kernel httpd acceleration daemon (kHTTPd) is a (limited) web server build into the kernel. It is limited since it can only diff --git a/Documentation/fb/clgenfb.txt b/Documentation/fb/clgenfb.txt index aad85d9a920d..4e3de5e83120 100644 --- a/Documentation/fb/clgenfb.txt +++ b/Documentation/fb/clgenfb.txt @@ -45,9 +45,7 @@ Full support for startup video modes (modedb) will be integrated soon. Version 1.9.4.4 --------------- * Preliminary Laguna support -* Overhaul color register routines. Shifts are now based on offset - values in var.cmap, so as long as those are correctly set for PReP - things should work (knock on wood). +* Overhaul color register routines. * Associated with the above, console colors are now obtained from a LUT called 'palette' instead of from the VGA registers. This code was modeled after that in atyfb and matroxfb. diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index cc9e3704bbf0..aa075a45c854 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt @@ -1,5 +1,5 @@ Ioctl Numbers -2 September 1999 +10 October 1999 Michael Elizabeth Chastain @@ -114,6 +114,8 @@ Code Seq# Include File Comments 'e' 00-1F linux/video_encoder.h conflict! 'e' 00-1F net/irda/irtty.h conflict! 'f' 00-1F linux/ext2_fs.h +'h' 00-7F Charon filesystem + 'i' 00-3F linux/i2o.h 'j' 00-3F linux/joystick.h 'k' all asm-sparc/kbio.h @@ -140,6 +142,8 @@ Code Seq# Include File Comments 'v' 00-1F linux/ext2_fs.h conflict! 'v' all linux/videodev.h conflict! 'w' all CERN SCI driver +'y' 00-1F packet based user level communications + 'z' 00-3F CAN bus card 'z' 40-7F CAN bus card diff --git a/Makefile b/Makefile index 39e92a6a0cd4..9a3da9537c76 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 3 -SUBLEVEL = 20 +SUBLEVEL = 21 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) @@ -126,6 +126,18 @@ endif DRIVERS := $(DRIVERS) drivers/net/net.a +ifdef CONFIG_NET_FC +DRIVERS := $(DRIVERS) drivers/net/fc/fc.a +endif + +ifdef CONFIG_TR +DRIVERS := $(DRIVERS) drivers/net/tokenring/tr.a +endif + +ifdef CONFIG_WAN +DRIVERS := $(DRIVERS) drivers/net/wan/wan.a +endif + ifdef CONFIG_ATM DRIVERS := $(DRIVERS) drivers/atm/atm.a endif diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index d8e1082d8c33..f280e454165c 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -139,7 +139,7 @@ EXPORT_SYMBOL(alpha_fp_emul); EXPORT_SYMBOL_NOVERS(__copy_user); EXPORT_SYMBOL_NOVERS(__do_clear_user); EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(__strlen_user); +EXPORT_SYMBOL(__strnlen_user); /* * The following are specially called from the semaphore assembly stubs. diff --git a/arch/alpha/lib/strlen_user.S b/arch/alpha/lib/strlen_user.S index 1f4fb07f589a..80094e18a267 100644 --- a/arch/alpha/lib/strlen_user.S +++ b/arch/alpha/lib/strlen_user.S @@ -3,6 +3,13 @@ * * Return the length of the string including the NUL terminator * (strlen+1) or zero if an error occurred. + * + * In places where it is critical to limit the processing time, + * and the data is not trusted, strnlen_user() should be used. + * It will return a value greater than its second argument if + * that limit would be exceeded. This implementation is allowed + * to access memory beyond the limit, but will not cross a page + * boundary when doing so. */ #include @@ -27,6 +34,14 @@ .align 3 __strlen_user: + ldah a1, 32767(zero) # do not use plain strlen_user() for strings + # that might be almost 2 GB long; you should + # be using strnlen_user() instead + + .globl __strnlen_user + + .align 3 +__strnlen_user: ldgp $29,0($27) # we do exceptions -- we need the gp. .prologue 1 @@ -37,9 +52,17 @@ __strlen_user: or t1, t0, t0 subq a0, 1, a0 # get our +1 for the return cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0 + subq a1, 7, t2 + subq a0, v0, t0 bne t1, $found -$loop: EX( ldq t0, 8(v0) ) + addq t2, t0, t2 + addq a1, 1, a1 + + .align 3 +$loop: ble t2, $limit + EX( ldq t0, 8(v0) ) + subq t2, 8, t2 addq v0, 8, v0 # addr += 8 cmpbge zero, t0, t1 beq t1, $loop @@ -61,4 +84,9 @@ $found: negq t1, t2 # clear all but least set bit $exception: ret + .align 3 # currently redundant +$limit: + subq a1, t2, v0 + ret + .end __strlen_user diff --git a/arch/i386/config.in b/arch/i386/config.in index 8e9c288326e3..872822e6cadc 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -183,9 +183,8 @@ if [ "$CONFIG_VT" = "y" ]; then bool 'Video mode selection support' CONFIG_VIDEO_SELECT if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE - bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB + source drivers/video/Config.in fi - source drivers/video/Config.in endmenu fi diff --git a/arch/i386/defconfig b/arch/i386/defconfig index bf0e611d8633..15d916e3b507 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -41,6 +41,9 @@ CONFIG_MODULES=y # # CONFIG_BIGMEM is not set CONFIG_NET=y +# CONFIG_VISWS is not set +CONFIG_X86_IO_APIC=y +CONFIG_X86_LOCAL_APIC=y CONFIG_PCI=y # CONFIG_PCI_GOBIOS is not set # CONFIG_PCI_GODIRECT is not set @@ -48,9 +51,6 @@ CONFIG_PCI_GOANY=y CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y # CONFIG_MCA is not set -# CONFIG_VISWS is not set -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y # # PCMCIA/Cardbus support @@ -95,10 +95,13 @@ CONFIG_BLK_DEV_IDE=y CONFIG_BLK_DEV_IDEDISK=y # CONFIG_IDEDISK_MULTI_MODE is not set CONFIG_BLK_DEV_IDECD=y -# CONFIG_IDECD_SLOTS is not set # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set # CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# CONFIG_BLK_DEV_CMD640=y # CONFIG_BLK_DEV_CMD640_ENHANCED is not set CONFIG_BLK_DEV_RZ1000=y @@ -106,8 +109,6 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_IDEDMA_PCI is not set # CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_AEC6210 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_IDE_CHIPSETS is not set @@ -241,53 +242,6 @@ CONFIG_DUMMY=m # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_EISA=y -# CONFIG_PCNET32 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -# CONFIG_DE4X5 is not set -# CONFIG_DEC_ELCP is not set -# CONFIG_DGRS is not set -CONFIG_EEXPRESS_PRO100=y -# CONFIG_NE2K_PCI is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_NET_POCKET is not set -# CONFIG_FDDI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_RADIO is not set - -# -# Token ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set - -# -# Wan interfaces -# -# CONFIG_HOSTESS_SV11 is not set -# CONFIG_COSA is not set -# CONFIG_SEALEVEL_4021 is not set -# CONFIG_DLCI is not set -# CONFIG_WAN_DRIVERS is not set -# CONFIG_LAPBETHER is not set -# CONFIG_X25_ASY is not set - -# -# PCMCIA network devices -# -# CONFIG_PCMCIA_PCNET is not set -# CONFIG_PCMCIA_3C589 is not set -CONFIG_PCMCIA_RAYCS=y -CONFIG_PCMCIA_NETCARD=y # # Amateur Radio support @@ -327,7 +281,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_BUSMOUSE is not set CONFIG_MOUSE=y CONFIG_PSMOUSE=y -CONFIG_82C710_MOUSE=y +# CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set # CONFIG_QIC02_TAPE is not set # CONFIG_WATCHDOG is not set diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 3bafdfcfc50b..a549946674ea 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -643,33 +643,6 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life) return APM_SUCCESS; } -static int apm_get_battery_status(u_short which, u_short *status, - u_short *bat, u_short *life, u_short *nbat) -{ - u32 eax; - u32 ebx; - u32 ecx; - u32 edx; - u32 esi; - - if (apm_bios_info.version < 0x0102) { - /* pretend we only have one battery. */ - if (which != 1) - return APM_BAD_DEVICE; - *nbat = 1; - return apm_get_power_status(status, bat, life); - } - - if (apm_bios_call(0x530a, (0x8000 | (which)), 0, &eax, - &ebx, &ecx, &edx, &esi)) - return (eax >> 8) & 0xff; - *status = ebx; - *bat = ecx; - *life = edx; - *nbat = esi; - return APM_SUCCESS; -} - static int __init apm_engage_power_management(u_short device) { u32 eax; @@ -1263,7 +1236,6 @@ int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy) unsigned short bx; unsigned short cx; unsigned short dx; - unsigned short nbat; unsigned short error; unsigned short ac_line_status = 0xff; unsigned short battery_status = 0xff; @@ -1473,7 +1445,7 @@ static int __init apm_init(void) if (apm_bios_info.version == 0) { printk(KERN_INFO "apm: BIOS not found.\n"); - return; + return -1; } printk(KERN_INFO "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n", @@ -1483,7 +1455,7 @@ static int __init apm_init(void) driver_version); if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0) { printk(KERN_INFO "apm: no 32 bit BIOS support\n"); - return; + return -1; } /* @@ -1512,7 +1484,7 @@ static int __init apm_init(void) if (apm_disabled) { printk(KERN_NOTICE "apm: disabled on user request.\n"); - return; + return -1; } #ifdef CONFIG_SMP @@ -1571,6 +1543,7 @@ static int __init apm_init(void) misc_register(&apm_device); kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD); + return 0; } module_init(apm_init) diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 5f5a6d50b573..043132b8e9f5 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -18,6 +18,7 @@ #include #include #include +#include extern void dump_thread(struct pt_regs *, struct user *); extern int dump_fpu(elf_fpregset_t *); @@ -73,7 +74,13 @@ EXPORT_SYMBOL(clear_user); EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(__generic_copy_from_user); EXPORT_SYMBOL(__generic_copy_to_user); -EXPORT_SYMBOL(strlen_user); +EXPORT_SYMBOL(strnlen_user); + +#ifdef CONFIG_X86_USE_3DNOW +EXPORT_SYMBOL(_mmx_memcpy); +EXPORT_SYMBOL(mmx_clear_page); +EXPORT_SYMBOL(mmx_copy_page); +#endif #ifdef __SMP__ EXPORT_SYMBOL(cpu_data); @@ -119,3 +126,4 @@ EXPORT_SYMBOL(mca_is_adapter_used); #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif + diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index a6f8dff0993b..3f7bef4aa5d6 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile @@ -9,4 +9,8 @@ L_TARGET = lib.a L_OBJS = checksum.o old-checksum.o delay.o \ usercopy.o getuser.o putuser.o +ifdef CONFIG_X86_USE_3DNOW +L_OBJS += mmx.o +endif + include $(TOPDIR)/Rules.make diff --git a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c new file mode 100644 index 000000000000..5257aeba6d8f --- /dev/null +++ b/arch/i386/lib/mmx.c @@ -0,0 +1,236 @@ +#include +#include +#include + +/* + * MMX 3DNow! library helper functions + * + * To do: + * We can use MMX just for prefetch in IRQ's. This may be a win. + * (reported so on K6-III) + * We should use a better code neutral filler for the short jump + * leal ebx. [ebx] is apparently best for K6-2, but Cyrix ?? + * We also want to clobber the filler register so we dont get any + * register forwarding stalls on the filler. + * + * Add *user handling. Checksums are not a win with MMX on any CPU + * tested so far for any MMX solution figured. + * + */ + +void *_mmx_memcpy(void *to, const void *from, size_t len) +{ + void *p=to; + int i= len >> 6; /* len/64 */ + + if (!(current->flags & PF_USEDFPU)) + clts(); + else + { + __asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387)); + current->flags &= ~PF_USEDFPU; + } + + __asm__ __volatile__ ( + "1: prefetch (%0)\n" /* This set is 28 bytes */ + " prefetch 64(%0)\n" + " prefetch 128(%0)\n" + " prefetch 192(%0)\n" + " prefetch 256(%0)\n" + "2: \n" + ".section .fixup, \"ax\"\n" + "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + " jmp 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b, 3b\n" + ".previous" + : : "r" (from) ); + + + for(; i>0; i--) + { + __asm__ __volatile__ ( + "1: prefetch 320(%0)\n" + "2: movq (%0), %%mm0\n" + " movq 8(%0), %%mm1\n" + " movq 16(%0), %%mm2\n" + " movq 24(%0), %%mm3\n" + " movq %%mm0, (%1)\n" + " movq %%mm1, 8(%1)\n" + " movq %%mm2, 16(%1)\n" + " movq %%mm3, 24(%1)\n" + " movq 32(%0), %%mm0\n" + " movq 40(%0), %%mm1\n" + " movq 48(%0), %%mm2\n" + " movq 56(%0), %%mm3\n" + " movq %%mm0, 32(%1)\n" + " movq %%mm1, 40(%1)\n" + " movq %%mm2, 48(%1)\n" + " movq %%mm3, 56(%1)\n" + ".section .fixup, \"ax\"\n" + "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + " jmp 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b, 3b\n" + ".previous" + : : "r" (from), "r" (to) : "memory"); + from+=64; + to+=64; + } + /* + * Now do the tail of the block + */ + __memcpy(to, from, len&63); + stts(); + return p; +} + +static void fast_clear_page(long page) +{ + int i; + if (!(current->flags & PF_USEDFPU)) + clts(); + else + { + __asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387)); + current->flags &= ~PF_USEDFPU; + } + + __asm__ __volatile__ ( + " pxor %%mm0, %%mm0\n" : : + ); + + for(i=0;i<4096/128;i++) + { + __asm__ __volatile__ ( + " movq %%mm0, (%0)\n" + " movq %%mm0, 8(%0)\n" + " movq %%mm0, 16(%0)\n" + " movq %%mm0, 24(%0)\n" + " movq %%mm0, 32(%0)\n" + " movq %%mm0, 40(%0)\n" + " movq %%mm0, 48(%0)\n" + " movq %%mm0, 56(%0)\n" + " movq %%mm0, 64(%0)\n" + " movq %%mm0, 72(%0)\n" + " movq %%mm0, 80(%0)\n" + " movq %%mm0, 88(%0)\n" + " movq %%mm0, 96(%0)\n" + " movq %%mm0, 104(%0)\n" + " movq %%mm0, 112(%0)\n" + " movq %%mm0, 120(%0)\n" + : : "r" (page) : "memory"); + page+=128; + } + stts(); +} + +static void fast_copy_page(long to, long from) +{ + int i; + if (!(current->flags & PF_USEDFPU)) + clts(); + else + { + __asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387)); + current->flags &= ~PF_USEDFPU; + } + + __asm__ __volatile__ ( + "1: prefetch (%0)\n" + " prefetch 64(%0)\n" + " prefetch 128(%0)\n" + " prefetch 192(%0)\n" + " prefetch 256(%0)\n" + "2: \n" + ".section .fixup, \"ax\"\n" + "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + " jmp 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b, 3b\n" + ".previous" + : : "r" (from) ); + + for(i=0; i<4096/64; i++) + { + __asm__ __volatile__ ( + "1: prefetch 320(%0)\n" + "2: movq (%0), %%mm0\n" + " movq 8(%0), %%mm1\n" + " movq 16(%0), %%mm2\n" + " movq 24(%0), %%mm3\n" + " movq %%mm0, (%1)\n" + " movq %%mm1, 8(%1)\n" + " movq %%mm2, 16(%1)\n" + " movq %%mm3, 24(%1)\n" + " movq 32(%0), %%mm0\n" + " movq 40(%0), %%mm1\n" + " movq 48(%0), %%mm2\n" + " movq 56(%0), %%mm3\n" + " movq %%mm0, 32(%1)\n" + " movq %%mm1, 40(%1)\n" + " movq %%mm2, 48(%1)\n" + " movq %%mm3, 56(%1)\n" + ".section .fixup, \"ax\"\n" + "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + " jmp 2b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 1b, 3b\n" + ".previous" + : : "r" (from), "r" (to) : "memory"); + from+=64; + to+=64; + } + stts(); +} + +/* + * Favour MMX for page clear and copy. + */ + +static void slow_zero_page(long page) +{ + int d0, d1; + __asm__ __volatile__( \ + "cld\n\t" \ + "rep ; stosl" \ + : "=&c" (d0), "=&D" (d1) + :"a" (0),"1" (page),"0" (1024) + :"memory"); +} + +void mmx_clear_page(long page) +{ + if(in_interrupt()) + slow_zero_page(page); + else + fast_clear_page(page); +} + +static void slow_copy_page(long to, long from) +{ + int d0, d1, d2; + __asm__ __volatile__( \ + "cld\n\t" \ + "rep ; movsl" \ + : "=&c" (d0), "=&D" (d1), "=&S" (d2) \ + : "0" (1024),"1" ((long) to),"2" ((long) from) \ + : "memory"); +} + + +void mmx_copy_page(long to, long from) +{ + if(in_interrupt()) + slow_copy_page(to, from); + else + fast_copy_page(to, from); +} diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c index f43be511f34a..21d8fdf62f98 100644 --- a/arch/i386/lib/usercopy.c +++ b/arch/i386/lib/usercopy.c @@ -6,6 +6,37 @@ * Copyright 1997 Linus Torvalds */ #include +#include + +#ifdef CONFIG_X86_USE_3DNOW_AND_WORKS + +unsigned long +__generic_copy_to_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + { + if(n<512) + __copy_user(to,from,n); + else + mmx_copy_user(to,from,n); + } + return n; +} + +unsigned long +__generic_copy_from_user(void *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + { + if(n<512) + __copy_user_zeroing(to,from,n); + else + mmx_copy_user_zeroing(to, from, n); + } + return n; +} + +#else unsigned long __generic_copy_to_user(void *to, const void *from, unsigned long n) @@ -23,6 +54,7 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n) return n; } +#endif /* * Copy a null terminated string from userspace. @@ -117,26 +149,31 @@ __clear_user(void *to, unsigned long n) /* * Return the size of a string (including the ending 0) * - * Return 0 for error + * Return 0 on exception, a value greater than N if too long */ -long strlen_user(const char *s) +long strnlen_user(const char *s, long n) { - unsigned long res; + unsigned long mask = -__addr_ok(s); + unsigned long res, tmp; __asm__ __volatile__( + " andl %0,%%ecx\n" "0: repne; scasb\n" - " notl %0\n" + " setne %%al\n" + " subl %%ecx,%0\n" + " addl %0,%%eax\n" "1:\n" ".section .fixup,\"ax\"\n" - "2: xorl %0,%0\n" + "2: xorl %%eax,%%eax\n" " jmp 1b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 0b,2b\n" ".previous" - :"=c" (res), "=D" (s) - :"1" (s), "a" (0), "0" (-__addr_ok(s))); - return res & -__addr_ok(s); + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp) + :"0" (n), "1" (s), "2" (0), "3" (mask) + :"cc"); + return res & mask; } diff --git a/arch/sh/config.in b/arch/sh/config.in index 043af83045c0..48874a0f0f9c 100644 --- a/arch/sh/config.in +++ b/arch/sh/config.in @@ -22,8 +22,8 @@ mainmenu_option next_comment comment 'Loadable module support' bool 'Enable loadable module support' CONFIG_MODULES if [ "$CONFIG_MODULES" = "y" ]; then - bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS - bool 'Kernel module loader' CONFIG_KMOD + bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS + bool ' Kernel module loader' CONFIG_KMOD fi endmenu @@ -44,7 +44,7 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then - bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD + bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD fi tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP @@ -52,14 +52,14 @@ tristate 'Network block device support' CONFIG_BLK_DEV_NBD endmenu if [ "$CONFIG_NET" = "y" ]; then - source net/Config.in + source net/Config.in fi mainmenu_option next_comment comment 'Unix 98 PTY support' bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then - int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 + int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 fi endmenu diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c index 5ee6df467f2c..050c6e0b3890 100644 --- a/arch/sparc64/solaris/timod.c +++ b/arch/sparc64/solaris/timod.c @@ -152,7 +152,7 @@ static void timod_wake_socket(unsigned int fd) sock = ¤t->files->fd[fd]->f_dentry->d_inode->u.socket_i; wake_up_interruptible(&sock->wait); if (sock->fasync_list && !(sock->flags & SO_WAITDATA)) - kill_fasync(sock->fasync_list, SIGIO); + kill_fasync(sock->fasync_list, SIGIO, POLL_IN); SOLD("done"); } diff --git a/drivers/acorn/block/Config.in b/drivers/acorn/block/Config.in index 6ed6cf6a3389..be2d2432ff20 100644 --- a/drivers/acorn/block/Config.in +++ b/drivers/acorn/block/Config.in @@ -5,11 +5,11 @@ mainmenu_option next_comment comment 'Acorn-specific block devices' if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" ]; then - tristate 'Old Archimedes floppy (1772) support' CONFIG_BLK_DEV_FD1772 - tristate 'MFM harddisk support' CONFIG_BLK_DEV_MFM - if [ "$CONFIG_BLK_DEV_MFM" != "n" ]; then - bool ' Autodetect hard drive geometry' CONFIG_BLK_DEV_MFM_AUTODETECT - fi + tristate 'Old Archimedes floppy (1772) support' CONFIG_BLK_DEV_FD1772 + tristate 'MFM harddisk support' CONFIG_BLK_DEV_MFM + if [ "$CONFIG_BLK_DEV_MFM" != "n" ]; then + bool ' Autodetect hard drive geometry' CONFIG_BLK_DEV_MFM_AUTODETECT + fi fi endmenu diff --git a/drivers/acorn/scsi/Config.in b/drivers/acorn/scsi/Config.in index 68d4f920bf51..28030bc32d1f 100644 --- a/drivers/acorn/scsi/Config.in +++ b/drivers/acorn/scsi/Config.in @@ -3,21 +3,21 @@ # dep_tristate 'Acorn SCSI card (aka30) support' CONFIG_SCSI_ACORNSCSI_3 $CONFIG_SCSI if [ "$CONFIG_SCSI_ACORNSCSI_3" != "n" ]; then - bool ' Support SCSI 2 Tagged queueing' CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE - bool ' Support SCSI 2 Synchronous Transfers' CONFIG_SCSI_ACORNSCSI_SYNC + bool ' Support SCSI 2 Tagged queueing' CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE + bool ' Support SCSI 2 Synchronous Transfers' CONFIG_SCSI_ACORNSCSI_SYNC fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'ARXE SCSI support (Experimental)' CONFIG_SCSI_ARXESCSI $CONFIG_SCSI - dep_tristate 'CumanaSCSI II support (Experimental)' CONFIG_SCSI_CUMANA_2 $CONFIG_SCSI - dep_tristate 'EESOX support (Experimental)' CONFIG_SCSI_EESOXSCSI $CONFIG_SCSI - dep_tristate 'PowerTec support (Experimental)' CONFIG_SCSI_POWERTECSCSI $CONFIG_SCSI + dep_tristate 'ARXE SCSI support (EXPERIMENTAL)' CONFIG_SCSI_ARXESCSI $CONFIG_SCSI + dep_tristate 'CumanaSCSI II support (EXPERIMENTAL)' CONFIG_SCSI_CUMANA_2 $CONFIG_SCSI + dep_tristate 'EESOX support (EXPERIMENTAL)' CONFIG_SCSI_EESOXSCSI $CONFIG_SCSI + dep_tristate 'PowerTec support (EXPERIMENTAL)' CONFIG_SCSI_POWERTECSCSI $CONFIG_SCSI - comment 'The following drivers are not fully supported' + comment 'The following drivers are not fully supported' - dep_tristate 'CumanaSCSI I support' CONFIG_SCSI_CUMANA_1 $CONFIG_SCSI - if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" ]; then - dep_tristate 'EcoScsi support' CONFIG_SCSI_ECOSCSI $CONFIG_SCSI - fi - dep_tristate 'Oak SCSI support' CONFIG_SCSI_OAK1 $CONFIG_SCSI + dep_tristate 'CumanaSCSI I support' CONFIG_SCSI_CUMANA_1 $CONFIG_SCSI + if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" ]; then + dep_tristate 'EcoScsi support' CONFIG_SCSI_ECOSCSI $CONFIG_SCSI + fi + dep_tristate 'Oak SCSI support' CONFIG_SCSI_OAK1 $CONFIG_SCSI fi diff --git a/drivers/block/Config.in b/drivers/block/Config.in index 7c00c4dd2331..c23b8d094b4c 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -6,198 +6,200 @@ comment 'Block devices' tristate 'Normal PC floppy disk support' CONFIG_BLK_DEV_FD if [ "$CONFIG_AMIGA" = "y" ]; then - tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY + tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY fi if [ "$CONFIG_ATARI" = "y" ]; then - tristate 'Atari floppy support' CONFIG_ATARI_FLOPPY + tristate 'Atari floppy support' CONFIG_ATARI_FLOPPY fi if [ "$CONFIG_MAC" = "y" ]; then - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)' CONFIG_BLK_DEV_SWIM_IOP - fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Macintosh IIfx/Quadra 900/Quadra 950 floppy support (EXPERIMENTAL)' CONFIG_BLK_DEV_SWIM_IOP + fi fi tristate 'Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE comment 'Please see Documentation/ide.txt for help/info on IDE drives' if [ "$CONFIG_BLK_DEV_IDE" = "n" ]; then - bool 'Old hard disk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY + bool 'Old hard disk (MFM/RLL/IDE) driver' CONFIG_BLK_DEV_HD_ONLY else - bool ' Use old disk-only driver on primary interface' CONFIG_BLK_DEV_HD_IDE - dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE - if [ "$CONFIG_BLK_DEV_IDEDISK" != "n" ]; then - bool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE - fi - dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE - if [ "$CONFIG_BLK_DEV_IDECD" = "y" ]; then - bool ' Include CD-Changer Reporting' CONFIG_IDECD_SLOTS - fi - dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE - dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE - dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE - if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then - bool ' CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640 - if [ "$CONFIG_BLK_DEV_CMD640" = "y" ]; then - bool ' CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED - fi - if [ "$CONFIG_PCI" = "y" ]; then - bool ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 - bool ' Generic PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI - if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then - bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI - if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then - bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Good-Bad DMA Model-Firmware (EXPERIMENTAL)' IDEDMA_NEW_DRIVE_LISTINGS - define_bool IDEDMA_PCI_EXPERIMENTAL y - else - define_bool IDEDMA_PCI_EXPERIMENTAL n - fi - fi - bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD - bool ' AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210 - if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_X86" = "y" ]; then - bool ' ALI M15x3 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_ALI15X3 - fi - bool ' CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646 - bool ' CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693 - fi - bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X - if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" -a \ - "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then - bool ' HPT34X DMA support (DANGEROUS)' CONFIG_BLK_DEV_HPT34X_DMA - fi - bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 - if [ "$CONFIG_X86" = "y" ]; then - bool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX - if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" -a \ - "$CONFIG_BLK_DEV_PIIX" = "y" ]; then - bool ' PIIXn Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TUNING - fi - fi - if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then - bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 - fi - if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then - bool ' PROMISE PDC20246/PDC20262 support' CONFIG_BLK_DEV_PDC202XX - if [ "$CONFIG_EXPERIMENTAL" = "y" -a \ - "$CONFIG_BLK_DEV_PDC202XX" = "y" ]; then - bool ' Special UDMA Feature (EXPERIMENTAL)' PDC202XX_FORCE_BURST_BIT - bool ' Special Mode Feature (DANGEROUS)' PDC202XX_FORCE_MASTER_MODE - fi - fi - if [ "$CONFIG_X86" = "y" ]; then - bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 - fi - if [ "$IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then - bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 - if [ "$CONFIG_X86" = "y" ]; then - bool ' VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586 - fi - fi + bool ' Use old disk-only driver on primary interface' CONFIG_BLK_DEV_HD_IDE + dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE + if [ "$CONFIG_BLK_DEV_IDEDISK" != "n" ]; then + bool ' Use multi-mode by default' CONFIG_IDEDISK_MULTI_MODE + fi + dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE + dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE + dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE + dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE + comment 'IDE chipset support/bugfixes' + if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then + bool ' CMD640 chipset bugfix/support' CONFIG_BLK_DEV_CMD640 + if [ "$CONFIG_BLK_DEV_CMD640" = "y" ]; then + bool ' CMD640 enhanced support' CONFIG_BLK_DEV_CMD640_ENHANCED fi - if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then - bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 + if [ "$CONFIG_PCI" = "y" ]; then + bool ' RZ1000 chipset bugfix/support' CONFIG_BLK_DEV_RZ1000 + bool ' Generic PCI IDE chipset support' CONFIG_BLK_DEV_IDEPCI + if [ "$CONFIG_BLK_DEV_IDEPCI" = "y" ]; then + bool ' Generic PCI bus-master DMA support' CONFIG_BLK_DEV_IDEDMA_PCI + if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then + bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' Good-Bad DMA Model-Firmware (EXPERIMENTAL)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS + define_bool CONFIG_IDEDMA_PCI_EXPERIMENTAL y + else + define_bool CONFIG_IDEDMA_PCI_EXPERIMENTAL n + fi + fi + bool ' Boot off-board chipsets first support' CONFIG_BLK_DEV_OFFBOARD + bool ' AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210 + if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_X86" = "y" ]; then + bool ' ALI M15x3 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_ALI15X3 + fi + bool ' CMD646 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CMD646 + bool ' CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693 + fi + if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then + bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X + if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a \ + "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then + bool ' HPT34X DMA support (DANGEROUS)' CONFIG_BLK_DEV_HPT34X_DMA + fi + bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 + fi + if [ "$CONFIG_X86" = "y" ]; then + bool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX + if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a \ + "$CONFIG_BLK_DEV_PIIX" = "y" ]; then + bool ' PIIXn Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TUNING + fi + fi + if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then + bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 + fi + if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then + bool ' PROMISE PDC20246/PDC20262 support' CONFIG_BLK_DEV_PDC202XX + if [ "$CONFIG_EXPERIMENTAL" = "y" -a \ + "$CONFIG_BLK_DEV_PDC202XX" = "y" ]; then + bool ' Special UDMA Feature (EXPERIMENTAL)' CONFIG_PDC202XX_FORCE_BURST_BIT + bool ' Special Mode Feature (DANGEROUS)' CONFIG_PDC202XX_FORCE_MASTER_MODE + fi + fi + if [ "$CONFIG_X86" = "y" ]; then + bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 + fi + if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then + bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 + if [ "$CONFIG_X86" = "y" ]; then + bool ' VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586 + fi + fi + fi + if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then + bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105 + fi fi - fi - if [ "$CONFIG_PMAC" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then - bool ' Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC - if [ "$CONFIG_BLK_DEV_IDE_PMAC" != "n" ]; then - bool ' PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC - if [ "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" ]; then - bool ' Use DMA by default' CONFIG_IDEDMA_PMAC_AUTO - fi - fi - fi - if [ "$CONFIG_ARCH_ACORN" = "y" ]; then - bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE - if [ "$CONFIG_BLK_DEV_IDE_ICSIDE" = "y" ]; then - bool ' ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS - if [ "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then - bool ' Use ICS DMA by default' CONFIG_IDEDMA_ICS_AUTO - fi - fi - bool ' RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE - fi - if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" -o \ - "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" -o \ - "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then - define_bool CONFIG_BLK_DEV_IDEDMA y - if [ "$CONFIG_IDEDMA_PCI_AUTO" = "y" -o \ - "$CONFIG_IDEDMA_PMAC_AUTO" = "y" -o \ - "$CONFIG_IDEDMA_ICS_AUTO" = "y" ]; then - define_bool CONFIG_IDEDMA_AUTO y + if [ "$CONFIG_PMAC" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then + bool ' Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC + if [ "$CONFIG_BLK_DEV_IDE_PMAC" != "n" ]; then + bool ' PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC + if [ "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" ]; then + bool ' Use DMA by default' CONFIG_IDEDMA_PMAC_AUTO + fi + fi fi - fi - bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS - if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then - comment 'Note: most of these also require special kernel boot parameters' - bool ' Generic 4 drives/port support' CONFIG_BLK_DEV_4DRIVES - bool ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX - bool ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278 - bool ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B - if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a \ - "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 + if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE + if [ "$CONFIG_BLK_DEV_IDE_ICSIDE" = "y" ]; then + bool ' ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS + if [ "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then + bool ' Use ICS DMA by default' CONFIG_IDEDMA_ICS_AUTO + fi + fi + bool ' RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE fi - bool ' QDI QD6580 support' CONFIG_BLK_DEV_QD6580 - bool ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672 - fi - if [ "$CONFIG_AMIGA" = "y" ]; then - bool ' Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Amiga IDE Doubler support' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE + if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" -o \ + "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" -o \ + "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then + define_bool CONFIG_BLK_DEV_IDEDMA y + if [ "$CONFIG_IDEDMA_PCI_AUTO" = "y" -o \ + "$CONFIG_IDEDMA_PMAC_AUTO" = "y" -o \ + "$CONFIG_IDEDMA_ICS_AUTO" = "y" ]; then + define_bool CONFIG_IDEDMA_AUTO y + fi fi - fi - if [ "$CONFIG_ZORRO" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool ' Buddha/Catweasel IDE interface support' CONFIG_BLK_DEV_BUDDHA - fi - if [ "$CONFIG_ATARI" = "y" ]; then - bool ' Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE - fi - if [ "$CONFIG_MAC" = "y" ]; then - bool ' Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE - fi - fi + bool ' Other IDE chipset support' CONFIG_IDE_CHIPSETS + if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then + comment 'Note: most of these also require special kernel boot parameters' + bool ' Generic 4 drives/port support' CONFIG_BLK_DEV_4DRIVES + bool ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX + bool ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278 + bool ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B + if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a \ + "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030 + fi + bool ' QDI QD6580 support' CONFIG_BLK_DEV_QD6580 + bool ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672 + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + bool ' Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Amiga IDE Doubler support (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE + fi + fi + if [ "$CONFIG_ZORRO" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' Buddha/Catweasel IDE interface support (EXPERIMENTAL)' CONFIG_BLK_DEV_BUDDHA + fi + if [ "$CONFIG_ATARI" = "y" ]; then + bool ' Falcon IDE interface support' CONFIG_BLK_DEV_FALCON_IDE + fi + if [ "$CONFIG_MAC" = "y" ]; then + bool ' Macintosh Quadra/Powerbook IDE interface support' CONFIG_BLK_DEV_MAC_IDE + fi + fi fi if [ "$CONFIG_MCA" = "y" ]; then - tristate 'PS/2 ESDI hard disk support' CONFIG_BLK_DEV_PS2 + tristate 'PS/2 ESDI hard disk support' CONFIG_BLK_DEV_PS2 fi if [ "$CONFIG_ZORRO" = "y" ]; then - tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM + tristate 'Amiga Zorro II ramdisk support' CONFIG_AMIGA_Z2RAM fi if [ "$CONFIG_ATARI" = "y" ]; then - tristate 'Atari ACSI support' CONFIG_ATARI_ACSI - if [ "$CONFIG_ATARI_ACSI" != "n" ]; then - comment 'Some devices (e.g. CD jukebox) support multiple LUNs' - bool 'Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN - dep_tristate 'Atari SLM laser printer support' CONFIG_ATARI_SLM $CONFIG_ATARI_ACSI - fi -fi -tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA + tristate 'Atari ACSI support' CONFIG_ATARI_ACSI + if [ "$CONFIG_ATARI_ACSI" != "n" ]; then + comment 'Some devices (e.g. CD jukebox) support multiple LUNs' + bool ' Probe all LUNs on each ACSI device' CONFIG_ACSI_MULTI_LUN + tristate ' Atari SLM laser printer support' CONFIG_ATARI_SLM + fi +fi +if [ "$CONFIG_PCI" = "y" ]; then + tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA +fi comment 'Additional Block Devices' tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP if [ "$CONFIG_NET" = "y" ]; then - tristate 'Network block device support' CONFIG_BLK_DEV_NBD + tristate 'Network block device support' CONFIG_BLK_DEV_NBD fi bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then - tristate ' Linear (append) mode' CONFIG_MD_LINEAR - tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED - tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING - tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 + tristate ' Linear (append) mode' CONFIG_MD_LINEAR + tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED + tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING + tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 fi if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then - bool ' Boot support (linear, striped)' CONFIG_MD_BOOT + bool ' Boot support (linear, striped)' CONFIG_MD_BOOT fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then - bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD + bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD fi tristate 'XT hard disk support' CONFIG_BLK_DEV_XD @@ -205,14 +207,14 @@ tristate 'XT hard disk support' CONFIG_BLK_DEV_XD # PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option # controls the choices given to the user ... -if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ] ; then +if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ]; then define_bool CONFIG_PARIDE_PARPORT y else define_bool CONFIG_PARIDE_PARPORT m fi dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then - source drivers/block/paride/Config.in + source drivers/block/paride/Config.in fi if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ @@ -226,15 +228,15 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_PIIX" = "y" -o \ "$CONFIG_BLK_DEV_SIS5513" = "y" -o \ "$CONFIG_BLK_DEV_SL82C105" = "y" ]; then - define_bool CONFIG_BLK_DEV_IDE_MODES y + define_bool CONFIG_BLK_DEV_IDE_MODES y else - define_bool CONFIG_BLK_DEV_IDE_MODES n + define_bool CONFIG_BLK_DEV_IDE_MODES n fi if [ "$CONFIG_BLK_DEV_HD_IDE" = "y" -o "$CONFIG_BLK_DEV_HD_ONLY" = "y" ]; then - define_bool CONFIG_BLK_DEV_HD y + define_bool CONFIG_BLK_DEV_HD y else - define_bool CONFIG_BLK_DEV_HD n + define_bool CONFIG_BLK_DEV_HD n fi endmenu diff --git a/drivers/block/Makefile b/drivers/block/Makefile index abc2242dc100..8519318d93f0 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -20,7 +20,7 @@ ALL_SUB_DIRS := $(SUB_DIRS) paride L_TARGET := block.a -L_OBJS := genhd.o cmos-probe.o +L_OBJS := genhd.o ide-geometry.o M_OBJS := MOD_LIST_NAME := BLOCK_MODULES LX_OBJS := ll_rw_blk.o blkpg.o @@ -248,7 +248,7 @@ ifeq ($(CONFIG_BLK_DEV_IDE),y) else ifeq ($(CONFIG_BLK_DEV_IDE),m) MIX_OBJS += ide.o $(IDE_OBJS) - M_OBJS += ide-mod.o ide-probe.o + M_OBJS += ide-mod.o ide-probe-mod.o endif endif @@ -376,3 +376,7 @@ include $(TOPDIR)/Rules.make ide-mod.o: ide.o $(IDE_OBJS) $(LD) $(LD_RFLAG) -r -o $@ ide.o $(IDE_OBJS) + +ide-probe-mod.o: ide-probe.o ide-geometry.o + $(LD) $(LD_RFLAG) -r -o $@ ide-probe.o ide-geometry.o + diff --git a/drivers/block/cmos-probe.c b/drivers/block/cmos-probe.c deleted file mode 100644 index f0147d5e3cbd..000000000000 --- a/drivers/block/cmos-probe.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * linux/drivers/block/cmos-probe.c Version 1.00 August 16, 1999 - * - * Copyright (C) 1994-1999 Linus Torvalds & authors (see below) - */ - -#undef REALLY_SLOW_IO /* most systems can safely undef this */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include - -/* - * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc - * controller that is BIOS compatible with ST-506, and thus showing up in our - * BIOS table, but not register compatible, and therefore not present in CMOS. - * - * Furthermore, we will assume that our ST-506 drives are the primary - * drives in the system -- the ones reflected as drive 1 or 2. The first - * drive is stored in the high nibble of CMOS byte 0x12, the second in the low - * nibble. This will be either a 4 bit drive type or 0xf indicating use byte - * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. A non-zero value - * means we have an AT controller hard disk for that drive. - * - * Of course, there is no guarantee that either drive is actually on the - * "primary" IDE interface, but we don't bother trying to sort that out here. - * If a drive is not actually on the primary interface, then these parameters - * will be ignored. This results in the user having to supply the logical - * drive geometry as a boot parameter for each drive not on the primary i/f. - * - * The only "perfect" way to handle this would be to modify the setup.[cS] code - * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info - * for us during initialization. I have the necessary docs -- any takers? -ml - */ -void probe_cmos_for_drives (ide_hwif_t *hwif) -{ -#ifdef __i386__ - extern struct drive_info_struct drive_info; - byte cmos_disks, *BIOS = (byte *) &drive_info; - int unit; - -#ifdef CONFIG_BLK_DEV_PDC4030 - if (hwif->chipset == ide_pdc4030 && hwif->channel != 0) - return; -#endif /* CONFIG_BLK_DEV_PDC4030 */ - outb_p(0x12,0x70); /* specify CMOS address 0x12 */ - cmos_disks = inb_p(0x71); /* read the data from 0x12 */ - /* Extract drive geometry from CMOS+BIOS if not already setup */ - for (unit = 0; unit < MAX_DRIVES; ++unit) { - ide_drive_t *drive = &hwif->drives[unit]; - if ((cmos_disks & (0xf0 >> (unit*4))) && !drive->present && !drive->nobios) { - drive->cyl = drive->bios_cyl = *(unsigned short *)BIOS; - drive->head = drive->bios_head = *(BIOS+2); - drive->sect = drive->bios_sect = *(BIOS+14); - drive->ctl = *(BIOS+8); - drive->present = 1; - } - BIOS += 16; - } -#endif -} diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 1b2be20dd648..579fbc13ae17 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -212,6 +212,7 @@ struct file_operations ida_fops = { */ static void ida_procinit(int i) { +#ifdef CONFIG_PROC_FS struct proc_dir_entry *pd; if (proc_array == NULL) { @@ -224,6 +225,7 @@ static void ida_procinit(int i) if (!pd) return; pd->read_proc = ida_proc_get_info; pd->data = hba[i]; +#endif } /* @@ -356,7 +358,9 @@ void cleanup_module(void) } } } +#ifdef CONFIG_PROC_FS remove_proc_entry("array", &proc_root); +#endif kfree(ida); kfree(ida_sizes); kfree(ida_hardsizes); diff --git a/drivers/block/ide-disk.c b/drivers/block/ide-disk.c index 2ea7d5b51d00..d2941a1ab7a8 100644 --- a/drivers/block/ide-disk.c +++ b/drivers/block/ide-disk.c @@ -94,42 +94,40 @@ static inline void idedisk_output_data (ide_drive_t *drive, void *buffer, unsign * * Returns: 1 if lba_capacity looks sensible * 0 otherwise + * + * It is called only once for each drive. */ static int lba_capacity_is_ok (struct hd_driveid *id) { - unsigned long lba_sects = id->lba_capacity; - unsigned long chs_sects = id->cyls * id->heads * id->sectors; - unsigned long _10_percent = chs_sects / 10; + unsigned long lba_sects, chs_sects, head, tail; /* - * very large drives (8GB+) may lie about the number of cylinders - * This is a split test for drives 8 Gig and Bigger only. + * The ATA spec tells large drives to return + * C/H/S = 16383/16/63 independent of their size. + * Some drives can be jumpered to use 15 heads instead of 16. */ - if ((id->lba_capacity >= 16514064) && (id->cyls == 0x3fff) && - (id->heads == 16) && (id->sectors == 63)) { - id->cyls = lba_sects / (16 * 63); /* correct cyls */ - return 1; /* lba_capacity is our only option */ - } - /* - * ... and at least one TLA VBC has POS instead of brain and can't - * tell 16 from 15. - */ - if ((id->lba_capacity >= 15481935) && (id->cyls == 0x3fff) && - (id->heads == 15) && (id->sectors == 63)) { - id->cyls = lba_sects / (15 * 63); /* correct cyls */ - return 1; /* lba_capacity is our only option */ - } - /* perform a rough sanity check on lba_sects: within 10% is "okay" */ - if ((lba_sects - chs_sects) < _10_percent) { - return 1; /* lba_capacity is good */ - } + if (id->cyls == 16383 && id->sectors == 63 && + (id->heads == 15 || id->heads == 16) && + id->lba_capacity >= 16383*63*id->heads) + return 1; + + lba_sects = id->lba_capacity; + chs_sects = id->cyls * id->heads * id->sectors; + + /* perform a rough sanity check on lba_sects: within 10% is OK */ + if ((lba_sects - chs_sects) < chs_sects/10) + return 1; + /* some drives have the word order reversed */ - lba_sects = (lba_sects << 16) | (lba_sects >> 16); - if ((lba_sects - chs_sects) < _10_percent) { - id->lba_capacity = lba_sects; /* fix it */ + head = ((lba_sects >> 16) & 0xffff); + tail = (lba_sects & 0xffff); + lba_sects = (head | (tail << 16)); + if ((lba_sects - chs_sects) < chs_sects/10) { + id->lba_capacity = lba_sects; return 1; /* lba_capacity is (now) good */ } - return 0; /* lba_capacity value is bad */ + + return 0; /* lba_capacity value may be bad */ } /* @@ -450,24 +448,28 @@ static int idedisk_media_change (ide_drive_t *drive) } /* - * current_capacity() returns the capacity (in sectors) of a drive - * according to its current geometry/LBA settings. + * Compute drive->capacity, the full capacity of the drive + * Called with drive->id != NULL. */ -static unsigned long idedisk_capacity (ide_drive_t *drive) +static void init_idedisk_capacity (ide_drive_t *drive) { struct hd_driveid *id = drive->id; unsigned long capacity = drive->cyl * drive->head * drive->sect; drive->select.b.lba = 0; + /* Determine capacity, and use LBA if the drive properly supports it */ - if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) { - if (id->lba_capacity >= capacity) { - drive->cyl = id->lba_capacity / (drive->head * drive->sect); - capacity = id->lba_capacity; - drive->select.b.lba = 1; - } + if ((id->capability & 2) && lba_capacity_is_ok(id)) { + capacity = id->lba_capacity; + drive->cyl = capacity / (drive->head * drive->sect); + drive->select.b.lba = 1; } - return (capacity - drive->sect0); + drive->capacity = capacity; +} + +static unsigned long idedisk_capacity (ide_drive_t *drive) +{ + return (drive->capacity - drive->sect0); } static void idedisk_special (ide_drive_t *drive) @@ -628,7 +630,7 @@ static void idedisk_add_settings(ide_drive_t *drive) int major = HWIF(drive)->major; int minor = drive->select.b.unit << PARTN_BITS; - ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_SHORT, 0, 65535, 1, 1, &drive->bios_cyl, NULL); + ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 65535, 1, 1, &drive->bios_cyl, NULL); ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); ide_add_setting(drive, "bswap", SETTING_READ, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->bswap, NULL); @@ -679,7 +681,7 @@ static int idedisk_cleanup (ide_drive_t *drive) static void idedisk_setup (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - unsigned long capacity, check; + unsigned long capacity; idedisk_add_settings(drive); @@ -705,66 +707,33 @@ static void idedisk_setup (ide_drive_t *drive) drive->head = drive->bios_head = id->heads; drive->sect = drive->bios_sect = id->sectors; } + /* Handle logical geometry translation by the drive */ if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) { - /* - * Extract the physical drive geometry for our use. - * Note that we purposely do *not* update the bios info. - * This way, programs that use it (like fdisk) will - * still have the same logical view as the BIOS does, - * which keeps the partition table from being screwed. - * - * An exception to this is the cylinder count, - * which we reexamine later on to correct for 1024 limitations. - */ drive->cyl = id->cur_cyls; drive->head = id->cur_heads; drive->sect = id->cur_sectors; - - /* check for word-swapped "capacity" field in id information */ - capacity = drive->cyl * drive->head * drive->sect; - check = (id->cur_capacity0 << 16) | id->cur_capacity1; - if (check == capacity) { /* was it swapped? */ - /* yes, bring it into little-endian order: */ - id->cur_capacity0 = (capacity >> 0) & 0xffff; - id->cur_capacity1 = (capacity >> 16) & 0xffff; - } } + /* Use physical geometry if what we have still makes no sense */ - if ((!drive->head || drive->head > 16) && - id->heads && id->heads <= 16) { - if ((id->lba_capacity > 16514064) || (id->cyls == 0x3fff)) { - id->cyls = ((int)(id->lba_capacity/(id->heads * id->sectors))); - } - drive->cyl = id->cur_cyls = id->cyls; - drive->head = id->cur_heads = id->heads; - drive->sect = id->cur_sectors = id->sectors; + if (drive->head > 16 && id->heads && id->heads <= 16) { + drive->cyl = id->cyls; + drive->head = id->heads; + drive->sect = id->sectors; } /* calculate drive capacity, and select LBA if possible */ - capacity = idedisk_capacity (drive); + init_idedisk_capacity (drive); /* * if possible, give fdisk access to more of the drive, * by correcting bios_cyls: */ + capacity = idedisk_capacity (drive); if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) && - (!drive->forced_geom) && drive->bios_sect && drive->bios_head) { + (!drive->forced_geom) && drive->bios_sect && drive->bios_head) drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head; -#ifdef DEBUG - printk("Fixing Geometry :: CHS=%d/%d/%d to CHS=%d/%d/%d\n", - drive->id->cur_cyls, - drive->id->cur_heads, - drive->id->cur_sectors, - drive->bios_cyl, - drive->bios_head, - drive->bios_sect); -#endif - drive->id->cur_cyls = drive->bios_cyl; - drive->id->cur_heads = drive->bios_head; - drive->id->cur_sectors = drive->bios_sect; - } #if 0 /* done instead for entire identify block in arch/ide.h stuff */ /* fix byte-ordering of buffer size field */ @@ -791,19 +760,6 @@ static void idedisk_setup (ide_drive_t *drive) } printk("\n"); - if (drive->select.b.lba) { - if (*(int *)&id->cur_capacity0 < id->lba_capacity) { -#ifdef DEBUG - printk(" CurSects=%d, LBASects=%d, ", - *(int *)&id->cur_capacity0, id->lba_capacity); -#endif - *(int *)&id->cur_capacity0 = id->lba_capacity; -#ifdef DEBUG - printk( "Fixed CurSects=%d\n", *(int *)&id->cur_capacity0); -#endif - } - } - drive->mult_count = 0; if (id->max_multsect) { #ifdef CONFIG_IDEDISK_MULTI_MODE diff --git a/drivers/block/ide-dma.c b/drivers/block/ide-dma.c index cd631c621728..d3c657516770 100644 --- a/drivers/block/ide-dma.c +++ b/drivers/block/ide-dma.c @@ -91,7 +91,7 @@ #include #include -#ifdef IDEDMA_NEW_DRIVE_LISTINGS +#ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS struct drive_list_entry { char * id_model; @@ -130,7 +130,7 @@ int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table) return 0; } -#else /* !IDEDMA_NEW_DRIVE_LISTINGS */ +#else /* !CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ /* * good_dma_drives() lists the model names (from "hdparm -i") @@ -162,7 +162,7 @@ const char *bad_dma_drives[] = {"WDC AC11000H", "WDC AC31600H", NULL}; -#endif /* IDEDMA_NEW_DRIVE_LISTINGS */ +#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ /* * Our Physical Region Descriptor (PRD) table should be large enough @@ -314,7 +314,7 @@ int check_drive_lists (ide_drive_t *drive, int good_bad) { struct hd_driveid *id = drive->id; -#ifdef IDEDMA_NEW_DRIVE_LISTINGS +#ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS if (good_bad) { return in_drive_list(id, drive_whitelist); } else { @@ -323,7 +323,7 @@ int check_drive_lists (ide_drive_t *drive, int good_bad) printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model); return(blacklist); } -#else /* !IDEDMA_NEW_DRIVE_LISTINGS */ +#else /* !CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ const char **list; if (good_bad) { @@ -344,7 +344,7 @@ int check_drive_lists (ide_drive_t *drive, int good_bad) } } } -#endif /* IDEDMA_NEW_DRIVE_LISTINGS */ +#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ return 0; } diff --git a/drivers/block/ide-floppy.c b/drivers/block/ide-floppy.c index 66b71b3a23d0..f1c8baef8bc4 100644 --- a/drivers/block/ide-floppy.c +++ b/drivers/block/ide-floppy.c @@ -1498,7 +1498,7 @@ static void idefloppy_add_settings(ide_drive_t *drive) int major = HWIF(drive)->major; int minor = drive->select.b.unit << PARTN_BITS; - ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_SHORT, 0, 1023, 1, 1, &drive->bios_cyl, NULL); + ide_add_setting(drive, "bios_cyl", SETTING_RW, -1, -1, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL); ide_add_setting(drive, "bios_head", SETTING_RW, -1, -1, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); ide_add_setting(drive, "bios_sect", SETTING_RW, -1, -1, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); ide_add_setting(drive, "breada_readahead", SETTING_RW, BLKRAGET, BLKRASET, TYPE_INT, 0, 255, 1, 2, &read_ahead[major], NULL); diff --git a/drivers/block/ide-geometry.c b/drivers/block/ide-geometry.c new file mode 100644 index 000000000000..974fb24f1962 --- /dev/null +++ b/drivers/block/ide-geometry.c @@ -0,0 +1,225 @@ +/* + * linux/drivers/block/ide-geometry.c + */ +#include + +#include + +/* + * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc + * controller that is BIOS compatible with ST-506, and thus showing up in our + * BIOS table, but not register compatible, and therefore not present in CMOS. + * + * Furthermore, we will assume that our ST-506 drives are the primary + * drives in the system -- the ones reflected as drive 1 or 2. The first + * drive is stored in the high nibble of CMOS byte 0x12, the second in the low + * nibble. This will be either a 4 bit drive type or 0xf indicating use byte + * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. A non-zero value + * means we have an AT controller hard disk for that drive. + * + * Of course, there is no guarantee that either drive is actually on the + * "primary" IDE interface, but we don't bother trying to sort that out here. + * If a drive is not actually on the primary interface, then these parameters + * will be ignored. This results in the user having to supply the logical + * drive geometry as a boot parameter for each drive not on the primary i/f. + */ +/* + * The only "perfect" way to handle this would be to modify the setup.[cS] code + * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info + * for us during initialization. I have the necessary docs -- any takers? -ml + */ +/* + * I did this, but it doesnt work - there is no reasonable way to find the + * correspondence between the BIOS numbering of the disks and the Linux + * numbering. -aeb + * + * The code below is bad. One of the problems is that drives 1 and 2 + * may be SCSI disks (even when IDE disks are present), so that + * the geometry we read here from BIOS is attributed to the wrong disks. + * Consequently, also the "drive->present = 1" below is a mistake. + * + * Eventually the entire routine below should be removed. + */ +void probe_cmos_for_drives (ide_hwif_t *hwif) +{ +#ifdef __i386__ + extern struct drive_info_struct drive_info; + byte cmos_disks, *BIOS = (byte *) &drive_info; + int unit; + +#ifdef CONFIG_BLK_DEV_PDC4030 + if (hwif->chipset == ide_pdc4030 && hwif->channel != 0) + return; +#endif /* CONFIG_BLK_DEV_PDC4030 */ + outb_p(0x12,0x70); /* specify CMOS address 0x12 */ + cmos_disks = inb_p(0x71); /* read the data from 0x12 */ + /* Extract drive geometry from CMOS+BIOS if not already setup */ + for (unit = 0; unit < MAX_DRIVES; ++unit) { + ide_drive_t *drive = &hwif->drives[unit]; + if ((cmos_disks & (0xf0 >> (unit*4))) && + !drive->present && !drive->nobios) { + drive->cyl = drive->bios_cyl = *(unsigned short *)BIOS; + drive->head = drive->bios_head = *(BIOS+2); + drive->sect = drive->bios_sect = *(BIOS+14); + drive->ctl = *(BIOS+8); +#if 0 + drive->present = 1; +#endif + } + BIOS += 16; + } +#endif +} + + +/* + * If heads is nonzero: find a translation with this many heads and S=63. + * Otherwise: find out how OnTrack Disk Manager would translate the disk. + */ +static void +ontrack(ide_drive_t *drive, int heads, int *c, int *h, int *s) { + struct hd_driveid *id = drive->id; + static const byte dm_head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; + const byte *headp = dm_head_vals; + unsigned long total, tracks; + + /* + * The specs say: take geometry as obtained from Identify, + * compute total capacity C*H*S from that, and truncate to + * 1024*255*63. Now take S=63, H the first in the sequence + * 4, 8, 16, 32, 64, 128, 255 such that 63*H*1024 >= total. + */ + if (id) + total = id->cyls * id->heads * id->sectors; + else + total = drive->cyl * drive->head * drive->sect; + + *s = 63; + + if (heads) { + *h = heads; + *c = total / (63 * heads); + return; + } + +#if 0 + while (63 * headp[0] * 1024 < total && headp[1] != 0) + headp++; + *h = headp[0]; + *c = total / (63 * headp[0]); +#else + /* The code below differs in two aspects: + (i) It will not produce geometries like C/H/S = 1024/64/63 + because of the `>='. This follows OnTracks text (which + claims that 512 <= C <= 1023), but not OnTracks code. + (ii) It starts dividing by 63, so that a rounding down occurs. + For example, with C=11159, H=10, S=37 we find total=4128830 + and DM would make C=512, H=128, S=63, but we make 1024/64/63 + if `>=' is replaced by `>'. + The reason we use this code is mainly that we have done so for + a long time without getting complaints. + */ + + tracks = total / 63; + while (*c >= 1024) { + *h = *headp; + *c = tracks / *h; + if (*++headp == 0) + break; + } +#endif +} + +/* + * This routine is called from the partition-table code in pt/msdos.c. + * It has two tasks: + * (i) to handle Ontrack DiskManager by offsetting everything by 63 sectors, + * or to handle EZdrive by remapping sector 0 to sector 1. + * (ii) to invent a translated geometry. + * Part (i) is suppressed if the user specifies the "noremap" option + * on the command line. + * Part (ii) is suppressed if the user specifies an explicit geometry. + * + * The ptheads parameter is either 0 or tells about the number of + * heads shown by the end of the first nonempty partition. + * If this is either 16, 32, 64, 128, 240 or 255 we'll believe it. + * + * The xparm parameter has the following meaning: + * 0 = convert to CHS with fewer than 1024 cyls + * using the same method as Ontrack DiskManager. + * 1 = same as "0", plus offset everything by 63 sectors. + * -1 = similar to "0", plus redirect sector 0 to sector 1. + * 2 = convert to a CHS geometry with "ptheads" heads. + * + * Returns 0 if the translation was not possible, if the device was not + * an IDE disk drive, or if a geometry was "forced" on the commandline. + * Returns 1 if the geometry translation was successful. + */ +int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg) +{ + ide_drive_t *drive; + const char *msg1 = ""; + int heads = 0; + int c, h, s; + int transl = 1; /* try translation */ + int ret = 0; + + drive = get_info_ptr(i_rdev); + if (!drive) + return 0; + + /* remap? */ + if (drive->remap_0_to_1 != 2) { + if (xparm == 1) { /* DM */ + drive->sect0 = 63; + msg1 = " [remap +63]"; + ret = 1; + } else if (xparm == -1) { /* EZ-Drive */ + if (drive->remap_0_to_1 == 0) { + drive->remap_0_to_1 = 1; + msg1 = " [remap 0->1]"; + ret = 1; + } + } + } + + /* There used to be code here that assigned drive->id->CHS + to drive->CHS and that to drive->bios_CHS. However, + some disks have id->C/H/S = 4092/16/63 but are larger than 2.1 GB. + In such cases that code was wrong. Moreover, + there seems to be no reason to do any of these things. */ + + /* translate? */ + if (drive->forced_geom) + transl = 0; + + /* does ptheads look reasonable? */ + if (ptheads == 32 || ptheads == 64 || ptheads == 128 || + ptheads == 240 || ptheads == 255) + heads = ptheads; + + if (xparm == 2) { + if (!heads || + (drive->bios_head >= heads && drive->bios_sect == 63)) + transl = 0; + } + if (xparm == -1) { + if (drive->bios_head > 16) + transl = 0; /* we already have a translation */ + } + + if (transl) { + ontrack(drive, heads, &c, &h, &s); + drive->bios_cyl = c; + drive->bios_head = h; + drive->bios_sect = s; + ret = 1; + } + + drive->part[0].nr_sects = current_capacity(drive); + + if (ret) + printk("%s%s [%d/%d/%d]", msg, msg1, + drive->bios_cyl, drive->bios_head, drive->bios_sect); + return ret; +} diff --git a/drivers/block/ide-pmac.c b/drivers/block/ide-pmac.c index 90fbf9cbc9ca..1ad5b3b969ac 100644 --- a/drivers/block/ide-pmac.c +++ b/drivers/block/ide-pmac.c @@ -30,8 +30,9 @@ #include #include #ifdef CONFIG_PMAC_PBOOK -#include -#include +#include +#include +#include #endif #include "ide_modes.h" @@ -50,9 +51,9 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr); #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ #ifdef CONFIG_PMAC_PBOOK -static int idepmac_notify(struct notifier_block *, unsigned long, void *); -struct notifier_block idepmac_sleep_notifier = { - idepmac_notify +static int idepmac_notify(struct pmu_sleep_notifier *self, int when); +struct pmu_sleep_notifier idepmac_sleep_notifier = { + idepmac_notify, SLEEP_LEVEL_BLOCK, }; #endif /* CONFIG_PMAC_PBOOK */ @@ -224,7 +225,7 @@ void __init pmac_ide_probe(void) pmac_ide_count = i; #ifdef CONFIG_PMAC_PBOOK - notifier_chain_register(&sleep_notifier_list, &idepmac_sleep_notifier); + pmu_register_sleep_notifier(&idepmac_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ } @@ -384,29 +385,107 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ #ifdef CONFIG_PMAC_PBOOK -static int idepmac_notify(struct notifier_block *this, - unsigned long code, void *p) +static void idepmac_sleep_disk(int i, unsigned long base) { - int i, timeout; + int j; + + /* Reset to PIO 0 */ + out_le32((unsigned *)(base + 0x200 + _IO_BASE), 0x2f8526); + + /* FIXME: We only handle the master IDE */ + if (ide_hwifs[i].drives[0].media == ide_disk) { + /* Spin down the drive */ + outb(0xa0, base+0x60); + outb(0x0, base+0x30); + outb(0x0, base+0x20); + outb(0x0, base+0x40); + outb(0x0, base+0x50); + outb(0xe0, base+0x70); + outb(0x2, base+0x160); + for (j = 0; j < 10; j++) { + int status; + mdelay(100); + status = inb(base+0x70); + if (!(status & BUSY_STAT) && (status & DRQ_STAT)) + break; + } + } +} + +static void idepmac_wake_disk(int i, unsigned long base) +{ + int j; + + /* Revive IDE disk and controller */ + feature_set(pmac_ide_node[i], FEATURE_IDE_enable); + mdelay(1); + feature_set(pmac_ide_node[i], FEATURE_IDE_DiskPower); + mdelay(100); + feature_set(pmac_ide_node[i], FEATURE_IDE_Reset); + mdelay(1); + /* Make sure we are still PIO0 */ + out_le32((unsigned *)(base + 0x200 + _IO_BASE), 0x2f8526); + mdelay(100); + + /* Wait up to 10 seconds (enough for recent drives) */ + for (j = 0; j < 100; j++) { + int status; + mdelay(100); + status = inb(base + 0x70); + if (!(status & BUSY_STAT)) + break; + } +} - switch (code) { - case PBOOK_SLEEP: - /* do anything here?? */ +/* Here we handle media bay devices */ +static void +idepmac_wake_bay(int i, unsigned long base) +{ + int timeout; + + timeout = 5000; + while ((inb(base + 0x70) & BUSY_STAT) && timeout) { + mdelay(1); + --timeout; + } +} + +static int idepmac_notify(struct pmu_sleep_notifier *self, int when) +{ + int i, ret; + unsigned long base; + + switch (when) { + case PBOOK_SLEEP_REQUEST: + break; + case PBOOK_SLEEP_REJECT: + break; + case PBOOK_SLEEP_NOW: + for (i = 0; i < pmac_ide_count; ++i) { + if ((base = pmac_ide_regbase[i]) == 0) + continue; + /* Disable irq during sleep */ + disable_irq(pmac_ide_irq[i]); + ret = check_media_bay_by_base(base, MB_CD); + if (ret == -ENODEV) + /* not media bay - put the disk to sleep */ + idepmac_sleep_disk(i, base); + } break; case PBOOK_WAKE: - /* wait for the controller(s) to become ready */ - timeout = 5000; for (i = 0; i < pmac_ide_count; ++i) { - unsigned long base = pmac_ide_regbase[i]; - if (check_media_bay_by_base(base, MB_CD) == -EINVAL) + if ((base = pmac_ide_regbase[i]) == 0) continue; - while ((inb(base + 0x70) & BUSY_STAT) && timeout) { - mdelay(1); - --timeout; - } + /* We don't handle media bay devices this way */ + ret = check_media_bay_by_base(base, MB_CD); + if (ret == -ENODEV) + idepmac_wake_disk(i, base); + else if (ret == 0) + idepmac_wake_bay(i, base); + enable_irq(pmac_ide_irq[i]); } break; } - return NOTIFY_DONE; + return PBOOK_SLEEP_OK; } #endif /* CONFIG_PMAC_PBOOK */ diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 74b3f71c6173..d2cb4b34b4e1 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -526,7 +526,7 @@ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int t * current_capacity() returns the capacity (in sectors) of a drive * according to its current geometry/LBA settings. */ -static unsigned long current_capacity (ide_drive_t *drive) +unsigned long current_capacity (ide_drive_t *drive) { if (!drive->present) return 0; @@ -1067,13 +1067,16 @@ static inline void start_request (ide_drive_t *drive) goto kill_rq; } block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0; -#if FAKE_FDISK_FOR_EZDRIVE - if (block == 0 && drive->remap_0_to_1) + + /* Yecch - this will shift the entire interval, + possibly killing some innocent following sector */ + if (block == 0 && drive->remap_0_to_1 == 1) block = 1; /* redirect MBR access to EZ-Drive partn table */ -#endif /* FAKE_FDISK_FOR_EZDRIVE */ + #if (DISK_RECOVERY_TIME > 0) while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME); #endif + SELECT_DRIVE(hwif, drive); if (ide_wait_stat(drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) { printk("%s: drive not ready for command\n", drive->name); @@ -1513,7 +1516,7 @@ void ide_intr (int irq, void *dev_id, struct pt_regs *regs) * get_info_ptr() returns the (ide_drive_t *) for a given device number. * It returns NULL if the given device number does not match any present drives. */ -static ide_drive_t *get_info_ptr (kdev_t i_rdev) +ide_drive_t *get_info_ptr (kdev_t i_rdev) { int major = MAJOR(i_rdev); unsigned int h; @@ -1609,11 +1612,8 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio } spin_unlock_irqrestore(&io_request_lock, flags); do_hwgroup_request(hwgroup); - save_flags(flags); /* all CPUs; overkill? */ - cli(); /* all CPUs; overkill? */ if (action == ide_wait && rq->rq_status != RQ_INACTIVE) down(&sem); /* wait for it to be serviced */ - restore_flags(flags); /* all CPUs; overkill? */ return rq->errors ? -EIO : 0; /* return -EIO if errors */ } @@ -2321,10 +2321,11 @@ static int ide_ioctl (struct inode *inode, struct file *file, case HDIO_GETGEO: { struct hd_geometry *loc = (struct hd_geometry *) arg; + unsigned short bios_cyl = drive->bios_cyl; /* truncate */ if (!loc || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL; if (put_user(drive->bios_head, (byte *) &loc->heads)) return -EFAULT; if (put_user(drive->bios_sect, (byte *) &loc->sectors)) return -EFAULT; - if (put_user(drive->bios_cyl, (unsigned short *) &loc->cylinders)) return -EFAULT; + if (put_user(bios_cyl, (unsigned short *) &loc->cylinders)) return -EFAULT; if (put_user((unsigned)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].start_sect, (unsigned long *) &loc->start)) return -EFAULT; return 0; @@ -2343,7 +2344,8 @@ static int ide_ioctl (struct inode *inode, struct file *file, return -EINVAL; if (drive->id == NULL) return -ENOMSG; - if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142)) + if (copy_to_user((char *)arg, (char *)drive->id, + (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142)) return -EFAULT; return 0; @@ -2629,6 +2631,7 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m * "hdx=nowerr" : ignore the WRERR_STAT bit on this drive * "hdx=cdrom" : drive is present, and is a cdrom drive * "hdx=cyl,head,sect" : disk drive is present, with specified geometry + * "hdx=noremap" : do not remap 0->1 even though EZD was detected * "hdx=autotune" : driver will attempt to tune interface speed * to the fastest PIO mode supported, * if possible for this drive only. @@ -2735,7 +2738,8 @@ void __init ide_setup (char *s) if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) { const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom", "serialize", "autotune", "noautotune", - "slow", "swapdata", "bswap", "flash", NULL}; + "slow", "swapdata", "bswap", "flash", + "remap", "noremap", NULL}; unit = s[2] - 'a'; hw = unit / MAX_DRIVES; unit = unit % MAX_DRIVES; @@ -2772,13 +2776,19 @@ void __init ide_setup (char *s) case -8: /* "slow" */ drive->slow = 1; goto done; - case -9: /* swapdata or bswap */ + case -9: /* "swapdata" or "bswap" */ case -10: drive->bswap = 1; goto done; - case -11: + case -11: /* "flash" */ drive->ata_flash = 1; goto done; + case -12: /* "remap" */ + drive->remap_0_to_1 = 1; + goto done; + case -13: /* "noremap" */ + drive->remap_0_to_1 = 2; + goto done; case 3: /* cyl,head,sect */ drive->media = ide_disk; drive->cyl = drive->bios_cyl = vals[0]; @@ -3022,113 +3032,6 @@ done: printk("\n"); } -/* - * This routine is called from the partition-table code in genhd.c - * to "convert" a drive to a logical geometry with fewer than 1024 cyls. - * - * The second parameter, "xparm", determines exactly how the translation - * will be handled: - * 0 = convert to CHS with fewer than 1024 cyls - * using the same method as Ontrack DiskManager. - * 1 = same as "0", plus offset everything by 63 sectors. - * -1 = similar to "0", plus redirect sector 0 to sector 1. - * >1 = convert to a CHS geometry with "xparm" heads. - * - * Returns 0 if the translation was not possible, if the device was not - * an IDE disk drive, or if a geometry was "forced" on the commandline. - * Returns 1 if the geometry translation was successful. - */ - -int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg) -{ - ide_drive_t *drive; - - static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0}; - const byte *heads = head_vals; - unsigned long tracks; - - drive = get_info_ptr(i_rdev); - if (!drive) - return 0; - - if (drive->forced_geom) { - /* - * Update the current 3D drive values. - */ - drive->id->cur_cyls = drive->bios_cyl; - drive->id->cur_heads = drive->bios_head; - drive->id->cur_sectors = drive->bios_sect; - return 0; - } - - if (xparm > 1 && xparm <= drive->bios_head && drive->bios_sect == 63) { - /* - * Update the current 3D drive values. - */ - drive->id->cur_cyls = drive->bios_cyl; - drive->id->cur_heads = drive->bios_head; - drive->id->cur_sectors = drive->bios_sect; - return 0; /* we already have a translation */ - } - - printk("%s ", msg); - - if (xparm < 0 && (drive->bios_cyl * drive->bios_head * drive->bios_sect) < (1024 * 16 * 63)) { - /* - * Update the current 3D drive values. - */ - drive->id->cur_cyls = drive->bios_cyl; - drive->id->cur_heads = drive->bios_head; - drive->id->cur_sectors = drive->bios_sect; - return 0; /* small disk: no translation needed */ - } - - if (drive->id) { - drive->cyl = drive->id->cyls; - drive->head = drive->id->heads; - drive->sect = drive->id->sectors; - } - drive->bios_cyl = drive->cyl; - drive->bios_head = drive->head; - drive->bios_sect = drive->sect; - drive->special.b.set_geometry = 1; - - tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63; - drive->bios_sect = 63; - if (xparm > 1) { - drive->bios_head = xparm; - drive->bios_cyl = tracks / drive->bios_head; - } else { - while (drive->bios_cyl >= 1024) { - drive->bios_head = *heads; - drive->bios_cyl = tracks / drive->bios_head; - if (0 == *++heads) - break; - } -#if FAKE_FDISK_FOR_EZDRIVE - if (xparm == -1) { - drive->remap_0_to_1 = 1; - printk("[remap 0->1] "); - } else -#endif /* FAKE_FDISK_FOR_EZDRIVE */ - if (xparm == 1) { - drive->sect0 = 63; - drive->bios_cyl = (tracks - 1) / drive->bios_head; - printk("[remap +63] "); - } - } - - drive->part[0].nr_sects = current_capacity(drive); - printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect); - /* - * Update the current 3D drive values. - */ - drive->id->cur_cyls = drive->bios_cyl; - drive->id->cur_heads = drive->bios_head; - drive->id->cur_sectors = drive->bios_sect; - return 1; -} - /* * probe_for_hwifs() finds/initializes "known" IDE interfaces */ @@ -3524,6 +3427,9 @@ EXPORT_SYMBOL(ide_register); EXPORT_SYMBOL(ide_unregister); EXPORT_SYMBOL(ide_setup_ports); +EXPORT_SYMBOL(get_info_ptr); +EXPORT_SYMBOL(current_capacity); + /* * This is gets invoked once during initialization, to set *everything* up */ diff --git a/drivers/block/pdc202xx.c b/drivers/block/pdc202xx.c index 5bbd0c3e77dc..aeffcc9ba939 100644 --- a/drivers/block/pdc202xx.c +++ b/drivers/block/pdc202xx.c @@ -14,7 +14,7 @@ * 8 are UDMA supported and 4 are limited to DMA mode 2 multi-word. * The 8/4 ratio is a BIOS code limit by promise. * - * UNLESS you enable "PDC202XX_FORCE_BURST_BIT" + * UNLESS you enable "CONFIG_PDC202XX_FORCE_BURST_BIT" * * There is only one BIOS in the three contollers. * @@ -521,15 +521,15 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) (primary_mode & 1) ? "MASTER" : "PCI", (secondary_mode & 1) ? "MASTER" : "PCI" ); -#ifdef PDC202XX_FORCE_BURST_BIT +#ifdef CONFIG_PDC202XX_FORCE_BURST_BIT if (!(udma_speed_flag & 1)) { printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1)); outb(udma_speed_flag|1, high_16 + 0x001f); printk("%sCTIVE\n", (inb(high_16 + 0x001f) & 1) ? "A" : "INA"); } -#endif /* PDC202XX_FORCE_BURST_BIT */ +#endif /* CONFIG_PDC202XX_FORCE_BURST_BIT */ -#ifdef PDC202XX_FORCE_MASTER_MODE +#ifdef CONFIG_PDC202XX_FORCE_MASTER_MODE if (!(primary_mode & 1)) { printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ", name, primary_mode, (primary_mode|1)); @@ -543,7 +543,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) outb(secondary_mode|1, high_16 + 0x001b); printk("%s\n", (inb(high_16 + 0x001b) & 1) ? "MASTER" : "PCI"); } -#endif /* PDC202XX_FORCE_MASTER_MODE */ +#endif /* CONFIG_PDC202XX_FORCE_MASTER_MODE */ return dev->irq; } diff --git a/drivers/char/adbmouse.c b/drivers/char/adbmouse.c index eaf1a8357a94..95c25b519047 100644 --- a/drivers/char/adbmouse.c +++ b/drivers/char/adbmouse.c @@ -35,8 +35,8 @@ #include #include #include +#include -#include #ifdef __powerpc__ #include #endif diff --git a/drivers/char/busmouse.c b/drivers/char/busmouse.c index 4620a3d60eac..42c2642f6698 100644 --- a/drivers/char/busmouse.c +++ b/drivers/char/busmouse.c @@ -144,7 +144,7 @@ busmouse_add_movementbuttons(int mousedev, int dx, int dy, int buttons) wake_up(&mse->wait); if (mse->fasyncptr) - kill_fasync(mse->fasyncptr, SIGIO); + kill_fasync(mse->fasyncptr, SIGIO, POLL_IN); } } @@ -450,13 +450,10 @@ bus_mouse_init(void) #ifdef CONFIG_ATARIMOUSE atari_mouse_init(); #endif -#ifdef CONFIG_MAC_MOUSE - mac_mouse_init(); -#endif #ifdef CONFIG_SUN_MOUSE sun_mouse_init(); #endif -#ifdef CONFIG_ADBMOUSE +#ifdef CONFIG_ADB_MOUSE adb_mouse_init(); #endif #ifdef CONFIG_RPCMOUSE diff --git a/drivers/char/console.c b/drivers/char/console.c index d0503cdcb9f2..f452237ab979 100644 --- a/drivers/char/console.c +++ b/drivers/char/console.c @@ -681,7 +681,7 @@ int vc_resize(unsigned int lines, unsigned int cols, else { unsigned short *p = (unsigned short *) kmalloc(ss, GFP_USER); if (!p) { - for (i = 0; i< currcons; i++) + for (i = first; i < currcons; i++) if (newscreens[i]) kfree_s(newscreens[i], ss); return -ENOMEM; diff --git a/drivers/char/dn_keyb.c b/drivers/char/dn_keyb.c index 97b237ca3628..38010e29b63e 100644 --- a/drivers/char/dn_keyb.c +++ b/drivers/char/dn_keyb.c @@ -469,7 +469,7 @@ static void dn_keyb_process_mouse_event(unsigned char mouse_data) { if (mouse_dy > 2048) mouse_dy = 2048; if (mouse_fasyncptr) - kill_fasync(mouse_fasyncptr, SIGIO); + kill_fasync(mouse_fasyncptr, SIGIO, POLL_IN); } mouse_byte_count=0; /* printk("mouse: %d, %d, %x\n",mouse_x,mouse_y,buttons); */ diff --git a/drivers/char/drm/fops.c b/drivers/char/drm/fops.c index 12ab4d6283d9..55deade81c98 100644 --- a/drivers/char/drm/fops.c +++ b/drivers/char/drm/fops.c @@ -197,7 +197,7 @@ int drm_write_string(drm_device_t *dev, const char *s) send -= count; } - if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO); + if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_OUT); DRM_DEBUG("waking\n"); wake_up_interruptible(&dev->buf_readers); return 0; diff --git a/drivers/char/ftape/Config.in b/drivers/char/ftape/Config.in index 2f837be5b7b4..59004dcf294e 100644 --- a/drivers/char/ftape/Config.in +++ b/drivers/char/ftape/Config.in @@ -1,17 +1,17 @@ # # Ftape configuration # -dep_tristate 'Zftape, the VFS interface' CONFIG_ZFTAPE $CONFIG_FTAPE +dep_tristate ' Zftape, the VFS interface' CONFIG_ZFTAPE $CONFIG_FTAPE if [ "$CONFIG_ZFTAPE" != "n" ]; then - int 'Default block size' CONFIG_ZFT_DFLT_BLK_SZ 10240 - comment 'The compressor will be built as a module only!' - define_bool CONFIG_ZFT_COMPRESSOR m + int ' Default block size' CONFIG_ZFT_DFLT_BLK_SZ 10240 + comment ' The compressor will be built as a module only!' + define_bool CONFIG_ZFT_COMPRESSOR m fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - int 'Number of ftape buffers (EXPERIMENTAL)' CONFIG_FT_NR_BUFFERS 3 + int ' Number of ftape buffers (EXPERIMENTAL)' CONFIG_FT_NR_BUFFERS 3 fi if [ "$CONFIG_PROC_FS" = "y" ]; then - bool 'Enable procfs status report (+2kb)' CONFIG_FT_PROC_FS y + bool ' Enable procfs status report (+2kb)' CONFIG_FT_PROC_FS fi choice 'Debugging output' \ "Normal CONFIG_FT_NORMAL_DEBUG \ @@ -25,14 +25,14 @@ choice 'Floppy tape controllers' \ FC-10/FC-20 CONFIG_FT_PROBE_FC10 \ Alt/82078 CONFIG_FT_ALT_FDC" Standard if [ "$CONFIG_FT_STD_FDC" != "y" ]; then - comment ' Consult the manuals of your tape drive for the correct settings!' - hex ' IO base of the floppy disk controller' CONFIG_FT_FDC_BASE 0 - int ' IRQ channel of the floppy disk controller' CONFIG_FT_FDC_IRQ 0 - int ' DMA channel of the floppy disk controller' CONFIG_FT_FDC_DMA 0 + comment ' Consult the manuals of your tape drive for the correct settings!' + hex ' IO base of the floppy disk controller' CONFIG_FT_FDC_BASE 0 + int ' IRQ channel of the floppy disk controller' CONFIG_FT_FDC_IRQ 0 + int ' DMA channel of the floppy disk controller' CONFIG_FT_FDC_DMA 0 fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - int 'Default FIFO threshold (EXPERIMENTAL)' CONFIG_FT_FDC_THR 8 - int 'Maximal data rate to use (EXPERIMENTAL)' CONFIG_FT_FDC_MAX_RATE 2000 + int ' Default FIFO threshold (EXPERIMENTAL)' CONFIG_FT_FDC_THR 8 + int ' Maximal data rate to use (EXPERIMENTAL)' CONFIG_FT_FDC_MAX_RATE 2000 fi comment 'ONLY for DEC Alpha architectures' -int 'CPU clock frequency of your DEC Alpha' CONFIG_FT_ALPHA_CLOCK 0 +int ' CPU clock frequency of your DEC Alpha' CONFIG_FT_ALPHA_CLOCK 0 diff --git a/drivers/char/joystick/Config.in b/drivers/char/joystick/Config.in index a41eaac33d98..810decada90f 100644 --- a/drivers/char/joystick/Config.in +++ b/drivers/char/joystick/Config.in @@ -2,18 +2,18 @@ # Joystick lowlevel driver configuration # -dep_tristate ' Classic PC analog joysticks and gamepads' CONFIG_JOY_ANALOG $CONFIG_JOYSTICK -dep_tristate ' FPGaming and MadCatz A3D controllers' CONFIG_JOY_ASSASIN $CONFIG_JOYSTICK -dep_tristate ' Gravis GrIP joysticks and gamepads' CONFIG_JOY_GRAVIS $CONFIG_JOYSTICK -dep_tristate ' Logitech Digital joysticks and gamepads' CONFIG_JOY_LOGITECH $CONFIG_JOYSTICK -dep_tristate ' Microsoft SideWinder, Genius Digital joysticks and gamepads' CONFIG_JOY_SIDEWINDER $CONFIG_JOYSTICK -dep_tristate ' ThrustMaster DirectConnect joysticks and gamepads' CONFIG_JOY_THRUSTMASTER $CONFIG_JOYSTICK -dep_tristate ' PDPI Lightning 4 gamecards' CONFIG_JOY_LIGHTNING $CONFIG_JOYSTICK +dep_tristate ' Classic PC analog joysticks and gamepads' CONFIG_JOY_ANALOG $CONFIG_JOYSTICK +dep_tristate ' FPGaming and MadCatz A3D controllers' CONFIG_JOY_ASSASIN $CONFIG_JOYSTICK +dep_tristate ' Gravis GrIP joysticks and gamepads' CONFIG_JOY_GRAVIS $CONFIG_JOYSTICK +dep_tristate ' Logitech Digital joysticks and gamepads' CONFIG_JOY_LOGITECH $CONFIG_JOYSTICK +dep_tristate ' Microsoft SideWinder, Genius Digital joysticks and gamepads' CONFIG_JOY_SIDEWINDER $CONFIG_JOYSTICK +dep_tristate ' ThrustMaster DirectConnect joysticks and gamepads' CONFIG_JOY_THRUSTMASTER $CONFIG_JOYSTICK +dep_tristate ' PDPI Lightning 4 gamecards' CONFIG_JOY_LIGHTNING $CONFIG_JOYSTICK if [ "$CONFIG_PARPORT" != "n" ]; then - dep_tristate ' NES, SNES, PSX, Multisystem joysticks and gamepads' CONFIG_JOY_CONSOLE $CONFIG_JOYSTICK $CONFIG_PARPORT - dep_tristate ' Sega, Multisystem joysticks and gamepads' CONFIG_JOY_DB9 $CONFIG_JOYSTICK $CONFIG_PARPORT - dep_tristate ' TurboGraFX Multisystem joystick interface' CONFIG_JOY_TURBOGRAFX $CONFIG_JOYSTICK $CONFIG_PARPORT + dep_tristate ' NES, SNES, PSX, Multisystem joysticks and gamepads' CONFIG_JOY_CONSOLE $CONFIG_JOYSTICK $CONFIG_PARPORT + dep_tristate ' Sega, Multisystem joysticks and gamepads' CONFIG_JOY_DB9 $CONFIG_JOYSTICK $CONFIG_PARPORT + dep_tristate ' TurboGraFX Multisystem joystick interface' CONFIG_JOY_TURBOGRAFX $CONFIG_JOYSTICK $CONFIG_PARPORT fi if [ "$CONFIG_AMIGA" = "y" ]; then - dep_tristate ' Amiga joysticks' CONFIG_JOY_AMIGA $CONFIG_JOYSTICK + dep_tristate ' Amiga joysticks' CONFIG_JOY_AMIGA $CONFIG_JOYSTICK fi diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 85167d74a156..5fa95dff2412 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -155,7 +156,6 @@ struct pt_regs * kbd_pt_regs; #ifdef CONFIG_MAGIC_SYSRQ static int sysrq_pressed; -int sysrq_enabled = 1; #endif /* diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 02f3873a0522..18ab3f269083 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -258,6 +258,12 @@ int __init misc_init(void) #endif #ifdef CONFIG_NWFLASH nwflash_init(); +#endif +#ifdef CONFIG_SGI_NEWPORT_GFX + gfx_register (); +#endif +#ifdef CONFIG_SGI + streamable_init (); #endif if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { printk("unable to get major %d for misc devices\n", diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index 7251a4e05098..0717fa418264 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c @@ -9,7 +9,7 @@ * Al Longyear , Paul Mackerras * * Original release 01/11/99 - * ==FILEDATE 19990524== + * ==FILEDATE 19990901== * * This code is released under the GNU General Public License (GPL) * @@ -21,8 +21,13 @@ * 1. tty write calls represent one complete transmit frame of data * The device driver should accept the complete frame or none of * the frame (busy) in the write method. Each write call should have - * a byte count in the range of 2-4096 bytes (2 is min HDLC frame - * with 1 addr byte and 1 ctrl byte). + * a byte count in the range of 2-65535 bytes (2 is min HDLC frame + * with 1 addr byte and 1 ctrl byte). The max byte count of 65535 + * should include any crc bytes required. For example, when using + * CCITT CRC32, 4 crc bytes are required, so the maximum size frame + * the application may transmit is limited to 65531 bytes. For CCITT + * CRC16, the maximum application frame size would be 65533. + * * * 2. receive callbacks from the device driver represents * one received frame. The device driver should bypass @@ -73,7 +78,7 @@ */ #define HDLC_MAGIC 0x239e -#define HDLC_VERSION "1.2" +#define HDLC_VERSION "1.11" #include #include @@ -100,6 +105,7 @@ #include #include #include +#include /* to get the struct task_struct */ #include /* used in new tty drivers */ #include /* used in new tty drivers */ #include @@ -113,6 +119,13 @@ #include #endif +#if LINUX_VERSION_CODE < VERSION(2,3,0) +typedef struct wait_queue *wait_queue_head_t; +#define DECLARE_WAITQUEUE(name,task) struct wait_queue (name) = {(task),NULL} +#define init_waitqueue_head(head) *(head) = NULL +#define set_current_state(a) current->state = (a) +#endif + #if LINUX_VERSION_CODE >= VERSION(2,1,4) #include #define GET_USER(error,value,addr) error = get_user(value,addr) @@ -189,18 +202,21 @@ typedef size_t rw_count_t; /* * Buffers for individual HDLC frames */ -#define MAX_HDLC_FRAME_SIZE 4096 +#define MAX_HDLC_FRAME_SIZE 65535 #define DEFAULT_RX_BUF_COUNT 10 -#define MAX_RX_BUF_COUNT 30 +#define MAX_RX_BUF_COUNT 60 #define DEFAULT_TX_BUF_COUNT 1 + typedef struct _n_hdlc_buf { struct _n_hdlc_buf *link; int count; - char buf[MAX_HDLC_FRAME_SIZE]; + char buf[1]; } N_HDLC_BUF; +#define N_HDLC_BUF_SIZE (sizeof(N_HDLC_BUF)+maxframe) + typedef struct _n_hdlc_buf_list { N_HDLC_BUF *head; @@ -246,12 +262,16 @@ static struct n_hdlc *n_hdlc_alloc (void); #if LINUX_VERSION_CODE >= VERSION(2,1,19) MODULE_PARM(debuglevel, "i"); +MODULE_PARM(maxframe, "i"); #endif /* debug level can be set by insmod for debugging purposes */ #define DEBUG_LEVEL_INFO 1 int debuglevel=0; +/* max frame size for memory allocations */ +ssize_t maxframe=4096; + /* TTY callbacks */ static rw_ret_t n_hdlc_tty_read(struct tty_struct *, @@ -353,6 +373,9 @@ static void n_hdlc_tty_close(struct tty_struct *tty) printk (KERN_WARNING"n_hdlc: trying to close unopened tty!\n"); return; } +#if defined(TTY_NO_WRITE_SPLIT) + clear_bit(TTY_NO_WRITE_SPLIT,&tty->flags); +#endif tty->disc_data = NULL; if (tty == n_hdlc->backup_tty) n_hdlc->backup_tty = 0; @@ -383,7 +406,9 @@ static int n_hdlc_tty_open (struct tty_struct *tty) struct n_hdlc *n_hdlc = tty2n_hdlc (tty); if (debuglevel >= DEBUG_LEVEL_INFO) - printk("%s(%d)n_hdlc_tty_open() called\n",__FILE__,__LINE__); + printk("%s(%d)n_hdlc_tty_open() called (major=%u,minor=%u)\n", + __FILE__,__LINE__, + MAJOR(tty->device), MINOR(tty->device)); /* There should not be an existing table for this slot. */ if (n_hdlc) { @@ -399,9 +424,14 @@ static int n_hdlc_tty_open (struct tty_struct *tty) tty->disc_data = n_hdlc; n_hdlc->tty = tty; - + MOD_INC_USE_COUNT; +#if defined(TTY_NO_WRITE_SPLIT) + /* change tty_io write() to not split large writes into 8K chunks */ + set_bit(TTY_NO_WRITE_SPLIT,&tty->flags); +#endif + /* Flush any pending characters in the driver and discipline. */ if (tty->ldisc.flush_buffer) @@ -597,18 +627,26 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, return; } + if ( count>maxframe ) { + if (debuglevel >= DEBUG_LEVEL_INFO) + printk("%s(%d) rx count>maxframesize, data discarded\n", + __FILE__,__LINE__); + return; + } + /* get a free HDLC buffer */ buf = n_hdlc_buf_get(&n_hdlc->rx_free_buf_list); if (!buf) { /* no buffers in free list, attempt to allocate another rx buffer */ /* unless the maximum count has been reached */ if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT) - buf = (N_HDLC_BUF*)kmalloc(sizeof(N_HDLC_BUF),GFP_ATOMIC); + buf = (N_HDLC_BUF*)kmalloc(N_HDLC_BUF_SIZE,GFP_ATOMIC); } if (!buf) { - printk("%s(%d) no more rx buffers, data discarded\n", - __FILE__,__LINE__); + if (debuglevel >= DEBUG_LEVEL_INFO) + printk("%s(%d) no more rx buffers, data discarded\n", + __FILE__,__LINE__); return; } @@ -622,7 +660,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, /* wake up any blocked reads and perform async signalling */ wake_up_interruptible (&n_hdlc->read_wait); if (n_hdlc->tty->fasync != NULL) - kill_fasync (n_hdlc->tty->fasync, SIGIO); + kill_fasync (n_hdlc->tty->fasync, SIGIO, POLL_IN); } /* end of n_hdlc_tty_receive() */ @@ -678,12 +716,11 @@ static rw_ret_t n_hdlc_tty_read (struct tty_struct *tty, if (file->f_flags & O_NONBLOCK) return -EAGAIN; - /* TODO: no timeout? current->timeout = 0;*/ interruptible_sleep_on (&n_hdlc->read_wait); if (signal_pending(current)) return -EINTR; } - + if (rbuf->count > nr) { /* frame too large for caller's buffer (discard frame) */ ret = (rw_ret_t)-EOVERFLOW; @@ -739,13 +776,13 @@ static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file, return -EIO; /* verify frame size */ - if (count > MAX_HDLC_FRAME_SIZE) { + if (count > maxframe ) { if (debuglevel & DEBUG_LEVEL_INFO) printk (KERN_WARNING "n_hdlc_tty_write: truncating user packet " "from %lu to %d\n", (unsigned long) count, - MAX_HDLC_FRAME_SIZE); - count = MAX_HDLC_FRAME_SIZE; + maxframe ); + count = maxframe; } /* Allocate transmit buffer */ @@ -754,8 +791,7 @@ static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file, /* sleep until transmit buffer available */ add_wait_queue(&n_hdlc->write_wait, &wait); while (!tbuf) { - /* TODO: no timeout? current->timeout = 0;*/ - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule(); n_hdlc = tty2n_hdlc (tty); @@ -773,7 +809,7 @@ static rw_ret_t n_hdlc_tty_write (struct tty_struct *tty, struct file *file, tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list); } - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&n_hdlc->write_wait, &wait); } @@ -1000,16 +1036,20 @@ static struct n_hdlc *n_hdlc_alloc (void) /* allocate free rx buffer list */ for(i=0;irx_free_buf_list,buf); + else if (debuglevel >= DEBUG_LEVEL_INFO) + printk("%s(%d)n_hdlc_alloc(), kalloc() failed for rx buffer %d\n",__FILE__,__LINE__, i); } - /* allocate free rx buffer list */ + /* allocate free tx buffer list */ for(i=0;itx_free_buf_list,buf); + else if (debuglevel >= DEBUG_LEVEL_INFO) + printk("%s(%d)n_hdlc_alloc(), kalloc() failed for tx buffer %d\n",__FILE__,__LINE__, i); } /* Initialize the control block */ @@ -1108,7 +1148,14 @@ int init_module(void) static struct tty_ldisc n_hdlc_ldisc; int status; - printk("HDLC line discipline: version %s\n", szVersion); + /* range check maxframe arg */ + if ( maxframe<4096) + maxframe=4096; + else if ( maxframe>65535) + maxframe=65535; + + printk("HDLC line discipline: version %s, maxframe=%u\n", + szVersion, maxframe); /* Register the tty discipline */ diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index d95cda30edd4..9027aa67ee01 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -604,7 +604,7 @@ send_signal: tty->canon_head = tty->read_head; tty->canon_data++; if (tty->fasync) - kill_fasync(tty->fasync, SIGIO); + kill_fasync(tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); return; @@ -706,7 +706,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { if (tty->fasync) - kill_fasync(tty->fasync, SIGIO); + kill_fasync(tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); } @@ -854,6 +854,7 @@ static inline int copy_from_read_buf(struct tty_struct *tty, retval = 0; n = MIN(*nr, MIN(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail)); if (n) { + mb(); retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n); n -= retval; tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); diff --git a/drivers/char/pc110pad.c b/drivers/char/pc110pad.c index 0c00dcfa5be9..7e4518e15865 100644 --- a/drivers/char/pc110pad.c +++ b/drivers/char/pc110pad.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include "pc110pad.h" @@ -51,7 +53,7 @@ static struct pc110pad_params current_params; static wait_queue_head_t queue; static struct fasync_struct *asyncptr; static int active=0; /* number of concurrent open()s */ - +static struct semaphore read_lock; /* * Utility to reset a timer to go off some time in the future. @@ -75,7 +77,7 @@ static void wake_readers(void) { wake_up_interruptible(&queue); if(asyncptr) - kill_fasync(asyncptr, SIGIO); + kill_fasync(asyncptr, SIGIO, POLL_IN); } @@ -503,10 +505,13 @@ static int close_pad(struct inode * inode, struct file * file) */ static int open_pad(struct inode * inode, struct file * file) { + unsigned long flags; + if (active++) return 0; MOD_INC_USE_COUNT; + save_flags(flags); cli(); outb(0x30, current_params.io+2); /* switch off digitiser */ pad_irq(0,0,0); /* read to flush any pending bytes */ @@ -522,7 +527,7 @@ static int open_pad(struct inode * inode, struct file * file) synthesize_tap=0; del_timer(&bounce_timer); del_timer(&tap_timer); - sti(); + restore_flags(flags); return 0; } @@ -556,14 +561,19 @@ static ssize_t read_pad(struct file * file, char * buffer, size_t count, loff_t { int r; + down(&read_lock); for(r=0; r #include #include -#include #include #include #include @@ -34,14 +33,15 @@ #include #include -#include #include #include #include +#include + /* Some configuration switches are present in the include file... */ -#include "pc_keyb.h" +#include /* Simple translation table for the SysRq keys */ @@ -56,10 +56,11 @@ unsigned char pckbd_sysrq_xlate[128] = "\r\000/"; /* 0x60 - 0x6f */ #endif -static void kbd_write(int address, int data); -static unsigned char handle_kbd_event(void); +static void kbd_write_command_w(int data); +static void kbd_write_output_w(int data); spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; +static unsigned char handle_kbd_event(void); /* used only by send_data - set by keyboard_interrupt */ static volatile unsigned char reply_expected = 0; @@ -83,11 +84,6 @@ static unsigned char mouse_reply_expected = 0; #define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT) #define MAX_RETRIES 60 /* some aux operations take long time*/ - -#ifndef AUX_IRQ -# define AUX_IRQ 12 -#endif - #endif /* CONFIG_PSMOUSE */ /* @@ -409,7 +405,7 @@ static inline void handle_mouse_event(unsigned char scancode) if (head != queue->tail) { queue->head = head; if (queue->fasync) - kill_fasync(queue->fasync, SIGIO); + kill_fasync(queue->fasync, SIGIO, POLL_IN); wake_up_interruptible(&queue->proc_list); } } @@ -425,22 +421,31 @@ static inline void handle_mouse_event(unsigned char scancode) */ static unsigned char handle_kbd_event(void) { - unsigned char status = inb(KBD_STATUS_REG); + unsigned char status = kbd_read_status(); + unsigned int work = 10000; while (status & KBD_STAT_OBF) { unsigned char scancode; - scancode = inb(KBD_DATA_REG); - + scancode = kbd_read_input(); if (status & KBD_STAT_MOUSE_OBF) { handle_mouse_event(scancode); } else { +#ifdef CONFIG_VT if (do_acknowledge(scancode)) handle_scancode(scancode, !(scancode & 0x80)); +#endif mark_bh(KEYBOARD_BH); } - status = inb(KBD_STATUS_REG); + status = kbd_read_status(); + + if(!work--) + { + printk(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n", + status); + break; + } } return status; @@ -451,8 +456,9 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; +#ifdef CONFIG_VT kbd_pt_regs = regs; - +#endif spin_lock_irqsave(&kbd_controller_lock, flags); handle_kbd_event(); spin_unlock_irqrestore(&kbd_controller_lock, flags); @@ -475,7 +481,7 @@ static int send_data(unsigned char data) acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */ resend = 0; reply_expected = 1; - kbd_write(KBD_DATA_REG, data); + kbd_write_output_w(data); for (;;) { if (acknowledge) return 1; @@ -529,14 +535,14 @@ __setup("kbd-reset", kbd_reset_setup); #define KBD_NO_DATA (-1) /* No data */ #define KBD_BAD_DATA (-2) /* Parity or other error */ -static int __init kbd_read_input(void) +static int __init kbd_read_data(void) { int retval = KBD_NO_DATA; unsigned char status; - status = inb(KBD_STATUS_REG); + status = kbd_read_status(); if (status & KBD_STAT_OBF) { - unsigned char data = inb(KBD_DATA_REG); + unsigned char data = kbd_read_input(); retval = data; if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) @@ -550,7 +556,7 @@ static void __init kbd_clear_input(void) int maxread = 100; /* Random number */ do { - if (kbd_read_input() == KBD_NO_DATA) + if (kbd_read_data() == KBD_NO_DATA) break; } while (--maxread); } @@ -560,7 +566,7 @@ static int __init kbd_wait_for_input(void) long timeout = KBD_INIT_TIMEOUT; do { - int retval = kbd_read_input(); + int retval = kbd_read_data(); if (retval >= 0) return retval; mdelay(1); @@ -568,13 +574,23 @@ static int __init kbd_wait_for_input(void) return -1; } -static void kbd_write(int address, int data) +static void kbd_write_command_w(int data) { unsigned long flags; spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); - outb(data, address); + kbd_write_command(data); + spin_unlock_irqrestore(&kbd_controller_lock, flags); +} + +static void kbd_write_output_w(int data) +{ + unsigned long flags; + + spin_lock_irqsave(&kbd_controller_lock, flags); + kb_wait(); + kbd_write_output(data); spin_unlock_irqrestore(&kbd_controller_lock, flags); } @@ -585,9 +601,9 @@ static void kbd_write_cmd(int cmd) spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); - outb(KBD_CCMD_WRITE_MODE, KBD_CNTL_REG); + kbd_write_command(KBD_CCMD_WRITE_MODE); kb_wait(); - outb(cmd, KBD_DATA_REG); + kbd_write_output(cmd); spin_unlock_irqrestore(&kbd_controller_lock, flags); } #endif /* CONFIG_PSMOUSE */ @@ -601,7 +617,7 @@ static char * __init initialize_kbd(void) * This seems to be the only way to get it going. * If the test is successful a x55 is placed in the input buffer. */ - kbd_write(KBD_CNTL_REG, KBD_CCMD_SELF_TEST); + kbd_write_command_w(KBD_CCMD_SELF_TEST); if (kbd_wait_for_input() != 0x55) return "Keyboard failed self test"; @@ -610,14 +626,14 @@ static char * __init initialize_kbd(void) * to test the keyboard clock and data lines. The results of the * test are placed in the input buffer. */ - kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_TEST); + kbd_write_command_w(KBD_CCMD_KBD_TEST); if (kbd_wait_for_input() != 0x00) return "Keyboard interface failed self test"; /* * Enable the keyboard by allowing the keyboard clock to run. */ - kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_ENABLE); + kbd_write_command_w(KBD_CCMD_KBD_ENABLE); /* * Reset keyboard. If the read times out @@ -628,7 +644,7 @@ static char * __init initialize_kbd(void) * Set up to try again if the keyboard asks for RESEND. */ do { - kbd_write(KBD_DATA_REG, KBD_CMD_RESET); + kbd_write_output_w(KBD_CMD_RESET); status = kbd_wait_for_input(); if (status == KBD_REPLY_ACK) break; @@ -646,7 +662,7 @@ static char * __init initialize_kbd(void) * Set up to try again if the keyboard asks for RESEND. */ do { - kbd_write(KBD_DATA_REG, KBD_CMD_DISABLE); + kbd_write_output_w(KBD_CMD_DISABLE); status = kbd_wait_for_input(); if (status == KBD_REPLY_ACK) break; @@ -654,37 +670,37 @@ static char * __init initialize_kbd(void) return "Disable keyboard: no ACK"; } while (1); - kbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE); - kbd_write(KBD_DATA_REG, KBD_MODE_KBD_INT + kbd_write_command_w(KBD_CCMD_WRITE_MODE); + kbd_write_output_w(KBD_MODE_KBD_INT | KBD_MODE_SYS | KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC); /* ibm powerpc portables need this to use scan-code set 1 -- Cort */ - kbd_write(KBD_CNTL_REG, KBD_CCMD_READ_MODE); + kbd_write_command_w(KBD_CCMD_READ_MODE); if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { /* * If the controller does not support conversion, * Set the keyboard to scan-code set 1. */ - kbd_write(KBD_DATA_REG, 0xF0); + kbd_write_output_w(0xF0); kbd_wait_for_input(); - kbd_write(KBD_DATA_REG, 0x01); + kbd_write_output_w(0x01); kbd_wait_for_input(); } - kbd_write(KBD_DATA_REG, KBD_CMD_ENABLE); + kbd_write_output_w(KBD_CMD_ENABLE); if (kbd_wait_for_input() != KBD_REPLY_ACK) return "Enable keyboard: no ACK"; /* * Finally, set the typematic rate to maximum. */ - kbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE); + kbd_write_output_w(KBD_CMD_SET_RATE); if (kbd_wait_for_input() != KBD_REPLY_ACK) return "Set rate: no ACK"; - kbd_write(KBD_DATA_REG, 0x00); + kbd_write_output_w(0x00); if (kbd_wait_for_input() != KBD_REPLY_ACK) return "Set rate: no ACK"; @@ -693,6 +709,8 @@ static char * __init initialize_kbd(void) void __init pckbd_init_hw(void) { + kbd_request_region(); + /* Flush any pending input. */ kbd_clear_input(); @@ -707,7 +725,7 @@ void __init pckbd_init_hw(void) #endif /* Ok, finally allocate the IRQ, and off we go.. */ - request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL); + kbd_request_irq(keyboard_interrupt); } #if defined CONFIG_PSMOUSE @@ -731,16 +749,16 @@ static int __init detect_auxiliary_port(void) * controller has an Auxiliary Port (a.k.a. Mouse Port). */ kb_wait(); - outb(KBD_CCMD_WRITE_AUX_OBUF, KBD_CNTL_REG); + kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF); kb_wait(); - outb(0x5a, KBD_DATA_REG); /* 0x5a is a random dummy value. */ + kbd_write_output(0x5a); /* 0x5a is a random dummy value. */ do { - unsigned char status = inb(KBD_STATUS_REG); + unsigned char status = kbd_read_status(); if (status & KBD_STAT_OBF) { - (void) inb(KBD_DATA_REG); + (void) kbd_read_input(); if (status & KBD_STAT_MOUSE_OBF) { printk(KERN_INFO "Detected PS/2 Mouse Port.\n"); retval = 1; @@ -763,9 +781,9 @@ static void aux_write_dev(int val) spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); - outb(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG); + kbd_write_command(KBD_CCMD_WRITE_MOUSE); kb_wait(); - outb(val, KBD_DATA_REG); + kbd_write_output(val); spin_unlock_irqrestore(&kbd_controller_lock, flags); } @@ -778,9 +796,9 @@ static void aux_write_ack(int val) spin_lock_irqsave(&kbd_controller_lock, flags); kb_wait(); - outb(KBD_CCMD_WRITE_MOUSE, KBD_CNTL_REG); + kbd_write_command(KBD_CCMD_WRITE_MOUSE); kb_wait(); - outb(val, KBD_DATA_REG); + kbd_write_output(val); /* we expect an ACK in response. */ mouse_reply_expected++; kb_wait(); @@ -827,8 +845,8 @@ static int release_aux(struct inode * inode, struct file * file) if (--aux_count) return 0; kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */ - kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); - free_irq(AUX_IRQ, AUX_DEV); + kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE); + aux_free_irq(AUX_DEV); return 0; } @@ -843,11 +861,11 @@ static int open_aux(struct inode * inode, struct file * file) return 0; } queue->head = queue->tail = 0; /* Flush input queue */ - if (request_irq(AUX_IRQ, keyboard_interrupt, SA_SHIRQ, "PS/2 Mouse", AUX_DEV)) { + if (aux_request_irq(keyboard_interrupt, AUX_DEV)) { aux_count--; return -EBUSY; } - kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable the + kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable the auxiliary port on controller. */ aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */ @@ -966,14 +984,14 @@ static int __init psaux_init(void) init_waitqueue_head(&queue->proc_list); #ifdef INITIALIZE_MOUSE - kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ + kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ aux_write_ack(AUX_SET_SAMPLE); aux_write_ack(100); /* 100 samples/sec */ aux_write_ack(AUX_SET_RES); aux_write_ack(3); /* 8 counts per mm */ aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */ #endif /* INITIALIZE_MOUSE */ - kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */ + kbd_write_command(KBD_CCMD_MOUSE_DISABLE); /* Disable aux device. */ kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints. */ return 0; diff --git a/drivers/char/ppdev.h b/drivers/char/ppdev.h index 40f013556c5f..f466f11e690a 100644 --- a/drivers/char/ppdev.h +++ b/drivers/char/ppdev.h @@ -75,7 +75,7 @@ struct ppdev_frob_struct { #define PPSETPHASE _IOW(PP_IOCTL, 0x94, int) /* Set and get port timeout (struct timeval's) */ -#define PPGETTIME _IOW(PP_IOCTL, 0x95, struct timeval) -#define PPSETTIME _IOR(PP_IOCTL, 0x96, struct timeval) +#define PPGETTIME _IOR(PP_IOCTL, 0x95, struct timeval) +#define PPSETTIME _IOW(PP_IOCTL, 0x96, struct timeval) diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 7d99d5b68831..17711734f336 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -661,25 +661,31 @@ static inline ssize_t do_tty_write( if (down_interruptible(&inode->i_sem)) { return -ERESTARTSYS; } - for (;;) { - unsigned long size = PAGE_SIZE*2; - if (size > count) - size = count; + if ( test_bit(TTY_NO_WRITE_SPLIT, &tty->flags) ) { lock_kernel(); - ret = write(tty, file, buf, size); + written = write(tty, file, buf, count); unlock_kernel(); - if (ret <= 0) - break; - written += ret; - buf += ret; - count -= ret; - if (!count) - break; - ret = -ERESTARTSYS; - if (signal_pending(current)) - break; - if (current->need_resched) - schedule(); + } else { + for (;;) { + unsigned long size = PAGE_SIZE*2; + if (size > count) + size = count; + lock_kernel(); + ret = write(tty, file, buf, size); + unlock_kernel(); + if (ret <= 0) + break; + written += ret; + buf += ret; + count -= ret; + if (!count) + break; + ret = -ERESTARTSYS; + if (signal_pending(current)) + break; + if (current->need_resched) + schedule(); + } } if (written) { file->f_dentry->d_inode->i_mtime = CURRENT_TIME; @@ -1996,7 +2002,8 @@ int tty_unregister_driver(struct tty_driver *driver) { int retval; struct tty_driver *p; - int found = 0; + int i, found = 0; + struct termios *tp; const char *othername = NULL; if (*driver->refcount) @@ -2027,6 +2034,23 @@ int tty_unregister_driver(struct tty_driver *driver) if (driver->next) driver->next->prev = driver->prev; + /* + * Free the termios and termios_locked structures because + * we don't want to get memory leaks when modular tty + * drivers are removed from the kernel. + */ + for (i = 0; i < driver->num; i++) { + tp = driver->termios[i]; + if (tp) { + driver->termios[i] = NULL; + kfree_s(tp, sizeof(struct termios)); + } + tp = driver->termios_locked[i]; + if (tp) { + driver->termios_locked[i] = NULL; + kfree_s(tp, sizeof(struct termios)); + } + } proc_tty_unregister_driver(driver); return 0; } diff --git a/drivers/fc4/Config.in b/drivers/fc4/Config.in index 8328f32bdef8..a11ab5b3e447 100644 --- a/drivers/fc4/Config.in +++ b/drivers/fc4/Config.in @@ -6,22 +6,22 @@ comment 'Fibre Channel support' tristate 'Fibre Channel and FC4 SCSI support' CONFIG_FC4 if [ ! "$CONFIG_FC4" = "n" ]; then - comment 'FC4 drivers' - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then - tristate 'Sun SOC/Sbus' CONFIG_FC4_SOC - tristate 'Sun SOC+ (aka SOCAL)' CONFIG_FC4_SOCAL - fi - comment 'FC4 targets' - dep_tristate 'SparcSTORAGE Array 100 and 200 series' CONFIG_SCSI_PLUTO $CONFIG_SCSI - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then - dep_tristate 'Sun Enterprise Network Array (A5000 and EX500)' CONFIG_SCSI_FCAL $CONFIG_SCSI - else - dep_tristate 'Generic FC-AL disk driver' CONFIG_SCSI_FCAL $CONFIG_SCSI - fi + comment 'FC4 drivers' + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + tristate 'Sun SOC/Sbus' CONFIG_FC4_SOC + tristate 'Sun SOC+ (aka SOCAL)' CONFIG_FC4_SOCAL + fi + comment 'FC4 targets' + dep_tristate 'SparcSTORAGE Array 100 and 200 series' CONFIG_SCSI_PLUTO $CONFIG_SCSI + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + dep_tristate 'Sun Enterprise Network Array (A5000 and EX500)' CONFIG_SCSI_FCAL $CONFIG_SCSI + else + dep_tristate 'Generic FC-AL disk driver' CONFIG_SCSI_FCAL $CONFIG_SCSI + fi else - define_bool CONFIG_FC4_SOC n - define_bool CONFIG_FC4_SOCAL n - define_bool CONFIG_SCSI_PLUTO n - define_bool CONFIG_SCSI_FCAL n + define_bool CONFIG_FC4_SOC n + define_bool CONFIG_FC4_SOCAL n + define_bool CONFIG_SCSI_PLUTO n + define_bool CONFIG_SCSI_FCAL n fi endmenu diff --git a/drivers/net/Config.in b/drivers/net/Config.in index 1902e507065b..3e07e6caee5e 100644 --- a/drivers/net/Config.in +++ b/drivers/net/Config.in @@ -7,12 +7,12 @@ comment 'ARCnet devices' tristate 'ARCnet support' CONFIG_ARCNET if [ "$CONFIG_ARCNET" != "n" ]; then - bool ' Enable arc0e (ARCnet "Ether-Encap" packet format)' CONFIG_ARCNET_ETH - bool ' Enable arc0s (ARCnet RFC1051 packet format)' CONFIG_ARCNET_1051 - dep_tristate ' ARCnet COM90xx (normal) chipset driver' CONFIG_ARCNET_COM90xx $CONFIG_ARCNET - dep_tristate ' ARCnet COM90xx (IO mapped) chipset driver' CONFIG_ARCNET_COM90xxIO $CONFIG_ARCNET - dep_tristate ' ARCnet COM90xx (RIM I) chipset driver' CONFIG_ARCNET_RIM_I $CONFIG_ARCNET - dep_tristate ' ARCnet COM20020 chipset driver' CONFIG_ARCNET_COM20020 $CONFIG_ARCNET + bool ' Enable arc0e (ARCnet "Ether-Encap" packet format)' CONFIG_ARCNET_ETH + bool ' Enable arc0s (ARCnet RFC1051 packet format)' CONFIG_ARCNET_1051 + dep_tristate ' ARCnet COM90xx (normal) chipset driver' CONFIG_ARCNET_COM90xx $CONFIG_ARCNET + dep_tristate ' ARCnet COM90xx (IO mapped) chipset driver' CONFIG_ARCNET_COM90xxIO $CONFIG_ARCNET + dep_tristate ' ARCnet COM90xx (RIM I) chipset driver' CONFIG_ARCNET_RIM_I $CONFIG_ARCNET + dep_tristate ' ARCnet COM20020 chipset driver' CONFIG_ARCNET_COM20020 $CONFIG_ARCNET fi endmenu @@ -20,9 +20,9 @@ endmenu tristate 'Dummy net driver support' CONFIG_DUMMY tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_NETLINK" = "y" ]; then - tristate 'Ethertap network tap' CONFIG_ETHERTAP - fi + if [ "$CONFIG_NETLINK" = "y" ]; then + tristate 'Ethertap network tap (EXPERIMENTAL)' CONFIG_ETHERTAP + fi fi tristate 'General Instruments Surfboard 1000' CONFIG_NET_SB1000 @@ -36,145 +36,154 @@ comment 'Ethernet (10 or 100Mbit)' bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET if [ "$CONFIG_NET_ETHERNET" = "y" ]; then - if [ "$CONFIG_ARM" = "y" ]; then - if [ "$CONFIG_ARCH_ACORN" != "y" ]; then - tristate 'AM79C961A support' CONFIG_ARM_AM79C961A - else - source drivers/acorn/net/Config.in - fi - fi - if [ "$CONFIG_PPC" = "y" ]; then - tristate 'MACE (Power Mac ethernet) support' CONFIG_MACE - tristate 'BMAC (G3 ethernet) support' CONFIG_BMAC - fi - if [ "$CONFIG_ZORRO" = "y" ]; then - tristate 'Ariadne support' CONFIG_ARIADNE - tristate 'Ariadne II support' CONFIG_ARIADNE2 - tristate 'A2065 support' CONFIG_A2065 - tristate 'Hydra support' CONFIG_HYDRA - fi - if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then - tristate 'MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC - fi - bool '3COM cards' CONFIG_NET_VENDOR_3COM - if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then - tristate '3c501 support' CONFIG_EL1 - tristate '3c503 support' CONFIG_EL2 - tristate '3c505 support' CONFIG_ELPLUS - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate '3c507 support' CONFIG_EL16 + if [ "$CONFIG_ARM" = "y" ]; then + if [ "$CONFIG_ARCH_ACORN" != "y" ]; then + tristate ' AM79C961A support' CONFIG_ARM_AM79C961A + else + source drivers/acorn/net/Config.in + fi + fi + if [ "$CONFIG_PPC" = "y" ]; then + tristate ' MACE (Power Mac ethernet) support' CONFIG_MACE + tristate ' BMAC (G3 ethernet) support' CONFIG_BMAC + fi + if [ "$CONFIG_ZORRO" = "y" ]; then + tristate ' Ariadne support' CONFIG_ARIADNE + tristate ' Ariadne II support' CONFIG_ARIADNE2 + tristate ' A2065 support' CONFIG_A2065 + tristate ' Hydra support' CONFIG_HYDRA + fi + if [ "$CONFIG_MIPS_JAZZ" = "y" ]; then + tristate ' MIPS JAZZ onboard SONIC Ethernet support' CONFIG_MIPS_JAZZ_SONIC + fi + bool ' 3COM cards' CONFIG_NET_VENDOR_3COM + if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then + tristate ' 3c501 support' CONFIG_EL1 + tristate ' 3c503 support' CONFIG_EL2 + tristate ' 3c505 support' CONFIG_ELPLUS + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' 3c507 support (EXPERIMENTAL)' CONFIG_EL16 + fi + tristate ' 3c509/3c529 (MCA)/3c579 support' CONFIG_EL3 + tristate ' 3c515 ISA Fast EtherLink' CONFIG_3C515 if [ "$CONFIG_MCA" = "y" ]; then - tristate '3c523 support' CONFIG_ELMC - tristate '3c527 support' CONFIG_ELMC_II + tristate ' 3c523 support' CONFIG_ELMC + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' 3c527 support (EXPERIMENTAL)' CONFIG_ELMC_II + fi fi - fi - tristate '3c509/3c579 support' CONFIG_EL3 - tristate '3c515 ISA Fast EtherLink' CONFIG_3C515 - tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX - fi - tristate 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE - bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC - if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then - tristate 'WD80*3 support' CONFIG_WD80x3 - if [ "$CONFIG_MCA" = "y" ]; then - tristate 'SMC Ultra MCA support' CONFIG_ULTRAMCA - fi - tristate 'SMC Ultra support' CONFIG_ULTRA - tristate 'SMC Ultra32 EISA support' CONFIG_ULTRA32 - tristate 'SMC 9194 support' CONFIG_SMC9194 + tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX + fi + tristate ' AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE + bool ' Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC + if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then + tristate ' WD80*3 support' CONFIG_WD80x3 + if [ "$CONFIG_MCA" = "y" ]; then + tristate ' SMC Ultra MCA support' CONFIG_ULTRAMCA + fi + tristate ' SMC Ultra support' CONFIG_ULTRA + tristate ' SMC Ultra32 EISA support' CONFIG_ULTRA32 + tristate ' SMC 9194 support' CONFIG_SMC9194 fi - bool 'Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL + bool ' Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL if [ "$CONFIG_NET_VENDOR_RACAL" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'NI5010 support' CONFIG_NI5010 + tristate ' NI5010 support (EXPERIMENTAL)' CONFIG_NI5010 fi - tristate 'NI5210 support' CONFIG_NI52 - tristate 'NI6510 support' CONFIG_NI65 + tristate ' NI5210 support' CONFIG_NI52 + tristate ' NI6510 support' CONFIG_NI65 fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139 - tristate 'SiS 900 PCI Fast Ethernet Adapter support' CONFIG_SIS900 - tristate 'Packet Engines Yellowfin Gigabit-NIC support' CONFIG_YELLOWFIN - tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC + # tristate ' Packet Engines Hamachi GNIC-II support (EXPERIMENTAL)' CONFIG_HAMACHI + tristate ' Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN + tristate ' RealTek 8129/8139 (not 8019/8029!) support (EXPERIMENTAL)' CONFIG_RTL8139 + tristate ' SiS 900 PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_SIS900 + tristate ' DM9102 PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_DM9102 + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700 + fi + tristate ' DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA + bool ' Other ISA cards' CONFIG_NET_ISA + if [ "$CONFIG_NET_ISA" = "y" ]; then + tristate ' Cabletron E21xx support' CONFIG_E2100 + tristate ' EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3 + tristate ' EtherExpress 16 support' CONFIG_EEXPRESS + tristate ' EtherExpressPro support' CONFIG_EEXPRESS_PRO + tristate ' FMV-181/182/183/184 support' CONFIG_FMV18X + tristate ' HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS + tristate ' HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN + tristate ' HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' ICL EtherTeam 16i/32 support (EXPERIMENTAL)' CONFIG_ETH16I + fi + tristate ' NE2000/NE1000 support' CONFIG_NE2000 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005 + fi + bool ' SK_G16 support' CONFIG_SK_G16 + fi + if [ "$CONFIG_MCA" = "y" ]; then + tristate ' SKnet MCA support' CONFIG_SKMC + tristate ' NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA + fi + bool ' EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA + if [ "$CONFIG_NET_EISA" = "y" ]; then + tristate ' AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + # tristate ' Adaptec Starfire support (EXPERIMENTAL)' CONFIG_ADAPTEC_STARFIRE + fi + tristate ' Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC if [ "$CONFIG_ACENIC" != "n" ]; then - bool 'Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I + bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 fi - fi - bool 'Other ISA cards' CONFIG_NET_ISA - if [ "$CONFIG_NET_ISA" = "y" ]; then - tristate 'AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700 - tristate 'Cabletron E21xx support' CONFIG_E2100 - tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA - tristate 'EtherWORKS 3 (DE203, DE204, DE205) support' CONFIG_EWRK3 - tristate 'EtherExpress 16 support' CONFIG_EEXPRESS - tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO - tristate 'FMV-181/182/183/184 support' CONFIG_FMV18X - tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS - tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN - tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'ICL EtherTeam 16i/32 support' CONFIG_ETH16I - fi - tristate 'NE2000/NE1000 support' CONFIG_NE2000 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'SEEQ8005 support (EXPERIMENTAL)' CONFIG_SEEQ8005 - fi - bool 'SK_G16 support' CONFIG_SK_G16 - fi - if [ "$CONFIG_MCA" = "y" ]; then - tristate 'NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA - tristate 'SKnet MCA support' CONFIG_SKMC - fi - bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA - if [ "$CONFIG_NET_EISA" = "y" ]; then - tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Ansel Communications EISA 3200 support (EXPERIMENTAL)' CONFIG_AC3200 - fi - tristate 'Apricot Xen-II on board Ethernet' CONFIG_APRICOT - tristate 'CS89x0 support' CONFIG_CS89x0 - tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 - tristate 'DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP - tristate 'Digi Intl. RightSwitch SE-X support' CONFIG_DGRS - tristate 'EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100 - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 - tristate 'Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 - fi - tristate 'PCI NE2000 support' CONFIG_NE2K_PCI - tristate 'TI ThunderLAN support' CONFIG_TLAN - tristate 'VIA Rhine support' CONFIG_VIA_RHINE - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 - tristate 'SMC EtherPower II (EXPERIMENTAL)' CONFIG_EPIC100 - bool 'Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET - fi - tristate 'Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE - fi - bool 'Pocket and portable adaptors' CONFIG_NET_POCKET - if [ "$CONFIG_NET_POCKET" = "y" ]; then - bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP - tristate 'D-Link DE600 pocket adaptor support' CONFIG_DE600 - tristate 'D-Link DE620 pocket adaptor support' CONFIG_DE620 - fi + tristate ' Apricot Xen-II on board Ethernet' CONFIG_APRICOT + tristate ' CS89x0 support' CONFIG_CS89x0 + tristate ' Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5 + tristate ' DECchip Tulip (dc21x4x) PCI support' CONFIG_DEC_ELCP + tristate ' Digi Intl. RightSwitch SE-X support' CONFIG_DGRS + tristate ' EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100 + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 + tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 + fi + tristate ' PCI NE2000 support' CONFIG_NE2K_PCI + # tristate ' Sundance Alta support' CONFIG_ALTA + tristate ' TI ThunderLAN support' CONFIG_TLAN + tristate ' VIA Rhine support' CONFIG_VIA_RHINE + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210 + tristate ' SMC EtherPower II (EXPERIMENTAL)' CONFIG_EPIC100 + bool ' Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET + fi + fi + bool ' Pocket and portable adapters' CONFIG_NET_POCKET + if [ "$CONFIG_NET_POCKET" = "y" ]; then + bool ' AT-LAN-TEC/RealTek pocket adapter support' CONFIG_ATP + tristate ' D-Link DE600 pocket adapter support' CONFIG_DE600 + tristate ' D-Link DE620 pocket adapter support' CONFIG_DE620 + fi fi endmenu bool 'FDDI driver support' CONFIG_FDDI if [ "$CONFIG_FDDI" = "y" ]; then - bool 'Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX + bool ' Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI - if [ "$CONFIG_HIPPI" = "y" ]; then - tristate 'Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER - if [ "$CONFIG_ROADRUNNER" != "n" ]; then - bool ' Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS - fi - fi + bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI + if [ "$CONFIG_HIPPI" = "y" ]; then + tristate ' Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER + if [ "$CONFIG_ROADRUNNER" != "n" ]; then + bool ' Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS + fi + fi fi # @@ -182,133 +191,66 @@ fi # if [ "$CONFIG_ATALK" != "n" ]; then - mainmenu_option next_comment - comment 'Appletalk devices' - dep_tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_ATALK - dep_tristate 'COPS LocalTalk PC support' CONFIG_COPS $CONFIG_ATALK - if [ "$CONFIG_COPS" != "n" ]; then - bool 'Dayna firmware support' CONFIG_COPS_DAYNA - bool 'Tangent firmware support' CONFIG_COPS_TANGENT - fi - dep_tristate 'Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_ATALK - if [ "$CONFIG_IPDDP" != "n" ]; then - bool 'IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP - bool 'Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP - fi - endmenu + mainmenu_option next_comment + comment 'Appletalk devices' + dep_tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_ATALK + dep_tristate 'COPS LocalTalk PC support' CONFIG_COPS $CONFIG_ATALK + if [ "$CONFIG_COPS" != "n" ]; then + bool ' Dayna firmware support' CONFIG_COPS_DAYNA + bool ' Tangent firmware support' CONFIG_COPS_TANGENT + fi + dep_tristate 'Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_ATALK + if [ "$CONFIG_IPDDP" != "n" ]; then + bool ' IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP + bool ' Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP + fi + endmenu fi if [ ! "$CONFIG_PARPORT" = "n" ]; then - dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT + dep_tristate 'PLIP (parallel port) support' CONFIG_PLIP $CONFIG_PARPORT fi tristate 'PPP (point-to-point protocol) support' CONFIG_PPP if [ ! "$CONFIG_PPP" = "n" ]; then - dep_tristate 'PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP - dep_tristate 'PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP - dep_tristate 'PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m + dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP + dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP + dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m fi tristate 'SLIP (serial line) support' CONFIG_SLIP if [ "$CONFIG_SLIP" != "n" ]; then - bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED - bool ' Keepalive and linefill' CONFIG_SLIP_SMART - bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 + bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED + bool ' Keepalive and linefill' CONFIG_SLIP_SMART + bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 fi +mainmenu_option next_comment +comment 'Wireless LAN (non-hamradio)' + bool 'Wireless LAN (non-hamradio)' CONFIG_NET_RADIO if [ "$CONFIG_NET_RADIO" = "y" ]; then - dep_tristate 'STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET - tristate 'AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN - tristate 'Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN - -fi + dep_tristate ' STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET + tristate ' AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN + tristate ' Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN -mainmenu_option next_comment -comment 'Token ring devices' - -bool 'Token Ring driver support' CONFIG_TR -if [ "$CONFIG_TR" = "y" ]; then - tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR -# tristate 'IBM Lanstreamer PCI adaptor support' CONFIG_IBMLS - tristate 'IBM Olympic chipset PCI adapter support' CONFIG_IBMOL - tristate 'SysKonnect adapter support' CONFIG_SKTR fi endmenu +source drivers/net/tokenring/Config.in + bool 'Fibre Channel driver support' CONFIG_NET_FC if [ "$CONFIG_NET_FC" = "y" ]; then - tristate 'Interphase 5526 Tachyon chipset based adaptor support' CONFIG_IPHASE5526 + dep_tristate ' Interphase 5526 Tachyon chipset based adapter support' CONFIG_IPHASE5526 $CONFIG_SCSI fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI - tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER + tristate 'Red Creek Hardware VPN (EXPERIMENTAL)' CONFIG_RCPCI + tristate 'Traffic Shaper (EXPERIMENTAL)' CONFIG_SHAPER fi -# -# WAN drivers support -# - -mainmenu_option next_comment -comment 'Wan interfaces' - - -# There is no way to detect a comtrol sv11 - force it modular for now. -# -dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m -# -# The COSA/SRP driver has not been tested as non-modular yet. -# -dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m -# -# There is no way to detect a Sealevel board. Force it modular -# -dep_tristate 'Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m - -tristate 'Frame relay DLCI support' CONFIG_DLCI -if [ "$CONFIG_DLCI" != "n" ]; then - int ' Max open DLCI' CONFIG_DLCI_COUNT 24 - int ' Max DLCI per device' CONFIG_DLCI_MAX 8 - dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI -fi - -# -# Wan router core. -# - -if [ "$CONFIG_WAN_ROUTER" != "n" ]; then - bool 'WAN drivers' CONFIG_WAN_DRIVERS - if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then - dep_tristate 'Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA $CONFIG_WAN_DRIVERS - if [ "$CONFIG_VENDOR_SANGOMA" != "n" ]; then - int ' Maximum number of cards' CONFIG_WANPIPE_CARDS 1 - bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25 - bool ' WANPIPE Frame Relay support' CONFIG_WANPIPE_FR - bool ' WANPIPE PPP support' CONFIG_WANPIPE_PPP - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate 'Cyclom 2X(tm) multiprotocol cards (EXPERIMENTAL)' CONFIG_CYCLADES_SYNC $CONFIG_WAN_DRIVERS - if [ "$CONFIG_CYCLADES_SYNC" != "n" ]; then - bool ' Cyclom 2X X.25 support (EXPERIMENTAL)' CONFIG_CYCLOMX_X25 - fi - fi - fi -fi - -endmenu - - -# -# X.25 network drivers -# -if [ "$CONFIG_X25" != "n" ]; then -if [ "$CONFIG_LAPB" != "n" ]; then - dep_tristate 'LAPB over Ethernet driver' CONFIG_LAPBETHER $CONFIG_LAPB - dep_tristate 'X.25 async driver' CONFIG_X25_ASY $CONFIG_LAPB -fi -fi +source drivers/net/wan/Config.in if [ "$CONFIG_PCMCIA" != "n" ]; then source drivers/net/pcmcia/Config.in diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e1abc4c0e3ae..4589d0ee31bd 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -5,7 +5,7 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) -ALL_SUB_DIRS := $(SUB_DIRS) hamradio irda fc pcmcia +ALL_SUB_DIRS := $(SUB_DIRS) fc hamradio irda pcmcia tokenring wan L_TARGET := net.a L_OBJS := auto_irq.o @@ -24,10 +24,6 @@ CONFIG_7990_BUILTIN := CONFIG_7990_MODULE := CONFIG_82596_BUILTIN := CONFIG_82596_MODULE := -CONFIG_85230_BUILTIN := -CONFIG_85230_MODULE := -CONFIG_SYNCPPP_BUILTIN := -CONFIG_SYNCPPP_MODULE := ifeq ($(CONFIG_PCMCIA),y) SUB_DIRS += pcmcia @@ -60,38 +56,6 @@ ifeq ($(CONFIG_SEEQ8005),y) L_OBJS += seeq8005.o endif -ifeq ($(CONFIG_IBMTR),y) -L_OBJS += ibmtr.o -else - ifeq ($(CONFIG_IBMTR),m) - M_OBJS += ibmtr.o - endif -endif - -ifeq ($(CONFIG_IBMLS),y) -L_OBJS += lanstreamer.o -else - ifeq ($(CONFIG_IBMLS),m) - M_OBJS += lanstreamer.o - endif -endif - -ifeq ($(CONFIG_IBMOL),y) -L_OBJS += olympic.o -else - ifeq ($(CONFIG_IBMOL),m) - M_OBJS += olympic.o - endif -endif - -ifeq ($(CONFIG_SKTR),y) -L_OBJS += sktr.o -else - ifeq ($(CONFIG_SKTR),m) - M_OBJS += sktr.o - endif -endif - ifeq ($(CONFIG_ETHERTAP),y) L_OBJS += ethertap.o else @@ -123,6 +87,13 @@ else endif endif +ifeq ($(CONFIG_PCMCIA_PCNET),y) +CONFIG_8390_BUILTIN = y +else + ifeq ($(CONFIG_PCMCIA_PCNET),m) + CONFIG_8390_MODULE = y + endif +endif ifeq ($(CONFIG_SHAPER),y) L_OBJS += shaper.o @@ -609,6 +580,15 @@ else endif endif +ifeq ($(CONFIG_DM9102),y) +L_OBJS += dmfe.o +else + ifeq ($(CONFIG_DM9102),m) + M_OBJS += dmfe.o + endif +endif + + ifeq ($(CONFIG_YELLOWFIN),y) L_OBJS += yellowfin.o else @@ -811,14 +791,6 @@ else endif endif -ifeq ($(CONFIG_LAPBETHER),y) -L_OBJS += lapbether.o -else - ifeq ($(CONFIG_LAPBETHER),m) - M_OBJS += lapbether.o - endif -endif - ifeq ($(CONFIG_EPIC100),y) L_OBJS += epic100.o else @@ -827,63 +799,6 @@ else endif endif -ifeq ($(CONFIG_HOSTESS_SV11),y) -L_OBJS += hostess_sv11.o -CONFIG_85230_BUILTIN = y -CONFIG_SYNCPPP_BUILTIN = y -else - ifeq ($(CONFIG_HOSTESS_SV11),m) - CONFIG_85230_MODULE = y - CONFIG_SYNCPPP_MODULE = y - M_OBJS += hostess_sv11.o - endif -endif - -ifeq ($(CONFIG_SEALEVEL_4021),y) -L_OBJS += sealevel.o -CONFIG_85230_BUILTIN = y -CONFIG_SYNCPPP_BUILTIN = y -else - ifeq ($(CONFIG_SEALEVEL_4021),m) - CONFIG_85230_MODULE = y - CONFIG_SYNCPPP_MODULE = y - M_OBJS += sealevel.o - endif -endif - - -ifeq ($(CONFIG_COSA),y) -L_OBJS += cosa.o -CONFIG_SYNCPPP_BUILTIN = y -else - ifeq ($(CONFIG_COSA),m) - CONFIG_SYNCPPP_MODULE = y - M_OBJS += cosa.o - endif -endif - -# If anything built-in uses syncppp, then build it into the kernel also. -# If not, but a module uses it, build as a module. - -ifdef CONFIG_SYNCPPP_BUILTIN -LX_OBJS += syncppp.o -else - ifdef CONFIG_SYNCPPP_MODULE - MX_OBJS += syncppp.o - endif -endif - -# If anything built-in uses Z85230, then build it into the kernel also. -# If not, but a module uses it, build as a module. - -ifdef CONFIG_85230_BUILTIN -LX_OBJS += z85230.o -else - ifdef CONFIG_85230_MODULE - MX_OBJS += z85230.o - endif -endif - # If anything built-in uses slhc, then build it into the kernel also. # If not, but a module uses it, build as a module. ifdef CONFIG_SLHC_BUILTIN @@ -914,6 +829,14 @@ else endif endif +ifeq ($(CONFIG_PCMCIA_PCNET),y) +CONFIG_8390_BUILTIN = y +else + ifeq ($(CONFIG_PCMCIA_PCNET),m) + CONFIG_8390_MODULE = y + endif +endif + # If anything built-in uses the 8390, then build it into the kernel also. # If not, but a module uses it, build as a module. ifdef CONFIG_8390_BUILTIN @@ -1036,22 +959,6 @@ else endif endif -ifeq ($(CONFIG_SDLA),y) -L_OBJS += sdla.o -else - ifeq ($(CONFIG_SDLA),m) - M_OBJS += sdla.o - endif -endif - -ifeq ($(CONFIG_DLCI),y) -L_OBJS += dlci.o -else - ifeq ($(CONFIG_DLCI),m) - M_OBJS += dlci.o - endif -endif - ifeq ($(CONFIG_ARIADNE),y) L_OBJS += ariadne.o else @@ -1128,68 +1035,6 @@ else endif endif -ifeq ($(CONFIG_ADAPTEC_STARFIRE),y) -L_OBJS += starfire.o -else - ifeq ($(CONFIG_ADAPTEC_STARFIRE),m) - M_OBJS += starfire.o - endif -endif - -ifeq ($(CONFIG_VENDOR_SANGOMA),y) - LX_OBJS += sdladrv.o - L_OBJS += sdlamain.o - ifeq ($(CONFIG_WANPIPE_X25),y) - L_OBJS += sdla_x25.o - endif - ifeq ($(CONFIG_WANPIPE_FR),y) - L_OBJS += sdla_fr.o - endif - ifeq ($(CONFIG_WANPIPE_PPP),y) - L_OBJS += sdla_ppp.o - endif -endif - -ifeq ($(CONFIG_VENDOR_SANGOMA),m) - MX_OBJS += sdladrv.o - M_OBJS += wanpipe.o - WANPIPE_OBJS = sdlamain.o - ifeq ($(CONFIG_WANPIPE_X25),y) - WANPIPE_OBJS += sdla_x25.o - endif - ifeq ($(CONFIG_WANPIPE_FR),y) - WANPIPE_OBJS += sdla_fr.o - endif - ifeq ($(CONFIG_WANPIPE_PPP),y) - WANPIPE_OBJS += sdla_ppp.o - endif -endif - -ifeq ($(CONFIG_CYCLADES_SYNC),y) - LX_OBJS += cycx_drv.o - L_OBJS += cycx_main.o - ifeq ($(CONFIG_CYCLOMX_X25),y) - L_OBJS += cycx_x25.o - endif -endif - -ifeq ($(CONFIG_CYCLADES_SYNC),m) - MX_OBJS += cycx_drv.o - M_OBJS += cyclomx.o - CYCLOMX_OBJS = cycx_main.o - ifeq ($(CONFIG_CYCLOMX_X25),y) - CYCLOMX_OBJS += cycx_x25.o - endif -endif - -ifeq ($(CONFIG_X25_ASY),y) -L_OBJS += x25_asy.o -else - ifeq ($(CONFIG_X25_ASY),m) - M_OBJS += x25_asy.o - endif -endif - # # HIPPI adapters # @@ -1211,6 +1056,24 @@ else endif endif +ifeq ($(CONFIG_TR),y) +SUB_DIRS += tokenring +MOD_IN_SUB_DIRS += tokenring +else + ifeq ($(CONFIG_TR),m) + MOD_IN_SUB_DIRS += tokenring + endif +endif + +ifeq ($(CONFIG_WAN),y) +SUB_DIRS += wan +MOD_IN_SUB_DIRS += wan +else + ifeq ($(CONFIG_WAN),m) + MOD_IN_SUB_DIRS += wan + endif +endif + ifeq ($(CONFIG_NET_FC),y) SUB_DIRS += fc MOD_IN_SUB_DIRS += fc @@ -1225,11 +1088,5 @@ include $(TOPDIR)/Rules.make clean: rm -f core *.o *.a *.s -wanpipe.o: $(WANPIPE_OBJS) - ld -r -o $@ $(WANPIPE_OBJS) - -cyclomx.o: $(CYCLOMX_OBJS) - ld -r -o $@ $(CYCLOMX_OBJS) - rcpci.o: rcpci45.o rclanmtl.o $(LD) -r -o rcpci.o rcpci45.o rclanmtl.o diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 27c431e14804..a10d519f5813 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -12,6 +12,8 @@ * Donald J. Becker, * * Changelog: + * Arnaldo Carvalho de Melo - 09/1999 + * - fix sbni: s/device/net_device/ * Paul Gortmaker (06/98): * - sort probes in a sane way, make sure all (safe) probes * get run once & failed autoprobes don't autoprobe again. @@ -104,6 +106,7 @@ extern int pamsnet_probe(struct net_device *); extern int tlan_probe(struct net_device *); extern int mace_probe(struct net_device *); extern int bmac_probe(struct net_device *); +extern int ncr885e_probe(struct net_device *); extern int cs89x0_probe(struct net_device *dev); extern int ethertap_probe(struct net_device *dev); extern int ether1_probe (struct net_device *dev); @@ -118,11 +121,12 @@ extern int bagetlance_probe(struct net_device *); extern int dec_lance_probe(struct net_device *); extern int mvme147lance_probe(struct net_device *dev); extern int via_rhine_probe(struct net_device *dev); -extern int starfire_probe(struct net_device *dev); extern int tc515_probe(struct net_device *dev); extern int lance_probe(struct net_device *dev); +extern int starfire_probe(struct net_device *dev); extern int rcpci_probe(struct net_device *); extern int mac_onboard_sonic_probe(struct net_device *dev); +extern int dmfe_reg_board(struct net_device *); /* Gigabit Ethernet adapters */ extern int yellowfin_probe(struct net_device *dev); @@ -143,6 +147,9 @@ extern int rr_hippi_probe(struct net_device *); /* Fibre Channel adapters */ extern int iph5526_probe(struct net_device *dev); +/* SBNI adapters */ +extern int sbni_probe(struct net_device *); + struct devprobe { int (*probe)(struct net_device *dev); @@ -216,6 +223,11 @@ struct devprobe pci_probes[] __initdata = { #ifdef CONFIG_SIS900 {sis900_probe, 0}, #endif + +#ifdef CONFIG_DM9102 + {dmfe_reg_board, 0}, +#endif + #ifdef CONFIG_YELLOWFIN {yellowfin_probe, 0}, #endif @@ -293,10 +305,10 @@ struct devprobe mca_probes[] __initdata = { /* * ISA probes that touch addresses < 0x400 (including those that also - * look for EISA/PCI cards in addition to ISA cards). + * look for EISA/PCI/MCA cards in addition to ISA cards). */ struct devprobe isa_probes[] __initdata = { -#ifdef CONFIG_EL3 /* ISA, EISA (MCA someday) 3c5x9 */ +#ifdef CONFIG_EL3 /* ISA, EISA, MCA 3c5x9 */ {el3_probe, 0}, #endif #ifdef CONFIG_HP100 /* ISA, EISA & PCI */ @@ -457,6 +469,9 @@ struct devprobe ppc_probes[] __initdata = { #endif #ifdef CONFIG_BMAC {bmac_probe, 0}, +#endif +#ifdef CONFIG_NCR885E + {ncr885e_probe, 0}, #endif {NULL, 0}, }; @@ -781,6 +796,7 @@ struct net_device eql_dev = { /* Token-ring device probe */ extern int ibmtr_probe(struct net_device *); extern int olympic_probe(struct net_device *); +extern int sktr_probe(struct net_device *); static int trif_probe(struct net_device *dev) @@ -876,6 +892,29 @@ static struct net_device tr0_dev = { # undef NEXT_DEV # define NEXT_DEV (&fc0_dev) #endif + + +#ifdef CONFIG_SBNI + static struct net_device sbni7_dev = + {"sbni7", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, sbni_probe}; + static struct net_device sbni6_dev = + {"sbni6", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni7_dev, sbni_probe}; + static struct net_device sbni5_dev = + {"sbni5", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni6_dev, sbni_probe}; + static struct net_device sbni4_dev = + {"sbni4", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni5_dev, sbni_probe}; + static struct net_device sbni3_dev = + {"sbni3", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni4_dev, sbni_probe}; + static struct net_device sbni2_dev = + {"sbni2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni3_dev, sbni_probe}; + static struct net_device sbni1_dev = + {"sbni1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni2_dev, sbni_probe}; + static struct net_device sbni0_dev = + {"sbni0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &sbni1_dev, sbni_probe}; + +#undef NEXT_DEV +#define NEXT_DEV (&sbni0_dev) +#endif #ifdef CONFIG_NET_SB1000 diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index d8bddd665b30..353b44dc8ef6 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -474,10 +474,12 @@ arcnet_open(struct net_device *dev) lp->sdev=(struct net_device *)kmalloc(sizeof(struct net_device)+10,GFP_KERNEL); if(lp->sdev == NULL) { +#ifdef CONFIG_ARCNET_ETH if(lp->edev) kfree(lp->edev); lp->edev=NULL; return -ENOMEM; +#endif } memcpy(lp->sdev,dev,sizeof(struct net_device)); lp->sdev->name=(char *)(lp+1); diff --git a/drivers/net/ncr885_debug.h b/drivers/net/ncr885_debug.h new file mode 100644 index 000000000000..bd1fead2dfa5 --- /dev/null +++ b/drivers/net/ncr885_debug.h @@ -0,0 +1,54 @@ +#ifndef _H_NCR885_DEBUG +#define _H_NCR885_DEBUG + +struct ncr885e_regs { + unsigned long tx_status; + unsigned long rx_status; + unsigned long mac_config; + unsigned long tx_control; + unsigned long rx_control; + unsigned long tx_cmd_ptr; + unsigned long rx_cmd_ptr; + unsigned long int_status; +}; + +#ifndef __KERNEL__ + +struct ncr885e_private { + + struct dbdma_cmd *head; + struct dbdma_cmd *tx_cmds; + struct dbdma_cmd *rx_cmds; + struct dbdma_cmd *stop_cmd; + + struct sk_buff *tx_skbufs[NR_TX_RING]; + struct sk_buff *rx_skbufs[NR_RX_RING]; + + int rx_current; + int rx_dirty; + + int tx_dirty; + int tx_current; + + unsigned short tx_status[NR_TX_RING]; + + unsigned char tx_fullup; + unsigned char tx_active; + + struct net_device_stats stats; + + struct device *dev; + + struct timer_list tx_timeout; + int timeout_active; + + spinlock_t lock; +}; + +#endif /* __KERNEL__ */ + + +#define NCR885E_GET_PRIV _IOR('N',1,sizeof( struct ncr885e_private )) +#define NCR885E_GET_REGS _IOR('N',2,sizeof( struct ncr885e_regs )) + +#endif diff --git a/drivers/net/ncr885e.c b/drivers/net/ncr885e.c new file mode 100644 index 000000000000..277f92520c71 --- /dev/null +++ b/drivers/net/ncr885e.c @@ -0,0 +1,1458 @@ +/* + * An Ethernet driver for the dual-function NCR 53C885 SCSI/Ethernet + * controller. + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +static const char *version = +"ncr885e.c:v0.8 11/30/98 dan@synergymicro.com\n"; + +#include + +#ifdef MODULE +#ifdef MODVERSIONS +#include +#endif +#include +#include +#else +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "ncr885e.h" +#include "ncr885_debug.h" + +static const char *chipname = "ncr885e"; + +/* debugging flags */ +#if 0 +#define DEBUG_FUNC 0x0001 +#define DEBUG_PACKET 0x0002 +#define DEBUG_CMD 0x0004 +#define DEBUG_CHANNEL 0x0008 +#define DEBUG_INT 0x0010 +#define DEBUG_RX 0x0020 +#define DEBUG_TX 0x0040 +#define DEBUG_DMA 0x0080 +#define DEBUG_MAC 0x0100 +#define DEBUG_DRIVER 0x0200 +#define DEBUG_ALL 0x1fff +#endif + +#ifdef DEBUG_NCR885E +#define NCR885E_DEBUG 0 +#else +#define NCR885E_DEBUG 0 +#endif + +/* The 885's Ethernet PCI device id. */ +#ifndef PCI_DEVICE_ID_NCR_53C885_ETHERNET +#define PCI_DEVICE_ID_NCR_53C885_ETHERNET 0x0701 +#endif + +#define NR_RX_RING 8 +#define NR_TX_RING 8 +#define MAX_TX_ACTIVE (NR_TX_RING-1) +#define NCMDS_TX NR_TX_RING + +#define RX_BUFLEN (ETH_FRAME_LEN + 8) +#define TX_TIMEOUT 5*HZ + +#define NCR885E_TOTAL_SIZE 0xe0 + +#define TXSR (1<<6) /* tx: xfer status written */ +#define TXABORT (1<<7) /* tx: abort */ +#define EOP (1<<7) /* rx: end of packet written to buffer */ + +int ncr885e_debug = NCR885E_DEBUG; +static int print_version = 0; + +struct ncr885e_private { + + /* preserve a 1-1 marking with buffs */ + struct dbdma_cmd *head; + struct dbdma_cmd *tx_cmds; + struct dbdma_cmd *rx_cmds; + struct dbdma_cmd *stop_cmd; + + struct sk_buff *tx_skbufs[NR_TX_RING]; + struct sk_buff *rx_skbufs[NR_RX_RING]; + + int rx_current; + int rx_dirty; + + int tx_dirty; + int tx_current; + + unsigned short tx_status[NR_TX_RING]; + + unsigned char tx_fullup; + unsigned char tx_active; + + struct net_device_stats stats; + + struct net_device *dev; + + struct timer_list tx_timeout; + int timeout_active; + + spinlock_t lock; +}; + +#ifdef MODULE +static struct net_device *root_dev = NULL; +#endif + + +static int ncr885e_open( struct net_device *dev ); +static int ncr885e_close( struct net_device *dev ); +static void ncr885e_rx( struct net_device *dev ); +static void ncr885e_tx( struct net_device *dev ); +static int ncr885e_probe1( struct net_device *dev, unsigned long ioaddr, + unsigned char irq ); +static int ncr885e_xmit_start( struct sk_buff *skb, struct net_device *dev ); +static struct net_device_stats *ncr885e_stats( struct net_device *dev ); +static void ncr885e_set_multicast( struct net_device *dev ); +static void ncr885e_config( struct net_device *dev ); +static int ncr885e_set_address( struct net_device *dev, void *addr ); +static void ncr885e_interrupt( int irq, void *dev_id, struct pt_regs *regs ); +static void show_dbdma_cmd( volatile struct dbdma_cmd *cmd ); +#if 0 +static int read_eeprom( unsigned int ioadddr, int location ); +#endif + +#ifdef NCR885E_DEBUG_MII +static void show_mii( unsigned long ioaddr ); +static int read_mii( unsigned long ioaddr, int reg ); +static void write_mii( unsigned long ioaddr, int reg, int data ); +#endif /* NCR885E_DEBUG_MII */ + +#define TX_RESET_FLAGS (TX_CHANNEL_RUN|TX_CHANNEL_PAUSE|TX_CHANNEL_WAKE) +#define RX_RESET_FLAGS (RX_CHANNEL_RUN|RX_CHANNEL_PAUSE|RX_CHANNEL_WAKE) + + +#if 0 +static int +debug_ioctl( struct net_device *dev, struct ifreq *req, int cmd ) +{ + unsigned long ioaddr = dev->base_addr; + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + struct ncr885e_private *data; + struct ncr885e_regs *regs; + unsigned long flags; + + union { + struct ncr885e_regs dump; + struct ncr885e_private priv; + } temp; + + switch( cmd ) { + + /* dump the rx ring status */ + case NCR885E_GET_PRIV: + + data = (struct ncr885e_private *) &req->ifr_data; + + if ( verify_area(VERIFY_WRITE, &req->ifr_data, + sizeof( struct ncr885e_private ))) + return -EFAULT; + + memcpy((char *) &temp.priv, sp, sizeof( struct ncr885e_private )); + copy_to_user( data, (char *) &temp.priv, sizeof( struct ncr885e_private)); + break; + + case NCR885E_GET_REGS: + + regs = (struct ncr885e_regs *) &req->ifr_data; + + if ( verify_area( VERIFY_WRITE, &req->ifr_data, + sizeof( struct ncr885e_regs ))) + return -EFAULT; + + spin_lock_irqsave( &sp->lock, flags ); + + temp.dump.tx_status = inl( ioaddr + TX_CHANNEL_STATUS ); + temp.dump.rx_status = inl( ioaddr + RX_CHANNEL_STATUS ); + temp.dump.mac_config = inl( ioaddr + MAC_CONFIG ); + temp.dump.tx_control = inl( ioaddr + TX_CHANNEL_CONTROL ); + temp.dump.rx_control = inl( ioaddr + RX_CHANNEL_CONTROL ); + temp.dump.tx_cmd_ptr = inl( ioaddr + TX_CMD_PTR_LO ); + temp.dump.rx_cmd_ptr = inl( ioaddr + RX_CMD_PTR_LO ); + temp.dump.int_status = inl( ioaddr + INTERRUPT_STATUS_REG ); + + spin_unlock_irqrestore( &sp->lock, flags ); + copy_to_user( regs, (char *) &temp.dump, sizeof( struct ncr885e_regs )); + + break; + + default: + return -EOPNOTSUPP; + } + return 0; +} +#endif + +/* Enable interrupts on the 53C885 */ +static inline void +ncr885e_enable( struct net_device *dev ) + +{ + unsigned long ioaddr = dev->base_addr; + unsigned short reg; + + reg = inw(ioaddr + INTERRUPT_ENABLE); + outw(reg | INTERRUPT_INTE, ioaddr + INTERRUPT_ENABLE); +} + +/* Disable interrupts on the 53c885 */ +static inline void +ncr885e_disable( struct net_device *dev ) + +{ + unsigned long ioaddr = dev->base_addr; + unsigned short reg; + + reg = inw( ioaddr + INTERRUPT_ENABLE ); + outw( reg & ~INTERRUPT_INTE, ioaddr + INTERRUPT_ENABLE ); +} + + +static inline void +ncr885e_reset( struct net_device *dev ) + +{ + unsigned short reg; + unsigned long cntl; + int i; + unsigned long ioaddr = dev->base_addr; + + if (ncr885e_debug > 1) + printk( KERN_INFO "%s: Resetting 53C885...\n", dev->name ); + + /* disable interrupts on the 53C885 */ + ncr885e_disable( dev ); + + /* disable rx in the MAC */ + reg = inw( ioaddr + MAC_CONFIG ); + outw( reg & ~MAC_CONFIG_RXEN, ioaddr + MAC_CONFIG ); + + for( i=0; i < 100; i++ ) { + + if ( !(inw( ioaddr + MAC_CONFIG ) & MAC_CONFIG_RXEN )) + break; + udelay( 10 ); + } + + reg = inw( ioaddr + MAC_CONFIG ); + outw( reg | MAC_CONFIG_SRST, ioaddr + MAC_CONFIG ); + outw( reg, ioaddr + MAC_CONFIG ); + + /* disable both rx and tx DBDMA channels */ + outl( TX_DBDMA_ENABLE << 16, ioaddr + TX_CHANNEL_CONTROL ); + outl( RX_DBDMA_ENABLE << 16, ioaddr + RX_CHANNEL_CONTROL ); + + for( i=0; i < 100; i++ ) { + + if ( !(inw( ioaddr + TX_CHANNEL_STATUS ) & TX_DBDMA_ENABLE ) && + !(inw( ioaddr + RX_CHANNEL_STATUS ) & RX_DBDMA_ENABLE )) + break; + udelay( 10 ); + } + + /* perform a "software reset" */ + cntl = inl( ioaddr + DBDMA_CONTROL ); + outl( cntl | DBDMA_SRST, ioaddr + DBDMA_CONTROL ); + + for( i=0; i < 100; i++ ) { + + if ( !(inl( ioaddr + DBDMA_CONTROL ) & DBDMA_SRST )) + break; + udelay( 10 ); + } + + /* books says that a software reset should be done to the MAC, as + well. This true??? */ + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: reset complete\n", dev->name ); + +} + + +/* configure the 53C885 chip. + + The DBDMA command descriptors on the 53C885 can be programmed to + branch, interrupt or pause conditionally or always by using the + interrupt, branch and wait select registers. */ + +static void +ncr885e_config( struct net_device *dev ) + +{ + unsigned long ioaddr = dev->base_addr; + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: Configuring 53C885.\n", dev->name ); + + ncr885e_reset( dev ); + + /* The 53C885 can be programmed to perform conditional DBDMA + branches, interrupts or waits. + + Neither channel makes use of "wait", as it requires that the + DBDMA engine to be restarted. Don't go there. The rx channel + will branch upon the successful reception of a packet ('EOP' in + the xfer_status field). The branch address is to the STOP + DBDMA command descriptor, which shuts down the rx channel until + the interrupt is serviced. */ + + /* cause tx channel to stop after "status received" */ + outl( 0, ioaddr + TX_INT_SELECT ); + outl( (TX_WAIT_STAT_RECV << 16) | TX_WAIT_STAT_RECV, + ioaddr + TX_WAIT_SELECT ); + outl( 0, ioaddr + TX_BRANCH_SELECT ); + + /* cause rx channel to branch to the STOP descriptor on "End-of-Packet" */ +#if 0 + outl( (RX_INT_SELECT_EOP << 16) | RX_INT_SELECT_EOP, + ioaddr + RX_INT_SELECT ); +#else + outl( 0, ioaddr + RX_INT_SELECT ); +#endif +#if 0 + outl( 0, ioaddr + RX_WAIT_SELECT ); +#else + outl( (RX_WAIT_SELECT_EOP << 16) | RX_WAIT_SELECT_EOP, + ioaddr + RX_WAIT_SELECT ); +#endif +#if 1 + outl( 0, ioaddr + RX_BRANCH_SELECT ); +#else + outl( (RX_BRANCH_SELECT_EOP << 16) | RX_BRANCH_SELECT_EOP, + ioaddr + RX_BRANCH_SELECT ); +#endif + + /* configure DBDMA */ + outl( (DBDMA_BE | DBDMA_DPMRLE | DBDMA_TDPCE | + DBDMA_DDPE | DBDMA_TDPE | + (DBDMA_BURST_4 << DBDMA_TX_BST_SHIFT) | + (DBDMA_BURST_4 << DBDMA_RX_BST_SHIFT) | + (DBDMA_TX_ARBITRATION_DEFAULT) | + (DBDMA_RX_ARBITRATION_DEFAULT)), ioaddr + DBDMA_CONTROL ); + + outl( 0, ioaddr + TX_THRESHOLD ); + + /* disable MAC loopback */ + outl( (MAC_CONFIG_ITXA | MAC_CONFIG_RXEN | MAC_CONFIG_RETRYL | + MAC_CONFIG_PADEN | (0x18 << 16)), + ioaddr + MAC_CONFIG ); + + /* configure MAC */ + outl( (MAC_CONFIG_ITXA | MAC_CONFIG_RXEN | MAC_CONFIG_RETRYL | + MAC_CONFIG_PADEN | ( 0x18 << 16)), ioaddr + MAC_CONFIG ); + + outw( (0x1018), ioaddr + NBTOB_INTP_GAP ); + + /* clear and enable interrupts */ + inw( ioaddr + INTERRUPT_CLEAR ); + ncr885e_enable( dev ); + + /* and enable them in the chip */ + outl( (INTERRUPT_INTE|INTERRUPT_TX_MASK|INTERRUPT_RX_MASK)<<16, + ioaddr + INTERRUPT_ENABLE - 2); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: 53C885 config complete.\n", dev->name ); + + return; +} + + + +/* + transmit interrupt */ + +static void +ncr885e_tx( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + volatile struct dbdma_cmd *cp, *dp; + unsigned short txbits, xfer; + int i; + + del_timer( &sp->tx_timeout ); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: ncr885e_tx: active=%d, dirty=%d, current=%d\n", + dev->name, sp->tx_active, sp->tx_dirty, sp->tx_current ); + + sp->timeout_active = 0; + + i = sp->tx_dirty; + cp = sp->tx_cmds + (i*3); + dp = cp+1; + sp->tx_active--; + + xfer = inw( &dp->xfer_status ); + txbits = inw( &sp->tx_status[i] ); + + if (ncr885e_debug > 4) { + show_dbdma_cmd( cp ); + show_dbdma_cmd( dp ); + } + + /* get xmit result */ + txbits = inw( &sp->tx_status[i] ); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: tx xfer=%04x, txbits=%04x\n", dev->name, + xfer, txbits ); + + /* look for any channel status (?) */ + if ( xfer ) { + + dev_kfree_skb( sp->tx_skbufs[i] ); + mark_bh( NET_BH ); + + if ( txbits & TX_STATUS_TXOK ) { + sp->stats.tx_packets++; + sp->stats.tx_bytes += inw( &cp->req_count ); + } + + /* dropped packets */ + if ( txbits & (TX_STATUS_TDLC|TX_STATUS_TDEC) ) { + sp->stats.tx_dropped++; + } + + /* add the collisions */ + sp->stats.collisions += ( txbits & 0x04 ); + + } + + dev->tbusy = 0; + + return; +} + +/* rx interrupt handling */ +static void +ncr885e_rx( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + volatile struct dbdma_cmd *cp; + struct sk_buff *skb; + int i, nb; + unsigned short status; + unsigned char *data, *stats; + unsigned long rxbits, ioaddr = dev->base_addr; + + i = sp->rx_current; + cp = sp->rx_cmds + (i*2); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: ncr885e_rx dirty=%d, current=%d (cp@%p)\n", + dev->name, sp->rx_dirty, sp->rx_current, cp ); + + nb = inw( &cp->req_count ) - inw( &cp->res_count ); + status = inw( &cp->xfer_status ); + + if (ncr885e_debug > 3) + printk( KERN_INFO "%s: (rx %d) bytes=%d, xfer_status=%04x\n", + dev->name, i, nb, status ); + + if ( status ) { + + skb = sp->rx_skbufs[i]; + data = skb->data; + stats = data + nb - 3; + rxbits = (stats[0]|stats[1]<<8|stats[2]<<16); + + if (ncr885e_debug > 3) + printk( KERN_INFO " rx_bits=%06lx\n", rxbits ); + + skb->dev = dev; + skb_put( skb, nb-3 ); + skb->protocol = eth_type_trans( skb, dev ); + netif_rx( skb ); + sp->rx_skbufs[i] = 0; + + if ( rxbits & RX_STATUS_RXOK ) { + sp->stats.rx_packets++; + sp->stats.rx_bytes += nb; + } + + if ( rxbits & RX_STATUS_MCAST ) + sp->stats.multicast++; + + } + + sp->rx_dirty = sp->rx_current; + + if ( ++sp->rx_current >= NR_RX_RING ) + sp->rx_current = 0; + + /* fix up the one we just trashed */ + cp = sp->rx_cmds + (sp->rx_dirty * 2); + + skb = dev_alloc_skb( RX_BUFLEN + 2 ); + if ( skb != 0 ) { + skb_reserve( skb, 2 ); + sp->rx_skbufs[sp->rx_dirty] = skb; + } + + if (ncr885e_debug > 2) + printk( KERN_INFO "%s: ncr885e_rx: using ring index %d, filling cp @ %p\n", + dev->name, sp->rx_current, cp ); + + outw( RX_BUFLEN, &cp->req_count ); + outw( 0, &cp->res_count ); + data = skb->data; + outl( virt_to_bus( data ), &cp->phy_addr ); + outw( 0, &cp->xfer_status ); + + cp = sp->rx_cmds + (sp->rx_current * 2); + + /* restart rx DMA */ + outl( virt_to_bus( cp ), ioaddr + RX_CMD_PTR_LO ); + outl( (RX_DBDMA_ENABLE << 16)|RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + + return; +} + +static void +ncr885e_misc_ints( struct net_device *dev, unsigned short status ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + struct dbdma_cmd *cp; + unsigned long ioaddr = dev->base_addr; + + if (ncr885e_debug > 1) + printk( KERN_INFO "miscellaneous interrupt handled; status=%02x\n", + status ); + + /* various transmit errors */ + if ( status & + (INTERRUPT_PPET | INTERRUPT_PBFT | INTERRUPT_IIDT) ) { + + /* illegal instruction in tx dma */ + if ( status & INTERRUPT_IIDT ) { + + cp = (struct dbdma_cmd *) bus_to_virt( inl( ioaddr + TX_CMD_PTR_LO )); + printk( KERN_INFO "%s: tx illegal insn:\n", dev->name ); + printk( KERN_INFO " tx DBDMA - cmd = %p, status = %04x\n", + cp, inw( ioaddr + TX_CHANNEL_STATUS )); + printk( KERN_INFO " command = %04x, phy_addr=%08x, req_count=%04x\n", + inw( &cp->command ), inw( &cp->phy_addr ), inw( &cp->req_count )); + } + + if ( status & INTERRUPT_PPET ) + printk( KERN_INFO "%s: tx PCI parity error\n", dev->name ); + + if ( status & INTERRUPT_PBFT ) + printk( KERN_INFO "%s: tx PCI bus fault\n", dev->name ); + } + + /* look for rx errors */ + if ( status & + (INTERRUPT_PPER | INTERRUPT_PBFR | INTERRUPT_IIDR)) { + + /* illegal instruction in rx dma */ + if ( status & INTERRUPT_IIDR ) { +#if 0 + cmd = inl( ioaddr + RX_CMD_PTR_LO ); +#endif + printk( KERN_ERR "%s: rx illegal DMA instruction:\n", dev->name ); + printk( KERN_ERR " channel status=%04x,\n", + inl( ioaddr + RX_CHANNEL_STATUS )); +#if 0 + show_dbdma_cmd( bus_to_virt( inl( ioaddr + RX_CMD_PTR_LO ))); + printk( KERN_ERR " instr (%08x) %08x %08x %08x\n", + (int) cmd, cmd[0], cmd[1], cmd[2] ); +#endif + } + + /* PCI parity error */ + if ( status & INTERRUPT_PPER ) + printk( KERN_INFO "%s: rx PCI parity error\n", dev->name ); + + if ( status & INTERRUPT_PBFR ) + printk( KERN_INFO "%s: rx PCI bus fault\n", dev->name ); + + sp->stats.rx_errors++; + } + + if ( status & INTERRUPT_WI ) { + printk( KERN_INFO "%s: link pulse\n", dev->name ); + } + + /* bump any counters */ + + + return; +} + +static void +ncr885e_interrupt( int irq, void *dev_id, struct pt_regs *regs ) + +{ + struct net_device *dev = (struct net_device *) dev_id; + struct ncr885e_private *sp; + unsigned short status; + int ioaddr; + + if ( dev == NULL ) { + printk( KERN_ERR "symba: Interrupt IRQ %d for unknown device\n", irq ); + return; + } + + ioaddr = dev->base_addr; + sp = (struct ncr885e_private *) dev->priv; + spin_lock( &sp->lock ); + + if ( dev->interrupt ) { + printk( KERN_ERR "%s: Re-entering interrupt handler...\n", + dev->name ); + } + + dev->interrupt = 1; + status = inw( ioaddr + INTERRUPT_CLEAR ); + + if (ncr885e_debug > 2) + printk( KERN_INFO "%s: 53C885 interrupt 0x%02x\n", dev->name, status ); + + /* handle non-tx and rx interrupts first */ + if ( status & ~(INTERRUPT_DIT|INTERRUPT_DIR)) + ncr885e_misc_ints( dev, status ); + + /* look for tx interrupt: more to transmit, DBDMA stopped, or tx done */ + if ( ( status & INTERRUPT_DIT ) ) { + + if (ncr885e_debug > 2) + printk( KERN_INFO "%s: tx int; int=%02x, chan stat=%02x\n", + dev->name, status, inw( ioaddr + TX_CHANNEL_STATUS )); + + /* turn off timer */ + del_timer( &sp->tx_timeout ); + sp->timeout_active = 0; + + /* stop DMA */ + outl( TX_DBDMA_ENABLE << 16, ioaddr + TX_CHANNEL_CONTROL ); + + ncr885e_tx( dev ); + } + + if ( status & INTERRUPT_DIR ) { + + if ( ncr885e_debug > 2 ) + printk( KERN_INFO "%s: rx interrupt; int=%02x, rx channel stat=%02x\n", + dev->name, status, inw( ioaddr + RX_CHANNEL_STATUS )); + + /* stop DMA */ + outl( RX_DBDMA_ENABLE << 16, ioaddr + RX_CHANNEL_CONTROL ); + + /* and handle the interrupt */ + ncr885e_rx( dev ); + } + + dev->interrupt = 0; + spin_unlock( &sp->lock ); + + return; +} + + +/* doesn't set the address permanently, however... */ +static int +ncr885e_set_address( struct net_device *dev, void *addr ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + struct sockaddr *saddr = addr; + unsigned long flags; + unsigned short reg[3]; + unsigned char *ioaddr, *p; + int i; + + memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len ); + + p = (unsigned char *) dev->dev_addr; + printk( KERN_INFO "%s: setting new MAC address - ", dev->name ); +#if 0 + for( p = (unsigned char *) dev->dev_addr, i=0; i < 6; i++, p++ ) + printk("%c%2.2x", i ? ':' : ' ', *p ); +#endif + + + p = (unsigned char *) ® + for( i=0; i < 6; i++ ) + p[i] = dev->dev_addr[i]; + +#if 0 + printk("%s: Setting new mac address - ", dev->name ); + for( i=0; i < 6; i++ ) { + printk("%02x", i ? ':' : ' ', p[i] ); + } + + printk("\n"); +#endif + + /* stop rx for the change */ + outl( RX_DBDMA_ENABLE << 16, ioaddr + RX_CHANNEL_CONTROL ); + + spin_lock_irqsave( &sp->lock, flags ); + + ioaddr = (unsigned char *) dev->base_addr; + + for( i = 0; i < 3; i++ ) { + reg[i] = ((reg[i] & 0xff) << 8) | ((reg[i] >> 8) & 0xff); + printk("%04x ", reg[i] ); + outw( reg[i], ioaddr + STATION_ADDRESS_0 + (i*2)); + } + printk("\n"); + + spin_unlock_irqrestore( &sp->lock, flags ); + + /* restart rx */ + outl((RX_DBDMA_ENABLE << 16)|RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + + return 0; +} + +static void +ncr885e_tx_timeout( unsigned long data ) + +{ + struct net_device *dev = (struct net_device *) data; + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + unsigned long flags, ioaddr; + int i; + + save_flags( flags ); + cli(); + + ioaddr = dev->base_addr; + sp->timeout_active = 0; + i = sp->tx_dirty; + + /* if we weren't active, bail... */ + if ( sp->tx_active == 0 ) { + printk( KERN_INFO "%s: ncr885e_timeout...tx not active!\n", dev->name ); + goto out; + } + + printk( KERN_ERR "%s: 53C885 timed out. Resetting...\n", dev->name ); + + /* disable rx and tx DMA */ + outl( (TX_DBDMA_ENABLE << 16), ioaddr + TX_CHANNEL_CONTROL ); + outl( (RX_DBDMA_ENABLE << 16), ioaddr + RX_CHANNEL_CONTROL ); + + /* reset the chip */ + ncr885e_config( dev ); + ncr885e_enable( dev ); + + /* clear the wedged skb in the tx ring */ + sp->tx_active = 0; + ++sp->stats.tx_errors; + + if ( sp->tx_skbufs[i] ) { + dev_kfree_skb( sp->tx_skbufs[i] ); + sp->tx_skbufs[i] = 0; + } + + /* start anew from the beginning of the ring buffer (why not?) */ + sp->tx_current = 0; + dev->tbusy = 0; + mark_bh( NET_BH ); + + /* restart rx dma */ + outl( (RX_DBDMA_ENABLE << 16) | RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + out: + + restore_flags( flags ); +} + +static inline void +ncr885e_set_timeout( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + unsigned long flags; + + save_flags(flags); + cli(); + + if ( sp->timeout_active ) + del_timer( &sp->tx_timeout ); + + sp->tx_timeout.expires = jiffies + TX_TIMEOUT; + sp->tx_timeout.function = ncr885e_tx_timeout; + sp->tx_timeout.data = (unsigned long) dev; + add_timer( &sp->tx_timeout ); + sp->timeout_active = 1; + restore_flags( flags ); +} + + +/* + * The goal is to set up DBDMA such that the rx ring contains only + * one DMA descriptor per ring element and the tx ring has two (using + * the cool features of branch- and wait-select. However, I'm not sure + * if it's possible. For now, we plod through it with 3 descriptors + * for tx, and two for rx. + */ + +static int +ncr885e_open( struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + unsigned long ioaddr = dev->base_addr; + struct sk_buff *skb; + int i, size; + char *data; + struct dbdma_cmd *cp; + unsigned long flags; + + /* allocate enough space for the tx and rx rings and a STOP descriptor */ + size = (sizeof( struct dbdma_cmd ) * + ((NR_TX_RING * 3) + (NR_RX_RING * 2) + 1)); + + cp = kmalloc( size, GFP_KERNEL ); + + if ( cp == 0 ) { + printk( KERN_ERR "Insufficient memory (%d bytes) for DBDMA\n", size ); + return -ENOMEM; + } + + spin_lock_init( &sp->lock ); + spin_lock_irqsave( &sp->lock, flags ); + + memset((char *) cp, 0, size ); + sp->head = cp; + + sp->stop_cmd = cp; + outl( DBDMA_STOP, &cp->command ); + + sp->rx_cmds = ++cp; + + for( i = 0; i < NR_RX_RING; i++ ) { + + cp = sp->rx_cmds + (i*2); + skb = dev_alloc_skb( RX_BUFLEN + 2 ); + + /* if there is insufficient memory, make this last ring use a + static buffer and leave the loop with that skb as final one */ + if ( skb == 0 ) { + printk( KERN_ERR "%s: insufficient memory for rx ring buffer\n", + dev->name ); + break; + } + + skb_reserve( skb, 2 ); + sp->rx_skbufs[i] = skb; + data = skb->data; + + /* The DMA commands here are done such that an EOP is the only + way that we should get an interrupt. This means that we could + fill more than one skbuff before getting the interrupt at EOP. */ + + /* Handle rx DMA such that it always interrupts.... */ + outw( (INPUT_MORE|INTR_ALWAYS), &cp->command ); + outw( RX_BUFLEN, &cp->req_count ); + outw( 0, &cp->res_count ); + outl( virt_to_bus( data ), &cp->phy_addr ); + outl( virt_to_bus( sp->stop_cmd ), &cp->cmd_dep ); + outw( 0, &cp->xfer_status ); +#if 0 + printk( KERN_INFO "rx at %p\n", cp ); + show_dbdma_cmd( cp ); +#endif + ++cp; + + outw( DBDMA_STOP, &cp->command ); + + } + + /* initialize to all rx buffers are available, fill limit is the end */ + sp->rx_dirty = 0; + sp->rx_current = 0; + + /* fill the tx ring */ + sp->tx_cmds = cp+1; + + for( i = 0; i < NR_TX_RING; i++ ) { + + /* minimal setup for tx command */ + cp = sp->tx_cmds + (i*3); + outw( OUTPUT_LAST, &cp->command ); + if (ncr885e_debug > 3) { + printk( KERN_INFO "tx OUTPUT_LAST at %p\n", cp ); + show_dbdma_cmd( cp ); + } + + /* full setup for the status cmd */ + cp++; + outw( INPUT_LAST|INTR_ALWAYS|WAIT_IFCLR, &cp->command ); + outl( virt_to_bus( &sp->tx_status[i] ), &cp->phy_addr ); + outw( 2, &cp->req_count ); + if ( ncr885e_debug > 3) { + printk( KERN_INFO "tx INPUT_LAST cmd at %p\n", cp ); + show_dbdma_cmd( cp ); + } + + ++cp; + outw( DBDMA_STOP, &cp->command ); + + } +#if 0 + /* chain the last tx DMA command to the STOP cmd */ + outw((INPUT_LAST|INTR_ALWAYS|BR_ALWAYS), &cp->command ); + outl( virt_to_bus( sp->stop_cmd ), &cp->cmd_dep ); +#endif + sp->tx_active = 0; + sp->tx_current = 0; + sp->tx_dirty = 0; + + spin_unlock_irqrestore( &sp->lock, flags ); + + /* the order seems important here for some reason. If the MPIC isn't + enabled before the ethernet chip is enabled, shrapnel from the + bootloader causes us to receive interrupts even though we've not + yet enabled the tx channel. Go figure. It'd be better to configure + the chip in the probe1() routine, but then we don't see interrupts + at all. Everything looks all right on the logic analyzer, but... */ + + ncr885e_config( dev ); + + /* enable ethernet interrupts */ + if ( request_irq( dev->irq, &ncr885e_interrupt, SA_SHIRQ, chipname, dev )) { + printk( KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq ); + return -EAGAIN; + } + + (void) inw( ioaddr + INTERRUPT_CLEAR ); + + ncr885e_enable( dev ); + + /* start rx DBDMA */ + outl( virt_to_bus( sp->rx_cmds ), ioaddr + RX_CMD_PTR_LO ); + outl( (RX_DBDMA_ENABLE << 16)|RX_CHANNEL_RUN, + ioaddr + RX_CHANNEL_CONTROL ); + + dev->start = 1; + dev->tbusy = 0; + dev->interrupt = 0; + + MOD_INC_USE_COUNT; + + return 0; +} + +static int +ncr885e_xmit_start( struct sk_buff *skb, struct net_device *dev ) + +{ + struct ncr885e_private *sp = (struct ncr885e_private *) dev->priv; + volatile struct dbdma_cmd *cp, *dp; + unsigned long flags, ioaddr = dev->base_addr; + int len, next, fill, entry; + + if ( ncr885e_debug > 3) + printk( KERN_INFO "%s: xmit_start len=%d, dirty=%d, current=%d, active=%d\n", + dev->name, skb->len, sp->tx_dirty, sp->tx_current, sp->tx_active ); + + spin_lock_irqsave( &sp->lock, flags ); + + /* find the free slot in the ring buffer */ + fill = sp->tx_current; + next = fill + 1; + + if ( next >= NR_TX_RING ) + next = 0; + + /* mark ourselves as busy, even if we have too many packets waiting */ + dev->tbusy = 1; + + /* see if it's necessary to defer this packet */ + if ( sp->tx_active >= MAX_TX_ACTIVE ) { + spin_unlock_irqrestore( &sp->lock, flags ); + return -1; + } + + sp->tx_active++; /* bump "active tx" count */ + sp->tx_current = next; /* and show that we've used this buffer */ + sp->tx_dirty = fill; /* and mark this one to get picked up */ + + len = skb->len; + + if ( len > ETH_FRAME_LEN ) { + printk( KERN_DEBUG "%s: xmit frame too long (%d)\n", dev->name, len ); + len = ETH_FRAME_LEN; + } + + /* get index into the tx DBDMA chain */ + entry = fill * 3; + sp->tx_skbufs[fill] = skb; + cp = sp->tx_cmds + entry; + dp = cp + 1; + + /* update the rest of the OUTPUT_MORE descriptor */ + outw( len, &cp->req_count ); + outl( virt_to_bus( skb->data ), &cp->phy_addr ); + outw( 0, &cp->xfer_status ); + outw( 0, &cp->res_count ); + + /* and finish off the INPUT_MORE */ + outw( 0, &dp->xfer_status ); + outw( 0, &dp->res_count ); + sp->tx_status[fill] = 0; + outl( virt_to_bus( &sp->tx_status[fill] ), &dp->phy_addr ); + + if ( ncr885e_debug > 2 ) + printk(KERN_INFO "%s: xmit_start: active %d, tx_current %d, tx_dirty %d\n", + dev->name, sp->tx_active, sp->tx_current, sp->tx_dirty ); + + if ( ncr885e_debug > 4 ) { + show_dbdma_cmd( cp ); + show_dbdma_cmd( dp ); + } + + + /* restart the tx DMA engine */ + outl( virt_to_bus( cp ), ioaddr + TX_CMD_PTR_LO ); + outl( (TX_DBDMA_ENABLE << 16)|TX_CHANNEL_RUN, + ioaddr + TX_CHANNEL_CONTROL ); + + ncr885e_set_timeout( dev ); + + spin_unlock_irqrestore( &sp->lock, flags ); + dev->trans_start = jiffies; + + return 0; +} + +static int +ncr885e_close(struct net_device *dev) + +{ + int i; + struct ncr885e_private *np = (struct ncr885e_private *) dev->priv; + unsigned long ioaddr = dev->base_addr; + + dev->start = 0; + dev->tbusy = 1; + + spin_lock( &np->lock ); + + printk(KERN_INFO "%s: NCR885E Ethernet closing...\n", dev->name ); + + if (ncr885e_debug > 1) + printk(KERN_DEBUG "%s: Shutting down Ethernet chip\n", dev->name); + + ncr885e_disable(dev); + + del_timer(&np->tx_timeout); + + /* flip off rx and tx */ + outl( (RX_DBDMA_ENABLE << 16), ioaddr + RX_CHANNEL_CONTROL ); + outl( (TX_DBDMA_ENABLE << 16), ioaddr + TX_CHANNEL_CONTROL ); + + /* free up the IRQ */ + free_irq( dev->irq, dev ); + + for( i = 0; i < NR_RX_RING; i++ ) { + if (np->rx_skbufs[i]) + dev_kfree_skb( np->rx_skbufs[i] ); + np->rx_skbufs[i] = 0; + } +#if 0 + for (i = 0; i < NR_TX_RING; i++) { + if (np->tx_skbufs[i]) + dev_kfree_skb(np->tx_skbufs[i]); + np->tx_skbufs[i] = 0; + } +#endif + spin_unlock( &np->lock ); + + kfree( np->head ); + + MOD_DEC_USE_COUNT; + + return 0; +} + + +/* + * multicast promiscuous mode isn't used here. Allow code in the + * IP stack to determine which multicast packets are good or bad.... + * (this avoids having to use the hash table registers) + */ +static void +ncr885e_set_multicast( struct net_device *dev ) + +{ + int ioaddr = dev->base_addr; + + if ( ncr885e_debug > 3 ) + printk("%s: set_multicast: dev->flags = %x, AF=%04x\n", + dev->name, dev->flags, inw( ioaddr + ADDRESS_FILTER )); + + if ( dev->flags & IFF_PROMISC ) { + printk( KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name ); + outw( ADDRESS_RPPRO, ioaddr + ADDRESS_FILTER ); + } + + /* accept all multicast packets without checking the mc_list. */ + else if ( dev->flags & IFF_ALLMULTI ) { + printk( KERN_INFO "%s: Enabling all multicast packets.\n", + dev->name ); + outw( ADDRESS_RPPRM, ioaddr + ADDRESS_FILTER ); + } + + /* enable broadcast rx */ + else { + outw( ADDRESS_RPABC, ioaddr + ADDRESS_FILTER ); + } +} + +static struct net_device_stats * +ncr885e_stats( struct net_device *dev ) + +{ + struct ncr885e_private *np = (struct ncr885e_private *) dev->priv; + + return &np->stats; +} + +/* By this function, we're certain that we have a 885 Ethernet controller + * so we finish setting it up and wrap up all the required Linux ethernet + * configuration. + */ + +static int +ncr885e_probe1( struct net_device *dev, unsigned long ioaddr, unsigned char irq ) + +{ + struct ncr885e_private *sp; + unsigned short station_addr[3], val; + unsigned char *p; + int i; + + dev = init_etherdev( dev, 0 ); + + /* construct private data for the 885 ethernet */ + dev->priv = kmalloc( sizeof( struct ncr885e_private ), GFP_KERNEL ); + + if ( dev->priv == NULL ) + return -ENOMEM; + + sp = (struct ncr885e_private *) dev->priv; + memset( sp, 0, sizeof( struct ncr885e_private )); + + /* snag the station address and display it */ + for( i = 0; i < 3; i++ ) { + val = inw( ioaddr + STATION_ADDRESS_0 + (i*2)); + station_addr[i] = ((val >> 8) & 0xff) | ((val << 8) & 0xff00); + } + + printk( KERN_INFO "%s: %s at %08lx,", dev->name, chipname, ioaddr ); + + p = (unsigned char *) &station_addr; + + for( i=0; i < 6; i++ ) { + dev->dev_addr[i] = *p; + printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i] ); + p++; + } + + printk(", IRQ %d.\n", irq ); + + request_region( ioaddr, NCR885E_TOTAL_SIZE, dev->name ); + + /* set up a timer */ + init_timer( &sp->tx_timeout ); + sp->timeout_active = 0; + + dev->base_addr = ioaddr; + dev->irq = irq; + + ether_setup( dev ); + + /* everything else */ + dev->open = ncr885e_open; + dev->stop = ncr885e_close; + dev->get_stats = ncr885e_stats; + dev->hard_start_xmit = ncr885e_xmit_start; + dev->set_multicast_list = ncr885e_set_multicast; + dev->set_mac_address = ncr885e_set_address; + + return 0; +} + +/* Since the NCR 53C885 is a multi-function chip, I'm not worrying about + * trying to get the the device(s) in slot order. For our (Synergy's) + * purpose, there's just a single 53C885 on the board and we don't + * worry about the rest. + */ + +int __init ncr885e_probe( struct net_device *dev ) +{ + struct pci_dev *pdev = NULL; + unsigned int ioaddr, chips = 0; + unsigned short cmd; + unsigned char irq, latency; + + while(( pdev = pci_find_device( PCI_VENDOR_ID_NCR, + PCI_DEVICE_ID_NCR_53C885_ETHERNET, + pdev )) != NULL ) { + + if ( !print_version ) { + print_version++; + printk( KERN_INFO "%s", version ); + } + + /* Use I/O space */ + pci_read_config_dword( pdev, PCI_BASE_ADDRESS_0, &ioaddr ); + pci_read_config_byte( pdev, PCI_INTERRUPT_LINE, &irq ); + + ioaddr &= ~3; + /* Adjust around the Grackle... */ +#ifdef CONFIG_GEMINI + ioaddr |= 0xfe000000; +#endif + + if ( check_region( ioaddr, NCR885E_TOTAL_SIZE )) + continue; + + /* finish off the probe */ + if ( !(ncr885e_probe1( dev, ioaddr, irq ))) { + + chips++; + + /* Access is via I/O space, bus master enabled... */ + pci_read_config_word( pdev, PCI_COMMAND, &cmd ); + + if ( !(cmd & PCI_COMMAND_MASTER) ) { + printk( KERN_INFO " PCI master bit not set! Now setting.\n"); + cmd |= PCI_COMMAND_MASTER; + pci_write_config_word( pdev, PCI_COMMAND, cmd ); + } + + if ( !(cmd & PCI_COMMAND_IO) ) { + printk( KERN_INFO " Enabling I/O space.\n" ); + cmd |= PCI_COMMAND_IO; + pci_write_config_word( pdev, PCI_COMMAND, cmd ); + } + + pci_read_config_byte( pdev, PCI_LATENCY_TIMER, &latency ); + + if ( latency < 10 ) { + printk( KERN_INFO " PCI latency timer (CFLT) is unreasonably" + " low at %d. Setting to 255.\n", latency ); + pci_write_config_byte( pdev, PCI_LATENCY_TIMER, 255 ); + } + } + } + + if ( !chips ) + return -ENODEV; + else + return 0; +} + +/* debugging to peek at dma descriptors */ +static void +show_dbdma_cmd( volatile struct dbdma_cmd *cmd ) + +{ + printk( KERN_INFO " cmd %04x, physaddr %08x, req_count %04x\n", + inw( &cmd->command ), inl( &cmd->phy_addr ), inw( &cmd->req_count )); + printk( KERN_INFO " res_count %04x, xfer_status %04x, branch %08x\n", + inw( &cmd->res_count ), inw( &cmd->xfer_status ),inl( &cmd->cmd_dep )); +} + +#if 0 +static int +read_eeprom( unsigned int ioaddr, int location ) + +{ + int loop; + unsigned char val; + + outb( (location & 0xff), ioaddr + EE_WORD_ADDR ); + + /* take spillover from location in control reg */ + outb(EE_CONTROL_RND_READB | (location & (0x7<<8)), ioaddr + EE_CONTROL); + + loop = 1000; + while( (inb( ioaddr + EE_STATUS) & EE_SEB) && + (loop > 0) ) { + udelay( 10 ); + loop--; + } + + if ( inb( ioaddr + EE_STATUS ) & EE_SEE ) { + printk("%s: Serial EEPROM read error\n", chipname); + val = 0xff; + } + + else + val = inb( ioaddr + EE_READ_DATA ); + + return (int) val; +} +#endif + +#ifdef NCR885E_DEBUG_MII +static void +show_mii( unsigned long ioaddr ) + +{ + int phyctrl, phystat, phyadvert, phypartner, phyexpan; + + phyctrl = read_mii( ioaddr, MII_AUTO_NEGOTIATION_CONTROL ); + phystat = read_mii( ioaddr, MII_AUTO_NEGOTIATION_STATUS ); + phyadvert = read_mii( ioaddr, MII_AUTO_NEGOTIATION_ADVERTISEMENT ); + phypartner = read_mii( ioaddr, MII_AUTO_NEGOTIATION_LINK_PARTNER ); + phyexpan = read_mii( ioaddr, MII_AUTO_NEGOTIATION_EXPANSION ); + + printk( KERN_INFO "PHY: advert=%d %s, partner=%s %s, link=%d, %s%s\n", + (phyadvert & MANATECH_100BASETX_FULL_DUPLEX ? 100 : 10), + (phyctrl & MANC_AUTO_NEGOTIATION_ENABLE ? "auto" : "fixed"), + (phypartner & MANLP_ACKNOWLEDGE ? + (phypartner & MANATECH_100BASETX_FULL_DUPLEX ? "100" : "10") : + "?"), + (phyexpan & MANE_LINK_PARTNER_AUTO_ABLE ? "auto" : "fixed"), + (phyctrl & MANC_PHY_SPEED_100 ? 100 : 10), + (phystat & MANS_LINK_STATUS ? "up" : "down"), + (phyexpan & MANE_PARALLEL_DETECTION_FAULT ? " PD-fault" : "" )); + return; +} + + +static int +read_mii( unsigned long ioaddr, int reg ) + +{ + int timeout; + + + timeout = 100000; + + while( inw( ioaddr + MII_INDICATOR ) & MII_BUSY ) { + + if ( timeout-- < 0 ) { + printk( KERN_INFO "Timed out waiting for MII\n" ); + return -1; + } + } + + outw( (1<<8) + reg, ioaddr + MII_ADDRESS ); + outw( MIIM_RSTAT, ioaddr + MIIM_COMMAND ); + + timeout = 100000; + while( inw( ioaddr + MII_INDICATOR ) & MII_BUSY ) { + if ( timeout-- < 0 ) { + printk( KERN_INFO "Timed out waiting for MII\n" ); + return -1; + } + } + + return( inw( ioaddr + MII_READ_DATA )); +} + +static void +write_mii( unsigned long ioaddr, int reg, int data ) + +{ + int timeout=100000; + + printk( KERN_INFO "MII indicator: %02x\n", inw( ioaddr + MII_INDICATOR )); + + while( inw( ioaddr + MII_INDICATOR ) & MII_BUSY ) { + if ( timeout-- <= 0 ) { + printk( KERN_INFO "Timeout waiting to write to MII\n" ); + return; + } + udelay( 10 ); + } + + outw( (1<<8) + reg, ioaddr + MII_ADDRESS ); + outw( data, ioaddr + MII_WRITE_DATA ); + + return; +} + +#endif /* NCR885E_DEBUG_MII */ + +#ifdef MODULE +#if defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x20118 +MODULE_AUTHOR("dan@synergymicro.com"); +MODULE_DESCRIPTION("Symbios 53C885 Ethernet driver"); +MODULE_PARM(debug, "i"); +#endif + +static int debug = 1; + +int +init_module(void) +{ + if ( debug >= 0) + ncr885e_debug = debug; + + return ncr885e_probe( NULL ); +} + +void +cleanup_module(void) +{ + struct ncr885e_private *np; + + if ( root_dev ) { + + unregister_netdev( root_dev ); + np = (struct ncr885e_private *) root_dev->priv; + release_region( root_dev->base_addr, NCR885E_TOTAL_SIZE ); + kfree( root_dev->priv ); + root_dev = NULL; + } +} +#endif /* MODULE */ + +/* + * Local variables: + * compile-command: "gcc -DMODULE -DMODVERSIONS -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O6 -c symba.c" + * End: + */ diff --git a/drivers/net/ncr885e.h b/drivers/net/ncr885e.h new file mode 100644 index 000000000000..bbcc82e11778 --- /dev/null +++ b/drivers/net/ncr885e.h @@ -0,0 +1,367 @@ +#ifndef _NET_H_SYMBA +#define _NET_H_SYMBA + +/* transmit status bit definitions */ +#define TX_STATUS_TXOK (1<<13) /* success */ +#define TX_STATUS_TDLC (1<<12) /* dropped for late colls */ +#define TX_STATUS_TCXSDFR (1<<11) /* excessive deferral */ +#define TX_STATUS_TDEC (1<<10) /* excessive collisions */ +#define TX_STATUS_TAUR (1<<9) /* abort on underrun/"jumbo" */ +#define TX_STATUS_PDFRD (1<<8) /* packet deferred */ +#define TX_STATUS_BCAST (1<<7) /* broadcast ok */ +#define TX_STATUS_MCAST (1<<6) /* multicast ok */ +#define TX_STATUS_CRCERR (1<<5) /* CRC error */ +#define TX_STATUS_LC (1<<4) /* late collision */ +#define TX_STATUS_CCNT_MASK 0xf /* collision count */ + +#define T_TXOK (1<<13) +#define T_TDLC (1<<12) +#define T_TCXSDFR (1<<11) +#define T_TDEC (1<<10) +#define T_TAUR (1<<9) +#define T_PDFRD (1<<8) +#define T_BCAST (1<<7) +#define T_MCAST (1<<6) +#define T_LC (1<<4) +#define T_CCNT_MASK 0xf + +/* receive status bit definitions */ +#define RX_STATUS_RXOVRN (1<<23) /* overrun */ +#define RX_STATUS_CEPS (1<<22) /* carrier event already seen */ +#define RX_STATUS_RXOK (1<<21) /* success */ +#define RX_STATUS_BCAST (1<<20) /* broadcast ok */ +#define RX_STATUS_MCAST (1<<19) /* multicast ok */ +#define RX_STATUS_CRCERR (1<<18) /* CRC error */ +#define RX_STATUS_DR (1<<17) /* dribble nibble */ +#define RX_STATUS_RCV (1<<16) /* rx code violation */ +#define RX_STATUS_PTL (1<<15) /* pkt > 1518 bytes */ +#define RX_STATUS_PTS (1<<14) /* pkt < 64 bytes */ +#define RX_STATUS_LEN_MASK 0x1fff /* length mask */ + +#define EEPROM_LENGTH 100 + + +/* Serial EEPROM interface */ +#define EE_STATUS 0xf0 +#define EE_CONTROL 0xf1 +#define EE_WORD_ADDR 0xf2 +#define EE_READ_DATA 0xf3 +#define EE_WRITE_DATA 0xf4 +#define EE_FEATURE_ENB 0xf5 + +/* Use on EE_STATUS */ +#define EE_SEB (1<<8) +#define EE_SEE 1 + +/* Serial EEPROM commands */ +#define EE_CONTROL_SEQ_READB (1<<4) +#define EE_CONTROL_RND_WRITEB (1<<5) +#define EE_CONTROL_RND_READB ((1<<4)|(1<<5)) + +/* Enable writing to serial EEPROM */ +#define EE_WRITE_ENB 1 + +/* The 885 configuration register */ +#define MAC_CONFIG 0xa0 +#define MAC_CONFIG_SRST 1<<15 +#define MAC_CONFIG_ITXA 1<<13 +#define MAC_CONFIG_RXEN 1<<12 +#define MAC_CONFIG_INTLB 1<<10 +#define MAC_CONFIG_MODE_MASK (1<<8|1<<9) +#define MAC_CONFIG_MODE_TP 1<<8 +#define MAC_CONFIG_HUGEN 1<<5 +#define MAC_CONFIG_RETRYL 1<<4 +#define MAC_CONFIG_CRCEN 1<<3 +#define MAC_CONFIG_PADEN 1<<2 +#define MAC_CONFIG_FULLD 1<<1 +#define MAC_CONFIG_NOCFR 1<<0 + + + + + +#define TX_WAIT_SELECT 0x18 +#define RX_CHANNEL_CONTROL 0x40 + +/* Tx channel status */ +#define TX_DBDMA_REG 0x00 +#define TX_CHANNEL_CONTROL 0x00 +#define TX_CHANNEL_STATUS 0x04 +#define TX_STATUS_RUN 1<<15 +#define TX_STATUS_PAUSE 1<<14 +#define TX_STATUS_WAKE 1<<12 +#define TX_STATUS_DEAD 1<<11 +#define TX_STATUS_ACTIVE 1<<10 +#define TX_STATUS_BT 1<<8 +#define TX_STATUS_TXABORT 1<<7 +#define TX_STATUS_TXSR 1<<6 + +#define TX_CHANNEL_RUN TX_STATUS_RUN +#define TX_CHANNEL_PAUSE TX_STATUS_PAUSE +#define TX_CHANNEL_WAKE TX_STATUS_WAKE +#define TX_CHANNEL_DEAD TX_STATUS_DEAD +#define TX_CHANNEL_ACTIVE TX_STATUS_ACTIVE +#define TX_CHANNEL_BT TX_STATUS_BT +#define TX_CHANNEL_TXABORT TX_STATUS_TXABORT +#define TX_CHANNEL_TXSR TX_STATUS_TXSR + +#define TX_DBDMA_ENABLE (TX_CHANNEL_WAKE | TX_CHANNEL_PAUSE | \ + TX_CHANNEL_RUN ) + +/* Transmit command ptr lo register */ +#define TX_CMD_PTR_LO 0x0c + +/* Transmit interrupt select register */ +#define TX_INT_SELECT 0x10 + +/* Transmit branch select register */ +#define TX_BRANCH_SELECT 0x14 + +/* Transmit wait select register */ +#define TX_WAIT_SELECT 0x18 +#define TX_WAIT_STAT_RECV 0x40 + +/* Rx channel status */ +#define RX_DBDMA_REG 0x40 +#define RX_CHANNEL_CONTROL 0x40 +#define RX_CHANNEL_STATUS 0x44 +#define RX_STATUS_RUN 1<<15 +#define RX_STATUS_PAUSE 1<<14 +#define RX_STATUS_WAKE 1<<12 +#define RX_STATUS_DEAD 1<<11 +#define RX_STATUS_ACTIVE 1<<10 +#define RX_STATUS_BT 1<<8 +#define RX_STATUS_EOP 1<<6 + +#define RX_CHANNEL_RUN RX_STATUS_RUN +#define RX_CHANNEL_PAUSE RX_STATUS_PAUSE +#define RX_CHANNEL_WAKE RX_STATUS_WAKE +#define RX_CHANNEL_DEAD RX_STATUS_DEAD +#define RX_CHANNEL_ACTIVE RX_STATUS_ACTIVE +#define RX_CHANNEL_BT RX_STATUS_BT +#define RX_CHANNEL_EOP RX_STATUS_EOP + +#define RX_DBDMA_ENABLE (RX_CHANNEL_WAKE | RX_CHANNEL_PAUSE | \ + RX_CHANNEL_RUN) + +/* Receive command ptr lo */ +#define RX_CMD_PTR_LO 0x4c + +/* Receive interrupt select register */ +#define RX_INT_SELECT 0x50 +#define RX_INT_SELECT_EOP 0x40 + +/* Receive branch select */ +#define RX_BRANCH_SELECT 0x54 +#define RX_BRANCH_SELECT_EOP 0x40 + +/* Receive wait select */ +#define RX_WAIT_SELECT 0x58 +#define RX_WAIT_SELECT_EOP 0x40 + +/* Event status register */ +#define EVENT_STATUS 0x80 +#define EVENT_TXSR 1<<2 +#define EVENT_EOP 1<<1 +#define EVENT_TXABORT 1<<0 + +/* Interrupt enable register */ +#define INTERRUPT_ENABLE 0x82 + +/* Interrupt clear register */ +#define INTERRUPT_CLEAR 0x84 + +/* Interrupt status register */ +#define INTERRUPT_STATUS_REG 0x86 + +/* bits for the above three interrupt registers */ +#define INTERRUPT_INTE 1<<15 /* interrupt enable */ +#define INTERRUPT_WI 1<<9 /* wakeup interrupt */ +#define INTERRUPT_ERI 1<<8 /* early recieve interrupt */ +#define INTERRUPT_PPET 1<<7 /* PCI Tx parity error */ +#define INTERRUPT_PBFT 1<<6 /* PCI Tx bus fault */ +#define INTERRUPT_IIDT 1<<5 /* illegal instruction Tx */ +#define INTERRUPT_DIT 1<<4 /* DBDMA Tx interrupt */ +#define INTERRUPT_PPER 1<<3 /* PCI Rx parity error */ +#define INTERRUPT_PBFR 1<<2 /* PCI Rx bus fault */ +#define INTERRUPT_IIDR 1<<1 /* illegal instruction Rx */ +#define INTERRUPT_DIR 1<<0 /* DBDMA Rx interrupt */ + +#define INTERRUPT_TX_MASK (INTERRUPT_PBFT|INTERRUPT_IIDT| \ + INTERRUPT_PPET|INTERRUPT_DIT) +#define INTERRUPT_RX_MASK (INTERRUPT_PBFR|INTERRUPT_IIDR| \ + INTERRUPT_PPER|INTERRUPT_DIR) + +/* chip revision register */ +#define CHIP_REVISION_REG 0x8c +#define CHIP_PCIREV_MASK (0xf<<16) +#define CHIP_PCIDEV_MASK 0xff + +/* Tx threshold register */ +#define TX_THRESHOLD 0x94 + +/* General purpose register */ +#define GEN_PURPOSE_REG 0x9e + +/* General purpose pin control reg */ +#define GEN_PIN_CONTROL_REG 0x9f + +/* DBDMA control register */ +#define DBDMA_CONTROL 0x90 +#define DBDMA_SRST 1<<31 +#define DBDMA_TDPCE 1<<23 +#define DBDMA_BE 1<<22 +#define DBDMA_TAP_MASK (1<<19|1<<20|1<<21) +#define DBDMA_RAP_MASK (1<<16|1<<17|1<<18) +#define DBDMA_DPMRLE 1<<15 +#define DBDMA_WIE 1<<14 +#define DBDMA_MP 1<<13 +#define DBDMA_SME 1<<12 +#define DBDMA_CME 1<<11 +#define DBDMA_DDPE 1<<10 +#define DBDMA_TDPE 1<<9 +#define DBDMA_EXTE 1<<8 +#define DBDMA_BST_MASK (1<<4|1<<5|1<<6) +#define DBDMA_BSR_MASK (1<<0|1<<1|1<<2) + +#define DBDMA_BURST_1 (0x00) +#define DBDMA_BURST_2 (0x01) +#define DBDMA_BURST_4 (0x02) +#define DBDMA_BURST_8 (0x03) +#define DBDMA_BURST_16 (0x04) +#define DBDMA_BURST_32 (0x05) +#define DBDMA_BURST_64 (0x06) +#define DBDMA_BURST_128 (0x07) + +#define DBDMA_TX_BST_SHIFT (4) +#define DBDMA_RX_BST_SHIFT (0) + +#define DBDMA_TX_ARBITRATION_DEFAULT ( 1 << 19 ) +#define DBDMA_RX_ARBITRATION_DEFAULT ( 2 << 16 ) + + +/* Back-to-back interpacket gap register */ +#define BTOB_INTP_GAP 0xa2 +#define BTOB_INTP_DEFAULT 0x18 + +/* Non-back-to-back interpacket gap register */ +#define NBTOB_INTP_GAP 0xa4 + +/* MIIM command register */ +#define MIIM_COMMAND 0xa6 +#define MIIM_SCAN 1<<1 +#define MIIM_RSTAT 1<<0 + +/* MII address register */ +#define MII_ADDRESS 0xa8 +#define MII_FIAD_MASK (1<<8|1<<9|1<<10|1<<11|1<<12) +#define MII_RGAD_MASK (1<<0|1<<1|1<<2|1<<3|1<<4) + +#define TPPMD_CONTROL_REG 0xa8 +#define TPPMD_FO 1<<1 +#define TPPMD_LB 1<<0 + +/* MII read and write registers */ +#define MII_WRITE_DATA 0xaa +#define MII_READ_DATA 0xac + +/* MII indicators */ +#define MII_INDICATOR 0xae +#define MII_NVALID 1<<2 +#define MII_SCAN 1<<1 +#define MII_BUSY 1<<0 + +/* Address filter */ +#define ADDRESS_FILTER 0xd0 +#define ADDRESS_RPPRM 1<<3 /* multicast promis. mode */ +#define ADDRESS_RPPRO 1<<2 /* promiscuous mode */ +#define ADDRESS_RPAMC 1<<1 /* accept multicasts */ +#define ADDRESS_RPABC 1<<0 /* accept broadcasts */ + +/* Station addresses + + Note that if the serial EEPROM is disabled, these values are all + zero. If, like us, you get the chips when they're fresh, they're + also zero and you have to initialize the address */ +#define STATION_ADDRESS_0 0xd2 +#define STATION_ADDRESS_1 0xd4 +#define STATION_ADDRESS_2 0xd6 + +/* Hash tables */ +#define HASH_TABLE_0 0xd8 +#define HASH_TABLE_1 0xda +#define HASH_TABLE_2 0xdc +#define HASH_TABLE_3 0xde + +/* PHY indentifiers */ +#define PHY_IDENTIFIER_0 0xe4 +#define PHY_IDENTIFIER_1 0xe6 + +/* MII Auto-negotiation register definitions */ + +#define MII_AUTO_NEGOTIATION_CONTROL (0x0000) +#define MANC_PHY_RESET (0x8000) +#define MANC_PHY_LOOPBACK_ENABLE (0x4000) +#define MANC_PHY_LOOPBACK_DISABLE (0x0000) +#define MANC_PHY_SPEED_100 (0x2000) +#define MANC_PHY_SPEED_10 (0x0000) +#define MANC_AUTO_NEGOTIATION_ENABLE (0x1000) +#define MANC_AUTO_NEGOTIATION_DISABLE (0x0000) +#define MANC_PHY_POWER_DOWN (0x0800) +#define MANC_PHY_POWER_UP (0x0000) +#define MANC_ISOLATE_ENABLE (0x0400) +#define MANC_ISOLATE_DISABLE (0x0000) +#define MANC_RESTART_AUTO_NEGOTIATION (0x0200) +#define MANC_FULL_DUPLEX (0x0100) +#define MANC_HALF_DUPLEX (0x0000) + +#define MII_AUTO_NEGOTIATION_STATUS (0x0001) +#define MANS_100BASE_T4_HALF_DUPLEX (0x8000) +#define MANS_100BASE_X_FULL_DUPLEX (0x4000) +#define MANS_100BASE_X_HALF_DUPLEX (0x2000) +#define MANS_10MBS_FULL_DUPLEX (0x1000) +#define MANS_10MBS_HALF_DUPLEX (0x0800) +#define MANS_AUTO_NEGOTIATION_COMPLETE (0x0020) +#define MANS_REMOTE_FAULT (0x0010) +#define MANS_AUTO_NEGOTIATION_ABILITY (0x0008) +#define MANS_LINK_STATUS (0x0004) +#define MANS_JABBER_DETECT (0x0002) +#define MANS_EXTENDED_CAPABILITY (0x0001) + +#define MII_PHY_IDENTIFIER_1 (0x0002) +#define MII_PHY_IDENTIFIER_2 (0x0003) + +#define MII_AUTO_NEGOTIATION_ADVERTISEMENT (0x0004) +#define MANA_NEXT_PAGE (0x8000) +#define MANA_REMOTE_FAULT (0x2000) +#define MANA_TECHNOLOGY_ABILITY_MASK (0x1FE0) +#define MANATECH_10BASET_HALF_DUPLEX (0x0020) +#define MANATECH_10BASET_FULL_DUPLEX (0x0040) +#define MANATECH_100BASETX_HALF_DUPLEX (0x0080) +#define MANATECH_100BASETX_FULL_DUPLEX (0x0100) +#define MANATECH_100BASET4 (0x0200) +#define MANA_SELECTOR_MASK (0x001F) +#define MANASELECTOR_802_3 (0x0001) + +#define MII_AUTO_NEGOTIATION_LINK_PARTNER (0x0005) +#define MANLP_NEXT_PAGE (0x8000) +#define MANLP_ACKNOWLEDGE (0x4000) +#define MANLP_REMOTE_FAULT (0x2000) +#define MANLP_TECHNOLOGY_ABILITY_MASK (0x1FE0) +#define MANLP_SELECTOR_MASK (0x001F) + +#define MII_AUTO_NEGOTIATION_EXPANSION (0x0006) +#define MANE_PARALLEL_DETECTION_FAULT (0x0010) +#define MANE_LINK_PARTNER_NEXT_PAGE_ABLE (0x0008) +#define MANE_NEXT_PAGE_ABLE (0x0004) +#define MANE_PAGE_RECEIVED (0x0002) +#define MANE_LINK_PARTNER_AUTO_ABLE (0x0001) + +#define MII_AUTO_NEGOTIATION_NEXT_PAGE_TRANSMIT (0x0007) +#define MANNPT_NEXT_PAGE (0x8000) +#define MANNPT_MESSAGE_PAGE (0x2000) +#define MANNPT_ACKNOWLEDGE_2 (0x1000) +#define MANNPT_TOGGLE (0x0800) +#define MANNPT_MESSAGE_FIELD_MASK (0x07FF) + +#endif diff --git a/drivers/net/sgiseeq.h b/drivers/net/sgiseeq.h index 4f684f5a1526..72dcedf3fb1f 100644 --- a/drivers/net/sgiseeq.h +++ b/drivers/net/sgiseeq.h @@ -1,4 +1,4 @@ -/* $Id: sgiseeq.h,v 1.1 1997/06/09 08:34:32 ralf Exp $ +/* $Id: sgiseeq.h,v 1.3 1998/08/25 09:17:45 ralf Exp $ * sgiseeq.h: Defines for the Seeq8003 ethernet controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c index c112489584a0..cdee2d6e6886 100644 --- a/drivers/net/sk_mca.c +++ b/drivers/net/sk_mca.c @@ -71,6 +71,7 @@ History: #include #include +#include #include #include #include diff --git a/drivers/net/tokenring/Config.in b/drivers/net/tokenring/Config.in new file mode 100644 index 000000000000..8b3065c8abe8 --- /dev/null +++ b/drivers/net/tokenring/Config.in @@ -0,0 +1,15 @@ +# +# Token Ring driver configuration +# + +mainmenu_option next_comment +comment 'Token Ring driver support' + +bool 'Token Ring driver support' CONFIG_TR +if [ "$CONFIG_TR" = "y" ]; then + tristate ' IBM Tropic chipset based adapter support' CONFIG_IBMTR + tristate ' IBM Olympic chipset PCI adapter support' CONFIG_IBMOL + tristate ' SysKonnect adapter support' CONFIG_SKTR +fi + +endmenu diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile new file mode 100644 index 000000000000..038c58b865b1 --- /dev/null +++ b/drivers/net/tokenring/Makefile @@ -0,0 +1,51 @@ +# +# Makefile for drivers/net/tokenring +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now inherited from the +# parent makefile. +# + +# +# Note : at this point, these files are compiled on all systems. +# In the future, some of these should be built conditionally. +# + +SUB_DIRS := +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) + + +L_TARGET := tr.a +L_OBJS := +M_OBJS := + +ifeq ($(CONFIG_IBMTR),y) + L_OBJS += ibmtr.o +else + ifeq ($(CONFIG_IBMTR),m) + M_OBJS += ibmtr.o + endif +endif + +ifeq ($(CONFIG_IBMOL),y) + L_OBJS += olympic.o +else + ifeq ($(CONFIG_IBMOL),m) + M_OBJS += olympic.o + endif +endif + +ifeq ($(CONFIG_SKTR),y) + L_OBJS += sktr.o +else + ifeq ($(CONFIG_SKTR),m) + M_OBJS += sktr.o + endif +endif + +include $(TOPDIR)/Rules.make + diff --git a/drivers/net/ibmtr.c b/drivers/net/tokenring/ibmtr.c similarity index 97% rename from drivers/net/ibmtr.c rename to drivers/net/tokenring/ibmtr.c index cf2514fa60b5..85cdfb77448b 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -79,6 +79,10 @@ * * Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) : * + added spinlocks for SMP sanity (10 March 1999) + * + * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting + * i.e. using functional address C0 00 00 04 00 00 to transmit and + * receive multicast packets. */ /* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value @@ -211,6 +215,7 @@ static int tok_open(struct net_device *dev); static int tok_close(struct net_device *dev); static int tok_send_packet(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats * tok_get_stats(struct net_device *dev); +static void tok_set_multicast_list(struct net_device *dev); void ibmtr_readlog(struct net_device *dev); void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev); int ibmtr_change_mtu(struct net_device *dev, int mtu); @@ -778,7 +783,7 @@ static int __init trdev_init(struct net_device *dev) dev->stop = tok_close; dev->hard_start_xmit = tok_send_packet; dev->get_stats = tok_get_stats; - dev->set_multicast_list = NULL; + dev->set_multicast_list = tok_set_multicast_list; dev->change_mtu = ibmtr_change_mtu; #ifndef MODULE @@ -790,6 +795,43 @@ static int __init trdev_init(struct net_device *dev) } +static void tok_set_multicast_list(struct net_device *dev) +{ + struct tok_info *ti=(struct tok_info *)dev->priv; + struct dev_mc_list *mclist; + unsigned char address[4]; + + int i; + + address[0] = address[1] = address[2] = address[3] = 0; + + mclist = dev->mc_list; + for (i=0; i< dev->mc_count; i++) + { + address[0] |= mclist->dmi_addr[2]; + address[1] |= mclist->dmi_addr[3]; + address[2] |= mclist->dmi_addr[4]; + address[3] |= mclist->dmi_addr[5]; + mclist = mclist->next; + } + SET_PAGE(ti->srb); + for (i=0; isrb+i); + + writeb(DIR_SET_FUNC_ADDR, + ti->srb + offsetof(struct srb_set_funct_addr, command)); + + DPRINTK("Setting functional address: "); + + for (i=0; i<4; i++) + { + writeb(address[i], + ti->srb + offsetof(struct srb_set_funct_addr, funct_address)+i); + printk("%02X ", address[i]); + } + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + printk("\n"); +} static int tok_open(struct net_device *dev) { @@ -1621,12 +1663,10 @@ static void tr_rx(struct net_device *dev) ti->tr_stats.rx_packets++; skb->protocol = tr_type_trans(skb,dev); - - if (IPv4_p){ + if (IPv4_p){ skb->csum = chksum; skb->ip_summed = 1; } - netif_rx(skb); } diff --git a/drivers/net/ibmtr.h b/drivers/net/tokenring/ibmtr.h similarity index 99% rename from drivers/net/ibmtr.h rename to drivers/net/tokenring/ibmtr.h index f51174c4fc68..3f3fa6aedd02 100644 --- a/drivers/net/ibmtr.h +++ b/drivers/net/tokenring/ibmtr.h @@ -444,6 +444,6 @@ struct srb_set_funct_addr { unsigned char reserved1; unsigned char ret_code; unsigned char reserved2[3]; - __u32 funct_address; + unsigned char funct_address[4]; }; diff --git a/drivers/net/olympic.c b/drivers/net/tokenring/olympic.c similarity index 100% rename from drivers/net/olympic.c rename to drivers/net/tokenring/olympic.c diff --git a/drivers/net/olympic.h b/drivers/net/tokenring/olympic.h similarity index 100% rename from drivers/net/olympic.h rename to drivers/net/tokenring/olympic.h diff --git a/drivers/net/sktr.c b/drivers/net/tokenring/sktr.c similarity index 95% rename from drivers/net/sktr.c rename to drivers/net/tokenring/sktr.c index f9b877f669f6..81b2df4bc00c 100644 --- a/drivers/net/sktr.c +++ b/drivers/net/tokenring/sktr.c @@ -24,7 +24,8 @@ * * Maintainer(s): * JS Jay Schulist jschlst@samba.anu.edu.au - * CG Christoph Goos cgoos@syskonnect.de + * CG Christoph Goos cgoos@syskonnect.de + * AF Adam Fritzler mid@auk.cx * * Modification History: * 29-Aug-97 CG Created @@ -33,10 +34,14 @@ * 27-May-98 JS Formated to Linux Kernel Format * 31-May-98 JS Hacked in PCI support * 16-Jun-98 JS Modulized for multiple cards with one driver + * 21-Sep-99 CG Fixed source routing issues for 2.2 kernels + * 21-Sep-99 AF Added multicast changes recommended by + * Jochen Friedrich (untested) + * Added detection of compatible Compaq PCI card * * To do: * 1. Selectable 16 Mbps or 4Mbps - * 2. Multi/Broadcast packet handling + * 2. Multi/Broadcast packet handling (might be done) * */ @@ -135,7 +140,6 @@ static void sktr_enable_interrupts(struct net_device *dev); static void sktr_exec_cmd(struct net_device *dev, unsigned short Command); static void sktr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue); /* "F" */ -static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen); /* "G" */ static struct enet_statistics *sktr_get_stats(struct net_device *dev); /* "H" */ @@ -254,10 +258,17 @@ static int __init sktr_pci_chk_card(struct net_device *dev) /* Remove I/O space marker in bit 0. */ pci_ioaddr &= ~3; - if(vendor != PCI_VENDOR_ID_SK) + if((vendor != PCI_VENDOR_ID_SK) && + (vendor != PCI_VENDOR_ID_COMPAQ)) continue; - if(device != PCI_DEVICE_ID_SK_TR) + + if((vendor == PCI_VENDOR_ID_SK) && + (device != PCI_DEVICE_ID_SK_TR)) + continue; + else if((vendor == PCI_VENDOR_ID_COMPAQ) && + (device != PCI_DEVICE_ID_COMPAQ_TOKENRING)) continue; + if(check_region(pci_ioaddr, SKTR_IO_EXTENT)) continue; request_region(pci_ioaddr, SKTR_IO_EXTENT, pci_cardname); @@ -390,6 +401,7 @@ static int __init sktr_probe1(struct net_device *dev, int ioaddr) { static unsigned version_printed = 0; struct net_local *tp; + int DeviceType = SK_PCI; int err; if(sktr_debug && version_printed++ == 0) @@ -407,6 +419,7 @@ static int __init sktr_probe1(struct net_device *dev, int ioaddr) err = sktr_isa_chk_card(dev, ioaddr); if(err < 0) return (-ENODEV); + DeviceType = SK_ISA; } /* Setup this devices private information structure */ @@ -414,6 +427,7 @@ static int __init sktr_probe1(struct net_device *dev, int ioaddr) if(tp == NULL) return (-ENOMEM); memset(tp, 0, sizeof(struct net_local)); + tp->DeviceType = DeviceType; init_waitqueue_head(&tp->wait_for_tok_int); dev->priv = tp; @@ -691,7 +705,9 @@ static void sktr_init_net_local(struct net_device *dev) skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); /* data unreachable for DMA ? then use local buffer */ - if(virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS) + if(tp->DeviceType == SK_ISA && + virt_to_bus(tp->Rpl[i].Skb->data) + + tp->MaxPacketSize > ISA_MAX_ADDRESS) { tp->Rpl[i].SkbStat = SKB_DATA_COPY; tp->Rpl[i].FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[i])); @@ -749,7 +765,7 @@ static void sktr_init_opb(struct net_local *tp) tp->ocpl.OPENOptions = 0; tp->ocpl.OPENOptions |= ENABLE_FULL_DUPLEX_SELECTION; - tp->ocpl.OPENOptions |= PAD_ROUTING_FIELD; +/* tp->ocpl.OPENOptions |= PAD_ROUTING_FIELD; no more needed */ tp->ocpl.FullDuplex = 0; tp->ocpl.FullDuplex |= OPEN_FULL_DUPLEX_OFF; @@ -826,32 +842,6 @@ static void sktr_exec_cmd(struct net_device *dev, unsigned short Command) return; } -/* - * Linux always gives 18 byte of source routing information in the frame header. - * But the length field can indicate shorter length. Then cut header - * appropriate. - */ -static unsigned char *sktr_fix_srouting(unsigned char *buf, short *FrameLen) -{ - struct trh_hdr *trh = (struct trh_hdr *)buf; - int len; - - if(buf[8] & TR_RII) - { - trh->rcf &= ~SWAPB((unsigned short) TR_RCF_LONGEST_FRAME_MASK); - trh->rcf |= SWAPB((unsigned short) TR_RCF_FRAME4K); - len = (SWAPB(trh->rcf) & TR_RCF_LEN_MASK) >> 8; - if(len < 18) - { - memcpy(&buf[18-len],buf,sizeof(struct trh_hdr)-18+len); - *FrameLen -= (18 - len); - } - return (&buf[18-len]); - } - - return (buf); -} - /* * Gets skb from system, queues it and checks if it can be sent */ @@ -934,7 +924,8 @@ static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* tp->QueueSkb++; /* Is buffer reachable for Busmaster-DMA? */ - if(virt_to_bus((void*)(((long) skb->data) + skb->len)) + if(tp->DeviceType == SK_ISA && + virt_to_bus((void*)(((long) skb->data) + skb->len)) > ISA_MAX_ADDRESS) { /* Copy frame to local buffer */ @@ -942,13 +933,13 @@ static void sktr_hardware_send_packet(struct net_device *dev, struct net_local* length = skb->len; buf = tp->LocalTxBuffers[i]; memcpy(buf, skb->data, length); - newbuf = sktr_fix_srouting(buf, &length); + newbuf = buf; } else { /* Send direct from skb->data */ length = skb->len; - newbuf = sktr_fix_srouting(skb->data, &length); + newbuf = skb->data; } /* Source address in packet? */ @@ -1486,53 +1477,65 @@ static struct enet_statistics *sktr_get_stats(struct net_device *dev) static void sktr_set_multicast_list(struct net_device *dev) { struct net_local *tp = (struct net_local *)dev->priv; - unsigned int OpenOptions; - - OpenOptions = tp->ocpl.OPENOptions & - ~(PASS_ADAPTER_MAC_FRAMES - | PASS_ATTENTION_FRAMES - | PASS_BEACON_MAC_FRAMES - | COPY_ALL_MAC_FRAMES - | COPY_ALL_NON_MAC_FRAMES); - - if(dev->flags & IFF_PROMISC) - /* Enable promiscuous mode */ - OpenOptions |= COPY_ALL_NON_MAC_FRAMES | COPY_ALL_MAC_FRAMES; - else - { - if(dev->flags & IFF_ALLMULTI) - /* || dev->mc_count > HW_MAX_ADDRS) */ - { - /* Disable promiscuous mode, use normal mode. */ - } - else - { - if(dev->mc_count) - { - /* Walk the address list, and load the filter */ - } - } - } - - tp->ocpl.OPENOptions = OpenOptions; - sktr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS); - - return; + unsigned int OpenOptions; + + OpenOptions = tp->ocpl.OPENOptions & + ~(PASS_ADAPTER_MAC_FRAMES + | PASS_ATTENTION_FRAMES + | PASS_BEACON_MAC_FRAMES + | COPY_ALL_MAC_FRAMES + | COPY_ALL_NON_MAC_FRAMES); + + tp->ocpl.FunctAddr = 0; + + if(dev->flags & IFF_PROMISC) + /* Enable promiscuous mode */ + OpenOptions |= COPY_ALL_NON_MAC_FRAMES | + COPY_ALL_MAC_FRAMES; + else + { + if(dev->flags & IFF_ALLMULTI) + { + /* Disable promiscuous mode, use normal mode. */ + tp->ocpl.FunctAddr = 0xFFFFFFFF; + + } + else + { + int i; + struct dev_mc_list *mclist = dev->mc_list; + for (i=0; i< dev->mc_count; i++) + { + ((char *)(&tp->ocpl.FunctAddr))[0] |= + mclist->dmi_addr[2]; + ((char *)(&tp->ocpl.FunctAddr))[1] |= + mclist->dmi_addr[3]; + ((char *)(&tp->ocpl.FunctAddr))[2] |= + mclist->dmi_addr[4]; + ((char *)(&tp->ocpl.FunctAddr))[3] |= + mclist->dmi_addr[5]; + mclist = mclist->next; + } + } + sktr_exec_cmd(dev, OC_SET_FUNCT_ADDR); + } + + tp->ocpl.OPENOptions = OpenOptions; + sktr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS); + return; } /* * Wait for some time (microseconds) + * + * udelay() is a bit harsh, but using a looser timer causes + * the bring-up-diags to stall indefinitly. + * */ + static void sktr_wait(unsigned long time) { - long tmp; - - tmp = jiffies + time/(1000000/HZ); - do { - current->state = TASK_INTERRUPTIBLE; - tmp = schedule_timeout(tmp); - } while(time_after(tmp, jiffies)); - + udelay(time); return; } @@ -2451,8 +2454,6 @@ static void sktr_rcv_status_irq(struct net_device *dev) /* Drop frames sent by myself */ if(sktr_chk_frame(dev, rpl->MData)) { - printk(KERN_INFO "%s: Received my own frame\n", - dev->name); if(rpl->Skb != NULL) dev_kfree_skb(rpl->Skb); } @@ -2464,9 +2465,10 @@ static void sktr_rcv_status_irq(struct net_device *dev) printk("%s: Packet Length %04X (%d)\n", dev->name, Length, Length); - /* Indicate the received frame to system the - * adapter does the Source-Routing padding for - * us. See: OpenOptions in sktr_init_opb() + /* Indicate the received frame to system. + * The source routing padding is no more + * necessary with 2.2.x kernel. + * See: OpenOptions in sktr_init_opb() */ skb = rpl->Skb; if(rpl->SkbStat == SKB_UNAVAILABLE) @@ -2497,6 +2499,7 @@ static void sktr_rcv_status_irq(struct net_device *dev) /* Deliver frame to system */ rpl->Skb = NULL; skb_trim(skb,Length); + skb->dev = dev; skb->protocol = tr_type_trans(skb,dev); netif_rx(skb); } @@ -2529,7 +2532,8 @@ static void sktr_rcv_status_irq(struct net_device *dev) skb_put(rpl->Skb, tp->MaxPacketSize); /* Data unreachable for DMA ? then use local buffer */ - if(virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize + if(tp->DeviceType == SK_ISA && + virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS) { rpl->SkbStat = SKB_DATA_COPY; diff --git a/drivers/net/sktr.h b/drivers/net/tokenring/sktr.h similarity index 99% rename from drivers/net/sktr.h rename to drivers/net/tokenring/sktr.h index 4c2a3bf368a1..90b5c382f7b5 100644 --- a/drivers/net/sktr.h +++ b/drivers/net/tokenring/sktr.h @@ -16,6 +16,9 @@ #define TR_RCF_LONGEST_FRAME_MASK 0x0070 #define TR_RCF_FRAME4K 0x0030 +#define SK_ISA 0 +#define SK_PCI 1 + /*------------------------------------------------------------------*/ /* Bit order for adapter communication with DMA */ /* -------------------------------------------------------------- */ @@ -642,7 +645,7 @@ typedef struct { * but possibly multiple TPLs for one frame) the length of the TPLs has to be * initialized in the OPL. (OPEN parameter list) */ -#define TPL_NUM 3 /* Number of Transmit Parameter Lists. +#define TPL_NUM 9 /* Number of Transmit Parameter Lists. * !! MUST BE >= 3 !! */ @@ -1063,6 +1066,8 @@ typedef struct net_local { unsigned char ScbInUse; unsigned short CMDqueue; + unsigned int DeviceType; + unsigned long AdapterOpenFlag:1; unsigned long AdapterVirtOpenFlag:1; unsigned long OpenCommandIssued:1; diff --git a/drivers/net/sktr_firmware.h b/drivers/net/tokenring/sktr_firmware.h similarity index 100% rename from drivers/net/sktr_firmware.h rename to drivers/net/tokenring/sktr_firmware.h diff --git a/drivers/net/wan/Config.in b/drivers/net/wan/Config.in new file mode 100644 index 000000000000..503854a0f9aa --- /dev/null +++ b/drivers/net/wan/Config.in @@ -0,0 +1,64 @@ +# +# wan devices configuration +# + +mainmenu_option next_comment +comment 'Wan interfaces' + +bool 'Wan interfaces support' CONFIG_WAN +if [ "$CONFIG_WAN" = "y" ]; then + + # There is no way to detect a comtrol sv11 - force it modular for now. + + dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m + + # The COSA/SRP driver has not been tested as non-modular yet. + + dep_tristate 'COSA/SRP sync serial boards support' CONFIG_COSA m + + # There is no way to detect a Sealevel board. Force it modular + + dep_tristate 'Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m + + tristate 'Frame relay DLCI support' CONFIG_DLCI + if [ "$CONFIG_DLCI" != "n" ]; then + int 'Max open DLCI' CONFIG_DLCI_COUNT 24 + int 'Max DLCI per device' CONFIG_DLCI_MAX 8 + dep_tristate ' SDLA (Sangoma S502/S508) support' CONFIG_SDLA $CONFIG_DLCI + fi + + # Wan router core. + + if [ "$CONFIG_WAN_ROUTER" != "n" ]; then + bool 'WAN router drivers' CONFIG_WAN_ROUTER_DRIVERS + if [ "$CONFIG_WAN_ROUTER_DRIVERS" = "y" ]; then + dep_tristate ' Sangoma WANPIPE(tm) multiprotocol cards' CONFIG_VENDOR_SANGOMA $CONFIG_WAN_ROUTER_DRIVERS + if [ "$CONFIG_VENDOR_SANGOMA" != "n" ]; then + int 'Maximum number of cards' CONFIG_WANPIPE_CARDS 1 + bool ' WANPIPE X.25 support' CONFIG_WANPIPE_X25 + bool ' WANPIPE Frame Relay support' CONFIG_WANPIPE_FR + bool ' WANPIPE PPP support' CONFIG_WANPIPE_PPP + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Cyclom 2X(tm) cards (EXPERIMENTAL)' CONFIG_CYCLADES_SYNC $CONFIG_WAN_ROUTER_DRIVERS + if [ "$CONFIG_CYCLADES_SYNC" != "n" ]; then + bool ' Cyclom 2X X.25 support' CONFIG_CYCLOMX_X25 + fi + fi + fi + fi + + # X.25 network drivers + + if [ "$CONFIG_X25" != "n" ]; then + if [ "$CONFIG_LAPB" != "n" ]; then + dep_tristate 'LAPB over Ethernet driver' CONFIG_LAPBETHER $CONFIG_LAPB + dep_tristate 'X.25 async driver' CONFIG_X25_ASY $CONFIG_LAPB + fi + fi + + tristate 'SBNI12-xx support' CONFIG_SBNI +fi + +endmenu + diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile new file mode 100644 index 000000000000..73060f5b971b --- /dev/null +++ b/drivers/net/wan/Makefile @@ -0,0 +1,181 @@ +# File: drivers/net/wan/Makefile +# +# Makefile for the Linux network (wan) device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now inherited from the +# parent makefile. +# + +SUB_DIRS := +MOD_SUB_DIRS := $(SUB_DIRS) +ALL_SUB_DIRS := $(SUB_DIRS) + +L_TARGET := wan.a +L_OBJS := +M_OBJS := + +# Need these to keep track of whether the 82530 or SYNCPPP +# modules should really go in the kernel or a module. +CONFIG_85230_BUILTIN := +CONFIG_85230_MODULE := +CONFIG_SYNCPPP_BUILTIN := +CONFIG_SYNCPPP_MODULE := + +ifeq ($(CONFIG_HOSTESS_SV11),y) +L_OBJS += hostess_sv11.o +CONFIG_85230_BUILTIN = y +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_HOSTESS_SV11),m) + CONFIG_85230_MODULE = y + CONFIG_SYNCPPP_MODULE = y + M_OBJS += hostess_sv11.o + endif +endif + +ifeq ($(CONFIG_SEALEVEL_4021),y) +L_OBJS += sealevel.o +CONFIG_85230_BUILTIN = y +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_SEALEVEL_4021),m) + CONFIG_85230_MODULE = y + CONFIG_SYNCPPP_MODULE = y + M_OBJS += sealevel.o + endif +endif + +ifeq ($(CONFIG_COSA),y) +L_OBJS += cosa.o +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_COSA),m) + CONFIG_SYNCPPP_MODULE = y + M_OBJS += cosa.o + endif +endif + +# If anything built-in uses syncppp, then build it into the kernel also. +# If not, but a module uses it, build as a module. + +ifdef CONFIG_SYNCPPP_BUILTIN +LX_OBJS += syncppp.o +else + ifdef CONFIG_SYNCPPP_MODULE + MX_OBJS += syncppp.o + endif +endif + +# If anything built-in uses Z85230, then build it into the kernel also. +# If not, but a module uses it, build as a module. + +ifdef CONFIG_85230_BUILTIN +LX_OBJS += z85230.o +else + ifdef CONFIG_85230_MODULE + MX_OBJS += z85230.o + endif +endif + +ifeq ($(CONFIG_DLCI),y) +L_OBJS += dlci.o +else + ifeq ($(CONFIG_DLCI),m) + M_OBJS += dlci.o + endif +endif + +ifeq ($(CONFIG_SDLA),y) + L_OBJS += sdla.o +else + ifeq ($(CONFIG_SDLA),m) + M_OBJS += sdla.o +endif + +ifeq ($(CONFIG_VENDOR_SANGOMA),y) + LX_OBJS += sdladrv.o + L_OBJS += sdlamain.o + ifeq ($(CONFIG_WANPIPE_X25),y) + L_OBJS += sdla_x25.o + endif + ifeq ($(CONFIG_WANPIPE_FR),y) + L_OBJS += sdla_fr.o + endif + ifeq ($(CONFIG_WANPIPE_PPP),y) + L_OBJS += sdla_ppp.o + endif +endif + +endif + +ifeq ($(CONFIG_VENDOR_SANGOMA),m) + MX_OBJS += sdladrv.o + M_OBJS += wanpipe.o + WANPIPE_OBJS = sdlamain.o + ifeq ($(CONFIG_WANPIPE_X25),y) + WANPIPE_OBJS += sdla_x25.o + endif + ifeq ($(CONFIG_WANPIPE_FR),y) + WANPIPE_OBJS += sdla_fr.o + endif + ifeq ($(CONFIG_WANPIPE_PPP),y) + WANPIPE_OBJS += sdla_ppp.o + endif +endif + +ifeq ($(CONFIG_CYCLADES_SYNC),y) + LX_OBJS += cycx_drv.o + L_OBJS += cycx_main.o + ifeq ($(CONFIG_CYCLOMX_X25),y) + L_OBJS += cycx_x25.o + endif +endif + +ifeq ($(CONFIG_CYCLADES_SYNC),m) + MX_OBJS += cycx_drv.o + M_OBJS += cyclomx.o + CYCLOMX_OBJS = cycx_main.o + ifeq ($(CONFIG_CYCLOMX_X25),y) + CYCLOMX_OBJS += cycx_x25.o + endif +endif + +ifeq ($(CONFIG_X25_ASY),y) +L_OBJS += x25_asy.o +else + ifeq ($(CONFIG_X25_ASY),m) + M_OBJS += x25_asy.o + endif +endif + +ifeq ($(CONFIG_LAPBETHER),y) +L_OBJS += lapbether.o +else + ifeq ($(CONFIG_LAPBETHER),m) + M_OBJS += lapbether.o + endif +endif + +ifeq ($(CONFIG_SBNI),y) +L_OBJS += sbni.o +else + ifeq ($(CONFIG_SBNI),m) + M_OBJS += sbni.o + endif +endif + +include $(TOPDIR)/Rules.make + +clean: + rm -f core *.o *.a *.s + +wanpipe.o: $(WANPIPE_OBJS) + ld -r -o $@ $(WANPIPE_OBJS) + +cyclomx.o: $(CYCLOMX_OBJS) + ld -r -o $@ $(CYCLOMX_OBJS) + diff --git a/drivers/net/cosa.c b/drivers/net/wan/cosa.c similarity index 100% rename from drivers/net/cosa.c rename to drivers/net/wan/cosa.c diff --git a/drivers/net/cosa.h b/drivers/net/wan/cosa.h similarity index 100% rename from drivers/net/cosa.h rename to drivers/net/wan/cosa.h diff --git a/drivers/net/cycx_drv.c b/drivers/net/wan/cycx_drv.c similarity index 100% rename from drivers/net/cycx_drv.c rename to drivers/net/wan/cycx_drv.c diff --git a/drivers/net/cycx_main.c b/drivers/net/wan/cycx_main.c similarity index 100% rename from drivers/net/cycx_main.c rename to drivers/net/wan/cycx_main.c diff --git a/drivers/net/cycx_x25.c b/drivers/net/wan/cycx_x25.c similarity index 100% rename from drivers/net/cycx_x25.c rename to drivers/net/wan/cycx_x25.c diff --git a/drivers/net/dlci.c b/drivers/net/wan/dlci.c similarity index 100% rename from drivers/net/dlci.c rename to drivers/net/wan/dlci.c diff --git a/drivers/net/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c similarity index 99% rename from drivers/net/hostess_sv11.c rename to drivers/net/wan/hostess_sv11.c index 7b24901ce40c..ba4e49c83a50 100644 --- a/drivers/net/hostess_sv11.c +++ b/drivers/net/wan/hostess_sv11.c @@ -320,7 +320,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) for(i=0;i<999;i++) { sprintf(sv->name,"hdlc%d", i); - if(dev_get(sv->name)==NULL) + if(dev_get(sv->name)==0) { struct net_device *d=dev->chanA.netdevice; diff --git a/drivers/net/lapbether.c b/drivers/net/wan/lapbether.c similarity index 100% rename from drivers/net/lapbether.c rename to drivers/net/wan/lapbether.c diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c new file mode 100644 index 000000000000..9d5fba082016 --- /dev/null +++ b/drivers/net/wan/sbni.c @@ -0,0 +1,1533 @@ +/* + * Driver for Granch SBNI-12 leased line network adapters. + * + * Copyright 1997 - 1999, Granch ltd. + * Written 1999 by Yaroslav Polyakov (xenon@granch.ru). + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + * + * // Whole developers team: + * // Yaroslav Polyakov (xenon@granch.ru) + * // - main developer of this version + * // Alexey Zverev (zverev@granch.ru) + * // - previous SBNI driver for linux + * // Alexey Chirkov (chirkov@granch.ru) + * // - all the hardware work and consulting + * // Max Khon (max@iclub.nsu.ru) + * // - first SBNI driver for linux + * // -------------------------------------------- + * // also I thank: + * // Max Krasnyansky (max@uznet.net) + * // - for bug hunting and many ideas + * // Alan Cox (Alan.Cox@linux.org) + * // - for consulting in some hardcore questions + * // Donald Becker (becker@cesdis.gsfc.nasa.gov) + * // - for pretty nice skeleton + * + * More info and useful utilities to work w/ SBNI you can find at + * http://www.granch.ru. + * + * 3.0.0 = Initial Revision, Yaroslav Polyakov (24 Feb 1999) + * - added pre-calculation for CRC, fixed bug with "len-2" frames, + * - removed outbound fragmentation (MTU=1000), written CRC-calculation + * - on asm, added work with hard_headers and now we have our own cache + * - for them, optionally supported word-interchange on some chipsets, + * - something else I cant remember ;) + * + * 3.0.1 = just fixed some bugs (14 apr 1999). + * - fixed statistical tx bug + * - fixed wrong creation dates (1998 -> 1999) in driver source code ;) + * - fixed source address bug. + * - fixed permanent nirvana bug + * + * 3.1.0 = (Katyusha) (26 apr 1999) + * - Added balancing feature + * + * 3.1.1 = (Medea) (5 aug 1999) + * - Fixed mac.raw bug + * - Thanks to tolix@olviko.ru and + * - to Barnaul Brewery, producers of my favorite beer "Medea". + * + * + */ + + +#undef GOODBUS16 +#define CRCASM +#define KATYUSHA + +#include + +#if LINUX_VERSION_CODE >=0x020200 +#define v22 +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include +#include +#include +#include +#include /* for CONFIG_INET. do we need this?*/ + +#include + + + +#ifdef v22 +#include +#include +#endif + +#include "sbni.h" + + +static const char *version = +"sbni.c: ver. 3.1.1 Medea 5 Aug 1999 Yaroslav Polyakov (xenon@granch.ru)\n"; + +int sbni_probe(struct net_device *dev); +static int sbni_probe1(struct net_device *dev, int ioaddr); +static int sbni_open(struct net_device *dev); +static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev); +static void sbni_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static int sbni_close(struct net_device *dev); +static void sbni_drop_tx_queue(struct net_device *dev); +static struct enet_statistics *sbni_get_stats(struct net_device *dev); +void card_start(struct net_device *dev); +static inline unsigned short sbni_recv(struct net_device *dev); +void change_level(struct net_device *dev); +static inline void sbni_xmit(struct net_device *dev); +static inline void sbni_get_packet(struct net_device* dev); +static void sbni_watchdog(unsigned long arg); +static void set_multicast_list(struct net_device *dev); +static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int sbni_set_mac_address(struct net_device *dev, void *addr); +unsigned long calc_crc(char *mem, int len, unsigned initial); +void sbni_nirvana(struct net_device *dev); +static int sbni_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, + void *daddr, void *saddr, unsigned len); + +static int sbni_rebuild_header(struct sk_buff *skb); +static int sbni_header_cache(struct neighbour *neigh, struct hh_cache *hh); + +static inline void sbni_outs(int port, void *data, int len); +static inline void sbni_ins(int port, void *data, int len); + + + +#define SIZE_OF_TIMEOUT_RXL_TAB 4 +static u_char timeout_rxl_tab[] = { + 0x03, 0x05, 0x08, 0x0b +}; + +static u_char rxl_tab[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, + 0x0a, 0x0c, 0x0f, 0x16, 0x18, 0x1a, 0x1c, 0x1f +}; + +/* A zero-terminated list of I/O addresses to be probed */ +static unsigned int netcard_portlist[] = { + 0x210, 0x2c0, 0x2d0, 0x2f0, 0x220, 0x230, 0x240, 0x250, + 0x260, 0x290, 0x2a0, 0x2b0, 0x224, 0x234, 0x244, 0x254, + 0x264, 0x294, 0x2a4, 0x2b4, 0}; + +static unsigned char magic_reply[] = { + 0x5a,0x06,0x30,0x00,0x00,0x50,0x65,0x44,0x20 +}; + +static int def_baud = DEF_RATE; +static int def_rxl = DEF_RXL_DELTA; +static long def_mac = 0; + + +/* + * CRC-32 stuff + */ + +#define CRC32(c,crc) (crc32tab[((size_t)(crc) ^ (c)) & 0xff] ^ (((crc) >> 8) & 0x00FFFFFF)) +/* CRC generator 0xEDB88320 */ +/* CRC remainder 0x2144DF1C */ +/* CRC initial value 0x00000000 */ +#define CRC32_REMAINDER 0x2144DF1C +#define CRC32_INITIAL 0x00000000 + +static unsigned long crc32tab[] = { + 0xD202EF8D, 0xA505DF1B, 0x3C0C8EA1, 0x4B0BBE37, + 0xD56F2B94, 0xA2681B02, 0x3B614AB8, 0x4C667A2E, + 0xDCD967BF, 0xABDE5729, 0x32D70693, 0x45D03605, + 0xDBB4A3A6, 0xACB39330, 0x35BAC28A, 0x42BDF21C, + 0xCFB5FFE9, 0xB8B2CF7F, 0x21BB9EC5, 0x56BCAE53, + 0xC8D83BF0, 0xBFDF0B66, 0x26D65ADC, 0x51D16A4A, + 0xC16E77DB, 0xB669474D, 0x2F6016F7, 0x58672661, + 0xC603B3C2, 0xB1048354, 0x280DD2EE, 0x5F0AE278, + 0xE96CCF45, 0x9E6BFFD3, 0x0762AE69, 0x70659EFF, + 0xEE010B5C, 0x99063BCA, 0x000F6A70, 0x77085AE6, + 0xE7B74777, 0x90B077E1, 0x09B9265B, 0x7EBE16CD, + 0xE0DA836E, 0x97DDB3F8, 0x0ED4E242, 0x79D3D2D4, + 0xF4DBDF21, 0x83DCEFB7, 0x1AD5BE0D, 0x6DD28E9B, + 0xF3B61B38, 0x84B12BAE, 0x1DB87A14, 0x6ABF4A82, + 0xFA005713, 0x8D076785, 0x140E363F, 0x630906A9, + 0xFD6D930A, 0x8A6AA39C, 0x1363F226, 0x6464C2B0, + 0xA4DEAE1D, 0xD3D99E8B, 0x4AD0CF31, 0x3DD7FFA7, + 0xA3B36A04, 0xD4B45A92, 0x4DBD0B28, 0x3ABA3BBE, + 0xAA05262F, 0xDD0216B9, 0x440B4703, 0x330C7795, + 0xAD68E236, 0xDA6FD2A0, 0x4366831A, 0x3461B38C, + 0xB969BE79, 0xCE6E8EEF, 0x5767DF55, 0x2060EFC3, + 0xBE047A60, 0xC9034AF6, 0x500A1B4C, 0x270D2BDA, + 0xB7B2364B, 0xC0B506DD, 0x59BC5767, 0x2EBB67F1, + 0xB0DFF252, 0xC7D8C2C4, 0x5ED1937E, 0x29D6A3E8, + 0x9FB08ED5, 0xE8B7BE43, 0x71BEEFF9, 0x06B9DF6F, + 0x98DD4ACC, 0xEFDA7A5A, 0x76D32BE0, 0x01D41B76, + 0x916B06E7, 0xE66C3671, 0x7F6567CB, 0x0862575D, + 0x9606C2FE, 0xE101F268, 0x7808A3D2, 0x0F0F9344, + 0x82079EB1, 0xF500AE27, 0x6C09FF9D, 0x1B0ECF0B, + 0x856A5AA8, 0xF26D6A3E, 0x6B643B84, 0x1C630B12, + 0x8CDC1683, 0xFBDB2615, 0x62D277AF, 0x15D54739, + 0x8BB1D29A, 0xFCB6E20C, 0x65BFB3B6, 0x12B88320, + 0x3FBA6CAD, 0x48BD5C3B, 0xD1B40D81, 0xA6B33D17, + 0x38D7A8B4, 0x4FD09822, 0xD6D9C998, 0xA1DEF90E, + 0x3161E49F, 0x4666D409, 0xDF6F85B3, 0xA868B525, + 0x360C2086, 0x410B1010, 0xD80241AA, 0xAF05713C, + 0x220D7CC9, 0x550A4C5F, 0xCC031DE5, 0xBB042D73, + 0x2560B8D0, 0x52678846, 0xCB6ED9FC, 0xBC69E96A, + 0x2CD6F4FB, 0x5BD1C46D, 0xC2D895D7, 0xB5DFA541, + 0x2BBB30E2, 0x5CBC0074, 0xC5B551CE, 0xB2B26158, + 0x04D44C65, 0x73D37CF3, 0xEADA2D49, 0x9DDD1DDF, + 0x03B9887C, 0x74BEB8EA, 0xEDB7E950, 0x9AB0D9C6, + 0x0A0FC457, 0x7D08F4C1, 0xE401A57B, 0x930695ED, + 0x0D62004E, 0x7A6530D8, 0xE36C6162, 0x946B51F4, + 0x19635C01, 0x6E646C97, 0xF76D3D2D, 0x806A0DBB, + 0x1E0E9818, 0x6909A88E, 0xF000F934, 0x8707C9A2, + 0x17B8D433, 0x60BFE4A5, 0xF9B6B51F, 0x8EB18589, + 0x10D5102A, 0x67D220BC, 0xFEDB7106, 0x89DC4190, + 0x49662D3D, 0x3E611DAB, 0xA7684C11, 0xD06F7C87, + 0x4E0BE924, 0x390CD9B2, 0xA0058808, 0xD702B89E, + 0x47BDA50F, 0x30BA9599, 0xA9B3C423, 0xDEB4F4B5, + 0x40D06116, 0x37D75180, 0xAEDE003A, 0xD9D930AC, + 0x54D13D59, 0x23D60DCF, 0xBADF5C75, 0xCDD86CE3, + 0x53BCF940, 0x24BBC9D6, 0xBDB2986C, 0xCAB5A8FA, + 0x5A0AB56B, 0x2D0D85FD, 0xB404D447, 0xC303E4D1, + 0x5D677172, 0x2A6041E4, 0xB369105E, 0xC46E20C8, + 0x72080DF5, 0x050F3D63, 0x9C066CD9, 0xEB015C4F, + 0x7565C9EC, 0x0262F97A, 0x9B6BA8C0, 0xEC6C9856, + 0x7CD385C7, 0x0BD4B551, 0x92DDE4EB, 0xE5DAD47D, + 0x7BBE41DE, 0x0CB97148, 0x95B020F2, 0xE2B71064, + 0x6FBF1D91, 0x18B82D07, 0x81B17CBD, 0xF6B64C2B, + 0x68D2D988, 0x1FD5E91E, 0x86DCB8A4, 0xF1DB8832, + 0x616495A3, 0x1663A535, 0x8F6AF48F, 0xF86DC419, + 0x660951BA, 0x110E612C, 0x88073096, 0xFF000000 +}; + +static inline void sbni_outs(int port, void *data, int len) +{ +#ifdef GOODBUS16 + outsw(port,data,len/2); + if(len & 1) + outb(((char*)data)[len - 1],port); +#else + outsb(port,data,len); +#endif +} + +static inline void sbni_ins(int port, void *data, int len) +{ +#ifdef GOODBUS16 + insw(port,data,len/2); + if(len & 1) + ((char*)data)[len - 1] = inb(port); +#else + insb(port,data,len); +#endif +} + + +static int sbni_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, + void *daddr, void *saddr, unsigned len) +{ + struct sbni_hard_header *hh = (struct sbni_hard_header *) + skb_push(skb, sizeof(struct sbni_hard_header)); + + + if(type!=ETH_P_802_3) + hh->h_proto = htons(type); + else + hh->h_proto = htons(len); + + if(saddr) + memcpy(hh->h_source,saddr,dev->addr_len); + else + memcpy(hh->h_source,dev->dev_addr,dev->addr_len); + + if(daddr) + { + memcpy(hh->h_dest,daddr,dev->addr_len); + return dev->hard_header_len; + } + return -dev->hard_header_len; +} + + +int sbni_header_cache(struct neighbour *neigh, struct hh_cache *hh) +{ + unsigned short type = hh->hh_type; + struct sbni_hard_header *sbni = (struct sbni_hard_header*) + (((u8*)hh->hh_data) - 8); + struct net_device *dev = neigh->dev; + + + if (type == __constant_htons(ETH_P_802_3)) + return -1; + + sbni->h_proto = type; + memcpy(sbni->h_source, dev->dev_addr, dev->addr_len); + memcpy(sbni->h_dest, neigh->ha, dev->addr_len); + return 0; +} + +static int sbni_rebuild_header(struct sk_buff *skb) +{ + struct sbni_hard_header *hh = (struct sbni_hard_header *)skb; + /* + * Only ARP/IP is currently supported + */ + + /* + * Try to get ARP to resolve the header. + */ + +#ifdef CONFIG_INET + return arp_find((unsigned char*)hh->h_dest, skb)? 1 : 0; +#else + return 0; +#endif +} + +static void sbni_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr) +{ + memcpy(((u8*)hh->hh_data) + 2, haddr, dev->addr_len); +} + + + +#ifdef HAVE_DEVLIST +struct netdev_entry sbni_drv = { + "sbni", sbni_probe1, SBNI_IO_EXTENT, netcard_portlist +}; + +#else + +int __init sbni_probe(struct net_device *dev) +{ + int i; + int base_addr = dev ? dev->base_addr : 0; + + DP( printk("%s: sbni_probe\n", dev->name); ) + + if(base_addr > 0x1ff) /* Check a single specified location. */ + return sbni_probe1(dev, base_addr); + else if(base_addr != 0) /* Don't probe at all. */ + return ENXIO; + for(i = 0; (base_addr = netcard_portlist[i]); i++) + { + if(!check_region(base_addr, SBNI_IO_EXTENT) && base_addr != 1) + { + /* Lock this address, or later we'll try it again */ + netcard_portlist[i] = 1; + if(sbni_probe1(dev, base_addr) == 0) + return 0; + } + } + return ENODEV; +} + +#endif /* have devlist*/ + +/* + * The actual probe. + */ + +/* + Valid combinations in CSR0 (for probing): + + VALID_DECODER 0000,0011,1011,1010 + + ; 0 ; - + TR_REQ ; 1 ; + + TR_RDY ; 2 ; - + TR_RDY TR_REQ ; 3 ; + + BU_EMP ; 4 ; + + BU_EMP TR_REQ ; 5 ; + + BU_EMP TR_RDY ; 6 ; - + BU_EMP TR_RDY TR_REQ ; 7 ; + + RC_RDY ; 8 ; + + RC_RDY TR_REQ ; 9 ; + + RC_RDY TR_RDY ; 10 ; - + RC_RDY TR_RDY TR_REQ ; 11 ; - + RC_RDY BU_EMP ; 12 ; - + RC_RDY BU_EMP TR_REQ ; 13 ; - + RC_RDY BU_EMP TR_RDY ; 14 ; - + RC_RDY BU_EMP TR_RDY TR_REQ ; 15 ; - +*/ +#define VALID_DECODER (2 + 8 + 0x10 + 0x20 + 0x80 + 0x100 + 0x200) + +static int __init sbni_probe1(struct net_device *dev, int ioaddr) + +{ + int autoirq = 0; + int bad_card = 0; + unsigned char csr0; + struct net_local* lp; + static int version_printed = 0; + + DP( printk("%s: sbni_probe1 ioaddr=%d\n", dev->name, ioaddr); ) + + if(check_region(ioaddr, SBNI_IO_EXTENT) < 0) + return -ENODEV; + if(version_printed++ == 0) + printk(version); + + /* check for valid combination in CSR0 */ + csr0 = inb(ioaddr + CSR0); + if(csr0 == 0xff || csr0 == 0) + bad_card = 1; + else + { + csr0 &= ~EN_INT; + if(csr0 & BU_EMP) + csr0 |= EN_INT; + if((VALID_DECODER & (1 << (csr0 >> 4))) == 0) + bad_card = 1; + } + + if(bad_card) + return ENODEV; + else + outb(0, ioaddr + CSR0); + if(dev->irq < 2) + { + DP( printk("%s: autoprobing\n", dev->name); ); + autoirq_setup(5); + outb(EN_INT | TR_REQ, ioaddr + CSR0); + outb(PR_RES, ioaddr + CSR1); + autoirq = autoirq_report(5); + + if(autoirq == 0) + { + printk("sbni probe at %#x failed to detect IRQ line\n", ioaddr); + return EAGAIN; + } + } + /* clear FIFO buffer */ + outb(0, ioaddr + CSR0); + + if(autoirq) + dev->irq = autoirq; + + { + int irqval=request_irq(dev->irq, sbni_interrupt, 0, dev->name, dev); + if (irqval) + { + printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval); + return EAGAIN; + } + } + + /* + * Initialize the device structure. + */ + + dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); + if(dev->priv == NULL) + { + DP( printk("%s: cannot allocate memory\n", dev->name); ) + return -ENOMEM; + } + + memset(dev->priv, 0, sizeof(struct net_local)); + dev->base_addr = ioaddr; + request_region(ioaddr, SBNI_IO_EXTENT, "sbni"); + + /* + * generate Ethernet address (0x00ff01xxxxxx) + */ + + *(u16*)dev->dev_addr = htons(0x00ff); + *(u32*)(dev->dev_addr+2) = htonl(((def_mac ? def_mac : (u32) dev->priv) & 0x00ffffff) | 0x01000000); + + lp = dev->priv; + if(def_rxl < 0) + { + /* autodetect receive level */ + lp->rxl_curr = 0xf; + lp->rxl_delta = -1; + } else { + /* fixed receive level */ + lp->rxl_curr = def_rxl & 0xf; + lp->rxl_delta = 0; + } + lp->csr1.rxl = rxl_tab[lp->rxl_curr]; + lp->csr1.rate = def_baud & 3; + lp->frame_len = DEF_FRAME_LEN; + printk("%s: sbni adapter at %#lx, using %sIRQ %d, MAC: 00:ff:01:%x:%x:%x\n", + dev->name, dev->base_addr, autoirq ? "auto":"assigned ", dev->irq, + *(unsigned char*)(dev->dev_addr+3), + *(unsigned char*)(dev->dev_addr+4), + *(unsigned char*)(dev->dev_addr+5) + ); + + printk("%s: receive level: ", dev->name); + if(lp->rxl_delta == 0) + printk ("%#1x (fixed)", lp->rxl_curr); + else + printk ("autodetect"); + printk(", baud rate: %u\n", (unsigned)lp->csr1.rate); + + /* + * The SBNI-specific entries in the device structure. + */ + dev->open = &sbni_open; + dev->hard_start_xmit = &sbni_start_xmit; + dev->stop = &sbni_close; + dev->get_stats = &sbni_get_stats; + dev->set_multicast_list = &set_multicast_list; + dev->set_mac_address = &sbni_set_mac_address; + dev->do_ioctl = &sbni_ioctl; + + /* + * Setup the generic properties + */ + + ether_setup(dev); + + dev->hard_header = sbni_header; + dev->hard_header_len = sizeof(struct sbni_hard_header); + dev->rebuild_header=sbni_rebuild_header; + dev->mtu = DEF_FRAME_LEN; + + dev->hard_header_cache = sbni_header_cache; + dev->header_cache_update = sbni_header_cache_update; + + lp->m=dev; + lp->me=dev; + lp->next_lp=NULL; + + return 0; +} + +/* + * Open/initialize the board. + */ + +static int sbni_open(struct net_device *dev) +{ + struct net_local* lp = (struct net_local*)dev->priv; + struct timer_list* watchdog = &lp->watchdog; + + + DP( printk("%s: sbni_open\n", dev->name); ) + + cli(); + lp->currframe = NULL; + + card_start(dev); + dev->start = 1; + /* set timer watchdog */ + init_timer(watchdog); + watchdog->expires = jiffies + SBNI_TIMEOUT; + watchdog->data = (unsigned long)dev; + watchdog->function = sbni_watchdog; + add_timer(watchdog); + DP( printk("%s: sbni timer watchdog initialized\n", dev->name); ); + + sti(); + + MOD_INC_USE_COUNT; + return 0; +} + +static int sbni_close(struct net_device *dev) +{ + int ioaddr = dev->base_addr; + struct net_local* lp = (struct net_local*) dev->priv; + struct timer_list* watchdog = &lp->watchdog; + + + DP( printk("%s: sbni_close\n", dev->name); ) + + cli(); + + sbni_drop_tx_queue(dev); + + dev->tbusy = 1; + dev->start = 0; + + del_timer(watchdog); + + outb(0, ioaddr + CSR0); + sti(); + + MOD_DEC_USE_COUNT; + return 0; +} + +static int sbni_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + struct sbni_hard_header *hh=(struct sbni_hard_header *)skb->data; + +#ifdef KATYUSHA + struct net_local *nl; + int stop; +#endif + + DP( printk("%s: sbni_start_xmit In \n", dev->name); ); + + + if(lp->me != dev) + panic("sbni: lp->me != dev !!!\nMail to developer (xenon@granch.ru) if you noticed this error\n"); + + if(dev->interrupt) + { + DP( printk("sbni_xmit_start: interrupt\n"); ) + /* May be unloading, don't stamp on */ + return 1; /* the packet buffer this time */ + } + + hh->number = 1; + hh->reserv = 0; + + hh->packetlen = (skb->len - sizeof (unsigned short) - + (sizeof(struct sbni_hard_header) - SBNI_HH_SZ)) + | PACKET_SEND_OK | PACKET_FIRST_FRAME; + + /* we should use hairy method to calculate crc because of extra bytes are + livin between hard header and data*/ + hh->crc = calc_crc((void*)&hh->packetlen, SBNI_HH_SZ - sizeof(unsigned), CRC32_INITIAL); + hh->crc = calc_crc(skb->data + sizeof(struct sbni_hard_header), + skb->len - sizeof(struct sbni_hard_header), + hh->crc); + +#ifdef KATYUSHA + /* looking for first idle device */ + for (stop=0,nl=lp; nl && !stop; nl=nl->next_lp) + { + if((!nl->currframe) && (nl->carrier)) /* if idle */ + { + skb->dev = lp->me; + nl->currframe = skb; + /* set request for transmit */ + outb(inb(nl->me->base_addr + CSR0) | TR_REQ, + nl->me->base_addr + CSR0); + stop=1; + } + } + + if(!stop) /* we havent found any idle.*/ + { + skb_queue_tail(&lp->queue,skb); + outb(inb(dev->base_addr + CSR0) | TR_REQ, dev->base_addr + CSR0); + + } +#else + if (lp->currframe || 1) + { + skb_queue_tail(&lp->queue,skb); + + } + else + { + lp->currframe = skb; + } + /* set request for transmit */ + outb(inb(dev->base_addr + CSR0) | TR_REQ, dev->base_addr + CSR0); +#endif + return 0; +} + +void card_start(struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + + DP( printk("%s: card_start\n",dev->name); ) + lp->wait_frame_number = 0; + lp->inppos = lp->outpos = 0; + lp->eth_trans_buffer_len = 0; + lp->tr_err = TR_ERROR_COUNT; + lp->last_receive_OK = FALSE; + lp->tr_resend = FALSE; + lp->timer_ticks = CHANGE_LEVEL_START_TICKS; + lp->timeout_rxl = 0; + + lp->waitack=0; + skb_queue_head_init(&lp->queue); + sbni_drop_tx_queue(dev); + dev->tbusy = 0; + + dev->interrupt = 0; + /* Reset the card and set start parameters */ + outb(PR_RES | *(char*)&lp->csr1, dev->base_addr + CSR1); + outb(EN_INT, dev->base_addr + CSR0); +} + +void sbni_nirvana(struct net_device *dev) +{ + sbni_outs(dev->base_addr+DAT,magic_reply,9); +} + +static inline unsigned short sbni_recv(struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + unsigned long crc; + unsigned short packetlen = 0; + unsigned short packetinf, packetfirst, receiveframeresend; + unsigned char current_frame; + unsigned int i, j; + unsigned char delme,rcv_res=RCV_WR; + + lp->in_stats.all_rx_number++; + + if((delme=inb(dev->base_addr + DAT)) == SBNI_SIG) + { + crc = CRC32_INITIAL; + *(((unsigned char *)&packetlen) + 0) = inb(dev->base_addr + DAT); + crc = CRC32(*(((unsigned char *)&packetlen) + 0), crc); + *(((unsigned char *)&packetlen) + 1) = inb(dev->base_addr + DAT); + crc = CRC32(*(((unsigned char *)&packetlen) + 1), crc); + packetinf = packetlen & PACKET_INF_MASK; + packetfirst = packetlen & PACKET_FIRST_FRAME; + receiveframeresend = packetlen & RECEIVE_FRAME_RESEND; + packetlen = packetlen & PACKET_LEN_MASK; + + + if((packetlen <= SB_MAX_BUFFER_ARRAY - 3) && (packetlen >= 6)) + { + /* read frame number */ + current_frame = inb(dev->base_addr + DAT); + crc = CRC32(current_frame, crc); + /* read HandShake counter */ + lp->HSCounter = inb(dev->base_addr + DAT); + crc = CRC32(lp->HSCounter, crc); + packetlen -= 2; + + sbni_ins(dev->base_addr + DAT, lp->eth_rcv_buffer + lp->inppos, packetlen); + + for(i = lp->inppos; i < (packetlen + lp->inppos); i++) + { + crc = CRC32(lp->eth_rcv_buffer[i], crc); + } + + if(crc == CRC32_REMAINDER) + { + if(packetlen > 4) + rcv_res=RCV_OK; + else if(packetlen == 4) + rcv_res=RCV_NO; + + if(lp->waitack && packetinf == PACKET_RESEND) + lp->in_stats.resend_tx_number++; + + + switch(packetinf) + { + case PACKET_SEND_OK: + { + lp->tr_err = TR_ERROR_COUNT; + lp->tr_resend = FALSE; + /* if(lp->trans_frame_number){ */ + lp->outpos += lp->realframelen; + + /* SendComplete + * not supported + */ + DP( printk("%s: sbni_recv SendComplete\n",dev->name); ); + /* + * We sucessfully sent current packet + */ + + if(lp->waitack) + { + dev_kfree_skb(lp->currframe); + lp->stats.tx_packets++; +#ifdef KATYUSHA + lp->currframe=skb_dequeue(&(((struct net_local*) (lp->m->priv))->queue)); +#else + lp->currframe=skb_dequeue(&lp->queue); +#endif + lp->in_stats.all_tx_number++; + lp->waitack=0; + } + + /* + * reset output active flags + */ + dev->tbusy = 0; + mark_bh(NET_BH); + /*} if */ + } + case PACKET_RESEND: + { + if(lp->tr_err) /**/ + lp->tr_err--; + if(lp->ok_curr < 0xffffffff) + lp->ok_curr++; + if(packetlen > 4 && !(lp->last_receive_OK && receiveframeresend)) + { + if(packetfirst) + { + if(lp->wait_frame_number) + { + for(i = lp->inppos, j = 0; + i < (lp->inppos + packetlen - 4); + i++, j++) + lp->eth_rcv_buffer[j] = lp->eth_rcv_buffer[i]; + } + lp->wait_frame_number = current_frame; + lp->inppos = 0; + } + if(current_frame == lp->wait_frame_number) + { + lp->inppos += (packetlen - 4); + if(lp->wait_frame_number == 1) + { + sbni_get_packet(dev); + lp->inppos = 0; + } + lp->wait_frame_number--; + } + } + lp->last_receive_OK = TRUE; + break; + } + default: + break; + } + } + else + { + DP(printk("%s: bad CRC32\n",dev->name)); + change_level(dev); + } + } + else + { + DP(printk("%s: bad len\n ",dev->name)); + change_level(dev); + lp->stats.rx_over_errors++; + } + } + else + { + DP(printk("%s: bad sig\n",dev->name)); + change_level(dev); + } + outb(inb(dev->base_addr + CSR0) ^ CT_ZER, dev->base_addr + CSR0); + return (rcv_res); +} + +void change_level(struct net_device *dev) +{ + struct net_local *lp = (struct net_local*)dev->priv; + + lp->in_stats.bad_rx_number++; + lp->stats.tx_errors++; + if(lp->rxl_delta == 0) + return; + /* + * set new rxl_delta value + */ + if(lp->rxl_curr == 0) + lp->rxl_delta = 1; + else if(lp->rxl_curr == 0xf) + lp->rxl_delta = -1; + else if(lp->ok_curr < lp->ok_prev) + lp->rxl_delta = -lp->rxl_delta; + /* + * set new rxl_curr value + */ + lp->csr1.rxl = rxl_tab[lp->rxl_curr += lp->rxl_delta]; + outb(*(char*)&lp->csr1, dev->base_addr + CSR1); + + + /* + * update ok_prev/ok_curr counters + */ + lp->ok_prev = lp->ok_curr; + lp->ok_curr = 0; + + DP( printk("%s: receive error, rxl_curr = %d, rxl_delta = %d\n",\ + dev->name,lp->rxl_curr, lp->rxl_delta); ) + +} + +static inline void sbni_xmit(struct net_device *dev) +{ + struct net_local* lp = (struct net_local *)dev->priv; + struct sk_buff *skb; + + skb=lp->currframe; + + DP( printk("%s: sbni_xmit CSR0=%02x\n",dev->name, (unsigned char)inb(dev->base_addr + CSR0)); ); + + /* push signature*/ + outb(SBNI_SIG, dev->base_addr + DAT); + + /* push frame w/o crc [HAiRY]*/ + sbni_outs(dev->base_addr + DAT, + &((struct sbni_hard_header *)(skb->data))->packetlen, + SBNI_HH_SZ - sizeof(unsigned)); + + sbni_outs(dev->base_addr + DAT, + skb->data + sizeof(struct sbni_hard_header), + skb->len - sizeof(struct sbni_hard_header)); /* ÕÓÐÅÅÍ ÅÝÅ */ + + /* push crc */ + sbni_outs(dev->base_addr + DAT, skb->data, sizeof(unsigned)); + + lp->waitack=1; +} + +/* + * The typical workload of the driver: + * Handle the ether interface interrupts. + */ +static void sbni_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct net_local* lp; + u_char csr0; + unsigned short rcv_res = RCV_NO; + + + if(dev == NULL || dev->irq != irq) + { + printk("sbni: irq %d for unknown device\n", irq); + return; + } + + if(dev->interrupt) + { + printk("%s: Reentering the interrupt driver!\n", dev->name); + return; + } + dev->interrupt = 1; + + csr0 = inb(dev->base_addr + CSR0); + DP( printk("%s: entering interrupt handler, CSR0 = %02x\n", dev->name, csr0); ) + + lp=dev->priv; + + if(!lp->carrier) + lp->carrier=1; + + /* + * Disable adapter interrupts + */ + outb((csr0 & ~EN_INT) | TR_REQ, dev->base_addr + CSR0); + lp->timer_ticks = CHANGE_LEVEL_START_TICKS; + csr0 = inb(dev->base_addr + CSR0); + + if(csr0 & (TR_RDY | RC_RDY)) + { + if(csr0 & RC_RDY) + rcv_res = sbni_recv(dev); + + if((lp->currframe) && (rcv_res != RCV_WR)) + sbni_xmit(dev); + else if (rcv_res == RCV_OK) + sbni_nirvana(dev); + + csr0 = inb(dev->base_addr + CSR0); + DP( printk("%s: CSR0 = %02x\n",dev->name, (u_int)csr0); ); + } + + + DP( printk("%s: leaving interrupt handler, CSR0 = %02x\n",dev->name, csr0 | EN_INT); ); + + /* here we should send pong */ + outb(inb(dev->base_addr+CSR0) & ~TR_REQ, dev->base_addr + CSR0); + if(lp->currframe) + outb(inb(dev->base_addr+CSR0) | TR_REQ, dev->base_addr + CSR0); + else + csr0 = inb(dev->base_addr + CSR0); + + /* + * Enable adapter interrupts + */ + + outb(csr0 | EN_INT, dev->base_addr + CSR0); + dev->interrupt = 0; +} + +static struct enet_statistics *sbni_get_stats(struct net_device *dev) +{ + struct net_local *lp = (struct net_local *)dev->priv; + return &lp->stats; +} + +static inline void sbni_get_packet(struct net_device* dev) +{ + struct net_local* lp = (struct net_local*)dev->priv; + struct sk_buff* skb; + unsigned char *rawp; + + + + skb = dev_alloc_skb(lp->inppos - ETH_HLEN + sizeof(struct sbni_hard_header)); + + if(skb == NULL) + { + DP( printk("%s: Memory squeeze, dropping packet.\n", dev->name); ) + lp->stats.rx_dropped++; + return; + } else { +#ifdef KATYUSHA + skb->dev = lp->m; +#else + skb->dev = dev; +#endif + memcpy((unsigned char*)skb_put(skb, lp->inppos + 8)+8, + lp->eth_rcv_buffer, + lp->inppos); + + + skb->mac.raw = skb->data + 8; + + if((*(char*)lp->eth_rcv_buffer) & 1) + { + if(memcmp(lp->eth_rcv_buffer,dev->broadcast, ETH_ALEN)==0) + skb->pkt_type=PACKET_BROADCAST; + else + skb->pkt_type=PACKET_MULTICAST; + } + else if(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)) + { + if(memcmp(lp->eth_rcv_buffer,dev->dev_addr, ETH_ALEN)) + skb->pkt_type=PACKET_OTHERHOST; + } + + if( htons(*((unsigned short*)(&lp->eth_rcv_buffer[2*ETH_ALEN]))) >= 1536) + skb->protocol = *((unsigned short*)(&lp->eth_rcv_buffer[2*ETH_ALEN])); + else + { + rawp = (unsigned char*)(&lp->eth_rcv_buffer[2*ETH_ALEN]); + if (*(unsigned short *)rawp == 0xFFFF) + skb->protocol=htons(ETH_P_802_3); + else + skb->protocol=htons(ETH_P_802_2); + } + + + skb_pull(skb,SBNI_HH_SZ); + + netif_rx(skb); + lp->stats.rx_packets++; + } + return; +} + +static void sbni_watchdog(unsigned long arg) +{ + struct net_device* dev = (struct net_device*)arg; + struct net_local* lp = (struct net_local *)dev->priv; + u_char csr0; + + + + DP( printk("%s: watchdog start\n",dev->name); ) + /* + * if no pong received and transmission is not in progress + * then assume error + */ + cli(); + csr0 = inb(dev->base_addr + CSR0); + if(csr0 & (RC_CHK | TR_REQ)) + { + if(lp->timer_ticks) + { + if(csr0 & (RC_RDY | BU_EMP)) + { + lp->timer_ticks--; + } + } + else + { + if(lp->rxl_delta) + { + lp->ok_prev = lp->ok_curr; + lp->ok_curr = 0; + lp->rxl_curr = timeout_rxl_tab[lp->timeout_rxl]; + lp->timeout_rxl++; + if(lp->timeout_rxl > SIZE_OF_TIMEOUT_RXL_TAB - 1) + lp->timeout_rxl = 0; + lp->csr1.rxl = rxl_tab[lp->rxl_curr]; + /* + * update ok_prev/ok_curr counters + */ + lp->ok_prev = lp->ok_curr; + lp->ok_curr = 0; + } + if(lp->tr_err) + lp->tr_err--; + else + { + /* Drop the queue of tx packets */ + sbni_drop_tx_queue(dev); + lp->carrier=0; + } + + /* + * send pong + */ + + csr0 = inb(dev->base_addr + CSR0); + outb(csr0 & ~TR_REQ, dev->base_addr + CSR0); + outb(*(char*)(&lp->csr1) | PR_RES, dev->base_addr + CSR1); + lp->in_stats.timeout_number++; + } + } + sti(); + outb(csr0 | RC_CHK, dev->base_addr + CSR0); + if(dev->start) + { + struct timer_list* watchdog = &lp->watchdog; + init_timer(watchdog); + watchdog->expires = jiffies + SBNI_TIMEOUT; + watchdog->data = arg; + watchdog->function = sbni_watchdog; + add_timer(watchdog); + } +} + +static void sbni_drop_tx_queue(struct net_device *dev) +{ + struct net_local* lp = (struct net_local *)dev->priv,*nl; + struct sk_buff *tmp; + + /* first of all, we should try to gift our packets to another interface */ + + nl=(struct net_local *)lp->m->priv; + if(nl==lp) + nl=lp->next_lp; + + if(nl) + { + /* we found device*/ + if(lp->currframe) + { + if(!nl->currframe) + { + nl->currframe=lp->currframe; + } + else + { + skb_queue_head(&((struct net_local*)(lp->m->priv))->queue,lp->currframe); + } + } + lp->currframe=NULL; + + if(!nl->currframe) + nl->currframe=skb_dequeue(&(((struct net_local*)(lp->m->priv))->queue)); + + /* set request for transmit */ + outb(inb(nl->me->base_addr + CSR0) | TR_REQ, nl->me->base_addr + CSR0); + + } + else + { + /* *sigh*, we should forget this packets */ + nl=lp->m->priv; + + while((tmp = skb_dequeue(&nl->queue)) != NULL) + { + dev_kfree_skb(tmp); + lp->stats.tx_packets++; + } + + if (lp->currframe) + { + dev_kfree_skb(lp->currframe); + lp->currframe = NULL; + lp->stats.tx_packets++; + } + } + lp->waitack=0; + dev->tbusy = 0; + + mark_bh(NET_BH); + DP( printk("%s: queue dropping stoped\n",dev->name); ); +} + +/* + * Set or clear the multicast filter for this adaptor. + * num_addrs == -1 Promiscuous mode, receive all packets + * num_addrs == 0 Normal mode, clear multicast list + * num_addrs > 0 Multicast mode, receive normal and MC packets, + * and do best-effort filtering. + */ + +static void set_multicast_list(struct net_device *dev) +{ + /* + * always enabled promiscuous mode. + */ + return; +} + +static int sbni_set_mac_address(struct net_device *dev, void *addr) +{ + /* struct net_local *lp = (struct net_local *)dev->priv; */ + struct sockaddr *saddr = addr; + + if(dev->start) + { + /* Only possible while card isn't started */ + return -EBUSY; + } + memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len); + return (0); +} + +static int sbni_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct net_local* lp = (struct net_local *)dev->priv,*tlp; + struct net_device *slave; + int error = 0; + char tmpstr[6]; + + + switch(cmd) + { + case SIOCDEVGETINSTATS: + { + struct sbni_in_stats *in_stats = (struct sbni_in_stats *)ifr->ifr_data; + DP( printk("%s: SIOCDEVGETINSTATS %08x\n",dev->name,(unsigned)in_stats);) + if(copy_to_user((void *)in_stats, (void *)(&(lp->in_stats)), sizeof(struct sbni_in_stats))) + return -EFAULT; + break; + } + case SIOCDEVRESINSTATS: + { + DP( printk("%s: SIOCDEVRESINSTATS\n",dev->name); ) + lp->in_stats.all_rx_number = 0; + lp->in_stats.bad_rx_number = 0; + lp->in_stats.timeout_number = 0; + lp->in_stats.all_tx_number = 0; + lp->in_stats.resend_tx_number = 0; + break; + } + case SIOCDEVGHWSTATE: + { + struct sbni_flags flags; + flags.rxl = lp->rxl_curr; + flags.rate = lp->csr1.rate; + flags.fixed_rxl = (lp->rxl_delta == 0); + flags.fixed_rate = 1; + ifr->ifr_data = *(caddr_t*)&flags; + DP( printk("%s: get flags (0x%02x)\n",dev->name, (unsigned char)ifr->ifr_data); ) + break; + } + case SIOCDEVSHWSTATE: + { + struct sbni_flags flags; + DP( printk("%s: SIOCDEVSHWSTATE flags=0x%02x\n",dev->name, (unsigned char)ifr->ifr_data); ) + /* root only */ + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + flags = *(struct sbni_flags*)&ifr->ifr_data; + if(flags.fixed_rxl) + { + lp->rxl_delta = 0; + lp->rxl_curr = flags.rxl; + } + else + { + lp->rxl_delta = DEF_RXL_DELTA; + lp->rxl_curr = DEF_RXL; + } + lp->csr1.rxl = rxl_tab[lp->rxl_curr]; + if(flags.fixed_rate) + lp->csr1.rate = flags.rate; + else + lp->csr1.rate = DEF_RATE; + /* + * Don't be afraid... + */ + outb(*(char*)(&lp->csr1) | PR_RES, dev->base_addr + CSR1); + + DP( printk("%s: set flags (0x%02x)\n receive level: %u, baud rate: %u\n",\ + dev->name, (unsigned char)ifr->ifr_data, (unsigned)lp->rxl_curr, (unsigned)lp->csr1.rate); ) + break; + } + + case SIOCDEVENSLAVE: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + if(copy_from_user( tmpstr, ifr->ifr_data, 6)) + return -EFAULT; + slave=dev_get(tmpstr); + if(!(slave && slave->flags & IFF_UP && dev->flags & IFF_UP)) + { + printk("%s: Both devices should be UP to enslave!\n",dev->name); + return -EINVAL; + } + + if(slave) + { + if(!((dev->flags & IFF_SLAVE) || (slave->flags & IFF_SLAVE))) + { + /* drop queue*/ + sbni_drop_tx_queue(slave); + slave->flags |= IFF_SLAVE; + ((struct net_local *)(slave->priv))->m=dev; + while(lp->next_lp) //tail it after last slave + lp=lp->next_lp; + lp->next_lp=slave->priv; + lp=(struct net_local *)dev->priv; + dev->flags |= IFF_MASTER; + } + else + { + printk("%s: one of devices is already slave!\n",dev->name); + return -EBUSY; + } + } + else + { + printk("%s: can't find device %s to enslave\n",dev->name,ifr->ifr_data); + return -ENOENT; + } + break; + + case SIOCDEVEMANSIPATE: + if(!capable(CAP_NET_ADMIN)) + return -EPERM; + + if(dev->flags & IFF_SLAVE) + { + dev->flags &= ~IFF_SLAVE; + /* exclude us from masters slavelist*/ + for(tlp=lp->m->priv;tlp->next_lp!=lp && tlp->next_lp;tlp=tlp->next_lp); + if(tlp->next_lp) + { + tlp->next_lp = lp->next_lp; + if(!((struct net_local *)lp->m->priv)->next_lp) + { + lp->m->flags &= ~IFF_MASTER; + } + lp->next_lp=NULL; + lp->m=dev; + } + else + { + printk("%s: Ooops. drivers structure is mangled!\n",dev->name); + return -EIO; + } + } + else + { + printk("%s: isn't slave device!\n",dev->name); + return -EINVAL; + } + break; + + default: + DP( printk("%s: invalid ioctl: 0x%x\n",dev->name, cmd); ) + error = -EINVAL; + } + return (error); +} + + + +#ifdef CRCASM + +unsigned long calc_crc(char *mem, int len, unsigned initial) +{ + + __asm__ ( + "xorl %%eax,%%eax\n\t" + "1:\n\t" + "lodsb\n\t" + "xorb %%dl,%%al\n\t" + "shrl $8,%%edx\n\t" + "xorl (%%edi,%%eax,4),%%edx\n\t" + "loop 1b\n\t" + "movl %%edx,%%eax" + : + : "S" (mem), "D" (&crc32tab[0]), "c" (len), "d" (initial) + : "eax", "edx", "ecx" + ); + /* return crc; */ +} + +#else + +unsigned long calc_crc(char *mem, int len, unsigned initial) +{ + unsigned crc; + crc = initial; + + for(;len;mem++,len--) + { + crc = CRC32(*mem, crc); + } + return(crc); +} +#endif /* CRCASM */ +#ifdef MODULE + +static int io[SBNI_MAX_NUM_CARDS] = { 0 }; +static int irq[SBNI_MAX_NUM_CARDS] = { 0 }; +static int rxl[SBNI_MAX_NUM_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +static int baud[SBNI_MAX_NUM_CARDS] = { 0 }; +static long mac[SBNI_MAX_NUM_CARDS] = { 0 }; + +#ifdef v22 +MODULE_PARM(io, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(irq, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(rxl, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(baud, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +MODULE_PARM(mac, "1-" __MODULE_STRING(SBNI_MAX_NUM_CARDS) "i"); +#endif + + +static int sbniautodetect = -1; + +static struct net_device dev_sbni[SBNI_MAX_NUM_CARDS] = { + { + "sbni0", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni1", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni2", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni3", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni4", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni5", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni6", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + }, + { + "sbni7", + 0, 0, 0, 0, /* memory */ + 0, 0, /* base, irq */ + 0, 0, 0, NULL, sbni_probe + } +}; + +int init_module(void) +{ + int devices = 0; + int installed = 0; + int i; + + /* My simple plug for this huge init_module. "XenON */ + + if(sbniautodetect != -1) + { + /* Autodetect mode */ + printk("sbni: Autodetect mode (not recommended!) ...\n"); + if(!sbniautodetect) + sbniautodetect=SBNI_MAX_NUM_CARDS; + printk("Trying to find %d SBNI cards...\n", sbniautodetect); + if(sbniautodetect > SBNI_MAX_NUM_CARDS) + { + sbniautodetect = SBNI_MAX_NUM_CARDS; + printk("sbni: You want to detect too many cards. Truncated to %d\n", SBNI_MAX_NUM_CARDS); + } + for(i = 0; i < sbniautodetect; i++) + { + if(!register_netdev(&dev_sbni[i])) + installed++; + } + if(installed) + return 0; + else + return -EIO; + } + + /* Manual mode */ + for(i = 0; i < SBNI_MAX_NUM_CARDS; i++) + { + if((io[i] != 0) || (irq[i] != 0)) + devices++; + } + for(i = 0; i < devices; i++) + { + dev_sbni[i].irq = irq[i]; + dev_sbni[i].base_addr = io[i]; + def_rxl = rxl[i]; + def_baud = baud[i]; + def_mac = mac[i]; + if(register_netdev(&dev_sbni[i])) + printk("sbni: card not found!\n"); + else + installed++; + } + if(installed) + return 0; + else + return -EIO; +} + +void cleanup_module(void) +{ + int i; + for(i = 0; i < 4; i++) + { + if(dev_sbni[i].priv) + { + free_irq(dev_sbni[i].irq, &dev_sbni[i]); + release_region(dev_sbni[i].base_addr, SBNI_IO_EXTENT); + unregister_netdev(&dev_sbni[i]); + kfree(dev_sbni[i].priv); + dev_sbni[i].priv = NULL; + } + } +} +#endif /* MODULE */ diff --git a/drivers/net/wan/sbni.h b/drivers/net/wan/sbni.h new file mode 100644 index 000000000000..2e34d8d3451d --- /dev/null +++ b/drivers/net/wan/sbni.h @@ -0,0 +1,194 @@ +/* + * sbni.h - header file for sbni linux device driver + * + * Copyright (C) 1999 Granch ltd., Yaroslav Polyakov (xenon@granch.ru). + * + */ + +/* + * SBNI12 definitions + * + * Revision 2.0.0 1997/08/27 + * Initial revision + * + * Revision 2.1.0 1999/04/26 + * dev_priv structure changed to support balancing and some other features. + * + */ + +#ifndef __SBNI_H +#define __SBNI_H + +#define SBNI_DEBUG 0 + +#if SBNI_DEBUG +#define DP( A ) A +#else +#define DP( A ) +#endif + +typedef unsigned char BOOLEAN; + +#define TRUE 1 +#define FALSE 0 + +#define SBNI_IO_EXTENT 0x4 +#define SB_MAX_BUFFER_ARRAY 1023 + +#define CSR0 0 +#define CSR1 1 + +#define DAT 2 + +/* CSR0 mapping */ +#define BU_EMP (1 << 1) /* r z */ +#define RC_CHK (1 << 2) /* rw */ +#define CT_ZER (1 << 3) /* w */ +#define TR_REQ (1 << 4) /* rwz* */ + +#define TR_RDY (1 << 5) /* r z */ +#define EN_INT (1 << 6) /* rwz* */ +#define RC_RDY (1 << 7) /* r z */ + +/* CSR1 mapping */ +#define PR_RES (1 << 7) /* w */ + +struct sbni_csr1 { + unsigned rxl:5; + unsigned rate:2; + unsigned:1; +}; + +#define DEF_RXL_DELTA -1 +#define DEF_RXL 0xf +#define DEF_RATE 0 +#define DEF_FRAME_LEN (1023 - 14 - 9) + +#ifdef MODULE + +#define SBNI_MAX_NUM_CARDS 8 +#define SBNI_MAX_SLAVES 8 + + +#endif /* MODULE */ + +#define SBNI_SIG 0x5a + +#define SB_ETHER_MIN_LEN 60 + +#define SB_FILLING_CHAR (unsigned char)0x00 +#define TR_ERROR_COUNT 32 +#define CHANGE_LEVEL_START_TICKS 4 +#define SBNI_INTERNAL_QUEUE_SIZE 10 /* 100 ? */ + +#define PACKET_FIRST_FRAME (unsigned short)0x8000 +#define RECEIVE_FRAME_RESEND (unsigned short)0x0800 +#define PACKET_RESEND 0x4000 +#define PACKET_SEND_OK 0x3000 +#define PACKET_LEN_MASK (unsigned short)0x03ff +#define PACKET_INF_MASK (unsigned short)0x7000 + +#define ETHER_ADDR_LEN 6 + +#define SBNI_TIMEOUT HZ/10 /* ticks to wait for pong or packet */ + /* sbni watchdog called SBNI_HZ times per sec. */ + +struct sbni_in_stats { + unsigned int all_rx_number; + unsigned int bad_rx_number; + unsigned int timeout_number; + unsigned int all_tx_number; + unsigned int resend_tx_number; +}; + + +/* + * Board-specific info in dev->priv. + */ +struct net_local { + struct enet_statistics stats; + + struct timer_list watchdog; + unsigned int realframelen; /* the current size of the SB-frame */ + unsigned int eth_trans_buffer_len; /* tx buffer length */ + unsigned int outpos; + unsigned int inppos; + unsigned int frame_len; /* The set SB-frame size */ + unsigned int tr_err; + unsigned int timer_ticks; + BOOLEAN last_receive_OK; + BOOLEAN tr_resend; + + unsigned char wait_frame_number; + unsigned char eth_trans_buffer[1520]; /* tx buffer */ + unsigned char HSCounter; /* Reserved field */ + unsigned char eth_rcv_buffer[2600]; /* rx buffer */ + struct sbni_csr1 csr1; + /* Internal Statistics */ + struct sbni_in_stats in_stats; + + int rxl_curr; /* current receive level value [0..0xf] */ + int rxl_delta; /* receive level delta (+1, -1) + rxl_delta == 0 - receive level + autodetection + disabled */ + unsigned int ok_curr; /* current ok frames received */ + unsigned int ok_prev; /* previous ok frames received */ + unsigned int timeout_rxl; + + struct sk_buff_head queue; + struct sk_buff *currframe; + BOOLEAN waitack; + + struct net_device *m; /* master */ + struct net_device *me; /* me */ + struct net_local *next_lp; /* next lp */ + + int carrier; + + +}; + + +struct sbni_hard_header { + + /* internal sbni stuff */ + unsigned int crc; /* 4 */ + unsigned short packetlen; /* 2 */ + unsigned char number; /* 1 */ + unsigned char reserv; /* 1 */ + + /* 8 */ + + /* ethernet stuff */ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ + /* +14 */ + /* 22 */ + +}; + +#define SBNI_HH_SZ 22 + +struct sbni_flags { + unsigned rxl:4; + unsigned rate:2; + unsigned fixed_rxl:1; + unsigned fixed_rate:1; +}; + +#define RCV_NO 0 +#define RCV_OK 1 +#define RCV_WR 2 + + +#define SIOCDEVGETINSTATS SIOCDEVPRIVATE +#define SIOCDEVRESINSTATS SIOCDEVPRIVATE+1 +#define SIOCDEVGHWSTATE SIOCDEVPRIVATE+2 +#define SIOCDEVSHWSTATE SIOCDEVPRIVATE+3 +#define SIOCDEVENSLAVE SIOCDEVPRIVATE+4 +#define SIOCDEVEMANSIPATE SIOCDEVPRIVATE+5 + + +#endif /* __SBNI_H */ diff --git a/drivers/net/sdla.c b/drivers/net/wan/sdla.c similarity index 100% rename from drivers/net/sdla.c rename to drivers/net/wan/sdla.c diff --git a/drivers/net/sdla_fr.c b/drivers/net/wan/sdla_fr.c similarity index 100% rename from drivers/net/sdla_fr.c rename to drivers/net/wan/sdla_fr.c diff --git a/drivers/net/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c similarity index 100% rename from drivers/net/sdla_ppp.c rename to drivers/net/wan/sdla_ppp.c diff --git a/drivers/net/sdla_x25.c b/drivers/net/wan/sdla_x25.c similarity index 100% rename from drivers/net/sdla_x25.c rename to drivers/net/wan/sdla_x25.c diff --git a/drivers/net/sdladrv.c b/drivers/net/wan/sdladrv.c similarity index 99% rename from drivers/net/sdladrv.c rename to drivers/net/wan/sdladrv.c index 7182dff425d1..5e1f6b99e9a0 100644 --- a/drivers/net/sdladrv.c +++ b/drivers/net/wan/sdladrv.c @@ -5,6 +5,7 @@ * used by all Sangoma drivers. * * Author: Gene Kozin +* Fixes: Arnaldo Carvalho de Melo * * Copyright: (c) 1995-1996 Sangoma Technologies Inc. * diff --git a/drivers/net/sdlamain.c b/drivers/net/wan/sdlamain.c similarity index 99% rename from drivers/net/sdlamain.c rename to drivers/net/wan/sdlamain.c index ca98eeff98e0..23b811fc91e6 100644 --- a/drivers/net/sdlamain.c +++ b/drivers/net/wan/sdlamain.c @@ -3,6 +3,7 @@ * * Author: Gene Kozin * Jaspreet Singh +* Fixes: Arnaldo Carvalho de Melo * * Copyright: (c) 1995-1997 Sangoma Technologies Inc. * diff --git a/drivers/net/sealevel.c b/drivers/net/wan/sealevel.c similarity index 99% rename from drivers/net/sealevel.c rename to drivers/net/wan/sealevel.c index 1dc146711dfd..5cbbff8c9522 100644 --- a/drivers/net/sealevel.c +++ b/drivers/net/wan/sealevel.c @@ -340,7 +340,7 @@ static struct slvl_board *slvl_init(int iobase, int irq, int txdma, int rxdma, i for(i=0;i<999;i++) { sprintf(sv->name,"hdlc%d", i); - if(dev_get(sv->name)==NULL) + if(dev_get(sv->name)==0) { struct net_device *d=sv->chan->netdevice; diff --git a/drivers/net/syncppp.c b/drivers/net/wan/syncppp.c similarity index 100% rename from drivers/net/syncppp.c rename to drivers/net/wan/syncppp.c diff --git a/drivers/net/syncppp.h b/drivers/net/wan/syncppp.h similarity index 100% rename from drivers/net/syncppp.h rename to drivers/net/wan/syncppp.h diff --git a/drivers/net/x25_asy.c b/drivers/net/wan/x25_asy.c similarity index 100% rename from drivers/net/x25_asy.c rename to drivers/net/wan/x25_asy.c diff --git a/drivers/net/x25_asy.h b/drivers/net/wan/x25_asy.h similarity index 100% rename from drivers/net/x25_asy.h rename to drivers/net/wan/x25_asy.h diff --git a/drivers/net/z85230.c b/drivers/net/wan/z85230.c similarity index 100% rename from drivers/net/z85230.c rename to drivers/net/wan/z85230.c diff --git a/drivers/net/z85230.h b/drivers/net/wan/z85230.h similarity index 100% rename from drivers/net/z85230.h rename to drivers/net/wan/z85230.h diff --git a/drivers/pnp/Config.in b/drivers/pnp/Config.in index a350c45266f0..de0fa6cfa201 100644 --- a/drivers/pnp/Config.in +++ b/drivers/pnp/Config.in @@ -6,6 +6,6 @@ comment 'Plug and Play configuration' tristate 'Plug and Play support' CONFIG_PNP -dep_tristate 'ISA Plug and Play support' CONFIG_ISAPNP $CONFIG_PNP +dep_tristate ' ISA Plug and Play support' CONFIG_ISAPNP $CONFIG_PNP endmenu diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c index dc34fe4cd245..3857c487d51e 100644 --- a/drivers/sbus/char/pcikbd.c +++ b/drivers/sbus/char/pcikbd.c @@ -764,7 +764,7 @@ void pcimouse_interrupt(int irq, void *dev_id, struct pt_regs *regs) queue->head = head; aux_ready = 1; if (queue->fasync) - kill_fasync(queue->fasync, SIGIO); + kill_fasync(queue->fasync, SIGIO, POLL_IN); wake_up_interruptible(&queue->proc_list); } diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c index e8e6a168c5fe..2b3a99604d5e 100644 --- a/drivers/sbus/char/sunkbd.c +++ b/drivers/sbus/char/sunkbd.c @@ -1273,7 +1273,7 @@ push_kbd (int scan) kbd_head = next; } if (kb_fasync) - kill_fasync (kb_fasync, SIGIO); + kill_fasync (kb_fasync, SIGIO, POLL_IN); wake_up_interruptible (&kbd_wait); } diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c index 77fe2ee77ca9..c3d8462e6818 100644 --- a/drivers/sbus/char/sunmouse.c +++ b/drivers/sbus/char/sunmouse.c @@ -137,7 +137,7 @@ push_char (char c) } sunmouse.ready = 1; if (sunmouse.fasync) - kill_fasync (sunmouse.fasync, SIGIO); + kill_fasync (sunmouse.fasync, SIGIO, POLL_IN); wake_up_interruptible (&sunmouse.proc_list); } @@ -334,7 +334,7 @@ sun_mouse_inbyte(unsigned char byte) */ sunmouse.ready = 1; if (sunmouse.fasync) - kill_fasync (sunmouse.fasync, SIGIO); + kill_fasync (sunmouse.fasync, SIGIO, POLL_IN); wake_up_interruptible(&sunmouse.proc_list); } return; diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index b11de29ebd0a..ccf2268d8a07 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -92,7 +92,7 @@ static struct miscdevice uctrl_dev = { #ifdef MODULE int init_module(void) #else -__initfunc(int uctrl_init(void)) +int __init uctrl_init(void) #endif { struct uctrl_driver *driver = &drv; diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 74c3c9d22278..4a2258cb53b1 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -815,7 +815,7 @@ static void sg_command_done(Scsi_Cmnd * SCpnt) /* Now wake up any sg_read() that is waiting for this packet. */ wake_up_interruptible(&sfp->read_wait); if ((sfp->async_qp) && (! closed)) - kill_fasync(sfp->async_qp, SIGPOLL); + kill_fasync(sfp->async_qp, SIGPOLL, POLL_IN); } static void sg_debug_all(const Sg_fd * sfp) diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c index 5f4ece09f3ea..59518b1536a8 100644 --- a/drivers/sgi/char/shmiq.c +++ b/drivers/sgi/char/shmiq.c @@ -118,7 +118,7 @@ shmiq_push_event (struct shmqevent *e) s->tail = tail_next; shmiqs [device].tail = tail_next; if (shmiqs [device].fasync) - kill_fasync (shmiqs [device].fasync, SIGIO); + kill_fasync (shmiqs [device].fasync, SIGIO, POLL_IN); wake_up_interruptible (&shmiqs [device].proc_list); } diff --git a/drivers/usb/audio.c b/drivers/usb/audio.c index 7d78404ee157..291f424dcbaf 100644 --- a/drivers/usb/audio.c +++ b/drivers/usb/audio.c @@ -769,7 +769,7 @@ static int usbin_retire_desc(struct usbin *u, struct usb_isoc_desc *id) static int usbin_completed(int status, void *__buffer, int rval, void *dev_id) { -#if 0 +#if 1 struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; struct usb_audiodev *as = (struct usb_audiodev *)id->context; #else @@ -777,10 +777,13 @@ static int usbin_completed(int status, void *__buffer, int rval, void *dev_id) struct usb_isoc_desc *id; #endif struct usbin *u = &as->usbin; + unsigned long flags; unsigned int next, idmask; +#if 0 printk(KERN_DEBUG "usbin_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); - spin_lock(&as->lock); +#endif + spin_lock_irqsave(&as->lock, flags); next = !(u->flags & FLG_NEXTID); idmask = FLG_ID1RUNNING >> next; u->flags = (u->flags & ~(FLG_NEXTID | idmask)) | next; @@ -794,7 +797,12 @@ static int usbin_completed(int status, void *__buffer, int rval, void *dev_id) u->flags &= ~FLG_RUNNING; printk(KERN_DEBUG "usbin_completed: descriptor not restarted\n"); } - spin_unlock(&as->lock); + if (!(u->flags & idmask)) { + printk(KERN_DEBUG "usbin_completed: killing id\n"); + usb_kill_isoc(id); + printk(KERN_DEBUG "usbin_completed: id killed\n"); + } + spin_unlock_irqrestore(&as->lock, flags); return 0; } @@ -833,7 +841,7 @@ static int usbin_sync_retire_desc(struct usbin *u, struct usb_isoc_desc *id) static int usbin_sync_completed(int status, void *__buffer, int rval, void *dev_id) { -#if 0 +#if 1 struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; struct usb_audiodev *as = (struct usb_audiodev *)id->context; #else @@ -841,13 +849,16 @@ static int usbin_sync_completed(int status, void *__buffer, int rval, void *dev_ struct usb_isoc_desc *id; #endif struct usbin *u = &as->usbin; + unsigned long flags; unsigned int next, idmask; +#if 0 printk(KERN_DEBUG "usbin_sync_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); - spin_lock(&as->lock); +#endif + spin_lock_irqsave(&as->lock, flags); next = !(u->flags & FLG_SYNCNEXTID); idmask = FLG_SYNC1RUNNING >> next; - u->flags = (u->flags & ~(FLG_SYNCNEXTID | idmask)) | (-next & FLG_SYNCNEXTID); + u->flags = (u->flags & ~(FLG_SYNCNEXTID | idmask)) | ((-next) & FLG_SYNCNEXTID); id = u->synciso[!next]; if (!usbin_sync_retire_desc(u, id) && u->flags & FLG_RUNNING && @@ -858,7 +869,12 @@ static int usbin_sync_completed(int status, void *__buffer, int rval, void *dev_ u->flags &= ~FLG_RUNNING; printk(KERN_DEBUG "usbin_sync_completed: descriptor not restarted\n"); } - spin_unlock(&as->lock); + if (!(u->flags & idmask)) { + printk(KERN_DEBUG "usbin_sync_completed: killing id\n"); + usb_kill_isoc(id); + printk(KERN_DEBUG "usbin_sync_completed: id killed\n"); + } + spin_unlock_irqrestore(&as->lock, flags); return 0; } @@ -870,8 +886,10 @@ static void usbin_start(struct usb_audiodev *as) unsigned long flags; unsigned int which, i; - printk(KERN_DEBUG "usbin_start: device %d ufmt %d dfmt %d srate %d\n", +#if 0 + printk(KERN_DEBUG "usbin_start: device %d ufmt 0x%08x dfmt 0x%08x srate %d\n", dev->devnum, u->format, u->dma.format, u->dma.srate); +#endif /* allocate USB storage if not already done */ /* UHCI wants the data to be page aligned - this is silly */ if (!u->data[0]) @@ -980,15 +998,18 @@ static void usbout_stop(struct usb_audiodev *as) unsigned long flags; unsigned int i; +printk(KERN_DEBUG "usb_audio: usbout_stop (1) flags 0x%04x\n", u->flags); spin_lock_irqsave(&as->lock, flags); u->flags &= ~FLG_RUNNING; i = u->flags; spin_unlock_irqrestore(&as->lock, flags); +printk(KERN_DEBUG "usb_audio: usbout_stop (2) flags 0x%04x\n", i); while (i & (FLG_ID0RUNNING|FLG_ID1RUNNING|FLG_SYNC0RUNNING|FLG_SYNC1RUNNING)) { schedule_timeout(1); spin_lock_irqsave(&as->lock, flags); i = u->flags; spin_unlock_irqrestore(&as->lock, flags); +printk(KERN_DEBUG "usb_audio: usbout_stop (3) flags 0x%04x\n", i); } if (u->dataiso[0]) usb_free_isoc(u->dataiso[0]); @@ -1219,7 +1240,7 @@ static int usbout_retire_desc(struct usbout *u, struct usb_isoc_desc *id) static int usbout_completed(int status, void *__buffer, int rval, void *dev_id) { -#if 0 +#if 1 struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; struct usb_audiodev *as = (struct usb_audiodev *)id->context; #else @@ -1227,10 +1248,13 @@ static int usbout_completed(int status, void *__buffer, int rval, void *dev_id) struct usb_isoc_desc *id; #endif struct usbout *u = &as->usbout; + unsigned long flags; unsigned int next, idmask; +#if 0 printk(KERN_DEBUG "usbout_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); - spin_lock(&as->lock); +#endif + spin_lock_irqsave(&as->lock, flags); next = !(u->flags & FLG_NEXTID); idmask = FLG_ID1RUNNING >> next; u->flags = (u->flags & ~(FLG_NEXTID | idmask)) | next; @@ -1244,7 +1268,12 @@ static int usbout_completed(int status, void *__buffer, int rval, void *dev_id) u->flags &= ~FLG_RUNNING; printk(KERN_DEBUG "usbout_completed: descriptor not restarted\n"); } - spin_unlock(&as->lock); + if (!(u->flags & idmask)) { + printk(KERN_DEBUG "usbout_completed: killing id\n"); + usb_kill_isoc(id); + printk(KERN_DEBUG "usbout_completed: id killed\n"); + } + spin_unlock_irqrestore(&as->lock, flags); return 0; } @@ -1286,7 +1315,7 @@ static int usbout_sync_retire_desc(struct usbout *u, struct usb_isoc_desc *id) static int usbout_sync_completed(int status, void *__buffer, int rval, void *dev_id) { -#if 0 +#if 1 struct usb_isoc_desc *id = (struct usb_isoc_desc *)dev_id; struct usb_audiodev *as = (struct usb_audiodev *)id->context; #else @@ -1294,13 +1323,16 @@ static int usbout_sync_completed(int status, void *__buffer, int rval, void *dev struct usb_isoc_desc *id; #endif struct usbout *u = &as->usbout; + unsigned long flags; unsigned int next, idmask; +#if 0 printk(KERN_DEBUG "usbout_sync_completed: status %d rval %d flags 0x%x\n", status, rval, u->flags); - spin_lock(&as->lock); +#endif + spin_lock_irqsave(&as->lock, flags); next = !(u->flags & FLG_SYNCNEXTID); idmask = FLG_SYNC1RUNNING >> next; - u->flags = (u->flags & ~(FLG_SYNCNEXTID | idmask)) | (-next & FLG_SYNCNEXTID); + u->flags = (u->flags & ~(FLG_SYNCNEXTID | idmask)) | ((-next) & FLG_SYNCNEXTID); id = u->synciso[!next]; if (!usbout_sync_retire_desc(u, id) && u->flags & FLG_RUNNING && @@ -1311,7 +1343,12 @@ static int usbout_sync_completed(int status, void *__buffer, int rval, void *dev u->flags &= ~FLG_RUNNING; printk(KERN_DEBUG "usbout_sync_completed: descriptor not restarted\n"); } - spin_unlock(&as->lock); + if (!(u->flags & idmask)) { + printk(KERN_DEBUG "usbout_sync_completed: killing id\n"); + usb_kill_isoc(id); + printk(KERN_DEBUG "usbout_sync_completed: id killed\n"); + } + spin_unlock_irqrestore(&as->lock, flags); return 0; } @@ -1323,8 +1360,10 @@ static void usbout_start(struct usb_audiodev *as) unsigned long flags; unsigned int which, i; - printk(KERN_DEBUG "usbout_start: device %d ufmt %d dfmt %d srate %d\n", +#if 0 + printk(KERN_DEBUG "usbout_start: device %d ufmt 0x%08x dfmt 0x%08x srate %d\n", dev->devnum, u->format, u->dma.format, u->dma.srate); +#endif /* allocate USB storage if not already done */ /* UHCI wants the data to be page aligned - this is silly */ if (!u->data[0]) @@ -1459,7 +1498,7 @@ static int set_format_in(struct usb_audiodev *as) struct usbin *u = &as->usbin; struct dmabuf *d = &u->dma; struct audioformat *fmt; - unsigned int fmtnr; + unsigned int fmtnr, ep; unsigned char data[3]; if (u->interface < 0 || u->interface >= config->bNumInterfaces) @@ -1474,7 +1513,7 @@ static int set_format_in(struct usb_audiodev *as) if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x08) { if (alts->bNumEndpoints < 2 || alts->endpoint[1].bmAttributes != 0x01 || - alts->endpoint[1].bSynchAddress == 0 || + alts->endpoint[1].bSynchAddress != 0 || alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress & 0x7f)) { printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n", dev->devnum, u->interface, fmt->altsetting); @@ -1497,18 +1536,21 @@ static int set_format_in(struct usb_audiodev *as) data[0] = d->srate; data[1] = d->srate >> 8; data[2] = d->srate >> 16; + ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN); if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, - SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { - printk(KERN_ERR "usbaudio: failure to set sampling frequency device %d endpoint %d\n", - dev->devnum, usb_pipeendpoint(u->datapipe)); + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { + printk(KERN_ERR "usbaudio: failure to set input sampling frequency device %d endpoint 0x%x to %u\n", + dev->devnum, ep, d->srate); return -1; } if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, - SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { - printk(KERN_ERR "usbaudio: failure to get sampling frequency device %d endpoint %d\n", - dev->devnum, usb_pipeendpoint(u->datapipe)); + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { + printk(KERN_ERR "usbaudio: failure to get input sampling frequency device %d endpoint 0x%x\n", + dev->devnum, ep); return -1; } + printk(KERN_DEBUG "usb_audio: set_format_in: device %d interface %d altsetting %d srate req: %u real %u\n", + dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)); d->srate = data[0] | (data[1] << 8) | (data[2] << 16); return 0; } @@ -1522,7 +1564,7 @@ static int set_format_out(struct usb_audiodev *as) struct usbout *u = &as->usbout; struct dmabuf *d = &u->dma; struct audioformat *fmt; - unsigned int fmtnr; + unsigned int fmtnr, ep; unsigned char data[3]; if (u->interface < 0 || u->interface >= config->bNumInterfaces) @@ -1537,7 +1579,7 @@ static int set_format_out(struct usb_audiodev *as) if ((alts->endpoint[0].bmAttributes & 0x0c) == 0x04) { if (alts->bNumEndpoints < 2 || alts->endpoint[1].bmAttributes != 0x01 || - alts->endpoint[1].bSynchAddress == 0 || + alts->endpoint[1].bSynchAddress != 0 || alts->endpoint[1].bEndpointAddress != (alts->endpoint[0].bSynchAddress | 0x80)) { printk(KERN_ERR "usb_audio: device %d interface %d altsetting %d invalid synch pipe\n", dev->devnum, u->interface, fmt->altsetting); @@ -1560,18 +1602,21 @@ static int set_format_out(struct usb_audiodev *as) data[0] = d->srate; data[1] = d->srate >> 8; data[2] = d->srate >> 16; + ep = usb_pipeendpoint(u->datapipe) | (u->datapipe & USB_DIR_IN); if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, - SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { - printk(KERN_ERR "usbaudio: failure to set sampling frequency device %d endpoint %d\n", - dev->devnum, usb_pipeendpoint(u->datapipe)); + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { + printk(KERN_ERR "usbaudio: failure to set output sampling frequency device %d endpoint 0x%x to %u\n", + dev->devnum, ep, d->srate); return -1; } if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_IN, - SAMPLING_FREQ_CONTROL << 8, usb_pipeendpoint(u->datapipe), data, 3, HZ) != 3) { - printk(KERN_ERR "usbaudio: failure to get sampling frequency device %d endpoint %d\n", - dev->devnum, usb_pipeendpoint(u->datapipe)); + SAMPLING_FREQ_CONTROL << 8, ep, data, 3, HZ) < 0) { + printk(KERN_ERR "usbaudio: failure to get output sampling frequency device %d endpoint 0x%x\n", + dev->devnum, ep); return -1; } + printk(KERN_DEBUG "usb_audio: set_format_out: device %d interface %d altsetting %d srate req: %u real %u\n", + dev->devnum, u->interface, fmt->altsetting, d->srate, data[0] | (data[1] << 8) | (data[2] << 16)); d->srate = data[0] | (data[1] << 8) | (data[2] << 16); return 0; } @@ -1642,7 +1687,7 @@ static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value) data[0] = v1; data[1] = v1 >> 8; if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - (ch->chnum << 8) | 1, ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + (ch->chnum << 8) | 1, ms->iface | (ch->unitid << 8), data, 2, HZ) < 0) goto err; if (!(ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) return 0; @@ -1650,7 +1695,7 @@ static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value) data[1] = v2 >> 8; if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)), - ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + ms->iface | (ch->unitid << 8), data, 2, HZ) < 0) goto err; return 0; @@ -1659,14 +1704,14 @@ static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value) data[0] = v1; data[1] = v1 >> 8; if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 2, HZ) < 0) goto err; if (ch->chnum == 0) return 0; data[0] = v2; data[1] = v2 >> 8; if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 2, HZ) < 2) + (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 2, HZ) < 0) goto err; return 0; @@ -1675,13 +1720,13 @@ static int wrmixer(struct usb_mixerdev *ms, unsigned mixch, unsigned value) case TREBLE_CONTROL: data[0] = v1 >> 8; if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 1, HZ) < 1) + (ch->selector << 8) | ch->chnum, ms->iface | (ch->unitid << 8), data, 1, HZ) < 0) goto err; if (ch->chnum == 0) return 0; data[0] = v2 >> 8; if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), SET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, - (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 1, HZ) < 1) + (ch->selector << 8) | (ch->chnum + 1), ms->iface | (ch->unitid << 8), data, 1, HZ) < 0) goto err; return 0; @@ -1839,7 +1884,7 @@ static int usb_audio_ioctl_mixdev(struct inode *inode, struct file *file, unsign for (val = i = 0; i < ms->numch; i++) if (ms->ch[i].flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) val |= 1 << ms->ch[i].osschannel; - return put_user(0, (int *)arg); + return put_user(val, (int *)arg); case SOUND_MIXER_CAPS: return put_user(0, (int *)arg); @@ -2778,26 +2823,26 @@ static unsigned int getvolchannel(struct consmixstate *state) if ((state->termtype & 0xff00) == 0x0000 && !(state->mixchmask & SOUND_MASK_VOLUME)) return SOUND_MIXER_VOLUME; if ((state->termtype & 0xff00) == 0x0100) { - if (!(state->mixchmask & SOUND_MASK_PCM)) + if (state->mixchmask & SOUND_MASK_PCM) return SOUND_MIXER_PCM; - if (!(state->mixchmask & SOUND_MASK_ALTPCM)) + if (state->mixchmask & SOUND_MASK_ALTPCM) return SOUND_MIXER_ALTPCM; } - if ((state->termtype & 0xff00) == 0x0200 && !(state->mixchmask & SOUND_MASK_MIC)) + if ((state->termtype & 0xff00) == 0x0200 && (state->mixchmask & SOUND_MASK_MIC)) return SOUND_MIXER_MIC; - if ((state->termtype & 0xff00) == 0x0300 && !(state->mixchmask & SOUND_MASK_SPEAKER)) + if ((state->termtype & 0xff00) == 0x0300 && (state->mixchmask & SOUND_MASK_SPEAKER)) return SOUND_MIXER_SPEAKER; - if ((state->termtype & 0xff00) == 0x0300 && !(state->mixchmask & SOUND_MASK_SPEAKER)) + if ((state->termtype & 0xff00) == 0x0300 && (state->mixchmask & SOUND_MASK_SPEAKER)) return SOUND_MIXER_SPEAKER; if ((state->termtype & 0xff00) == 0x0500) { - if (!(state->mixchmask & SOUND_MASK_PHONEIN)) + if (state->mixchmask & SOUND_MASK_PHONEIN) return SOUND_MIXER_PHONEIN; - if (!(state->mixchmask & SOUND_MASK_PHONEOUT)) + if (state->mixchmask & SOUND_MASK_PHONEOUT) return SOUND_MIXER_PHONEOUT; } - if (state->termtype >= 0x710 && state->termtype <= 0x711 && !(state->mixchmask & SOUND_MASK_RADIO)) + if (state->termtype >= 0x710 && state->termtype <= 0x711 && (state->mixchmask & SOUND_MASK_RADIO)) return SOUND_MIXER_RADIO; - if (state->termtype >= 0x709 && state->termtype <= 0x70f && !(state->mixchmask & SOUND_MASK_VIDEO)) + if (state->termtype >= 0x709 && state->termtype <= 0x70f && (state->mixchmask & SOUND_MASK_VIDEO)) return SOUND_MIXER_VIDEO; u = ffs(state->mixchmask & (SOUND_MASK_LINE | SOUND_MASK_CD | SOUND_MASK_LINE1 | SOUND_MASK_LINE2 | SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | SOUND_MASK_DIGITAL3)); @@ -2818,18 +2863,18 @@ static void prepmixch(struct consmixstate *state) switch (ch->selector) { case 0: /* mixer unit request */ if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; ch->minval = buf[0] | (buf[1] << 8); if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; ch->maxval = buf[0] | (buf[1] << 8); v2 = ch->maxval - ch->minval; if (!v2) v2 = 1; if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + (ch->chnum << 8) | 1, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; v1 = buf[0] | (buf[1] << 8); v3 = v1 - ch->minval; @@ -2840,7 +2885,7 @@ static void prepmixch(struct consmixstate *state) if (ch->flags & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT)) { if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, ((ch->chnum + !!(ch->flags & MIXFLG_STEREOIN)) << 8) | (1 + !!(ch->flags & MIXFLG_STEREOOUT)), - state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; v1 = buf[0] | (buf[1] << 8); v3 = v1 - ch->minval; @@ -2854,15 +2899,15 @@ static void prepmixch(struct consmixstate *state) /* various feature unit controls */ case VOLUME_CONTROL: if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; ch->minval = buf[0] | (buf[1] << 8); if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; ch->maxval = buf[0] | (buf[1] << 8); if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; v1 = buf[0] | (buf[1] << 8); v2 = ch->maxval - ch->minval; @@ -2875,7 +2920,7 @@ static void prepmixch(struct consmixstate *state) ch->value = v3; if (ch->chnum != 0) { if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 2) + (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 2, HZ) < 0) goto err; v1 = buf[0] | (buf[1] << 8); v3 = v1 - ch->minval; @@ -2890,15 +2935,15 @@ static void prepmixch(struct consmixstate *state) case MID_CONTROL: case TREBLE_CONTROL: if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MIN, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 0) goto err; ch->minval = buf[0] << 8; if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_MAX, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 0) goto err; ch->maxval = buf[0] << 8; if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + (ch->selector << 8) | ch->chnum, state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 0) goto err; v1 = buf[0] << 8; v2 = ch->maxval - ch->minval; @@ -2911,7 +2956,7 @@ static void prepmixch(struct consmixstate *state) ch->value = v3; if (ch->chnum != 0) { if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), GET_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 1) + (ch->selector << 8) | (ch->chnum + 1), state->ctrlif | (ch->unitid << 8), buf, 1, HZ) < 0) goto err; v1 = buf[0] << 8; v3 = v1 - ch->minval; @@ -2942,12 +2987,12 @@ extern inline int checkmixbmap(unsigned char *bmap, unsigned char flg, unsigned unsigned int idx; idx = inidx*numoch; - if (!(bmap[idx >> 3] & (1 << (idx & 7)))) + if (!(bmap[-(idx >> 3)] & (0x80 >> (idx & 7)))) return 0; if (!(flg & (MIXFLG_STEREOIN | MIXFLG_STEREOOUT))) return 1; idx = (inidx+!!(flg & MIXFLG_STEREOIN))*numoch+!!(flg & MIXFLG_STEREOOUT); - if (!(bmap[idx >> 3] & (1 << (idx & 7)))) + if (!(bmap[-(idx >> 3)] & (0x80 >> (idx & 7)))) return 0; return 1; } @@ -2958,6 +3003,8 @@ static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer unsigned int chidx[SOUND_MIXER_NRDEVICES+1]; unsigned int termt[SOUND_MIXER_NRDEVICES]; unsigned char flg = (nroutch >= 2) ? MIXFLG_STEREOOUT : 0; + unsigned char *bmap = &mixer[9+mixer[4]]; + unsigned int bmapsize; struct mixerchannel *ch; unsigned int i; @@ -2977,7 +3024,9 @@ static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer } state->termtype = 0; state->chconfig = mixer[6+mixer[4]] | (mixer[7+mixer[4]] << 8); - if (mixer[0] < 10+mixer[4]+((nroutch * chidx[mixer[4]] + 7) >> 3)) { + bmapsize = (nroutch * chidx[mixer[4]] + 7) >> 3; + bmap += bmapsize - 1; + if (mixer[0] < 10+mixer[4]+bmapsize) { printk(KERN_ERR "usb_audio: unit %u invalid MIXER_UNIT descriptor (bitmap too small)\n", mixer[3]); return; } @@ -2985,7 +3034,7 @@ static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer state->termtype = termt[i]; if (chidx[i+1]-chidx[i] >= 2) { flg |= MIXFLG_STEREOIN; - if (checkmixbmap(&mixer[9+mixer[4]], flg, chidx[i], nroutch)) { + if (checkmixbmap(bmap, flg, chidx[i], nroutch)) { ch = getmixchannel(state, getvolchannel(state)); if (ch) { ch->unitid = mixer[3]; @@ -2998,7 +3047,7 @@ static void usb_audio_mixerunit(struct consmixstate *state, unsigned char *mixer } } flg &= ~MIXFLG_STEREOIN; - if (checkmixbmap(&mixer[9+mixer[4]], flg, chidx[i], nroutch)) { + if (checkmixbmap(bmap, flg, chidx[i], nroutch)) { ch = getmixchannel(state, getvolchannel(state)); if (ch) { ch->unitid = mixer[3]; @@ -3134,6 +3183,7 @@ static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid) { unsigned char *p1; + unsigned int i, j; if (test_and_set_bit(unitid, &state->unitbitmap)) { printk(KERN_ERR "usb_audio: mixer path recursion detected, unit %d!\n", unitid); @@ -3195,15 +3245,16 @@ static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unit printk(KERN_ERR "usb_audio: unit %u: invalid EXTENSION_UNIT descriptor\n", unitid); return; } - { - unsigned int i; - - for (i = 0; i < p1[6]; i++) - usb_audio_recurseunit(state, p1[7+i]); + for (j = i = 0; i < p1[6]; i++) { + usb_audio_recurseunit(state, p1[7+i]); + if (!i) + j = state->termtype; + else if (j != state->termtype) + j = 0; } state->nrchannels = p1[7+p1[6]]; state->chconfig = p1[8+p1[6]] | (p1[9+p1[6]] << 8); - state->termtype = 0; + state->termtype = j; return; default: @@ -3378,6 +3429,10 @@ static int usb_audio_probe(struct usb_device *dev) return -1; configfound: + if (usb_set_configuration(dev, config->bConfigurationValue) < 0) { + printk(KERN_ERR "usb_audio: set_configuration failed (ConfigValue 0x%x)\n", config->bConfigurationValue); + return -1; + } ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8); if (ret) { printk(KERN_ERR "usb_audio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum); diff --git a/drivers/usb/mouse.c b/drivers/usb/mouse.c index 4384f07d3383..da5ee515ef55 100644 --- a/drivers/usb/mouse.c +++ b/drivers/usb/mouse.c @@ -120,7 +120,7 @@ static int mouse_irq(int state, void *__buffer, int len, void *dev_id) wake_up_interruptible(&mouse->wait); if (mouse->fasync) - kill_fasync(mouse->fasync, SIGIO); + kill_fasync(mouse->fasync, SIGIO, POLL_IN); return 1; } diff --git a/drivers/video/Config.in b/drivers/video/Config.in index 9fb8d39050ac..a8e223f6bf04 100644 --- a/drivers/video/Config.in +++ b/drivers/video/Config.in @@ -2,350 +2,362 @@ # Video configuration # +mainmenu_option next_comment +comment 'Frame-buffer support' + +bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB + if [ "$CONFIG_FB" = "y" ]; then - define_bool CONFIG_DUMMY_CONSOLE y - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then - tristate 'Cirrus Logic suport (experimental)' CONFIG_FB_CLGEN - tristate 'Permedia2 support (experimental)' CONFIG_FB_PM2 - if [ "$CONFIG_FB_PM2" = "y" ]; then - if [ "$CONFIG_PCI" = "y" ]; then - bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT - bool ' generic Permedia2 PCI board support' CONFIG_FB_PM2_PCI - fi - if [ "$CONFIG_AMIGA" = "y" ]; then - bool ' Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC - fi + define_bool CONFIG_DUMMY_CONSOLE y + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then + tristate ' Cirrus Logic suport (EXPERIMENTAL)' CONFIG_FB_CLGEN + tristate ' Permedia2 support (EXPERIMENTAL)' CONFIG_FB_PM2 + if [ "$CONFIG_FB_PM2" = "y" ]; then + if [ "$CONFIG_PCI" = "y" ]; then + bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT + bool ' generic Permedia2 PCI board support' CONFIG_FB_PM2_PCI + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + bool ' Phase5 CVisionPPC/BVisionPPC support' CONFIG_FB_PM2_CVPPC + fi + fi fi - fi - fi - if [ "$CONFIG_ARCH_ACORN" = "y" ]; then - bool 'Acorn VIDC support' CONFIG_FB_ACORN - fi - if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then - tristate 'Cyber2000 support' CONFIG_FB_CYBER2000 - fi - if [ "$CONFIG_APOLLO" = "y" ]; then - define_bool CONFIG_FB_APOLLO y - fi - if [ "$CONFIG_Q40" = "y" ]; then - define_bool CONFIG_FB_Q40 y - fi - if [ "$CONFIG_AMIGA" = "y" ]; then - bool 'Amiga native chipset support' CONFIG_FB_AMIGA - if [ "$CONFIG_FB_AMIGA" != "n" ]; then - bool 'Amiga OCS chipset support' CONFIG_FB_AMIGA_OCS - bool 'Amiga ECS chipset support' CONFIG_FB_AMIGA_ECS - bool 'Amiga AGA chipset support' CONFIG_FB_AMIGA_AGA - fi - fi - if [ "$CONFIG_ZORRO" = "y" ]; then - tristate 'Amiga CyberVision support' CONFIG_FB_CYBER - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE - tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3 - bool 'Amiga FrameMaster II/Rainbow II support (experimental)' CONFIG_FB_FM2 - fi - fi - if [ "$CONFIG_ATARI" = "y" ]; then - bool 'Atari native chipset support' CONFIG_FB_ATARI - tristate 'ATI Mach64 display support' CONFIG_FB_ATY - fi - if [ "$CONFIG_PPC" = "y" ]; then - bool 'Open Firmware frame buffer device support' CONFIG_FB_OF - if [ "$CONFIG_FB_OF" = "y" ]; then - bool 'Apple "control" display support' CONFIG_FB_CONTROL - bool 'Apple "platinum" display support' CONFIG_FB_PLATINUM - bool 'Apple "valkyrie" display support' CONFIG_FB_VALKYRIE - tristate 'ATI Mach64 display support' CONFIG_FB_ATY - bool 'IMS Twin Turbo display support' CONFIG_FB_IMSTT - bool 'Chips 65550 display support' CONFIG_FB_CT65550 - bool 'S3 Trio display support' CONFIG_FB_S3TRIO - fi - tristate 'VGA 16-color graphics console' CONFIG_FB_VGA16 - fi - if [ "$CONFIG_MAC" = "y" ]; then - define_bool CONFIG_FB_MAC y - fi - if [ "$CONFIG_HP300" = "y" ]; then - define_bool CONFIG_FB_HP300 y - fi - if [ "$ARCH" = "alpha" ]; then - tristate 'TGA framebuffer support' CONFIG_FB_TGA - fi - if [ "$ARCH" = "i386" ]; then - bool 'VESA VGA graphics console' CONFIG_FB_VESA - tristate 'VGA 16-color graphics console' CONFIG_FB_VGA16 - define_bool CONFIG_VIDEO_SELECT y - fi - if [ "$CONFIG_VISWS" = "y" ]; then - tristate 'SGI Visual Workstation framebuffer support' CONFIG_FB_SGIVW - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_PCI" != "n" ]; then - tristate 'Matrox acceleration' CONFIG_FB_MATROX - if [ "$CONFIG_FB_MATROX" != "n" ]; then - bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM - bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE - bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100 - bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD + fi + if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + bool ' Acorn VIDC support' CONFIG_FB_ACORN + fi + if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then + tristate ' Cyber2000 support' CONFIG_FB_CYBER2000 + fi + if [ "$CONFIG_APOLLO" = "y" ]; then + define_bool CONFIG_FB_APOLLO y + fi + if [ "$CONFIG_Q40" = "y" ]; then + define_bool CONFIG_FB_Q40 y + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + bool ' Amiga native chipset support' CONFIG_FB_AMIGA + if [ "$CONFIG_FB_AMIGA" != "n" ]; then + bool ' Amiga OCS chipset support' CONFIG_FB_AMIGA_OCS + bool ' Amiga ECS chipset support' CONFIG_FB_AMIGA_ECS + bool ' Amiga AGA chipset support' CONFIG_FB_AMIGA_AGA fi - tristate 'ATI Mach64 display support' CONFIG_FB_ATY - fi - fi - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then - bool 'SBUS and UPA framebuffers' CONFIG_FB_SBUS - if [ "$CONFIG_FB_SBUS" != "n" ]; then - if [ "$ARCH" = "sparc64" ]; then - bool ' Creator/Creator3D support' CONFIG_FB_CREATOR + fi + if [ "$CONFIG_ZORRO" = "y" ]; then + tristate ' Amiga CyberVision support' CONFIG_FB_CYBER + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' Amiga CyberVision3D support (EXPERIMENTAL)' CONFIG_FB_VIRGE + tristate ' Amiga RetinaZ3 support (EXPERIMENTAL)' CONFIG_FB_RETINAZ3 + bool ' Amiga FrameMaster II/Rainbow II support (EXPERIMENTAL)' CONFIG_FB_FM2 fi - bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX - bool ' BWtwo support' CONFIG_FB_BWTWO - bool ' CGthree support' CONFIG_FB_CGTHREE - if [ "$ARCH" = "sparc" ]; then - bool ' TCX (SS4/SS5 only) support' CONFIG_FB_TCX - bool ' CGfourteen (SX) support' CONFIG_FB_CGFOURTEEN - bool ' P9100 (Sparcbook 3 only) support' CONFIG_FB_P9100 + fi + if [ "$CONFIG_ATARI" = "y" ]; then + bool ' Atari native chipset support' CONFIG_FB_ATARI + tristate ' ATI Mach64 display support' CONFIG_FB_ATY + fi + if [ "$CONFIG_PPC" = "y" ]; then + bool ' Open Firmware frame buffer device support' CONFIG_FB_OF + if [ "$CONFIG_FB_OF" = "y" ]; then + bool ' Apple "control" display support' CONFIG_FB_CONTROL + bool ' Apple "platinum" display support' CONFIG_FB_PLATINUM + bool ' Apple "valkyrie" display support' CONFIG_FB_VALKYRIE + bool ' IMS Twin Turbo display support' CONFIG_FB_IMSTT + bool ' Chips 65550 display support' CONFIG_FB_CT65550 + bool ' S3 Trio display support' CONFIG_FB_S3TRIO fi - bool ' Leo (ZX) support' CONFIG_FB_LEO - fi - fi - if [ "$ARCH" = "sparc" ]; then - if [ "$CONFIG_PCI" != "n" ]; then - bool 'PCI framebuffers' CONFIG_FB_PCI - if [ "$CONFIG_FB_PCI" != "n" ]; then - bool ' IGA 168x display support' CONFIG_FB_IGA + tristate ' VGA 16-color graphics console' CONFIG_FB_VGA16 + fi + if [ "$CONFIG_MAC" = "y" ]; then + define_bool CONFIG_FB_MAC y + fi + if [ "$CONFIG_HP300" = "y" ]; then + define_bool CONFIG_FB_HP300 y + fi + if [ "$ARCH" = "alpha" ]; then + tristate ' TGA framebuffer support' CONFIG_FB_TGA + fi + if [ "$ARCH" = "i386" ]; then + bool ' VESA VGA graphics console' CONFIG_FB_VESA + tristate ' VGA 16-color graphics console' CONFIG_FB_VGA16 + define_bool CONFIG_VIDEO_SELECT y + fi + if [ "$CONFIG_VISWS" = "y" ]; then + tristate ' SGI Visual Workstation framebuffer support' CONFIG_FB_SGIVW + define_bool CONFIG_BUS_I2C y + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + tristate ' Matrox acceleration (EXPERIMENTAL)' CONFIG_FB_MATROX + if [ "$CONFIG_FB_MATROX" != "n" ]; then + bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM + bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE + bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100 + bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD + fi + tristate ' ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY + bool ' 3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX fi - fi - fi - if [ "$ARCH" = "sparc64" ]; then - if [ "$CONFIG_PCI" != "n" ]; then - bool 'PCI framebuffers' CONFIG_FB_PCI - if [ "$CONFIG_FB_PCI" != "n" ]; then - tristate ' ATI Mach64 display support' CONFIG_FB_ATY + fi + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then + bool ' SBUS and UPA framebuffers' CONFIG_FB_SBUS + if [ "$CONFIG_FB_SBUS" != "n" ]; then + if [ "$ARCH" = "sparc64" ]; then + bool ' Creator/Creator3D support' CONFIG_FB_CREATOR + fi + bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX + bool ' BWtwo support' CONFIG_FB_BWTWO + bool ' CGthree support' CONFIG_FB_CGTHREE + if [ "$ARCH" = "sparc" ]; then + bool ' TCX (SS4/SS5 only) support' CONFIG_FB_TCX + bool ' CGfourteen (SX) support' CONFIG_FB_CGFOURTEEN + bool ' P9100 (Sparcbook 3 only) support' CONFIG_FB_P9100 + fi + bool ' Leo (ZX) support' CONFIG_FB_LEO fi - fi - fi - tristate 'Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL - - bool 'Advanced low level driver options' CONFIG_FBCON_ADVANCED - if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then - tristate 'Monochrome support' CONFIG_FBCON_MFB - tristate '2 bpp packed pixels support' CONFIG_FBCON_CFB2 - tristate '4 bpp packed pixels support' CONFIG_FBCON_CFB4 - tristate '8 bpp packed pixels support' CONFIG_FBCON_CFB8 - tristate '16 bpp packed pixels support' CONFIG_FBCON_CFB16 - tristate '24 bpp packed pixels support' CONFIG_FBCON_CFB24 - tristate '32 bpp packed pixels support' CONFIG_FBCON_CFB32 - tristate 'Amiga bitplanes support' CONFIG_FBCON_AFB - tristate 'Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM - tristate 'Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2 - tristate 'Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4 - tristate 'Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8 -# tristate 'Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16 - tristate 'Mac variable bpp packed pixels support' CONFIG_FBCON_MAC - tristate 'VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES - tristate 'VGA characters/attributes support' CONFIG_FBCON_VGA - else - # Guess what we need - if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_AMIGA" = "y" -o \ - "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ - "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \ - "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then - define_bool CONFIG_FBCON_MFB y - else - if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \ - "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ - "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \ - "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then - define_bool CONFIG_FBCON_MFB m + fi + if [ "$ARCH" = "sparc" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + bool ' PCI framebuffers' CONFIG_FB_PCI + if [ "$CONFIG_FB_PCI" != "n" ]; then + bool ' IGA 168x display support' CONFIG_FB_IGA + fi + fi + fi + if [ "$ARCH" = "sparc64" ]; then + if [ "$CONFIG_PCI" != "n" ]; then + bool ' PCI framebuffers' CONFIG_FB_PCI + if [ "$CONFIG_FB_PCI" != "n" ]; then + tristate ' ATI Mach64 display support' CONFIG_FB_ATY + fi fi - fi - if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ - "$CONFIG_FB_VIRTUAL" = "y" ]; then - define_bool CONFIG_FBCON_CFB2 y - define_bool CONFIG_FBCON_CFB4 y - else - if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ - "$CONFIG_FB_VIRTUAL" = "m" ]; then - define_bool CONFIG_FBCON_CFB2 m - define_bool CONFIG_FBCON_CFB4 m + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate ' Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL + fi + + bool ' Advanced low level driver options' CONFIG_FBCON_ADVANCED + if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then + tristate ' Monochrome support' CONFIG_FBCON_MFB + tristate ' 2 bpp packed pixels support' CONFIG_FBCON_CFB2 + tristate ' 4 bpp packed pixels support' CONFIG_FBCON_CFB4 + tristate ' 8 bpp packed pixels support' CONFIG_FBCON_CFB8 + tristate ' 16 bpp packed pixels support' CONFIG_FBCON_CFB16 + tristate ' 24 bpp packed pixels support' CONFIG_FBCON_CFB24 + tristate ' 32 bpp packed pixels support' CONFIG_FBCON_CFB32 + tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB + tristate ' Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM + tristate ' Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2 + tristate ' Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4 + tristate ' Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8 +# tristate ' Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16 + tristate ' Mac variable bpp packed pixels support' CONFIG_FBCON_MAC + tristate ' VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES + tristate ' VGA characters/attributes support' CONFIG_FBCON_VGA + else + # Guess what we need + if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_AMIGA" = "y" -o \ + "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ + "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \ + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then + define_bool CONFIG_FBCON_MFB y + else + if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \ + "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ + "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \ + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then + define_bool CONFIG_FBCON_MFB m + fi fi - fi - if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \ - "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ - "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \ - "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ - "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \ - "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ - "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ - "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_P9100" = "y" -o \ - "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then - define_bool CONFIG_FBCON_CFB8 y - else - if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ - "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ - "$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \ - "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ - "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \ - "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ - "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ - "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_P9100" = "m" -o \ - "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then - define_bool CONFIG_FBCON_CFB8 m + if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ + "$CONFIG_FB_VIRTUAL" = "y" ]; then + define_bool CONFIG_FBCON_CFB2 y + define_bool CONFIG_FBCON_CFB4 y + else + if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ + "$CONFIG_FB_VIRTUAL" = "m" ]; then + define_bool CONFIG_FBCON_CFB2 m + define_bool CONFIG_FBCON_CFB4 m + fi fi - fi - if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ - "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ - "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ - "$CONFIG_FB_Q40" = "y" -o \ - "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ - "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ - "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ - "$CONFIG_FB_CYBER2000" = "y" ]; then - define_bool CONFIG_FBCON_CFB16 y - else - if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ - "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ - "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \ - "$CONFIG_FB_Q40" = "m" -o \ - "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ - "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ - "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \ - "$CONFIG_FB_CYBER2000" = "m" ]; then - define_bool CONFIG_FBCON_CFB16 m + if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \ + "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ + "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \ + "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ + "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ + "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \ + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ + "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ + "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_P9100" = "y" -o \ + "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \ + "$CONFIG_FB_3DFX" = "y" ]; then + define_bool CONFIG_FBCON_CFB8 y + else + if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ + "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ + "$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \ + "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ + "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ + "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \ + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ + "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ + "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_P9100" = "m" -o \ + "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then + define_bool CONFIG_FBCON_CFB8 m + fi fi - fi - if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ - "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_CYBER2000" = "y" ]; then - define_bool CONFIG_FBCON_CFB24 y - else - if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ - "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_CYBER2000" = "m" ]; then - define_bool CONFIG_FBCON_CFB24 m + if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ + "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ + "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ + "$CONFIG_FB_Q40" = "y" -o \ + "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ + "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \ + "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \ + "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ + "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" ]; then + define_bool CONFIG_FBCON_CFB16 y + else + if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ + "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ + "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \ + "$CONFIG_FB_Q40" = "m" -o \ + "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ + "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \ + "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \ + "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \ + "$CONFIG_FB_CYBER2000" = "m" ]; then + define_bool CONFIG_FBCON_CFB16 m + fi fi - fi - if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ - "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ - "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ - "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ - "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ - "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" ]; then - define_bool CONFIG_FBCON_CFB32 y - else - if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ - "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ - "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ - "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ - "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ - "$CONFIG_FB_SGIVW" = "m" ]; then - define_bool CONFIG_FBCON_CFB32 m + if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ + "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_CYBER2000" = "y" ]; then + define_bool CONFIG_FBCON_CFB24 y + else + if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ + "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_CYBER2000" = "m" ]; then + define_bool CONFIG_FBCON_CFB24 m + fi fi - fi - if [ "$CONFIG_FB_AMIGA" = "y" ]; then - define_bool CONFIG_FBCON_AFB y - define_bool CONFIG_FBCON_ILBM y - else - if [ "$CONFIG_FB_AMIGA" = "m" ]; then - define_bool CONFIG_FBCON_AFB m - define_bool CONFIG_FBCON_ILBM m + if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ + "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ + "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ + "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ + "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ + "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ + "$CONFIG_FB_3DFX" = "y" ]; then + define_bool CONFIG_FBCON_CFB32 y + else + if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ + "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ + "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ + "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ + "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ + "$CONFIG_FB_SGIVW" = "m" ]; then + define_bool CONFIG_FBCON_CFB32 m + fi fi - fi - if [ "$CONFIG_FB_ATARI" = "y" ]; then - define_bool CONFIG_FBCON_IPLAN2P2 y - define_bool CONFIG_FBCON_IPLAN2P4 y - define_bool CONFIG_FBCON_IPLAN2P8 y -# define_bool CONFIG_FBCON_IPLAN2P16 y - else - if [ "$CONFIG_FB_ATARI" = "m" ]; then - define_bool CONFIG_FBCON_IPLAN2P2 m - define_bool CONFIG_FBCON_IPLAN2P4 m - define_bool CONFIG_FBCON_IPLAN2P8 m -# define_bool CONFIG_FBCON_IPLAN2P16 m + if [ "$CONFIG_FB_AMIGA" = "y" ]; then + define_bool CONFIG_FBCON_AFB y + define_bool CONFIG_FBCON_ILBM y + else + if [ "$CONFIG_FB_AMIGA" = "m" ]; then + define_bool CONFIG_FBCON_AFB m + define_bool CONFIG_FBCON_ILBM m + fi fi - fi - if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then - define_bool CONFIG_FBCON_MAC y - else - if [ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then - define_bool CONFIG_FBCON_MAC m + if [ "$CONFIG_FB_ATARI" = "y" ]; then + define_bool CONFIG_FBCON_IPLAN2P2 y + define_bool CONFIG_FBCON_IPLAN2P4 y + define_bool CONFIG_FBCON_IPLAN2P8 y +# define_bool CONFIG_FBCON_IPLAN2P16 y + else + if [ "$CONFIG_FB_ATARI" = "m" ]; then + define_bool CONFIG_FBCON_IPLAN2P2 m + define_bool CONFIG_FBCON_IPLAN2P4 m + define_bool CONFIG_FBCON_IPLAN2P8 m +# define_bool CONFIG_FBCON_IPLAN2P16 m + fi fi - fi - if [ "$CONFIG_FB_VGA16" = "y" ]; then - define_bool CONFIG_FBCON_VGA_PLANES y - else - if [ "$CONFIG_FB_VGA16" = "m" ]; then - define_bool CONFIG_FBCON_VGA_PLANES m + if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then + define_bool CONFIG_FBCON_MAC y + else + if [ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then + define_bool CONFIG_FBCON_MAC m + fi fi - fi - if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then - define_bool CONFIG_FBCON_VGA y - else - if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then - define_bool CONFIG_FBCON_VGA m + if [ "$CONFIG_FB_VGA16" = "y" ]; then + define_bool CONFIG_FBCON_VGA_PLANES y + else + if [ "$CONFIG_FB_VGA16" = "m" ]; then + define_bool CONFIG_FBCON_VGA_PLANES m + fi fi - fi - fi - bool 'Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY - if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then - bool 'Sparc console 8x16 font' CONFIG_FONT_SUN8x16 - if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - bool 'Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 - fi - bool 'Select other fonts' CONFIG_FBCON_FONTS - if [ "$CONFIG_FBCON_FONTS" = "y" ]; then - bool ' VGA 8x8 font' CONFIG_FONT_8x8 - bool ' VGA 8x16 font' CONFIG_FONT_8x16 - if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 + if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then + define_bool CONFIG_FBCON_VGA y + else + if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then + define_bool CONFIG_FBCON_VGA m + fi fi - bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 - bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 - fi - else - bool 'Select compiled-in fonts' CONFIG_FBCON_FONTS - if [ "$CONFIG_FBCON_FONTS" = "y" ]; then - bool ' VGA 8x8 font' CONFIG_FONT_8x8 - bool ' VGA 8x16 font' CONFIG_FONT_8x16 + fi + bool ' Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY + if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16 if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 - bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 + bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 fi - bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 - bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 - else - define_bool CONFIG_FONT_8x8 y - define_bool CONFIG_FONT_8x16 y - if [ "$CONFIG_MAC" = "y" ]; then - if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then - define_bool CONFIG_FONT_6x11 y - fi + bool ' Select other fonts' CONFIG_FBCON_FONTS + if [ "$CONFIG_FBCON_FONTS" = "y" ]; then + bool ' VGA 8x8 font' CONFIG_FONT_8x8 + bool ' VGA 8x16 font' CONFIG_FONT_8x16 + if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then + bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 + fi + bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 + bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 fi - if [ "$CONFIG_AMIGA" = "y" ]; then - define_bool CONFIG_FONT_PEARL_8x8 y + else + bool ' Select compiled-in fonts' CONFIG_FBCON_FONTS + if [ "$CONFIG_FBCON_FONTS" = "y" ]; then + bool ' VGA 8x8 font' CONFIG_FONT_8x8 + bool ' VGA 8x16 font' CONFIG_FONT_8x16 + bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16 + if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then + bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22 + bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11 + fi + bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8 + bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8 + else + define_bool CONFIG_FONT_8x8 y + define_bool CONFIG_FONT_8x16 y + if [ "$CONFIG_MAC" = "y" ]; then + if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then + define_bool CONFIG_FONT_6x11 y + fi + fi + if [ "$CONFIG_AMIGA" = "y" ]; then + define_bool CONFIG_FONT_PEARL_8x8 y + fi + if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then + define_bool CONFIG_FONT_ACORN_8x8 y + fi fi - if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then - define_bool CONFIG_FONT_ACORN_8x8 y - fi - fi - fi + fi fi + +endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 15050f347035..e4f8cefe1c80 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -150,13 +150,17 @@ else endif ifeq ($(CONFIG_FB_SGIVW),y) -L_OBJS += sgivwfb.o +LX_OBJS += sgivwfb.o else ifeq ($(CONFIG_FB_SGIVW),m) - M_OBJS += sgivwfb.o + MX_OBJS += sgivwfb.o endif endif +ifeq ($(CONFIG_FB_3DFX),y) +L_OBJS += tdfxfb.o +endif + ifeq ($(CONFIG_FB_MAC),y) L_OBJS += macfb.o endif diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c index 47531e1bb997..fb578ffdbc8f 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/amifb.c @@ -1736,6 +1736,7 @@ default_chipset: fb_info.updatevar = &amifbcon_updatevar; fb_info.blank = &amifbcon_blank; fb_info.flags = FBINFO_FLAG_DEFAULT; + memset(&var, 0, sizeof(var)); if (!fb_find_mode(&var, &fb_info, mode_option, ami_modedb, NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) diff --git a/drivers/video/aty.h b/drivers/video/aty.h index e7b6620adae7..2e5900f34905 100644 --- a/drivers/video/aty.h +++ b/drivers/video/aty.h @@ -103,6 +103,8 @@ #define CUSTOM_MACRO_CNTL 0x00D4 /* Dword offset 0_35 */ +#define POWER_MANAGEMENT 0x00D8 /* Dword offset 0_36 (LG) */ + #define CONFIG_CNTL 0x00DC /* Dword offset 0_37 (CT, ET, VT) */ #define CONFIG_CHIP_ID 0x00E0 /* Dword offset 0_38 */ #define CONFIG_STAT0 0x00E4 /* Dword offset 0_39 */ @@ -951,4 +953,15 @@ #define MACH64_NUM_CLOCKS 16 #define MACH64_NUM_FREQS 50 +/* Power Management register constants (LTG and LT Pro) */ +#define PWR_MGT_ON 0x00000001 +#define PWR_MGT_MODE_MASK 0x00000006 +#define AUTO_PWR_UP 0x00000008 +#define SELF_REFRESH 0x00000080 +#define PWR_BLON 0x02000000 +#define STANDBY_NOW 0x10000000 +#define SUSPEND_NOW 0x20000000 +#define PWR_MGT_STATUS_MASK 0xC0000000 +#define PWR_MGT_STATUS_SUSPEND 0x80000000 + #endif /* REGMACH64_H */ diff --git a/drivers/video/atyfb.c b/drivers/video/atyfb.c index f12fec6e11d0..edba704a3f7b 100644 --- a/drivers/video/atyfb.c +++ b/drivers/video/atyfb.c @@ -1,4 +1,4 @@ -/* $Id: atyfb.c,v 1.122 1999/09/06 20:44:08 geert Exp $ +/* $Id: atyfb.c,v 1.126 1999/09/16 18:46:23 geert Exp $ * linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64 * * Copyright (C) 1997-1998 Geert Uytterhoeven @@ -52,7 +52,6 @@ #include #include #include -#include #include #include @@ -62,12 +61,15 @@ #include -#if defined(CONFIG_PPC) +#ifdef __powerpc__ +#include +#include #include #include #include