]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.118 2.1.118
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:16:25 +0000 (15:16 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:16:25 +0000 (15:16 -0500)
277 files changed:
CREDITS
Documentation/radiotrack.txt [deleted file]
Documentation/video4linux/API.html [new file with mode: 0644]
Documentation/video4linux/bttv/CARDS [new file with mode: 0644]
Documentation/video4linux/bttv/CONTRIBUTORS [new file with mode: 0644]
Documentation/video4linux/bttv/ICs [new file with mode: 0644]
Documentation/video4linux/bttv/INSTALL [new file with mode: 0644]
Documentation/video4linux/bttv/PROBLEMS [new file with mode: 0644]
Documentation/video4linux/bttv/README [new file with mode: 0644]
Documentation/video4linux/bttv/README.FIRST [new file with mode: 0644]
Documentation/video4linux/bttv/README.Hauppauge [new file with mode: 0644]
Documentation/video4linux/bttv/README.MIRO [new file with mode: 0644]
Documentation/video4linux/bttv/README.PCI [new file with mode: 0644]
Documentation/video4linux/bttv/README.RADIO [new file with mode: 0644]
Documentation/video4linux/bttv/THANKS [new file with mode: 0644]
Documentation/video4linux/radiotrack.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/i386/kernel/bios32.c
arch/i386/kernel/mca.c
arch/i386/kernel/mtrr.c
arch/i386/kernel/process.c
arch/i386/kernel/signal.c
arch/i386/lib/usercopy.c
arch/i386/mm/init.c
arch/m68k/atari/stram.c
arch/m68k/bvme6000/rtc.c
arch/m68k/mac/adb-bus.c
arch/m68k/mvme16x/rtc.c
arch/ppc/kernel/ppc_htab.c
arch/sparc64/solaris/socksys.c
drivers/Makefile
drivers/acorn/block/fd1772.c
drivers/acorn/block/mfmhd.c
drivers/ap1000/ap.c
drivers/ap1000/ddv.c
drivers/ap1000/ringbuf.c
drivers/block/Makefile
drivers/block/acsi.c
drivers/block/acsi_slm.c
drivers/block/amiflop.c
drivers/block/ataflop.c
drivers/block/floppy.c
drivers/block/genhd.c
drivers/block/ide.c
drivers/block/loop.c
drivers/block/md.c
drivers/block/nbd.c
drivers/block/paride/Makefile
drivers/block/paride/bpck.c
drivers/block/paride/paride.c
drivers/block/paride/pcd.c
drivers/block/paride/pd.c
drivers/block/paride/pf.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/ps2esdi.c
drivers/block/rd.c
drivers/block/swim3.c
drivers/block/xd.c
drivers/block/z2ram.c
drivers/cdrom/Makefile
drivers/cdrom/aztcd.c
drivers/cdrom/cdrom.c
drivers/cdrom/gscd.c
drivers/cdrom/optcd.c
drivers/cdrom/sbpcd.c
drivers/cdrom/sjcd.c
drivers/cdrom/sonycd535.c
drivers/char/Config.in
drivers/char/Makefile
drivers/char/acquirewdt.c
drivers/char/adbmouse.c
drivers/char/amigamouse.c
drivers/char/apm_bios.c
drivers/char/atarimouse.c
drivers/char/atixlmouse.c
drivers/char/bt848.h
drivers/char/bttv.c
drivers/char/bttv.h
drivers/char/busmouse.c
drivers/char/cyclades.c
drivers/char/dn_keyb.c
drivers/char/dsp56k.c
drivers/char/fbmem.c
drivers/char/ftape/lowlevel/ftape-proc.c
drivers/char/ftape/zftape/zftape-init.c
drivers/char/h8.c
drivers/char/hfmodem/main.c
drivers/char/lp.c
drivers/char/lp_m68k.c
drivers/char/macmouse.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/msbusmouse.c
drivers/char/n_tty.c
drivers/char/nvram.c
drivers/char/pc110pad.c
drivers/char/pcwd.c
drivers/char/psaux.c
drivers/char/radio-aimslab.c
drivers/char/radio-aztech.c
drivers/char/radio-miropcm20.c [new file with mode: 0644]
drivers/char/radio-rtrack2.c
drivers/char/radio-sf16fmi.c
drivers/char/radio-zoltrix.c
drivers/char/random.c
drivers/char/rtc.c
drivers/char/softdog.c
drivers/char/stallion.c
drivers/char/tpqic02.c
drivers/char/tty_io.c
drivers/char/tuner.c
drivers/char/vc_screen.c
drivers/char/videodev.c
drivers/char/wdt.c
drivers/isdn/avmb1/capi.c
drivers/macintosh/adb.c
drivers/macintosh/nvram.c
drivers/macintosh/via-pmu.c
drivers/pci/oldproc.c
drivers/pci/pci.c
drivers/pci/proc.c
drivers/sbus/audio/audio.c
drivers/sbus/char/bpp.c
drivers/sbus/char/envctrl.c
drivers/sbus/char/flash.c
drivers/sbus/char/openprom.c
drivers/sbus/char/pcikbd.c
drivers/sbus/char/rtc.c
drivers/sbus/char/sunkbd.c
drivers/sbus/char/sunmouse.c
drivers/sbus/char/vfc_dev.c
drivers/scsi/Makefile
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/seagate.h
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/sgi/char/graphics.c
drivers/sgi/char/shmiq.c
drivers/sgi/char/streamable.c
drivers/sgi/char/usema.c
drivers/sound/Config.in
drivers/sound/dmasound.c
drivers/sound/es1370.c
drivers/sound/es1371.c
drivers/sound/lowlevel/README
drivers/sound/lowlevel/README.aedsp16 [deleted file]
drivers/sound/lowlevel/aci.c
drivers/sound/lowlevel/aedsp16.c
drivers/sound/lowlevel/miroaci.h [new file with mode: 0644]
drivers/sound/lowlevel/soundlow.c
drivers/sound/msnd_pinnacle.c
drivers/sound/sb_common.c
drivers/sound/sonicvibes.c
drivers/sound/sound_core.c
drivers/sound/soundcard.c
drivers/zorro/proc.c
fs/adfs/dir.c
fs/adfs/file.c
fs/affs/dir.c
fs/affs/file.c
fs/autofs/dir.c
fs/autofs/root.c
fs/bad_inode.c
fs/binfmt_aout.c
fs/binfmt_elf.c
fs/binfmt_em86.c
fs/binfmt_java.c
fs/binfmt_misc.c
fs/binfmt_script.c
fs/buffer.c
fs/coda/dir.c
fs/coda/file.c
fs/coda/pioctl.c
fs/coda/psdev.c
fs/dcache.c
fs/devices.c
fs/devpts/inode.c
fs/devpts/root.c
fs/dquot.c
fs/exec.c
fs/ext2/balloc.c
fs/ext2/dir.c
fs/ext2/file.c
fs/ext2/ialloc.c
fs/fat/dir.c
fs/fat/file.c
fs/fifo.c
fs/file_table.c
fs/filesystems.c
fs/hfs/dir_cap.c
fs/hfs/dir_dbl.c
fs/hfs/dir_nat.c
fs/hfs/file.c
fs/hfs/file_cap.c
fs/hfs/file_hdr.c
fs/isofs/dir.c
fs/isofs/file.c
fs/lockd/clntproc.c
fs/lockd/svclock.c
fs/minix/dir.c
fs/minix/file.c
fs/ncpfs/dir.c
fs/ncpfs/file.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/mount_clnt.c
fs/nfs/nfs2xdr.c
fs/nfs/write.c
fs/ntfs/fs.c
fs/open.c
fs/pipe.c
fs/proc/array.c
fs/proc/base.c
fs/proc/fd.c
fs/proc/generic.c
fs/proc/kmsg.c
fs/proc/link.c
fs/proc/mem.c
fs/proc/net.c
fs/proc/omirr.c
fs/proc/openpromfs.c
fs/proc/root.c
fs/proc/scsi.c
fs/smbfs/dir.c
fs/smbfs/file.c
fs/super.c
fs/sysv/dir.c
fs/sysv/file.c
fs/ufs/dir.c
fs/ufs/file.c
fs/umsdos/dir.c
fs/umsdos/file.c
fs/umsdos/rdir.c
fs/umsdos/symlink.c
include/asm-alpha/fcntl.h
include/asm-alpha/posix_types.h
include/asm-arm/uaccess.h
include/asm-i386/fcntl.h
include/asm-i386/fixmap.h
include/asm-i386/uaccess.h
include/asm-i386/unistd.h
include/asm-m68k/uaccess.h
include/asm-ppc/uaccess.h
include/asm-sparc/uaccess.h
include/linux/file.h
include/linux/fs.h
include/linux/pci.h
include/linux/shm.h
include/linux/videodev.h
init/main.c
ipc/sem.c
ipc/shm.c
ipc/util.c
kernel/capability.c
kernel/fork.c
kernel/kmod.c
kernel/panic.c
kernel/printk.c
kernel/resource.c
kernel/sched.c
kernel/signal.c
kernel/sysctl.c
mm/mmap.c
mm/page_alloc.c
mm/slab.c
mm/swapfile.c
mm/vmscan.c
net/netlink/netlink_dev.c
net/socket.c
net/sunrpc/clnt.c
net/sunrpc/sched.c
net/sunrpc/xprt.c
net/wanrouter/wanproc.c

diff --git a/CREDITS b/CREDITS
index d7ee2925775bf4e01b85703448db5f92e17119f4..c563579b70ee9e2642261b8c3a9afff30cae2606 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -67,6 +67,7 @@ P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC  C0 4B 81 1D 8C 15 C8 E5
 D: Parport hacker
 D: Implemented a workaround for some interrupt buggy printers
 D: Author of pscan that helps to fix lp/parport bug
+D: Author of lil (Linux Interrupt Latency benchmark)
 D: Various other kernel hacks
 S: Via Ciaclini 26
 S: Imola 40026
@@ -333,18 +334,19 @@ S: East Malvern, Victoria, 3145
 S: Australia
 
 N: Alan Cox
-E: alan@lxorguk.ukuu.org.uk (linux related - except big patches)
-E: iialan@www.uk.linux.org (linux.org.uk/big patches)
-E: alan@cymru.net (commercial CymruNET stuff)
+W: http://roadrunner.swansea.linux.org.uk/alan.shtml
+E: alan@lxorguk.ukuu.org.uk
+E: alan@www.linux.org.uk (linux.org.uk stuff)
 E: Alan.Cox@linux.org (if others fail)
-D: NET2Debugged/NET3 author
-D: Network layer debugging
-D: Initial AX.25 & IPX releases
-D: Original Linux netatalk patches.
+D: Linux Networking (0.99.10->2.0.29)
+D: Original Appletalk, AX.25, and IPX code
 D: Current 3c501 hacker. >>More 3c501 info/tricks wanted<<.
 D: Watchdog timer drivers
-D: Linux/SMP
-S: CymruNet Limited
+D: Linux/SMP x86 (up to 2.0 only)
+D: Initial Mac68K port
+D: Video4Linux design, bw-qcam and PMS driver ports.
+D: 2.1.x modular sound
+S: c/o I2IT Limited
 S: The Innovation Centre
 S: Singleton Park
 S: Swansea, SA2 8PP
diff --git a/Documentation/radiotrack.txt b/Documentation/radiotrack.txt
deleted file mode 100644 (file)
index fe942e8..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-NOTES ON RADIOTRACK CARD CONTROL
-by Stephen M. Benoit (benoits@servicepro.com)  Dec 14, 1996
-----------------------------------------------------------------------------
-
-Document version 1.0
-
-ACKNOWLEDGMENTS
-----------------
-This document was made based on 'C' code for Linux from Gideon le Grange
-(legrang@active.co.za or legrang@cs.sun.ac.za) in 1994, and elaborations from
-Frans Brinkman (brinkman@esd.nl) in 1996.  The results reported here are from
-experiments that the author performed on his own setup, so your mileage may
-vary... I make no guarantees, claims or warrantees to the suitability or
-validity of this information.  No other documentation on the AIMS
-Lab (http://www.aimslab.com/) RadioTrack card was made available to the
-author.  This document is offered in the hopes that it might help users who
-want to use the RadioTrack card in an environment other than MS Windows.
-
-WHY THIS DOCUMENT?
-------------------
-I have a RadioTrack card from back when I ran an MS-Windows platform.  After
-converting to Linux, I found Gideon le Grange's command-line software for
-running the card, and found that it was good!  Frans Brinkman made a
-comfortable X-windows interface, and added a scanning feature.  For hack
-value, I wanted to see if the tuner could be tuned beyond the usual FM radio
-broadcast band, so I could pick up the audio carriers from North American
-broadcast TV channels, situated just below and above the 87.0-109.0 MHz range.
-I did not get much success, but I learned about programming ioports under
-Linux and gained some insights about the hardware design used for the card.
-
-So, without further delay, here are the details.
-
-
-PHYSICAL DESCRIPTION
---------------------
-The RadioTrack card is an ISA 8-bit FM radio card.  The radio frequency (RF)
-input is simply an antenna lead, and the output is a power audio signal
-available through a miniature phono plug.  Its RF frequencies of operation are
-more or less limited from 87.0 to 109.0 MHz (the commercial FM broadcast
-band).  Although the registers can be programmed to request frequencies beyond
-these limits, experiments did not give promising results.  The variable
-frequency oscillator (VFO) that demodulates the intermediate frequency (IF)
-signal probably has a small range of useful frequencies, and wraps around or
-gets clipped beyond the limits mentioned above.
-
-
-CONTROLLING THE CARD WITH IOPORT
---------------------------------
-The RadioTrack (base) ioport is configurable for 0x30c or 0x20c.  Only one
-ioport seems to be involved.  The ioport decoding circuitry must be pretty
-simple, as individual ioport bits are directly matched to specific functions
-(or blocks) of the radio card.  This way, many functions can be changed in
-parallel with one write to the ioport.  The only feedback available through
-the ioports appears to be the "Stereo Detect" bit.
-
-The bits of the ioport are arranged as follows:
-
-  MSb                                                         LSb
-+------+------+------+--------+--------+-------+---------+--------+
-| VolA | VolB | ???? | Stereo | Radio  | TuneA | TuneB   | Tune   |
-|  (+) |  (-) |      | Detect | Audio  | (bit) | (latch) | Update |
-|      |      |      | Enable | Enable |       |         | Enable |
-+------+------+------+--------+--------+-------+---------+--------+
-
-
-VolA . VolB  [AB......]
------------
-0 0 : audio mute
-0 1 : volume +    (some delay required)
-1 0 : volume -    (some delay required)
-1 1 : stay at present volume
-
-Stereo Detect Enable [...S....]
---------------------
-0 : No Detect
-1 : Detect
-
-  Results available by reading ioport >60 msec after last port write.
-  0xff ==> no stereo detected,  0xfd ==> stereo detected.
-
-Radio to Audio (path) Enable [....R...]
-----------------------------
-0 : Disable path (silence)
-1 : Enable path  (audio produced)
-
-TuneA . TuneB [.....AB.]
--------------
-0 0 : "zero" bit phase 1
-0 1 : "zero" bit phase 2
-
-1 0 : "one" bit phase 1
-1 1 : "one" bit phase 2
-
-  24-bit code, where bits = (freq*40) + 10486188.
-  The Most Significant 11 bits must be 1010 xxxx 0x0 to be valid.
-  The bits are shifted in LSb first.
-
-Tune Update Enable [.......T]
-------------------
-0 : Tuner held constant
-1 : Tuner updating in progress
-
-
-PROGRAMMING EXAMPLES
---------------------
-Default:        BASE <-- 0xc8  (current volume, no stereo detect,
-                               radio enable, tuner adjust disable)
-
-Card Off:      BASE <-- 0x00  (audio mute, no stereo detect,
-                               radio disable, tuner adjust disable)
-
-Card On:       BASE <-- 0x00  (see "Card Off", clears any unfinished business)
-               BASE <-- 0xc8  (see "Default")
-
-Volume Down:    BASE <-- 0x48  (volume down, no stereo detect,
-                               radio enable, tuner adjust disable)
-               * wait 10 msec *
-               BASE <-- 0xc8  (see "Default")
-
-Volume Up:      BASE <-- 0x88  (volume up, no stereo detect,
-                               radio enable, tuner adjust disable)
-               * wait 10 msec *
-               BASE <-- 0xc8  (see "Default")
-
-Check Stereo:   BASE <-- 0xd8  (current volume, stereo detect,
-                               radio enable, tuner adjust disable)
-               * wait 100 msec *
-               x <-- BASE     (read ioport)
-               BASE <-- 0xc8  (see "Default")
-
-               x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
-
-Set Frequency:  code = (freq*40) + 10486188
-                foreach of the 24 bits in code,
-                (from Least to Most Significant):
-                  to write a "zero" bit,
-                    BASE <-- 0x01  (audio mute, no stereo detect, radio
-                                   disable, "zero" bit phase 1, tuner adjust)
-                    BASE <-- 0x03  (audio mute, no stereo detect, radio
-                                   disable, "zero" bit phase 2, tuner adjust)
-                  to write a "one" bit,
-                    BASE <-- 0x05  (audio mute, no stereo detect, radio
-                                   disable, "one" bit phase 1, tuner adjust)
-                    BASE <-- 0x07  (audio mute, no stereo detect, radio
-                                   disable, "one" bit phase 2, tuner adjust)
-
-----------------------------------------------------------------------------
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html
new file mode 100644 (file)
index 0000000..5b3780c
--- /dev/null
@@ -0,0 +1,354 @@
+<HTML><HEAD>
+<TITLE>Video4Linux Kernel API Reference v0.1:19980516</TITLE>
+</HEAD>
+<BODY bgcolor="#ffffff">
+<H3>Devices</H3>
+Video4Linux provides the following sets of device files. These live on the
+character device formerly known as "/dev/bttv". /dev/bttv should be a
+symlink to /dev/video0 for most people. 
+<P>
+<TABLE>
+<TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH>
+<TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD>
+<TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD>
+<TR><TD>/dev/vtx</TD><TD>192-223</TD><TD>Teletext Interface Chips</TD>
+<TR><TD>/dev/vbi</TD><TD>224-239</TD><TD>Raw VBI Data (Intercast/teletext)</TD>
+</TABLE>
+<P>
+Video4Linux programs open and scan the devices to find what they are looking
+for. Capability queries define what each interface supports. The 
+described API is only defined for video capture cards. The relevant subset
+applies to radio cards. Teletext interfaces talk the existing VTX API.
+<P>
+<H3>Capability Query Ioctl</H3>
+The <B>VIDIOCGCAP</B> ioctl call is used to obtain the capability
+information for a video device. The <b>struct video_capability</b> object
+passed to the ioctl is completed and returned. It contains the following
+information
+<P>
+<TABLE>
+<TR><TD><b>name[32]</b><TD>Cannonical name for this interface</TD>
+<TR><TD><b>type</b><TD>Type of interface</TD>
+<TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD>
+<TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD>
+<TR><TD><b>maxwidth</b><TD>Maximum capture width in pixels</TD>
+<TR><TD><b>maxheight</b><TD>Maximum capture height in pixels</TD>
+<TR><TD><b>minwidth</b><TD>Minimum capture width in pixels</TD>
+<TR><TD><b>minheight</b><TD>Minimum capture height in pixels</TD>
+</TABLE>
+<P>
+The type field lists the capability flags for the device. These are
+as follows
+<P>
+<TABLE>
+<TR><TH>Name</TH><TH>Description</TH>
+<TR><TD><b>VID_TYPE_CAPTURE</b><TD>Can capture to memory</TD>
+<TR><TD><b>VID_TYPE_TUNER</b><TD>Has a tuner of some form</TD>
+<TR><TD><b>VID_TYPE_TELETEXT</b><TD>Has teletext capability</TD>
+<TR><TD><b>VID_TYPE_OVERLAY</b><TD>Can overlay its image onto the frame buffer</TD>
+<TR><TD><b>VID_TYPE_CHROMAKEY</b><TD>Overlay is Chromakeyed</TD>
+<TR><TD><b>VID_TYPE_CLIPPING</b><TD>Overlay clipping is supported</TD>
+<TR><TD><b>VID_TYPE_FRAMERAM</b><TD>Overlay overwrites frame buffer memory</TD>
+<TR><TD><b>VID_TYPE_SCALES</b><TD>The hardware supports image scaling</TD>
+<TR><TD><b>VID_TYPE_MONOCHROME</b><TD>Image capture is grey scale only</TD>
+<TR><TD><b>VID_TYPE_SUBCAPTURE</b><TD>Capture can be of only part of the image</TD>
+</TABLE>
+<P>
+The minimum and maximum sizes listed for a capture device do not imply all
+that all height/width ratios or sizes within the range are possible. A
+request to set a size will be honoured by the largest available capture
+size whose capture is no large than the requested rectangle in either
+direction. For example the quickcam has 3 fixed settings. 
+<P>
+<H3>Frame Buffer</H3>
+Capture cards that drop data directly onto the frame buffer must be told the
+base address of the frame buffer, its size and organisation. This is a 
+privileged ioctl and one that eventually X itself should set.
+<P>
+The <b>VIDIOCSFBUF</b> ioctl sets the frame buffer parameters for a capture
+card. If the card does not do direct writes to the frame buffer then this
+ioctl will be unsupported. The <b>VIDIOCGFBUF</b> ioctl returns the
+currently used parameters. The structure used in both cases is a 
+<b>struct video_buffer</b>.
+<P>
+<TABLE>
+<TR><TD><b>void *base</b></TD><TD>Base physical address of the buffer</TD>
+<TR><TD><b>int height</b></TD><TD>Height of the frame buffer</TD>
+<TR><TD><b>int width</b></TD><TD>Width of the frame buffer</TD>
+<TR><TD><b>int depth</b></TD><TD>Depth of the frame buffer</TD>
+<TR><TD><b>int bytesperline</b></TD><TD>Number of bytes of memory between the start of two adjacent lines</TD>
+</TABLE>
+<P>
+Note that these values reflect the physical layout of the frame buffer. 
+The visible area may be smaller. In fact under XFree86 this is commonly the
+case. XFree86 DGA can provide the parameters required to set up this ioctl.
+Setting the base address to NULL indicates there is no physical frame buffer
+access.
+<P>
+<H3>Capture Windows</H3>
+The capture area is described by a <b>struct video_window</b>. This defines
+a capture area and the clipping information if relevant. The 
+<b>VIDIOCGWIN</b> ioctl recovers the current settings and the 
+<b>VIDIOCSWIN</b> sets new values. A successful call to <b>VIDIOCSWIN</b> 
+indicates that a suitable set of parameters have been chosen. They do not
+indicate that exactly what was requested was granted. The program should
+call <b>VIDIOCGWIN</b> to check if the nearest match was suitable. The
+<b>struct video_window</b> contains the following fields.
+<P>
+<TABLE>
+<TR><TD><b>x</b><TD>The X co-ordinate specified in X windows format.</TD>
+<TR><TD><b>y</b><TD>The Y co-ordinate specified in X windows format.</TD>
+<TR><TD><b>width</b><TD>The width of the image capture.</TD>
+<TR><TD><b>height</b><TD>The height of the image capture.</TD>
+<TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD>
+<TR><TD><b>flags</b><TD>Additional capture flags.</TD>
+<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em)</TD>
+<TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD>
+</TABLE>
+<P>
+Clipping rectangles are passed as an array. Each clip consists of the following
+fields available to the user.
+<P>
+<TABLE>
+<TR><TD><b>x</b></TD><TD>X co-ordinate of rectangle to skip</TD>
+<TR><TD><b>y</b></TD><TD>Y co-ordinate of rectangle to skip</TD>
+<TR><TD><b>width</b></TD><TD>Width of rectangle to skip</TD>
+<TR><TD><b>height</b></TD><TD>Height of rectangle to skip</TD>
+</TABLE>
+<P>
+Merely setting the window does not enable capturing. Overlay capturing
+is activatied by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
+disabled by passing it a value of 0. 
+<P>
+Some capture devices can capture a subfield of the image they actually see.
+This is indicated when VIDEO_TYPE_SUBCAPTURE is defined.
+The video_capture describes the time and spacial subfields to capture.
+The video_capture structure contains the following fields.
+<P>
+<TABLE>
+<TR><TD><b>x</b></TD><TD>X co-ordinate of source rectangle to grab</TD>
+<TR><TD><b>y</b></TD><TD>Y co-ordinate of source rectangle to grab</TD>
+<TR><TD><b>width</b></TD><TD>Width of source rectangle to grab</TD>
+<TR><TD><b>height</b></TD><TD>Height of source rectangle to grab</TD>
+<TR><TD><b>decimation</b></TD><TD>Decimation to apply</TD>
+<TR><TD><b>flags</b></TD><TD>Flag settings for grabbing</TD>
+</TABLE>
+The available flags are
+<P>
+<TABLE>
+<TR><TH>Name</TH><TH>Description</TH>
+<TR><TD><b>VIDEO_CAPTURE_ODD</b><TD>Capture only odd frames</TD>
+<TR><TD><b>VIDEO_CAPTURE_EVEN</b><TD>Capture only even frames</TD>
+</TABLE>
+<P>
+<H3>Video Sources</H3>
+Each video4linux video or audio device captures from one or more 
+source <b>channels</b>. Each channel can be queries with the 
+<b>VDIOCGCHAN</b> ioctl call. Before invoking this function the caller
+must set the channel field to the channel that is being queried. On return
+the <b>struct video_channel</b> is filled in with information about the
+nature of the channel itself.
+<P>
+The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the
+capture to this input. It is not defined whether paramters such as colour
+settings or tuning are maintained across a channel switch. The caller should
+maintain settings as desired for each channel. (This is reasonable as 
+different video inputs may have different properties).
+<P>
+The <b>struct video_channel</b> consists of the following
+<P>
+<TABLE>
+<TR><TD><b>channel</b></TD><TD>The channel number</TD>
+<TR><TD><b>name</b></TD><TD>The input name - preferably reflecting the label
+on the card input itself</TD>
+<TR><TD><b>tuners</b></TD><TD>Number of tuners for this input</TD>
+<TR><TD><b>flags</b></TD><TD>Properties the tuner has</TD>
+<TR><TD><b>type</b></TD><TD>Input type (if known)</TD>
+<TR><TD><b>norm</b><TD>The norm for this channel</TD>
+</TABLE>
+<P>
+The flags defined are
+<P>
+<TABLE>
+<TR><TD><b>VIDEO_VC_TUNER</b><TD>Channel has tuners.</TD>
+<TR><TD><b>VIDEO_VC_AUDIO</b><TD>Channel has audio.</TD>
+<TR><TD><b>VIDEO_VC_NORM</b><TD>Channel has norm setting.</TD>
+</TABLE>
+<P>
+The types defined are
+<P>
+<TABLE>
+<TR><TD><b>VIDEO_TYPE_TV</b><TD>The input is a TV input.</TD>
+<TR><TD><b>VIDEO_TYPE_CAMERA</b><TD>The input is a camera.</TD>
+</TABLE>
+<P>
+<H3>Image Properties</H3>
+The image properties of the picture can be queried with the <b>VIDIOCGPICT</b>
+ioctl which fills in a <b>struct video_picture</b>. The <b>VIDIOCSPICT</b> 
+ioctl allows values to be changed. All values except for the palette type
+are scaled between 0-65535. 
+<P>
+The <b>struct video_picture</b> consists of the following fields
+<P>
+<TABLE>
+<TR><TD><b>brightness</b><TD>Picture brightness</TD>
+<TR><TD><b>hue</b><TD>Picture hue (colour only)</TD>
+<TR><TD><b>colour</b><TD>Picture colour (colour only)</TD>
+<TR><TD><b>contrast</b><TD>Picture contrast</TD>
+<TR><TD><b>whiteness</b><TD>The whiteness (greyscale only)</TD>
+<TR><TD><b>depth</b><TD>The capture depth (may need to match the frame buffer depth)</TD>
+<TR><TD><b>palette</b><TD>Reports the palette that should be used for this image</TD>
+</TABLE>
+<P>
+The following palettes are defined
+<P>
+<TABLE>
+<TR><TD><b>VIDEO_PALETTE_GREY</b><TD>Linear intensity grey scale (255 is brightest).</TD>
+<TR><TD><b>VIDEO_PALETTE_HI240</b><TD>The BT848 8bit colour cube.</TD>
+<TR><TD><b>VIDEO_PALETTE_RGB565</b><TD>RGB565 packed into 16 bit words.</TD>
+<TR><TD><b>VIDEO_PALETTE_RGB555</b><TD>RGV555 packed into 16 bit words, top bit undefined.</TD>
+<TR><TD><b>VIDEO_PALETTE_RGB24</b><TD>RGB888 packed into 24bit words.</TD>
+<TR><TD><b>VIDEO_PALETTE_RGB32</b><TD>RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.</TD>
+<TR><TD><b>VIDEO_PALETTE_YUV422</b><TD>Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V</TD>
+<TR><TD><b>VIDEO_PALETTE_YUYV</b><TD>Describe me</TD>
+<TR><TD><b>VIDEO_PALETTE_UYVY</b><TD>Describe me</TD>
+<TR><TD><b>VIDEO_PALETTE_YUV420</b><TD>YUV420 capture</TD>
+<TR><TD><b>VIDEO_PALETTE_YUV411</b><TD>YUV411 capture</TD>
+<TR><TD><b>VIDEO_PALETTE_RAW</b><TD>RAW capture (BT848)</TD>
+<TR><TD><b>VIDEO_PALETTE_YUV422P</b><TD>YUV 4:2:2 Planar</TD>
+<TR><TD><b>VIDEO_PALETTE_YUV411P</b><TD>YUV 4:1:1 Planar</TD>
+</TABLE>
+<P>
+<H3>Tuning</H3>
+Each video input channel can have one or more tuners associated with it. Many
+devices will not have tuners. TV cards and radio cards will have one or more
+tuners attached.
+<P>
+Tuners are described by a <b>struct video_tuner</b> which can be obtained by
+the <b>VIDIOCGTUNER</b> ioctl. Fill in the tuner number in the structure
+then pass the structure to the ioctl to have the data filled in. The 
+tuner can be switched using <b>VIDIOCSTUNER</b> which takes an integer argument
+giving the tuner to use. A struct tuner has the following fields
+<P>
+<TABLE>
+<TR><TD><b>tuner</b><TD>Number of the tuner</TD>
+<TR><TD><b>name</b><TD>Cannonical name for this tuner (eg FM/AM/TV)</TD>
+<TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD>
+<TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD>
+<TR><TD><b>flags</b><TD>Flags describing the tuner</TD>
+<TR><TD><b>mode</b><TD>The video signal mode if relevant</TD>
+<TR><TD><b>signal</b><TD>Signal strength if known - between 0-65535</TD>
+</TABLE>
+<P>
+The following flags exist
+<P>
+<TABLE>
+<TR><TD><b>VIDEO_TUNER_PAL</b><TD>PAL tuning is supported</TD>
+<TR><TD><b>VIDEO_TUNER_NTSC</b><TD>NTSC tuning is supported</TD>
+<TR><TD><b>VIDEO_TUNER_SECAM</b><TD>SECAM tuning is supported</TD>
+<TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD>
+<TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD>
+<TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD>
+</TABLE>
+<P>
+The following modes are defined
+<P>
+<TABLE>
+<TR><TD><b>VIDEO_MODE_PAL</b><TD>The tuner is in PAL mode</TD>
+<TR><TD><b>VIDEO_MODE_NTSC</b><TD>The tuner is in NTSC mode</TD>
+<TR><TD><b>VIDEO_MODE_SECAM</b><TD>The tuner is in SECAM mode</TD>
+<TR><TD><b>VIDEO_MODE_AUTO</b><TD>The tuner auto switches, or mode does not apply</TD>
+</TABLE>
+<P>
+Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the
+<b>VIDEO_TUNER_LOW</b> flag is set they are in 1/16th KHz. The current
+frequency is obtained as an unsigned long via the <b>VIDIOCGFREQ</b> ioctl and
+set by the <b>VIDIOCSFREQ</b> ioctl.
+<P>
+<H3>Audio</H3>
+TV and Radio devices have one or more audio inputs that may be selected. 
+The audio properties are queried by passing a <b>struct video_audio</b> to <b>VIDIOCGAUDIO</b> ioctl. The
+<b>VIDIOCSAUDIO</b> ioctl sets audio properties.
+<P>
+The structure contains the following fields
+<P>
+<TABLE>
+<TR><TD><b>audio</b><TD>The channel number</TD>
+<TR><TD><b>volume</b><TD>The voume level</TD>
+<TR><TD><b>bass</b><TD>The bass level</TD>
+<TR><TD><b>treble</b><TD>The treble level</TD>
+<TR><TD><b>flags</b><TD>Flags describing the audio channel</TD>
+<TR><TD><b>name</b><TD>Canonical name for the audio input</TD>
+<TR><TD><b>mode</b><TD>The mode the audio input is in</TD>
+<TR><TD><b>balance</b><TD>The left/right balance</TD>
+<TR><TD><b>step</b><TD>Actual step used by the hardware</TD>
+</TABLE>
+<P>
+The following flags are defined
+<P>
+<TABLE>
+<TR><TD><b>VIDEO_AUDIO_MUTE</b><TD>The audio is muted</TD>
+<TR><TD><b>VIDEO_AUDIO_MUTABLE</b><TD>Audio muting is supported</TD>
+<TR><TD><b>VIDEO_AUDIO_VOLUME</b><TD>The volume is controllable</TD>
+<TR><TD><b>VIDEO_AUDIO_BASS</b><TD>The bass is controllable</TD>
+<TR><TD><b>VIDEO_AUDIO_TREBLE</b><TD>The treble is controllable</TD>
+<TR><TD><b>VIDEO_AUDIO_BALANCE</b><TD>The balance is controllable</TD>
+</TABLE>
+<P>
+The following decoding modes are defined
+<P>
+<TABLE>
+<TR><TD><b>VIDEO_SOUND_MONO</b><TD>Mono signal</TD>
+<TR><TD><b>VIDEO_SOUND_STEREO</b><TD>Stereo signal (NICAM for TV)</TD>
+<TR><TD><b>VIDEO_SOUND_LANG1</b><TD>European TV alternate language 1</TD>
+<TR><TD><b>VIDEO_SOUND_LANG2</b><TD>European TV alternate language 2</TD>
+</TABLE>
+<P>
+<H3>Reading Images</H3>
+Each call to the <b>read</b> syscall returns the next available image from
+the device. It is up to the caller to set the format and then to pass a 
+suitable size buffer and length to the function. Not all devices will support
+read operations.
+<P>
+A second way to handle image capture is via the mmap interface if supported.
+To use the mmap interface a user first sets the desired image size and depth
+properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size
+of buffer to mmap and the offset within the buffer for each frame. The
+number of frames supported is device dependant and may only be one. 
+<P>
+The video_mbuf structure contains the following fields
+<P>
+<TABLE>
+<TR><TD><b>size</b><TD>The number of bytes to map</TD>
+<TR><TD><b>frames</b><TD>The number of frames</TD>
+<TR><TD><b>offsets</b><TD>The offset of each frame</TD>
+</TABLE>
+<P>
+Once the mmap has been made the VIDIOCMCAPTURE ioctl sets the image size
+you wish to use (which should match or be below the initial query size).
+Having done so it will begin capturing to the memory mapped buffer. Whenever
+a buffer is "used" by the program it should called VIDIOCSYNC to free this
+frame up and continue. <em>to add:</em>VIDIOCSYNC takes the frame number
+you are freeing as its argument. When the buffer is unmapped or all the
+buffers are full capture ceases. While capturing to memory the driver will
+make a "best effort" attempt to capture to screen as well if requested. This
+normally means all frames that "miss" memory mapped capture will go to the
+display.
+<P>
+A final ioctl exists to allow a device to obtain related devices if a
+driver has multiple components (for example video0 may not be associated
+with vbi0 which would cause an intercast display program to make a bad
+mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated
+devices if any exist. The video_unit structure has the following fields.
+<P>
+<TABLE>
+<TR><TD><b>video</b><TD>Video capture device</TD>
+<TR><TD><b>vbi</b><TD>VBI capture device</TD>
+<TR><TD><b>radio</b><TD>Radio device</TD>
+<TR><TD><b>audio</b><TD>Audio mixer</TD>
+<TR><TD><b>teletext</b><TD>Teletext device</TD>
+</TABLE>
+<P>
+
+</BODY>
+</HTML>
diff --git a/Documentation/video4linux/bttv/CARDS b/Documentation/video4linux/bttv/CARDS
new file mode 100644 (file)
index 0000000..0cfd4d7
--- /dev/null
@@ -0,0 +1,104 @@
+Suppported cards:
+
+
+Bt848/Bt848a/Bt849/Bt878/Bt879 cards
+------------------------------------
+
+All cards with Bt848/Bt848a/Bt849/Bt878/Bt879 and normal Composite/S-VHS inputs
+are supported.
+Teletext and Intercast support (PAL only) via VBI samples decoding in software.
+
+Some cards with additional multiplexing of inputs are only partially 
+supported (unless specifications by the card manufacturer are given).
+
+All other cards only differ by additional components as tuners, sound decoders,
+EEPROMs, teletext decoders ...
+
+Tuner and sound decoder support for Bt878/879 is not fully working yet.
+
+
+MATRIX Vision
+-------------
+
+MV-Delta
+- Bt848A
+- 4 Composite inputs, 1 S-VHS input (shared with 4th composite)
+- EEPROM
+
+http://www.matrix-vision.de/
+
+This card has no tuner but supports all 4 composite (1 shared with an
+S-VHS input) of the Bt848A.
+Very nice card if you only have satellite TV but several tuners connected
+to the card via composite.
+
+Many thanks to Matrix-Vision for giving us 2 cards for free which made
+Bt848a/Bt849 single crytal operation support possible!!!
+
+
+
+Miro/Pinnacle PCTV
+------------------
+
+- Bt848 
+  some (all??) come with 2 crystals for PAL/SECAM and NTSC 
+- PAL, SECAM or NTSC TV tuner (Philips or TEMIC)
+- MSP34xx sound decoder on add on board
+  decoder is supported but AFAIK does not yet work 
+  (other sound MUX setting in GPIO port needed??? somebody who fixed this???)
+- 1 tuner, 1 composite and 1 S-VHS input
+- tuner type is autodetected
+
+http://www.miro.de/
+http://www.miro.com/
+
+
+Many thanks for the free card which made first NTSC support possible back
+in 1997!
+
+
+Hauppauge Win/TV pci
+--------------------
+
+There are many different versions of the Hauppauge cards with different 
+tuners (TV+Radio ...), teletext decoders.
+Note that even cards with same model numbers have (depending on the revision)
+different chips on it.
+
+- Bt848 (and others but always in 2 crystal operation???)
+  newer cards have a Bt878, I2C support for it is still experimental 
+- PAL, SECAM, NTSC or tuner with or without Radio support
+
+e.g.:
+  PAL: 
+  TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+  TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
+  
+  NTSC:
+  TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+  TSA5518: no datasheet available on Philips site
+- Philips SAA5246 or SAA5284 ( or no) Teletext decoder chip    
+  with buffer RAM (e.g. Winbond W24257AS-35: 32Kx8 CMOS static RAM)
+  SAA5246 (I2C 0x22) is supported
+- 256 bytes EEPROM: Microchip 24LC02B or Philips 8582E2Y 
+  with configuration information
+  I2C address 0xa0 (24LC02B also responds to 0xa2-0xaf)
+- 1 tuner, 1 composite and (depending on model) 1 S-VHS input
+- 14052B: mux for selection of sound source
+- sound decoder: TDA9800, MSP34xx (stereo cards) 
+
+
+AverMedia
+---------
+
+...
+
+
+
+
+
+
+
+
+
diff --git a/Documentation/video4linux/bttv/CONTRIBUTORS b/Documentation/video4linux/bttv/CONTRIBUTORS
new file mode 100644 (file)
index 0000000..cf7d230
--- /dev/null
@@ -0,0 +1,20 @@
+Contributors to bttv: 
+
+Michael Chu <mmchu@pobox.com>
+  AverMedia fix and more flexible card recognition
+
+Alan Cox <alan@cymru.net>
+  Video4Linux interface and 2.1.x kernel adaptation
+
+Chris Kleitsch
+  Hardware I2C
+  
+Gerd Knorr <kraxel@cs.tu-berlin.de> 
+  Radio card (ITT sound processor)
+
++ many more (please mail me if you are missing in this list and would
+             like to be mentioned)
+
+
+
+
diff --git a/Documentation/video4linux/bttv/ICs b/Documentation/video4linux/bttv/ICs
new file mode 100644 (file)
index 0000000..6b74913
--- /dev/null
@@ -0,0 +1,37 @@
+all boards:
+
+Brooktree Bt848/848A/849/878/879: video capture chip
+
+
+
+Miro PCTV:
+
+Philips or Temic Tuner
+
+
+
+Hauppauge Win/TV pci (version 405):
+
+Microchip 24LC02B or
+Philips 8582E2Y: 256 Byte EEPROM with configuration information
+                 I2C 0xa0-0xa1, (24LC02B also responds to 0xa2-0xaf)
+Philips SAA5246AGP/E: Videotext decoder chip, I2C 0x22-0x23
+TDA9800: sound decoder
+Winbond W24257AS-35: 32Kx8 CMOS static RAM (Videotext buffer mem)
+14052B: analog switch for selection of sound source
+
+PAL: 
+TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
+
+NTSC:
+TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
+TSA5518: no datasheet available on Philips site
+
+
+
+STB TV pci:
+
+???
+if you want better support for STB cards send me info!
+Look at the board! What chips are on it?
diff --git a/Documentation/video4linux/bttv/INSTALL b/Documentation/video4linux/bttv/INSTALL
new file mode 100644 (file)
index 0000000..52cac1e
--- /dev/null
@@ -0,0 +1,73 @@
+- Make sure you have a recent 2.0.x kernel (I recommend AT LEAST 2.0.33!)
+  or a recent 2.1.x kernel.
+  Older kernels might lead to problems. 
+
+- Do NOT compile videodev into your kernel!
+  Use the module supplied with bttv.
+
+- Edit "driver/Makefile":
+
+  - If you do NOT have a Miro card:
+    Adjust TUNER to a number between 0 and 7. 
+
+    This number has the following meaning:
+
+    0: Temic PAL tuner
+    1: Philips PAL_I tuner
+    2: Philips NTSC tuner
+    3: Philips SECAM tuner
+    4: no tuner
+    5: Philips PAL tuner
+    6: Temic NTSC tuner
+    7: Temic PAL tuner
+
+    The number corresponds to the number (-1) given at the GPIO port of the
+    Bt848 on Miro cards.
+
+
+  - Adjust CARD to one of the numbers below:
+
+    0: Auto-Detect
+    1: Miro
+    2: Hauppauge
+    3: STB
+    4: Intel
+    5: Diamond
+    6: AVerMedia
+
+
+  - You may have to adjust BTTV_MAJOR to a different number depending on your
+    kernel version. The official number 81 does not work on some setups.
+    But instead of changing it, better update to a newer kernel.
+
+  - If you have a Bt848a or Bt849 on your board you might have to
+    uncomment: -DUSE_PLL 
+
+- do a "make" in the main directory.
+
+If you have Hauppauge card read "README.HAUPPAUGE" before proceeding.
+
+- type "make ins"
+
+  This creates the bttv devices in /dev and installs the bttv module
+
+  Look in the kernel log file (/var/adm/syslog or /var/log/kernel or something
+  else depending on your /etc/syslogd.conf or just call "dmesg")
+  and see what bttv reported (lines starting with "bttv:")
+  If the installation failed and you send e-mail to me always include those
+  lines! Dumps of the insmod output alone do not help at all.
+
+- Start X11 in hi or true color mode 
+  8 bit color is also supported but really ugly!
+  (If you have an S3 card you might have to start X11 before installing
+   the module!)
+
+  If you have Motif or LessTif, "xtvscreen" in the "XTV" directory should
+  have been compiled with the "make" above.
+  Otherwise use the statically linked version which should be available 
+  on the web site you got bttv from.
+  Read the documentation in "XTV" and start xtvscreen.
+
+- make applications by typing "make" in "apps"
+   
+
diff --git a/Documentation/video4linux/bttv/PROBLEMS b/Documentation/video4linux/bttv/PROBLEMS
new file mode 100644 (file)
index 0000000..6148f85
--- /dev/null
@@ -0,0 +1,62 @@
+- Start capturing by pressing "c" or by selecting it via a menu!
+
+- Start capturing by pressing "c" or by selecting it via a menu!!!
+
+- The memory of some S3 cards is not recognized right:
+  
+  First of all, if you are not using Xfree-3.2 or newer, upgrade AT LEAST to
+  XFree-3.2A! This solved the problem for most people.
+
+  Start up X11 like this: "XF86_S3 -probeonly" and write down where the
+  linear frame buffer is.
+  If it is different to the address found by bttv install bttv like this:
+  "insmod bttv vidmem=0xfb0"
+  if the linear frame buffer is at 0xfb000000 (i.e. omit the last 5 zeros!)
+
+  Some S3 cards even take up 64MB of memory but only report 32MB to the BIOS.
+  If this 64MB area overlaps the IO memory of the Bt848 you also have to
+  remap this. E.g.: insmod bttv vidmem=0xfb0 remap=0xfa0
+
+  If the videomemory is found at the right place and there are no address
+  conflicts but still no picture (or the computer even crashes.),
+  try disabling features of your PCI chipset in the BIOS Setup.
+
+  Frank Kapahnke <frank@kapahnke.prima.ruhr.de> also reported that problems
+  with his S3 868 went away when he upgraded to XFree 3.2.
+
+
+- I still only get a black picture with my S3 card!
+
+  Even with XFree-3.2A some people have problems with their S3 cards
+  (mostly with Trio 64 but also with some others)
+  Get the free demo version of Accelerated X from www.xinside.com and try
+  bttv with it. bttv seems to work with most S3 cards with Accelerated X.
+  
+  Since I do not know much (better make that almost nothing) about VGA card
+  programming I do not know the reason for this.
+  Looks like XFree does something different when setting up the video memory?
+  Maybe somebody can enlighten me?  
+  Would be nice if somebody could get this to work with XFree since 
+  Accelerated X costs more than some of the grabber cards ... 
+  Better linear frame buffer support for S3 cards will probably be in
+  XFree 4.0.
+  
+- Grabbing is not switched off when changing consoles with XFree.
+  That's because XFree and some AcceleratedX versions do not send unmap
+  events.
+
+- Some popup windows (e.g. of the window manager) are not refreshed.
+  
+  Disable backing store by starting X with the option "-bs"
+
+- When using 32bpp in XFree or 24+8bpp mode in AccelX 3.1 the system
+  can sometimes lock up if you use more than 1 bt848 card at the same time.
+  You will always get pixel errors when e.g. using more than 1 card in full
+  screen mode. Maybe we need something faster than the PCI bus ...
+
+
+- Some S3 cards and the Matrox Mystique will produce pixel erros with
+  full resolution in 32bit mode.
+
+- Some video cards have problems with Accelerated X 4.1
\ No newline at end of file
diff --git a/Documentation/video4linux/bttv/README b/Documentation/video4linux/bttv/README
new file mode 100644 (file)
index 0000000..72f4f4b
--- /dev/null
@@ -0,0 +1,41 @@
+bttv - BT848 frame grabber driver
+
+Copyright (C) 1996,97 Ralph Metzler  (rjkm@thp.uni-koeln.de)
+                    & Marcus Metzler (mocm@thp.uni-koeln.de)
+                    according to GNU GPL in file COPYING.
+
+
+Bttv is a device driver for frame grabber cards using the Bt848 family
+of video decoder chips.
+Among those are the Bt848, Bt848A, Bt849, Bt878 and Bt879.
+The only major differences between the cards by different manufacturers 
+are the types of tuners and extra components on the boards.
+E.g., some cards by Hauppauge have an additional Videotext decoder 
+and/or sound decoder chip.
+Also type (Composite or S-VHS) and number of inputs differ.
+Other Brooktree chips (e.g. the Bt829) or chips by other manufacturers 
+(Philips, Zoran, ...) are NOT supported by bttv.
+
+You can use several cards at the same time.
+Interrupts can be shared with other Bt848 cards or any other drivers
+which allow it.
+The (arbitrary) maximum number of cards is 4 but can be adjusted by
+changing BTTV_MAX at the beginning of bttv.c if you need more.
+(But which board has more than 4 PCI slots plus 1 for the VGA card?)
+
+Bttv is a standard component of all newer 2.1.x kernels.
+This distribution additionally supports 2.0.x kernels and all other
+changes and improvements which did not make it into the kernel version
+yet. 
+It also includes versions of videodev.c, i2.c, tuner.c and others
+which are the same as in the latest 2.1.x kernel but with 2.0.x support.
+A kernel version >2.0.30 is recommended.
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Although bttv is now used and tested by many people it still might crash your
+computer! Take all precautions to avoid data loss until you are certain
+bttv runs on your setup without problems.
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+The latest version of bttv can be found at:
+http://www.thp.uni-koeln.de/~rjkm/linux/bttv.html
diff --git a/Documentation/video4linux/bttv/README.FIRST b/Documentation/video4linux/bttv/README.FIRST
new file mode 100644 (file)
index 0000000..ea68726
--- /dev/null
@@ -0,0 +1,4 @@
+o Please direct queries about the in kernel version of this driver to
+  Alan Cox first not to Ralph, or better yet join the video4linux mailing
+  list (mail majordomo@phunk.org with "subscribe video4linux")
+
diff --git a/Documentation/video4linux/bttv/README.Hauppauge b/Documentation/video4linux/bttv/README.Hauppauge
new file mode 100644 (file)
index 0000000..0076ed8
--- /dev/null
@@ -0,0 +1,29 @@
+The current I2C-Code could by accident overwrite the configuration EEPROM on 
+Hauppauge boards!!! 
+(E.g. the videotext driver and the bt848 driver do not know about each other.
+This might cause unwanted states on the I2C bus which overwrite the EEPROM)
+
+Back up this EEPROM before doing anything else by typing:
+(do this AFTER installing bttv.o with "make ins" but BEFORE starting the
+X application)
+
+make readee
+readee > tvee.h
+
+If you encounter any problems in Windows95 (like "PNP component not found" ...)
+go back into linux, load bttv and type:
+
+make writeee
+writeee
+
+to write the backed up contents.
+If you backed up your EEPROM as described above, this will restore it to its
+original state.
+A detailed description of the meaning of the EEPROM bytes by
+Hauppauge would of course be even more helpful! 
+
+If you have board type 405 and you did not make a backup, my tvee.h file in 
+mytvee.h might be of help.
+
+Forget about all of the above if you do not have a Hauppauge board.
+
diff --git a/Documentation/video4linux/bttv/README.MIRO b/Documentation/video4linux/bttv/README.MIRO
new file mode 100644 (file)
index 0000000..e74fc4a
--- /dev/null
@@ -0,0 +1,3 @@
+The right tuner type should automatically be detected.
+Look in your kernel log files to see which one bttv thinks it is.
+
diff --git a/Documentation/video4linux/bttv/README.PCI b/Documentation/video4linux/bttv/README.PCI
new file mode 100644 (file)
index 0000000..1ae8276
--- /dev/null
@@ -0,0 +1,36 @@
+Because some people were asking about the bandwidth the Bt848 might use up
+on the PCI bus I did a little benchmark.
+
+"bonnie -s 200" with a Fireball TM 3.8 Gb using Busmaster DMA on an ASUS P6NP5
+
+without capturing:
+
+              -------Sequential Output-------- ---Sequential Input-- --Random--
+              -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
+Machine    MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU  /sec %CPU
+          200  5353 76.6  5898 16.9  2363 12.1  5889 51.3  6416 10.2  37.8  0.9
+
+
+while capturing full screen PAL (786x576) with 24bpp:
+
+              -------Sequential Output-------- ---Sequential Input-- --Random--
+              -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- --Seeks---
+Machine    MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU  /sec %CPU
+          200  5619 69.3  5939 16.9  2334 12.0  5859 50.9  6441 10.5  37.9  0.9
+
+The differences are small and probably within the normal error margin of
+bonnie.
+So, one bt848 card does not have much(any?) impact on the normal operation 
+of a Linux system.
+If you have several cards running this will look very differently!
+The same is probably true if your Linux box is used as a file server 
+with 15 (or 30) SCSI drives.
+I tested having 2 Bt848 cards grabbing in 32 bit mode (That's almost 100MB/s!)
+while running bonnie.
+The xtvscreen windows showed severe pixel errors.
+After a while the ide driver failed to use DMA and switched DMA off.
+It continued running but the results where bad.
+
+
+
diff --git a/Documentation/video4linux/bttv/README.RADIO b/Documentation/video4linux/bttv/README.RADIO
new file mode 100644 (file)
index 0000000..53d04f5
--- /dev/null
@@ -0,0 +1,15 @@
+Support is in now:
+  - Turn on the "big red switch" of the sound processor.
+  - two ioctls to access (some) registers of the sound processor.
+  - a function in the TV-Widget which monitors the signal quality
+    and does the mono/stereo switching.
+
+So you should have TV with (stereo) sound now.  Radio does _not_ work.
+It probably does not work with sat receivers. I can't test this and
+therefore hav'nt added support for it yet. If someone needs this and
+can help testing the sat stuff, drop me a note.
+
+  Gerd
+
+--
+Gerd Knorr <kraxel@cs.tu-berlin.de>
diff --git a/Documentation/video4linux/bttv/THANKS b/Documentation/video4linux/bttv/THANKS
new file mode 100644 (file)
index 0000000..0da6d9f
--- /dev/null
@@ -0,0 +1,24 @@
+Many thanks to:
+
+- Markus Schroeder <schroedm@uni-duesseldorf.de> for information on the Bt848 
+  and tuner programming and his control program xtvc.
+
+- Martin Buck <martin-2.buck@student.uni-ulm.de> for his great Videotext
+  package.
+
+- Gerd Knorr <kraxel@cs.tu-berlin.de> for the MSP3400 support and the modular
+  I2C, tuner, ... support.
+
+
+- MATRIX Vision for giving us 2 cards for free, which made support of
+  single crystal operation possible.
+
+- MIRO for providing a free PCTV card and detailed information about the
+  components on their cards. (E.g. how the tuner type is detected)
+  Without their card I could not have debugged the NTSC mode.
+       
+- Hauppauge for telling how the sound input is selected and what compenents
+  they do and will use on their radio cards.
+  Also many thanks for faxing me the FM1216 data sheet.
+
+
diff --git a/Documentation/video4linux/radiotrack.txt b/Documentation/video4linux/radiotrack.txt
new file mode 100644 (file)
index 0000000..fe942e8
--- /dev/null
@@ -0,0 +1,147 @@
+NOTES ON RADIOTRACK CARD CONTROL
+by Stephen M. Benoit (benoits@servicepro.com)  Dec 14, 1996
+----------------------------------------------------------------------------
+
+Document version 1.0
+
+ACKNOWLEDGMENTS
+----------------
+This document was made based on 'C' code for Linux from Gideon le Grange
+(legrang@active.co.za or legrang@cs.sun.ac.za) in 1994, and elaborations from
+Frans Brinkman (brinkman@esd.nl) in 1996.  The results reported here are from
+experiments that the author performed on his own setup, so your mileage may
+vary... I make no guarantees, claims or warrantees to the suitability or
+validity of this information.  No other documentation on the AIMS
+Lab (http://www.aimslab.com/) RadioTrack card was made available to the
+author.  This document is offered in the hopes that it might help users who
+want to use the RadioTrack card in an environment other than MS Windows.
+
+WHY THIS DOCUMENT?
+------------------
+I have a RadioTrack card from back when I ran an MS-Windows platform.  After
+converting to Linux, I found Gideon le Grange's command-line software for
+running the card, and found that it was good!  Frans Brinkman made a
+comfortable X-windows interface, and added a scanning feature.  For hack
+value, I wanted to see if the tuner could be tuned beyond the usual FM radio
+broadcast band, so I could pick up the audio carriers from North American
+broadcast TV channels, situated just below and above the 87.0-109.0 MHz range.
+I did not get much success, but I learned about programming ioports under
+Linux and gained some insights about the hardware design used for the card.
+
+So, without further delay, here are the details.
+
+
+PHYSICAL DESCRIPTION
+--------------------
+The RadioTrack card is an ISA 8-bit FM radio card.  The radio frequency (RF)
+input is simply an antenna lead, and the output is a power audio signal
+available through a miniature phono plug.  Its RF frequencies of operation are
+more or less limited from 87.0 to 109.0 MHz (the commercial FM broadcast
+band).  Although the registers can be programmed to request frequencies beyond
+these limits, experiments did not give promising results.  The variable
+frequency oscillator (VFO) that demodulates the intermediate frequency (IF)
+signal probably has a small range of useful frequencies, and wraps around or
+gets clipped beyond the limits mentioned above.
+
+
+CONTROLLING THE CARD WITH IOPORT
+--------------------------------
+The RadioTrack (base) ioport is configurable for 0x30c or 0x20c.  Only one
+ioport seems to be involved.  The ioport decoding circuitry must be pretty
+simple, as individual ioport bits are directly matched to specific functions
+(or blocks) of the radio card.  This way, many functions can be changed in
+parallel with one write to the ioport.  The only feedback available through
+the ioports appears to be the "Stereo Detect" bit.
+
+The bits of the ioport are arranged as follows:
+
+  MSb                                                         LSb
++------+------+------+--------+--------+-------+---------+--------+
+| VolA | VolB | ???? | Stereo | Radio  | TuneA | TuneB   | Tune   |
+|  (+) |  (-) |      | Detect | Audio  | (bit) | (latch) | Update |
+|      |      |      | Enable | Enable |       |         | Enable |
++------+------+------+--------+--------+-------+---------+--------+
+
+
+VolA . VolB  [AB......]
+-----------
+0 0 : audio mute
+0 1 : volume +    (some delay required)
+1 0 : volume -    (some delay required)
+1 1 : stay at present volume
+
+Stereo Detect Enable [...S....]
+--------------------
+0 : No Detect
+1 : Detect
+
+  Results available by reading ioport >60 msec after last port write.
+  0xff ==> no stereo detected,  0xfd ==> stereo detected.
+
+Radio to Audio (path) Enable [....R...]
+----------------------------
+0 : Disable path (silence)
+1 : Enable path  (audio produced)
+
+TuneA . TuneB [.....AB.]
+-------------
+0 0 : "zero" bit phase 1
+0 1 : "zero" bit phase 2
+
+1 0 : "one" bit phase 1
+1 1 : "one" bit phase 2
+
+  24-bit code, where bits = (freq*40) + 10486188.
+  The Most Significant 11 bits must be 1010 xxxx 0x0 to be valid.
+  The bits are shifted in LSb first.
+
+Tune Update Enable [.......T]
+------------------
+0 : Tuner held constant
+1 : Tuner updating in progress
+
+
+PROGRAMMING EXAMPLES
+--------------------
+Default:        BASE <-- 0xc8  (current volume, no stereo detect,
+                               radio enable, tuner adjust disable)
+
+Card Off:      BASE <-- 0x00  (audio mute, no stereo detect,
+                               radio disable, tuner adjust disable)
+
+Card On:       BASE <-- 0x00  (see "Card Off", clears any unfinished business)
+               BASE <-- 0xc8  (see "Default")
+
+Volume Down:    BASE <-- 0x48  (volume down, no stereo detect,
+                               radio enable, tuner adjust disable)
+               * wait 10 msec *
+               BASE <-- 0xc8  (see "Default")
+
+Volume Up:      BASE <-- 0x88  (volume up, no stereo detect,
+                               radio enable, tuner adjust disable)
+               * wait 10 msec *
+               BASE <-- 0xc8  (see "Default")
+
+Check Stereo:   BASE <-- 0xd8  (current volume, stereo detect,
+                               radio enable, tuner adjust disable)
+               * wait 100 msec *
+               x <-- BASE     (read ioport)
+               BASE <-- 0xc8  (see "Default")
+
+               x=0xff ==> "not stereo", x=0xfd ==> "stereo detected"
+
+Set Frequency:  code = (freq*40) + 10486188
+                foreach of the 24 bits in code,
+                (from Least to Most Significant):
+                  to write a "zero" bit,
+                    BASE <-- 0x01  (audio mute, no stereo detect, radio
+                                   disable, "zero" bit phase 1, tuner adjust)
+                    BASE <-- 0x03  (audio mute, no stereo detect, radio
+                                   disable, "zero" bit phase 2, tuner adjust)
+                  to write a "one" bit,
+                    BASE <-- 0x05  (audio mute, no stereo detect, radio
+                                   disable, "one" bit phase 1, tuner adjust)
+                    BASE <-- 0x07  (audio mute, no stereo detect, radio
+                                   disable, "one" bit phase 2, tuner adjust)
+
+----------------------------------------------------------------------------
index 9fbebebbd1c1eeda716df3184ddcf9a4199e36d8..dd0e825e1850d99d2d01c02005c48e1e36cdff9f 100644 (file)
@@ -47,6 +47,10 @@ trivial patch so apply some common sense.
 
 Maintainers List (try to look for most precise areas first)
 
+Note: For the hard of thinking, this list is meant to remain in Alphabetical
+order. If you could add yourselves to it in Alphabetical order that would
+so much easier [Ed]
+
 P: Person
 M: Mail patches to
 L: Mailing list that is relevant to this area
@@ -66,7 +70,7 @@ S: Status, one of the following:
 
 3C501 NETWORK DRIVER
 P:     Alan Cox
-M:     net-patches@lxorguk.ukuu.org.uk
+M:     alan@the.3c501.cabal.tm
 L:     linux-net@vger.rutgers.edu
 S:     Maintained
 
@@ -124,6 +128,19 @@ M: layes@loran.com
 L:     linux-net@vger.rutgers.edu
 S:     Maintained
 
+ARM MFM AND FLOPPY DRIVERS
+P:     Dave Gilbert
+M:     linux@treblig.org
+S:     Maintained
+
+ARM PORT
+P:     Russell King
+M:     linux@arm.uk.linux.org
+L:     linux-arm@vger.rutgers.edu
+L:     arm-linux@tardis.ed.ac.uk
+W:     http://www.arm.uk.linux.org/~rmk/armlinux.html
+S:     Maintained
+
 AX.25 NETWORK LAYER
 P:     Jon Naylor
 M:     jsn@cs.nott.ac.uk
@@ -365,7 +382,7 @@ P:  Alan Cox
 M:     Alan.Cox@linux.org
 W:     http://www.mac.linux-m68k.org/home.html
 L:     linux-mac68k@wave.lm.com
-S:     Maintained
+S:     As time permits [Michael confess, you are the mac68k maintainer 8)]
 
 MENUCONFIG:
 P:     Michael Elizabeth Chastain
@@ -548,8 +565,8 @@ S:  Maintained
 
 SOUND
 P:     Alan Cox 
-M:     Alan.Cox@linux.org
-S:     Maintained
+M:     alan@redhat.com
+S:     Supported
 
 SPARC:
 P:     Eddie C. Dost
@@ -641,6 +658,7 @@ S:  Maintained
 VIDEO FOR LINUX
 P:     Alan Cox
 M:     Alan.Cox@linux.org
+W:     http://roadrunner.swansea.linux.org.uk/v4l.shtml
 S:     Maintained
 
 WAN ROUTER AND SANGOMA WANPIPE DRIVERS (X.25, FRAME RELAY, PPP)
@@ -669,18 +687,6 @@ W: http://qsl.net/dl1bke/
 L:     linux-hams@vger.rutgers.edu
 S:     Maintained
 
-ARM PORT
-P:     Russell King
-M:     linux@arm.uk.linux.org
-L:     linux-arm@vger.rutgers.edu
-L:     arm-linux@tardis.ed.ac.uk
-W:     http://www.arm.uk.linux.org/~rmk/armlinux.html
-S:     Maintained
-
-ARM MFM AND FLOPPY DRIVERS
-P:     Dave Gilbert
-M:     linux@treblig.org
-S:     Maintained
 
 REST:
 P:     Linus Torvalds
index 1b52ea5b6c57a9038371f217e6a9e305fc425122..4fa20439d0467e434dfb52cc42b7f20d5687540e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 117
+SUBLEVEL = 118
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
@@ -125,7 +125,7 @@ ifeq ($(CONFIG_SCSI),y)
 DRIVERS := $(DRIVERS) drivers/scsi/scsi.a
 endif
 
-ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR),)
+ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
 DRIVERS := $(DRIVERS) drivers/cdrom/cdrom.a
 endif
 
index 1752ff2c033abe0aec32bb03884a13ae9fe15ea6..0aa1f455379c71b3fec83e4f3a7e7c58f052822e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * bios32.c - Low-Level PCI Access
  *
- * $Id: bios32.c,v 1.44 1998/08/04 14:54:56 mj Exp $
+ * $Id: bios32.c,v 1.45 1998/08/15 10:41:04 mj Exp $
  *
  * Copyright 1993, 1994 Drew Eckhardt
  *      Visionary Computing
@@ -945,7 +945,8 @@ __initfunc(void pcibios_fixup_ghosts(struct pci_bus *b))
 __initfunc(void pcibios_fixup_peer_bridges(void))
 {
        struct pci_bus *b = &pci_root;
-       int i;
+       int i, cnt=-1;
+       struct pci_dev *d;
 
 #ifdef CONFIG_PCI_DIRECT
        /*
@@ -956,23 +957,34 @@ __initfunc(void pcibios_fixup_peer_bridges(void))
        if (access_pci == &pci_direct_conf2)
                return;
 #endif
+       for(d=b->devices; d; d=d->sibling)
+               if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
+                       cnt++;
        do {
                int n = b->subordinate+1;
+               int found = 0;
                u16 l;
                for(i=0; i<256; i += 8)
                        if (!pcibios_read_config_word(n, i, PCI_VENDOR_ID, &l) &&
                            l != 0x0000 && l != 0xffff) {
                                DBG("Found device at %02x:%02x\n", n, i);
-                               printk("PCI: Discovered primary peer bus %02x\n", n);
-                               b = kmalloc(sizeof(*b), GFP_KERNEL);
-                               memset(b, 0, sizeof(*b));
-                               b->next = pci_root.next;
-                               pci_root.next = b;
-                               b->number = b->secondary = n;
-                               b->subordinate = 0xff;
-                               b->subordinate = pci_scan_bus(b);
-                               break;
+                               found++;
+                               if (!pcibios_read_config_word(n, i, PCI_CLASS_DEVICE, &l) &&
+                                   l == PCI_CLASS_BRIDGE_HOST)
+                                       cnt++;
                        }
+               if (found && cnt > 0) {
+                       cnt--;
+                       printk("PCI: Discovered primary peer bus %02x\n", n);
+                       b = kmalloc(sizeof(*b), GFP_KERNEL);
+                       memset(b, 0, sizeof(*b));
+                       b->next = pci_root.next;
+                       pci_root.next = b;
+                       b->number = b->secondary = n;
+                       b->subordinate = 0xff;
+                       b->subordinate = pci_scan_bus(b);
+                       break;
+               }
        } while (i < 256);
 }
 
@@ -1032,21 +1044,25 @@ __initfunc(void pcibios_fixup_devices(void))
 #ifdef __SMP__
                /*
                 * Recalculate IRQ numbers if we use the I/O APIC
+                *
+                * NOTE! If the "original" interrupt is marked as an old-fashioned
+                * irq, we have to keep it old-fashioned even if it's a PCI device
+                * and we could have found it in the MP-table transform.
                 */
-               {
-               int irq;
-               unsigned char pin;
-
-               pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-               if (pin) {
-                       pin--;          /* interrupt pins are numbered starting from 1 */
-                       irq = IO_APIC_get_PCI_irq_vector (dev->bus->number, PCI_SLOT(dev->devfn), pin);
-                       if (irq >= 0) {
-                               printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
-                                       dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
-                               dev->irq = irq;
-                               }
-               }
+               if (IO_APIC_IRQ(dev->irq)) {
+                       int irq;
+                       unsigned char pin;
+
+                       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+                       if (pin) {
+                               pin--;          /* interrupt pins are numbered starting from 1 */
+                               irq = IO_APIC_get_PCI_irq_vector (dev->bus->number, PCI_SLOT(dev->devfn), pin);
+                               if (irq >= 0) {
+                                       printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+                                               dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
+                                       dev->irq = irq;
+                                       }
+                       }
                }
 #endif
                /*
index ae67822bcfdc47bad940cc22b2b1491ff0e764ea..de6efd1e2ac550f447317c517a4ff731af3f0e3e 100644 (file)
@@ -68,7 +68,7 @@ static int mca_default_procfn( char* buf, int slot );
 static ssize_t proc_mca_read( struct file*, char*, size_t, loff_t *);
 static struct file_operations proc_mca_operations = {
        NULL, proc_mca_read,
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 static struct inode_operations proc_mca_inode_operations = {
        &proc_mca_operations,
index 02d5b61a0c32584d7b18d960dab06e157c95679d..f56bcdfa15047b9dc62fae5924677a8abc186a8d 100644 (file)
@@ -1086,6 +1086,7 @@ static struct file_operations mtrr_fops =
     mtrr_ioctl,  /*  IOctl             */
     NULL,        /*  MMAP              */
     mtrr_open,   /*  Open              */
+    NULL,        /*  Flush             */
     mtrr_close,  /*  Release           */
     NULL,        /*  Fsync             */
     NULL,        /*  Fasync            */
index 3bcd0f9bc7724200265a63db2451622309d7a0cc..731797f6b50dd6621e9f4bd0b120ee7f9566041b 100644 (file)
@@ -727,6 +727,13 @@ void __switch_to(struct task_struct *prev, struct task_struct *next)
        gdt_table[next->tss.tr >> 3].b &= 0xfffffdff;
        asm volatile("ltr %0": :"g" (*(unsigned short *)&next->tss.tr));
 
+       /*
+        * Save away %fs and %gs. No need to save %es and %ds, as
+        * those are always kernel segments while inside the kernel.
+        */
+       asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->tss.fs));
+       asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->tss.gs));
+
        /* Re-load LDT if necessary */
        if (next->mm->segments != prev->mm->segments)
                asm volatile("lldt %0": :"g" (*(unsigned short *)&next->tss.ldt));
@@ -736,13 +743,8 @@ void __switch_to(struct task_struct *prev, struct task_struct *next)
                asm volatile("movl %0,%%cr3": :"r" (next->tss.cr3));
 
        /*
-        * Save away %fs and %gs. No need to save %es and %ds, as
-        * those are always kernel segments while inside the kernel.
-        * Restore the new values.
+        * Restore %fs and %gs.
         */
-       asm volatile("movl %%fs,%0":"=m" (*(int *)&prev->tss.fs));
-       asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->tss.gs));
-
        loadsegment(fs,next->tss.fs);
        loadsegment(gs,next->tss.gs);
 
@@ -761,28 +763,19 @@ void __switch_to(struct task_struct *prev, struct task_struct *next)
 
 asmlinkage int sys_fork(struct pt_regs regs)
 {
-       int ret;
-
-       lock_kernel();
-       ret = do_fork(SIGCHLD, regs.esp, &regs);
-       unlock_kernel();
-       return ret;
+       return do_fork(SIGCHLD, regs.esp, &regs);
 }
 
 asmlinkage int sys_clone(struct pt_regs regs)
 {
        unsigned long clone_flags;
        unsigned long newsp;
-       int ret;
 
-       lock_kernel();
        clone_flags = regs.ebx;
        newsp = regs.ecx;
        if (!newsp)
                newsp = regs.esp;
-       ret = do_fork(clone_flags, newsp, &regs);
-       unlock_kernel();
-       return ret;
+       return do_fork(clone_flags, newsp, &regs);
 }
 
 /*
index 05e53287a6d98a3cca68302d10d5d76891803555..231356d909cd1caeb3d5ec32ca4f13e7e3804212 100644 (file)
@@ -184,26 +184,17 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *peax)
 
 #define COPY_SEG(seg)                                                  \
        { unsigned short tmp;                                           \
-          err |= __get_user(tmp, &sc->seg);                            \
-         if ((tmp & 0xfffc)            /* not a NULL selectors */      \
-             && (tmp & 0x4) != 0x4     /* not a LDT selector */        \
-             && (tmp & 3) != 3)        /* not a RPL3 GDT selector */   \
-                 goto badframe;                                        \
+         err |= __get_user(tmp, &sc->seg);                             \
          regs->x##seg = tmp; }
 
 #define COPY_SEG_STRICT(seg)                                           \
        { unsigned short tmp;                                           \
          err |= __get_user(tmp, &sc->seg);                             \
-         if ((tmp & 0xfffc) && (tmp & 3) != 3) goto badframe;          \
-         regs->x##seg = tmp; }
+         regs->x##seg = tmp|3; }
 
 #define GET_SEG(seg)                                                   \
        { unsigned short tmp;                                           \
          err |= __get_user(tmp, &sc->seg);                             \
-         if ((tmp & 0xfffc)            /* not a NULL selectors */      \
-             && (tmp & 0x4) != 0x4     /* not a LDT selector */        \
-             && (tmp & 3) != 3)        /* not a RPL3 GDT selector */   \
-                 goto badframe;                                        \
          loadsegment(seg,tmp); }
 
        GET_SEG(gs);
@@ -459,15 +450,12 @@ static void setup_frame(int sig, struct k_sigaction *ka,
        /* Set up registers for signal handler */
        regs->esp = (unsigned long) frame;
        regs->eip = (unsigned long) ka->sa.sa_handler;
-       {
-               unsigned long seg = __USER_DS;
-               __asm__("movl %w0,%%fs ; movl %w0,%%gs": "=r"(seg) : "0"(seg));
-               set_fs(USER_DS);
-               regs->xds = seg;
-               regs->xes = seg;
-               regs->xss = seg;
-               regs->xcs = __USER_CS;
-       }
+
+       set_fs(USER_DS);
+       regs->xds = __USER_DS;
+       regs->xes = __USER_DS;
+       regs->xss = __USER_DS;
+       regs->xcs = __USER_CS;
        regs->eflags &= ~TF_MASK;
 
 #if DEBUG_SIG
@@ -533,15 +521,12 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        /* Set up registers for signal handler */
        regs->esp = (unsigned long) frame;
        regs->eip = (unsigned long) ka->sa.sa_handler;
-       {
-               unsigned long seg = __USER_DS;
-               __asm__("movl %w0,%%fs ; movl %w0,%%gs": "=r"(seg) : "0"(seg));
-               set_fs(USER_DS);
-               regs->xds = seg;
-               regs->xes = seg;
-               regs->xss = seg;
-               regs->xcs = __USER_CS;
-       }
+
+       set_fs(USER_DS);
+       regs->xds = __USER_DS;
+       regs->xes = __USER_DS;
+       regs->xss = __USER_DS;
+       regs->xcs = __USER_CS;
        regs->eflags &= ~TF_MASK;
 
 #if DEBUG_SIG
index 6b313d99c3a9d64882779884046174e8a339cba4..d5b052c20f3cab7e460faeed2a1e7321ceb281be 100644 (file)
@@ -7,7 +7,7 @@
  */
 #include <asm/uaccess.h>
 
-inline unsigned long
+unsigned long
 __generic_copy_to_user(void *to, const void *from, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
@@ -15,11 +15,11 @@ __generic_copy_to_user(void *to, const void *from, unsigned long n)
        return n;
 }
 
-inline unsigned long
+unsigned long
 __generic_copy_from_user(void *to, const void *from, unsigned long n)
 {
        if (access_ok(VERIFY_READ, from, n))
-               __copy_user(to,from,n);
+               __copy_user_zeroing(to,from,n);
        return n;
 }
 
index b4cba8730475b2ea80d8602b62669ef7f5c2029f..b5febaf59c7fa0110aacec478f0ebef7a68cbcd0 100644 (file)
@@ -220,7 +220,7 @@ static unsigned long __init fixmap_init(unsigned long start_mem)
 
        for (idx=1; idx <= __end_of_fixed_addresses; idx += PTRS_PER_PTE)
        {
-               address = fix_to_virt(__end_of_fixed_addresses-idx);
+               address = __fix_to_virt(__end_of_fixed_addresses-idx);
                pg_dir = swapper_pg_dir + (address >> PGDIR_SHIFT);
                memset((void *)start_mem, 0, PAGE_SIZE);
                pgd_val(*pg_dir) = _PAGE_TABLE | __pa(start_mem);
@@ -246,8 +246,12 @@ static void set_pte_phys (unsigned long vaddr, unsigned long phys)
 
 void set_fixmap (enum fixed_addresses idx, unsigned long phys)
 {
-       unsigned long address = fix_to_virt(idx);
+       unsigned long address = __fix_to_virt(idx);
 
+       if (idx >= __end_of_fixed_addresses) {
+               printk("Invalid set_fixmap\n");
+               return;
+       }
        set_pte_phys (address,phys);
 }
 
index 02821ebaf8f61363e51bfa21bc85bb43515a74cb..d11011c5efee6bcf4384f321aee95ace511f03c8 100644 (file)
@@ -218,31 +218,31 @@ static unsigned stat_swap_force = 0;
 #ifdef CONFIG_STRAM_SWAP
 static int swap_init( unsigned long start_mem, unsigned long swap_data );
 static inline int unswap_pte( struct vm_area_struct * vma, unsigned long
-                              address, pte_t *dir, unsigned long entry,
-                              unsigned long page, int isswap );
+                             address, pte_t *dir, unsigned long entry,
+                             unsigned long page, int isswap );
 static inline int unswap_pmd( struct vm_area_struct * vma, pmd_t *dir,
-                              unsigned long address, unsigned long size,
-                              unsigned long offset, unsigned long entry,
-                              unsigned long page, int isswap );
+                             unsigned long address, unsigned long size,
+                             unsigned long offset, unsigned long entry,
+                             unsigned long page, int isswap );
 static inline int unswap_pgd( struct vm_area_struct * vma, pgd_t *dir,
-                              unsigned long address, unsigned long size,
-                              unsigned long entry, unsigned long page, int
-                              isswap );
+                             unsigned long address, unsigned long size,
+                             unsigned long entry, unsigned long page, int
+                             isswap );
 static int unswap_vma( struct vm_area_struct * vma, pgd_t *pgdir, unsigned
-                       long entry, unsigned long page, int isswap );
+                      long entry, unsigned long page, int isswap );
 static int unswap_process( struct mm_struct * mm, unsigned long entry,
-                           unsigned long page, int isswap );
+                          unsigned long page, int isswap );
 static int unswap_by_move( unsigned char *map, unsigned long max, unsigned
-                           long start, unsigned long n_pages );
+                          long start, unsigned long n_pages );
 static int unswap_by_read( unsigned char *map, unsigned long max, unsigned
-                           long start, unsigned long n_pages );
+                          long start, unsigned long n_pages );
 static void *get_stram_region( unsigned long n_pages );
 static void free_stram_region( unsigned long offset, unsigned long n_pages
-                               );
+                              );
 static int in_some_region( unsigned long addr );
 static unsigned long find_free_region( unsigned long n_pages, unsigned long
-                                       *total_free, unsigned long
-                                       *region_free );
+                                      *total_free, unsigned long
+                                      *region_free );
 static void do_stram_request( void );
 static int stram_open( struct inode *inode, struct file *filp );
 static int stram_release( struct inode *inode, struct file *filp );
@@ -1249,16 +1249,17 @@ static int stram_release( struct inode *inode, struct file *filp )
 
 
 static struct file_operations stram_fops = {
-        NULL,                   /* lseek - default */
-        block_read,             /* read - general block-dev read */
-        block_write,            /* write - general block-dev write */
-        NULL,                   /* readdir - bad */
-        NULL,                   /* select */
-        NULL,                   /* ioctl */
-        NULL,                   /* mmap */
-        stram_open,             /* open */
-        stram_release,          /* release */
-        block_fsync             /* fsync */
+       NULL,                   /* lseek - default */
+       block_read,             /* read - general block-dev read */
+       block_write,            /* write - general block-dev write */
+       NULL,                   /* readdir - bad */
+       NULL,                   /* select */
+       NULL,                   /* ioctl */
+       NULL,                   /* mmap */
+       stram_open,             /* open */
+       NULL,                   /* flush */
+       stram_release,          /* release */
+       block_fsync             /* fsync */
 };
 
 __initfunc(int stram_device_init(void))
@@ -1269,12 +1270,12 @@ __initfunc(int stram_device_init(void))
        return( -ENXIO );
 
     if (!max_swap_size)
-        /* swapping not enabled */
+       /* swapping not enabled */
        return( -ENXIO );
        
     if (register_blkdev( STRAM_MAJOR, "stram", &stram_fops)) {
-        printk( KERN_ERR "stram: Unable to get major %d\n", STRAM_MAJOR );
-        return( -ENXIO );
+       printk( KERN_ERR "stram: Unable to get major %d\n", STRAM_MAJOR );
+       return( -ENXIO );
     }
 
     blk_dev[STRAM_MAJOR].request_fn = do_stram_request;
index ca9f677f85eece035f343a228ac8b061d54580c7..cf05ab9aa71979c929fca4187f25ec54bfb77081 100644 (file)
@@ -153,6 +153,7 @@ static struct file_operations rtc_fops = {
        rtc_ioctl,
        NULL,           /* No mmap */
        rtc_open,
+       NULL,           /* flush */
        rtc_release
 };
 
index 0f41bc6aaba905ae502de1bdeaabd9583a215ed0..6421643148cc0b492adfcb29ec403e5513dc531a 100644 (file)
@@ -2504,6 +2504,7 @@ static struct file_operations adb_fops = {
        NULL,           /* no ioctl yet */
        NULL,           /* no mmap */
        adb_open,
+       NULL,           /* flush */
        adb_release
 };
 
@@ -2688,6 +2689,7 @@ static struct file_operations adb_fops = {
        NULL,           /* no ioctl */
        NULL,           /* no mmap */
        adb_open,
+       NULL,           /* flush */
        adb_release
 };
 
index 6b7c0c01145b7ca00aae38925e131d60263bef2a..b9485e54db3d2bfdf248bffcb21c6b34447d102a 100644 (file)
@@ -144,6 +144,7 @@ static struct file_operations rtc_fops = {
        rtc_ioctl,
        NULL,           /* No mmap */
        rtc_open,
+       NULL,           /* flush */
        rtc_release
 };
 
index 074e15a9dca0869eb9abe89fca6e2128a6f1e190..c1445d39369fb3212b265f356a77f82249e5fa12 100644 (file)
@@ -49,6 +49,7 @@ static struct file_operations ppc_htab_operations = {
     NULL,              /* ioctl   */
     NULL,              /* mmap    */
     NULL,              /* no special open code    */
+    NULL,              /* flush */
     NULL,              /* no special release code */
     NULL               /* can't fsync */
 };
index 523073a6d56c8be78dc7af4b4922217ef69a4e30..dce7927d863436e32af2354c50f1d58039526b67 100644 (file)
@@ -57,6 +57,7 @@ static struct file_operations socksys_file_ops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        NULL,           /* open */
+       NULL,           /* flush */
        NULL,           /* release */
 };
 
@@ -170,6 +171,7 @@ static struct file_operations socksys_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        socksys_open,   /* open */
+       NULL,           /* flush */
        socksys_release,/* release */
 };
 
index d661fcd4b9fb703c691e3f9550713e372be24555..f6b73e35f93ba4aa94eaea15116c0e26e1d082d1 100644 (file)
@@ -63,7 +63,7 @@ else
   endif
 endif
 
-ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR),)
+ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
 SUB_DIRS += cdrom
 MOD_SUB_DIRS += cdrom
 endif
index d9afbea9bb02e34f315e6905a2fb4cd5e15b22d1..a92320305539e4dec464c090960a754076fb5210 100644 (file)
@@ -1589,6 +1589,7 @@ static struct file_operations floppy_fops =
        fd_ioctl,               /* ioctl */
        NULL,                   /* mmap */
        floppy_open,            /* open */
+       NULL,                   /* flush */
        floppy_release,         /* release */
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
index 614d8403c2c07872b43044600e9aa44367ce1183..bec74c62ba220f1d115245b127756f1c41f4ecc0 100644 (file)
@@ -1372,6 +1372,7 @@ static struct file_operations mfm_fops =
        mfm_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        mfm_open,               /* open */
+       NULL,                   /* flush */
        mfm_release,            /* release */
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
index ae2071cf9124733387c731d22d47720afbe6e8aa..ce50c5edb31957d6fa3c8bd9048f4e9cf7633154 100644 (file)
@@ -48,12 +48,10 @@ static int ap_fds[NUM_APDEVS];
 
 static volatile int request_count = 0;
 
-#ifdef MODULE
 static void ap_release(struct inode * inode, struct file * filp)
 {
        MOD_DEC_USE_COUNT;
 }
-#endif
 
 static void ap_request(void)
 {
@@ -247,20 +245,17 @@ void ap_open_reply(struct cap_request *creq)
 } 
 
 static struct file_operations ap_fops = {
-        NULL,                   /* lseek - default */
-        block_read,             /* read - general block-dev read */
-        block_write,            /* write - general block-dev write */
-        NULL,                   /* readdir - bad */
-        NULL,                   /* poll */
-        ap_ioctl,               /* ioctl */
-        NULL,                   /* mmap */
-        ap_open,                /* open */
-#ifndef MODULE
-       NULL,           /* no special release code... */
-#else
-       ap_release,     /* module needs to decrement use count */
-#endif
-        block_fsync,            /* fsync */
+       NULL,                   /* lseek - default */
+       block_read,             /* read - general block-dev read */
+       block_write,            /* write - general block-dev write */
+       NULL,                   /* readdir - bad */
+       NULL,                   /* poll */
+       ap_ioctl,               /* ioctl */
+       NULL,                   /* mmap */
+       ap_open,                /* open */
+       NULL,                   /* flush */
+       ap_release,             /* module needs to decrement use count */
+       block_fsync,            /* fsync */
 };
 
 
index 2e7f492a54bfac3e3930e2afd83a68f26638c970..4a21a588212e46ac681be5bbe7d402d0a0e06c1a 100644 (file)
@@ -884,6 +884,7 @@ static struct file_operations ddv_fops = {
         ddv_ioctl,               /* ioctl */
         NULL,                   /* mmap */
         ddv_open,                /* open */
+       NULL,                   /* flush */
        ddv_release,
         block_fsync          /* fsync */
 };
index 905b8f0693ad75ff5ffb43ab0174f1bb70e912cf..d8f9b02c3a3fb9f8d9f7cab3e777ba8c5b6aed08 100644 (file)
@@ -302,6 +302,7 @@ static struct file_operations proc_ringbuf_operations = {
        ringbuf_ioctl,  /* ioctl */
        NULL,           /* mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
 };
index f3543db2ed3c0dc3b1bbb1f1d36ce0bf237cbc02..eff9baf4318554fd64fb3f7551c96b05c7f42692 100644 (file)
@@ -269,10 +269,10 @@ endif
 
 ifeq ($(CONFIG_PARIDE),y)
 SUB_DIRS       += paride
-MOD_SUB_DIRS   += paride
+MOD_IN_SUB_DIRS        += paride
 else
   ifeq ($(CONFIG_PARIDE),m)
-  MOD_SUB_DIRS += paride
+  MOD_IN_SUB_DIRS      += paride
   endif
 endif
 
index 3594eb189f21b503de00c70c9365a8551ece5011..f49f186a8a849e4b2bef716c00183fba27552f9c 100644 (file)
@@ -1788,7 +1788,8 @@ static struct file_operations acsi_fops = {
        acsi_ioctl,             /* ioctl */
        NULL,                   /* mmap */
        acsi_open,              /* open */
-       acsi_release,   /* release */
+       NULL,                   /* flush */
+       acsi_release,           /* release */
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
        acsi_media_change,      /* media_change */
index 4b301cb2a034f71e6ecee5f67ebbc368c7d987dd..66121340f1bf107753ff5f074ab48d2f18e8e465 100644 (file)
@@ -288,7 +288,8 @@ static struct file_operations slm_fops = {
        slm_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        slm_open,               /* open */
-       slm_release,    /* release */
+       NULL,                   /* flush */
+       slm_release,            /* release */
        NULL                    /* fsync */
 };
 
index afee4899e7598cd9803180a0b38771457ce7165e..a7631741e0f15924ae366f2630e08929cab03a5b 100644 (file)
@@ -1747,6 +1747,7 @@ static struct file_operations floppy_fops = {
        fd_ioctl,               /* ioctl */
        NULL,                   /* mmap */
        floppy_open,            /* open */
+       NULL,                   /* flush */
        floppy_release,         /* release */
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
index 640ddfd3ad9b805502ca9c40225ca9f871a24127..5c55700a7cd877e51044bec7285a4092f17f517d 100644 (file)
@@ -2008,6 +2008,7 @@ static struct file_operations floppy_fops = {
        fd_ioctl,               /* ioctl */
        NULL,                   /* mmap */
        floppy_open,            /* open */
+       NULL,                   /* flush */
        floppy_release,         /* release */
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
index 9fb5c8e7e57ba82b8915700bfa9a7665cf23b921..b8ef979224bd8263ea5542708deb50110cb93c4a 100644 (file)
@@ -3836,6 +3836,7 @@ static struct file_operations floppy_fops = {
        fd_ioctl,               /* ioctl */
        NULL,                   /* mmap */
        floppy_open,            /* open */
+       NULL,                   /* flush */
        floppy_release,         /* release */
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
index e739090f12aac5f1f01d0ba2b28fa0df6a9c3f41..0246d15bf9aa34d3d857b96477649289a092b84f 100644 (file)
@@ -411,29 +411,23 @@ check_table:
                } else {
                        /*
                         * Examine the partition table for common translations.
-                        * This is necessary for drives for situations where
-                        * the translated geometry is unavailable from the BIOS.
+                        * This is useful for drives in situations where the
+                        * translated geometry is unavailable from the BIOS.
                         */
-                       int     xlate_done = 0;
-                       for (i = 0; i < 4 && !xlate_done; i++) {
+                       for (i = 0; i < 4; i++) {
                                struct partition *q = &p[i];
                                if (NR_SECTS(q)
                                   && (q->sector & 63) == 1
                                   && (q->end_sector & 63) == 63) {
                                        unsigned int heads = q->end_head + 1;
-                                       if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {
-
+                                       if (heads == 32 || heads == 64 ||
+                                           heads == 128 || heads == 255 ||
+                                           heads == 240) {
                                                (void) ide_xlate_1024(dev, heads, " [PTBL]");
-                                               xlate_done = 1;
+                                               break;
                                        }
                                }
                        }
-                       if (!xlate_done) {
-                               /*
-                                * Default translation is equivalent of "BIOS LBA":
-                                */
-                               ide_xlate_1024(dev, -2, " [LBA]");
-                       }
                }
        }
 #endif /* CONFIG_BLK_DEV_IDE */
index 01a4e18e4b534edc4e070adaf314a3a192e69f36..07463389a1eb6362ff2860decd003e177c022c31 100644 (file)
@@ -2869,6 +2869,7 @@ struct file_operations ide_fops[] = {{
        ide_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        ide_open,               /* open */
+       NULL,                   /* flush */
        ide_release,            /* release */
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
index 268c9187aa3e23365569092383f1ef053a3dded4..5a936899fd1d9fc023b31ad14563539f2541954d 100644 (file)
@@ -670,6 +670,7 @@ static struct file_operations lo_fops = {
        lo_ioctl,               /* ioctl */
        NULL,                   /* mmap */
        lo_open,                /* open */
+       NULL,                   /* flush */
        lo_release              /* release */
 };
 
index d0eae5a2999b0a68e7ac403e8576eca135a57209..b6cf3d34e26ec951b57233929003b13aa59a27f4 100644 (file)
@@ -754,6 +754,7 @@ static struct file_operations md_fops=
   md_ioctl,
   NULL,
   md_open,
+  NULL,
   md_release,
   block_fsync
 };
index ddec2b425572526b80667681b27b2dfdad2df02e..94464709615c4139ae70da46d304b39767a853a3 100644 (file)
@@ -415,6 +415,7 @@ static struct file_operations nbd_fops =
        nbd_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        nbd_open,               /* open */
+       NULL,                   /* flush */
        nbd_release             /* release */
 };
 
index abb45d2fc84c0d897c8907f4be95f53b0342667b..ae2d54dd9f56bcf1e90bb0b24ad6251bb63e2273 100644 (file)
@@ -12,6 +12,7 @@ SUB_DIRS     :=
 MOD_SUB_DIRS := $(SUB_DIRS)
 ALL_SUB_DIRS := $(SUB_DIRS)
 
+MOD_LIST_NAME := PARIDE_MODULES
 L_TARGET := paride.a
 MX_OBJS  :=
 LX_OBJS  := 
@@ -30,7 +31,7 @@ ifeq ($(CONFIG_PARIDE_PD),y)
   LX_OBJS += pd.o
 else
   ifeq ($(CONFIG_PARIDE_PD),m)
-    MX_OBJS += pd.o
+    M_OBJS += pd.o
   endif
 endif
 
@@ -38,7 +39,7 @@ ifeq ($(CONFIG_PARIDE_PCD),y)
   LX_OBJS += pcd.o
 else
   ifeq ($(CONFIG_PARIDE_PCD),m)
-    MX_OBJS += pcd.o
+    M_OBJS += pcd.o
   endif
 endif
 
@@ -46,7 +47,7 @@ ifeq ($(CONFIG_PARIDE_PF),y)
   LX_OBJS += pf.o
 else
   ifeq ($(CONFIG_PARIDE_PF),m)
-    MX_OBJS += pf.o
+    M_OBJS += pf.o
   endif
 endif
 
@@ -54,7 +55,7 @@ ifeq ($(CONFIG_PARIDE_PT),y)
   LX_OBJS += pt.o
 else
   ifeq ($(CONFIG_PARIDE_PT),m)
-    MX_OBJS += pt.o
+    M_OBJS += pt.o
   endif
 endif
 
@@ -62,7 +63,7 @@ ifeq ($(CONFIG_PARIDE_PG),y)
   LX_OBJS += pg.o
 else
   ifeq ($(CONFIG_PARIDE_PG),m)
-    MX_OBJS += pg.o
+    M_OBJS += pg.o
   endif
 endif
 
@@ -70,7 +71,7 @@ ifeq ($(CONFIG_PARIDE_ATEN),y)
   LX_OBJS += aten.o
 else
   ifeq ($(CONFIG_PARIDE_ATEN),m)
-    MX_OBJS += aten.o
+    M_OBJS += aten.o
   endif
 endif
 
@@ -78,7 +79,7 @@ ifeq ($(CONFIG_PARIDE_BPCK),y)
   LX_OBJS += bpck.o
 else
   ifeq ($(CONFIG_PARIDE_BPCK),m)
-    MX_OBJS += bpck.o
+    M_OBJS += bpck.o
   endif
 endif
 
@@ -86,7 +87,7 @@ ifeq ($(CONFIG_PARIDE_COMM),y)
   LX_OBJS += comm.o
 else
   ifeq ($(CONFIG_PARIDE_COMM),m)
-    MX_OBJS += comm.o
+    M_OBJS += comm.o
   endif
 endif
 
@@ -94,7 +95,7 @@ ifeq ($(CONFIG_PARIDE_DSTR),y)
   LX_OBJS += dstr.o
 else
   ifeq ($(CONFIG_PARIDE_DSTR),m)
-    MX_OBJS += dstr.o
+    M_OBJS += dstr.o
   endif
 endif
 
@@ -102,7 +103,7 @@ ifeq ($(CONFIG_PARIDE_KBIC),y)
   LX_OBJS += kbic.o
 else
   ifeq ($(CONFIG_PARIDE_KBIC),m)
-    MX_OBJS += kbic.o
+    M_OBJS += kbic.o
   endif
 endif
 
@@ -110,7 +111,7 @@ ifeq ($(CONFIG_PARIDE_EPAT),y)
   LX_OBJS += epat.o
 else
   ifeq ($(CONFIG_PARIDE_EPAT),m)
-    MX_OBJS += epat.o
+    M_OBJS += epat.o
   endif
 endif
 
@@ -118,7 +119,7 @@ ifeq ($(CONFIG_PARIDE_EPIA),y)
   LX_OBJS += epia.o
 else
   ifeq ($(CONFIG_PARIDE_EPIA),m)
-    MX_OBJS += epia.o
+    M_OBJS += epia.o
   endif
 endif
 
@@ -126,7 +127,7 @@ ifeq ($(CONFIG_PARIDE_FIT2),y)
   LX_OBJS += fit2.o
 else
   ifeq ($(CONFIG_PARIDE_FIT2),m)
-    MX_OBJS += fit2.o
+    M_OBJS += fit2.o
   endif
 endif
 
@@ -134,7 +135,7 @@ ifeq ($(CONFIG_PARIDE_FIT3),y)
   LX_OBJS += fit3.o
 else
   ifeq ($(CONFIG_PARIDE_FIT3),m)
-    MX_OBJS += fit3.o
+    M_OBJS += fit3.o
   endif
 endif
 
@@ -142,7 +143,7 @@ ifeq ($(CONFIG_PARIDE_FRPW),y)
   LX_OBJS += frpw.o
 else
   ifeq ($(CONFIG_PARIDE_FRPW),m)
-    MX_OBJS += frpw.o
+    M_OBJS += frpw.o
   endif
 endif
 
@@ -150,7 +151,7 @@ ifeq ($(CONFIG_PARIDE_ON20),y)
   LX_OBJS += on20.o
 else
   ifeq ($(CONFIG_PARIDE_ON20),m)
-    MX_OBJS += on20.o
+    M_OBJS += on20.o
   endif
 endif
 
@@ -158,7 +159,7 @@ ifeq ($(CONFIG_PARIDE_ON26),y)
   LX_OBJS += on26.o
 else
   ifeq ($(CONFIG_PARIDE_ON26),m)
-    MX_OBJS += on26.o
+    M_OBJS += on26.o
   endif
 endif
 
@@ -166,7 +167,7 @@ ifeq ($(CONFIG_PARIDE_KTTI),y)
   LX_OBJS += ktti.o
 else
   ifeq ($(CONFIG_PARIDE_KTTI),m)
-    MX_OBJS += ktti.o
+    M_OBJS += ktti.o
   endif
 endif
 
index 4b241c737c71c18dc649c2c0e5f70675e963b546..05e2de2da8f0e7819790ba03109939b212ff978d 100644 (file)
 /* Changes:
 
        1.01    GRG 1998.05.05 init_proto, release_proto, pi->delay 
+       1.02    GRG 1998.08.15 default pi->delay returned to 4
 
 */
 
-#define        BPCK_VERSION    "1.01
+#define        BPCK_VERSION    "1.02
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -450,7 +451,7 @@ static void bpck_release_proto( PIA *pi)
 {       MOD_DEC_USE_COUNT;
 }
 
-struct pi_protocol bpck = { "bpck",0,5,2,1,256,
+struct pi_protocol bpck = { "bpck",0,5,2,4,256,
                          bpck_write_regr,
                          bpck_read_regr,
                          bpck_write_block,
index 805b69e19785da5d1fab1ea21b145d99b37b31cc..068deffd6edf3fa979d33cf0d4eb3abc9cda49bc 100644 (file)
 
        1.01    GRG 1998.05.03  Use spinlocks
        1.02    GRG 1998.05.05  init_proto, release_proto, ktti
+       1.03    GRG 1998.08.15  eliminate compiler warning
 
 */
 
-#define PI_VERSION      "1.02"
+#define PI_VERSION      "1.03"
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -249,7 +250,7 @@ static void pi_register_parport( PIA *pi, int verbose)
 
        if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port,pp->name);
        
-       pi->parname = pp->name;
+       pi->parname = (char *)pp->name;
 
 #endif
 }
index ecacacb3b12474171090a1b4dd87c58ea72ad1b7..4a083abbfcb14c69bc75efd88105726d3739f668 100644 (file)
@@ -2,11 +2,11 @@
        pcd.c   (c) 1997-8  Grant R. Guenther <grant@torque.net>
                            Under the terms of the GNU public license.
 
-       This is a high-level driver for parallel port ATAPI CDROM
+       This is a high-level driver for parallel port ATAPI CD-ROM
         drives based on chips supported by the paride module.
 
         By default, the driver will autoprobe for a single parallel
-        port ATAPI CDROM drive, but if their individual parameters are
+        port ATAPI CD-ROM drive, but if their individual parameters are
         specified, the driver can handle up to 4 drives.
 
         The behaviour of the pcd driver can be altered by setting
@@ -38,7 +38,7 @@
                         of the mode numbers supported by the adapter.
                         (-1 if not given)
 
-               <slv>   ATAPI CDROMs can be jumpered to master or slave.
+               <slv>   ATAPI CD-ROMs can be jumpered to master or slave.
                        Set this to 0 to choose the master drive, 1 to
                         choose the slave, -1 (the default) to choose the
                        first drive found.
                         (default "pcd")
 
             verbose     This parameter controls the amount of logging
-                        that is done while the driver probes for
-                        devices.  Set it to 0 for a quiet load, or 1 to
-                        see all the progress messages.  (default 0)
-
+                        that the driver will do.  Set it to 0 for
+                        normal operation, 1 to see autoprobe progress
+                        messages, or 2 to see additional debugging
+                        output.  (default 0)
+  
             nice        This parameter controls the driver's use of
                         idle CPU time, at the expense of some speed.
  
 
 /* Changes:
 
-       1.01    GRG 1997.01.24  Added test unit ready support
+       1.01    GRG 1998.01.24  Added test unit ready support
        1.02    GRG 1998.05.06  Changes to pcd_completion, ready_wait,
                                and loosen interpretation of ATAPI
                                standard for clearing error status.
                                Use spinlocks. Eliminate sti().
        1.03    GRG 1998.06.16  Eliminated an Ugh
+       1.04    GRG 1998.08.15  Added extra debugging, improvements to
+                               pcd_completion, use HZ in loop timing
+       1.05    GRG 1998.08.16  Conformed to "Uniform CD-ROM" standard
+       1.06    GRG 1998.08.19  Added audio ioctl support
 
 */
 
-#define        PCD_VERSION     "1.03"
+#define        PCD_VERSION     "1.06"
 #define PCD_MAJOR      46
 #define PCD_NAME       "pcd"
 #define PCD_UNITS      4
@@ -185,9 +190,10 @@ MODULE_PARM(drive3,"1-6i");
 #define PCD_RETRIES         5
 #define PCD_TMO                   800          /* timeout in jiffies */
 #define PCD_DELAY           50          /* spin delay in uS */
-#define PCD_READY_TMO      20
+#define PCD_READY_TMO      20          /* in seconds */
+#define PCD_RESET_TMO      30          /* in tenths of a second */
 
-#define PCD_SPIN               (10000/PCD_DELAY)*PCD_TMO
+#define PCD_SPIN       (1000000*PCD_TMO)/(HZ*PCD_DELAY)
 
 #define IDE_ERR                0x01
 #define IDE_DRQ         0x08
@@ -197,33 +203,33 @@ MODULE_PARM(drive3,"1-6i");
 int pcd_init(void);
 void cleanup_module( void );
 
-static int     pcd_open(struct inode *inode, struct file *file);
-static void    do_pcd_request(void);
-static void    do_pcd_read(void);
-static int     pcd_ioctl(struct inode *inode,struct file *file,
-                         unsigned int cmd, unsigned long arg);
-
-static int pcd_release (struct inode *inode, struct file *file);
+static int pcd_open(struct cdrom_device_info *cdi, int purpose);
+static void pcd_release(struct cdrom_device_info *cdi);
+static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
+static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr);
+static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
+static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
+static int pcd_drive_reset(struct cdrom_device_info *cdi);
+static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
+static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
+                               unsigned int cmd, void *arg);
 
 static int     pcd_detect(void);
-static void     pcd_lock(int unit);
-static void     pcd_unlock(int unit);
-static void     pcd_eject(int unit);
-static int      pcd_check_media(int unit);
 static void     do_pcd_read_drq(void);
+static void    do_pcd_request(void);
+static void    do_pcd_read(void);
 
 static int pcd_blocksizes[PCD_UNITS];
 
-#define PCD_NAMELEN    8
-
 struct pcd_unit {
-       struct pi_adapter pia;  /* interface to paride layer */
+       struct pi_adapter pia;          /* interface to paride layer */
        struct pi_adapter *pi;
-       int drive;              /* master/slave */
-       int last_sense;         /* result of last request sense */
-       int access;             /* count of active opens */
-       int present;            /* does this unit exist ? */
-       char name[PCD_NAMELEN]; /* pcd0, pcd1, etc */
+       int drive;                      /* master/slave */
+       int last_sense;                 /* result of last request sense */
+       int changed;                    /* media change seen */
+       int present;                    /* does this unit exist ? */
+       char *name;                     /* pcd0, pcd1, etc */
+       struct cdrom_device_info info;  /* uniform cdrom interface */
        };
 
 struct pcd_unit pcd[PCD_UNITS];
@@ -251,22 +257,32 @@ static int pcd_sector;                    /* address of next requested sector */
 static int pcd_count;                  /* number of blocks still to do */
 static char * pcd_buf;                 /* buffer for request in progress */
 
+static int pcd_warned = 0;             /* Have we logged a phase warning ? */
+
 /* kernel glue structures */
 
-static struct file_operations pcd_fops = {
-       NULL,                   /* lseek - default */
-       block_read,             /* read - general block-dev read */
-       block_write,            /* write - general block-dev write */
-       NULL,                   /* readdir - bad */
-       NULL,                   /* select */
-       pcd_ioctl,              /* ioctl */
-       NULL,                   /* mmap */
-       pcd_open,               /* open */
-       pcd_release,            /* release */
-       block_fsync,            /* fsync */
-       NULL,                   /* fasync */
-       NULL,                   /* media change ? */
-       NULL                    /* revalidate new media */
+static struct cdrom_device_ops pcd_dops = {
+       pcd_open,
+       pcd_release,
+       pcd_drive_status,
+       pcd_media_changed,
+       pcd_tray_move,
+       pcd_lock_door,
+       0,                      /* select speed */
+       0,                      /* select disk  */
+       0,                      /* get last session */
+       pcd_get_mcn,
+       pcd_drive_reset,
+       pcd_audio_ioctl,
+       0,                      /* dev_ioctl */
+       CDC_CLOSE_TRAY    |
+       CDC_OPEN_TRAY     |
+       CDC_LOCK          |
+       CDC_MCN           |
+       CDC_MEDIA_CHANGED |
+       CDC_RESET         |
+       CDC_PLAY_AUDIO,
+       0
 };
 
 static void pcd_init_units( void )
@@ -276,21 +292,31 @@ static void pcd_init_units( void )
         pcd_drive_count = 0;
         for (unit=0;unit<PCD_UNITS;unit++) {
                 PCD.pi = & PCD.pia;
-                PCD.access = 0;
                 PCD.present = 0;
                PCD.last_sense = 0;
-                j = 0;
-                while ((j < PCD_NAMELEN-2) && (PCD.name[j]=name[j])) j++;
-                PCD.name[j++] = '0' + unit;
-                PCD.name[j] = 0;
+               PCD.changed = 1;
                 PCD.drive = DU[D_SLV];
                 if (DU[D_PRT]) pcd_drive_count++;
+                j = 0;
+                while ((j < (sizeof(PCD.info.name)-2)) && 
+                      (PCD.info.name[j]=name[j])) j++;
+                PCD.info.name[j++] = '0' + unit;
+                PCD.info.name[j] = 0;
+               PCD.name = &PCD.info.name[0];
+
+               PCD.info.ops = &pcd_dops;
+               PCD.info.handle = NULL;
+               PCD.info.dev = MKDEV(major,unit);
+               PCD.info.speed = 0;
+               PCD.info.capacity = 1;
+               PCD.info.mask = 0;
         }
 }
 
 int pcd_init (void)    /* preliminary initialisation */
 
-{       int    i;
+{       int    i, unit;
 
        if (disable) return -1;
 
@@ -298,10 +324,14 @@ int pcd_init (void)       /* preliminary initialisation */
 
        if (pcd_detect()) return -1;
 
-       if (register_blkdev(MAJOR_NR,name,&pcd_fops)) {
+       if (register_blkdev(MAJOR_NR,name,&cdrom_fops)) {
                printk("pcd: unable to get major number %d\n",MAJOR_NR);
                return -1;
        }
+
+       for (unit=0;unit<PCD_UNITS;unit++)
+               if (PCD.present) register_cdrom(&PCD.info);
+
        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
 
@@ -311,100 +341,20 @@ int pcd_init (void)      /* preliminary initialisation */
        return 0;
 }
 
-static int pcd_open (struct inode *inode, struct file *file)
+static int pcd_open(struct cdrom_device_info *cdi, int purpose)
 
-{      int unit = DEVICE_NR(inode->i_rdev);
+{      int unit = DEVICE_NR(cdi->dev);
 
        if  ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
 
-       if (file->f_mode & 2) return -EROFS;  /* wants to write ? */
-
        MOD_INC_USE_COUNT;
 
-       if (pcd_check_media(unit)) {
-               MOD_DEC_USE_COUNT;
-               return -ENXIO;
-       }
-
-       pcd_lock(unit);
-
-       PCD.access++;
        return 0;
 }
 
-static void do_pcd_request (void)
-
-{       int unit;
-
-       if (pcd_busy) return;
-        while (1) {
-           if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
-           INIT_REQUEST;
-           if (CURRENT->cmd == READ) {
-               unit = MINOR(CURRENT->rq_dev);
-               if (unit != pcd_unit) {
-                       pcd_bufblk = -1;
-                       pcd_unit = unit;
-               }
-               pcd_sector = CURRENT->sector;
-               pcd_count = CURRENT->nr_sectors;
-               pcd_buf = CURRENT->buffer;
-               pcd_busy = 1;
-               ps_set_intr(do_pcd_read,0,0,nice); 
-               return;
-           } 
-           else end_request(0);
-       }
-}
-
-static int pcd_ioctl(struct inode *inode,struct file *file,
-                   unsigned int cmd, unsigned long arg)
-
-/* we currently support only the EJECT ioctl. */
-
-{      int unit = DEVICE_NR(inode->i_rdev);
-       if  ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
-
-       switch (cmd) {
-            case CDROMEJECT: if (PCD.access == 1) {
-                               pcd_eject(unit);
-                               return 0;
-                            }
-           default:
-               return -EINVAL;
-       }
-}
-
-static int pcd_release (struct inode *inode, struct file *file)
-
-{      kdev_t  devp;
-       int     unit;
-
-        struct super_block *sb;
-
-       devp = inode->i_rdev;
-       unit = DEVICE_NR(devp);
-
-       if  ((unit >= PCD_UNITS) || (PCD.access <= 0)) 
-                       return -EINVAL;
-       
-       PCD.access--;
-
-       if (!PCD.access) { 
-               fsync_dev(devp);
-
-                sb = get_super(devp);
-                if (sb) invalidate_inodes(sb);
-
-               invalidate_buffers(devp);
-               pcd_unlock(unit);
-
-       }
-
-       MOD_DEC_USE_COUNT;
-
-        return 0;
+static void pcd_release(struct cdrom_device_info *cdi)
 
+{      MOD_DEC_USE_COUNT;
 }
 
 #ifdef MODULE
@@ -423,11 +373,14 @@ int       init_module(void)
 void   cleanup_module(void)
 
 {      int unit;
-
-       unregister_blkdev(MAJOR_NR,name);
        
         for (unit=0;unit<PCD_UNITS;unit++) 
-           if (PCD.present) pi_release(PI);
+           if (PCD.present) {
+               pi_release(PI);
+               unregister_cdrom(&PCD.info);
+          }
+
+       unregister_blkdev(MAJOR_NR,name);
 }
 
 #endif
@@ -489,39 +442,68 @@ static int pcd_command( int unit, char * cmd, int dlen, char * fun )
 
 static int pcd_completion( int unit, char * buf,  char * fun )
 
-{      int r, s, n;
-
-       r = pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,fun,"completion");
-
-       if ((RR(0,2)&2) && (RR(0,7)&IDE_DRQ)) { 
-               n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
-               pi_read_block(PI,buf,n);
+{      int r, d, p, n, k, j;
+
+       r = -1; k = 0; j = 0;
+
+       if (!pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
+                                               fun,"completion")) {
+           r = 0;
+           while (RR(0,7)&IDE_DRQ) {
+               d = (RR(0,4)+256*RR(0,5));
+               n = ((d+3)&0xfffc);
+               p = RR(0,2)&3;
+
+               if ((p == 2) && (n > 0) && (j == 0)) {
+                   pi_read_block(PI,buf,n);
+                   if (verbose > 1) 
+                       printk("%s: %s: Read %d bytes\n",PCD.name,fun,n);
+                   r = 0; j++;
+               } else {
+                   if (verbose > 1) 
+                       printk("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
+                                       PCD.name,fun,p,d,k);
+                   if ((verbose < 2) && !pcd_warned) {
+                       pcd_warned = 1;
+                       printk("%s: WARNING: ATAPI phase errors\n",PCD.name);
+                       }
+                   mdelay(1);
+               } 
+               if (k++ > PCD_TMO) {
+                       printk("%s: Stuck DRQ\n",PCD.name);
+                       break;
+               }
+               if (pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
+                               fun,"completion")) { 
+                       r = -1;
+                       break;
+               }
+           }
        }
-
-       s = pcd_wait(unit,IDE_BUSY,IDE_READY|IDE_ERR,fun,"data done");
-
+       
        pi_disconnect(PI); 
 
-       return (r?r:s);
+       return r;
 }
 
-static void pcd_req_sense( int unit, int quiet )
+static void pcd_req_sense( int unit, char *fun )
 
 {      char    rs_cmd[12] = { 0x03,0,0,0,16,0,0,0,0,0,0,0 };
        char    buf[16];
-       int     r;
+       int     r, c;
 
        r = pcd_command(unit,rs_cmd,16,"Request sense");
        mdelay(1);
        if (!r) pcd_completion(unit,buf,"Request sense");
 
-       PCD.last_sense = -1;
+       PCD.last_sense = -1;  c = 2;
        if (!r) {
-            if (!quiet) printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
-                              PCD.name,buf[2]&0xf,buf[12],buf[13]);
-           PCD.last_sense = (buf[2]&0xf) | ((buf[12]&0xff)<<8)
-                                          | ((buf[13]&0xff)<<16) ;
+            if (fun) printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
+                              PCD.name,fun,buf[2]&0xf,buf[12],buf[13]);
+           c = buf[2]&0xf;
+           PCD.last_sense = c | ((buf[12]&0xff)<<8) | ((buf[13]&0xff)<<16);
         } 
+       if ((c == 2) || (c == 6)) PCD.changed = 1;
 }
 
 static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
@@ -531,45 +513,42 @@ static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
        r = pcd_command(unit,cmd,dlen,fun);
        mdelay(1);
        if (!r) r = pcd_completion(unit,buf,fun);
-       if (r) pcd_req_sense(unit,!fun);
+       if (r) pcd_req_sense(unit,fun);
        
        return r;
 }
 
-#define DBMSG(msg)     NULL
+#define DBMSG(msg)     ((verbose>1)?(msg):NULL)
 
-static void pcd_lock(int unit)
+static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
 
-{      char    lo_cmd[12] = { 0x1e,0,0,0,1,0,0,0,0,0,0,0 };
-       char    cl_cmd[12] = { 0x1b,0,0,0,3,0,0,0,0,0,0,0 };
+{      int     r;
+       int     unit = DEVICE_NR(cdi->dev);
 
-       pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd1")); 
-       pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd2"));
-       pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd3"));
-       pcd_atapi(unit,cl_cmd,0,pcd_scratch,DBMSG("cd4"));
-       pcd_atapi(unit,cl_cmd,0,pcd_scratch,"close door");
+       r = PCD.changed;
+       PCD.changed = 0;
 
-        pcd_atapi(unit,lo_cmd,0,pcd_scratch,DBMSG("ld"));
-        pcd_atapi(unit,lo_cmd,0,pcd_scratch,"lock door");
+       return r;    
 }
 
-static void pcd_unlock( int unit )
+static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
 
-{      char    un_cmd[12] = { 0x1e,0,0,0,0,0,0,0,0,0,0,0 };
+{      char    un_cmd[12] = { 0x1e,0,0,0,lock,0,0,0,0,0,0,0 };
+        int     unit = DEVICE_NR(cdi->dev);
 
-       pcd_atapi(unit,un_cmd,0,pcd_scratch,"unlock door");
+       return pcd_atapi(unit,un_cmd,0,pcd_scratch,
+                               lock?"lock door":"unlock door");
 }
 
-static void pcd_eject( int unit)
+static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
 
-{      char    ej_cmd[12] = { 0x1b,0,0,0,2,0,0,0,0,0,0,0 };
+{      char    ej_cmd[12] = { 0x1b,0,0,0,3-position,0,0,0,0,0,0,0 };
+       int     unit = DEVICE_NR(cdi->dev);
 
-       pcd_unlock(unit);
-       pcd_atapi(unit,ej_cmd,0,pcd_scratch,"eject");
+       return pcd_atapi(unit,ej_cmd,0,pcd_scratch,
+                               position?"eject":"close tray");
 }
 
-#define PCD_RESET_TMO  30              /* in tenths of a second */
-
 static void pcd_sleep( int cs )
 
 {       current->state = TASK_INTERRUPTIBLE;
@@ -579,11 +558,6 @@ static void pcd_sleep( int cs )
 
 static int pcd_reset( int unit )
 
-/* the ATAPI standard actually specifies the contents of all 7 registers
-   after a reset, but the specification is ambiguous concerning the last
-   two bytes, and different drives interpret the standard differently.
-*/
-
 {      int     i, k, flg;
        int     expect[5] = {1,1,1,0x14,0xeb};
 
@@ -591,11 +565,11 @@ static int pcd_reset( int unit )
        WR(0,6,0xa0 + 0x10*PCD.drive);
        WR(0,7,8);
 
-       pcd_sleep(2);           /* delay a bit*/
+       pcd_sleep(2);           /* delay a bit */
 
        k = 0;
        while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
-               pcd_sleep(10);
+               pcd_sleep(HZ/10);
 
        flg = 1;
        for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
@@ -611,6 +585,11 @@ static int pcd_reset( int unit )
        return flg-1;   
 }
 
+static int pcd_drive_reset(struct cdrom_device_info *cdi)
+
+{      return pcd_reset(DEVICE_NR(cdi->dev));
+}
+
 static int pcd_ready_wait( int unit, int tmo )
 
 {       char    tr_cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
@@ -629,12 +608,16 @@ static int pcd_ready_wait( int unit, int tmo )
         return 0x000020;        /* timeout */
 }
 
-static int pcd_check_media( int unit )
+static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 
 {      char    rc_cmd[12] = { 0x25,0,0,0,0,0,0,0,0,0,0,0};
+       int     unit = DEVICE_NR(cdi->dev);
 
-       pcd_ready_wait(unit,PCD_READY_TMO);
-       return (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")));
+       if (pcd_ready_wait(unit,PCD_READY_TMO)) 
+               return CDS_DRIVE_NOT_READY;
+       if (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")))
+               return CDS_NO_DISC;
+       return CDS_DISC_OK;
 }
 
 static int pcd_identify( int unit, char * id )
@@ -648,7 +631,7 @@ static int pcd_identify( int unit, char * id )
 
        if (s) return -1;
        if ((pcd_buffer[0] & 0x1f) != 5) {
-         if (verbose) printk("%s: %s is not a CDROM\n",
+         if (verbose) printk("%s: %s is not a CD-ROM\n",
                        PCD.name,PCD.drive?"Slave":"Master");
          return -1;
        }
@@ -709,12 +692,37 @@ static int pcd_detect( void )
 
        if (k) return 0;
        
-       printk("%s: No CDROM drive found\n",name);
+       printk("%s: No CD-ROM drive found\n",name);
        return -1;
 }
 
 /* I/O request processing */
 
+static void do_pcd_request (void)
+
+{       int unit;
+
+       if (pcd_busy) return;
+        while (1) {
+           if ((!CURRENT) || (CURRENT->rq_status == RQ_INACTIVE)) return;
+           INIT_REQUEST;
+           if (CURRENT->cmd == READ) {
+               unit = MINOR(CURRENT->rq_dev);
+               if (unit != pcd_unit) {
+                       pcd_bufblk = -1;
+                       pcd_unit = unit;
+               }
+               pcd_sector = CURRENT->sector;
+               pcd_count = CURRENT->nr_sectors;
+               pcd_buf = CURRENT->buffer;
+               pcd_busy = 1;
+               ps_set_intr(do_pcd_read,0,0,nice); 
+               return;
+           } 
+           else end_request(0);
+       }
+}
+
 static int pcd_ready( void )
 
 {      int     unit = pcd_unit;
@@ -793,7 +801,7 @@ static void do_pcd_read_drq( void )
 
        if (pcd_completion(unit,pcd_buffer,"read block")) {
                 if (pcd_retries < PCD_RETRIES) {
-                        mdelay(1);
+                        mdelay(1); 
                         pcd_retries++;
                        pi_do_claimed(PI,pcd_start);
                         return;
@@ -812,6 +820,227 @@ static void do_pcd_read_drq( void )
        do_pcd_request();
        spin_unlock_irqrestore(&io_request_lock,saved_flags); 
 }
+
+/* the audio_ioctl stuff is adapted from sr_ioctl.c */
+
+static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
+                                unsigned int cmd, void *arg)
+
+{      int     unit = DEVICE_NR(cdi->dev);
+       switch (cmd) { 
+    
+       case CDROMPAUSE: 
+
+       {       char cmd[12]={SCMD_PAUSE_RESUME,0,0,0,0,0,0,0,0,0,0,0};
+
+               return (pcd_atapi(unit,cmd,0,NULL,"pause")) * EIO;
+       }
+
+       case CDROMRESUME:
+       
+       {       char cmd[12]={SCMD_PAUSE_RESUME,0,0,0,0,0,0,0,1,0,0,0};
+
+               return (pcd_atapi(unit,cmd,0,NULL,"resume")) * EIO;
+       }
+       
+       case CDROMPLAYMSF:
+
+       {       char cmd[12]={SCMD_PLAYAUDIO_MSF,0,0,0,0,0,0,0,0,0,0,0};
+               struct cdrom_msf* msf = (struct cdrom_msf*)arg;
+
+               cmd[3] = msf->cdmsf_min0;
+               cmd[4] = msf->cdmsf_sec0;
+               cmd[5] = msf->cdmsf_frame0;
+               cmd[6] = msf->cdmsf_min1;
+               cmd[7] = msf->cdmsf_sec1;
+               cmd[8] = msf->cdmsf_frame1;
+       
+               return (pcd_atapi(unit,cmd,0,NULL,"play msf")) * EIO;
+       }
+
+       case CDROMPLAYBLK:
+
+       {       char cmd[12]={SCMD_PLAYAUDIO10,0,0,0,0,0,0,0,0,0,0,0};
+               struct cdrom_blk* blk = (struct cdrom_blk*)arg;
+
+               cmd[2] = blk->from >> 24;
+               cmd[3] = blk->from >> 16;
+               cmd[4] = blk->from >> 8;
+               cmd[5] = blk->from;
+               cmd[7] = blk->len >> 8;
+               cmd[8] = blk->len;
+       
+               return (pcd_atapi(unit,cmd,0,NULL,"play block")) * EIO;
+       }
+               
+       case CDROMPLAYTRKIND:
+
+       {       char cmd[12]={SCMD_PLAYAUDIO_TI,0,0,0,0,0,0,0,0,0,0,0};
+               struct cdrom_ti* ti = (struct cdrom_ti*)arg;
+
+               cmd[4] = ti->cdti_trk0;
+               cmd[5] = ti->cdti_ind0;
+               cmd[7] = ti->cdti_trk1;
+               cmd[8] = ti->cdti_ind1;
+
+               return (pcd_atapi(unit,cmd,0,NULL,"play track")) * EIO;
+       }
+       
+       case CDROMREADTOCHDR:
+    
+       {       char cmd[12]={SCMD_READ_TOC,0,0,0,0,0,0,0,12,0,0,0};
+               struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
+               char buffer[32];
+               int r;
+       
+               r = pcd_atapi(unit,cmd,12,buffer,"read toc header");
+
+               tochdr->cdth_trk0 = buffer[2];
+               tochdr->cdth_trk1 = buffer[3];
+       
+               return r * EIO;
+       }
+       
+       case CDROMREADTOCENTRY:
+
+       {       char cmd[12]={SCMD_READ_TOC,0,0,0,0,0,0,0,12,0,0,0};
+
+               struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
+               unsigned char buffer[32];
+               int     r;
+       
+               cmd[1] = (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
+               cmd[6] = tocentry->cdte_track;
+       
+               r = pcd_atapi(unit,cmd,12,buffer,"read toc entry");
+
+               tocentry->cdte_ctrl = buffer[5] & 0xf;  
+               tocentry->cdte_adr = buffer[5] >> 4;
+               tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04)?1:0;
+               if (tocentry->cdte_format == CDROM_MSF) {
+                   tocentry->cdte_addr.msf.minute = buffer[9];
+                   tocentry->cdte_addr.msf.second = buffer[10];
+                   tocentry->cdte_addr.msf.frame = buffer[11];
+               } else
+                   tocentry->cdte_addr.lba = 
+                               (((((buffer[8] << 8) + buffer[9]) << 8)
+                                       + buffer[10]) << 8) + buffer[11];
+       
+                return r * EIO;
+        }
+
+       case CDROMSTOP:
+
+       {       char cmd[12]={0x1b,1,0,0,0,0,0,0,0,0,0,0};
+
+                return (pcd_atapi(unit,cmd,0,NULL,"stop")) * EIO;
+        }                                                         
+       
+       case CDROMSTART:
+
+        {       char cmd[12]={0x1b,1,0,0,1,0,0,0,0,0,0,0};
+
+                return (pcd_atapi(unit,cmd,0,NULL,"start")) * EIO;
+        } 
+       
+       case CDROMVOLCTRL:
+
+       {       char cmd[12]={0x5a,0,0,0,0,0,0,0,0,0,0,0};
+               char buffer[32];
+               char mask[32];
+               struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+
+               cmd[2] = 0xe;
+               cmd[4] = 28;
+
+                if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol")) 
+                       return -EIO;
+
+               cmd[2] = 0x4e;
+       
+               if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol mask"))
+                       return -EIO;
+       
+               buffer[0] = 0;
+       
+               buffer[21] = volctrl->channel0 & mask[21];
+               buffer[23] = volctrl->channel1 & mask[23];
+               buffer[25] = volctrl->channel2 & mask[25];
+               buffer[27] = volctrl->channel3 & mask[27];
+       
+               cmd[0] = 0x55;
+               cmd[1] = 0x10;
+
+               return pcd_atapi(unit,cmd,28,buffer,"mode select vol") * EIO;
+       }
+
+       case CDROMVOLREAD:
+
+        {       char cmd[12]={0x5a,0,0,0,0,0,0,0,0,0,0,0};
+                char buffer[32];
+                struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+                int     r;
+
+                cmd[2] = 0xe;
+                cmd[4] = 28;
+
+                r = pcd_atapi(unit,cmd,28,buffer,"mode sense vol read");
+
+               volctrl->channel0 = buffer[21];
+               volctrl->channel1 = buffer[23];
+               volctrl->channel2 = buffer[25];
+               volctrl->channel3 = buffer[27];
+
+                return r * EIO;
+        }
+  
+       
+       case CDROMSUBCHNL:
+
+       {       char cmd[12]={SCMD_READ_SUBCHANNEL,2,0x40,1,0,0,0,0,16,0,0,0};
+               struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg;
+               char buffer[32];
+       
+                if (pcd_atapi(unit,cmd,16,buffer,"read subchannel"))
+                        return -EIO;
+       
+               subchnl->cdsc_audiostatus = buffer[1];
+               subchnl->cdsc_format = CDROM_MSF;
+               subchnl->cdsc_ctrl = buffer[5] & 0xf;
+               subchnl->cdsc_trk = buffer[6];
+               subchnl->cdsc_ind = buffer[7];
+       
+               subchnl->cdsc_reladdr.msf.minute = buffer[13];
+               subchnl->cdsc_reladdr.msf.second = buffer[14];
+               subchnl->cdsc_reladdr.msf.frame = buffer[15];
+               subchnl->cdsc_absaddr.msf.minute = buffer[9];
+               subchnl->cdsc_absaddr.msf.second = buffer[10];
+               subchnl->cdsc_absaddr.msf.frame = buffer[11];
+
+               return 0;       
+       }
+
+       default:
+
+               return -ENOSYS;
+       }
+}
        
+static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
+
+{      char    cmd[12]={SCMD_READ_SUBCHANNEL,0,0x40,2,0,0,0,0,24,0,0,0};
+        char   buffer[32];
+       int     k;
+       int     unit = DEVICE_NR(cdi->dev);
+
+        if (pcd_atapi(unit,cmd,24,buffer,"get mcn")) return -EIO;
+
+       for (k=0;k<13;k++) mcn->medium_catalog_number[k] = buffer[k+9];
+       mcn->medium_catalog_number[13] = 0;
+       
+       return 0;
+}
+
 /* end of pcd.c */
 
index 3be1de32cf208b40d2b2354b700fe70032164127..69274fe4873d366f56ccc7a754c5e49a663f25cc 100644 (file)
                        (default 64)
 
            verbose     This parameter controls the amount of logging
-                       that is done while the driver probes for
-                       devices.  Set it to 0 for a quiet load, or to 1
-                       see all the progress messages.  (default 0)
+                       that the driver will do.  Set it to 0 for 
+                       normal operation, 1 to see autoprobe progress
+                       messages, or 2 to see additional debugging
+                       output.  (default 0)
 
             nice        This parameter controls the driver's use of
                         idle CPU time, at the expense of some speed.
        1.02    GRG 1998.05.06  SMP spinlock changes, 
                                Added slave support
        1.03    GRG 1998.06.16  Eliminate an Ugh.
+       1.04    GRG 1998.08.15  Extra debugging, use HZ in loop timing
 
 */
 
-#define PD_VERSION      "1.03"
+#define PD_VERSION      "1.04"
 #define PD_MAJOR       45
 #define PD_NAME                "pd"
 #define PD_UNITS       4
@@ -223,7 +225,7 @@ MODULE_PARM(drive3,"1-8i");
 #define PD_TMO          800             /* interrupt timeout in jiffies */
 #define PD_SPIN_DEL     50              /* spin delay in micro-seconds  */
 
-#define PD_SPIN         (10000/PD_SPIN_DEL)*PD_TMO  
+#define PD_SPIN         (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)  
 
 #define STAT_ERR        0x00001
 #define STAT_INDEX      0x00002
@@ -359,6 +361,7 @@ static struct file_operations pd_fops = {
         pd_ioctl,               /* ioctl */
         NULL,                   /* mmap */
         pd_open,                /* open */
+       NULL,                   /* flush */
         pd_release,             /* release */
         block_fsync,            /* fsync */
         NULL,                   /* fasync */
@@ -666,7 +669,7 @@ static void pd_reset( int unit )    /* called only for MASTER drive */
        udelay(250);
 }
 
-#define DBMSG(msg)     NULL
+#define DBMSG(msg)     ((verbose>1)?(msg):NULL)
 
 static int pd_wait_for( int unit, int w, char * msg )    /* polled wait */
 
index a176c45d3808de3806913a5dd3e51cc5ab4f54f2..a2f1f1da9e306d151c6245346b39df154c846dff 100644 (file)
                         (default 64)
 
             verbose     This parameter controls the amount of logging
-                        that is done while the driver probes for
-                        devices.  Set it to 0 for a quiet load, or 1 to
-                        see all the progress messages.  (default 0)
-
+                        that the driver will do.  Set it to 0 for
+                        normal operation, 1 to see autoprobe progress
+                        messages, or 2 to see additional debugging
+                        output.  (default 0)
            nice        This parameter controls the driver's use of
                        idle CPU time, at the expense of some speed.
 
                                Small change in pf_completion to round
                                up transfer size.
        1.02    GRG 1998.06.16  Eliminated an Ugh
+       1.03    GRG 1998.08.16  Use HZ in loop timings, extra debugging
 
 */
 
-#define PF_VERSION      "1.02"
+#define PF_VERSION      "1.03"
 #define PF_MAJOR       47
 #define PF_NAME                "pf"
 #define PF_UNITS       4
@@ -217,7 +219,7 @@ MODULE_PARM(drive3,"1-7i");
 #define PF_TMO          800             /* interrupt timeout in jiffies */
 #define PF_SPIN_DEL     50              /* spin delay in micro-seconds  */
 
-#define PF_SPIN         (10000/PF_SPIN_DEL)*PF_TMO  
+#define PF_SPIN         (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
 
 #define STAT_ERR        0x00001
 #define STAT_INDEX      0x00002
@@ -316,6 +318,7 @@ static struct file_operations pf_fops = {
         pf_ioctl,               /* ioctl */
         NULL,                   /* mmap */
         pf_open,                /* open */
+       NULL,                   /* flush */
         pf_release,             /* release */
         block_fsync,            /* fsync */
         NULL,                   /* fasync */
@@ -627,7 +630,7 @@ static int pf_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
         return r;
 }
 
-#define DBMSG(msg)      NULL
+#define DBMSG(msg)      ((verbose>1)?(msg):NULL)
 
 static void pf_lock(int unit, int func)
 
index 816b44edec4098a2990b07cc4eea89d8a229d68d..fd001008dad750281eb38e60ceb31dc9c61014fd 100644 (file)
@@ -1,35 +1,35 @@
 /* 
-        pg.c    (c) 1998  Grant R. Guenther <grant@torque.net>
-                          Under the terms of the GNU public license.
+       pg.c    (c) 1998  Grant R. Guenther <grant@torque.net>
+                         Under the terms of the GNU public license.
 
        The pg driver provides a simple character device interface for
-        sending ATAPI commands to a device.  With the exception of the
+       sending ATAPI commands to a device.  With the exception of the
        ATAPI reset operation, all operations are performed by a pair
-        of read and write operations to the appropriate /dev/pgN device.
+       of read and write operations to the appropriate /dev/pgN device.
        A write operation delivers a command and any outbound data in
-        a single buffer.  Normally, the write will succeed unless the
-        device is offline or malfunctioning, or there is already another
+       a single buffer.  Normally, the write will succeed unless the
+       device is offline or malfunctioning, or there is already another
        command pending.  If the write succeeds, it should be followed
-        immediately by a read operation, to obtain any returned data and
-        status information.  A read will fail if there is no operation
-        in progress.
+       immediately by a read operation, to obtain any returned data and
+       status information.  A read will fail if there is no operation
+       in progress.
 
        As a special case, the device can be reset with a write operation,
-        and in this case, no following read is expected, or permitted.
+       and in this case, no following read is expected, or permitted.
 
        There are no ioctl() operations.  Any single operation
        may transfer at most PG_MAX_DATA bytes.  Note that the driver must
-        copy the data through an internal buffer.  In keeping with all
+       copy the data through an internal buffer.  In keeping with all
        current ATAPI devices, command packets are assumed to be exactly
        12 bytes in length.
 
        To permit future changes to this interface, the headers in the
        read and write buffers contain a single character "magic" flag.
-        Currently this flag must be the character "P".
+       Currently this flag must be the character "P".
 
-        By default, the driver will autoprobe for a single parallel
-        port ATAPI device, but if their individual parameters are
-        specified, the driver can handle up to 4 devices.
+       By default, the driver will autoprobe for a single parallel
+       port ATAPI device, but if their individual parameters are
+       specified, the driver can handle up to 4 devices.
 
        To use this device, you must have the following device 
        special files defined:
 
        (You'll need to change the 97 to something else if you use
        the 'major' parameter to install the driver on a different
-        major number.)
+       major number.)
 
-        The behaviour of the pg driver can be altered by setting
-        some parameters from the insmod command line.  The following
-        parameters are adjustable:
+       The behaviour of the pg driver can be altered by setting
+       some parameters from the insmod command line.  The following
+       parameters are adjustable:
 
-            drive0      These four arguments can be arrays of       
-            drive1      1-6 integers as follows:
-            drive2
-            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
+           drive0      These four arguments can be arrays of       
+           drive1      1-6 integers as follows:
+           drive2
+           drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
 
-                        Where,
+                       Where,
 
-                <prt>   is the base of the parallel port address for
-                        the corresponding drive.  (required)
+               <prt>   is the base of the parallel port address for
+                       the corresponding drive.  (required)
 
-                <pro>   is the protocol number for the adapter that
-                        supports this drive.  These numbers are
-                        logged by 'paride' when the protocol modules
-                        are initialised.  (0 if not given)
+               <pro>   is the protocol number for the adapter that
+                       supports this drive.  These numbers are
+                       logged by 'paride' when the protocol modules
+                       are initialised.  (0 if not given)
 
-                <uni>   for those adapters that support chained
-                        devices, this is the unit selector for the
-                        chain of devices on the given port.  It should
-                        be zero for devices that don't support chaining.
-                        (0 if not given)
+               <uni>   for those adapters that support chained
+                       devices, this is the unit selector for the
+                       chain of devices on the given port.  It should
+                       be zero for devices that don't support chaining.
+                       (0 if not given)
 
-                <mod>   this can be -1 to choose the best mode, or one
-                        of the mode numbers supported by the adapter.
-                        (-1 if not given)
+               <mod>   this can be -1 to choose the best mode, or one
+                       of the mode numbers supported by the adapter.
+                       (-1 if not given)
 
-                <slv>   ATAPI devices can be jumpered to master or slave.
-                        Set this to 0 to choose the master drive, 1 to
-                        choose the slave, -1 (the default) to choose the
-                        first drive found.
+               <slv>   ATAPI devices can be jumpered to master or slave.
+                       Set this to 0 to choose the master drive, 1 to
+                       choose the slave, -1 (the default) to choose the
+                       first drive found.
 
-                <dly>   some parallel ports require the driver to 
-                        go more slowly.  -1 sets a default value that
-                        should work with the chosen protocol.  Otherwise,
-                        set this to a small integer, the larger it is
-                        the slower the port i/o.  In some cases, setting
-                        this to zero will speed up the device. (default -1)
+               <dly>   some parallel ports require the driver to 
+                       go more slowly.  -1 sets a default value that
+                       should work with the chosen protocol.  Otherwise,
+                       set this to a small integer, the larger it is
+                       the slower the port i/o.  In some cases, setting
+                       this to zero will speed up the device. (default -1)
 
            major       You may use this parameter to overide the
                        default major number (97) that this driver
                        device (in /proc output, for instance).
                        (default "pg").
 
-            verbose     This parameter controls the amount of logging
-                        that is done by the driver.  Set it to 0 for 
+           verbose     This parameter controls the amount of logging
+                       that is done by the driver.  Set it to 0 for 
                        quiet operation, to 1 to enable progress
                        messages while the driver probes for devices,
                        or to 2 for full debug logging.  (default 0)
 
-        If this driver is built into the kernel, you can use 
-        the following command line parameters, with the same values
-        as the corresponding module parameters listed above:
+       If this driver is built into the kernel, you can use 
+       the following command line parameters, with the same values
+       as the corresponding module parameters listed above:
 
-            pg.drive0
-            pg.drive1
-            pg.drive2
-            pg.drive3
+           pg.drive0
+           pg.drive1
+           pg.drive2
+           pg.drive3
 
-        In addition, you can use the parameter pg.disable to disable
-        the driver entirely.
+       In addition, you can use the parameter pg.disable to disable
+       the driver entirely.
 
 */
 
@@ -175,9 +175,9 @@ static int pg_drive_count;
 #include "setup.h"
 
 static STT pg_stt[5] = {{"drive0",6,drive0},
-                        {"drive1",6,drive1},
-                        {"drive2",6,drive2},
-                        {"drive3",6,drive3},
+                       {"drive1",6,drive1},
+                       {"drive2",6,drive2},
+                       {"drive3",6,drive3},
                        {"disable",1,&disable}};
 
 void pg_setup( char *str, int *ints)
@@ -221,9 +221,9 @@ void cleanup_module( void );
 static int pg_open(struct inode *inode, struct file *file);
 static int pg_release (struct inode *inode, struct file *file);
 static ssize_t pg_read(struct file * filp, char * buf, 
-                       size_t count, loff_t *ppos);
+                      size_t count, loff_t *ppos);
 static ssize_t pg_write(struct file * filp, const char * buf, 
-                        size_t count, loff_t *ppos);
+                       size_t count, loff_t *ppos);
 static int pg_detect(void);
 
 static int pg_identify (int unit, int log);
@@ -257,39 +257,40 @@ static char pg_scratch[512];            /* scratch block buffer */
 /* kernel glue structures */
 
 static struct file_operations pg_fops = {
-        NULL,                   /* lseek - default */
-        pg_read,                /* read */
-        pg_write,               /* write */
-        NULL,                   /* readdir - bad */
-        NULL,                   /* select */
-        NULL,                   /* ioctl */
-        NULL,                   /* mmap */
-        pg_open,                /* open */
-        pg_release,             /* release */
-        NULL,                   /* fsync */
-        NULL,                   /* fasync */
-        NULL,                   /* media change ? */
-        NULL                    /* revalidate new media */
+       NULL,                   /* lseek - default */
+       pg_read,                /* read */
+       pg_write,               /* write */
+       NULL,                   /* readdir - bad */
+       NULL,                   /* select */
+       NULL,                   /* ioctl */
+       NULL,                   /* mmap */
+       pg_open,                /* open */
+       NULL,                   /* flush */
+       pg_release,             /* release */
+       NULL,                   /* fsync */
+       NULL,                   /* fasync */
+       NULL,                   /* media change ? */
+       NULL                    /* revalidate new media */
 };
 
 void pg_init_units( void )
 
 {       int     unit, j;
 
-        pg_drive_count = 0;
-        for (unit=0;unit<PG_UNITS;unit++) {
-                PG.pi = & PG.pia;
-                PG.access = 0;
-                PG.busy = 0;
-                PG.present = 0;
+       pg_drive_count = 0;
+       for (unit=0;unit<PG_UNITS;unit++) {
+               PG.pi = & PG.pia;
+               PG.access = 0;
+               PG.busy = 0;
+               PG.present = 0;
                PG.bufptr = NULL;
                PG.drive = DU[D_SLV];
-                j = 0;
-                while ((j < PG_NAMELEN-2) && (PG.name[j]=name[j])) j++;
-                PG.name[j++] = '0' + unit;
-                PG.name[j] = 0;
-                if (DU[D_PRT]) pg_drive_count++;
-        }
+               j = 0;
+               while ((j < PG_NAMELEN-2) && (PG.name[j]=name[j])) j++;
+               PG.name[j++] = '0' + unit;
+               PG.name[j] = 0;
+               if (DU[D_PRT]) pg_drive_count++;
+       }
 } 
 
 int pg_init (void)      /* preliminary initialisation */
@@ -302,15 +303,15 @@ int pg_init (void)      /* preliminary initialisation */
 
        if (pg_detect()) return -1;
 
-        if (register_chrdev(major,name,&pg_fops)) {
-                printk("pg_init: unable to get major number %d\n",
-                        major);
-               for (unit=0;unit<PG_UNITS;unit++)
-                 if (PG.present) pi_release(PI);
-                return -1;
-        }
+       if (register_chrdev(major,name,&pg_fops)) {
+               printk("pg_init: unable to get major number %d\n",
+                       major);
+               for (unit=0;unit<PG_UNITS;unit++)
+                 if (PG.present) pi_release(PI);
+               return -1;
+       }
 
-        return 0;
+       return 0;
 }
 
 #ifdef MODULE
@@ -323,16 +324,16 @@ int     init_module(void)
 
 {       int     err;
 
-        err = pg_init();
+       err = pg_init();
 
-        return err;
+       return err;
 }
 
 void    cleanup_module(void)
 
 {       int unit;
 
-        unregister_chrdev(major,name);
+       unregister_chrdev(major,name);
 
        for (unit=0;unit<PG_UNITS;unit++)
          if (PG.present) pi_release(PI);
@@ -348,8 +349,8 @@ void    cleanup_module(void)
 static void pg_sleep( int cs )
 
 {       current->state = TASK_INTERRUPTIBLE;
-        current->timeout = jiffies + cs;
-        schedule();
+       current->timeout = jiffies + cs;
+       schedule();
 }
 
 static int pg_wait( int unit, int go, int stop, int tmo, char * msg )
@@ -358,26 +359,26 @@ static int pg_wait( int unit, int go, int stop, int tmo, char * msg )
 
        PG.status = 0;
 
-        j = 0;
-        while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies<tmo)) {
-                if (j++ < PG_SPIN) udelay(PG_SPIN_DEL);
+       j = 0;
+       while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies<tmo)) {
+               if (j++ < PG_SPIN) udelay(PG_SPIN_DEL);
                else pg_sleep(1);
        }
 
-        if ((r&(STAT_ERR&stop))||(jiffies>=tmo)) {
-           s = RR(0,7);
-           e = RR(0,1);
-           p = RR(0,2);
-           if (verbose > 1)
+       if ((r&(STAT_ERR&stop))||(jiffies>=tmo)) {
+          s = RR(0,7);
+          e = RR(0,1);
+          p = RR(0,2);
+          if (verbose > 1)
             printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n",
-                   PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":"");
+                  PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":"");
 
 
-           if (jiffies>=tmo) e |= 0x100;
+          if (jiffies>=tmo) e |= 0x100;
           PG.status = (e >> 4) & 0xff;
-           return -1;
-        }
-        return 0;
+          return -1;
+       }
+       return 0;
 }
 
 static int pg_command( int unit, char * cmd, int dlen, int tmo )
@@ -386,64 +387,64 @@ static int pg_command( int unit, char * cmd, int dlen, int tmo )
 
        pi_connect(PI);
 
-        WR(0,6,DRIVE);
+       WR(0,6,DRIVE);
 
-        if (pg_wait(unit,STAT_BUSY|STAT_DRQ,0,tmo,"before command")) {
-                pi_disconnect(PI);
-                return -1;
-        }
+       if (pg_wait(unit,STAT_BUSY|STAT_DRQ,0,tmo,"before command")) {
+               pi_disconnect(PI);
+               return -1;
+       }
 
-        WR(0,4,dlen % 256);
-        WR(0,5,dlen / 256);
-        WR(0,7,0xa0);          /* ATAPI packet command */
+       WR(0,4,dlen % 256);
+       WR(0,5,dlen / 256);
+       WR(0,7,0xa0);          /* ATAPI packet command */
 
-        if (pg_wait(unit,STAT_BUSY,STAT_DRQ,tmo,"command DRQ")) {
-                pi_disconnect(PI);
-                return -1;
-        }
+       if (pg_wait(unit,STAT_BUSY,STAT_DRQ,tmo,"command DRQ")) {
+               pi_disconnect(PI);
+               return -1;
+       }
 
-        if (RR(0,2) != 1) {
-           printk("%s: command phase error\n",PG.name);
-           pi_disconnect(PI);
-           return -1;
-        }
+       if (RR(0,2) != 1) {
+          printk("%s: command phase error\n",PG.name);
+          pi_disconnect(PI);
+          return -1;
+       }
 
-        pi_write_block(PI,cmd,12);
+       pi_write_block(PI,cmd,12);
 
        if (verbose > 1) {
                printk("%s: Command sent, dlen=%d packet= ", PG.name,dlen);
                for (k=0;k<12;k++) printk("%02x ",cmd[k]&0xff);
                printk("\n");
        }
-        return 0;
+       return 0;
 }
 
 static int pg_completion( int unit, char * buf, int tmo)
 
 {       int r, d, n, p;
 
-        r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
+       r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
                        tmo,"completion");
 
        PG.dlen = 0;
 
-        while (RR(0,7)&STAT_DRQ) {
-           d = (RR(0,4)+256*RR(0,5));
-           n = ((d+3)&0xfffc);
+       while (RR(0,7)&STAT_DRQ) {
+          d = (RR(0,4)+256*RR(0,5));
+          n = ((d+3)&0xfffc);
           p = RR(0,2)&3;
           if (p == 0) pi_write_block(PI,buf,n);
           if (p == 2) pi_read_block(PI,buf,n);
           if (verbose > 1) printk("%s: %s %d bytes\n",PG.name,
                                    p?"Read":"Write",n);
-           PG.dlen += (1-p)*d;
-           buf += d;
-           r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
-                        tmo,"completion");
-        }
+          PG.dlen += (1-p)*d;
+          buf += d;
+          r = pg_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
+                       tmo,"completion");
+       }
 
-        pi_disconnect(PI); 
+       pi_disconnect(PI); 
 
-        return r;
+       return r;
 }
 
 static int pg_reset( int unit )
@@ -457,9 +458,9 @@ static int pg_reset( int unit )
 
        pg_sleep(2);
 
-        k = 0;
-        while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))
-                pg_sleep(1);
+       k = 0;
+       while ((k++ < PG_RESET_TMO) && (RR(1,6)&STAT_BUSY))
+               pg_sleep(1);
 
        flg = 1;
        for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
@@ -494,7 +495,7 @@ static int pg_identify( int unit, int log )
        char    id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
        char    buf[36];
 
-        s = pg_command(unit,id_cmd,36,jiffies+PG_TMO);
+       s = pg_command(unit,id_cmd,36,jiffies+PG_TMO);
        if (s) return -1;
        s = pg_completion(unit,buf,jiffies+PG_TMO);
        if (s) return -1;
@@ -502,7 +503,7 @@ static int pg_identify( int unit, int log )
        if (log) {
                xs(buf,mf,8,8);
                xs(buf,id,16,16);
-               printk("%s: %s %s, %s\n",PG.name,mf,id,ms[PG.drive]);
+               printk("%s: %s %s, %s\n",PG.name,mf,id,ms[PG.drive]);
        }
 
        return 0;
@@ -511,7 +512,7 @@ static int pg_identify( int unit, int log )
 static int pg_probe( int unit )
 
 /*     returns  0, with id set if drive is detected
-               -1, if drive detection failed
+               -1, if drive detection failed
 */
 
 {      if (PG.drive == -1) {
@@ -520,7 +521,7 @@ static int pg_probe( int unit )
        } else {
           if (!pg_reset(unit)) return pg_identify(unit,1);
        }
-        return -1; 
+       return -1; 
 }
 
 static int pg_detect( void )
@@ -534,22 +535,22 @@ static int pg_detect( void )
        if (pg_drive_count == 0) {
            unit = 0;
            if (pi_init(PI,1,-1,-1,-1,-1,-1,pg_scratch,
-                        PI_PG,verbose,PG.name)) {
-               if (!pg_probe(unit)) {
+                       PI_PG,verbose,PG.name)) {
+               if (!pg_probe(unit)) {
                        PG.present = 1;
                        k++;
-               } else pi_release(PI);
+               } else pi_release(PI);
            }
 
        } else for (unit=0;unit<PG_UNITS;unit++) if (DU[D_PRT])
            if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
                        DU[D_PRO],DU[D_DLY],pg_scratch,PI_PG,verbose,
                        PG.name)) { 
-                if (!pg_probe(unit)) {
-                        PG.present = 1;
-                        k++;
-                } else pi_release(PI);
-            }
+               if (!pg_probe(unit)) {
+                       PG.present = 1;
+                       k++;
+               } else pi_release(PI);
+           }
 
        if (k) return 0;
 
@@ -563,16 +564,16 @@ static int pg_open (struct inode *inode, struct file *file)
 
 {       int    unit = DEVICE_NR(inode->i_rdev);
 
-        if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;
+       if ((unit >= PG_UNITS) || (!PG.present)) return -ENODEV;
 
-        PG.access++;
+       PG.access++;
 
        if (PG.access > 1) {
                PG.access--;
                return -EBUSY;
        }
 
-        MOD_INC_USE_COUNT;
+       MOD_INC_USE_COUNT;
 
        if (PG.busy) {
                pg_reset(unit);
@@ -590,34 +591,34 @@ static int pg_open (struct inode *inode, struct file *file)
                return -ENOMEM;
        }
 
-        return 0;
+       return 0;
 }
 
 static int pg_release (struct inode *inode, struct file *file)
 {
-        int    unit = DEVICE_NR(inode->i_rdev);
+       int     unit = DEVICE_NR(inode->i_rdev);
 
-        if ((unit >= PG_UNITS) || (PG.access <= 0)) 
-                return -EINVAL;
+       if ((unit >= PG_UNITS) || (PG.access <= 0)) 
+               return -EINVAL;
 
        PG.access--;
 
        kfree(PG.bufptr);
        PG.bufptr = NULL;
 
-        MOD_DEC_USE_COUNT;
+       MOD_DEC_USE_COUNT;
 
        return 0;
 
 }
 
 static ssize_t pg_write(struct file * filp, const char * buf, 
-                        size_t count, loff_t *ppos)
+                       size_t count, loff_t *ppos)
 
 {       struct inode            *ino = filp->f_dentry->d_inode;
-        int                     unit = DEVICE_NR(ino->i_rdev);
-        struct pg_write_hdr     hdr;
-        int                     hs = sizeof(hdr);
+       int                     unit = DEVICE_NR(ino->i_rdev);
+       struct pg_write_hdr     hdr;
+       int                     hs = sizeof(hdr);
 
        if (PG.busy) return -EBUSY;
        if (count < hs) return -EINVAL;
@@ -652,7 +653,7 @@ static ssize_t pg_write(struct file * filp, const char * buf,
 }
 
 static ssize_t pg_read(struct file * filp, char * buf, 
-                       size_t count, loff_t *ppos)
+                      size_t count, loff_t *ppos)
 
 {      struct inode            *ino = filp->f_dentry->d_inode;
        int                     unit = DEVICE_NR(ino->i_rdev);
@@ -673,7 +674,7 @@ static ssize_t pg_read(struct file * filp, char * buf,
        copy = 0;
 
        if (hdr.dlen < 0) {
-               hdr.dlen = -1 * hdr.dlen;
+               hdr.dlen = -1 * hdr.dlen;
                copy = hdr.dlen;
                if (copy > (count - hs)) copy = count - hs;
        }
index de77c1b5a91f563711e7c36923f0c2247da78545..44c4dadfbe6ebe150537f1b33763034cf8e5dc5c 100644 (file)
                        (default "pt").
 
             verbose     This parameter controls the amount of logging
-                        that is done while the driver probes for
-                        devices.  Set it to 0 for a quiet load, or 1 to
-                        see all the progress messages.  (default 0)
-
+                        that the driver will do.  Set it to 0 for
+                        normal operation, 1 to see autoprobe progress
+                        messages, or 2 to see additional debugging
+                        output.  (default 0)
         If this driver is built into the kernel, you can use 
         the following command line parameters, with the same values
         as the corresponding module parameters listed above:
                                for clearing error status.
                                Eliminate sti();
        1.02    GRG 1998.06.16  Eliminate an Ugh.
+       1.03    GRG 1998.08.15  Adjusted PT_TMO, use HZ in loop timing,
+                               extra debugging
 
 */
 
-#define PT_VERSION      "1.02"
+#define PT_VERSION      "1.03"
 #define PT_MAJOR       96
 #define PT_NAME                "pt"
 #define PT_UNITS       4
@@ -174,13 +177,13 @@ MODULE_PARM(drive3,"1-6i");
 #include "paride.h"
 
 #define PT_MAX_RETRIES  5
-#define PT_TMO          800             /* interrupt timeout in jiffies */
+#define PT_TMO          3000            /* interrupt timeout in jiffies */
 #define PT_SPIN_DEL     50              /* spin delay in micro-seconds  */
-#define PT_RESET_TMO    30             /* 3 seconds */
+#define PT_RESET_TMO    30             /* 30 seconds */
 #define PT_READY_TMO   60              /* 60 seconds */
 #define PT_REWIND_TMO  1200            /* 20 minutes */
 
-#define PT_SPIN         (10000/PT_SPIN_DEL)*PT_TMO  
+#define PT_SPIN         ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)  
 
 #define STAT_ERR        0x00001
 #define STAT_INDEX      0x00002
@@ -265,6 +268,7 @@ static struct file_operations pt_fops = {
         pt_ioctl,               /* ioctl */
         NULL,                   /* mmap */
         pt_open,                /* open */
+       NULL,                   /* flush */
         pt_release,             /* release */
         NULL,                   /* fsync */
         NULL,                   /* fasync */
@@ -505,7 +509,7 @@ static void pt_write_fm( int unit )
         pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark");
 }
 
-#define DBMSG(msg)      NULL
+#define DBMSG(msg)      ((verbose>1)?(msg):NULL)
 
 static int pt_reset( int unit )
 
index bef50bd36159b0c1d7eb6dbba1095e15b17e1d15..e56616a773abad97d536ada55601f7823f162798 100644 (file)
@@ -157,6 +157,7 @@ static struct file_operations ps2esdi_fops =
        ps2esdi_ioctl,          /* ioctl */
        NULL,                   /* mmap */
        ps2esdi_open,           /* open */
+       NULL,                   /* flush */
        ps2esdi_release,        /* release */
        block_fsync             /* fsync */
 };
index 822e3ec18ec0a267d54310503d62b257901d1427..dd1933a47336eb7801d80c04b776e353f4dea7c8 100644 (file)
@@ -223,6 +223,7 @@ static struct file_operations initrd_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        NULL,           /* open */
+       NULL,           /* flush */
        initrd_release, /* release */
        NULL            /* fsync */ 
 };
@@ -249,13 +250,11 @@ static int rd_open(struct inode * inode, struct file * filp)
        return 0;
 }
 
-#ifdef MODULE
 static int rd_release(struct inode * inode, struct file * filp)
 {
        MOD_DEC_USE_COUNT;
        return 0;
 }
-#endif
 
 static struct file_operations fd_fops = {
        NULL,           /* lseek - default */
@@ -266,11 +265,8 @@ static struct file_operations fd_fops = {
        rd_ioctl,       /* ioctl */
        NULL,           /* mmap */
        rd_open,        /* open */
-#ifndef MODULE
-       NULL,           /* no special release code... */
-#else
+       NULL,           /* flush */
        rd_release,     /* module needs to decrement use count */
-#endif
        block_fsync             /* fsync */ 
 };
 
index 5598ad0a7c8b7ad78ff65c5b7f906f01d4de52a0..eb2b38e953cfc370742b69ad3408e0e73ddaba2b 100644 (file)
@@ -968,7 +968,8 @@ static struct file_operations floppy_fops = {
        floppy_ioctl,           /* ioctl */
        NULL,                   /* mmap */
        floppy_open,            /* open */
-       floppy_release,         /* release */
+       NULL,                   /* flush */
+       floppy_release,         /* release *
        block_fsync,            /* fsync */
        NULL,                   /* fasync */
        floppy_check_change,    /* check_media_change */
index ffb1645ac23b29bebd0c8bd56ef6a28d791a4aa8..ccbcc0a97a959363f08e00de771e96f6f1ba7fac 100644 (file)
@@ -157,6 +157,7 @@ static struct file_operations xd_fops = {
        xd_ioctl,               /* ioctl */
        NULL,                   /* mmap */
        xd_open,                /* open */
+       NULL,                   /* flush */
        xd_release,             /* release */
        block_fsync             /* fsync */
 };
index ac13bcff2e9152df2da0cccf28127032c3d6f0d9..193208d0d8649b23c309eb4cc35ebebf27e0cc86 100644 (file)
@@ -63,46 +63,46 @@ do_z2_request( void )
 
     while ( TRUE )
     {
-        INIT_REQUEST;
-
-        start = CURRENT->sector << 9;
-        len  = CURRENT->current_nr_sectors << 9;
-
-        if ( ( start + len ) > z2ram_size )
-        {
-            printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ld\n",
-                CURRENT->sector,
-                CURRENT->current_nr_sectors);
-            end_request( FALSE );
-            continue;
-        }
-
-        if ( ( CURRENT->cmd != READ ) && ( CURRENT->cmd != WRITE ) )
-        {
-            printk( KERN_ERR DEVICE_NAME ": bad command: %d\n", CURRENT->cmd );
-            end_request( FALSE );
-            continue;
-        }
-
-        while ( len ) 
-        {
-            addr = start & Z2RAM_CHUNKMASK;
-            size = Z2RAM_CHUNKSIZE - addr;
-            if ( len < size )
-                size = len;
-
-            addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ];
-
-            if ( CURRENT->cmd == READ )
-                memcpy( CURRENT->buffer, (char *)addr, size );
-            else
-                memcpy( (char *)addr, CURRENT->buffer, size );
-
-            start += size;
-            len -= size;
-        }
-
-        end_request( TRUE );
+       INIT_REQUEST;
+
+       start = CURRENT->sector << 9;
+       len  = CURRENT->current_nr_sectors << 9;
+
+       if ( ( start + len ) > z2ram_size )
+       {
+           printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ld\n",
+               CURRENT->sector,
+               CURRENT->current_nr_sectors);
+           end_request( FALSE );
+           continue;
+       }
+
+       if ( ( CURRENT->cmd != READ ) && ( CURRENT->cmd != WRITE ) )
+       {
+           printk( KERN_ERR DEVICE_NAME ": bad command: %d\n", CURRENT->cmd );
+           end_request( FALSE );
+           continue;
+       }
+
+       while ( len ) 
+       {
+           addr = start & Z2RAM_CHUNKMASK;
+           size = Z2RAM_CHUNKSIZE - addr;
+           if ( len < size )
+               size = len;
+
+           addr += z2ram_map[ start >> Z2RAM_CHUNKSHIFT ];
+
+           if ( CURRENT->cmd == READ )
+               memcpy( CURRENT->buffer, (char *)addr, size );
+           else
+               memcpy( (char *)addr, CURRENT->buffer, size );
+
+           start += size;
+           len -= size;
+       }
+
+       end_request( TRUE );
     }
 }
 
@@ -113,13 +113,13 @@ get_z2ram( void )
 
     for ( i = 0; i < Z2RAM_SIZE / Z2RAM_CHUNKSIZE; i++ )
     {
-        if ( test_bit( i, zorro_unused_z2ram ) )
-        {
-            z2_count++;
-            z2ram_map[ z2ram_size++ ] = 
-                ZTWO_VADDR( Z2RAM_START ) + ( i << Z2RAM_CHUNKSHIFT );
-            clear_bit( i, zorro_unused_z2ram );
-        }
+       if ( test_bit( i, zorro_unused_z2ram ) )
+       {
+           z2_count++;
+           z2ram_map[ z2ram_size++ ] = 
+               ZTWO_VADDR( Z2RAM_START ) + ( i << Z2RAM_CHUNKSHIFT );
+           clear_bit( i, zorro_unused_z2ram );
+       }
     }
 
     return;
@@ -131,18 +131,18 @@ get_chipram( void )
 
     while ( amiga_chip_avail() > ( Z2RAM_CHUNKSIZE * 4 ) )
     {
-        chip_count++;
-        z2ram_map[ z2ram_size ] =
-            (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE );
+       chip_count++;
+       z2ram_map[ z2ram_size ] =
+           (u_long)amiga_chip_alloc( Z2RAM_CHUNKSIZE );
 
-        if ( z2ram_map[ z2ram_size ] == 0 )
-        {
-            break;
-        }
+       if ( z2ram_map[ z2ram_size ] == 0 )
+       {
+           break;
+       }
 
-        z2ram_size++;
+       z2ram_size++;
     }
-        
+       
     return;
 }
 
@@ -151,99 +151,99 @@ z2_open( struct inode *inode, struct file *filp )
 {
     int device;
     int max_z2_map = ( Z2RAM_SIZE / Z2RAM_CHUNKSIZE ) *
-        sizeof( z2ram_map[0] );
+       sizeof( z2ram_map[0] );
     int max_chip_map = ( amiga_chip_size / Z2RAM_CHUNKSIZE ) *
-        sizeof( z2ram_map[0] );
+       sizeof( z2ram_map[0] );
 
     device = DEVICE_NR( inode->i_rdev );
 
     if ( current_device != -1 && current_device != device )
     {
-        return -EBUSY;
+       return -EBUSY;
     }
 
     if ( current_device == -1 )
     {
-        z2_count   = 0;
-        chip_count = 0;
-        z2ram_size = 0;
-
-        switch ( device )
-        {
-            case Z2MINOR_COMBINED:
-
-                z2ram_map = kmalloc( max_z2_map + max_chip_map, GFP_KERNEL );
-                if ( z2ram_map == NULL )
-                {
-                    printk( KERN_ERR DEVICE_NAME
-                        ": cannot get mem for z2ram_map\n" );
-                    return -ENOMEM;
-                }
-
-                get_z2ram();
-                get_chipram();
-
-                if ( z2ram_size != 0 )
-                    printk( KERN_INFO DEVICE_NAME 
-                        ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)\n",
-                        z2_count * Z2RAM_CHUNK1024,
-                        chip_count * Z2RAM_CHUNK1024,
-                        ( z2_count + chip_count ) * Z2RAM_CHUNK1024 );
-
-            break;
+       z2_count   = 0;
+       chip_count = 0;
+       z2ram_size = 0;
+
+       switch ( device )
+       {
+           case Z2MINOR_COMBINED:
+
+               z2ram_map = kmalloc( max_z2_map + max_chip_map, GFP_KERNEL );
+               if ( z2ram_map == NULL )
+               {
+                   printk( KERN_ERR DEVICE_NAME
+                       ": cannot get mem for z2ram_map\n" );
+                   return -ENOMEM;
+               }
+
+               get_z2ram();
+               get_chipram();
+
+               if ( z2ram_size != 0 )
+                   printk( KERN_INFO DEVICE_NAME 
+                       ": using %iK Zorro II RAM and %iK Chip RAM (Total %dK)\n",
+                       z2_count * Z2RAM_CHUNK1024,
+                       chip_count * Z2RAM_CHUNK1024,
+                       ( z2_count + chip_count ) * Z2RAM_CHUNK1024 );
+
+           break;
 
            case Z2MINOR_Z2ONLY:
-                z2ram_map = kmalloc( max_z2_map, GFP_KERNEL );
-                if ( z2ram_map == NULL )
-                {
-                    printk( KERN_ERR DEVICE_NAME
-                        ": cannot get mem for z2ram_map\n" );
-                    return -ENOMEM;
-                }
-
-                get_z2ram();
-
-                if ( z2ram_size != 0 )
-                    printk( KERN_INFO DEVICE_NAME 
-                        ": using %iK of Zorro II RAM\n",
-                        z2_count * Z2RAM_CHUNK1024 );
-
-            break;
-
-            case Z2MINOR_CHIPONLY:
-                z2ram_map = kmalloc( max_chip_map, GFP_KERNEL );
-                if ( z2ram_map == NULL )
-                {
-                    printk( KERN_ERR DEVICE_NAME
-                        ": cannot get mem for z2ram_map\n" );
-                    return -ENOMEM;
-                }
-
-                get_chipram();
-
-                if ( z2ram_size != 0 )
-                    printk( KERN_INFO DEVICE_NAME 
-                        ": using %iK Chip RAM\n",
-                        chip_count * Z2RAM_CHUNK1024 );
-                    
-            break;
-
-            default:
-                return -ENODEV;
-        }
-
-        if ( z2ram_size == 0 )
-        {
-            kfree( z2ram_map );
-            printk( KERN_NOTICE DEVICE_NAME
-                ": no unused ZII/Chip RAM found\n" );
-            return -ENOMEM;
-        }
-
-        current_device = device;
-        z2ram_size <<= Z2RAM_CHUNKSHIFT;
-        z2_sizes[ device ] = z2ram_size >> 10;
-        blk_size[ MAJOR_NR ] = z2_sizes;
+               z2ram_map = kmalloc( max_z2_map, GFP_KERNEL );
+               if ( z2ram_map == NULL )
+               {
+                   printk( KERN_ERR DEVICE_NAME
+                       ": cannot get mem for z2ram_map\n" );
+                   return -ENOMEM;
+               }
+
+               get_z2ram();
+
+               if ( z2ram_size != 0 )
+                   printk( KERN_INFO DEVICE_NAME 
+                       ": using %iK of Zorro II RAM\n",
+                       z2_count * Z2RAM_CHUNK1024 );
+
+           break;
+
+           case Z2MINOR_CHIPONLY:
+               z2ram_map = kmalloc( max_chip_map, GFP_KERNEL );
+               if ( z2ram_map == NULL )
+               {
+                   printk( KERN_ERR DEVICE_NAME
+                       ": cannot get mem for z2ram_map\n" );
+                   return -ENOMEM;
+               }
+
+               get_chipram();
+
+               if ( z2ram_size != 0 )
+                   printk( KERN_INFO DEVICE_NAME 
+                       ": using %iK Chip RAM\n",
+                       chip_count * Z2RAM_CHUNK1024 );
+                   
+           break;
+
+           default:
+               return -ENODEV;
+       }
+
+       if ( z2ram_size == 0 )
+       {
+           kfree( z2ram_map );
+           printk( KERN_NOTICE DEVICE_NAME
+               ": no unused ZII/Chip RAM found\n" );
+           return -ENOMEM;
+       }
+
+       current_device = device;
+       z2ram_size <<= Z2RAM_CHUNKSHIFT;
+       z2_sizes[ device ] = z2ram_size >> 10;
+       blk_size[ MAJOR_NR ] = z2_sizes;
     }
 
 #if defined(MODULE)
@@ -258,7 +258,7 @@ z2_release( struct inode *inode, struct file *filp )
 {
 
     if ( current_device == -1 )
-        return;     
+       return;     
 
     sync_dev( inode->i_rdev );
 
@@ -271,16 +271,17 @@ z2_release( struct inode *inode, struct file *filp )
 
 static struct file_operations z2_fops =
 {
-        NULL,                   /* lseek - default */
-        block_read,             /* read - general block-dev read */
-        block_write,            /* write - general block-dev write */
-        NULL,                   /* readdir - bad */
-        NULL,                   /* poll */
-        NULL,                   /* ioctl */
-        NULL,                   /* mmap */
-        z2_open,                /* open */
-        z2_release,             /* release */
-        block_fsync             /* fsync */
+       NULL,                   /* lseek - default */
+       block_read,             /* read - general block-dev read */
+       block_write,            /* write - general block-dev write */
+       NULL,                   /* readdir - bad */
+       NULL,                   /* poll */
+       NULL,                   /* ioctl */
+       NULL,                   /* mmap */
+       z2_open,                /* open */
+       NULL,                   /* flush */
+       z2_release,             /* release */
+       block_fsync             /* fsync */
 };
 
 __initfunc(int
@@ -288,13 +289,13 @@ z2_init( void ))
 {
 
     if ( !MACH_IS_AMIGA )
-        return -ENXIO;
+       return -ENXIO;
 
     if ( register_blkdev( MAJOR_NR, DEVICE_NAME, &z2_fops ) )
     {
-        printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n",
-            MAJOR_NR );
-        return -EBUSY;
+       printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n",
+           MAJOR_NR );
+       return -EBUSY;
     }
    
     blk_dev[ MAJOR_NR ].request_fn = DEVICE_REQUEST;
@@ -313,7 +314,7 @@ init_module( void )
     error = z2_init();
     if ( error == 0 )
     {
-        printk( KERN_INFO DEVICE_NAME ": loaded as module\n" );
+       printk( KERN_INFO DEVICE_NAME ": loaded as module\n" );
     }
     
     return error;
@@ -325,29 +326,29 @@ cleanup_module( void )
     int i, j;
 
     if ( unregister_blkdev( MAJOR_NR, DEVICE_NAME ) != 0 )
-        printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n");
+       printk( KERN_ERR DEVICE_NAME ": unregister of device failed\n");
 
     if ( current_device != -1 )
     {
-        i = 0;
-
-        for ( j = 0 ; j < z2_count; j++ )
-        {
-            set_bit( i++, zorro_unused_z2ram ); 
-        }
-
-        for ( j = 0 ; j < chip_count; j++ )
-        {
-            if ( z2ram_map[ i ] )
-            {
-                amiga_chip_free( (void *) z2ram_map[ i++ ] );
-            }
-        }
-
-        if ( z2ram_map != NULL )
-        {
-            kfree( z2ram_map );
-        }
+       i = 0;
+
+       for ( j = 0 ; j < z2_count; j++ )
+       {
+           set_bit( i++, zorro_unused_z2ram ); 
+       }
+
+       for ( j = 0 ; j < chip_count; j++ )
+       {
+           if ( z2ram_map[ i ] )
+           {
+               amiga_chip_free( (void *) z2ram_map[ i++ ] );
+           }
+       }
+
+       if ( z2ram_map != NULL )
+       {
+           kfree( z2ram_map );
+       }
     }
 
     return;
index 00cb2cda28ffcd66bb21377aa10e9b4671d66eaa..025b25a7a871c36713d18ce494c541f2ca74f9a8 100644 (file)
@@ -25,6 +25,7 @@ obj-          :=
 
 obj-$(CONFIG_BLK_DEV_IDECD)    +=              cdrom.o
 obj-$(CONFIG_BLK_DEV_SR)       +=              cdrom.o
+obj-$(CONFIG_PARIDE_PCD)       +=              cdrom.o
 
 obj-$(CONFIG_AZTCD)            += aztcd.o
 obj-$(CONFIG_CDU31A)           += cdu31a.o     cdrom.o
index 0d8848fdc6cff74eab80c52df547ea9cef8e05d7..0342a538150613e55fb95c85c9481a588b3c6712 100644 (file)
@@ -379,6 +379,7 @@ static struct file_operations azt_fops = {
        aztcd_ioctl,            /* ioctl */
        NULL,                   /* mmap */
        aztcd_open,             /* open */
+       NULL,                   /* flush */
        aztcd_release,          /* release */
        NULL,                   /* fsync */
        NULL,                   /* fasync*/
index a2806b8581792794cc5870557c647478252dfb74..af5fb70219af96be8dd4dc1512fbb87fbb77bee5 100644 (file)
@@ -184,6 +184,7 @@ struct file_operations cdrom_fops =
        cdrom_ioctl,                    /* ioctl */
        NULL,                           /* mmap */
        cdrom_open,                     /* open */
+       NULL,                           /* flush */
        cdrom_release,                  /* release */
        NULL,                           /* fsync */
        NULL,                           /* fasync */
@@ -1081,10 +1082,12 @@ static void cdrom_sysctl_register(void)
        initialized = 1;
 }
 
+#ifdef MODULE
 static void cdrom_sysctl_unregister(void)
 {
        unregister_sysctl_table(cdrom_sysctl_header);
 }
+#endif /* endif MODULE */
 #endif /* endif CONFIG_SYSCTL */
 
 #ifdef MODULE
index 3fad59c73c17e558798bd9418c3d06595883226f..ea3f9093c5afc35a5c13431ae0ce24abaf3082ad 100644 (file)
@@ -160,6 +160,7 @@ static struct file_operations gscd_fops = {
        gscd_ioctl,             /* ioctl */
        NULL,                   /* mmap */
        gscd_open,              /* open */
+       NULL,                   /* flush */
        gscd_release,           /* release */
        NULL,                   /* fsync */
        NULL,                   /* fasync*/
index eae60ad3ca2c3ea1dea184b56becf79b1dd30778..76103945be2e2ec047fa296a12507a2236837055 100644 (file)
@@ -2008,6 +2008,7 @@ static struct file_operations opt_fops = {
        opt_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        opt_open,               /* open */
+       NULL,                   /* flush */
        opt_release,            /* release */
        NULL,                   /* fsync */
        NULL,                   /* fasync */
index 428964d8fe288af50e770e3e6f66f3c48a7fba59..11b99e645aacea75ac6cd0dba2ea04cef7b1049d 100644 (file)
@@ -4540,7 +4540,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
                /* resume playing audio tracks when a previous PLAY AUDIO call has  */
                /* been paused with a PAUSE command.                                */
                /* It will resume playing from the location saved in SubQ_run_tot.  */
-               if (D_S[d].audio_state!=audio_pausing) return -EINVAL;
+               if (D_S[d].audio_state!=audio_pausing) RETURN_UP(-EINVAL);
                if (famL_drive)
                        i=cc_PlayAudio(D_S[d].pos_audio_start,
                                       D_S[d].pos_audio_end);
@@ -4654,7 +4654,9 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
 #endif SAFE_MIXED
                i=cc_Pause_Resume(1);
                D_S[d].audio_state=0;
+#if 0
                cc_DriveReset();
+#endif
                RETURN_UP(i);
                
        case CDROMSTART:  /* Spin up the drive */
@@ -4676,7 +4678,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
        case CDROMVOLREAD:   /* read Volume settings from drive */
                msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
                st=cc_GetVolume();
-               if (st<0) return (st);
+               if (st<0) RETURN_UP(st);
                volctrl.channel0=D_S[d].vol_ctrl0;
                volctrl.channel1=D_S[d].vol_ctrl1;
                volctrl.channel2=0;
index dc6e243f163cf2f4fb736550ead9d58f87182ba5..6681f2a19b76261395460af13258132fb355692d 100644 (file)
@@ -1429,6 +1429,7 @@ static struct file_operations sjcd_fops = {
   sjcd_ioctl,         /* ioctl */
   NULL,               /* mmap */
   sjcd_open,          /* open */
+  NULL,                      /* flush */
   sjcd_release,       /* release */
   NULL,               /* fsync */
   NULL,               /* fasync */
index 52e64890e72eba0d82e42cbfbdbd55f062cffdf4..aaad43c966ed01d02f5604ebb2c2a0bac0a70849 100644 (file)
@@ -1469,16 +1469,17 @@ static struct file_operations cdu_fops =
 {
        NULL,                                           /* lseek - default */
        block_read,                                     /* read - general block-dev read */
-       block_write,                            /* write - general block-dev write */
+       block_write,                                    /* write - general block-dev write */
        NULL,                                           /* readdir - bad */
        NULL,                                           /* poll */
        cdu_ioctl,                                      /* ioctl */
        NULL,                                           /* mmap */
        cdu_open,                                       /* open */
-       cdu_release,                            /* release */
+       NULL,                                           /* flush */
+       cdu_release,                                    /* release */
        NULL,                                           /* fsync */
        NULL,                                           /* fasync */
-       cdu535_check_media_change,      /* check media change */
+       cdu535_check_media_change,                      /* check media change */
        NULL                                            /* revalidate */
 };
 
index 407238f401dfb62a5038b0cff91bb2dcced684f2..8ee33b612b73a20a851f5d7174b288bbae95171a 100644 (file)
@@ -113,10 +113,15 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
   if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then
     hex '  RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f
   fi
+  dep_tristate 'AIMSlab RadioTrack II support' CONFIG_RADIO_RTRACK2 $CONFIG_VIDEO_DEV
+  if [ "$CONFIG_RADIO_RTRACK2" = "y" ]; then
+    hex '  RadioTrack II i/o port (0x20c or 0x30c)' CONFIG_RADIO_RTRACK2_PORT 30c
+  fi
   dep_tristate 'Aztech/Packard Bell Radio' CONFIG_RADIO_AZTECH $CONFIG_VIDEO_DEV
   if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then
     hex '  Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350
   fi
+  dep_tristate 'Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
   dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
   if [ "$CONFIG_PARPORT" != "n" ]; then
     dep_tristate 'Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV
index baa7c859ac9ce6de8fc5c2189de039e640472e0f..e8424737f1628446985b75254ec70b368112f98e 100644 (file)
@@ -407,6 +407,14 @@ else
   endif
 endif                                             
 
+ifeq ($(CONFIG_RADIO_MIROPCM20),y)
+L_OBJS += radio-miropcm20.o
+else
+  ifeq ($(CONFIG_RADIO_MIROPCM20),m)
+  M_OBJS += radio-miropcm20.o
+  endif
+endif
+
 ifeq ($(CONFIG_QIC02_TAPE),y)
 L_OBJS += tpqic02.o
 else
index 153cb9ad7416c350f201ee429fb37601e6b7fa84..a9aa7671467ff5324c8ed845c12b23a03d5e2f42 100644 (file)
@@ -174,6 +174,7 @@ static struct file_operations acq_fops = {
        acq_ioctl,
        NULL,           /* No mmap */
        acq_open,
+       NULL,           /* flush */
        acq_close
 };
 
index 2703baac041874e997c58c403c3b443ab130b03f..43930ff1b5349f17febb28567a8bb8b1e3ee18ca 100644 (file)
@@ -236,6 +236,7 @@ struct file_operations adb_mouse_fops = {
     NULL,              /* mouse_ioctl */
     NULL,              /* mouse_mmap */
     open_mouse,
+    NULL,              /* flush */
     release_mouse,
     NULL,
     fasync_mouse,
index 45eaa0a73df35aa377602b837f862cb5eb57f250..e62ea57535a2365554061e6fd5a36f5f4b8b2592 100644 (file)
@@ -299,6 +299,7 @@ struct file_operations amiga_mouse_fops = {
        NULL,           /* mouse_ioctl */
        NULL,           /* mouse_mmap */
        open_mouse,
+       NULL,           /* flush */
        release_mouse,
        NULL,
        fasync_mouse,
index e9e964c4308d1e887e580b0dbc501321c824e417..32f109be32f5a84c7be79918855685694e12a7e0 100644 (file)
@@ -401,6 +401,7 @@ static struct file_operations apm_bios_fops = {
        do_ioctl,
        NULL,           /* mmap */
        do_open,
+       NULL,           /* flush */
        do_release,
        NULL,           /* fsync */
        NULL            /* fasync */
index 683d6de80ff5dcc5d019033c11422a2404e4f55c..33d71d3769d44e8ddbc09ba7f56ae55817e4caaa 100644 (file)
@@ -149,6 +149,7 @@ struct file_operations atari_mouse_fops = {
     NULL,              /* mouse_ioctl */
     NULL,              /* mouse_mmap */
     open_mouse,
+    NULL,              /* flush */
     release_mouse,
     NULL,
     fasync_mouse,
index 4a25dc4b1751d32427fcff48288f76abecaec6ee..52ce4bf679a080479715cd26241fcecf555fd5a6 100644 (file)
@@ -191,6 +191,7 @@ struct file_operations atixl_busmouse_fops = {
        NULL,           /* mouse_ioctl */
        NULL,           /* mouse_mmap */
        open_mouse,
+       NULL,           /* flush */
        release_mouse,
        NULL,
        fasync_mouse,
index 79ea691c28afe94cc43e0aa244721c55cce6ed74..5227ef712aa37e55e30a879f2af654f033f4cc12 100644 (file)
 #ifndef PCI_DEVICE_ID_BT849
 #define PCI_DEVICE_ID_BT849     0x351
 #endif
+#ifndef PCI_DEVICE_ID_BT878
+#define PCI_DEVICE_ID_BT878     0x36e
+#endif
+#ifndef PCI_DEVICE_ID_BT879
+#define PCI_DEVICE_ID_BT879     0x36f
+#endif
 
 
 /* Brooktree 848 registers */
 #define BT848_RISC_COUNT       0x120
 #define BT848_GPIO_DATA        0x200
 
-/* Bt878 register */
-
-#define BT878_DEVCTRL 0x40
-#define BT878_NTBF 0x02
 
 /* Bt848 RISC commands */
 
 #define BT848_FCAP             0x0E8
 #define BT848_PLL_F_LO         0x0F0
 #define BT848_PLL_F_HI         0x0F4
+
 #define BT848_PLL_XCI          0x0F8
+#define BT848_PLL_X            (1<<7)
+#define BT848_PLL_C            (1<<6)
+
+/* Bt878 register */
 
+#define BT878_DEVCTRL 0x40
+#define BT878_EN_TBFX 0x02
 
 #endif
index 58d8fadc154e31ece77ac15adb00037d71701794..9f797543982849659bc119127873ad29fde624d8 100644 (file)
 #define DEBUG(x)               /* Debug driver */      
 #define IDEBUG(x)              /* Debug interrupt handler */
 
-static unsigned int remap=0;    /* remap Bt848 */
-static unsigned int vidmem=0;   /* manually set video mem address */
-static int triton1=0;
-static int radio=0;
-
-static unsigned int card=0;
-
-MODULE_PARM(remap,"i");
 MODULE_PARM(vidmem,"i");
 MODULE_PARM(triton1,"i");
-MODULE_PARM(radio,"i");
-MODULE_PARM(card,"i");
+MODULE_PARM(remap,"1-4i");
+MODULE_PARM(radio,"1-4i");
+MODULE_PARM(card,"1-4i");
+MODULE_PARM(pll,"1-4i");
 
 static int find_vga(void);
 static void bt848_set_risc_jmps(struct bttv *btv);
@@ -84,12 +78,19 @@ static void bt848_set_risc_jmps(struct bttv *btv);
 /* Anybody who uses more than four? */
 #define BTTV_MAX 4
 
+static unsigned int vidmem=0;   /* manually set video mem address */
+static int triton1=0;
+
+static unsigned int remap[BTTV_MAX];    /* remap Bt848 */
+static unsigned int radio[BTTV_MAX];
+static unsigned int card[BTTV_MAX] = { 0, 0, 
+                                       0, 0 };
+static unsigned int pll[BTTV_MAX] = { 0, 0, 0, 0 };
+
 static int bttv_num;                   /* number of Bt848s in use */
 static struct bttv bttvs[BTTV_MAX];
 
 #define I2C_TIMING (0x7<<4)
-#define I2C_COMMAND (I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA)
-
 #define I2C_DELAY   10
 #define I2C_SET(CTRL,DATA) \
     { btwrite((CTRL<<1)|(DATA), BT848_I2C); udelay(I2C_DELAY); }
@@ -128,10 +129,6 @@ static inline unsigned long uvirt_to_phys(unsigned long adr)
 
 static inline unsigned long uvirt_to_bus(unsigned long adr) 
 {
-       /*  printk("adr: 0x%8x, ",adr);
-       printk("phys: 0x%8x, ",(uvirt_to_phys(adr)));
-       printk("bus: 0x%8x\n",virt_to_bus(phys_to_virt(uvirt_to_phys(adr))));
-       */
        return virt_to_bus(phys_to_virt(uvirt_to_phys(adr)));
 }
 
@@ -199,7 +196,8 @@ static int fbuffer_alloc(struct bttv *btv)
        if(!btv->fbuffer)
                btv->fbuffer=(unsigned char *) rvmalloc(2*BTTV_MAX_FBUF);
        else
-               printk(KERN_ERR "bttv: Double alloc of fbuffer!\n");
+               printk(KERN_ERR "bttv%d: Double alloc of fbuffer!\n",
+                       btv->nr);
        if(!btv->fbuffer)
                return -ENOBUFS;
        return 0;
@@ -236,7 +234,7 @@ static int I2CRead(struct i2c_bus *bus, unsigned char addr)
        /* clear status bit ; BT848_INT_RACK is ro */
        btwrite(BT848_INT_I2CDONE, BT848_INT_STAT);
   
-       btwrite(((addr & 0xff) << 24) | I2C_COMMAND, BT848_I2C);
+       btwrite(((addr & 0xff) << 24) | btv->i2c_command, BT848_I2C);
   
        /*
         * Timeout for I2CRead is 1 second (this should be enough, really!)
@@ -251,7 +249,8 @@ static int I2CRead(struct i2c_bus *bus, unsigned char addr)
   
        if (!i) 
        {
-               printk(KERN_DEBUG "bttv: I2CRead timeout\n");
+               printk(KERN_DEBUG "bttv%d: I2CRead timeout\n",
+                       btv->nr);
                return -1;
        }
        if (!(stat & BT848_INT_RACK))
@@ -274,7 +273,7 @@ static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
        /* clear status bit; BT848_INT_RACK is ro */
        btwrite(BT848_INT_I2CDONE, BT848_INT_STAT);
   
-       data=((addr & 0xff) << 24) | ((b1 & 0xff) << 16) | I2C_COMMAND;
+       data=((addr & 0xff) << 24) | ((b1 & 0xff) << 16) | btv->i2c_command;
        if (both)
        {
                data|=((b2 & 0xff) << 8);
@@ -293,7 +292,8 @@ static int I2CWrite(struct i2c_bus *bus, unsigned char addr, unsigned char b1,
   
        if (!i) 
        {
-               printk(KERN_DEBUG "bttv: I2CWrite timeout\n");
+               printk(KERN_DEBUG "bttv%d: I2CWrite timeout\n",
+                       btv->nr);
                return -1;
        }
        if (!(stat & BT848_INT_RACK))
@@ -356,9 +356,10 @@ void attach_inform(struct i2c_bus *bus, int id)
                        if (btv->tuner_type != -1) 
                        {
                                tunertype=btv->tuner_type;
-                               i2c_control_device(&(btv->i2c), I2C_DRIVERID_TUNER,
-                                       TUNER_SET_TYPE,&tunertype);
-                       }
+                               i2c_control_device(&(btv->i2c), 
+                                                   I2C_DRIVERID_TUNER,
+                                                   TUNER_SET_TYPE,&tunertype);
+                       }
                        break;
        }
 }
@@ -406,6 +407,7 @@ struct tvcard
         u32 gpiomask;
         u32 muxsel[8];
         u32 audiomux[6]; /* Tuner, Radio, internal, external, mute, stereo */
+        u32 gpiomask2; /* GPIO MUX mask */
 };
 
 static struct tvcard tvcards[] = 
@@ -423,12 +425,14 @@ static struct tvcard tvcards[] =
        /* Diamond DTV2000 */
         { 3, 0, 2, 3, { 2, 3, 1, 1}, { 0, 1, 0, 1, 3}},
        /* AVerMedia TVPhone */
-        { 3, 0, 2,15, { 2, 3, 1, 1}, {12, 0,11,11, 0}},
+        { 3, 0, 3,15, { 2, 3, 1, 1}, {12, 0,11,11, 0}},
         /* Matrix Vision MV-Delta */
-        { 5,-1, 4, 0, { 2, 3, 1, 0, 0}},
+        { 5,-1, 3, 0, { 2, 3, 1, 0, 0}},
         /* Fly Video II */
         { 3, 0, 2, 0xc00, { 2, 3, 1, 1}, 
         {0, 0xc00, 0x800, 0x400, 0xc00, 0}},
+        /* TurboTV */
+        { 3, 0, 2, 3, { 2, 3, 1, 1}, { 1, 1, 2, 3, 0}},
 };
 #define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
 
@@ -503,12 +507,46 @@ static void bt848_cap(struct bttv *btv, uint state)
 
 /* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC*/
 
+/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C 
+   PLL_X = Reference pre-divider (0=1, 1=2) 
+   PLL_C = Post divider (0=6, 1=4)
+   PLL_I = Integer input 
+   PLL_F = Fractional input 
+   
+   F_input = 28.636363 MHz: 
+   PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
+*/
+
+static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
+{
+        unsigned char fl, fh, fi;
+        
+        /* prevent overflows */
+        fin/=4;
+        fout/=4;
+
+        fout*=12;
+        fi=fout/fin;
+
+        fout=(fout-fin*fi)*256;
+        fh=fout/fin;
+
+        fout=(fout-fin*fh)*256;
+        fl=fout/fin;
+
+        /*printk("0x%02x 0x%02x 0x%02x\n", fi, fh, fl);*/
+        btwrite(fl,BT848_PLL_F_LO);
+        btwrite(fh,BT848_PLL_F_HI);
+        btwrite(fi|BT848_PLL_X,BT848_PLL_XCI);
+}
+
 static int set_pll(struct bttv *btv)
 {
         int i;
+        unsigned long tv;
 
-       if (!btv->pll)
-               return 0;
+        if (!btv->pll)
+               return 0;
         if ((btread(BT848_IFORM)&BT848_IFORM_XT0))
         {
                 /* printk ("switching PLL off\n");*/
@@ -524,13 +562,24 @@ static int set_pll(struct bttv *btv)
         
         /* printk ("setting PLL for PAL/SECAM\n");*/
 
+       set_pll_freq(btv, 28636363, 35468950);
+/*     
         btwrite(0x00,BT848_TGCTRL);
         btwrite(0xf9,BT848_PLL_F_LO);
         btwrite(0xdc,BT848_PLL_F_HI);
-        btwrite(0x8e,BT848_PLL_XCI);
+        btwrite(14|BT848_PLL_X,BT848_PLL_XCI);
+*/
+       /*
+        *      Let other people run while the PLL stabilizes
+        */
+       
+       tv=jiffies+HZ/10;       /* .1 seconds */
+       do
+       {
+               schedule();
+       }
+       while(time_before(jiffies,tv));
 
-       /* Ugh ugh ugh .. schedule ? */
-        udelay(100000);
         for (i=0; i<100; i++) 
         {
                 if ((btread(BT848_DSTATUS)&BT848_DSTATUS_PLOCK))
@@ -548,7 +597,8 @@ static int set_pll(struct bttv *btv)
 
 static void bt848_muxsel(struct bttv *btv, unsigned int input)
 {
-       btwrite(tvcards[btv->type].gpiomask, BT848_GPIO_OUT_EN);
+       btaor(tvcards[btv->type].gpiomask2,~tvcards[btv->type].gpiomask2,
+               BT848_GPIO_OUT_EN);
 
        /* This seems to get rid of some synchronization problems */
        btand(~(3<<5), BT848_IFORM);
@@ -569,23 +619,7 @@ static void bt848_muxsel(struct bttv *btv, unsigned int input)
        audio(btv, (input!=tvcards[btv->type].tuner) ? 
               AUDIO_EXTERN : AUDIO_TUNER);
        btaor(tvcards[btv->type].muxsel[input]>>4,
-              ~tvcards[btv->type].gpiomask, BT848_GPIO_DATA);
-#if 0
-       if (input==3) 
-       {
-               btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
-               btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
-       }
-       else
-       {
-               btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
-               btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
-       }
-       if (input==2)
-               input=3;
-       btaor(((input+2)&3)<<5, ~(3<<5), BT848_IFORM);
-       audio(btv, input ? AUDIO_EXTERN : AUDIO_TUNER);
-#endif
+               ~tvcards[btv->type].gpiomask2, BT848_GPIO_DATA);
 }
 
 
@@ -645,27 +679,28 @@ int palette2fmt[] = {
        BT848_COLOR_FMT_RGB15,
        BT848_COLOR_FMT_YUY2,
        BT848_COLOR_FMT_BtYUV,
-       -1,
-       -1,
-       -1,
+       0,
+       0,
+       0,
        BT848_COLOR_FMT_RAW,
        BT848_COLOR_FMT_YCrCb422,
        BT848_COLOR_FMT_YCrCb411,
 };
 #define PALETTEFMT_MAX 11
 
-static int  make_rawrisctab(struct bttv *btv, unsigned int *ro,
+static int make_rawrisctab(struct bttv *btv, unsigned int *ro,
                             unsigned int *re, unsigned int *vbuf)
 {
         unsigned long line;
-       unsigned long bpl=1024;
+       unsigned long bpl=1024;         /* bytes per line */
        unsigned long vadr=(unsigned long) vbuf;
 
        *(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
        *(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
   
         /* In PAL 650 blocks of 256 DWORDs are sampled, but only if VDELAY
-           is 2. We'll have to handle this inside the IRQ handler ... */
+           is 2 and without separate VBI grabbing.
+           We'll have to handle this inside the IRQ handler ... */
 
        for (line=0; line < 640; line++)
        {
@@ -802,6 +837,152 @@ static inline void write_risc_segment(unsigned int **rp, unsigned long line_adr,
        *x+=dx;
 }
 
+static void make_clip_tab(struct bttv *btv, struct video_clip *cr, int ncr)
+{
+       int i,t;
+       int yy, y, x, dx;
+       struct video_clip first, *cur, *cur2, *nx, first2, *prev, *nx2;
+       int bpp, bpl, width, height, inter;
+       unsigned int **rp,*ro,*re;
+       unsigned long adr;
+       int cx,cx2,cy,cy2;
+
+       inter=(btv->win.interlace&1)^1;
+       bpp=btv->win.bpp;
+       bpl=btv->win.bpl;
+       ro=btv->risc_odd;
+       re=btv->risc_even;
+       width=btv->win.width;
+       height=btv->win.height;
+       adr=btv->win.vidadr+btv->win.x*bpp+btv->win.y*bpl;
+
+       /* clip clipping rects against viewing window AND screen 
+          so we do not have to rely on the user program
+        */
+       cx=(btv->win.x<0) ? (-btv->win.x) : 0;
+       cy=(btv->win.y<0) ? (-btv->win.y) : 0;
+       cx2=(btv->win.x+width>btv->win.swidth) ? 
+               (btv->win.swidth-btv->win.x) : width;
+       cy2=(btv->win.y+height>btv->win.sheight) ? 
+               (btv->win.sheight-btv->win.y) : height;
+       first.next=NULL;
+       for (i=0; i<ncr; i++)
+       {
+                if ((t=cy-cr[i].y)>0)
+               {
+                       if (cr[i].height<=t)
+                               continue;
+                        cr[i].height-=t;
+                       cr[i].y=cy;
+               } 
+               if ((t=cy2-cr[i].y)<cr[i].height) 
+               {
+                       if (t<=0)
+                               continue;
+                       cr[i].height=t;
+               }
+                if ((t=cx-cr[i].x)>0)
+               {
+                       if (cr[i].width<=t)
+                               continue;
+                        cr[i].width-=t;
+                       cr[i].x=cx;
+               } 
+               if ((t=cx2-cr[i].x)<cr[i].width) 
+               {
+                       if (t<=0)
+                               continue;
+                       cr[i].width=t;
+               }
+               cur=&first;
+               while ((nx=cur->next) && (cr[i].y > cur->next->y))
+                       cur=nx; 
+               cur->next=&(cr[i]);
+               cr[i].next=nx;
+       }
+       first2.next=NULL;
+       
+       *(ro++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(ro++)=0;
+       *(re++)=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1; *(re++)=0;
+       
+       /* loop through all lines */
+       for (yy=0; yy<(height<<inter); yy++) 
+        {
+                y=yy>>inter;
+                rp= (yy&1) ? &re : &ro;
+         
+                /* remove rects with y2 > y */
+                if ((cur=first2.next))
+                {
+                        prev=&first2;
+                        do
+                        {
+                                if (cur->y+cur->height <= y) 
+                                        prev->next=cur->next;
+                                else
+                                        prev=cur;
+                        } 
+                        while ((cur=cur->next));
+                }
+                
+                /* add rect to second (x-sorted) list if rect.y == y  */
+                if ((cur=first.next))
+                {
+                        while ((cur) && (cur->y == y))
+                        { 
+                                first.next=cur->next;
+                                cur2=&first2;
+                                while ((nx2=cur2->next) && (cur->x > cur2->next->x)) 
+                                        cur2=nx2; 
+                                cur2->next=cur;
+                                cur->next=nx2;
+                                cur=first.next;
+                        }
+                }
+                x=0;
+                if ((btv->win.y+y<=0)||(btv->win.y+y>=btv->win.sheight))
+                        write_risc_segment(rp, adr, BT848_RISC_SKIP, &x,
+                                           width, bpp, width);
+                else 
+                {
+                        dx=cx;
+                        for (cur2=first2.next; cur2; cur2=cur2->next)
+                        {
+                                if (x+dx < cur2->x)
+                                {
+                                        write_risc_segment(rp, adr, BT848_RISC_SKIP,
+                                                           &x, dx, bpp, width);
+                                        dx=cur2->x-x;
+                                        write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+                                                           &x, dx, bpp, width);
+                                        dx=cur2->width;
+                                }
+                                else if (x+dx < cur2->x+cur2->width) 
+                                        dx=cur2->x+cur2->width-x; 
+                        }
+                        if (cx2<width)
+                        {
+                                write_risc_segment(rp, adr, BT848_RISC_SKIP,
+                                                   &x, dx, bpp, width);
+                                write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+                                                   &x, cx2-x, bpp, width);
+                                dx=width-x;
+                        }
+                        write_risc_segment(rp, adr, BT848_RISC_SKIP,
+                                           &x, dx, bpp, width);
+                        write_risc_segment(rp, adr, BT848_RISC_WRITEC,
+                                           &x, width-x, bpp, width);
+                }
+                if ((!inter)||(yy&1))
+                        adr+=bpl;
+       }
+        
+        *(ro++)=BT848_RISC_JUMP;
+       *(ro++)=btv->bus_vbi_even;
+       *(re++)=BT848_RISC_JUMP;
+       *(re++)=btv->bus_vbi_odd;
+}
+
 
 /*
  *     Set the registers for the size we have specified. Don't bother
@@ -814,36 +995,50 @@ static inline void write_risc_segment(unsigned int **rp, unsigned long line_adr,
  
 struct tvnorm 
 {
-        u16 cropwidth, cropheight;
+        u32 Fsc;
+        u16 swidth, sheight; /* scaled standard width, height */
        u16 totalwidth;
        u8 adelay, bdelay, iform;
        u32 scaledtwidth;
        u16 hdelayx1, hactivex1;
-       u16 vdelay;
+       u16 vdelay, fporch;
 };
 
 static struct tvnorm tvnorms[] = {
        /* PAL-BDGHI */
-        { 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
-           944, 186, 922, 0x20},
+        /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
+        { 35468950,
+          924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+          1135, 186, 924, 0x20},
+/*
+        { 35468950, 
+          768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
+         944, 186, 922, 0x20},
+*/
        /* NTSC */
-       { 640, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
-           780, 135, 754, 0x16},
+       { 28636363,
+          640, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC|BT848_IFORM_XT0),
+          780, 135, 754, 0x1a},
        /* SECAM */
-       { 768, 576, 1135, 0x7f, 0xb0, (BT848_IFORM_SECAM|BT848_IFORM_XT1),
-           944, 186, 922, 0x20},
+       { 28636363, 
+          640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
+         780, 135, 754, 0x16},
        /* PAL-M */
-       { 640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
-           780, 135, 754, 0x16},
+       { 28636363, 
+          640, 480, 910, 0x68, 0x5d, (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
+         780, 135, 754, 0x16},
        /* PAL-N */
-       { 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
-           944, 186, 922, 0x20},
+       { 35468950, 
+          768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
+         944, 186, 922, 0x20},
        /* PAL-NC */
-       { 768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
-           944, 186, 922, 0x20},
+       { 35468950, 
+          768, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
+         944, 186, 922, 0x20},
        /* NTSC-Japan */
-       { 640, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
-           780, 135, 754, 0x16},
+       { 28636363,
+          640, 480,  910, 0x68, 0x5d, (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
+         780, 135, 754, 0x16},
 };
 #define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
 
@@ -891,6 +1086,10 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
 
        tvn=&tvnorms[btv->win.norm];
        
+        btv->win.cropheight=tvn->sheight;
+        btv->win.cropwidth=tvn->swidth;
+
+/*
        if (btv->win.cropwidth>tvn->cropwidth)
                 btv->win.cropwidth=tvn->cropwidth;
        if (btv->win.cropheight>tvn->cropheight)
@@ -900,7 +1099,7 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
                 width=btv->win.cropwidth;
        if (height>btv->win.cropheight)
                height=btv->win.cropheight;
-
+*/
        btwrite(tvn->adelay, BT848_ADELAY);
        btwrite(tvn->bdelay, BT848_BDELAY);
        btaor(tvn->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM);
@@ -916,12 +1115,13 @@ static void bt848_set_geo(struct bttv *btv, u16 width, u16 height, u16 fmt)
      
        btv->win.interlace = (height>btv->win.cropheight/2) ? 1 : 0;
        inter=(btv->win.interlace&1)^1;
+       vdelay=btv->win.cropy+tvn->vdelay;
+
        xsf = (hactive*tvn->scaledtwidth)/btv->win.cropwidth;
        hscale = ((tvn->totalwidth*4096UL)/xsf-4096);
-       vdelay=btv->win.cropy+tvn->vdelay;
 
-       hdelay=(tvn->hdelayx1*tvn->scaledtwidth)/tvn->totalwidth;
-       hdelay=((hdelay+btv->win.cropx)*hactive)/btv->win.cropwidth;
+       hdelay=tvn->hdelayx1+btv->win.cropx;
+       hdelay=(hdelay*hactive)/btv->win.cropwidth;
        hdelay&=0x3fe;
 
        sr=((btv->win.cropheight>>inter)*512)/height-512;
@@ -948,22 +1148,23 @@ static void bt848_set_winsize(struct bttv *btv)
 {
         unsigned short format;
 
-        btv->win.color_fmt=format= (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
-               bpp2fmt[(btv->win.bpp-1)&3];
-                       
+        btv->win.color_fmt = format = 
+                (btv->win.depth==15) ? BT848_COLOR_FMT_RGB15 :
+                        bpp2fmt[(btv->win.bpp-1)&3];
+
        /*      RGB8 seems to be a 9x5x5 GRB color cube starting at
         *      color 16. Why the h... can't they even mention this in the
         *      data sheet?  [AC - because it's a standard format so I guess
         *      it never occurred to them]
         *      Enable dithering in this mode.
         */
-#if 0   
+
        if (format==BT848_COLOR_FMT_RGB8)
-                btand(~0x10, BT848_CAP_CTL); 
+                btand(~BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL); 
        else
-               btor(0x10, BT848_CAP_CTL);
-#endif
-        bt848_set_geo(btv,btv->win.width, btv->win.height, format);
+               btor(BT848_CAP_CTL_DITH_FRAME, BT848_CAP_CTL);
+
+        bt848_set_geo(btv, btv->win.width, btv->win.height, format);
 }
 
 /*
@@ -978,7 +1179,7 @@ static void set_freq(struct bttv *btv, unsigned short freq)
        audio(btv, AUDIO_MUTE);
        udelay(AUDIO_MUTE_DELAY);
 
-       if (btv->radio
+       if (radio[btv->nr]
        {
                if (btv->have_tuner)
                        i2c_control_device(&(btv->i2c), I2C_DRIVERID_TUNER,
@@ -1027,7 +1228,7 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
                if(fbuffer_alloc(btv))
                        return -ENOBUFS;
        }
-       if(btv->grabbing>1)
+       if(btv->grabbing >= MAX_GBUFFERS)
                return -ENOBUFS;
        
        /*
@@ -1040,9 +1241,16 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
        if(mp->height <0 || mp->width <0)
                return -EINVAL;
        
+/*      This doesn´t work like this for NTSC anyway.
+        So, better check the total image size ...
+*/
+/*
        if(mp->height>576 || mp->width>768)
                return -EINVAL;
-
+*/
+       if (mp->height*mp->width*fmtbppx2[mp->format&0x0f]/2>BTTV_MAX_FBUF)
+               return -EINVAL;
        /*
         *      FIXME: Check the format of the grab here. This is probably
         *      also less restrictive than the normal overlay grabs. Stuff
@@ -1055,27 +1263,31 @@ static int vgrab(struct bttv *btv, struct video_mmap *mp)
         
        vbuf=(unsigned int *)(btv->fbuffer+BTTV_MAX_FBUF*mp->frame);
 /*     if (!(btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC))
-                return -EAGAIN; */
+                return -EAGAIN;*/
        ro=btv->grisc+(((btv->grabcount++)&1) ? 4096 :0);
        re=ro+2048;
        btv->gwidth=mp->width;
        btv->gheight=mp->height;
+
        if (mp->format > PALETTEFMT_MAX)
                return -EINVAL;
        btv->gfmt=palette2fmt[mp->format];
-       if(btv->gfmt==-1)
+       if(btv->gfmt==0)
                return -EINVAL;
                
        make_vrisctab(btv, ro, re, vbuf, btv->gwidth, btv->gheight, btv->gfmt);
        /* bt848_set_risc_jmps(btv); */
        btor(3, BT848_CAP_CTL);
        btor(3, BT848_GPIO_DMA_CTL);
+        btv->frame_stat[mp->frame] = GBUFFER_GRABBING;
         if (btv->grabbing) {
                btv->gro_next=virt_to_bus(ro);
                btv->gre_next=virt_to_bus(re);
+                btv->grf_next=mp->frame;
         } else {
                btv->gro=virt_to_bus(ro);
                btv->gre=virt_to_bus(re);
+                btv->grf=mp->frame;
         }
        if (!(btv->grabbing++)) 
                btv->risc_jmp[12]=BT848_RISC_JUMP|(0x8<<16)|BT848_RISC_IRQ;
@@ -1159,7 +1371,12 @@ static int bttv_open(struct video_device *dev, int flags)
                                btv->user--;
                                return -EINVAL;
                        }
-                       break;
+                        btv->grabbing = 0;
+                        btv->grab = 0;
+                        btv->lastgrab = 0;
+                        for (i = 0; i < MAX_GBUFFERS; i++)
+                               btv->frame_stat[i] = GBUFFER_UNUSED;
+                        break;
                case 1:
                        break;
        }
@@ -1227,265 +1444,6 @@ static inline void bt848_sat_v(struct bttv *btv, unsigned long data)
        btaor(datahi, ~1, BT848_O_CONTROL);
 }
 
-
-/*
- *     Cliprect -> risc table.
- *
- *     FIXME: This is generating wrong code when we have some kinds of
- *     rectangle lists. If you generate overlapped rectangles then it
- *     gets a bit confused. Since we add the frame buffer clip rectangles
- *     we need to fix this. Better yet to rewrite this function.
- */
-static void write_risc_data(struct bttv *btv, struct video_clip *vp, int count)
-{
-       int i;
-       u32 yy, y, x, dx, ox;
-       u32 *rmem, *rmem2;
-       struct video_clip first, *cur, *cur2, *nx, first2, *prev, *nx2;
-       u32 *rp, rpo=0, rpe=0, p, bpsl;
-       u32 *rpp;
-       u32 mask;
-       int interlace;
-       int depth;
-  
-       rmem=(u32 *)btv->risc_odd;
-       rmem2=(u32 *)btv->risc_even;
-       depth=btv->win.bpp;
-  
-       /* create y-sorted list  */
-       
-       first.next=NULL;
-       for (i=0; i<count; i++) 
-       {
-               cur=&first;
-               while ((nx=cur->next) && (vp[i].y > cur->next->y))
-                       cur=nx; 
-               cur->next=&(vp[i]);
-               vp[i].next=nx;
-       }
-       first2.next=NULL;
-       
-       rmem[rpo++]=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1|(0xf<<20);
-       rmem[rpo++]=0;
-
-       rmem2[rpe++]=BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1;
-       rmem2[rpe++]=0;
-
-
-       /*
-        *      32bit depth frame buffers need extra flags setting
-        */
-        
-       if (depth==4)
-               mask=BT848_RISC_BYTE3;
-       else
-               mask=0;
-               
-       bpsl=btv->win.width*btv->win.bpp;
-       p=btv->win.vidadr+btv->win.x*btv->win.bpp+
-               btv->win.y*btv->win.bpl;
-
-       interlace=btv->win.interlace;
-
-       /*
-        *      Loop through all lines 
-        */
-        
-       for (yy=0; yy<(btv->win.height<<(1^interlace)); yy++) 
-       {
-               y=yy>>(1^interlace);
-               
-               /*
-                *      Even or odd frame generation. We have to 
-                *      write the RISC instructions to the right stream.
-                */
-                
-               if(!(y&1))
-               {
-                       rp=&rpo;
-                       rpp=rmem;
-               }
-               else
-               {
-                       rp=&rpe;
-                       rpp=rmem2;
-               }
-               
-               
-               /*
-                *      first2 is the header of a list of "active" rectangles. We add
-                *      rectangles as we hit their top and remove them as they fall off
-                *      the bottom
-                */
-               
-                /* remove rects with y2 > y */
-               if ((cur=first2.next)) 
-               {
-                       prev=&first2;
-                       do 
-                       {
-                               if (cur->y+cur->height < y) 
-                                       prev->next=cur->next;
-                               else
-                                       prev=cur;
-                       }
-                       while ((cur=cur->next));
-               }
-
-               /*
-                *      Fixme - we have to handle overlapped rectangles
-                *      here, but the overlap might be partial
-                */
-                
-               /* add rect to second (x-sorted) list if rect.y == y  */
-               if ((cur=first.next)) 
-               {
-                       while ((cur) && (cur->y == y))
-                       { 
-                               first.next=cur->next;
-                               cur2=&first2;
-                               while ((nx2=cur2->next) && (cur->x > cur2->next->x)) 
-                                       cur2=nx2; 
-                               cur2->next=cur;
-                               cur->next=nx2;
-                               cur=first.next;
-                       }
-               }
-               
-               
-               /*
-                *      Begin writing the RISC script
-                */
-    
-               dx=x=0;
-               
-               /*
-                *      Starting at x position 0 on a new scan line
-                *      write to location p, don't yet write the number
-                *      of pixels for the instruction
-                */
-                
-               rpp[(*rp)++]=BT848_RISC_WRITE|BT848_RISC_SOL;
-               rpp[(*rp)++]=p;
-               
-               /*
-                *      For each rectangle we have in the "active" list - sorted left to
-                *      right..
-                */
-                
-               for (cur2=first2.next; cur2; cur2=cur2->next) 
-               {
-                       /*
-                        *      If we are to the left of the first drawing area
-                        */
-                        
-                       if (x+dx < cur2->x) 
-                       {
-                               /* Bytes pending ? */
-                               if (dx) 
-                               {
-                                       /* For a delta away from the start we need to write a SKIP */
-                                       if (x) 
-                                               rpp[(*rp)++]=BT848_RISC_SKIP|(dx*depth);
-                                       else
-                                       /* Rewrite the start of line WRITE to a SKIP */
-                                               rpp[(*rp)-2]|=BT848_RISC_BYTE_ALL|(dx*depth);
-                                       /* Move X to the next point (drawing start) */
-                                       x=x+dx;
-                               }
-                               /* Ok how far are we from the start of the next rectangle ? */
-                               dx=cur2->x-x;
-                               /* dx is now the size of data to write */
-                               
-                               /* If this isnt the left edge generate a "write continue" */
-                               if (x) 
-                                       rpp[(*rp)++]=BT848_RISC_WRITEC|(dx*depth)|mask;
-                               else
-                                       /* Fill in the byte count on the initial WRITE */
-                                       rpp[(*rp)-2]|=(dx*depth)|mask;
-                               /* Move to the start of the rectangle */
-                               x=cur2->x;
-                               /* x is our left dx is byte size of hole */
-                               dx=cur2->width+1;
-                       }
-                       else
-                       /* Already in a clip zone.. set dx */
-                               if (x+dx < cur2->x+cur2->width) 
-                                       dx=cur2->x+cur2->width-x+1;
-               }
-               /* now treat the rest of the line */
-               ox=x;
-               if (dx) 
-               {
-                       /* Complete the SKIP to eat to the end of the gap */
-                       if (x) 
-                               rpp[(*rp)++]=BT848_RISC_SKIP|(dx*depth);
-                       else
-                       /* Rewrite to SKIP start to this point */
-                               rpp[(*rp)-2]|=BT848_RISC_BYTE_ALL|(dx*depth);
-                       x=x+dx;
-               }
-               
-               /*
-                *      Not at the right hand edge ?
-                */
-                
-               if ((dx=btv->win.width-x)!=0) 
-               {
-                       /* Write to edge of display */
-                       if (x)
-                               rpp[(*rp)++]=BT848_RISC_WRITEC|(dx*depth)|BT848_RISC_EOL|mask;
-                       else
-                       /* Entire frame is a write - patch first order */
-                               rpp[(*rp)-2]|=(dx*depth)|BT848_RISC_EOL|mask;
-               }
-               else
-               {
-                       /* End of line if needed */
-                       if (ox)
-                               rpp[(*rp)-1]|=BT848_RISC_EOL|mask;
-                       else 
-                       {
-                               /* Skip the line : write a SKIP + start/end of line marks */
-                               (*rp)--;
-                               rpp[(*rp)-1]=BT848_RISC_SKIP|
-                                       (btv->win.width*depth)|
-                                         BT848_RISC_EOL|BT848_RISC_SOL;
-                       }
-               }
-               /*
-                *      Move the video render pointer on a line 
-                */
-               if (interlace||(y&1))
-                       p+=btv->win.bpl;
-       }
-       
-       /*
-        *      Attach the interframe jumps
-        */
-
-       rmem[rpo++]=BT848_RISC_JUMP; 
-       rmem[rpo++]=btv->bus_vbi_even;
-
-       rmem2[rpe++]=BT848_RISC_JUMP;
-       rmem2[rpe++]=btv->bus_vbi_odd;
-}
-
-/*
- *     Helper for adding clips.
- */
-
-static void new_risc_clip(struct video_window *vw, struct video_clip *vcp, int x, int y, int w, int h)
-{
-       vcp[vw->clipcount].x=x;
-       vcp[vw->clipcount].y=y;
-       vcp[vw->clipcount].width=w;
-       vcp[vw->clipcount].height=h;
-       vw->clipcount++;
-}
-
-
 /*
  *     ioctl routine
  */
@@ -1495,7 +1453,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
        unsigned char eedata[256];
        struct bttv *btv=(struct bttv *)dev;
-       static int lastchan=0;
+       int i;
        
        switch (cmd)
        {       
@@ -1510,8 +1468,8 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                VID_TYPE_CLIPPING|
                                VID_TYPE_FRAMERAM|
                                VID_TYPE_SCALES;
-                       b.channels = 4; /* tv  , input, svhs */
-                       b.audios = 4; /* tv, input, svhs */
+                       b.channels = tvcards[btv->type].inputs;
+                       b.audios = tvcards[btv->type].inputs;
                        b.maxwidth = 768;
                        b.maxheight = 576;
                        b.minwidth = 32;
@@ -1528,26 +1486,21 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        v.flags=VIDEO_VC_AUDIO;
                        v.tuners=0;
                        v.type=VIDEO_TYPE_CAMERA;
-                       switch(v.channel)
-                       {
-                               case 0:
-                                       strcpy(v.name,"Television");
-                                       v.flags|=VIDEO_VC_TUNER;
-                                       v.type=VIDEO_TYPE_TV;
-                                       v.tuners=1;
-                                       break;
-                               case 1:
-                                       strcpy(v.name,"Composite1");
-                                       break;
-                               case 2:
-                                       strcpy(v.name,"Composite2");
-                                       break;
-                               case 3:
-                                       strcpy(v.name,"SVHS");
-                                       break;
-                               default:
-                                       return -EINVAL;
-                       }
+                       v.norm = btv->win.norm;
+                        if (v.channel>=tvcards[btv->type].inputs)
+                                return -EINVAL;
+                        if(v.channel==tvcards[btv->type].tuner) 
+                        {
+                                strcpy(v.name,"Television");
+                                v.flags|=VIDEO_VC_TUNER;
+                                v.type=VIDEO_TYPE_TV;
+                                v.tuners=1;
+                        } 
+                        else if(v.channel==tvcards[btv->type].svhs) 
+                                strcpy(v.name,"SVHS");
+                        else
+                                sprintf(v.name,"Composite%d",v.channel);
+
                        if(copy_to_user(arg,&v,sizeof(v)))
                                return -EFAULT;
                        return 0;
@@ -1557,11 +1510,19 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                 */
                case VIDIOCSCHAN:
                {
-                       int v;
-                       if(copy_from_user(&v, arg, sizeof(v)))
+                       struct video_channel v;
+                       if(copy_from_user(&v, arg,sizeof(v)))
                                return -EFAULT;
-                       bt848_muxsel(btv, v);
-                       lastchan=v;
+                        
+                        if (v.channel>tvcards[btv->type].inputs)
+                                return -EINVAL;
+                       bt848_muxsel(btv, v.channel);
+                       if(v.norm!=VIDEO_MODE_PAL&&v.norm!=VIDEO_MODE_NTSC
+                          &&v.norm!=VIDEO_MODE_SECAM)
+                               return -EOPNOTSUPP;
+                       btv->win.norm = v.norm;
+                       bt848_set_winsize(btv);
+                       btv->channel=v.channel;
                        return 0;
                }
                case VIDIOCGTUNER:
@@ -1569,7 +1530,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        struct video_tuner v;
                        if(copy_from_user(&v,arg,sizeof(v))!=0)
                                return -EFAULT;
-                       if(v.tuner||lastchan)   /* Only tuner 0 */
+                       if(v.tuner||btv->channel)       /* Only tuner 0 */
                                return -EINVAL;
                        strcpy(v.name, "Television");
                        v.rangelow=0;
@@ -1581,23 +1542,22 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        return 0;
                }
-               /* We have but tuner 0 */
+               /* We have but one tuner */
                case VIDIOCSTUNER:
                {
                        struct video_tuner v;
                        if(copy_from_user(&v, arg, sizeof(v)))
                                return -EFAULT;
-                       /* Only channel 0 has a tuner */
-                       if(v.tuner!=0 || lastchan)
-                               return -EINVAL;
+
+                       /* Only one channel has a tuner */
+                        if(v.tuner!=tvcards[btv->type].tuner)
+                               return -EINVAL;
+                               
                        if(v.mode!=VIDEO_MODE_PAL&&v.mode!=VIDEO_MODE_NTSC
                           &&v.mode!=VIDEO_MODE_SECAM)
                                return -EOPNOTSUPP;
-                       /* FIXME: norm should be in video_channel struct 
-                          composite source can have different norms too
-                        */
-                       btv->win.norm = v.mode;
-                       bt848_set_winsize(btv);
+                       btv->win.norm = v.mode;
+                       bt848_set_winsize(btv);
                        return 0;
                }
                case VIDIOCGPICT:
@@ -1682,24 +1642,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -ENOMEM;
                        if(vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount))
                                return -EFAULT;
-                       /*
-                        *      Impose display clips
-                        */
-                       if(btv->win.x<0)
-                               new_risc_clip(&vw, vcp, 0, 0, -btv->win.x, btv->win.height-1);
-                       if(btv->win.y<0)
-                               new_risc_clip(&vw, vcp, 0, 0, btv->win.width-1,-btv->win.y);
-                       if(btv->win.x+btv->win.width> btv->win.swidth)
-                               new_risc_clip(&vw, vcp, btv->win.swidth-btv->win.x, 0, btv->win.width-1, btv->win.height-1);
-                       if(btv->win.y+btv->win.height > btv->win.sheight)
-                               new_risc_clip(&vw, vcp, 0, btv->win.sheight-btv->win.y, btv->win.width-1, btv->win.height-1);
-                       /*
-                        *      Question: Do we need to walk the clip list
-                        *      and saw off any clips outside the window 
-                        *      frame or will write_risc_tab do the right
-                        *      thing ?
-                        */
-                       write_risc_data(btv,vcp, vw.clipcount);
+                       make_clip_tab(btv,vcp, vw.clipcount);
                        vfree(vcp);
                        if(on && btv->win.vidadr!=0)
                                bt848_cap(btv,1);
@@ -1764,7 +1707,7 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        btv->win.vidadr=(unsigned long)v.base;
                        btv->win.sheight=v.height;
                        btv->win.swidth=v.width;
-                       btv->win.bpp=((v.depth+1)&0x38)/8;
+                       btv->win.bpp=((v.depth+7)&0x38)/8;
                        btv->win.depth=v.depth;
                        btv->win.bpl=v.bytesperline;
                        
@@ -1832,8 +1775,8 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        if(v.flags&VIDEO_AUDIO_MUTE)
                                audio(btv, AUDIO_MUTE);
-                       /* One audio source per tuner */
-                       if(v.audio!=0)
+                       /* One audio source per tuner */
+                       if(v.audio!=0)
                                return -EINVAL;
                        bt848_muxsel(btv,v.audio);
                        if(!(v.flags&VIDEO_AUDIO_MUTE))
@@ -1858,12 +1801,19 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                }
 
                case VIDIOCSYNC:
-                       if (!btv->grabbing)
-                               return -EAGAIN;
-                       if (btv->grab==btv->lastgrab)
-                               interruptible_sleep_on(&btv->capq);
-                       btv->lastgrab++;
-                       return 0;
+                       if(copy_from_user((void *)&i,arg,sizeof(int)))
+                               return -EFAULT;
+                        switch (btv->frame_stat[i]) {
+                        case GBUFFER_UNUSED:
+                                return -EINVAL;
+                        case GBUFFER_GRABBING:
+                               interruptible_sleep_on(&btv->capq);
+                                /* fall */
+                        case GBUFFER_DONE:
+                                btv->frame_stat[i] = GBUFFER_UNUSED;
+                                break;
+                        }
+                        return 0;
 
                case BTTV_WRITEE:
                        if(!capable(CAP_SYS_ADMIN))
@@ -1881,11 +1831,19 @@ static int bttv_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        break;
 
+               case BTTV_FIELDNR:
+                       if(copy_to_user((void *) arg, (void *) &btv->last_field, 
+                                        sizeof(btv->last_field)))
+                               return -EFAULT;
+                        break;
+
                case VIDIOCMCAPTURE:
                {
                         struct video_mmap vm;
                        if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm)))
                                return -EFAULT;
+                        if (btv->frame_stat[vm.frame] == GBUFFER_GRABBING)
+                                return -EBUSY;
                        return vgrab(btv, &vm);
                }
                
@@ -2127,21 +2085,34 @@ static long radio_read(struct video_device *v, char *buf, unsigned long count, i
 static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
 {
         struct bttv *btv=(struct bttv *)(dev-1);
-       static int lastchan=0;
        switch (cmd) {  
        case VIDIOCGCAP:
-               /* XXX */
+       {
+               struct video_capability v;
+               strcpy(v.name,btv->video_dev.name);
+               v.type = VID_TYPE_TUNER;
+               v.channels = 1;
+               v.audios = 1;
+               /* No we don't do pictures */
+               v.maxwidth = 0;
+               v.maxheight = 0;
+               v.minwidth = 0;
+               v.minheight = 0;
+               if (copy_to_user(arg, &v, sizeof(v)))
+                       return -EFAULT;
+               return 0;
                break;
+       }
        case VIDIOCGTUNER:
        {
                struct video_tuner v;
                if(copy_from_user(&v,arg,sizeof(v))!=0)
                        return -EFAULT;
-               if(v.tuner||lastchan)   /* Only tuner 0 */
+               if(v.tuner||btv->channel)       /* Only tuner 0 */
                        return -EINVAL;
                strcpy(v.name, "Radio");
                v.rangelow=(int)(87.5*16);
-               v.rangehigh=(int)(108.0*16);
+               v.rangehigh=(int)(108*16);
                v.flags= 0; /* XXX */
                v.mode = 0; /* XXX */
                if(copy_to_user(arg,&v,sizeof(v)))
@@ -2154,7 +2125,7 @@ static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                if(copy_from_user(&v, arg, sizeof(v)))
                        return -EFAULT;
                /* Only channel 0 has a tuner */
-               if(v.tuner!=0 || lastchan)
+               if(v.tuner!=0 || btv->channel)
                        return -EINVAL;
                /* XXX anything to do ??? */
                return 0;
@@ -2198,6 +2169,8 @@ struct vidbases
 };
 
 static struct vidbases vbs[] = {
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_215CT222,
+                "ATI MACH64 CT", PCI_BASE_ADDRESS_0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_210888GX,
                "ATI MACH64 Winturbo", PCI_BASE_ADDRESS_0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_215GT,
@@ -2214,8 +2187,12 @@ static struct vidbases vbs[] = {
        { PCI_VENDOR_ID_MATROX, 0x051a, "Matrox Mystique", PCI_BASE_ADDRESS_1},
        { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128, 
                "Number Nine Imagine 128", PCI_BASE_ADDRESS_0},
+       { PCI_VENDOR_ID_N9, PCI_DEVICE_ID_N9_I128_2, 
+               "Number Nine Imagine 128 Series 2", PCI_BASE_ADDRESS_0},
        { PCI_VENDOR_ID_S3, 0, "S3", PCI_BASE_ADDRESS_0},
        { PCI_VENDOR_ID_TSENG, 0, "TSENG", PCI_BASE_ADDRESS_0},
+       { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
+                "Riva128", PCI_BASE_ADDRESS_1},
 };
 
 
@@ -2409,13 +2386,16 @@ static void init_tda9850(struct i2c_bus *bus)
 
 /* Figure out card and tuner type */
 
-static void idcard(struct bttv *btv)
+static void idcard(int i)
 {
+        struct bttv *btv = &bttvs[i];
+
+       int tunertype;
        btwrite(0, BT848_GPIO_OUT_EN);
-       DEBUG(printk(KERN_DEBUG "bttv: GPIO: 0x%08x\n", btread(BT848_GPIO_DATA)));
+       DEBUG(printk(KERN_DEBUG "bttv%d: GPIO: 0x%08x\n", i, btread(BT848_GPIO_DATA)));
 
        /* Default the card to the user-selected one. */
-       btv->type=card;
+       btv->type=card[i];
         btv->tuner_type=-1; /* use default tuner type */
 
        /* If we were asked to auto-detect, then do so! 
@@ -2440,13 +2420,13 @@ static void idcard(struct bttv *btv)
         if (I2CRead(&(btv->i2c), I2C_TDA9850) >=0)
         {
                btv->audio_chip = TDA9850;
-               printk(KERN_INFO "bttv: audio chip: TDA9850\n");
+               printk(KERN_INFO "bttv%d: audio chip: TDA9850\n", i);
         }
 
         if (I2CRead(&(btv->i2c), I2C_TDA8425) >=0)
         {
             btv->audio_chip = TDA8425;
-            printk("bttv: audio chip: TDA8425\n");
+            printk("bttv%d: audio chip: TDA8425\n", i);
         }
         
         switch(btv->audio_chip)
@@ -2460,11 +2440,18 @@ static void idcard(struct bttv *btv)
         }
 
        /* How do I detect the tuner type for other cards but Miro ??? */
-       printk(KERN_INFO "bttv: model: ");
+       printk(KERN_INFO "bttv%d: model: ", btv->nr);
        switch (btv->type) 
        {
                case BTTV_MIRO:
                        printk("MIRO\n");
+                       if (btv->have_tuner) 
+                       {
+                               tunertype=((btread(BT848_GPIO_DATA)>>10)-1)&7;
+                               i2c_control_device(&(btv->i2c),
+                                                  I2C_DRIVERID_TUNER,
+                                                  TUNER_SET_TYPE,&tunertype);
+                       }
                        strcpy(btv->video_dev.name,"BT848(Miro)");
                        break;
                case BTTV_HAUPPAUGE:
@@ -2558,8 +2545,18 @@ static int init_bt848(int i)
 
        /* reset the bt848 */
        btwrite(0, BT848_SRESET);
-
-       DEBUG(printk(KERN_DEBUG "bttv: bt848_mem: 0x%08x\n",(unsigned int) btv->bt848_mem));
+       DEBUG(printk(KERN_DEBUG "bttv%d: bt848_mem: 0x%08x\n",i,(unsigned int) btv->bt848_mem));
+
+#ifdef RESET_MSP_HAUPPAUGE
+        /* Reset the MSP on some Hauppauge cards */
+        /* Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! */
+        /* Can this hurt cards without one? What about Miros with MSP? */
+        btaor(32, ~32, BT848_GPIO_OUT_EN);
+        btaor(0, ~32, BT848_GPIO_DATA);
+        udelay(2500);
+        btaor(32, ~32, BT848_GPIO_DATA);
+        btaor(0, ~32, BT848_GPIO_OUT_EN);
+#endif
 
        /* default setup for max. PAL size in a 1024xXXX hicolor framebuffer */
 
@@ -2591,6 +2588,7 @@ static int init_bt848(int i)
        btv->grabcount=0;
        btv->grab=0;
        btv->lastgrab=0;
+        btv->field=btv->last_field=0;
 
        /* i2c */
        memcpy(&(btv->i2c),&bttv_i2c_bus_template,sizeof(struct i2c_bus));
@@ -2642,8 +2640,8 @@ static int init_bt848(int i)
        btwrite(0xd8, BT848_CONTRAST_LO);
        bt848_bright(btv, 0x10);
 
-       btwrite(0x60, BT848_E_VSCALE_HI);
-       btwrite(0x60, BT848_O_VSCALE_HI);
+       btwrite(0x20, BT848_E_VSCALE_HI);
+       btwrite(0x20, BT848_O_VSCALE_HI);
        btwrite(/*BT848_ADC_SYNC_T|*/
                BT848_ADC_RESERVED|BT848_ADC_CRUSH, BT848_ADC);
 
@@ -2662,9 +2660,10 @@ static int init_bt848(int i)
        btwrite(0xfffffUL, BT848_INT_STAT);
         
        /* set interrupt mask */
-       btwrite(triton1|
-/*             BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
-               BT848_INT_FDSR|BT848_INT_FTRGT|BT848_INT_FBUS|*/
+       btwrite(btv->triton1|
+                /*BT848_INT_PABORT|BT848_INT_RIPERR|BT848_INT_PPERR|
+                  BT848_INT_FDSR|BT848_INT_FTRGT|BT848_INT_FBUS|*/
+                BT848_INT_VSYNC|
                BT848_INT_SCERR|
                BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
                BT848_INT_FMTCHG|BT848_INT_HLOCK,
@@ -2680,7 +2679,7 @@ static int init_bt848(int i)
        memcpy(&btv->video_dev,&bttv_template, sizeof(bttv_template));
        memcpy(&btv->vbi_dev,&vbi_template, sizeof(vbi_template));
        memcpy(&btv->radio_dev,&radio_template,sizeof(radio_template));
-       idcard(btv);
+       idcard(i);
 
        if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER)<0)
                return -1;
@@ -2689,7 +2688,7 @@ static int init_bt848(int i)
                video_unregister_device(&btv->video_dev);
                return -1;
        }
-       if (radio)
+       if (radio[i])
        {
                if(video_register_device(&btv->radio_dev, VFL_TYPE_RADIO)<0) 
                 {
@@ -2720,28 +2719,28 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                if (!astat)
                        return;
                btwrite(astat,BT848_INT_STAT);
-               IDEBUG(printk ("bttv: astat %08x\n",astat));
-               IDEBUG(printk ("bttv:  stat %08x\n",stat));
+               IDEBUG(printk ("bttv%d: astat %08x\n", btv->nr, astat));
+               IDEBUG(printk ("bttv%d:  stat %08x\n", btv->nr, stat));
 
                /* get device status bits */
                dstat=btread(BT848_DSTATUS);
     
                if (astat&BT848_INT_FMTCHG) 
                {
-                       IDEBUG(printk ("bttv: IRQ_FMTCHG\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_FMTCHG\n", btv->nr));
                        /*btv->win.norm&=
                          (dstat&BT848_DSTATUS_NUML) ? (~1) : (~0); */
                }
                if (astat&BT848_INT_VPRES) 
                {
-                       IDEBUG(printk ("bttv: IRQ_VPRES\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_VPRES\n", btv->nr));
                }
                if (astat&BT848_INT_VSYNC) 
                {
-                       IDEBUG(printk ("bttv: IRQ_VSYNC\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_VSYNC\n", btv->nr));
                }
                if (astat&BT848_INT_SCERR) {
-                       IDEBUG(printk ("bttv: IRQ_SCERR\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_SCERR\n", btv->nr));
                        bt848_dma(btv, 0);
                        bt848_dma(btv, 1);
                        wake_up_interruptible(&btv->vbiq);
@@ -2750,7 +2749,7 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                }
                if (astat&BT848_INT_RISCI) 
                {
-                       IDEBUG(printk ("bttv: IRQ_RISCI\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_RISCI\n", btv->nr));
 
                        /* captured VBI frame */
                        if (stat&(1<<28)) 
@@ -2763,10 +2762,14 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                        if (stat&(2<<28)) 
                        {
                                wake_up_interruptible(&btv->capq);
+                                btv->last_field=btv->field;
+                                btv->grab++;
+                                btv->frame_stat[btv->grf] = GBUFFER_DONE;
                                if ((--btv->grabbing))
                                {
                                        btv->gro = btv->gro_next;
                                        btv->gre = btv->gre_next;
+                                       btv->grf = btv->grf_next;
                                         btv->risc_jmp[5]=btv->gro;
                                        btv->risc_jmp[11]=btv->gre;
                                        bt848_set_geo(btv, btv->gwidth,
@@ -2792,31 +2795,31 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
                }
                if (astat&BT848_INT_OCERR) 
                {
-                       IDEBUG(printk ("bttv: IRQ_OCERR\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_OCERR\n", btv->nr));
                }
                if (astat&BT848_INT_PABORT) 
                {
-                       IDEBUG(printk ("bttv: IRQ_PABORT\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_PABORT\n", btv->nr));
                }
                if (astat&BT848_INT_RIPERR) 
                {
-                       IDEBUG(printk ("bttv: IRQ_RIPERR\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_RIPERR\n", btv->nr));
                }
                if (astat&BT848_INT_PPERR) 
                {
-                       IDEBUG(printk ("bttv: IRQ_PPERR\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_PPERR\n", btv->nr));
                }
                if (astat&BT848_INT_FDSR) 
                {
-                       IDEBUG(printk ("bttv: IRQ_FDSR\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_FDSR\n", btv->nr));
                }
                if (astat&BT848_INT_FTRGT) 
                {
-                       IDEBUG(printk ("bttv: IRQ_FTRGT\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_FTRGT\n", btv->nr));
                }
                if (astat&BT848_INT_FBUS) 
                {
-                       IDEBUG(printk ("bttv: IRQ_FBUS\n"));
+                       IDEBUG(printk ("bttv%d: IRQ_FBUS\n", btv->nr));
                }
                if (astat&BT848_INT_HLOCK) 
                {
@@ -2832,12 +2835,12 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
     
                count++;
                if (count > 10)
-                       printk (KERN_WARNING "bttv: irq loop %d\n", count);
+                       printk (KERN_WARNING "bttv%d: irq loop %d\n", btv->nr, count);
                if (count > 20) 
                {
                        btwrite(0, BT848_INT_MASK);
                        printk(KERN_ERR 
-                              "bttv: IRQ lockup, cleared int mask\n");
+                              "bttv%d: IRQ lockup, cleared int mask\n", btv->nr);
                }
        }
 }
@@ -2847,120 +2850,132 @@ static void bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
 /*
  *     Scan for a Bt848 card, request the irq and map the io memory 
  */
-static int find_bt848(void)
+
+int configure_bt848(struct pci_dev *dev, int bttv_num)
 {
-       unsigned char command, latency;
        int result;
+       unsigned char bus, devfn, command;
        struct bttv *btv;
-       struct pci_dev *dev;
 
-       bttv_num=0;
+        btv=&bttvs[bttv_num];
+        btv->dev=dev;
+        btv->nr = bttv_num;
+        btv->bus=bus=dev->bus->number;
+        btv->devfn=devfn=dev->devfn;
+        btv->bt848_mem=NULL;
+        btv->vbibuf=NULL;
+        btv->risc_jmp=NULL;
+        btv->vbi_odd=NULL;
+        btv->vbi_even=NULL;
+        btv->vbiq=NULL;
+        btv->capq=NULL;
+        btv->capqo=NULL;
+        btv->capqe=NULL;
+        btv->vbip=VBIBUF_SIZE;
+
+        btv->id=dev->device;
+        btv->irq=dev->irq;
+        btv->bt848_adr=dev->base_address[0];
+        if (btv->id >= 878)
+                btv->i2c_command = 0x83;                   
+        else
+                btv->i2c_command=(I2C_TIMING | BT848_I2C_SCL | BT848_I2C_SDA);
+
+        if (remap[bttv_num])
+        {
+                if (remap[bttv_num] < 0x1000)
+                        remap[bttv_num]<<=20;
+                remap[bttv_num]&=PCI_BASE_ADDRESS_MEM_MASK;
+                printk(KERN_INFO "bttv%d: remapping to : 0x%08x.\n",
+                       bttv_num,remap[bttv_num]);
+                remap[bttv_num]|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
+                pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, remap[bttv_num]);
+                pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &btv->bt848_adr);
+                btv->dev->base_address[0] = btv->bt848_adr;
+        }                                      
+        btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
+        pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
+        printk(KERN_INFO "bttv%d: Brooktree Bt%d (rev %d) ",
+               bttv_num,btv->id, btv->revision);
+        printk("bus: %d, devfn: %d, ",
+               btv->bus, btv->devfn);
+        printk("irq: %d, ",btv->irq);
+        printk("memory: 0x%08x.\n", btv->bt848_adr);
+        
+        btv->pll=0;
+        if(pll[btv->nr])
+                if (!(btv->id==848 && btv->revision==0x11))
+                {
+                        printk(KERN_INFO "bttv%d: internal PLL, single crystal operation enabled\n",bttv_num);
+                        btv->pll=1;
+                }
+        
+        btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
+        
+       /* clear interrupt mask */
+       btwrite(0, BT848_INT_MASK);
 
-       if (!pcibios_present()) 
-       {
-               DEBUG(printk(KERN_DEBUG "bttv: PCI-BIOS not present or not accessible!\n"));
-               return 0;
-       }
-       for (dev = pci_devices; dev != NULL; dev = dev->next) 
-       {
-               if (dev->vendor != PCI_VENDOR_ID_BROOKTREE)
-                       continue;
-               if (dev->device != PCI_DEVICE_ID_BT849 &&
-                       dev->device != PCI_DEVICE_ID_BT848)
-                       continue;
+        result = request_irq(btv->irq, bttv_irq,
+                             SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
+        if (result==-EINVAL) 
+        {
+                printk(KERN_ERR "bttv%d: Bad irq number or handler\n",
+                       bttv_num);
+                return -EINVAL;
+        }
+        if (result==-EBUSY)
+        {
+                printk(KERN_ERR "bttv%d: IRQ %d busy, change your PnP config in BIOS\n",bttv_num,btv->irq);
+                return result;
+        }
+        if (result < 0) 
+                return result;
+        
+        pci_set_master(dev);
 
-               /* Ok, Bt848 or Bt849 found! */
-               btv=&bttvs[bttv_num];
-               btv->dev=dev;
-               btv->bt848_mem=NULL;
-               btv->vbibuf=NULL;
-               btv->risc_jmp=NULL;
-               btv->vbi_odd=NULL;
-               btv->vbi_even=NULL;
-               btv->vbiq=NULL;
-               btv->capq=NULL;
-               btv->capqo=NULL;
-               btv->capqe=NULL;
-
-               btv->vbip=VBIBUF_SIZE;
-
-               pci_read_config_word (btv->dev, PCI_DEVICE_ID,      &btv->id);
-
-               /* pci_read_config_dword(btv->dev, PCI_BASE_ADDRESS_0, &btv->bt848_adr); */
-               btv->bt848_adr = btv->dev->base_address[0];
-    
-               if (remap&&(!bttv_num))
-               { 
-                       remap<<=20;
-                       remap&=PCI_BASE_ADDRESS_MEM_MASK;
-                       printk(KERN_INFO "Remapping to : 0x%08x.\n", remap);
-                       remap|=btv->bt848_adr&(~PCI_BASE_ADDRESS_MEM_MASK);
-                       pci_write_config_dword(btv->dev, PCI_BASE_ADDRESS_0, remap);
-                       pci_read_config_dword(btv->dev,  PCI_BASE_ADDRESS_0, &btv->bt848_adr);
-                       btv->dev->base_address[0] = btv->bt848_adr;
-               }                                       
-    
-               btv->bt848_adr&=PCI_BASE_ADDRESS_MEM_MASK;
-               pci_read_config_byte(btv->dev, PCI_CLASS_REVISION,
-                            &btv->revision);
-               printk(KERN_INFO "bttv: Brooktree Bt%d (rev %d) ",
-                       btv->id, btv->revision);
-               printk("bus: %d, devfn: %d, ",
-                       btv->dev->bus->number, btv->dev->devfn);
-               printk("irq: %d, ",btv->dev->irq);
-               printk("memory: 0x%08x.\n", btv->bt848_adr);
-    
-               btv->pll = 0;
-#ifdef USE_PLL
-                if (btv->id==849 || (btv->id==848 && btv->revision==0x12))
+        btv->triton1=triton1 ? BT848_INT_ETBF : 0;
+        if (triton1 && btv->id >= 878) 
+        {
+                btv->triton1 = 0;
+                printk("bttv: Enabling 430FX compatibilty for bt878\n");
+                pci_read_config_byte(dev, BT878_DEVCTRL, &command);
+                command|=BT878_EN_TBFX;
+                pci_write_config_byte(dev, BT878_DEVCTRL, command);
+                pci_read_config_byte(dev, BT878_DEVCTRL, &command);
+                if (!(command&BT878_EN_TBFX)) 
                 {
-                        printk(KERN_INFO "bttv: internal PLL, single crystal operation enabled.\n");
-                        btv->pll=1;
+                        printk("bttv: 430FX compatibility could not be enabled\n");
+                        return -1;
                 }
-#endif
-                
-               btv->bt848_mem=ioremap(btv->bt848_adr, 0x1000);
+        }
+        
+        return 0;
+}
 
-               result = request_irq(btv->dev->irq, bttv_irq,
-                       SA_SHIRQ | SA_INTERRUPT,"bttv",(void *)btv);
-               if (result==-EINVAL) 
-               {
-                       printk(KERN_ERR "bttv: Bad irq number or handler\n");
-                       return -EINVAL;
-               }
-               if (result==-EBUSY)
-               {
-                       printk(KERN_ERR "bttv: IRQ %d busy, change your PnP config in BIOS\n",btv->dev->irq);
-                       return result;
-               }
-               if (result < 0) 
-                       return result;
+static int find_bt848(void)
+{
+        struct pci_dev *dev = pci_devices;
+        int result=0;
 
-               /* Enable bus-mastering */
-               pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
-               command|=PCI_COMMAND_MASTER;
-               pci_write_config_byte(btv->dev, PCI_COMMAND, command);
-               pci_read_config_byte(btv->dev, PCI_COMMAND, &command);
-               if (!(command&PCI_COMMAND_MASTER)) 
-               {
-                       printk(KERN_ERR "bttv: PCI bus-mastering could not be enabled\n");
-                       return -1;
-               }
-               pci_read_config_byte(btv->dev, PCI_LATENCY_TIMER, &latency);
-               if (!latency) 
-               {
-                       latency=32;
-                       pci_write_config_byte(btv->dev, PCI_LATENCY_TIMER, latency);
-               }
-               DEBUG(printk(KERN_DEBUG "bttv: latency: %02x\n", latency));
-               bttv_num++;
-       }
+        bttv_num=0;
+
+        while (dev)
+        {
+                if (dev->vendor == PCI_VENDOR_ID_BROOKTREE)
+                        if ((dev->device == PCI_DEVICE_ID_BT848)||
+                            (dev->device == PCI_DEVICE_ID_BT849)||
+                            (dev->device == PCI_DEVICE_ID_BT878)||
+                            (dev->device == PCI_DEVICE_ID_BT879))
+                                result=configure_bt848(dev,bttv_num++);
+                if (result)
+                        return result;
+                dev = dev->next;
+        }
        if(bttv_num)
                printk(KERN_INFO "bttv: %d Bt848 card(s) found.\n", bttv_num);
        return bttv_num;
 }
-
 
 static void release_bttv(void)
 {
@@ -3009,7 +3024,7 @@ static void release_bttv(void)
                        vfree((void *) btv->vbibuf);
 
 
-               free_irq(btv->dev->irq,btv);
+               free_irq(btv->irq,btv);
                DEBUG(printk(KERN_DEBUG "bt848_mem: 0x%08x.\n", btv->bt848_mem));
                if (btv->bt848_mem)
                        iounmap(btv->bt848_mem);
index e1e21f595a84c6b60f21e4504408d5d6eddef709..83a0cecb6aee6ed639a80a2cd6b3f6e511cbd40f 100644 (file)
 #include <linux/videodev.h>
 
 #define MAX_CLIPRECS   100
+#define MAX_GBUFFERS   2
 #define RISCMEM_LEN    (32744*2)
-#define BTTV_MAX_FBUF  0x144000
-
-
-/* clipping rectangle */
-struct cliprec 
-{
-       int x, y, x2, y2;
-       struct cliprec *next;
-};
 
+/* maximum needed buffer size for extended VBI frame mode capturing */
+#define BTTV_MAX_FBUF  0x151000
 
 #ifdef __KERNEL__
 
@@ -75,9 +69,14 @@ struct bttv
        int have_msp3400;
        int have_tuner;
         int tuner_type;
-
+        int channel;
+        
+        unsigned int nr;
        unsigned short id;
+       unsigned char bus;          /* PCI bus the Bt848 is on */
+       unsigned char devfn;
        struct pci_dev *dev;
+       unsigned char irq;          /* IRQ used by Bt848 card */
        unsigned char revision;
        unsigned int bt848_adr;      /* bus address of IO mem returned by PCI BIOS */
        unsigned char *bt848_mem;   /* pointer to mapped IO memory */
@@ -106,24 +105,37 @@ struct bttv
        u32 *risc_odd;
        u32 *risc_even;
        int cap;
-       struct cliprec *cliprecs;
-       int ncr;                /* number of clipping rectangles */
+       struct video_clip *cliprecs;
 
        struct gbuffer *ogbuffers;
        struct gbuffer *egbuffers;
        u16 gwidth, gheight, gfmt;
        u32 *grisc;
+       
        unsigned long gro;
        unsigned long gre;
        unsigned long gro_next;
        unsigned long gre_next;
-       char *fbuffer;
+
+        int grf,grf_next;  /* frame numbers in grab queue */
+        int frame_stat[MAX_GBUFFERS];
+#define GBUFFER_UNUSED       0
+#define GBUFFER_GRABBING     1
+#define GBUFFER_DONE         2
+
+        char *fbuffer;
        int gmode;
        int grabbing;
        int lastgrab;
        int grab;
        int grabcount;
+
        int pll;
+       unsigned int Fsc;
+       unsigned int field;
+       unsigned int last_field; /* number of last grabbed field */
+       int i2c_command;
+       int triton1;
 };
 
 #endif
@@ -148,6 +160,7 @@ struct bttv
 #define BTTV_READEE            _IOW('v',  BASE_VIDIOCPRIVATE+0, char [256])
 #define BTTV_WRITEE            _IOR('v',  BASE_VIDIOCPRIVATE+1, char [256])
 #define BTTV_GRAB              _IOR('v' , BASE_VIDIOCPRIVATE+2, struct gbuf)
+#define BTTV_FIELDNR           _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int)
 
 
 #define BTTV_UNKNOWN       0x00
@@ -186,7 +199,6 @@ struct bttv
 #define TDA9850_ALI2       0x09
 #define TDA9850_ALI3       0x0a
 
-
 #define TDA8425_VL         0x00
 #define TDA8425_VR         0x01
 #define TDA8425_BA         0x02
index f86a73e9e00a65b1a06bcc26b24e0df6f10bb832..34651f9e9a0082a1b3411ce8d3151677aa7b51b8 100644 (file)
@@ -238,6 +238,7 @@ struct file_operations bus_mouse_fops = {
        NULL,           /* mouse_ioctl */
        NULL,           /* mouse_mmap */
        open_mouse,
+       NULL,           /* flush */
        close_mouse,
        NULL,
        fasync_mouse,
index 97621982540e8be0cbc6d937a37054a7fc617c7e..efd4854ceddf951e6d4a2e65668033bdc6647403 100644 (file)
@@ -1,7 +1,7 @@
 #define BLOCKMOVE
 #define        Z_WAKE
 static char rcsid[] =
-"$Revision: 2.2.1.5 $$Date: 1998/08/10 18:10:28 $";
+"$Revision: 2.2.1.6 $$Date: 1998/08/20 17:15:39 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -31,6 +31,11 @@ static char rcsid[] =
  *   void cleanup_module(void);
  *
  * $Log: cyclades.c,v $
+ * Revision 2.2.1.6  1998/08/20 17:15:39 ivan
+ * Fixed bug in cy_close function, which causes malfunction
+ * of one of the first 4 ports when a higher port is closed
+ * (Cyclom-Y only).
+ *
  * Revision 2.2.1.5  1998/08/10 18:10:28 ivan
  * Fixed Cyclom-4Yo hardware detection bug.
  *
@@ -2679,9 +2684,11 @@ cy_close(struct tty_struct * tty, struct file * filp)
     }
 
     if (!IS_CYC_Z(cy_card[info->card])) {
-       unsigned char *base_addr = (unsigned char *) 
-                                       cy_card[info->card].base_addr;
+       int channel = info->line - cy_card[info->card].first_line;
        int index = cy_card[info->card].bus_index;
+       unsigned char *base_addr = (unsigned char *)
+                       (cy_card[info->card].base_addr +
+                        (cy_chip_offset[channel>>2] <<index));
        /* Stop accepting input */
        cy_writeb((u_long)base_addr+(CySRER<<index),
                        cy_readb(base_addr+(CySRER<<index)) & ~CyRxData);
index 5fb05738fc8b8f63be75ade0efecf4598f6a0f38..02436b8f2c5b44fe0cdbb66b492639f21cc0eb8e 100644 (file)
@@ -560,6 +560,7 @@ struct file_operations apollo_mouse_fops = {
         NULL,           /* mouse_ioctl */
         NULL,           /* mouse_mmap */
         open_mouse,
+       NULL,           /* flush */
         release_mouse,
         NULL,
         fasync_mouse,
index 7818e8da319e35a827d039b1ba2a2d5d2d7e2816..c9c22f6952cd4f20dd8d7855aca3ca81ab42ebb8 100644 (file)
@@ -510,6 +510,7 @@ static struct file_operations dsp56k_fops = {
        dsp56k_ioctl,
        NULL,    /* no special dsp56k_mmap */
        dsp56k_open,
+       NULL,   /* flush */
        dsp56k_release,
        NULL,    /* no special dsp56k_fsync */
        NULL,    /* no special dsp56k_fasync */
index 8f8612b35ec4e4df44655432607c79747c93d50d..e1c11404043dd73596aaccee338105e83f27e684 100644 (file)
@@ -468,6 +468,7 @@ static struct file_operations fb_fops = {
        fb_ioctl,       /* ioctl        */
        fb_mmap,        /* mmap         */
        fb_open,        /* open         */
+       NULL,           /* flush        */
        fb_release,     /* release      */
        NULL            /* fsync        */
 };
index ebb6a3f04041cc46b3e1d95fe74728b9854edd44..ee21d92d405ab07f747c374c4ed17c91a0d1dade 100644 (file)
@@ -94,6 +94,7 @@ static struct file_operations ftape_proc_fops =
        NULL,                   /* ioctl   */
        NULL,                   /* mmap    */
        NULL,                   /* no special open code    */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL,                   /* can't fsync */
 };
index 78a857ace7373b2f586fc1a91ab4b8c62eb854db..1b50349391ec22585e893a72dc4ef0b76e4b5d77 100644 (file)
@@ -134,6 +134,7 @@ static struct file_operations zft_cdev =
        zft_ioctl,              /* ioctl */
        zft_mmap,               /* mmap */
        zft_open,               /* open */
+       NULL,                   /* flush */
        zft_close,              /* release */
        NULL,                   /* fsync */
 };
index 2876982986d21bb44536d6d6f2262d9fc992e5bb..c76aeb79b8f3d5eac6c752cb49ec9d2b155cce8d 100644 (file)
@@ -113,6 +113,7 @@ static struct file_operations h8_fops = {
         NULL,
         NULL,           /* mmap */
         NULL,
+       NULL,           /* flush */
         NULL,
         NULL,           /* fsync */
         NULL            /* fasync */
index a0fc34463e02af2fd400193137056e16983a8972..de5ed5cc2e58e2a55d0961b37e60f4a0cf5c4a76 100644 (file)
@@ -565,6 +565,7 @@ static struct file_operations hfmodem_fops = {
        hfmodem_ioctl,      /* hfmodem_ioctl */
        NULL,               /* hfmodem_mmap */
        hfmodem_open,       /* hfmodem_open */
+       NULL,               /* flush */
        hfmodem_close,      /* hfmodem_close */
        NULL,               /* hfmodem_fsync */
        NULL,               /* hfmodem_fasync */
index 1036f104629b2dac89e47b9baf863560bff239b1..6aada68785ce985a1903c556d866067442b9195f 100644 (file)
@@ -714,6 +714,7 @@ static struct file_operations lp_fops = {
        lp_ioctl,
        NULL,           /* lp_mmap */
        lp_open,
+       NULL,           /* flush */
        lp_release
 };
 
index 5079b2e628f5fb5c63826564bcba5ec9000d5f52..dc0300751dcbecf246fbd56dd1a61fab6e91cb2a 100644 (file)
@@ -467,6 +467,7 @@ static struct file_operations lp_fops = {
        lp_ioctl,
        NULL,           /* lp_mmap */
        lp_open,
+       NULL,           /* flush */
        lp_release
 };
 
index e14c235cf5002d1811f66ab1deeadfcdcb3e0bc1..b9236bb9375ef8815712b2251d89f8daee84964a 100644 (file)
@@ -242,6 +242,7 @@ struct file_operations mac_mouse_fops = {
     NULL,              /* mouse_ioctl */
     NULL,              /* mouse_mmap */
     open_mouse,
+    NULL,              /* flush */
     release_mouse,
     NULL,
     fasync_mouse,
index e2bae2c53b0977aa613a327a6dd07617a519c43a..fac10176b75c6dbeeacac4fd2e039c64eb11c0e6 100644 (file)
@@ -415,6 +415,7 @@ static struct file_operations mem_fops = {
        NULL,           /* mem_ioctl */
        mmap_mem,
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* fsync */
 };
@@ -428,6 +429,7 @@ static struct file_operations kmem_fops = {
        NULL,           /* kmem_ioctl */
        mmap_kmem,
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* fsync */
 };
@@ -441,6 +443,7 @@ static struct file_operations null_fops = {
        NULL,           /* null_ioctl */
        NULL,           /* null_mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* fsync */
 };
@@ -454,6 +457,7 @@ static struct file_operations port_fops = {
        NULL,           /* port_ioctl */
        NULL,           /* port_mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* fsync */
 };
@@ -467,6 +471,7 @@ static struct file_operations zero_fops = {
        NULL,           /* zero_ioctl */
        mmap_zero,
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL            /* no special release code */
 };
 
@@ -479,6 +484,7 @@ static struct file_operations full_fops = {
        NULL,           /* full_ioctl */        
        NULL,           /* full_mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL            /* no special release code */
 };
 
@@ -526,6 +532,7 @@ static struct file_operations memory_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        memory_open,    /* just a selector for the real open */
+       NULL,           /* flush */
        NULL,           /* release */
        NULL            /* fsync */
 };
index 4e11a3fbd5baa7f05893f6f759aa116546539a39..054df01cbac06ca5f98f044485b6573a0c428634 100644 (file)
@@ -139,6 +139,7 @@ static struct file_operations misc_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
         misc_open,
+       NULL,           /* flush */
         NULL           /* release */
 };
 
index 6937597738e6853f811ac1d34d42f5966a736e30..b49bfe9a6208f77a9c6bd2478f0daa7fcba024e9 100644 (file)
@@ -174,6 +174,7 @@ struct file_operations ms_bus_mouse_fops = {
        NULL,           /* mouse_ioctl */
        NULL,           /* mouse_mmap */
        open_mouse,
+       NULL,           /* flush */
        release_mouse,
        NULL,
        fasync_mouse,
index 1cf7e9d018cfb5cad35cbc59a76a84c42df9538d..07272723d90a3c6acde3fbd35e7bdb521cfa5da0 100644 (file)
@@ -842,22 +842,25 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
  * buffer, and once to drain the space from the (physical) beginning of
  * the buffer to head pointer.
  */
-static inline void copy_from_read_buf(struct tty_struct *tty,
+static inline int copy_from_read_buf(struct tty_struct *tty,
                                      unsigned char **b,
                                      size_t *nr)
 
 {
+       int retval;
        ssize_t n;
 
+       retval = 0;
        n = MIN(*nr, MIN(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail));
-       if (!n)
-               return;
-       /* N.B. copy_to_user may work only partially */
-       n -= copy_to_user(*b, &tty->read_buf[tty->read_tail], n);
-       tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1);
-       tty->read_cnt -= n;
-       *b += n;
-       *nr -= n;
+       if (n) {
+               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);
+               tty->read_cnt -= n;
+               *b += n;
+               *nr -= n;
+       }
+       return retval;
 }
 
 static ssize_t read_chan(struct tty_struct *tty, struct file *file,
@@ -996,9 +999,13 @@ do_it_again:
                                }
                        }
                } else {
-                       /* N.B. check for errors writing to user space? */
-                       copy_from_read_buf(tty, &b, &nr);
-                       copy_from_read_buf(tty, &b, &nr);
+                       int uncopied;
+                       uncopied = copy_from_read_buf(tty, &b, &nr);
+                       uncopied += copy_from_read_buf(tty, &b, &nr);
+                       if (uncopied) {
+                               retval = -EFAULT;
+                               break;
+                       }
                }
 
                /* If there is enough space in the read buffer now, let the
index a3353f4afab3628410b4288f325efba13084acfd..11e7eadcf883542633a44c3761b9627642193db5 100644 (file)
@@ -402,6 +402,7 @@ static struct file_operations nvram_fops = {
        nvram_ioctl,
        NULL,                   /* No mmap */
        nvram_open,
+       NULL,                   /* flush */
        nvram_release
 };
 
index 3921235e2976afe7cdacab8405ecf4029b327709..ea6d706cb9c93ba86e8e4ccfb346388d668a3ee8 100644 (file)
@@ -626,6 +626,7 @@ static struct file_operations pad_fops = {
        pad_ioctl,
        NULL,           /* pad_mmap */
        open_pad,
+       NULL,           /* flush */
        close_pad,
        NULL,           /* fsync */
        fasync_pad,
index 4bd0f0f290aef89db0d972addd159b6a502b6dfb..ded35916ced647ac0ab173979f9520d8f62bffd3 100644 (file)
@@ -515,6 +515,7 @@ static struct file_operations pcwd_fops = {
        pcwd_ioctl,     /* IOctl */
        NULL,           /* MMAP */
        pcwd_open,      /* Open */
+       NULL,           /* flush */
        pcwd_close,     /* Release */
        NULL,           /* Fsync */
        NULL,           /* Fasync */
index 50c0b63c44afe5361980e544a9a5693cde199e8b..e4a54097bcecc79a31f6312319c839609a46c52f 100644 (file)
@@ -582,6 +582,7 @@ struct file_operations psaux_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        open_aux,
+       NULL,           /* flush */
        release_aux,
        NULL,
        fasync_aux,
index 08fc6116d0239fd9104c3c56ba4f6d6bb9e91723..59d95042ee86c4efe4684761717f55832118dc5c 100644 (file)
@@ -216,6 +216,7 @@ static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        v.maxheight=0;
                        v.minwidth=0;
                        v.minheight=0;
+                       strcpy(v.name, "RadioTrack");
                        if(copy_to_user(arg,&v,sizeof(v)))
                                return -EFAULT;
                        return 0;
index caaa60c7c9646c9a72c8b71d2615df4206cafa57..39d56a86fcf465f660af25a748af22ab92443941 100644 (file)
@@ -167,6 +167,7 @@ static int az_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        v.maxheight=0;
                        v.minwidth=0;
                        v.minheight=0;
+                       strcpy(v.name, "Aztech Radio");
                        if(copy_to_user(arg,&v,sizeof(v)))
                                return -EFAULT;
                        return 0;
diff --git a/drivers/char/radio-miropcm20.c b/drivers/char/radio-miropcm20.c
new file mode 100644 (file)
index 0000000..ffc1d19
--- /dev/null
@@ -0,0 +1,245 @@
+/* Miro PCM20 radio driver for Linux radio support
+ * (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ * Thanks to Norberto Pellici for the ACI device interface specification
+ * The API part is based on the radiotrack driver by M. Kirkwood
+ * This driver relies on the aci mixer (drivers/sound/lowlevel/aci.c)
+ * Look there for further info...
+ */
+
+#include <linux/module.h>              /* Modules                      */
+#include <linux/init.h>                        /* Initdata                     */
+#include <asm/uaccess.h>               /* copy to/from user            */
+#include <linux/videodev.h>            /* kernel radio structs         */
+#include <linux/config.h>              /* CONFIG_RADIO_MIROPCM20       */
+#include "../sound/lowlevel/miroaci.h" /* ACI Control by acimixer      */
+
+static int users = 0;
+
+struct pcm20_device
+{
+       int port;
+       int curvol;
+       unsigned long curfreq;
+       int muted;
+};
+
+
+/* local things */
+
+
+static void pcm20_mute(struct pcm20_device *dev)
+{
+
+       dev->muted = 1;
+       aci_write_cmd(0xa3,0x01);                       
+
+}
+
+static int pcm20_setvol(struct pcm20_device *dev, int vol)
+{
+
+       if(vol == dev->curvol) {        /* requested volume = current */
+               if (dev->muted) {       /* user is unmuting the card  */
+                       dev->muted = 0;
+                       aci_write_cmd(0xa3,0x00);       /* enable card */
+               }       
+       
+               return 0;
+       }
+
+       if(vol == 0) {                  /* volume = 0 means mute the card */
+               aci_write_cmd(0x3d, 0x20);
+               aci_write_cmd(0x35, 0x20);
+               return 0;
+       }
+
+       dev->muted = 0;
+       aci_write_cmd(0x3d, 32-vol);    /* Right Channel */
+       aci_write_cmd(0x35, 32-vol);    /* Left Channel */
+       dev->curvol = vol;
+
+       return 0;
+}
+
+static int pcm20_setfreq(struct pcm20_device *dev, unsigned long freq)
+{
+       unsigned char freql;
+       unsigned char freqh;
+
+       freq = (freq * 10) / 16;
+       freql = freq & 0xff;
+       freqh = freq >> 8;      
+
+
+       aci_write_cmd_d(0xa7, freql, freqh);    /*  Tune to frequency   */
+
+       return 0;
+}
+
+int pcm20_getsigstr(struct pcm20_device *dev)
+{
+       unsigned char buf;
+       aci_indexed_cmd(0xf0, 0x32, &buf);
+       if ((buf & 0x80) == 0x80)       
+               return 0;
+       return 1;               /* signal present               */
+}
+
+static int pcm20_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+       struct pcm20_device *pcm20=dev->priv;
+       
+       switch(cmd)
+       {
+               case VIDIOCGCAP:
+               {
+                       struct video_capability v;
+                       v.type=VID_TYPE_TUNER;
+                       strcpy(v.name, "Miro PCM20");
+                       v.channels=1;
+                       v.audios=1;
+                       /* No we don't do pictures */
+                       v.maxwidth=0;
+                       v.maxheight=0;
+                       v.minwidth=0;
+                       v.minheight=0;
+                       if(copy_to_user(arg,&v,sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCGTUNER:
+               {
+                       struct video_tuner v;
+                       if(copy_from_user(&v, arg,sizeof(v))!=0) 
+                               return -EFAULT;
+                       if(v.tuner)     /* Only 1 tuner */ 
+                               return -EINVAL;
+                       v.rangelow=(int)(87.5*16);
+                       v.rangehigh=(int)(108.0*16);
+                       v.flags=0;
+                       v.mode=VIDEO_MODE_AUTO;
+                       v.signal=0xFFFF*pcm20_getsigstr(pcm20);
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCSTUNER:
+               {
+                       struct video_tuner v;
+                       if(copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       if(v.tuner!=0)
+                               return -EINVAL;
+                       /* Only 1 tuner so no setting needed ! */
+                       return 0;
+               }
+               case VIDIOCGFREQ:
+                       if(copy_to_user(arg, &pcm20->curfreq, sizeof(pcm20->curfreq)))
+                               return -EFAULT;
+                       return 0;
+               case VIDIOCSFREQ:
+                       if(copy_from_user(&pcm20->curfreq, arg,sizeof(pcm20->curfreq)))
+                               return -EFAULT;
+                       pcm20_setfreq(pcm20, pcm20->curfreq);
+                       return 0;
+               case VIDIOCGAUDIO:
+               {       
+                       struct video_audio v;
+                       memset(&v,0, sizeof(v));
+                       v.flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME;
+                       v.volume=pcm20->curvol * 2048;
+                       strcpy(v.name, "Radio");
+                       if(copy_to_user(arg,&v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;                       
+               }
+               case VIDIOCSAUDIO:
+               {
+                       struct video_audio v;
+                       if(copy_from_user(&v, arg, sizeof(v))) 
+                               return -EFAULT; 
+                       if(v.audio) 
+                               return -EINVAL;
+
+                       if(v.flags&VIDEO_AUDIO_MUTE) 
+                               pcm20_mute(pcm20);
+                       else
+                               pcm20_setvol(pcm20,v.volume/2048);      
+
+                       return 0;
+               }
+               default:
+                       return -ENOIOCTLCMD;
+       }
+}
+
+static int pcm20_open(struct video_device *dev, int flags)
+{
+       if(users)
+               return -EBUSY;
+       users++;
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static void pcm20_close(struct video_device *dev)
+{
+       users--;
+       MOD_DEC_USE_COUNT;
+}
+
+static struct pcm20_device pcm20_unit;
+
+static struct video_device pcm20_radio=
+{
+       "Miro PCM 20 radio",
+       VID_TYPE_TUNER,
+       VID_HARDWARE_RTRACK,
+       pcm20_open,
+       pcm20_close,
+       NULL,   /* Can't read  (no capture ability) */
+       NULL,   /* Can't write */
+       NULL,   /* Can't poll */
+       pcm20_ioctl,
+       NULL,
+       NULL
+};
+
+__initfunc(int pcm20_init(struct video_init *v))
+{
+
+       pcm20_radio.priv=&pcm20_unit;
+       
+       if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO)==-1)
+               return -EINVAL;
+               
+       printk(KERN_INFO "Miro PCM20 radio card driver.\n");
+
+       /* mute card - prevents noisy bootups */
+
+       /* this ensures that the volume is all the way down  */
+
+       pcm20_unit.curvol = 0;
+
+       return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Ruurd Reitsma");
+MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
+
+EXPORT_NO_SYMBOLS;
+
+int init_module(void)
+{
+
+       return pcm20_init(NULL); 
+}
+
+void cleanup_module(void)
+{
+       video_unregister_device(&pcm20_radio);
+}
+
+#endif
index c035efe293e31fb4affca278466591e7c5f94529..175c665f7bba7f983b8f7e6c6037002ef687b2b5 100644 (file)
@@ -113,6 +113,7 @@ static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        v.maxheight=0;
                        v.minwidth=0;
                        v.minheight=0;
+                       strcpy(v.name, "RadioTrack II");
                        if(copy_to_user(arg,&v,sizeof(v)))
                                return -EFAULT;
                        return 0;
index d8dee777d62e3087d65bc8d891aa613a6316d21f..192fa5236f536937352fbf662891d6e76bacd175 100644 (file)
 #include <linux/videodev.h>    /* kernel radio structs         */
 #include <linux/config.h>      /* CONFIG_RADIO_SF16MI_PORT     */
 
-#include "rsf16fmi.h"
-
 struct fmi_device
 {
        int port;
-       int curvol;
-       unsigned long curfreq;
-       int flags;
+        int curvol; /* 1 or 0 */
+        unsigned long curfreq; /* RSF16_PREC * freq in MHz */
+        __u32 flags;
 };
 
 #ifndef CONFIG_RADIO_SF16FMI_PORT
@@ -39,11 +37,16 @@ struct fmi_device
 static int io = CONFIG_RADIO_SF16FMI_PORT; 
 static int users = 0;
 
-/* local things */
-/* freq in 1/16kHz to internal number */
-#define RSF16_ENCODE(x)        ((x/16+10700)/50)
+/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
+/* It is only usefull to give freq in intervall of 800 (=0.05Mhz),
+ * other bits will be truncated, e.g 92.7400016 -> 92.7, but 
+ * 92.7400017 -> 92.75
+ */
+#define RSF16_ENCODE(x)        ((x)/800+214)
+#define RSF16_MINFREQ 88*16000
+#define RSF16_MAXFREQ 108*16000
 
-static void outbits(int bits, int data, int port)
+static void outbits(int bits, unsigned int data, int port)
 {
        while(bits--) {
                if(data & 1) {
@@ -73,7 +76,7 @@ static void fmi_unmute(int port)
 
 static int fmi_setfreq(struct fmi_device *dev, unsigned long freq)
 {
-       int myport = dev->port;
+        int myport = dev->port;
 
        outbits(16, RSF16_ENCODE(freq), myport);
        outbits(8, 0xC0, myport);
@@ -105,6 +108,7 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                case VIDIOCGCAP:
                {
                        struct video_capability v;
+                       strcpy(v.name, "SF16-FMx radio");
                        v.type=VID_TYPE_TUNER;
                        v.channels=1;
                        v.audios=1;
@@ -120,17 +124,16 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                case VIDIOCGTUNER:
                {
                        struct video_tuner v;
+                       int mult;
+
                        if(copy_from_user(&v, arg,sizeof(v))!=0)
                                return -EFAULT;
                        if(v.tuner)     /* Only 1 tuner */
                                return -EINVAL;
-                       if (fmi->flags & VIDEO_TUNER_LOW) {
-                               v.rangelow = 87500 * 16;
-                               v.rangehigh = 108000 * 16;
-                       } else {
-                               v.rangelow=(int)(175*8 /* 87.5 *16 */);
-                               v.rangehigh=(int)(108*16);
-                       }
+                       strcpy(v.name, "FM");
+                       mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000;
+                       v.rangelow = RSF16_MINFREQ/mult;
+                       v.rangehigh = RSF16_MAXFREQ/mult;
                        v.flags=fmi->flags;
                        v.mode=VIDEO_MODE_AUTO;
                        v.signal=0xFFFF*fmi_getsigstr(fmi);
@@ -165,6 +168,8 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        if (!(fmi->flags & VIDEO_TUNER_LOW))
                                tmp *= 1000;
+                       if ( tmp<RSF16_MINFREQ || tmp>RSF16_MAXFREQ )
+                         return -EINVAL;
                        fmi->curfreq = tmp;
                        fmi_setfreq(fmi, fmi->curfreq);
                        return 0;
@@ -172,12 +177,15 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                case VIDIOCGAUDIO:
                {       
                        struct video_audio v;
-                       memset(&v,0, sizeof(v));
-                       v.flags|=VIDEO_AUDIO_MUTABLE;
-                       v.mode=VIDEO_SOUND_MONO;
-                       v.volume=fmi->curvol;
-                       v.step=65535;
+                       v.audio=0;
+                       v.volume=0;
+                       v.bass=0;
+                       v.treble=0;
+                       v.flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
                        strcpy(v.name, "Radio");
+                       v.mode=VIDEO_SOUND_MONO;
+                       v.balance=0;
+                       v.step=0; /* No volume, just (un)mute */
                        if(copy_to_user(arg,&v, sizeof(v)))
                                return -EFAULT;
                        return 0;                       
@@ -189,15 +197,23 @@ static int fmi_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                                return -EFAULT;
                        if(v.audio)
                                return -EINVAL;
-                       fmi->curvol=v.volume;
-                       if(v.flags&VIDEO_AUDIO_MUTE)
-                               fmi_mute(fmi->port);
-                       else if(fmi->curvol)
-                               fmi_unmute(fmi->port);
-                       else
-                               fmi_mute(fmi->port);
+                       fmi->curvol= v.flags&VIDEO_AUDIO_MUTE ? 0 : 1;
+                       fmi->curvol ? 
+                         fmi_unmute(fmi->port) : fmi_mute(fmi->port);
                        return 0;
                }
+               case VIDIOCGUNIT:
+               {
+                               struct video_unit v;
+                       v.video=VIDEO_NO_UNIT;
+                       v.vbi=VIDEO_NO_UNIT;
+                       v.radio=dev->minor;
+                       v.audio=0; /* How do we find out this??? */
+                       v.teletext=VIDEO_NO_UNIT;
+                       if(copy_to_user(arg, &v, sizeof(v)))
+                               return -EFAULT;
+                       return 0;                       
+               }
                default:
                        return -ENOIOCTLCMD;
        }
@@ -222,7 +238,7 @@ static struct fmi_device fmi_unit;
 
 static struct video_device fmi_radio=
 {
-       "SF16FMI radio",
+       "SF16FMx radio",
        VID_TYPE_TUNER,
        VID_HARDWARE_SF16MI,
        fmi_open,
@@ -243,15 +259,17 @@ __initfunc(int fmi_init(struct video_init *v))
                return -EBUSY;
        }
 
-       fmi_unit.port=io;
+       fmi_unit.port = io;
+       fmi_unit.curvol = 0;
+       fmi_unit.curfreq = 0;
        fmi_unit.flags = VIDEO_TUNER_LOW;
-       fmi_radio.priv=&fmi_unit;
+       fmi_radio.priv = &fmi_unit;
        
        if(video_register_device(&fmi_radio, VFL_TYPE_RADIO)==-1)
                return -EINVAL;
                
        request_region(io, 2, "fmi");
-       printk(KERN_INFO "SF16FMI radio card driver.\n");
+       printk(KERN_INFO "SF16FMx radio card driver at 0x%x.\n", io);
        printk(KERN_INFO "(c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz.\n");
        /* mute card - prevents noisy bootups */
        fmi_mute(io);
index 8c28247b999acadb201d0ff7ed307fb255d284d4..115606ac33127eaf986b31b97867744a91723c13 100644 (file)
@@ -176,6 +176,7 @@ static int zol_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
                        v.maxheight = 0;
                        v.minwidth = 0;
                        v.minheight = 0;
+                       strcpy(v.name, "Zoltrix Radio");
                        if (copy_to_user(arg, &v, sizeof(v)))
                                return -EFAULT;
                        return 0;
index b7ed4e10b0ea537990763cfc24d3c2b6efbe8a40..5db97f906d35648fad5a2787828ae626ec8f2bbe 100644 (file)
@@ -1526,6 +1526,7 @@ struct file_operations random_fops = {
        random_ioctl,
        NULL,           /* random_mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL            /* no special release code */
 };
 
@@ -1538,6 +1539,7 @@ struct file_operations urandom_fops = {
        random_ioctl,
        NULL,           /* urandom_mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL            /* no special release code */
 };
 
index 1a0079531498c2c14f1cf466dc879a1589926a4c..c5b326083d29e3f13bc45f8ee753bcb85af6c579 100644 (file)
@@ -506,6 +506,7 @@ static struct file_operations rtc_fops = {
        rtc_ioctl,
        NULL,           /* No mmap */
        rtc_open,
+       NULL,           /* flush */
        rtc_release
 };
 
index 60e1dccdf05acfba9d2c257cee80f0bcd720781a..c611b53448186348cb3ad4b618412cee9b7a2595 100644 (file)
@@ -168,6 +168,7 @@ static struct file_operations softdog_fops=
        softdog_ioctl,  /* Ioctl */
        NULL,           /* MMap */
        softdog_open,
+       NULL,           /* flush */
        softdog_release,
        NULL,           
        NULL            /* Fasync */
index 7239923ec47aa10e2a834bb2d0db3ca0e05bd32c..81d389cad51669388710626016ad52245838bc1e 100644 (file)
@@ -672,6 +672,7 @@ static struct file_operations       stl_fsiomem = {
        stl_memioctl,
        NULL,
        stl_memopen,
+       NULL,           /* flush */
        stl_memclose,
        NULL
 };
index 461e58165407abe0ad5c637e8345c2ea253465ce..56e2099bae914f14a41d04236fa2d2d3d700410d 100644 (file)
@@ -2756,6 +2756,7 @@ static struct file_operations qic02_tape_fops = {
        qic02_tape_ioctl,               /* ioctl */
        NULL,                           /* mmap not allowed */
        qic02_tape_open,                /* open */
+       NULL,                           /* flush */
        qic02_tape_release,             /* release */
        NULL,                           /* fsync */
        NULL,                           /* fasync */
index ff5fe5d5a1924a8549f8afc30b6388ceede97cc6..091cd26dc0c99127097655bdb7ff6dcac080f13f 100644 (file)
@@ -358,6 +358,7 @@ static struct file_operations tty_fops = {
        tty_ioctl,
        NULL,           /* tty_mmap */
        tty_open,
+       NULL,           /* flush */
        tty_release,
        NULL,           /* tty_fsync */
        tty_fasync
@@ -372,6 +373,7 @@ static struct file_operations hung_up_tty_fops = {
        hung_up_tty_ioctl,
        NULL,           /* hung_up_tty_mmap */
        NULL,           /* hung_up_tty_open */
+       NULL,           /* flush */
        tty_release,    /* hung_up_tty_release */
        NULL,           /* hung_up_tty_fsync  */
        NULL            /* hung_up_tty_fasync */
@@ -1976,7 +1978,7 @@ int tty_unregister_driver(struct tty_driver *driver)
  * Just do some early initializations, and do the complex setup
  * later.
  */
-long console_init(long kmem_start, long kmem_end)
+long __init console_init(long kmem_start, long kmem_end)
 {
        /* Setup the default TTY line discipline. */
        memset(ldiscs, 0, sizeof(ldiscs));
index 9eb3d39442103dec74c29907723c37add0ba3ffc..c640ff32166657ecf47990d1e60e354f035bd951 100644 (file)
@@ -108,7 +108,7 @@ static void set_tv_freq(struct tuner *t, int freq)
        else
                config = tun->UHF;
 
-       div=freq + (int)(16*38.9);
+       div=freq + tun->IFPCoff;
        div&=0x7fff;
 
        LOCK_I2C_BUS(t->bus);
index 30de4d39b6cd119411165d38b76df17cb043fa2b..bbdf7e4d5fcc833a9f80927a6bf7db21265fae41 100644 (file)
@@ -258,6 +258,7 @@ static struct file_operations vcs_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        vcs_open,       /* open */
+       NULL,           /* flush */
        NULL,           /* release */
        NULL            /* fsync */
 };
index 868ba4eb958f982b6b09ab2bb6d36661aa80419c..2ba0bd030ee366f7125caca64250495e36d8f09f 100644 (file)
@@ -62,6 +62,9 @@ extern int rtrack_init(struct video_init *);
 #ifdef CONFIG_RADIO_SF16FMI
 extern int fmi_init(struct video_init *);
 #endif
+#ifdef CONFIG_RADIO_MIROPCM20
+extern int pcm20_init(struct video_init *);
+#endif
 
 static struct video_init video_init_list[]={
 #ifdef CONFIG_VIDEO_BT848
@@ -88,6 +91,9 @@ static struct video_init video_init_list[]={
 #endif 
 #ifdef CONFIG_RADIO_SF16FMI
        {"SF16FMI", fmi_init}, 
+#endif
+#ifdef CONFIG_RADIO_MIROPCM20
+       {"PCM20", pcm20_init}, 
 #endif 
        {"end", NULL}
 };
@@ -315,6 +321,7 @@ static struct file_operations video_fops=
        video_ioctl,
        video_mmap,
        video_open,
+       NULL,           /* flush */
        video_release
 };
 
index 86ce2974448c6f721140c7121de7077f6f156435..a42c35fe3b0f2b7368986ddc9a1da3e2c924474f 100644 (file)
@@ -327,6 +327,7 @@ static struct file_operations wdt_fops = {
        wdt_ioctl,
        NULL,           /* No mmap */
        wdt_open,
+       NULL,           /* flush */
        wdt_release
 };
 
index d94a8a77187005faecb3c2bd25f31121043cfd56..f4f5c70391254ec9a0a46f2c68433c0b60bd80a7 100644 (file)
@@ -464,6 +464,7 @@ static struct file_operations capi_fops =
        capi_ioctl,
        NULL,                   /* capi_mmap */
        capi_open,
+       NULL,                   /* flush */
        capi_release,
        NULL,                   /* capi_fsync */
        NULL,                   /* capi_fasync */
index f8a7d46e530c6177e6dbb71b053b32cb3007532e..4c9a67cc0f1dfbf106dfb55cea9192b3a8d774a8 100644 (file)
@@ -442,6 +442,7 @@ static struct file_operations adb_fops = {
        NULL,           /* no ioctl yet */
        NULL,           /* no mmap */
        adb_open,
+       NULL,           /* flush */
        adb_release
 };
 
index ad06d3f8552409bb336578ef2651191adc0b3b09..33297e3f28af6ea5e009fa9b004d40f23eb26b9b 100644 (file)
@@ -82,6 +82,7 @@ struct file_operations nvram_fops = {
        NULL,           /* nvram_ioctl */
        NULL,           /* nvram_mmap */
        nvram_open,
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* fsync */
 };
index ee6b014bde9d2c019d18aaac62cacd363ef29c27..407a930026a788ff59e498fb39c2a9073063ba8b 100644 (file)
@@ -903,6 +903,7 @@ static struct file_operations pmu_device_fops = {
        pmu_ioctl,
        NULL,           /* no mmap */
        pmu_open,
+       NULL,           /* flush */
        NULL            /* no release */
 };
 
index a71f26bbeeda0fca8344ac87f55ccf5ddd3bcc19..95e904a40ad0278676234394b9e6f8eb49a09c28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: oldproc.c,v 1.16 1998/07/19 17:50:18 davem Exp $
+ *     $Id: oldproc.c,v 1.20 1998/08/23 12:12:01 mj Exp $
  *
  *     Backward-compatible procfs interface for PCI.
  *
@@ -122,7 +122,9 @@ struct pci_dev_info dev_info[] = {
        DEVICE( IBM,            IBM_82351,      "82351"),
        DEVICE( IBM,            IBM_SERVERAID,  "ServeRAID"),
        DEVICE( IBM,            IBM_TR_WAKE,    "Wake On LAN Token Ring"),
+       DEVICE( IBM,            IBM_MPIC,       "MPIC-2 Interrupt Controller"),
        DEVICE( IBM,            IBM_3780IDSP,   "MWave DSP"),
+       DEVICE( IBM,            IBM_MPIC_2,     "MPIC-2 ASIC Interrupt Controller"),
        DEVICE( WD,             WD_7197,        "WD 7197"),
        DEVICE( AMD,            AMD_LANCE,      "79C970"),
        DEVICE( AMD,            AMD_SCSI,       "53C974"),
index b70b879ab661634837095c88f0850675285f023e..8b1f6011b62d316e178b3e4f3980813043393014 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: pci.c,v 1.86 1998/07/15 20:34:47 mj Exp $
+ *     $Id: pci.c,v 1.88 1998/08/15 10:37:12 mj Exp $
  *
  *     PCI Bus Services, see include/linux/pci.h for further explanation.
  *
@@ -170,13 +170,14 @@ __initfunc(unsigned int pci_scan_bus(struct pci_bus *bus))
                        /* not a multi-function device */
                        continue;
                }
-               pcibios_read_config_byte(bus->number, devfn, PCI_HEADER_TYPE, &hdr_type);
+               if (pcibios_read_config_byte(bus->number, devfn, PCI_HEADER_TYPE, &hdr_type))
+                       continue;
                if (!PCI_FUNC(devfn))
                        is_multi = hdr_type & 0x80;
 
-               pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l);
-               /* some broken boards return 0 if a slot is empty: */
-               if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) {
+               if (pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID, &l) ||
+                   /* some broken boards return 0 if a slot is empty: */
+                   l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) {
                        is_multi = 0;
                        continue;
                }
index b9362798f11f6c97b5d5f2116604eb9afb6fed87..d1a78fe53feb9364c6e395749b078daf8e33b746 100644 (file)
@@ -204,6 +204,7 @@ static struct file_operations proc_bus_pci_operations = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
 };
index ab14e276780ca8fd246849ea27f8fa14a231e73c..c98923da439ef96a884f0ad7e741d451e8e632b2 100644 (file)
@@ -881,6 +881,7 @@ static struct file_operations sparcaudioctl_fops = {
        sparcaudio_ioctl,
        NULL,                   /* sparcaudio_mmap */
        NULL,
+       NULL,                   /* flush */
        sparcaudioctl_release
 };
 
index 983e3893f90666436858ea196b3efc99c0b11347..846f7cd7bb7800aa6e0a8b17c8b2f54527f6c5c5 100644 (file)
@@ -866,6 +866,7 @@ static struct file_operations bpp_fops = {
        bpp_ioctl,
        NULL,           /* bpp_mmap */
        bpp_open,
+       NULL,           /* flush */
        bpp_release,
 };
 
index b957ce81cc01a42f354c9a731d0f613fc04e9c80..af8f6ce789603c1125ed229e4e892f112ad3f573 100644 (file)
@@ -298,6 +298,7 @@ static struct file_operations envctrl_fops = {
        envctrl_ioctl,
        NULL,           /* mmap */
        envctrl_open,
+       NULL,           /* flush */
        envctrl_release
 };
 
index 0a09e07e29f5c9a8bf32d966b7748b5b263f8055..fd91eeefdd566caa2af72337bc62ddd9fb3ee433 100644 (file)
@@ -143,6 +143,7 @@ static struct file_operations flash_fops = {
        NULL,           /* ioctl */
        flash_mmap,
        flash_open,
+       NULL,           /* flush */
        flash_release
 };
 
index 6d09bfca421912002f089d4d378319926311adbc..7d17e08ea4d852c5f63601c8e59c8c5dec7a9075 100644 (file)
@@ -564,6 +564,7 @@ static struct file_operations openprom_fops = {
        openprom_ioctl,
        NULL,                   /* openprom_mmap */
        openprom_open,
+       NULL,                   /* flush */
        openprom_release
 };
 
index 06140fa68bddc0d18ceed9503e65d9fad4726f4b..d6be1fca078823f57efba5443ddea4cfc14930db 100644 (file)
@@ -869,6 +869,7 @@ struct file_operations psaux_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        aux_open,
+       NULL,           /* flush */
        aux_release,
        NULL,
        aux_fasync,
index f506a7c90724c2b144f9e5901730b8a13300dae8..8e001c0bdf23207488dbc28e1afcbbaf40bdbe7e 100644 (file)
@@ -133,6 +133,7 @@ static struct file_operations rtc_fops = {
        rtc_ioctl,
        NULL,           /* rtc_mmap */
        rtc_open,
+       NULL,           /* flush */
        rtc_release
 };
 
index 63586750e4073f44ab7d220484c5b2da3192074f..59b77a5e4d265edb6393a9c7f1f3b436755a4ada 100644 (file)
@@ -1494,6 +1494,7 @@ file_operations kbd_fops =
        kbd_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        kbd_open,               /* open */
+       NULL,                   /* flush */
        kbd_close,              /* close */
        NULL,                   /* fsync */
        kbd_fasync,             /* fasync */
index 70edaab36654872350441f0ae53be6e8fe1152bb..3a6d672fbf577ee3d0796021383482a6da80e5d1 100644 (file)
@@ -474,6 +474,7 @@ struct file_operations sun_mouse_fops = {
        sun_mouse_ioctl,
        NULL,
        sun_mouse_open,
+       NULL,           /* flush */
        sun_mouse_close,
        NULL,
        sun_mouse_fasync,
index 81a8b7477e57b00923b61827c3e620455d6a6b67..b16581679f47406fd9b29f80a78daae9d8060f00 100644 (file)
@@ -603,6 +603,7 @@ static struct file_operations vfc_fops = {
        vfc_ioctl,   
        vfc_mmap, 
        vfc_open,
+       NULL,           /* flush */
        vfc_release,
 };
 
index 1582159613840533ce8c0f71041d12a0a4b00eec..6441113acc8d541e7ee1551817d3ccf17fb8b235 100644 (file)
@@ -15,7 +15,7 @@ SCSI_SRCS = $(wildcard $(L_OBJS:%.o=%.c))
 
 CFLAGS_aha152x.o =   -DDEBUG_AHA152X -DAUTOCONF
 CFLAGS_gdth.o    = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
-CFLAGS_seagate.o =   -DARBITRATE -DSLOW_HANDSHAKE -DFAST32 -DPARITY
+CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
 
 .SUFFIXES:
 .SUFFIXES: .c .o .h .a
index cd4ca8f4db27df4334ce5a67ac9f2a6981ce3153..a7d86efba2c9215ae446620cfc14308221201886 100644 (file)
@@ -222,6 +222,7 @@ static struct file_operations sd_fops = {
     sd_ioctl,                    /* ioctl */
     NULL,                        /* mmap */
     sd_open,                     /* open code */
+    NULL,                       /* flush */
     sd_release,                  /* release */
     block_fsync,                 /* fsync */
     NULL,                        /* fasync */
index 130e6a233c9d0a75c2e2f8190c0cb2dadbd9d74f..f5a316d313fd2f6a8d7c96997b8743adaa9c0c9a 100644 (file)
@@ -1,30 +1,23 @@
 /*
  *    seagate.c Copyright (C) 1992, 1993 Drew Eckhardt
  *      low level scsi driver for ST01/ST02, Future Domain TMC-885,
- *      TMC-950  by
- *
- *              Drew Eckhardt
- *
- *      <drew@colorado.edu>
+ *      TMC-950 by Drew Eckhardt <drew@colorado.edu>
  *
  *      Note : TMC-880 boards don't work because they have two bits in
  *              the status register flipped, I'll fix this "RSN"
+ *     [why do I have strong feeling that above message is from 1993? :-) pavel@ucw.cz]
  *
  *      This card does all the I/O via memory mapped I/O, so there is no need
  *      to check or allocate a region of the I/O address space.
  */
 
-/* Modified 1996 to use new read{b,w,l}, write{b,w,l}, and phys_to_virt
-   macros. This meant redefining st0x_cr_sr and st0x_dr, as well as
-   replacing the "DATA = foo;" and "CONTROL = foo;" structures with 
-   WRITE_DATA(foo) and WRITE_CONTROL(foo) macros.
-
-   Replaced assembler routines with C. There's probably a performance hit,
-   but I only have a cdrom and can't tell. Define SEAGATE_USE_ASM if you
-   want the old assembler code.
-
-   Look for the string "SJT" for details.
-
+/* 1996 - to use new read{b,w,l}, write{b,w,l}, and phys_to_virt
+ * macros, replaced assembler routines with C. There's probably a
+ * performance hit, but I only have a cdrom and can't tell. Define
+ * SEAGATE_USE_ASM if you want the old assembler code -- SJT
+ *
+ * 1998-jul-29 - created DPRINTK macros and made it work under 
+ * linux 2.1.112, simplified some #defines etc. <pavel@ucw.cz>
  */
 
 /*
@@ -50,7 +43,7 @@
  *      let us do one command per Lun when I integrate my
  *      reorganization changes into the distribution sources.
  *
- * -DDEBUG
+ * -DDEBUG=65535
  *      Will activate debug code.
  *
  * -DFAST or -DFAST32 
  *      Will use older seagate assembly code. should be (very small amount)
  *      Faster.
  *
- * -DSLOW_HANDSHAKE
+ * -DSLOW_RATE=50
  *      Will allow compatibility with broken devices that don't
  *      handshake fast enough (ie, some CD ROM's) for the Seagate
  *      code.
  *
- * -DSLOW_RATE=x
- *      x is some number, It will let you specify a default
+ *      50 is some number, It will let you specify a default
  *      transfer rate if handshaking isn't working correctly.
  *
  * -DOLDCNTDATASCEME  There is a new sceme to set the CONTROL
 #include <linux/string.h>
 #include <linux/config.h>
 #include <linux/proc_fs.h>
+#include <linux/init.h>
 
 #include <linux/blk.h>
 #include "scsi.h"
 #include "hosts.h"
 #include "seagate.h"
 #include "constants.h"
-#include<linux/stat.h>
+#include <linux/stat.h>
 #include <asm/uaccess.h>
 #include "sd.h"
 #include <scsi/scsi_ioctl.h>
+#include <asm/delay.h>
+
+#ifdef DEBUG
+#define DPRINTK( when, msg... ) do { if ( (DEBUG & (when)) == (when) ) printk( msg ); } while (0)
+#else
+#define DPRINTK( when, msg... ) do { } while (0)
+#endif
+#define DANY( msg... ) DPRINTK( 0xffff, msg );
 
 static struct proc_dir_entry proc_scsi_seagate =
 {
@@ -118,24 +119,16 @@ static struct proc_dir_entry proc_scsi_seagate =
 #define IRQ 5
 #endif
 
-#if (defined(FAST32) && !defined(FAST))
+#ifdef FAST32
 #define FAST
 #endif
 
-#if defined(SLOW_RATE) && !defined(SLOW_HANDSHAKE)
-#define SLOW_HANDSHAKE
-#endif
-
-#if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE)
-#define SLOW_RATE 50
-#endif
+#undef LINKED          /* Linked commands are currently broken! */
 
-#if defined(LINKED)
-#undef LINKED                           /* Linked commands are currently
-                                           broken! */
+#if defined(OVERRIDE) && !defined(CONTROLLER)
+#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
 #endif
 
-
 /*
        Thanks to Brian Antoine for the example code in his Messy-Loss ST-01
                driver, and Mitsugu Suzuki for information on the ST-01
@@ -206,7 +199,7 @@ extern volatile int seagate_st0x_timeout;
 #define PHASE_MSGIN 0x40
 #define PHASE_MSGOUT 0x80
 #define PHASE_STATUSIN 0x100
-#define PHASE_ETC (PHASE_DATAIN | PHASE_DATA_OUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN)
+#define PHASE_ETC (PHASE_DATAIN | PHASE_DATAOUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN)
 #define PRINT_COMMAND 0x200
 #define PHASE_EXIT 0x400
 #define PHASE_RESELECT 0x800
@@ -223,8 +216,6 @@ extern volatile int seagate_st0x_timeout;
 #define ST0X_BUS_FREE_DELAY 25
 #define ST0X_SELECTION_DELAY 25
 
-#define eoi() __asm__("push %%eax\nmovb $0x20, %%al\noutb %%al, $0x20\npop %%eax"::)
-       
 #define SEAGATE 1      /* these determine the type of the controller */
 #define FD     2
 
@@ -242,10 +233,6 @@ static int incommand;                   /* set if arbitration has finished
 static unsigned int base_address = 0;   /* Where the card ROM starts, used to 
                                            calculate memory mapped register
                                            location.  */
-#ifdef notyet
-static volatile int abort_confirm = 0;
-
-#endif
 
 static unsigned long st0x_cr_sr;        /* control register write, status
                                            register read.  256 bytes in
@@ -262,15 +249,13 @@ static volatile int st0x_aborted = 0;   /* set when we are aborted, ie by a
 static unsigned char controller_type = 0;       /* set to SEAGATE for ST0x
                                                    boards or FD for TMC-8xx
                                                    boards */
-static unsigned char irq = IRQ;
+static int irq = IRQ;
 
 #define retcode(result) (((result) << 16) | (message << 8) | status)
-#define STATUS (readb(st0x_cr_sr))
-#define DATA (readb(st0x_dr))
-/* SJT: Start. */
-#define WRITE_CONTROL(d) writeb((d), st0x_cr_sr)
-#define WRITE_DATA(d) writeb((d), st0x_dr)
-/* SJT: End. */
+#define STATUS ((u8) readb(st0x_cr_sr))
+#define DATA ((u8) readb(st0x_dr))
+#define WRITE_CONTROL(d) { writeb((d), st0x_cr_sr); }
+#define WRITE_DATA(d) { writeb((d), st0x_dr); }
 
 void st0x_setup (char *str, int *ints)
 {
@@ -302,9 +287,8 @@ typedef struct
 }
 Signature;
 
-static const Signature signatures[] =
+static const Signature __initdata signatures[] =
 {
-#ifdef CONFIG_SCSI_SEAGATE
   {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
   {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
 
@@ -331,9 +315,7 @@ static const Signature signatures[] =
   {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
   {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
   {"FUTURE DOMAIN TMC-950", 5, 21, FD},
-#endif                                  /* CONFIG_SCSI_SEAGATE */
-}
-;
+};
 
 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
 #endif /* n OVERRIDE */
@@ -348,10 +330,11 @@ static void do_seagate_reconnect_intr (int, void *, struct pt_regs *);
 
 #ifdef FAST
 static int fast = 1;
-
+#else
+#define fast 0
 #endif
 
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
 /*
  * Support for broken devices :
  * The Seagate board has a handshaking problem.  Namely, a lack
@@ -387,10 +370,13 @@ static int fast = 1;
  * the best thing for us to do will be to calibrate a timing
  * loop in the initialization code using the timer chip before
  * gettimeofday() can screw with it.
+ *
+ * FIXME: this is broken (not borken :-). Empty loop costs less than
+ * loop with ISA access in it! -- pavel@ucw.cz
  */
 
 static int borken_calibration = 0;
-static void borken_init (void)
+static void __init borken_init (void)
 {
   register int count = 0, start = jiffies + 1, stop = start + 25;
 
@@ -399,53 +385,47 @@ static void borken_init (void)
 
 /*
  * Ok, we now have a count for .25 seconds.  Convert to a
- * count per second and divide by transfer rate in K.
- */
+ * count per second and divide by transfer rate in K.  */
 
   borken_calibration = (count * 4) / (SLOW_RATE * 1024);
 
   if (borken_calibration < 1)
     borken_calibration = 1;
-#if (DEBUG & DEBUG_BORKEN)
-  printk ("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n",
-          hostno, BORKEN_RATE, borken_calibration);
-#endif
 }
 
 static inline void borken_wait (void)
 {
   register int count;
 
-  for (count = borken_calibration; count && (STATUS & STAT_REQ);
-       --count) ;
+  for (count = borken_calibration; count && (STATUS & STAT_REQ); --count) ;
 #if (DEBUG & DEBUG_BORKEN)
   if (count)
     printk ("scsi%d : borken timeout\n", hostno);
 #endif
 }
 
-#endif /* def SLOW_HANDSHAKE */
+#endif /* def SLOW_RATE */
+
+/* These beasts only live on ISA, and ISA means 8MHz. Each ULOOP()
+ * contains at least one ISA access, which takes more than 0.125
+ * usec. So if we loop 8 times time in usec, we are safe.
+ */
+
+#define ULOOP( i ) for (clock = i*8;;)
+#define TIMEOUT (!(clock--))
 
-int seagate_st0x_detect (Scsi_Host_Template * tpnt)
+int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
 {
   struct Scsi_Host *instance;
-
-#ifndef OVERRIDE
   int i, j;
 
-#endif
-
   tpnt->proc_dir = &proc_scsi_seagate;
 /*
- *    First, we try for the manual override.
- */
-#ifdef DEBUG
-  printk ("Autodetecting ST0x / TMC-8xx\n");
-#endif
+ *    First, we try for the manual override.  */
+  DANY ("Autodetecting ST0x / TMC-8xx\n");
 
-  if (hostno != -1)
-  {
-    printk ("ERROR : seagate_st0x_detect() called twice.\n");
+  if (hostno != -1) {
+    printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
     return 0;
   }
 
@@ -456,17 +436,10 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt)
   {
 #ifdef OVERRIDE
     base_address = OVERRIDE;
-
-/* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */
-#ifdef CONTROLLER
     controller_type = CONTROLLER;
-#else
-#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
-#endif /* CONTROLLER */
-#ifdef DEBUG
-    printk ("Base address overridden to %x, controller type is %s\n",
+
+    DANY("Base address overridden to %x, controller type is %s\n",
             base_address, controller_type == SEAGATE ? "SEAGATE" : "FD");
-#endif
 #else /* OVERRIDE */
 /*
  *    To detect this card, we simply look for the signature
@@ -493,33 +466,46 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt)
   tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
   tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
 
-  if (base_address)
-  {
-    st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
-    st0x_dr = st0x_cr_sr + 0x200;
-#ifdef DEBUG
-    printk ("%s detected. Base address = %x, cr = %x, dr = %x\n",
-            tpnt->name, base_address, st0x_cr_sr, st0x_dr);
-#endif
+  if (!base_address) {
+    DANY ("ST0x / TMC-8xx not detected.\n");
+    return 0;
+  }
+
+  st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
+  st0x_dr = st0x_cr_sr + 0x200;
+
+  DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
+       tpnt->name, base_address, st0x_cr_sr, st0x_dr);
+
 /*
  *    At all times, we will use IRQ 5.  Should also check for IRQ3 if we
  *      loose our first interrupt.
  */
-    instance = scsi_register (tpnt, 0);
-    hostno = instance->host_no;
-    if (request_irq ((int) irq, do_seagate_reconnect_intr, SA_INTERRUPT,
-                (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL))
-    {
-      printk ("scsi%d : unable to allocate IRQ%d\n", hostno, (int) irq);
-      return 0;
-    }
-    instance->irq = irq;
-    instance->io_port = base_address;
-#ifdef SLOW_HANDSHAKE
-    borken_init ();
+  instance = scsi_register (tpnt, 0);
+  hostno = instance->host_no;
+  if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
+                  (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) {
+    printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
+    return 0;
+  }
+  instance->irq = irq;
+  instance->io_port = base_address;
+#ifdef SLOW_RATE
+  printk( "Calibrating borken timer... " );
+  borken_init ();
+  printk( " %d cycles per transfer\n", borken_calibration );
 #endif
 
-    printk ("%s options:"
+  printk( "This is one second... " );
+  {
+    int clock;
+    ULOOP( 1*1000*1000 ) {
+      volatile int x = STATUS;
+      if (TIMEOUT) break;
+    }
+  }
+
+  printk ("done, %s options:"
 #ifdef ARBITRATE
             " ARBITRATE"
 #endif
@@ -527,10 +513,9 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt)
             " DEBUG"
 #endif
 #ifdef FAST
-#ifdef FAST32
-            " FAST32"
-#else
             " FAST"
+#ifdef FAST32
+            "32"
 #endif
 #endif
 #ifdef LINKED
@@ -542,8 +527,8 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt)
 #ifdef SEAGATE_USE_ASM
             " SEAGATE_USE_ASM"
 #endif
-#ifdef SLOW_HANDSHAKE
-            " SLOW_HANDSHAKE"
+#ifdef SLOW_RATE
+            " SLOW_RATE"
 #endif
 #ifdef SWAPSTAT
             " SWAPSTAT"
@@ -551,16 +536,8 @@ int seagate_st0x_detect (Scsi_Host_Template * tpnt)
 #ifdef SWAPCNTDATA
             " SWAPCNTDATA"
 #endif
-            "\n", tpnt->name);
-    return 1;
-  }
-  else
-  {
-#ifdef DEBUG
-    printk ("ST0x / TMC-8xx not detected.\n");
-#endif
-    return 0;
-  }
+         "\n", tpnt->name);
+  return 1;
 }
 
 const char *seagate_st0x_info (struct Scsi_Host *shpnt)
@@ -585,7 +562,6 @@ static struct scatterlist *current_buffer;
 static int current_bufflen;
 
 #ifdef LINKED
-
 /*
  * linked_connected indicates whether or not we are currently connected to
  * linked_target, linked_lun and in an INFORMATION TRANSFER phase,
@@ -594,7 +570,6 @@ static int current_bufflen;
 
 static int linked_connected = 0;
 static unsigned char linked_target, linked_lun;
-
 #endif
 
 static void (*done_fn) (Scsi_Cmnd *) = NULL;
@@ -609,17 +584,14 @@ static Scsi_Cmnd *SCint = NULL;
 #define RECONNECT_NOW   1
 #define CAN_RECONNECT   2
 
-#ifdef LINKED
-
 /*
  * LINKED_RIGHT indicates that we are currently connected to the correct target
  * for this command, LINKED_WRONG indicates that we are connected to the wrong
- * target.  Note that these imply CAN_RECONNECT.
+ * target. Note that these imply CAN_RECONNECT and require defined(LINKED).
  */
 
 #define LINKED_RIGHT    3
 #define LINKED_WRONG    4
-#endif
 
 /*
  * This determines if we are expecting to reconnect or not.
@@ -633,8 +605,7 @@ static int should_reconnect = 0;
  * asserting SEL.
  */
 
-static void do_seagate_reconnect_intr (int irq, void *dev_id, 
-                                    struct pt_regs *regs)
+static void do_seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
   unsigned long flags;
 
@@ -643,15 +614,12 @@ static void do_seagate_reconnect_intr (int irq, void *dev_id,
   spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
-static void seagate_reconnect_intr (int irq, void *dev_id, 
-                                    struct pt_regs *regs)
+static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
   int temp;
   Scsi_Cmnd *SCtmp;
 
-#if (DEBUG & PHASE_RESELECT)
-  printk ("scsi%d : seagate_reconnect_intr() called\n", hostno);
-#endif
+  DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno);
 
   if (!should_reconnect)
     printk ("scsi%d: unexpected interrupt.\n", hostno);
@@ -659,11 +627,9 @@ static void seagate_reconnect_intr (int irq, void *dev_id,
   {
     should_reconnect = 0;
 
-#if (DEBUG & PHASE_RESELECT)
-    printk ("scsi%d : internal_command("
-            "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno,
+    DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
+            "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
             current_target, current_data, current_bufflen);
-#endif
 
     temp = internal_command (current_target, current_lun, current_cmnd,
                              current_data, current_bufflen, RECONNECT_NOW);
@@ -672,10 +638,8 @@ static void seagate_reconnect_intr (int irq, void *dev_id,
     {
       if (done_fn)
       {
-#if (DEBUG & PHASE_RESELECT)
-        printk ("scsi%d : done_fn(%d,%08x)", hostno,
+        DPRINTK (PHASE_RESELECT, "scsi%d : done_fn(%d,%08x)", hostno,
                 hostno, temp);
-#endif
         if (!SCint)
           panic ("SCint == NULL in seagate");
         SCtmp = SCint;
@@ -707,6 +671,7 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
   int result, reconnect;
   Scsi_Cmnd *SCtmp;
 
+  DANY( "seagate: que_command" );
   done_fn = done;
   current_target = SCpnt->target;
   current_lun = SCpnt->lun;
@@ -714,10 +679,7 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
   current_data = (unsigned char *) SCpnt->request_buffer;
   current_bufflen = SCpnt->request_bufflen;
   SCint = SCpnt;
-  if (recursion_depth)
-  {
-    return 0;
-  };
+  if (recursion_depth) return 0;
   recursion_depth++;
   do
   {
@@ -729,22 +691,16 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
     current_cmnd[SCpnt->cmd_len] |= 0x01;
     if (linked_connected)
     {
-#if (DEBUG & DEBUG_LINKED)
-      printk ("scsi%d : using linked commands, current I_T_L nexus is ",
-              hostno);
-#endif
+      DPRINTK (DEBUG_LINKED, 
+              "scsi%d : using linked commands, current I_T_L nexus is ", hostno);
       if ((linked_target == current_target) && (linked_lun == current_lun))
       {
-#if (DEBUG & DEBUG_LINKED)
-        printk ("correct\n");
-#endif
+        DPRINTK (DEBUG_LINKED, "correct\n");
         reconnect = LINKED_RIGHT;
       }
       else
       {
-#if (DEBUG & DEBUG_LINKED)
-        printk ("incorrect\n");
-#endif
+        DPRINTK (DEBUG_LINKED, "incorrect\n");
         reconnect = LINKED_WRONG;
       }
     }
@@ -753,10 +709,8 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
       reconnect = CAN_RECONNECT;
 
     result = internal_command (SCint->target, SCint->lun, SCint->cmnd,
-                               SCint->request_buffer, SCint->request_bufflen,
-                               reconnect);
-    if (msg_byte (result) == DISCONNECT)
-      break;
+                               SCint->request_buffer, SCint->request_bufflen, reconnect);
+    if (msg_byte (result) == DISCONNECT) break;
     SCtmp = SCint;
     SCint = NULL;
     SCtmp->result = result;
@@ -775,59 +729,33 @@ int seagate_st0x_command (Scsi_Cmnd * SCpnt)
 }
 
 static int internal_command (unsigned char target, unsigned char lun, 
-                             const void *cmnd, void *buff, int bufflen, 
-                             int reselect)
+                             const void *cmnd, void *buff, int bufflen, int reselect)
 {
-  int len = 0;
   unsigned char *data = NULL;
   struct scatterlist *buffer = NULL;
-  int nobuffs = 0;
-  int clock;
-  int temp;
-
-#ifdef SLOW_HANDSHAKE
-  int borken;                           /* Does the current target require
-                                           Very Slow I/O ?  */
-#endif
-
-#if (DEBUG & PHASE_DATAIN) || (DEBUG & PHASE_DATOUT)
-  int transfered = 0;
-
-#endif
-
-#if (((DEBUG & PHASE_ETC) == PHASE_ETC) || (DEBUG & PRINT_COMMAND) || \
-     (DEBUG & PHASE_EXIT))
-  int i;
-
-#endif
-
-#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
-  int phase = 0, newphase;
+  int clock, temp, nobuffs = 0, done = 0, len = 0;
+  unsigned long flags;
 
+#ifdef DEBUG
+  int transfered = 0, phase = 0, newphase;
 #endif
 
-  int done = 0;
-  unsigned char status = 0;
-  unsigned char message = 0;
   register unsigned char status_read;
+  unsigned char tmp_data, tmp_control, status = 0, message = 0;
 
-#ifndef OLDCNTDATASCEME
-  volatile unsigned char tmp_data;
-  volatile unsigned char tmp_control;
-#endif
   unsigned transfersize = 0, underflow = 0;
 
+#ifdef SLOW_RATE
+  int borken = (int) SCint->device->borken; /* Does the current target require
+                                              Very Slow I/O ?  */
+#endif
+
   incommand = 0;
   st0x_aborted = 0;
 
-#ifdef SLOW_HANDSHAKE
-  borken = (int) SCint->device->borken;
-#endif
-
 #if (DEBUG & PRINT_COMMAND)
   printk ("scsi%d : target = %d, command = ", hostno, target);
   print_command ((unsigned char *) cmnd);
-  printk ("\n");
 #endif
 
 #if (DEBUG & PHASE_RESELECT)
@@ -864,9 +792,7 @@ static int internal_command (unsigned char target, unsigned char lun,
   switch (reselect)
   {
     case RECONNECT_NOW:
-#if (DEBUG & PHASE_RESELECT)
-      printk ("scsi%d : phase RESELECT \n", hostno);
-#endif
+      DPRINTK ( PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
 
 /*
  *    At this point, we should find the logical or of our ID and the original
@@ -876,19 +802,14 @@ static int internal_command (unsigned char target, unsigned char lun,
  *      target ID are asserted.  A valid initiator ID is not on the bus
  *      until IO is asserted, so we must wait for that.
  */
-      clock = jiffies + 10;
-      for (;;)
-      {
+      ULOOP( 100*1000 ) {
         temp = STATUS;
         if ((temp & STAT_IO) && !(temp & STAT_BSY))
           break;
 
-        if (jiffies > clock)
-        {
-#if (DEBUG & PHASE_RESELECT)
-          printk ("scsi%d : RESELECT timed out while waiting for IO .\n",
-                  hostno);
-#endif
+        if (TIMEOUT) {
+          DPRINTK (PHASE_RESELECT, 
+                  "scsi%d : RESELECT timed out while waiting for IO .\n", hostno);
           return (DID_BAD_INTR << 16);
         }
       }
@@ -900,10 +821,9 @@ static int internal_command (unsigned char target, unsigned char lun,
 
       if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
       {
-#if (DEBUG & PHASE_RESELECT)
-        printk ("scsi%d : detected reconnect request to different target.\n"
-                "\tData bus = %d\n", hostno, temp);
-#endif
+        DPRINTK (PHASE_RESELECT,
+                "scsi%d : detected reconnect request to different target.\n"
+                "\tData bus = %d\n", hostno, temp);
         return (DID_BAD_INTR << 16);
       }
 
@@ -936,16 +856,14 @@ static int internal_command (unsigned char target, unsigned char lun,
  *      BSY.
  */
 
-      for (clock = jiffies + 10; (jiffies < clock) && (STATUS & STAT_SEL);) ;
-
-      if (jiffies >= clock)
-      {
-        WRITE_CONTROL (BASE_CMD | CMD_INTR);
-#if (DEBUG & PHASE_RESELECT)
-        printk ("scsi%d : RESELECT timed out while waiting for SEL.\n", 
-                hostno);
-#endif
-        return (DID_BAD_INTR << 16);
+      ULOOP( 100*1000 ) {
+       if (!(STATUS & STAT_SEL)) break;
+       if (TIMEOUT) {
+         WRITE_CONTROL (BASE_CMD | CMD_INTR);
+         DPRINTK (PHASE_RESELECT,
+                  "scsi%d : RESELECT timed out while waiting for SEL.\n", hostno);
+         return (DID_BAD_INTR << 16);
+       }
       }
 
       WRITE_CONTROL (BASE_CMD);
@@ -969,9 +887,7 @@ static int internal_command (unsigned char target, unsigned char lun,
 
 #endif
 
-#if (DEBUG & PHASE_BUS_FREE)
-      printk ("scsi%d : phase = BUS FREE \n", hostno);
-#endif
+      DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n", hostno);
 
 /*
  *    BUS FREE PHASE
@@ -982,12 +898,13 @@ static int internal_command (unsigned char target, unsigned char lun,
  *      eliminate wire glitch.
  */
 
+#ifndef ARBITRATE
+#error FIXME: this is broken: we may not use jiffies here - we are under cli(). It will hardlock.
       clock = jiffies + ST0X_BUS_FREE_DELAY;
 
-#if !defined (ARBITRATE)
       while (((STATUS | STATUS | STATUS) &
               (STAT_BSY | STAT_SEL)) &&
-             (!st0x_aborted) && (jiffies < clock)) ;
+             (!st0x_aborted) && (jiffies < clock));
 
       if (jiffies > clock)
         return retcode (DID_BUS_BUSY);
@@ -995,9 +912,7 @@ static int internal_command (unsigned char target, unsigned char lun,
         return retcode (st0x_aborted);
 #endif
 
-#if (DEBUG & PHASE_SELECTION)
-      printk ("scsi%d : phase = SELECTION\n", hostno);
-#endif
+      DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n", hostno);
 
       clock = jiffies + ST0X_SELECTION_DELAY;
 
@@ -1012,33 +927,27 @@ static int internal_command (unsigned char target, unsigned char lun,
  * 6.  Enable SCSI drivers and asserted SEL and ATTN
  */
 
-#if defined(ARBITRATE)
-      { unsigned long flags;
+#ifdef ARBITRATE
       save_flags (flags);
       cli ();
       WRITE_CONTROL (0);
       WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
       WRITE_CONTROL (CMD_START_ARB);
       restore_flags (flags);
-      }
-      while (!((status_read = STATUS) & (STAT_ARB_CMPL | STAT_SEL)) &&
-             (jiffies < clock) && !st0x_aborted) ;
 
-      if (!(status_read & STAT_ARB_CMPL))
-      {
-#if (DEBUG & PHASE_SELECTION)
-        if (status_read & STAT_SEL)
-          printk ("scsi%d : arbitration lost\n", hostno);
-        else
-          printk ("scsi%d : arbitration timeout.\n", hostno);
-#endif
-        WRITE_CONTROL (BASE_CMD);
-        return retcode (DID_NO_CONNECT);
-      };
+      ULOOP( ST0X_SELECTION_DELAY * 10000 ) {
+       status_read = STATUS;
+       if (status_read & STAT_ARB_CMPL) break;
+       if (st0x_aborted)       /* FIXME: What? We are going to do something even after abort? */
+          break;
+       if (TIMEOUT || (status_read & STAT_SEL)) {
+         printk( "scsi%d : arbitration lost or timeout.\n", hostno );
+         WRITE_CONTROL (BASE_CMD);
+         return retcode (DID_NO_CONNECT);
+       }
+      }
 
-#if (DEBUG & PHASE_SELECTION)
-      printk ("scsi%d : arbitration complete\n", hostno);
-#endif
+      DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n", hostno);
 #endif
 
 /*
@@ -1053,81 +962,53 @@ static int internal_command (unsigned char target, unsigned char lun,
  *    try this with a SCSI protocol or logic analyzer to see what is
  *    going on.
  */
+       tmp_data = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
+       tmp_control = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN : 0);
+
+       save_flags(flags);
+       cli();
 #ifdef OLDCNTDATASCEME
 #ifdef SWAPCNTDATA
-      { unsigned long flags;
-        save_flags(flags);
-       cli();
-      WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
-                     (reselect ? CMD_ATTN : 0));
-      WRITE_DATA ((unsigned char) ((1 << target) |
-                               (controller_type == SEAGATE ? 0x80 : 0x40)));
-       restore_flags(flags);
-      }
+       WRITE_CONTROL (tmp_control);
+       WRITE_DATA (tmp_data);
 #else
-      { unsigned long flags;
-      save_flags(flags);
-      cli ();
-      WRITE_DATA ((unsigned char) ((1 << target) |
-                               (controller_type == SEAGATE ? 0x80 : 0x40)));
-      WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
-                     (reselect ? CMD_ATTN : 0));
-      restore_flags (flags);
-      }
+       WRITE_DATA (tmp_data);
+       WRITE_CONTROL (tmp_control);
 #endif
 #else
-       tmp_data = (unsigned char) ((1 << target) | (controller_type == SEAGATE 
-? 0x80 : 0x40));
-       tmp_control = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
-                (reselect ? CMD_ATTN : 0) | CMD_BSY;
-       WRITE_CONTROL(tmp_data);
-       WRITE_DATA(tmp_control);
-       tmp_control ^= CMD_BSY;
-       WRITE_CONTROL(tmp_control);
-#endif /* OLDCNTDATASCEME */
-      while (!((status_read = STATUS) & STAT_BSY) && (jiffies < clock)
-             && !st0x_aborted)
-#if 0 && (DEBUG & PHASE_SELECTION)
-      {
-        temp = clock - jiffies;
+       tmp_control ^= CMD_BSY;         /* This is guesswork. What used to be in driver    */
+       WRITE_CONTROL (tmp_control);    /* could never work: it sent data into control     */
+       WRITE_DATA (tmp_data);          /* register and control info into data. Hopefully  */
+       tmp_control ^= CMD_BSY;         /* fixed, but order of first two may be wrong.     */
+       WRITE_CONTROL (tmp_control);                                  /* -- pavel@ucw.cz   */
+#endif       
 
-        if (!(jiffies % 5))
-          printk ("seagate_st0x_timeout : %d            \r", temp);
-      }
-      printk ("Done.                                             \n");
-      printk ("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n",
-              hostno, status_read, temp, st0x_aborted);
-#else
-        ;
-#endif
 
-      if ((jiffies >= clock) && !(status_read & STAT_BSY))
-      {
-#if (DEBUG & PHASE_SELECTION)
-        printk ("scsi%d : NO CONNECT with target %d, status = %x \n",
-                hostno, target, STATUS);
-#endif
-        return retcode (DID_NO_CONNECT);
-      }
+       restore_flags (flags);
 
+       ULOOP( 250*1000 ) {
+        if (st0x_aborted) {
 /*
  *    If we have been aborted, and we have a command in progress, IE the
  *      target still has BSY asserted, then we will reset the bus, and
  *      notify the midlevel driver to expect sense.
  */
 
-      if (st0x_aborted)
-      {
-        WRITE_CONTROL (BASE_CMD);
-        if (STATUS & STAT_BSY)
-        {
-          printk ("scsi%d : BST asserted after we've been aborted.\n",
-                  hostno);
-          seagate_st0x_reset (NULL, 0);
-          return retcode (DID_RESET);
-        }
-        return retcode (st0x_aborted);
-      }
+          WRITE_CONTROL (BASE_CMD);
+          if (STATUS & STAT_BSY) {
+            printk ("scsi%d : BST asserted after we've been aborted.\n", hostno);
+            seagate_st0x_reset (NULL, 0);
+            return retcode (DID_RESET);
+          }
+          return retcode (st0x_aborted);
+        }
+        if (STATUS & STAT_BSY) break;
+        if (TIMEOUT) {
+          DPRINTK (PHASE_SELECTION, "scsi%d : NO CONNECT with target %d, stat = %x \n",
+                   hostno, target, STATUS);
+          return retcode (DID_NO_CONNECT);
+        }
+       }
 
 /* Establish current pointers.  Take into account scatter / gather */
 
@@ -1151,17 +1032,13 @@ static int internal_command (unsigned char target, unsigned char lun,
       }
       else
       {
-#if (DEBUG & DEBUG_SG)
-        printk ("scsi%d : scatter gather not requested.\n", hostno);
-#endif
+        DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
         buffer = NULL;
         len = SCint->request_bufflen;
         data = (unsigned char *) SCint->request_buffer;
       }
 
-#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT))
-      printk ("scsi%d : len = %d\n", hostno, len);
-#endif
+      DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n", hostno, len);
 
       break;
 #ifdef LINKED
@@ -1205,9 +1082,7 @@ static int internal_command (unsigned char target, unsigned char lun,
  *
  */
 
-#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
-  printk ("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
-#endif
+  DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
 
   incommand = 1;
   transfersize = SCint->transfersize;
@@ -1271,12 +1146,10 @@ static int internal_command (unsigned char target, unsigned char lun,
  * in word-sized chunks as fast as we can.
  */
 
-#ifdef FAST
           if (!len)
           {
 #if 0
-            printk ("scsi%d: underflow to target %d lun %d \n", hostno,
-                    target, lun);
+            printk ("scsi%d: underflow to target %d lun %d \n", hostno, target, lun);
             st0x_aborted = DID_ERROR;
             fast = 0;
 #endif
@@ -1290,11 +1163,10 @@ static int internal_command (unsigned char target, unsigned char lun,
 #endif
             )
           {
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+            DPRINTK (DEBUG_FAST,
+                    "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
                     "         len = %d, data = %08x\n",
                   hostno, SCint->underflow, SCint->transfersize, len, data);
-#endif
 
 /* SJT: Start. Fast Write */
 #ifdef SEAGATE_USE_ASM
@@ -1332,13 +1204,11 @@ static int internal_command (unsigned char target, unsigned char lun,
 /* SJT: End */
             len -= transfersize;
             data += transfersize;
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer complete len = %d data = %08x\n",
+            DPRINTK (DEBUG_FAST,
+                    "scsi%d : FAST transfer complete len = %d data = %08x\n",
                     hostno, len, data);
-#endif
           }
           else
-#endif /* ifdef FAST */
           {
 /*
  *    We loop as long as we are in a data out phase, there is data to send,
@@ -1404,15 +1274,14 @@ static int internal_command (unsigned char target, unsigned char lun,
             ++buffer;
             len = buffer->length;
             data = (unsigned char *) buffer->address;
-#if (DEBUG & DEBUG_SG)
-            printk ("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+            DPRINTK (DEBUG_SG,
+                   "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
                     hostno, len, data);
-#endif
           }
           break;
 
         case REQ_DATAIN:
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
           if (borken)
           {
 #if (DEBUG & (PHASE_DATAIN))
@@ -1432,7 +1301,7 @@ static int internal_command (unsigned char target, unsigned char lun,
           }
           else
 #endif
-#ifdef FAST
+
             if (fast && transfersize && !(len % transfersize) &&
                 (len >= transfersize)
 #ifdef FAST32
@@ -1440,11 +1309,11 @@ static int internal_command (unsigned char target, unsigned char lun,
 #endif
             )
           {
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+            DPRINTK (DEBUG_FAST,
+                    "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
                     "         len = %d, data = %08x\n",
                   hostno, SCint->underflow, SCint->transfersize, len, data);
-#endif
+
 /* SJT: Start. Fast Read */
 #ifdef SEAGATE_USE_ASM
             __asm__(
@@ -1486,13 +1355,11 @@ static int internal_command (unsigned char target, unsigned char lun,
             transfered += transfersize;
 #endif
 
-#if (DEBUG & DEBUG_FAST)
-            printk ("scsi%d : FAST transfer complete len = %d data = %08x\n",
+            DPRINTK (DEBUG_FAST,
+                    "scsi%d : FAST transfer complete len = %d data = %08x\n",
                     hostno, len, data);
-#endif
           }
           else
-#endif
           {
 
 #if (DEBUG & PHASE_DATAIN)
@@ -1571,10 +1438,9 @@ static int internal_command (unsigned char target, unsigned char lun,
             ++buffer;
             len = buffer->length;
             data = (unsigned char *) buffer->address;
-#if (DEBUG & DEBUG_SG)
-            printk ("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+            DPRINTK (DEBUG_SG, 
+                    "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
                     hostno, len, data);
-#endif
           }
 
           break;
@@ -1586,7 +1452,7 @@ static int internal_command (unsigned char target, unsigned char lun,
             {
               WRITE_DATA (*(const unsigned char *) cmnd);
               cmnd = 1 + (const unsigned char *) cmnd;
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
               if (borken)
                 borken_wait ();
 #endif
@@ -1613,9 +1479,7 @@ static int internal_command (unsigned char target, unsigned char lun,
             case CAN_RECONNECT:
               WRITE_DATA (IDENTIFY (1, lun));
 
-#if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT))
-              printk ("scsi%d : sent IDENTIFY message.\n", hostno);
-#endif
+              DPRINTK (PHASE_RESELECT | PHASE_MSGOUT, "scsi%d : sent IDENTIFY message.\n", hostno);
               break;
 #ifdef LINKED
             case LINKED_WRONG:
@@ -1623,13 +1487,10 @@ static int internal_command (unsigned char target, unsigned char lun,
               linked_connected = 0;
               reselect = CAN_RECONNECT;
               goto connect_loop;
-#if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
-              printk ("scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGOUT | DEBUG_LINKED, 
+                      "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
 #endif /* LINKED */
-#if (DEBUG & DEBUG_LINKED)
-              printk ("correct\n");
-#endif
+              DPRINTK (DEBUG_LINKED, "correct\n");
             default:
               WRITE_DATA (NOP);
               printk ("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
@@ -1640,6 +1501,7 @@ static int internal_command (unsigned char target, unsigned char lun,
           switch (message = DATA)
           {
             case DISCONNECT:
+             DANY ("seagate: deciding to disconnect\n");
               should_reconnect = 1;
               current_data = data;      /* WDE add */
               current_buffer = buffer;
@@ -1649,9 +1511,7 @@ static int internal_command (unsigned char target, unsigned char lun,
               linked_connected = 0;
 #endif
               done = 1;
-#if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
-              printk ("scsi%d : disconnected.\n", hostno);
-#endif
+              DPRINTK ((PHASE_RESELECT | PHASE_MSGIN), "scsi%d : disconnected.\n", hostno);
               break;
 
 #ifdef LINKED
@@ -1662,15 +1522,11 @@ static int internal_command (unsigned char target, unsigned char lun,
 /*
  * Note : we should check for underflow here.
  */
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : command complete.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : command complete.\n", hostno);
               done = 1;
               break;
             case ABORT:
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : abort message.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : abort message.\n", hostno);
               done = 1;
               break;
             case SAVE_POINTERS:
@@ -1678,9 +1534,7 @@ static int internal_command (unsigned char target, unsigned char lun,
               current_bufflen = len;    /* WDE add */
               current_data = data;      /* WDE mod */
               current_nobuffs = nobuffs;
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : pointers saved.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : pointers saved.\n", hostno);
               break;
             case RESTORE_POINTERS:
               buffer = current_buffer;
@@ -1688,15 +1542,13 @@ static int internal_command (unsigned char target, unsigned char lun,
               data = current_data;      /* WDE mod */
               len = current_bufflen;
               nobuffs = current_nobuffs;
-#if (DEBUG & PHASE_MSGIN)
-              printk ("scsi%d : pointers restored.\n", hostno);
-#endif
+              DPRINTK (PHASE_MSGIN, "scsi%d : pointers restored.\n", hostno);
               break;
             default:
 
 /*
  *    IDENTIFY distinguishes itself from the other messages by setting the
- *      high byte.
+ *      high byte. [FIXME: should not this read "the high bit"? - pavel@ucw.cz]
  *
  *      Note : we need to handle at least one outstanding command per LUN,
  *      and need to hash the SCSI command for that I_T_L nexus based on the
@@ -1705,10 +1557,8 @@ static int internal_command (unsigned char target, unsigned char lun,
 
               if (message & 0x80)
               {
-#if (DEBUG & PHASE_MSGIN)
-                printk ("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
+                DPRINTK (PHASE_MSGIN, "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
                         hostno, target, message & 7);
-#endif
               }
               else
               {
@@ -1719,10 +1569,8 @@ static int internal_command (unsigned char target, unsigned char lun,
  *      needs some serious restructuring first though.
  */
 
-#if (DEBUG & PHASE_MSGIN)
-                printk ("scsi%d : unknown message %d from target %d.\n",
-                        hostno, message, target);
-#endif
+                DPRINTK (PHASE_MSGIN, 
+                        "scsi%d : unknown message %d from target %d.\n", hostno, message, target);
               }
           }
           break;
@@ -1733,7 +1581,7 @@ static int internal_command (unsigned char target, unsigned char lun,
       }                                 /* end of switch (status_read &
                                            REQ_MASK) */
 
-#ifdef SLOW_HANDSHAKE
+#ifdef SLOW_RATE
 /*
  * I really don't care to deal with borken devices in each single
  * byte transfer case (ie, message in, message out, status), so
@@ -1747,9 +1595,8 @@ static int internal_command (unsigned char target, unsigned char lun,
   }                                     /* while(((status_read = STATUS)...)
                                            ends */
 
-#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
-  printk ("scsi%d : Transfered %d bytes\n", hostno, transfered);
-#endif
+  DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT, 
+          "scsi%d : Transfered %d bytes\n", hostno, transfered);
 
 #if (DEBUG & PHASE_EXIT)
 #if 0                                   /* Doesn't work for scatter/gather */
@@ -1764,17 +1611,6 @@ static int internal_command (unsigned char target, unsigned char lun,
 #endif
 
 /* We shouldn't reach this until *after* BSY has been deasserted */
-#ifdef notyet
-  if (st0x_aborted)
-  {
-    if (STATUS & STAT_BSY)
-    {
-      seagate_st0x_reset (NULL);
-      st0x_aborted = DID_RESET;
-    }
-    abort_confirm = 1;
-  }
-#endif
 
 #ifdef LINKED
   else
@@ -1797,10 +1633,8 @@ static int internal_command (unsigned char target, unsigned char lun,
         linked_target = current_target;
         linked_lun = current_lun;
         linked_connected = 1;
-#if (DEBUG & DEBUG_LINKED)
-        printk ("scsi%d : keeping I_T_L nexus established for linked command.\n",
-                hostno);
-#endif
+       DPRINTK (DEBUG_LINKED, "scsi%d : keeping I_T_L nexus established"
+                "for linked command.\n", hostno);
     /* We also will need to adjust status to accommodate intermediate
        conditions. */
         if ((status == INTERMEDIATE_GOOD) ||
@@ -1814,9 +1648,7 @@ static int internal_command (unsigned char target, unsigned char lun,
  * and flake if things aren't right.
  */
       default:
-#if (DEBUG & DEBUG_LINKED)
-        printk ("scsi%d : closing I_T_L nexus.\n", hostno);
-#endif
+        DPRINTK (DEBUG_LINKED, "scsi%d : closing I_T_L nexus.\n", hostno);
         linked_connected = 0;
     }
   }
@@ -1824,10 +1656,8 @@ static int internal_command (unsigned char target, unsigned char lun,
 
   if (should_reconnect)
   {
-#if (DEBUG & PHASE_RESELECT)
-    printk ("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
-            hostno);
-#endif
+    DPRINTK (PHASE_RESELECT, "scsi%d : exiting seagate_st0x_queue_command()"
+            "with reconnect enabled.\n", hostno);
     WRITE_CONTROL (BASE_CMD | CMD_INTR);
   }
   else
@@ -1841,32 +1671,27 @@ int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
   st0x_aborted = DID_ABORT;
   return SCSI_ABORT_PENDING;
 }
+#undef ULOOP
+#undef TIMEOUT
 
 /*
-   the seagate_st0x_reset function resets the SCSI bus */
+ * the seagate_st0x_reset function resets the SCSI bus 
+ */
 
 int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 {
-  unsigned clock;
-
 /* No timeouts - this command is going to fail because it was reset. */
-#ifdef DEBUG
-  printk ("In seagate_st0x_reset()\n");
-#endif
+  DANY ("scsi%d: Reseting bus... ", hostno );
 
 /* assert  RESET signal on SCSI bus.  */
   WRITE_CONTROL (BASE_CMD | CMD_RST);
-  clock = jiffies + 2;
 
-/* Wait.  */
-  while (jiffies < clock) ;
+  udelay( 20*1000 );
 
   WRITE_CONTROL (BASE_CMD);
   st0x_aborted = DID_RESET;
 
-#ifdef DEBUG
-  printk ("SCSI bus reset.\n");
-#endif
+  DANY ("done.\n");
   return SCSI_RESET_WAKEUP;
 }
 
index 2d07fd9a7e3b5752f06af4e66c694fab4358140f..c8ead00c4df683403d31fc372c0e1ef9904d73cc 100644 (file)
@@ -20,10 +20,6 @@ int seagate_st0x_abort(Scsi_Cmnd *);
 const char *seagate_st0x_info(struct Scsi_Host *);
 int seagate_st0x_reset(Scsi_Cmnd *, unsigned int); 
 
-#ifndef NULL
-       #define NULL 0
-#endif
-
 #include <linux/kdev_t.h>
 int seagate_st0x_biosparam(Disk *, kdev_t, int*);
 
index 4232a56a5845a480c79184ebb0dcec90bf7e922a..8eb3894cd70811cbe483be0bceb30ecf438033e3 100644 (file)
@@ -574,6 +574,7 @@ static struct file_operations sg_fops = {
     sg_ioctl,        /* ioctl */
     NULL,            /* mmap */
     sg_open,         /* open */
+    NULL,           /* flush */
     sg_close,        /* release */
     NULL             /* fsync */
 };
index a0adf83b33bfc6f46114bec9fe61627e08980b53..38b05c29a2094efd07bbba86451e5c0439ae5874 100644 (file)
@@ -3162,6 +3162,7 @@ static struct file_operations st_fops = {
    st_ioctl,        /* ioctl */
    NULL,            /* mmap */
    scsi_tape_open,  /* open */
+   NULL,           /* flush */
    scsi_tape_close, /* release */
    NULL                    /* fsync */
 };
index b7e69b243ccd44654b268cafeeab0faec09c0cdc..80803da81c88e34284326ef6015ee86221493f5f 100644 (file)
@@ -274,6 +274,7 @@ struct file_operations sgi_graphics_fops = {
        sgi_graphics_ioctl,     /* ioctl */
        sgi_graphics_mmap,      /* mmap */
        sgi_graphics_open,      /* open */
+       NULL,                   /* flush */
        sgi_graphics_close,     /* release */
        NULL,                   /* fsync */
        NULL,                   /* check_media_change */
index 81d43617ae5661214ff11e259c98a2d7c325b438..6a41d0ae0c0b8b4634556933f030c6b3589f67ac 100644 (file)
@@ -445,6 +445,7 @@ file_operations shmiq_fops =
         shmiq_qcntl_ioctl,      /* ioctl */
         shmiq_qcntl_mmap,       /* mmap */
         shmiq_qcntl_open,       /* open */
+       NULL,                   /* flush */
         shmiq_qcntl_close,      /* close */
         NULL,                   /* fsync */
         shmiq_qcntl_fasync,     /* fasync */
index f26aad0e2cd630e352f8c135b4a8b3faed12f3ed..a1f4b07b215f7e743ab17d81d18ece078b0af89e 100644 (file)
@@ -79,6 +79,7 @@ struct file_operations sgi_gfx_fops = {
        sgi_gfx_ioctl,          /* ioctl */
        NULL,                   /* mmap */
        sgi_gfx_open,           /* open */
+       NULL,                   /* flush */
        sgi_gfx_close,          /* release */
        NULL,                   /* fsync */
        NULL,                   /* check_media_change */
@@ -199,6 +200,7 @@ struct file_operations sgi_keyb_fops = {
        sgi_keyb_ioctl,         /* ioctl */
        NULL,                   /* mmap */
        sgi_keyb_open,          /* open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        NULL,                   /* fsync */
        NULL,                   /* check_media_change */
@@ -339,6 +341,7 @@ struct file_operations sgi_mouse_fops = {
        sgi_mouse_ioctl,        /* ioctl */
        NULL,                   /* mmap */
        sgi_mouse_open,         /* open */
+       NULL,                   /* flush */
        sgi_mouse_close,        /* release */
        NULL,                   /* fsync */
        NULL,                   /* check_media_change */
index 4ca11db5177d78998041ca7c82aebd2236d576a9..5bf0e4ee7e6a9b8293d8323e6f44773229c4ead6 100644 (file)
@@ -172,6 +172,7 @@ struct file_operations sgi_usemaclone_fops = {
        sgi_usemaclone_ioctl,   /* ioctl */
        NULL,                   /* mmap */
        sgi_usemaclone_open,    /* open */
+       NULL,                   /* flush */
        sgi_usemaclone_release, /* release */
        NULL,                   /* fsync */
        NULL,                   /* check_media_change */
index 95a89cdb6eb94e4b3d5b47987cfe5e25e2adc5ce..ae125308d8af84ad70abc77aaecb7880570c26ee 100644 (file)
@@ -156,7 +156,7 @@ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
 
   dep_tristate 'Support for Crystal CS4232 based (PnP) cards' CONFIG_SOUND_CS4232 $CONFIG_SOUND_OSS
   if [ "$CONFIG_SOUND_CS4232" = "y" ]; then
-      hex 'CS4232 audio I/O base 530, 604, E80 or F40' CONFIG_CS4232_BASE 530
+      hex 'CS4232 audio I/O base (normally 530, 604, E80 or F40)' CONFIG_CS4232_BASE 530
       int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CONFIG_CS4232_IRQ 11
       int 'CS4232 audio DMA 0, 1 or 3' CONFIG_CS4232_DMA 0
       int 'CS4232 second (duplex) DMA 0, 1 or 3' CONFIG_CS4232_DMA2 3
index f944252bf2b706f7f8e0a0ce7aa8d6e69784d758..b351c73db614f0c62eec75227f320737b2c20d39 100644 (file)
@@ -3808,6 +3808,7 @@ static struct file_operations mixer_fops =
        mixer_ioctl,
        NULL,                   /* mixer_mmap */
        mixer_open,
+       NULL,                   /* flush */
        mixer_release,
 };
 
@@ -4169,6 +4170,7 @@ static struct file_operations sq_fops =
        sq_ioctl,
        NULL,                   /* sq_mmap */
        sq_open,
+       NULL,                   /* flush */
        sq_release,
 };
 
@@ -4363,6 +4365,7 @@ static struct file_operations state_fops =
        NULL,                   /* state_ioctl */
        NULL,                   /* state_mmap */
        state_open,
+       NULL,                   /* flush */
        state_release,
 };
 
index 2e6abb3d66d3560825e18a18182d18361905b469..90d12d84b3baa8cceff12b44b48f6652622781da 100644 (file)
@@ -977,6 +977,7 @@ static /*const*/ struct file_operations es1370_mixer_fops = {
        &es1370_ioctl_mixdev,
        NULL,  /* mmap */
        &es1370_open_mixdev,
+       NULL,   /* flush */
        &es1370_release_mixdev,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -1626,6 +1627,7 @@ static /*const*/ struct file_operations es1370_audio_fops = {
        &es1370_ioctl,
        &es1370_mmap,
        &es1370_open,
+       NULL,   /* flush */
        &es1370_release,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -1992,6 +1994,7 @@ static /*const*/ struct file_operations es1370_dac_fops = {
        &es1370_ioctl_dac,
        &es1370_mmap_dac,
        &es1370_open_dac,
+       NULL,   /* flush */
        &es1370_release_dac,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -2228,6 +2231,7 @@ static /*const*/ struct file_operations es1370_midi_fops = {
        NULL,  /* ioctl */
        NULL,  /* mmap */
        &es1370_midi_open,
+       NULL,   /* flush */
        &es1370_midi_release,
        NULL,  /* fsync */
        NULL,  /* fasync */
index 6a510d9d4db41450262c51ff0222aa94c3cf44ae..4963d1271500fe221e1fd7ab8035aea3d5321d41 100644 (file)
@@ -1425,6 +1425,7 @@ static /*const*/ struct file_operations es1371_mixer_fops = {
        &es1371_ioctl_mixdev,
        NULL,  /* mmap */
        &es1371_open_mixdev,
+       NULL,   /* flush */
        &es1371_release_mixdev,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -2072,6 +2073,7 @@ static /*const*/ struct file_operations es1371_audio_fops = {
        &es1371_ioctl,
        &es1371_mmap,
        &es1371_open,
+       NULL,   /* flush */
        &es1371_release,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -2428,6 +2430,7 @@ static /*const*/ struct file_operations es1371_dac_fops = {
        &es1371_ioctl_dac,
        &es1371_mmap_dac,
        &es1371_open_dac,
+       NULL,   /* flush */
        &es1371_release_dac,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -2663,6 +2666,7 @@ static /*const*/ struct file_operations es1371_midi_fops = {
        NULL,  /* ioctl */
        NULL,  /* mmap */
        &es1371_midi_open,
+       NULL,   /* flush */
        &es1371_midi_release,
        NULL,  /* fsync */
        NULL,  /* fasync */
index 86c93b55bc213d362d39dcedbf2431a15e4e73a1..76fba8dee84d6a058b9da9b38c5858afc952febb 100644 (file)
@@ -11,7 +11,8 @@ Hannu Savolainen (hannu@voxware.pp.fi) for more info.
 The following low level drivers are included:
 
 - ACI MIXER for miroPCM12 by Markus Kuhn
-(mskuhn@cip.informatik.uni-erlangen.de).
+  (mskuhn@cip.informatik.uni-erlangen.de).
+- Audio Excel DSP 16 initialization driver by Riccardo Facchetti
+  (fizban@tin.it)
 - SB32/AWE synthesizer driver (Emu8000) by Takashi Iwai
-(iwai@dragon.mm.t.u-tokyo.ac.jp). See README.awe for more
-info.
+  (iwai@dragon.mm.t.u-tokyo.ac.jp). See README.awe for more info.
diff --git a/drivers/sound/lowlevel/README.aedsp16 b/drivers/sound/lowlevel/README.aedsp16
deleted file mode 100644 (file)
index 8f5b05a..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-Driver
-------
-
-Informations about Audio Excel DSP 16 driver can be found in the source
-file lowlevel/aedsp16.c
-Please, read the head of the source before using it. It contain useful
-informations.
-
-Configuration
--------------
-
-The Audio Excel configuration, is now done with the standard Linux setup.
-You have to configure the sound card (Sound Blaster or Microsoft Sound System)
-and, if you want it, the Roland MPU-401 (do not use the Sound Blaster MPU-401,
-SB-MPU401) in the main driver menu. Activate the lowlevel drivers then select
-the Audio Excel hardware that you want to initialize. Check the IRQ/DMA/MIRQ
-of the Audio Excel initialization: it must be the same as the SBPRO (or MSS)
-setup. If the parameters are different, correct it.
-I you own a Gallant's audio card based on SC-6600, activate the SC-6600 support.
-If you want to change the configuration of the sound board, be sure to
-check off all the configuration items before re-configure it.
-
-Module parameters
------------------
-To use this driver as a module, you must configure some module parameters, to
-set up I/O addresses, IRQ lines and DMA channels. Some parameters are
-mandatory while some others are optional. Here a list of parameters you can
-use with this module:
-
-Name           Description
-====           ===========
-MANDATORY
-io             I/O base address (0x220 or 0x240)
-irq            irq line (5, 7, 9, 10 or 11)
-dma            dma channel (0, 1 or 3)
-
-OPTIONAL
-mss_base       I/O base address for activate MSS mode (default SBPRO)
-               (0x530 or 0xE80)
-mpu_base       I/O base address for activate MPU-401 mode
-               (0x300, 0x310, 0x320 or 0x330)
-mpu_irq                MPU-401 irq line (5, 7, 9, 10 or 0)
-
-The /etc/conf.modules will have a line like this:
-
-options aedsp16 io=0x220 irq=10 dma=3 mss_base=0x530
-
-Of course, you must write the 'options' for all other subsequent modules,
-opl3, ad1848, adlib_card, sb
-
-Then you must load the sound modules stack in this order:
-sound -> aedsp16 -> [ ad1848, opl3 ]
-
-Sound cards supported
----------------------
-This driver supports the SC-6000 and SC-6600 based Gallant's sound card.
-It don't support the Audio Excel DSP 16 III (try the SC-6600 code).
-I'm working on the III version of the card: if someone have useful
-informations about it, please let me know.
-For all the non-supported audio cards, you have to boot MS-DOS (or WIN95)
-activating the audio card with the MS-DOS device driver, then you have to
-<ctrl>-<alt>-<del> and boot Linux.
-Follow these steps:
-
-1) Compile Linux kernel with standard sound driver, using the emulation
-   you want, with the parameters of your audio card,
-   e.g. Microsoft Sound System irq10 dma3
-2) Install your new kernel as the default boot kernel.
-3) Boot MS-DOS and configure the audio card with the boot time device
-   driver, for MSS irq10 dma3 in our example.
-4) <ctrl>-<alt>-<del> and boot Linux. This will mantain the DOS configuration
-   and will boot the new kernel with sound driver. The sound driver will find
-   the audio card and will recognize and attach it.
-
-Reports on User successes
--------------------------
-
-[--------------------------------------------------------------------------]
-
-From POPmail Mon Jul 29 18:23:12 1996
-Received: from cdc8g5.cdc.polimi.it by mbox.vol.it with SMTP
-       (1.39.111.2/16.2) id AA257995686; Mon, 29 Jul 1996 09:34:46 +0200
-Return-Path: <sjg95@unixfe.rl.ac.uk>
-Received: from [130.246.12.16] by cdc8g5.cdc.polimi.it with SMTP
-       (1.38.193.4/15.6) id AA27426; Mon, 29 Jul 1996 09:42:49 +0200
-Posted-Date: Mon, 29 Jul 1996 08:35:40 +0100
-Received-Date: Mon, 29 Jul 1996 09:42:49 +0200
-Received: (from sjg95@localhost) by unixfe.rl.ac.uk (8.7.3/8.7.3) 
-          id IAA58788 for riccardo@cdc8g5.cdc.polimi.it; Mon, 29 Jul 1996 08:35:40 +0100
-Date: Mon, 29 Jul 1996 08:35:40 +0100
-From: Mr S J Greenaway <sjg95@unixfe.rl.ac.uk>
-Message-Id: <199607290735.IAA58788@unixfe.rl.ac.uk>
-To: riccardo@cdc8g5.cdc.polimi.it (Riccardo Facchetti)
-Subject: Re: Audio Excel DSP 16 initialization code
-Newsgroups: comp.os.linux.announce
-X-Newsreader: TIN [version 1.2 PL2]
-Status: RO
-X-Status: A
-
-Just to let you know got my Audio Excel (emulating a MSS) working
-with my original SB16, thanks for the driver!
-
-/dev/sndstat:
-
-Linux huey 2.0.9 #10 Sat Jul 27 11:41:42 BST 1996 i586)
-Kernel: Linux huey 2.0.9 #14 Sun Jul 28 12:50:43 BST 1996 i586
-Config options: c0202
-
-Installed drivers: 
-Type 10: MS Sound System
-Type 24: MS Sound System (AXP)
-Type 27: Compaq Deskpro XL
-Type 2: Sound Blaster
-
-Card config: 
-MS Sound System at 0x530 irq 11 drq 3
-Sound Blaster at 0x240 irq 5 drq 1,5
-
-Audio devices:
-0: MSS audio codec (CS4231A)
-1: Sound Blaster 16 (4.12)
-
-Synth devices:
-
-Midi devices: NOT ENABLED IN CONFIG
-
-Timers:
-0: System clock
-1: MSS audio codec (CS4231A)
-
-Mixers:
-0: MSS audio codec (CS4231A)
-1: Sound Blaster
-
-[--------------------------------------------------------------------------]
-
-    Riccardo
index b98c02ea6d5ef33435522065f81b3e5a224fa61c..fc71be47dc6a466359e0a434c656dc3813e10fb9 100644 (file)
@@ -4,17 +4,21 @@
  * ACI is a protocol used to communicate with the microcontroller on
  * some sound cards produced by miro, e.g. the miroSOUND PCM12 and
  * PCM20. The ACI has been developed for miro by Norberto Pellicci
- * <pellicci@ix.netcom.com>. Special thanks to both him and miro for
+ * <pellicci@home.com>. Special thanks to both him and miro for
  * providing the ACI specification.
  *
  * The main function of the ACI is to control the mixer and to get a
  * product identification. On the PCM20, ACI also controls the radio
- * tuner on this card, however this is not yet supported in this
- * software.
+ * tuner on this card, this is supported in the Video for Linux 
+ * radio-miropcm20 driver.
  * 
  * This Voxware ACI driver currently only supports the ACI functions
- * on the miroSOUND PCM12 card. Support for miro sound cards with
- * additional ACI functions can easily be added later.
+ * on the miroSOUND PCM12 and PCM20 card. Support for miro sound cards 
+ * with additional ACI functions can easily be added later.
+ *
+ * / NOTE / When compiling as a module, make sure to load the module 
+ * after loading the mad16 module. The initialisation code expects the
+ * MAD16 default mixer to be already available.
  *
  * / NOTE / When compiling as a module, make sure to load the module 
  * after loading the mad16 module. The initialisation code expects the
@@ -31,8 +35,9 @@
  *   1996-05-28  Markus Kuhn
  *        Initialize CS4231A mixer, make ACI first mixer,
  *        use new private mixer API for solo mode.
- *   1998-08-04  Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
- *       Small modification to complete modularisation.
+ *   1998-08-18  Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
+ *       Small modification to export ACI functions and 
+ *       complete modularisation.
  */
 
 /*
@@ -84,7 +89,7 @@ static int aci_present = 0;
 #ifdef MODULE                  /* Whether the aci mixer is to be reset.    */
 int aci_reset = 0;             /* Default: don't reset if the driver is a  */
 MODULE_PARM(aci_reset,"i");
-#else                          /* module; use "insmod sound.o aci_reset=1" */
+#else                          /* module; use "insmod aci.o aci_reset=1" */
 int aci_reset = 1;             /* to override.                             */
 #endif
 
@@ -150,12 +155,12 @@ static int read_general_status(void)
  * If a problem occurred, they return -1.
  */
 
-static int implied_cmd(unsigned char opcode)
+int aci_implied_cmd(unsigned char opcode)
 {
   unsigned long flags;
 
 #ifdef DEBUG
-  printk("ACI: implied_cmd(0x%02x)\n", opcode);
+  printk("ACI: aci_implied_cmd(0x%02x)\n", opcode);
 #endif
 
   save_flags(flags);
@@ -172,13 +177,13 @@ static int implied_cmd(unsigned char opcode)
 }
 
 
-static int write_cmd(unsigned char opcode, unsigned char parameter)
+int aci_write_cmd(unsigned char opcode, unsigned char parameter)
 {
   unsigned long flags;
   int status;
 
 #ifdef DEBUG
-  printk("ACI: write_cmd(0x%02x, 0x%02x)\n", opcode, parameter);
+  printk("ACI: aci_write_cmd(0x%02x, 0x%02x)\n", opcode, parameter);
 #endif
 
   save_flags(flags);
@@ -209,8 +214,53 @@ static int write_cmd(unsigned char opcode, unsigned char parameter)
   return 0;
 }
 
+/*
+ * This write command send 2 parameters instead of one.
+ * Only used in PCM20 radio frequency tuning control
+ */
+
+int aci_write_cmd_d(unsigned char opcode, unsigned char parameter, unsigned char parameter2)
+{
+  unsigned long flags;
+  int status;
+
+#ifdef DEBUG
+  printk("ACI: aci_write_cmd_d(0x%02x, 0x%02x)\n", opcode, parameter, parameter2);
+#endif
+
+  save_flags(flags);
+  cli();
+  
+  if (read_general_status() < 0 || busy_wait()) {
+    restore_flags(flags);
+    return -1;
+  }
+  outb_p(opcode, COMMAND_REGISTER);
+  if (busy_wait()) { restore_flags(flags); return -1; }
+  outb_p(parameter, COMMAND_REGISTER);
+  if (busy_wait()) { restore_flags(flags); return -1; }
+  outb_p(parameter2, COMMAND_REGISTER);
+
+  if ((status = read_general_status()) < 0) {
+    restore_flags(flags);
+    return -1;
+  }
+  /* polarity of the INVALID flag depends on ACI version */
+  if ((aci_version <  0xb0 && (status & 0x40) != 0) ||
+      (aci_version >= 0xb0 && (status & 0x40) == 0)) {
+    restore_flags(flags);
+#if 0  /* Frequency tuning works, but the INVALID flag is set ??? */
+    printk("ACI: invalid write (double) command 0x%02x, 0x%02x, 0x%02x.\n",
+          opcode, parameter, parameter2);
+#endif
+    return -1;
+  }
+
+  restore_flags(flags);
+  return 0;
+}
 
-static int read_cmd(unsigned char opcode, int length, unsigned char *parameter)
+int aci_read_cmd(unsigned char opcode, int length, unsigned char *parameter)
 {
   unsigned long flags;
   int i = 0;
@@ -226,10 +276,10 @@ static int read_cmd(unsigned char opcode, int length, unsigned char *parameter)
     parameter[i++] = inb_p(STATUS_REGISTER);
 #ifdef DEBUG
     if (i == 1)
-      printk("ACI: read_cmd(0x%02x, %d) = 0x%02x\n", opcode, length,
+      printk("ACI: aci_read_cmd(0x%02x, %d) = 0x%02x\n", opcode, length,
             parameter[i-1]);
     else
-      printk("ACI: read_cmd cont.: 0x%02x\n", parameter[i-1]);
+      printk("ACI: aci_read_cmd cont.: 0x%02x\n", parameter[i-1]);
 #endif
   }
 
@@ -238,7 +288,7 @@ static int read_cmd(unsigned char opcode, int length, unsigned char *parameter)
 }
 
 
-static int indexed_cmd(unsigned char opcode, unsigned char index,
+int aci_indexed_cmd(unsigned char opcode, unsigned char index,
                       unsigned char *parameter)
 {
   unsigned long flags;
@@ -256,7 +306,7 @@ static int indexed_cmd(unsigned char opcode, unsigned char index,
   if (busy_wait()) { restore_flags(flags); return -1; }
   *parameter = inb_p(STATUS_REGISTER);
 #ifdef DEBUG
-  printk("ACI: indexed_cmd(0x%02x, 0x%02x) = 0x%02x\n", opcode, index,
+  printk("ACI: aci_indexed_cmd(0x%02x, 0x%02x) = 0x%02x\n", opcode, index,
         *parameter);
 #endif
 
@@ -292,10 +342,10 @@ static int getvolume(caddr_t arg,
   unsigned char buf;
 
   /* left channel */
-  if (indexed_cmd(0xf0, left_index, &buf)) return -EIO;
+  if (aci_indexed_cmd(0xf0, left_index, &buf)) return -EIO;
   vol = SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0);
   /* right channel */
-  if (indexed_cmd(0xf0, right_index, &buf)) return -EIO;
+  if (aci_indexed_cmd(0xf0, right_index, &buf)) return -EIO;
   vol |= SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0) << 8;
 
   return (*(int *) arg = vol);
@@ -311,13 +361,13 @@ static int setvolume(caddr_t arg,
   vol = *(int *)arg & 0xff;
   if (vol > 100) vol = 100;
   vol = SCALE(100, 0x20, vol);
-  if (write_cmd(left_index, 0x20 - vol)) return -EIO;
+  if (aci_write_cmd(left_index, 0x20 - vol)) return -EIO;
   ret = SCALE(0x20, 100, vol);
   /* right channel */
   vol = (*(int *)arg >> 8) & 0xff;
   if (vol > 100) vol = 100;
   vol = SCALE(100, 0x20, vol);
-  if (write_cmd(right_index, 0x20 - vol)) return -EIO;
+  if (aci_write_cmd(right_index, 0x20 - vol)) return -EIO;
   ret |= SCALE(0x20, 100, vol) << 8;
  
   return (*(int *) arg = ret);
@@ -334,7 +384,7 @@ aci_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
   if (cmd == SOUND_MIXER_PRIVATE1) {
     if (*(int *) arg >= 0) {
       aci_solo = !!*(int *) arg;
-      if (write_cmd(0xd2, aci_solo)) return -EIO;
+      if (aci_write_cmd(0xd2, aci_solo)) return -EIO;
     } else if (aci_version >= 0xb0) {
       if ((status = read_general_status()) < 0) return -EIO;
       return (*(int *) arg = (status & 0x20) == 0);
@@ -366,7 +416,7 @@ aci_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
        vol = *(int *) arg & 0xff;
        if (vol > 100) vol = 100;
        vol = SCALE(100, 3, vol);
-       if (write_cmd(0x03, vol)) return -EIO;
+       if (aci_write_cmd(0x03, vol)) return -EIO;
        vol = SCALE(3, 100, vol);
        return (*(int *) arg = vol | (vol << 8));
       case SOUND_MIXER_RECSRC:
@@ -421,7 +471,7 @@ aci_mixer_ioctl (int dev, unsigned int cmd, caddr_t arg)
       case SOUND_MIXER_LINE2:  /* AUX2 */
        return getvolume(arg, 0x13, 0x12);
       case SOUND_MIXER_IGAIN:  /* MIC pre-amp */
-       if (indexed_cmd(0xf0, 0x21, &buf)) return -EIO;
+       if (aci_indexed_cmd(0xf0, 0x21, &buf)) return -EIO;
        vol = SCALE(3, 100, buf <= 3 ? buf : 3);
        vol |= vol << 8;
        return (*(int *) arg = vol);
@@ -485,13 +535,13 @@ int attach_aci(void)
     return 0;
   }
 
-  if (read_cmd(0xf2, 2, aci_idcode)) {
+  if (aci_read_cmd(0xf2, 2, aci_idcode)) {
 #ifdef DEBUG
     printk("ACI: Failed to read idcode.\n");
 #endif
     return 0;
   }
-  if (read_cmd(0xf1, 1, &aci_version)) {
+  if (aci_read_cmd(0xf1, 1, &aci_version)) {
 #ifdef DEBUG
     printk("ACI: Failed to read version.\n");
 #endif
@@ -523,7 +573,7 @@ int attach_aci(void)
 
   if (aci_reset) {
     /* initialize ACI mixer */
-    implied_cmd(0xff);
+    aci_implied_cmd(0xff);
     aci_solo = 0;
   }
 
index cb919507ebc86f0e3ebbbda7b33455ba96021fd9..48ef93f19552929ae99489aea6c797b60da6a326 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include "../sound_config.h"
 #include "../soundmodule.h"
 
      the flexibility of modular version, I have removed all the conditional
      compilation for SBPRO, MPU and MSS code. Now it is all managed with
      the ae_config structure.
+   v1.2
+   - Module informations added.
+   - Removed aedsp16_delay_10msec(), now using mdelay(10)
+   - All data and funcs moved to .*.init section.
 
    Known Problems:
    - Audio Excel DSP 16 III don't work with this driver.
  */
 
 
-#define VERSION "1.1"          /* Version of Audio Excel DSP 16 driver */
+#define VERSION "1.2"          /* Version of Audio Excel DSP 16 driver */
 
 #undef AEDSP16_DEBUG 1         /* Define this to enable debug code     */
 #undef AEDSP16_DEBUG_MORE 1    /* Define this to enable more debug     */
 #define INIT_MSS    (1<<1)
 #define INIT_MPU401 (1<<2)
 
-static int      soft_cfg = 0;  /* Will contain or'ed values of soft cf */
-static int      soft_cfg_1 = 0;        /* Will contain or'ed values of some cf */
-static int      gc = 0;                /* generic counter (utility counter)    */
-static int      ver[3];         /* DSP Version, hi<-ver[0], lo<-ver[1]  */
+static int      soft_cfg __initdata = 0;       /* bitmapped config */
+static int      soft_cfg_mss __initdata = 0;   /* bitmapped mss config */
+static int      ver[CARDVERLEN] __initdata = {0, 0};   /* DSP Ver:
+                                                  hi->ver[0] lo->ver[1] */
 
 #if defined(CONFIG_SC6600)
 static int     hard_cfg[2]     /* lo<-hard_cfg[0] hi<-hard_cfg[1]      */
-                     = { 0, 0};
+                     __initdata = { 0, 0};
 #endif /* CONFIG_SC6600 */
 
 #if defined(CONFIG_SC6600)
@@ -440,7 +445,10 @@ struct     d_hcfg {
        int wssbase;
        int cdrom;
        int cdrombase;
-} decoded_hcfg;
+};
+
+struct d_hcfg decoded_hcfg __initdata = {0, };
+
 #endif /* CONFIG_SC6600 */
 
 /* orVals contain the values to be or'ed                                       */
@@ -464,7 +472,7 @@ struct aedsp16_info {
  * Magic values that the DSP will eat when configuring irq/mirq/dma
  */
 /* DSP IRQ conversion array             */
-static struct orVals orIRQ[] = {
+static struct orVals orIRQ[] __initdata = {
        {0x05, 0x28},
        {0x07, 0x08},
        {0x09, 0x10},
@@ -474,7 +482,7 @@ static struct orVals orIRQ[] = {
 };
 
 /* MPU-401 IRQ conversion array         */
-static struct orVals orMIRQ[] = {
+static struct orVals orMIRQ[] __initdata = {
        {0x05, 0x04},
        {0x07, 0x44},
        {0x09, 0x84},
@@ -483,14 +491,14 @@ static struct orVals orMIRQ[] = {
 };
 
 /* DMA Channels conversion array        */
-static struct orVals orDMA[] = {
+static struct orVals orDMA[] __initdata = {
        {0x00, 0x01},
        {0x01, 0x02},
        {0x03, 0x03},
        {0x00, 0x00}
 };
 
-static struct aedsp16_info ae_config = {
+static struct aedsp16_info ae_config __initdata = {
        DEF_AEDSP16_IOB,
        DEF_AEDSP16_IRQ,
        DEF_AEDSP16_MRQ,
@@ -503,16 +511,10 @@ static struct aedsp16_info ae_config = {
 /*
  * Buffers to store audio card informations
  */
-static char     DSPCopyright[CARDNAMELEN + 1];
-static char     DSPVersion[CARDVERLEN + 1];
+static char     DSPCopyright[CARDNAMELEN + 1] __initdata = {0, };
+static char     DSPVersion[CARDVERLEN + 1] __initdata = {0, };
 
-static void aedsp16_delay_10msec(void)
-{
-       for (gc = 0; gc < 1000; gc++)
-               udelay(10);
-}
-
-static int aedsp16_wait_data(int port)
+static int __init aedsp16_wait_data(int port)
 {
        int             loop = STATUSRETRY;
        unsigned char   ret = 0;
@@ -535,7 +537,7 @@ static int aedsp16_wait_data(int port)
        return FALSE;
 }
 
-static int aedsp16_read(int port)
+static int __init aedsp16_read(int port)
 {
        int inbyte;
 
@@ -553,12 +555,12 @@ static int aedsp16_read(int port)
        return inbyte;
 }
 
-static int aedsp16_test_dsp(int port)
+static int __init aedsp16_test_dsp(int port)
 {
        return ((aedsp16_read(port) == 0xaa) ? TRUE : FALSE);
 }
 
-static int aedsp16_dsp_reset(int port)
+static int __init aedsp16_dsp_reset(int port)
 {
        /*
         * Reset DSP
@@ -579,7 +581,7 @@ static int aedsp16_dsp_reset(int port)
        return FALSE;
 }
 
-static int aedsp16_write(int port, int cmd)
+static int __init aedsp16_write(int port, int cmd)
 {
        unsigned char   ret;
        int             loop = HARDRETRY;
@@ -607,7 +609,7 @@ static int aedsp16_write(int port, int cmd)
 #if defined(CONFIG_SC6600)
 
 #if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
-void aedsp16_pinfo(void) {
+void __init aedsp16_pinfo(void) {
        DBG(("\n Base address:  %x\n", decoded_hcfg.iobase));
        DBG((" Joystick    : %s present\n", decoded_hcfg.joystick?"":" not"));
        DBG((" WSS addr    :  %x\n", decoded_hcfg.wssbase));
@@ -617,7 +619,7 @@ void aedsp16_pinfo(void) {
 }
 #endif
 
-void aedsp16_hard_decode(void) {
+void __init aedsp16_hard_decode(void) {
 
        DBG((" aedsp16_hard_decode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
 
@@ -661,7 +663,7 @@ void aedsp16_hard_decode(void) {
        DBG(("success.\n"));
 }
 
-void aedsp16_hard_encode(void) {
+void __init aedsp16_hard_encode(void) {
 
        DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
 
@@ -686,7 +688,7 @@ void aedsp16_hard_encode(void) {
 
 }
 
-static int aedsp16_hard_write(int port) {
+static int __init aedsp16_hard_write(int port) {
 
        DBG(("aedsp16_hard_write:\n"));
 
@@ -721,7 +723,7 @@ static int aedsp16_hard_write(int port) {
        return TRUE;
 }
 
-static int aedsp16_hard_read(int port) {
+static int __init aedsp16_hard_read(int port) {
 
        DBG(("aedsp16_hard_read:\n"));
 
@@ -755,7 +757,7 @@ static int aedsp16_hard_read(int port) {
        return TRUE;
 }
 
-static int aedsp16_ext_cfg_write(int port) {
+static int __init aedsp16_ext_cfg_write(int port) {
 
        int extcfg, val;
 
@@ -809,7 +811,7 @@ static int aedsp16_ext_cfg_write(int port) {
 
 #endif /* CONFIG_SC6600 */
 
-static int aedsp16_cfg_write(int port) {
+static int __init aedsp16_cfg_write(int port) {
        if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
                printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
                return FALSE;
@@ -821,11 +823,11 @@ static int aedsp16_cfg_write(int port) {
        return TRUE;
 }
 
-static int aedsp16_init_mss(int port)
+static int __init aedsp16_init_mss(int port)
 {
        DBG(("aedsp16_init_mss:\n"));
 
-       aedsp16_delay_10msec();
+       mdelay(10);
 
        if (aedsp16_write(port, DSP_INIT_MSS)) {
                printk("[AEDSP16] aedsp16_init_mss [0x%x]: failed!\n",
@@ -833,19 +835,20 @@ static int aedsp16_init_mss(int port)
                DBG(("failure.\n"));
                return FALSE;
        }
-       aedsp16_delay_10msec();
+       
+       mdelay(10);
 
        if (aedsp16_cfg_write(port) == FALSE)
                return FALSE;
 
-       outb(soft_cfg_1, ae_config.mss_base);
+       outb(soft_cfg_mss, ae_config.mss_base);
 
        DBG(("success.\n"));
 
        return TRUE;
 }
 
-static int aedsp16_setup_board(int port) {
+static int __init aedsp16_setup_board(int port) {
        int     loop = RETRY;
 
 #if defined(CONFIG_SC6600)
@@ -873,7 +876,7 @@ static int aedsp16_setup_board(int port) {
                        printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_88);
                        return FALSE;
                }
-               aedsp16_delay_10msec();
+               mdelay(10);
        } while ((aedsp16_wait_data(port) == FALSE) && loop--);
 
        if (aedsp16_read(port) == -1) {
@@ -934,7 +937,7 @@ static int aedsp16_setup_board(int port) {
        return TRUE;
 }
 
-static int aedsp16_stdcfg(int port) {
+static int __init aedsp16_stdcfg(int port) {
        if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
                printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
                return FALSE;
@@ -949,7 +952,7 @@ static int aedsp16_stdcfg(int port) {
        return TRUE;
 }
 
-static int aedsp16_dsp_version(int port)
+static int __init aedsp16_dsp_version(int port)
 {
        int             len = 0;
        int             ret;
@@ -980,7 +983,7 @@ static int aedsp16_dsp_version(int port)
        return TRUE;
 }
 
-static int aedsp16_dsp_copyright(int port)
+static int __init aedsp16_dsp_copyright(int port)
 {
        int             len = 0;
        int             ret;
@@ -1016,29 +1019,31 @@ static int aedsp16_dsp_copyright(int port)
        return TRUE;
 }
 
-static void aedsp16_init_tables(void)
+static void __init aedsp16_init_tables(void)
 {
+       int i = 0;
+
        memset(DSPCopyright, 0, CARDNAMELEN + 1);
        memset(DSPVersion, 0, CARDVERLEN + 1);
 
-       for (gc = 0; orIRQ[gc].or; gc++)
-               if (orIRQ[gc].val == ae_config.irq) {
-                       soft_cfg |= orIRQ[gc].or;
-                       soft_cfg_1 |= orIRQ[gc].or;
+       for (i = 0; orIRQ[i].or; i++)
+               if (orIRQ[i].val == ae_config.irq) {
+                       soft_cfg |= orIRQ[i].or;
+                       soft_cfg_mss |= orIRQ[i].or;
                }
 
-       for (gc = 0; orMIRQ[gc].or; gc++)
-               if (orMIRQ[gc].or == ae_config.mpu_irq)
-                       soft_cfg |= orMIRQ[gc].or;
+       for (i = 0; orMIRQ[i].or; i++)
+               if (orMIRQ[i].or == ae_config.mpu_irq)
+                       soft_cfg |= orMIRQ[i].or;
 
-       for (gc = 0; orDMA[gc].or; gc++)
-               if (orDMA[gc].val == ae_config.dma) {
-                       soft_cfg |= orDMA[gc].or;
-                       soft_cfg_1 |= orDMA[gc].or;
+       for (i = 0; orDMA[i].or; i++)
+               if (orDMA[i].val == ae_config.dma) {
+                       soft_cfg |= orDMA[i].or;
+                       soft_cfg_mss |= orDMA[i].or;
                }
 }
 
-static int aedsp16_init_board(void)
+static int __init aedsp16_init_board(void)
 {
        aedsp16_init_tables();
 
@@ -1134,12 +1139,12 @@ static int aedsp16_init_board(void)
        printk("]\n");
 #endif /* MODULE || AEDSP16_INFO || AEDSP16_DEBUG */
 
-       aedsp16_delay_10msec();
+       mdelay(10);
 
        return TRUE;
 }
 
-static int init_aedsp16_sb(void)
+static int __init init_aedsp16_sb(void)
 {
        DBG(("init_aedsp16_sb: "));
 
@@ -1159,7 +1164,7 @@ static int init_aedsp16_sb(void)
        return TRUE;
 }
 
-static void uninit_aedsp16_sb(void)
+static void __init uninit_aedsp16_sb(void)
 {
        DBG(("uninit_aedsp16_sb: "));
 
@@ -1168,7 +1173,7 @@ static void uninit_aedsp16_sb(void)
        DBG(("done.\n"));
 }
 
-static int init_aedsp16_mss(void)
+static int __init init_aedsp16_mss(void)
 {
        DBG(("init_aedsp16_mss: "));
 
@@ -1207,7 +1212,7 @@ static int init_aedsp16_mss(void)
        return TRUE;
 }
 
-static void uninit_aedsp16_mss(void)
+static void __init uninit_aedsp16_mss(void)
 {
        DBG(("uninit_aedsp16_mss: "));
 
@@ -1221,7 +1226,7 @@ static void uninit_aedsp16_mss(void)
        DBG(("done.\n"));
 }
 
-static int init_aedsp16_mpu(void)
+static int __init init_aedsp16_mpu(void)
 {
        DBG(("init_aedsp16_mpu: "));
 
@@ -1251,7 +1256,7 @@ static int init_aedsp16_mpu(void)
        return TRUE;
 }
 
-static void uninit_aedsp16_mpu(void)
+static void __init uninit_aedsp16_mpu(void)
 {
        DBG(("uninit_aedsp16_mpu: "));
 
@@ -1266,7 +1271,7 @@ static void uninit_aedsp16_mpu(void)
        DBG(("done.\n"));
 }
 
-int init_aedsp16(void)
+int __init init_aedsp16(void)
 {
        int initialized = FALSE;
 
@@ -1324,7 +1329,7 @@ int init_aedsp16(void)
        return initialized;
 }
 
-void uninit_aedsp16(void)
+void __init uninit_aedsp16(void)
 {
        if (ae_config.mss_base != -1)
                uninit_aedsp16_mss();
@@ -1344,12 +1349,20 @@ int mss_base = -1;
 int mpu_base = -1;
 
 
-MODULE_PARM(io,"i");
-MODULE_PARM(irq,"i");
-MODULE_PARM(dma,"i");
-MODULE_PARM(mpu_irq,"i");
-MODULE_PARM(mss_base,"i");
-MODULE_PARM(mpu_base,"i");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O base address (0x220 0x240)");
+MODULE_PARM(irq, "i");
+MODULE_PARM_DESC(irq, "IRQ line (5 7 9 10 11)");
+MODULE_PARM(dma, "i");
+MODULE_PARM_DESC(dma, "dma line (0 1 3)");
+MODULE_PARM(mpu_irq, "i");
+MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ line (5 7 9 10 0)");
+MODULE_PARM(mss_base, "i");
+MODULE_PARM_DESC(mss_base, "MSS emulation I/O base address (0x530 0xE80)");
+MODULE_PARM(mpu_base, "i");
+MODULE_PARM_DESC(mpu_base,"MPU-401 I/O base address (0x300 0x310 0x320 0x330)");
+MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>");
+MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION);
 
 int init_module(void) {
        printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
diff --git a/drivers/sound/lowlevel/miroaci.h b/drivers/sound/lowlevel/miroaci.h
new file mode 100644 (file)
index 0000000..9d64eaa
--- /dev/null
@@ -0,0 +1,6 @@
+extern int aci_implied_cmd(unsigned char opcode);
+extern int aci_write_cmd(unsigned char opcode, unsigned char parameter);
+extern int aci_write_cmd_d(unsigned char opcode, unsigned char parameter, unsigned char parameter2);
+extern int aci_read_cmd(unsigned char opcode, int length, unsigned char *parameter);
+extern int aci_indexed_cmd(unsigned char opcode, unsigned char index, unsigned char *parameter);
+
index 64ac00ccd95cd1a1752bf1e194edffc8ce5b9ea9..96fdb94be3e93f78549f9782af4f04e83a8e373d 100644 (file)
@@ -5,6 +5,7 @@
 #include "lowlevel.h"
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include "../soundvers.h"
 
 #ifdef LOWLEVEL_MODULE
@@ -15,8 +16,8 @@ extern int attach_aci(void);
 extern void unload_aci(void);
 extern int attach_awe(void);
 extern void unload_awe(void);
-extern int init_aedsp16(void);
-extern void uninit_aedsp16(void);
+extern int init_aedsp16(void) __init;
+extern void uninit_aedsp16(void) __init;
 
 /*
  * There are two places where you can insert initialization calls of
index 07bba6bc6ca6df520d450dfb4fe4e32ac2ce1042..bed4ec1bfe7bfdf7f631cc91ec383f62ec20ed75 100644 (file)
@@ -944,6 +944,7 @@ static struct file_operations dev_fileops = {
        dev_ioctl,
        NULL,
        dev_open,
+       NULL,           /* flush */
        dev_close,
 };
 
index 3ec472f4d26cdaa1e3c1c230ee1264a67032c547..04b3d785414b6d41e9511c24e113380be6826400 100644 (file)
@@ -694,7 +694,7 @@ int sb_dsp_detect(struct address_info *hw_config)
        return 1;
 }
 
-static int sb_dsp_init(struct address_info *hw_config)
+int sb_dsp_init(struct address_info *hw_config)
 {
        sb_devc *devc;
        char name[100];
index 066d722eb95e50403fa21bfad30a1f05496c32f6..0643420881a03c8487a92c33e767c18b0cabd42f 100644 (file)
@@ -1208,6 +1208,7 @@ static /*const*/ struct file_operations sv_mixer_fops = {
        &sv_ioctl_mixdev,
        NULL,  /* mmap */
        &sv_open_mixdev,
+       NULL,   /* flush */
        &sv_release_mixdev,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -1810,6 +1811,7 @@ static /*const*/ struct file_operations sv_audio_fops = {
        &sv_ioctl,
        &sv_mmap,
        &sv_open,
+       NULL,   /* flush */
        &sv_release,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -2054,6 +2056,7 @@ static /*const*/ struct file_operations sv_midi_fops = {
        NULL,  /* ioctl */
        NULL,  /* mmap */
        &sv_midi_open,
+       NULL,   /* flush */
        &sv_midi_release,
        NULL,  /* fsync */
        NULL,  /* fasync */
@@ -2227,6 +2230,7 @@ static /*const*/ struct file_operations sv_dmfm_fops = {
        &sv_dmfm_ioctl,
        NULL,  /* mmap */
        &sv_dmfm_open,
+       NULL,   /* flush */
        &sv_dmfm_release,
        NULL,  /* fsync */
        NULL,  /* fasync */
index 95ef40a0f851a0968a4fa1c60be2af84041c8067..63322ec2ba12f75004e849fcdec5316e64914b00 100644 (file)
@@ -262,6 +262,7 @@ static struct file_operations soundcore_fops=
        NULL,
        NULL,
        NULL,
+       NULL,
        NULL
 };
 
index d679ff8bc715a5b0425942c4fa1bfad8a23df207..1fbb368d86e09efe013474d7a8cd408ba4475d12 100644 (file)
@@ -769,6 +769,7 @@ struct file_operations oss_sound_fops =
        sound_ioctl,
        sound_mmap,
        sound_open,
+       NULL,                   /* flush */
        sound_release
 };
 
index 4f9243359aa33d31bf67dc268d295a243987619e..b208392a9ce470a6dac791b6870c6a286d11e120 100644 (file)
@@ -71,6 +71,7 @@ static struct file_operations proc_bus_zorro_operations = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
 };
index bdadee2c526084f35b9a33073318c1dc3fa5e13f..12f7f6f6d99a8c908d815428f07bf49b2b1fe72e 100644 (file)
@@ -27,6 +27,7 @@ static struct file_operations adfs_dir_operations = {
        NULL,                   /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync,             /* fsync */
        NULL,                   /* fasync */
index 5627c7db4a4c40c08514ba3c6b1a258df4072a88..a886c68cee483c833fc6798fc1433f7c520dcd24 100644 (file)
@@ -40,6 +40,7 @@ static struct file_operations adfs_file_operations = {
        NULL,                   /* ioctl                */
        generic_file_mmap,      /* mmap                 */
        NULL,                   /* open - not special   */
+       NULL,                   /* flush                */
        NULL,                   /* release              */
        file_fsync,             /* fsync                */
        NULL,                   /* fasync               */
index 4cc74217949508d5fc4ecd7aefe4cbe8b12a1eb5..51e45b682be0f39cec3680b9ea875dd760b2ce39 100644 (file)
@@ -36,6 +36,7 @@ static struct file_operations affs_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync              /* default fsync */
 };
index 6f0db87fd6c0dceaedddf0f982cdebc5ded8da33..1961b4ec34935a2eece56ba69ab4dd4e42b0c82e 100644 (file)
@@ -52,6 +52,7 @@ static struct file_operations affs_file_operations = {
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync,             /* brute force, but works */
        NULL,                   /* fasync */
@@ -92,6 +93,7 @@ static struct file_operations affs_file_operations_ofs = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync,             /* brute force, but works */
        NULL,                   /* fasync */
index 9264806b4e6021ae0eda87eadfb0b02fe58c0784..67b2c04bf09d6abe2c0ce8018d48995ae8f03cf7 100644 (file)
@@ -53,6 +53,7 @@ static struct file_operations autofs_dir_operations = {
        NULL,                   /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        NULL,                   /* fsync */
        NULL,                   /* fasync */
index 0947e40e04980fa4fed88b931aa71d8d5df5fd49..41694e8ebb6f9eb52130f46fb7308f60d2527959 100644 (file)
@@ -32,6 +32,7 @@ static struct file_operations autofs_root_operations = {
         autofs_root_ioctl,     /* ioctl */
         NULL,                   /* mmap */
         NULL,                   /* open */
+       NULL,                   /* flush */
         NULL,                   /* release */
         NULL,                  /* fsync */
        NULL,                   /* fasync */
index 71106655b7cc560d14aebca00dbb21cc19916820..6eee191e84dee73a876aa5a02d83ffe8cd4375ab 100644 (file)
@@ -38,6 +38,7 @@ static struct file_operations bad_file_ops =
        EIO_ERROR,              /* ioctl */
        EIO_ERROR,              /* mmap */
        EIO_ERROR,              /* open */
+       EIO_ERROR,              /* flush */
        EIO_ERROR,              /* release */
        EIO_ERROR,              /* fsync */
        EIO_ERROR,              /* fasync */
index 122491c7a5d3519020f704daef79b86a3e2c1edc..e96cb18d5e032da20f5741cbda958fdb718b8c1e 100644 (file)
@@ -318,7 +318,6 @@ static inline int do_load_aout_binary(struct linux_binprm * bprm, struct pt_regs
                return -ENOEXEC;
        }
 
-       current->personality = PER_LINUX;
        fd_offset = N_TXTOFF(ex);
 
 #ifdef __i386__
@@ -350,6 +349,8 @@ static inline int do_load_aout_binary(struct linux_binprm * bprm, struct pt_regs
                return retval;
 
        /* OK, This is the point of no return */
+       current->personality = PER_LINUX;
+
 #if defined(__sparc__) && !defined(__sparc_v9__)
        memcpy(&current->tss.core_exec, &ex, sizeof(struct exec));
 #endif
@@ -563,7 +564,7 @@ load_aout_library(int fd)
 }
 
 
-__initfunc(int init_aout_binfmt(void))
+int __init init_aout_binfmt(void)
 {
        return register_binfmt(&aout_format);
 }
index a14debe633b39eff0fff9ab17253859d7d015846..976eec39056fa266b3606f680313d727662c5b53 100644 (file)
@@ -1331,7 +1331,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
 }
 #endif         /* USE_ELF_CORE_DUMP */
 
-__initfunc(int init_elf_binfmt(void))
+int __init init_elf_binfmt(void)
 {
        return register_binfmt(&elf_format);
 }
index 133586e69f247ccbbf89b34b37fd3392fb7bb3e0..d1992ca0643bc94c0338789d10efb6ead451df6f 100644 (file)
@@ -110,7 +110,7 @@ struct linux_binfmt em86_format = {
 #endif
 };
 
-__initfunc(int init_em86_binfmt(void))
+int __init init_em86_binfmt(void)
 {
        return register_binfmt(&em86_format);
 }
index 41e66a21a28576b4b1da713a68bb23985b93d91a..ca1ad396c34b6fca6ba1b4ac71bf9ca1cac147ba 100644 (file)
@@ -174,7 +174,7 @@ static struct linux_binfmt applet_format = {
 #endif
 };
 
-__initfunc(int init_java_binfmt(void))
+int __init init_java_binfmt(void)
 {
        register_binfmt(&java_format);
        return register_binfmt(&applet_format);
index bc1da662ee22352190c8b687c4fb1baee3b28dae..8acea3b64ab45a6dd6551ddc7dea2e56aab4874d 100644 (file)
@@ -488,7 +488,7 @@ static void bm_modcount(struct inode *inode, int fill)
 }
 #endif
 
-__initfunc(int init_misc_binfmt(void))
+int __init init_misc_binfmt(void)
 {
        struct proc_dir_entry *status = NULL, *reg;
        int error = -ENOMEM;
index 5a38cf545eea815a677b4ca196a80d7ce7431723..6aa1508a4b9bcfe54f83e2c0340b178231ad84f2 100644 (file)
@@ -107,7 +107,7 @@ struct linux_binfmt script_format = {
 #endif
 };
 
-__initfunc(int init_script_binfmt(void))
+int __init init_script_binfmt(void)
 {
        return register_binfmt(&script_format);
 }
index 7bf6e2824c9f2d2cdaaa38be049e79a2ed7b99f6..103caefa32a65206f00887c1dd8b537fd1999f65 100644 (file)
@@ -1736,7 +1736,7 @@ void show_buffers(void)
  * Use gfp() for the hash table to decrease TLB misses, use
  * SLAB cache for buffer heads.
  */
-__initfunc(void buffer_init(void))
+void __init buffer_init(void)
 {
        int order = 5;          /* Currently maximum order.. */
        unsigned int nr_hash;
index fabc4e3c8a0155a5b47f1656f51055571e9d6d8a..b555415328a8c5b690049f5e2a215cac147b1ee3 100644 (file)
@@ -96,6 +96,7 @@ struct file_operations coda_dir_operations = {
         NULL,                   /* ioctl */
         NULL,                   /* mmap */
         coda_open,              /* open */
+       NULL,                   /* flush */
         coda_release,           /* release */
        coda_fsync,             /* fsync */
         NULL,                   
index 949d9ce00e9f2dfb3f835a504213f4b9ab1f3e6d..3635c8ec9470faffd841a8027a3c4767d22028c6 100644 (file)
@@ -66,6 +66,7 @@ struct file_operations coda_file_operations = {
        NULL,                   /* ioctl */
        coda_file_mmap,         /* mmap */
        coda_open,              /* open */
+       NULL,                   /* flush */
        coda_release,           /* release */
        coda_fsync,             /* fsync */
        NULL,                   /* fasync */
index aa143afcfc7af36b98d3e793c3ff4fef1a8c883c..9f86a7ac2151f2e765102b37530332a41b4ecef8 100644 (file)
@@ -65,6 +65,7 @@ struct file_operations coda_ioctl_operations = {
        coda_pioctl,            /* ioctl */
        NULL,                   /* mmap */
        coda_ioctl_open,        /* open */
+       NULL,                   /* flush */
        coda_ioctl_release,     /* release */
        NULL,                   /* fsync */
 };
index 73fa6ddfe0f1304aba56263898a3df68b27d1698..3618940e363897db86af7afc2b56f1dbdac1d926 100644 (file)
@@ -391,6 +391,7 @@ static struct file_operations coda_psdev_fops = {
       NULL,                  /* ioctl */
       NULL,                 /* coda_psdev_mmap */
       coda_psdev_open,       /* open */
+      NULL,                  /* flush */
       coda_psdev_release,    /* release */
       NULL,                  /* fsync */
       NULL,                  /* fasync */
index 6cd34bb4a6b0cbc0ac48cfd5429552efd2d38e6b..c37da320e70711392df6406131fc54d403b67d2f 100644 (file)
@@ -916,7 +916,7 @@ out:
        return ino;
 }
 
-__initfunc(void dcache_init(void))
+void __init dcache_init(void)
 {
        int i;
        struct list_head *d = dentry_hashtable;
index f0ab040fc4bf8de1a311c79a611b2f0d27f2e986..db5cca48be7698f946b85cf9e1b6f000f1be2622 100644 (file)
@@ -261,6 +261,7 @@ struct file_operations def_blk_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        blkdev_open,    /* open */
+       NULL,           /* flush */
        NULL,           /* release */
 };
 
@@ -313,6 +314,7 @@ struct file_operations def_chr_fops = {
        NULL,           /* ioctl */
        NULL,           /* mmap */
        chrdev_open,    /* open */
+       NULL,           /* flush */
        NULL,           /* release */
 };
 
index 9ba675b16772fa7839c10acadc0fc00efb3dd317..78d3ae6250c7d238694d2d224abdb77e9cf646a0 100644 (file)
@@ -77,13 +77,15 @@ static int devpts_parse_options(char *options, struct devpts_sb_info *sbi)
 {
        int setuid = 0;
        int setgid = 0;
-       uid_t uid = 0;          /* To shut up gcc */
+       uid_t uid = 0;
        gid_t gid = 0;
        umode_t mode = 0600;
        char *this_char, *value;
 
-       if ( !options ) return 1;
-       for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
+       this_char = NULL;
+       if ( options )
+               this_char = strtok(options,",");
+       for ( ; this_char; this_char = strtok(NULL,",")) {
                if ((value = strchr(this_char,'=')) != NULL)
                        *value++ = 0;
                if (!strcmp(this_char,"uid")) {
index e5930501cbbb624a48989503e12d39f65e4e89c2..04215ad40e9cb9761e6e3775bb5a336f9121bb12 100644 (file)
@@ -29,6 +29,7 @@ static struct file_operations devpts_root_operations = {
        NULL,                   /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        NULL,                   /* fsync */
        NULL,                   /* fasync */
index 9ec40618ee2c00467a6e6ac567c1315d99332b9c..3179a5d4d4f4f3741c8e1baad0c869c22ad97bd2 100644 (file)
@@ -1063,7 +1063,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr, char direction, uid
 }
 
 
-__initfunc(void dquot_init_hash(void))
+void __init dquot_init_hash(void)
 {
        printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
 
index a76757c932aeb83e615e993fac95a8c380728fe1..8633f0dfbd91ac45ff85c88d320ab4455d1ea29f 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -67,7 +67,7 @@ asmlinkage int sys_brk(unsigned long);
 
 static struct linux_binfmt *formats = (struct linux_binfmt *) NULL;
 
-__initfunc(void binfmt_setup(void))
+void __init binfmt_setup(void)
 {
 #ifdef CONFIG_BINFMT_MISC
        init_misc_binfmt();
index 40845df97092265b3fbde8ff6a97b0b44b027c79..8f69f0baf82cb76938e6725ec8aa437286395cba 100644 (file)
@@ -213,7 +213,7 @@ static inline int load_block_bitmap (struct super_block * sb,
        if (sb->u.ext2_sb.s_loaded_block_bitmaps > 0 &&
            sb->u.ext2_sb.s_block_bitmap_number[0] == block_group &&
            sb->u.ext2_sb.s_block_bitmap[block_group]) {
-               slot = 0;
+               return 0;
        }
        /*
         * Or can we do a fast lookup based on a loaded group on a filesystem
index cbf6a9020829f424c9b907ba9b9b21cd95ba6e11..c5af9d8e1d3814f137fb6509ace2880eb33c5e23 100644 (file)
@@ -43,6 +43,7 @@ static struct file_operations ext2_dir_operations = {
        ext2_ioctl,             /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        ext2_sync_file,         /* fsync */
        NULL,                   /* fasync */
index d5e74cf35e3082f90d5b4ce1428657ad66cc09c5..0a98bad09cd7726cafc429564124ec36ed4a336e 100644 (file)
@@ -74,6 +74,7 @@ static struct file_operations ext2_file_operations = {
 #else
        ext2_open_file,
 #endif
+       NULL,                   /* flush */
        ext2_release_file,      /* release */
        ext2_sync_file,         /* fsync */
        NULL,                   /* fasync */
index 2e3cbbc0c48ab462b86755bb03a34a2bac856db9..7043188f87e70f4424960def87372698bfae5318 100644 (file)
@@ -101,7 +101,8 @@ static int load_inode_bitmap (struct super_block * sb,
                            "block_group = %d, groups_count = %lu",
                             block_group, sb->u.ext2_sb.s_groups_count);
        if (sb->u.ext2_sb.s_loaded_inode_bitmaps > 0 &&
-           sb->u.ext2_sb.s_inode_bitmap_number[0] == block_group)
+           sb->u.ext2_sb.s_inode_bitmap_number[0] == block_group &&
+           sb->u.ext2_sb.s_inode_bitmap[0] != NULL)
                return 0;
        if (sb->u.ext2_sb.s_groups_count <= EXT2_MAX_GROUP_LOADED) {
                if (sb->u.ext2_sb.s_inode_bitmap[block_group]) {
index 00ad263303756a0a1c69ec95362a855b84d6b5de..1c44247a00a5e0227b831614d13b6f404f6af076 100644 (file)
@@ -46,6 +46,7 @@ struct file_operations fat_dir_operations = {
        fat_dir_ioctl,          /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync              /* fsync */
 };
index 2495400f4726802e9d1283f74754e2eecc16f340..52e36caea5767eb32bdd5b2e7389224cbc0e2f87 100644 (file)
@@ -39,6 +39,7 @@ static struct file_operations fat_file_operations = {
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync              /* fsync */
 };
@@ -79,6 +80,7 @@ static struct file_operations fat_file_operations_1024 = {
        NULL,                   /* ioctl - default */
        fat_mmap,               /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync              /* fsync */
 };
@@ -122,6 +124,7 @@ static struct file_operations fat_file_operations_readpage = {
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync              /* fsync */
 };
index 76fb7a5309b0ae989f28f6a607e81487ed383963..7536995ac76f0a78aa768c803d3626d153625a42 100644 (file)
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -128,6 +128,8 @@ static struct file_operations def_fifo_fops = {
        NULL,
        fifo_open,              /* will set read or write pipe_fops */
        NULL,
+       NULL,
+       NULL,
        NULL
 };
 
index 3b5f05f8194b09426bfc77d54de9e382e3dd0f5f..6a4b1df4341314bfc403ae1bbf02072db04c4aba 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/init.h>
 
 /* SLAB cache for filp's. */
 static kmem_cache_t *filp_cache;
@@ -44,8 +45,7 @@ static inline void put_inuse(struct file *file)
        file->f_pprev = &inuse_filps;
 }
 
-/* N.B. This should be an __initfunc ... */
-void file_table_init(void)
+void __init file_table_init(void)
 {
        filp_cache = kmem_cache_create("filp", sizeof(struct file),
                                       0,
index d359b8002559e960143baeb256dded78bdf3c698..dcd1cf1d495d3981f22b37f6fabc61b68f9c5039 100644 (file)
@@ -50,7 +50,7 @@ extern void device_setup(void);
 extern void binfmt_setup(void);
 extern void free_initmem(void);
 
-__initfunc(static void do_sys_setup(void))
+static void __init do_sys_setup(void)
 {
        device_setup();
 
index a7bb7f633aa35bd2fc412f4f768b2629c2bf02c2..a40854e66433072cf8bd29fcce68fdbeb9d4e45e 100644 (file)
@@ -66,6 +66,7 @@ static struct file_operations hfs_cap_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap - none */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync,             /* fsync - default */
        NULL,                   /* fasync - default */
index 553fe8ef95bf1a832866735d82c4da4650fb8123..1e14b3f24847465eaab41c23409ba5c9f9788118 100644 (file)
@@ -66,6 +66,7 @@ static struct file_operations hfs_dbl_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap - none */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync,             /* fsync - default */
         NULL,                  /* fasync - default */
index b29bfdc17a2b90b14b6d060b5196d9a2f7200326..b69a6bd706bcb219e842380cda59887c4419da81 100644 (file)
@@ -69,6 +69,7 @@ static struct file_operations hfs_nat_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap - none */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync,             /* fsync - default */
         NULL,                  /* fasync - default */
index e12792036cd6e2acaf23a819bbd57b947c04a6da..6157afb4730a501dc2220de7b8242f6314ca8f4f 100644 (file)
@@ -41,6 +41,7 @@ static struct file_operations hfs_file_operations = {
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync,             /* fsync - default */
         NULL,                  /* fasync - default */
index 10f39f751ad216bf94cb7f5a8f7662d9b815716c..4fbd1f0908ed1e69b5c65c518c715c493de7a651 100644 (file)
@@ -55,6 +55,7 @@ static struct file_operations hfs_cap_info_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap - not yet */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync,             /* fsync - default */
        NULL,                   /* fasync - default */
index 049381dd03e55a754484486da0ca86e4e6d19dc0..b12a4606b3d5d8210a274f520a0447dadaa228ca 100644 (file)
@@ -48,6 +48,7 @@ static struct file_operations hfs_hdr_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap - XXX: not yet */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync,             /* fsync - default */
         NULL,                  /* fasync - default */
index 524624572d012ede5df889e1a009d799a98d50ba..f73ec5271fd2c15c9ae9dd75987caf4891f345c8 100644 (file)
@@ -35,6 +35,7 @@ static struct file_operations isofs_dir_operations =
        NULL,                   /* poll - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* fsync */
 };
index 0f230e0d270c686e5ddca7c677c96e1cff9169cd..0a508c90bc0df2f4c3058536e046be12c81b3d2a 100644 (file)
@@ -31,6 +31,7 @@ static struct file_operations isofs_file_operations = {
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        NULL                    /* fsync */
 };
index eec09e3adc38a01da504e5e009435db348483e10..bbfdefc7138c8b021d08a5a55eac707f8dea904b 100644 (file)
@@ -51,34 +51,39 @@ nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
 }
 
 /*
- * Initialize arguments for GRANTED call
+ * Initialize arguments for GRANTED call. The nlm_rqst structure
+ * has been cleared already.
  */
 int
 nlmclnt_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
 {
-       struct nlm_args *argp = &call->a_args;
-       struct nlm_lock *alock = &argp->lock;
-       void            *data = NULL;
-
-       if (lock->oh.len > NLMCLNT_OHSIZE
-        && !(data = kmalloc(lock->oh.len, GFP_KERNEL)))
-               return 0;
+       call->a_args.cookie  = nlm_cookie++;
+       call->a_args.lock    = *lock;
+       call->a_args.lock.caller = system_utsname.nodename;
+
+       /* set default data area */
+       call->a_args.lock.oh.data = call->a_owner;
+
+       if (lock->oh.len > NLMCLNT_OHSIZE) {
+               void *data = kmalloc(lock->oh.len, GFP_KERNEL);
+               if (!data)
+                       return 0;
+               call->a_args.lock.oh.data = (u8 *) data;
+       }
 
-       argp->cookie  = nlm_cookie++;
-       argp->lock    = *lock;
-       alock->caller = system_utsname.nodename;
-       if (data)
-               alock->oh.data = (u8 *) data;
-       else
-               alock->oh.data = call->a_owner;
-       memcpy(alock->oh.data, lock->oh.data, lock->oh.len);
+       memcpy(call->a_args.lock.oh.data, lock->oh.data, lock->oh.len);
        return 1;
 }
 
 void
 nlmclnt_freegrantargs(struct nlm_rqst *call)
 {
-       kfree(call->a_args.lock.caller);
+       /*
+        * Check whether we allocated memory for the owner.
+        */
+       if (call->a_args.lock.oh.data != (u8 *) call->a_owner) {
+               kfree(call->a_args.lock.oh.data);
+       }
 }
 
 /*
@@ -404,9 +409,15 @@ nlmclnt_reclaim(struct nlm_host *host, struct file_lock *fl)
 static int
 nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
 {
+       struct nlm_host *host = req->a_host;
        struct nlm_res  *resp = &req->a_res;
        int             status;
 
+       /* No monitor, no lock: see nlmclnt_lock().
+        * Since this is an UNLOCK, don't try to setup monitoring here. */
+       if (!host->h_monitored)
+               return -ENOLCK;
+
        /* Clean the GRANTED flag now so the lock doesn't get
         * reclaimed while we're stuck in the unlock call. */
        fl->fl_u.nfs_fl.flags &= ~NFS_LCK_GRANTED;
index 69a9eeb219036037b5e196c2c60f8d56cfa0180f..ac650b5f3b09d69701183bdf12c449fdc5e0095e 100644 (file)
@@ -158,10 +158,8 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
 
        /* Set notifier function for VFS, and init args */
        lock->fl.fl_notify = nlmsvc_notify_blocked;
-       if (!nlmclnt_setgrantargs(&block->b_call, lock)) {
-               kfree(block);
-               goto failed;
-       }
+       if (!nlmclnt_setgrantargs(&block->b_call, lock))
+               goto failed_free;
        block->b_call.a_args.cookie = cookie;   /* see above */
 
        dprintk("lockd: created block %p...\n", block);
@@ -182,6 +180,8 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
 
        return block;
 
+failed_free:
+       kfree(block);
 failed:
        nlm_release_host(host);
        return NULL;
index 4c407817b2f73442b5666c0df37b71f68b90c79a..dc3e63347cf7d5b325c3d029135223d79fe5be40 100644 (file)
@@ -31,6 +31,7 @@ static struct file_operations minix_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync              /* default fsync */
 };
index a44a635b0be81a1cb5feb3bf373e2d1eca66b180..f6ddda02140c22fc74ae7e6622d78c4699895bf7 100644 (file)
@@ -42,6 +42,7 @@ static struct file_operations minix_file_operations = {
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        minix_sync_file         /* fsync */
 };
index bec1c55a23f13d546e41da6bd0350e6c58168907..caa2dc2617c4bf73526c85b5ce63e48f9d5cc155 100644 (file)
@@ -70,6 +70,7 @@ static struct file_operations ncp_dir_operations =
        ncp_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* fsync */
 };
index d26fee881e16f713af94b457bf805cb83af9c02a..50d91a2b290c0e2f3835f7d02c5e134dd42b0f96 100644 (file)
@@ -252,6 +252,7 @@ static struct file_operations ncp_file_operations =
        ncp_ioctl,              /* ioctl */
        ncp_mmap,               /* mmap */
        NULL,                   /* open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        ncp_fsync,              /* fsync */
 };
index ba7a6c6e9719b19fa9d9379d5f1e49d095f695ac..3e5e59affdf946019b9d254a44d47fbf197557cc 100644 (file)
  *              Following Linus comments on my original hack, this version
  *              depends only on the dcache stuff and doesn't touch the inode
  *              layer (iput() and friends).
- * 04 Aug 1998  Ion Badulescu <ionut@cs.columbia.edu>     
- *             FIFO's need special handling in NFSv2
- */
-
-/*
- * Fixes:
- *    Ion Badulescu <ionut@cs.columbia.edu>     : FIFO's need special handling in NFSv2
  */
 
 #include <linux/sched.h>
@@ -86,6 +79,7 @@ static struct file_operations nfs_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        nfs_dir_open,           /* open - revalidate */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* fsync */
 };
@@ -652,10 +646,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode)
        if (dentry->d_name.len > NFS_MAXNAMLEN)
                goto out;
 
-       if (mode & S_IFIFO)
-               sattr.mode = (mode & ~S_IFMT) | S_IFCHR;
-       else
-               sattr.mode = mode;
+       sattr.mode = mode;
        sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
        sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
 
@@ -665,15 +656,6 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode)
        nfs_invalidate_dircache(dir);
        error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent),
                        dentry->d_name.name, &sattr, &fhandle, &fattr);
-       /*
-        *      Retry invalid FIFO creates as the original object
-        *      to cover for NFS servers that don't cope.
-        */
-       if (error == -EINVAL && (mode & S_IFIFO)) {
-               sattr.mode = mode;
-               error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent),
-                                       dentry->d_name.name, &sattr, &fhandle, &fattr);
-       }
        if (!error)
                error = nfs_instantiate(dentry, &fhandle, &fattr);
        if (error)
@@ -703,10 +685,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
        if (dentry->d_name.len > NFS_MAXNAMLEN)
                return -ENAMETOOLONG;
 
-       if (mode & S_IFIFO)
-               sattr.mode = (mode & ~S_IFMT) | S_IFCHR;
-       else
-               sattr.mode = mode;
+       sattr.mode = mode;
        sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
        if (S_ISCHR(mode) || S_ISBLK(mode))
                sattr.size = rdev; /* get out your barf bag */
@@ -715,11 +694,6 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
        nfs_invalidate_dircache(dir);
        error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent),
                                dentry->d_name.name, &sattr, &fhandle, &fattr);
-       if (error == -EINVAL && (mode & S_IFIFO)) {
-               sattr.mode = mode;
-               error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dentry->d_parent),
-                                       dentry->d_name.name, &sattr, &fhandle, &fattr);
-       }
        if (!error)
                error = nfs_instantiate(dentry, &fhandle, &fattr);
        if (error)
index 9ec883aff90139836f5b89e185426e61c20822f4..973ad52ece0f69818b616ad04ce318fbb6245822 100644 (file)
@@ -35,6 +35,7 @@
 static int  nfs_file_mmap(struct file *, struct vm_area_struct *);
 static ssize_t nfs_file_read(struct file *, char *, size_t, loff_t *);
 static ssize_t nfs_file_write(struct file *, const char *, size_t, loff_t *);
+static int  nfs_file_flush(struct file *);
 static int  nfs_file_close(struct inode *, struct file *);
 static int  nfs_fsync(struct file *, struct dentry *dentry);
 
@@ -47,6 +48,7 @@ static struct file_operations nfs_file_operations = {
        NULL,                   /* ioctl - default */
        nfs_file_mmap,          /* mmap */
        NULL,                   /* no special open is needed */
+       nfs_file_flush,         /* flush */
        nfs_file_close,         /* release */
        nfs_fsync,              /* fsync */
        NULL,                   /* fasync */
@@ -84,13 +86,7 @@ struct inode_operations nfs_file_inode_operations = {
 #endif
 
 /*
- * Flush all dirty pages, and check for write errors.
- *
- * Note that since the file close operation is called only by the
- * _last_ process to close the file, we need to flush _all_ dirty 
- * pages. This also means that there is little sense in checking
- * for errors for this specific process -- we should probably just
- * clear all errors.
+ * Sync the file..
  */
 static int
 nfs_file_close(struct inode *inode, struct file *file)
@@ -106,6 +102,22 @@ nfs_file_close(struct inode *inode, struct file *file)
        return status;
 }
 
+/*
+ * Flush all dirty pages, and check for write errors.
+ *
+ * We should probably do this better - this does get called at every
+ * close, so we should probably just flush the changes that "this"
+ * file has done and report on only those.
+ *
+ * Right now we use the "flush everything" approach. Overkill, but
+ * works.
+ */
+static int
+nfs_file_flush(struct file *file)
+{
+       return nfs_file_close(file->f_dentry->d_inode, file);
+}
+
 static ssize_t
 nfs_file_read(struct file * file, char * buf, size_t count, loff_t *ppos)
 {
index e89abdbce10defce072be0e49805100aa88286e9..59782127092e1ec5c8d2d674d361bc610d3181e0 100644 (file)
@@ -652,6 +652,7 @@ _nfs_revalidate_inode(struct nfs_server *server, struct dentry *dentry)
        int              status = 0;
        struct nfs_fattr fattr;
 
+       /* Don't bother revalidating if we've done it recently */
        if (jiffies - NFS_READTIME(inode) < NFS_ATTRTIMEO(inode))
                goto out;
 
@@ -745,6 +746,20 @@ nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
        if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
                goto out_changed;
 
+       /*
+        * If we have pending write-back entries, we don't want
+        * to look at the size the server sends us too closely..
+        * In particular, ignore the server if it tells us that
+        * the file is smaller or older than we locally think it
+        * is.. 
+        */
+       if (NFS_WRITEBACK(inode)) {
+               if (inode->i_size > fattr->size)
+                       fattr->size = inode->i_size;
+               if (inode->i_mtime > fattr->mtime.seconds)
+                       fattr->mtime.seconds = inode->i_mtime;
+       }
+
        /*
         * If the size or mtime changed from outside, we want
         * to invalidate the local caches immediately.
index 3ecb9bfa630e44c713f67dd45124323a25d6be66..81da8f9968ddbd4e9528631ff6c3ba262a419bdd 100644 (file)
@@ -78,7 +78,6 @@ mnt_create(char *hostname, struct sockaddr_in *srvaddr)
                clnt->cl_softrtry = 1;
                clnt->cl_chatty   = 1;
                clnt->cl_oneshot  = 1;
-               clnt->cl_intr = 1;
        }
        return clnt;
 }
index bab335a15f30dd86902f5c9aee30d468b19c3f2d..1c6a74a71799c48734500a4b8f0aa44b7036cb1a 100644 (file)
@@ -5,9 +5,6 @@
  *
  * Copyright (C) 1992, 1993, 1994  Rick Sladkey
  * Copyright (C) 1996 Olaf Kirch
- *
- * 04 Aug 1998  Ion Badulescu <ionut@cs.columbia.edu>     
- *             FIFO's need special handling in NFSv2
  */
 
 #define NFS_NEED_XDR_TYPES
@@ -117,11 +114,6 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
        fattr->mtime.useconds = ntohl(*p++);
        fattr->ctime.seconds = ntohl(*p++);
        fattr->ctime.useconds = ntohl(*p++);
-       if (fattr->type == NFCHR && fattr->rdev == NFS_FIFO_DEV) {
-               fattr->type = NFFIFO;
-               fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
-               fattr->rdev = 0;
-       }
        return p;
 }
 
index 0a58b6a025a893c114fbfea83f9261ab6c74a15b..572c413d007dc5e7974dc85078acb5a71e0ca126 100644 (file)
@@ -63,6 +63,8 @@
  *
  * Until we have a per-mount soft/hard mount policy that we can honour
  * we must default to hard mounting!
+ *
+ * And yes, this should be "interruptible", not soft.
  */
 #define IS_SOFT 0
 
@@ -442,11 +444,15 @@ schedule_write_request(struct nfs_wreq *req, int sync)
                sync = 1;
 
        if (sync) {
+               sigset_t        oldmask;
+               struct rpc_clnt *clnt = NFS_CLIENT(inode);
                dprintk("NFS: %4d schedule_write_request (sync)\n",
                                        task->tk_pid);
                /* Page is already locked */
                req->wb_flags |= NFS_WRITE_LOCKED;
+               rpc_clnt_sigmask(clnt, &oldmask);
                rpc_execute(task);
+               rpc_clnt_sigunmask(clnt, &oldmask);
        } else {
                dprintk("NFS: %4d schedule_write_request (async)\n",
                                        task->tk_pid);
@@ -467,19 +473,19 @@ wait_on_write_request(struct nfs_wreq *req)
 {
        struct wait_queue       wait = { current, NULL };
        struct page             *page = req->wb_page;
-       int                     retval;
+       int retval;
        sigset_t                oldmask;
+       struct rpc_clnt         *clnt = NFS_CLIENT(req->wb_inode);
 
-       rpc_clnt_sigmask(NFS_CLIENT(req->wb_inode), &oldmask);
+       rpc_clnt_sigmask(clnt, &oldmask);
        add_wait_queue(&page->wait, &wait);
        atomic_inc(&page->count);
        for (;;) {
-               current->state = IS_SOFT ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
+               current->state = TASK_INTERRUPTIBLE;
                retval = 0;
                if (!PageLocked(page))
                        break;
                retval = -ERESTARTSYS;
-               /* IS_SOFT is a timeout item .. */
                if (signalled())
                        break;
                schedule();
@@ -488,7 +494,7 @@ wait_on_write_request(struct nfs_wreq *req)
        current->state = TASK_RUNNING;
        /* N.B. page may have been unused, so we must use free_page() */
        free_page(page_address(page));
-       rpc_clnt_sigunmask(NFS_CLIENT(req->wb_inode), &oldmask);
+       rpc_clnt_sigunmask(clnt, &oldmask);
        return retval;
 }
 
index bf5b8505e06f702849c34c6fa34ace424546db5b..bb489912b4396bdf8fbe5fde3e59fccfa4f452fd 100644 (file)
@@ -385,6 +385,7 @@ struct file_operations ntfs_file_operations_nommap = {
        NULL, /* ioctl */
        NULL, /* mmap */
        NULL, /* open */
+       NULL, /* flush */
        NULL, /* release */
        NULL, /* fsync */
        NULL, /* fasync */
@@ -506,6 +507,7 @@ struct file_operations ntfs_file_operations = {
        NULL, /* ioctl */
        generic_file_mmap,
        NULL, /* open */
+       NULL, /* flush */
        NULL, /* release */
        NULL, /* fsync */
        NULL, /* fasync */
@@ -546,6 +548,7 @@ struct file_operations ntfs_dir_operations = {
        NULL, /* ioctl */
        NULL, /* mmap */
        NULL, /* open */
+       NULL, /* flush */
        NULL, /* release */
        NULL, /* fsync */
        NULL, /* fasync */
index 0bade427b0842e39325d87a65309c3addbd23851..e7e1e82469d5928c9da06e92154a2da4ee869e24 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -770,19 +770,17 @@ asmlinkage int sys_creat(const char * pathname, int mode)
 /*
  * Called when retiring the last use of a file pointer.
  */
-int __fput(struct file *filp)
+void __fput(struct file *filp)
 {
        struct dentry * dentry = filp->f_dentry;
        struct inode * inode = dentry->d_inode;
-       int     error = 0;
 
        if (filp->f_op && filp->f_op->release)
-               error = filp->f_op->release(inode, filp);
+               filp->f_op->release(inode, filp);
        filp->f_dentry = NULL;
        if (filp->f_mode & FMODE_WRITE)
                put_write_access(inode);
        dput(dentry);
-       return error;
 }
 
 /*
@@ -791,6 +789,7 @@ int __fput(struct file *filp)
  */
 int close_fp(struct file *filp, fl_owner_t id)
 {
+       int retval;
        struct dentry *dentry = filp->f_dentry;
 
        if (filp->f_count == 0) {
@@ -799,7 +798,11 @@ int close_fp(struct file *filp, fl_owner_t id)
        }
        if (dentry->d_inode)
                locks_remove_posix(filp, id);
-       return fput(filp);
+       retval = 0;
+       if (filp->f_op && filp->f_op->flush)
+               retval = filp->f_op->flush(filp);
+       fput(filp);
+       return retval;
 }
 
 /*
index 0e3c2ff39329a7b7d51ec446899eafb1b92454fb..8308eb06ce16f1d8cb67ddae9bd8678af9fdfc21 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -304,6 +304,7 @@ struct file_operations connecting_fifo_fops = {
        pipe_ioctl,
        NULL,           /* no mmap on pipes.. surprise */
        pipe_read_open,
+       NULL,           /* flush */
        pipe_read_release,
        NULL
 };
@@ -317,6 +318,7 @@ struct file_operations read_fifo_fops = {
        pipe_ioctl,
        NULL,           /* no mmap on pipes.. surprise */
        pipe_read_open,
+       NULL,           /* flush */
        pipe_read_release,
        NULL
 };
@@ -330,6 +332,7 @@ struct file_operations write_fifo_fops = {
        pipe_ioctl,
        NULL,           /* mmap */
        pipe_write_open,
+       NULL,           /* flush */
        pipe_write_release,
        NULL
 };
@@ -343,6 +346,7 @@ struct file_operations rdwr_fifo_fops = {
        pipe_ioctl,
        NULL,           /* mmap */
        pipe_rdwr_open,
+       NULL,           /* flush */
        pipe_rdwr_release,
        NULL
 };
@@ -356,6 +360,7 @@ struct file_operations read_pipe_fops = {
        pipe_ioctl,
        NULL,           /* no mmap on pipes.. surprise */
        pipe_read_open,
+       NULL,           /* flush */
        pipe_read_release,
        NULL
 };
@@ -369,6 +374,7 @@ struct file_operations write_pipe_fops = {
        pipe_ioctl,
        NULL,           /* mmap */
        pipe_write_open,
+       NULL,           /* flush */
        pipe_write_release,
        NULL
 };
@@ -382,6 +388,7 @@ struct file_operations rdwr_pipe_fops = {
        pipe_ioctl,
        NULL,           /* mmap */
        pipe_rdwr_open,
+       NULL,           /* flush */
        pipe_rdwr_release,
        NULL
 };
index d5a97963983c811906fa2c17698e6acac0ec60dd..f235a56df5aed1a3df6a1c9c19bbbe96661f1992 100644 (file)
@@ -1390,6 +1390,7 @@ static struct file_operations proc_array_operations = {
        NULL,           /* array_ioctl */
        NULL,           /* mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
 };
@@ -1437,6 +1438,7 @@ static struct file_operations proc_arraylong_operations = {
        NULL,           /* array_ioctl */
        NULL,           /* mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
 };
index edfe8b75891bf9acc4690580f694be95863cbdca..c9b2d8649bf490370b69925ef43b0e0f65a5114e 100644 (file)
@@ -24,6 +24,7 @@ static struct file_operations proc_base_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
index 57f99bfd79f7f5abc8e30ce94163d8b692a72beb..5409e2d671aa1c25bd2ea3cb0e4f560bc14c696b 100644 (file)
@@ -30,6 +30,7 @@ static struct file_operations proc_fd_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
index a9b00f1f50a316009878ea716482c10d1d5e0093..54b16f84bdb9ef37fc2d93d667cbfd672c38ed61 100644 (file)
@@ -42,6 +42,7 @@ static struct file_operations proc_file_operations = {
     NULL,              /* ioctl   */
     NULL,              /* mmap    */
     NULL,              /* no special open code    */
+    NULL,              /* flush */
     NULL,              /* no special release code */
     NULL               /* can't fsync */
 };
index e21c0cd1cba60e7bf6391bfc1cd4fbfeb6bc7059..ff8ec4877173671bfd3cdc4ef74a913ea8698055 100644 (file)
@@ -54,6 +54,7 @@ static struct file_operations proc_kmsg_operations = {
        NULL,           /* kmsg_ioctl */
        NULL,           /* mmap */
        kmsg_open,
+       NULL,           /* flush */
        kmsg_release,
        NULL            /* can't fsync */
 };
index 05ab85030d57ecf9ca0d73fc9ddefc15a8696af4..df5ea85e6f164e1f7fd92df2718a202d378cf271 100644 (file)
@@ -31,6 +31,7 @@ static struct file_operations proc_fd_link_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* very special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
index 6478dab77a9ad0c74e574bf99816ab25db83a86b..8a8ec9bc098137cc439bba955955ceb3390676ed 100644 (file)
@@ -316,6 +316,7 @@ static struct file_operations proc_mem_operations = {
        NULL,           /* mem_ioctl */
        mem_mmap,       /* mmap */
        NULL,           /* no special open code */
+       NULL,           /* flush */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
 };
index 408c8e0d437080c2daa394150b114ebcfdc0b1dc..a6d8c561654724ee29083a0ba987bfdf4317bcb0 100644 (file)
@@ -92,6 +92,7 @@ static struct file_operations proc_net_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
index 041e493d219709ab14925030f60617ff2174c5a8..9bde82e82377361472cedb710abedc6f312d5725 100644 (file)
@@ -268,6 +268,7 @@ static struct file_operations omirr_operations = {
     NULL,      /* omirr_ioctl */
     NULL,      /* mmap */
     omirr_open,
+    NULL,      /* flush */
     omirr_release,
     NULL,      /* fsync */
     NULL,       /* fasync */
index 0380e18999a6c73d635db00eb5394e9bb226f525..b3871059e14bd35ba11dd953993e2bbea02aa96f 100644 (file)
@@ -479,6 +479,7 @@ static struct file_operations openpromfs_prop_ops = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        property_release,       /* no special release code */
        NULL                    /* can't fsync */
 };
@@ -512,6 +513,7 @@ static struct file_operations openpromfs_nodenum_ops = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
@@ -545,6 +547,7 @@ static struct file_operations openprom_alias_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
index e74e91366622a2061fca6880ca3fd26bc9f3df85..18eb65ef9eda9ff8f4cd2eff85b6b2c251e68fdc 100644 (file)
@@ -50,6 +50,7 @@ static struct file_operations proc_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
@@ -117,6 +118,7 @@ static struct file_operations proc_root_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* no fsync */
 };
@@ -276,6 +278,7 @@ static struct file_operations proc_openprom_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
@@ -901,20 +904,19 @@ int proc_readdir(struct file * filp,
  * tasklist lock while doing this, and we must release it before
  * we actually do the filldir itself, so we use a temp buffer..
  */
-static int get_pid_list(unsigned int index, unsigned int *pids)
+static int get_pid_list(int index, unsigned int *pids)
 {
        struct task_struct *p;
-       int nr = FIRST_PROCESS_ENTRY;
        int nr_pids = 0;
 
+       index -= FIRST_PROCESS_ENTRY;
        read_lock(&tasklist_lock);
        for_each_task(p) {
-               int pid;
-               if (nr++ < index)
-                       continue;
-               pid = p->pid;
+               int pid = p->pid;
                if (!pid)
                        continue;
+               if (--index >= 0)
+                       continue;
                pids[nr_pids] = pid;
                nr_pids++;
                if (nr_pids >= PROC_MAXPIDS)
index 3bc4b1d5901b9c516d87f1814a4343341f08f4f2..6f3ad077070d574321d035ebac11b38dfd5ca838 100644 (file)
@@ -50,6 +50,7 @@ static struct file_operations proc_scsi_operations = {
     NULL,              /* ioctl   */
     NULL,              /* mmap    */
     NULL,              /* no special open code    */
+    NULL,              /* flush */
     NULL,              /* no special release code */
     NULL               /* can't fsync */
 };
index ed547eee62be45cd316054285e17f9cb0fb91cf6..92cd94363c80fb533c1d1b8810f5eb5edb89e388 100644 (file)
@@ -40,6 +40,7 @@ static struct file_operations smb_dir_operations =
        smb_ioctl,              /* ioctl */
        NULL,                   /* mmap */
        smb_dir_open,           /* open(struct inode *, struct file *) */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* fsync */
 };
index 0b886da90640c5cf02928cfecb1c663acd0c057c..3c3e87aa6a016d284430b7fcd894c8aa00633918 100644 (file)
@@ -389,6 +389,7 @@ static struct file_operations smb_file_operations =
        smb_ioctl,              /* ioctl */
        smb_file_mmap,          /* mmap(struct file*, struct vm_area_struct*) */
        smb_file_open,          /* open(struct inode*, struct file*) */
+       NULL,                   /* flush */
        smb_file_release,       /* release(struct inode*, struct file*) */
        smb_fsync,              /* fsync(struct file*, struct dentry*) */
        NULL,                   /* fasync(struct file*, int) */
index 924a02f8fc3183c3a1c0e1ba463ee4856790693a..843464421796c7d838d31aaec9c074d34b917a69 100644 (file)
@@ -539,8 +539,8 @@ static struct super_block *get_empty_super(void)
        if (nr_super_blocks >= max_super_blocks)
                return NULL;
        s = kmalloc(sizeof(struct super_block),  GFP_USER);
-       nr_super_blocks++;
        if (s) {
+               nr_super_blocks++;
                memset(s, 0, sizeof(struct super_block));
                INIT_LIST_HEAD(&s->s_dirty);
                list_add (&s->s_list, super_blocks.prev);
@@ -1129,7 +1129,7 @@ clean_up:
        goto dput_and_out;
 }
 
-__initfunc(void mount_root(void))
+void __init mount_root(void)
 {
        struct file_system_type * fs_type;
        struct super_block * sb;
@@ -1228,7 +1228,7 @@ __initfunc(void mount_root(void))
 
 extern int initmem_freed;
 
-__initfunc(static int do_change_root(kdev_t new_root_dev,const char *put_old))
+static int __init do_change_root(kdev_t new_root_dev,const char *put_old)
 {
        kdev_t old_root_dev;
        struct vfsmount *vfsmnt;
index e93f8bb11ca7cfc16a5bb8de46687228f9bec2c5..ee99164fb56a0920239bdfb860463dfc2fe29343 100644 (file)
@@ -38,6 +38,7 @@ static struct file_operations sysv_dir_operations = {
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        file_fsync              /* default fsync */
 };
index f4cf216c5d944dc1281e494cf2774084949748fe..d60be8fa5ebf50ad70a9263a19ca994de46a2579 100644 (file)
@@ -48,6 +48,7 @@ static struct file_operations sysv_file_operations = {
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        sysv_sync_file          /* fsync */
 };
index ee0e85674197f440f9ac29fbb7605d7209f47f7f..03d95fda57a086eeefd521d3ea4af2654bf7f318 100644 (file)
@@ -199,6 +199,7 @@ static struct file_operations ufs_dir_operations = {
        NULL,                   /* ioctl */
        NULL,                   /* mmap */
        NULL,                   /* open */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync,             /* fsync */
        NULL,                   /* fasync */
index a6fa503772092f0cdbf4c8d34f0ccc8eea4cdd2c..d6bd7c139c06183937e94f74d399380f4aca4d87 100644 (file)
@@ -61,6 +61,7 @@ static struct file_operations ufs_file_operations = {
        NULL,                   /* ioctl */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        ufs_release_file,       /* release */
        NULL,                   /* fsync */
        NULL,                   /* fasync */
index 3f49d0c2e00d377147c0446d26831e6da6cd82ea..5cc8f57277fd5f3d5192607f11db4e34a14aa741 100644 (file)
@@ -1022,6 +1022,7 @@ static struct file_operations umsdos_dir_operations =
        UMSDOS_ioctl_dir,       /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* fsync *//* in original NULL. changed to file_fsync. FIXME? /mn/ */
 };
index a9267e122f43e8e0aa9b22427f0289875dbcfe93..99bf747cc09e9ca58a0906a28fe225172b7631ed 100644 (file)
@@ -86,6 +86,7 @@ struct file_operations umsdos_file_operations =
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync              /* fsync */
 };
@@ -123,6 +124,7 @@ struct file_operations umsdos_file_operations_no_bmap =
        NULL,                   /* ioctl - default */
        fat_mmap,               /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync              /* fsync */
 };
@@ -160,6 +162,7 @@ struct file_operations umsdos_file_operations_readpage =
        NULL,                   /* ioctl - default */
        generic_file_mmap,      /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* flush */
        NULL,                   /* release */
        file_fsync              /* fsync */
 };
index f0252254a5b41a4d5ef45488b6cd980c72cc3161..5d5cd55af86b3ba2517274d66a008d9b5322edee 100644 (file)
@@ -284,6 +284,7 @@ static struct file_operations umsdos_rdir_operations =
        UMSDOS_ioctl_dir,       /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open code */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* fsync */
 };
index 32510a46b40b68463b001d5107c9e4ba54852076..696059ce21c9e49f62a7c11acfdf102d5fa31531 100644 (file)
@@ -149,6 +149,7 @@ static struct file_operations umsdos_symlink_operations =
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
        NULL,                   /* no special open is needed */
+       NULL,                   /* no flush code */
        NULL,                   /* release */
        NULL                    /* fsync */
 };
index 7f0e967aac65747545a8c5b277ae190c9ca73939..7df92de11270b951858c76ea25ded8576526a901 100644 (file)
@@ -17,6 +17,7 @@
 #define O_NDELAY       O_NONBLOCK
 #define O_SYNC         040000
 #define FASYNC         020000  /* fcntl, for BSD compatibility */
+#define O_DIRECT       040000  /* direct disk access - should check with OSF/1 */
 
 #define F_DUPFD                0       /* dup */
 #define F_GETFD                1       /* get f_flags */
index 3cbf6d573fbc2d7b1b2b10d701f9673a6c48e2b5..50967ef96141c6c9bd15aaace180ffa4ea45385a 100644 (file)
@@ -40,7 +40,7 @@ typedef struct {
 
 #define        __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
 #define        __FD_CLR(d, set)        ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
-#define        __FD_ISSET(d, set)      ((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define        __FD_ISSET(d, set)      (((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0)
 #define        __FD_ZERO(set)  \
   ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
 
index 30b4950fedbb8ddb17316fbc7361a0ee86af7f06..5e4c118a9e6713b7f461581e90fd5f49dfe971b7 100644 (file)
@@ -60,8 +60,11 @@ extern inline int verify_area(int type, const void * addr, unsigned long size)
 
 static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
 {
-       if (access_ok(VERIFY_READ, from, n))
+       char *end = (char *)to + n;
+       if (access_ok(VERIFY_READ, from, n)) {
                __do_copy_from_user(to, from, n);
+               if (n) memset(end - n, 0, n);
+       }
        return n;
 }
 
index dfdd500c6ef5484eabf95561f38cfd04f3620b4d..f0ddc3e616fc3c7f58bcec296731036746781137 100644 (file)
@@ -3,19 +3,21 @@
 
 /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
    located on an ext2 file system */
-#define O_ACCMODE        0003
-#define O_RDONLY           00
-#define O_WRONLY           01
-#define O_RDWR             02
-#define O_CREAT                  0100  /* not fcntl */
-#define O_EXCL           0200  /* not fcntl */
-#define O_NOCTTY         0400  /* not fcntl */
-#define O_TRUNC                 01000  /* not fcntl */
-#define O_APPEND        02000
-#define O_NONBLOCK      04000
+#define O_ACCMODE         0003
+#define O_RDONLY            00
+#define O_WRONLY            01
+#define O_RDWR              02
+#define O_CREAT                   0100 /* not fcntl */
+#define O_EXCL            0200 /* not fcntl */
+#define O_NOCTTY          0400 /* not fcntl */
+#define O_TRUNC                  01000 /* not fcntl */
+#define O_APPEND         02000
+#define O_NONBLOCK       04000
 #define O_NDELAY       O_NONBLOCK
-#define O_SYNC         010000
-#define FASYNC         020000  /* fcntl, for BSD compatibility */
+#define O_SYNC          010000
+#define FASYNC          020000 /* fcntl, for BSD compatibility */
+#define O_DIRECT        040000 /* direct disk access hint - currently ignored */
+#define O_LARGEFILE    0100000
 
 #define F_DUPFD                0       /* dup */
 #define F_GETFD                1       /* get f_flags */
index c56966f64a389ee4c42026b09b81ca942480254e..dc9d624d70b534ebc01bbc2f072484890195973a 100644 (file)
@@ -60,6 +60,10 @@ extern void set_fixmap (enum fixed_addresses idx, unsigned long phys);
 #define FIXADDR_SIZE   (__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START  (FIXADDR_TOP - FIXADDR_SIZE)
 
+#define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+
+extern void __this_fixmap_does_not_exist(void);
+
 /*
  * 'index to address' translation. If anyone tries to use the idx
  * directly without tranlation, we catch the bug with a NULL-deference
@@ -71,12 +75,15 @@ extern inline unsigned long fix_to_virt(const unsigned int idx)
         * this branch gets completely eliminated after inlining,
         * except when someone tries to use fixaddr indices in an
         * illegal way. (such as mixing up address types or using
-        * out-of-range indices)
+        * out-of-range indices).
+        *
+        * If it doesn't get removed, the linker will complain
+        * loudly with a reasonably clear error message..
         */
        if (idx >= __end_of_fixed_addresses)
-               panic("illegal fixaddr index!");
+               __this_fixmap_does_not_exist();
 
-        return FIXADDR_TOP - (idx << PAGE_SHIFT);
+        return __fix_to_virt(idx);
 }
 
 #endif
index 9da2fff06f4971a3746382c543503cd7d621b6c7..dcc56f31c1665f06fc047e91b45e00954500d017 100644 (file)
@@ -268,13 +268,38 @@ do {                                                                      \
                : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from)      \
                : "di", "si", "memory")
 
+#define __copy_user_zeroing(to,from,size)                              \
+       __asm__ __volatile__(                                           \
+               "0:     rep; movsl\n"                                   \
+               "       movl %1,%0\n"                                   \
+               "1:     rep; movsb\n"                                   \
+               "2:\n"                                                  \
+               ".section .fixup,\"ax\"\n"                              \
+               "3:     lea 0(%1,%0,4),%0\n"                            \
+               "4:     pushl %0\n"                                     \
+               "       pushl %%eax\n"                                  \
+               "       xorl %%eax,%%eax\n"                             \
+               "       rep; stosb\n"                                   \
+               "       popl %%eax\n"                                   \
+               "       popl %0\n"                                      \
+               "       jmp 2b\n"                                       \
+               ".previous\n"                                           \
+               ".section __ex_table,\"a\"\n"                           \
+               "       .align 4\n"                                     \
+               "       .long 0b,3b\n"                                  \
+               "       .long 1b,4b\n"                                  \
+               ".previous"                                             \
+               : "=&c"(size)                                           \
+               : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from)      \
+               : "di", "si", "memory");
+
 /* We let the __ versions of copy_from/to_user inline, because they're often
  * used in fast paths and have only a small space overhead.
  */
 static inline unsigned long
 __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
 {
-       __copy_user(to,from,n);
+       __copy_user_zeroing(to,from,n);
        return n;
 }
 
@@ -369,6 +394,141 @@ do {                                                              \
        }                                                       \
 } while (0)
 
+/* Optimize just a little bit when we know the size of the move. */
+#define __constant_copy_user_zeroing(to, from, size)           \
+do {                                                           \
+       switch (size & 3) {                                     \
+       default:                                                \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "2:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       jmp 1b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,2b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size)                            \
+                       : "S"(from), "D"(to), "0"(size/4)       \
+                       : "di", "si", "memory");                \
+               break;                                          \
+       case 1:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsb\n"                        \
+                       "2:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "3:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       incl %0\n"                      \
+                       "       jmp 2b\n"                       \
+                       "4:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       incl %0\n"                      \
+                       "       jmp 2b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,3b\n"                  \
+                       "       .long 1b,4b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size)                            \
+                       : "S"(from), "D"(to), "0"(size/4)       \
+                       : "di", "si", "memory");                \
+               break;                                          \
+       case 2:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsw\n"                        \
+                       "2:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "3:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       stosw\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       addl $2,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       "4:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosw\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       addl $2,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,3b\n"                  \
+                       "       .long 1b,4b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size)                            \
+                       : "S"(from), "D"(to), "0"(size/4)       \
+                       : "di", "si", "memory");                \
+               break;                                          \
+       case 3:                                                 \
+               __asm__ __volatile__(                           \
+                       "0:     rep; movsl\n"                   \
+                       "1:     movsw\n"                        \
+                       "2:     movsb\n"                        \
+                       "3:\n"                                  \
+                       ".section .fixup,\"ax\"\n"              \
+                       "4:     pushl %0\n"                     \
+                       "       pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       rep; stosl\n"                   \
+                       "       stosw\n"                        \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       popl %0\n"                      \
+                       "       shl $2,%0\n"                    \
+                       "       addl $3,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       "5:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosw\n"                        \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       addl $3,%0\n"                   \
+                       "       jmp 2b\n"                       \
+                       "6:     pushl %%eax\n"                  \
+                       "       xorl %%eax,%%eax\n"             \
+                       "       stosb\n"                        \
+                       "       popl %%eax\n"                   \
+                       "       incl %0\n"                      \
+                       "       jmp 2b\n"                       \
+                       ".previous\n"                           \
+                       ".section __ex_table,\"a\"\n"           \
+                       "       .align 4\n"                     \
+                       "       .long 0b,4b\n"                  \
+                       "       .long 1b,5b\n"                  \
+                       "       .long 2b,6b\n"                  \
+                       ".previous"                             \
+                       : "=c"(size)                            \
+                       : "S"(from), "D"(to), "0"(size/4)       \
+                       : "di", "si", "memory");                \
+               break;                                          \
+       }                                                       \
+} while (0)
+
 unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
 unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
 
@@ -384,7 +544,7 @@ static inline unsigned long
 __constant_copy_from_user(void *to, const void *from, unsigned long n)
 {
        if (access_ok(VERIFY_READ, from, n))
-               __constant_copy_user(to,from,n);
+               __constant_copy_user_zeroing(to,from,n);
        return n;
 }
 
@@ -398,7 +558,7 @@ __constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
 static inline unsigned long
 __constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
 {
-       __constant_copy_user(to,from,n);
+       __constant_copy_user_zeroing(to,from,n);
        return n;
 }
 
index 1b23625c626a2838c917a8c2ae2762fe031e92c0..ced7f4a2003afb398fa03c26e45cccd0175a3c88 100644 (file)
@@ -27,7 +27,7 @@
 #define __NR_lseek              19
 #define __NR_getpid             20
 #define __NR_mount              21
-#define __NR_oldumount          22
+#define __NR_umount             22
 #define __NR_setuid             23
 #define __NR_getuid             24
 #define __NR_stime              25
@@ -57,7 +57,7 @@
 #define __NR_geteuid            49
 #define __NR_getegid            50
 #define __NR_acct               51
-#define __NR_umount             52
+#define __NR_umount2            52
 #define __NR_lock               53
 #define __NR_ioctl              54
 #define __NR_fcntl              55
index 64b8be7bdc136e84dae60ef5b0faf1b73040a73d..ffd5567b4e1070adc35bae5bbeed65ba9274c79c 100644 (file)
@@ -712,9 +712,16 @@ __constant_copy_to_user(void *to, const void *from, unsigned long n)
 }
 
 #define copy_from_user(to, from, n)            \
+{ void *__to = (to);                           \
+  void *__from = (from);                       \
+  unsigned long __n = (n);                     \
+  char *__end = (char *)__to + __n;            \
+  unsigned long __res =                                \
 (__builtin_constant_p(n) ?                     \
  __constant_copy_from_user(to, from, n) :      \
- __generic_copy_from_user(to, from, n))
+ __generic_copy_from_user(to, from, n));       \
+  if (__res) memset(__end - __res, 0, __res);  \
+  res; }
 
 #define copy_to_user(to, from, n)              \
 (__builtin_constant_p(n) ?                     \
index df3d3d591085dbab649da8caf6d964864c9f882c..65ca165b7ff2d2a019094d43d344743b621a6080 100644 (file)
@@ -211,9 +211,12 @@ extern int __copy_tofrom_user(void *to, const void *from, unsigned long size);
 extern inline unsigned long
 copy_from_user(void *to, const void *from, unsigned long n)
 {
-       if (access_ok(VERIFY_READ, from, n))
-               return __copy_tofrom_user(to, from, n);
-       return n? -EFAULT: 0;
+       unsigned long res = n;
+       if (access_ok(VERIFY_READ, from, n)) {
+                res = __copy_tofrom_user(to, from, n);
+                if (res) memset((char *)to + n - res, 0, res);
+       }
+       return res;
 }
 
 extern inline unsigned long
@@ -221,7 +224,7 @@ copy_to_user(void *to, const void *from, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
                return __copy_tofrom_user(to, from, n);
-       return n? -EFAULT: 0;
+       return n;
 }
 
 #define __copy_from_user(to, from, size) \
index 638e234a09594351e85901d460b2df072ab98aed..3f4a586014351a3db46dbb96f775b01a6fe30f51 100644 (file)
@@ -318,11 +318,14 @@ if (__copy_to_user(to,from,n)) \
 })
 
 #define copy_from_user(to,from,n) ({ \
+void *__copy_to = (void *) (to); \
 void *__copy_from = (void *) (from); \
 __kernel_size_t __copy_size = (__kernel_size_t) (n); \
 __kernel_size_t __copy_res; \
 if(__copy_size && __access_ok((unsigned long)__copy_from, __copy_size)) { \
-__copy_res = __copy_user((void *) (to), __copy_from, __copy_size); \
+__copy_res = __copy_user(__copy_to, __copy_from, __copy_size); \
+if(__copy_res) \
+memset((char *)__copy_to + __copy_size - __copy_res, 0, __copy_res); \
 } else __copy_res = __copy_size; \
 __copy_res; })
 
index fe7ca60c965dec6fafdeb0b26e4d8df763e420f8..0884fad2ffe2b7762e629fe9d70598285a6b555d 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef __LINUX_FILE_H
 #define __LINUX_FILE_H
 
-extern int __fput(struct file *);
+extern void __fput(struct file *);
 extern void insert_file_free(struct file *file);
 
 /*
@@ -58,20 +58,18 @@ extern inline void remove_filp(struct file *file)
        *file->f_pprev = file->f_next;
 }
 
-extern inline int fput(struct file *file)
+extern inline void fput(struct file *file)
 {
        int count = file->f_count-1;
-       int error = 0;
 
        if (!count) {
                locks_remove_flock(file);
-               error = __fput(file);
+               __fput(file);
                file->f_count = 0;
                remove_filp(file);
                insert_file_free(file);
        } else
                file->f_count = count;
-       return error;
 }
 
 extern inline void put_filp(struct file *file)
index 24b132b249cce0d86514927affe08aed84ad0284..40728572ca5e706870abcd3be728d173575b79d4 100644 (file)
@@ -596,6 +596,7 @@ struct file_operations {
        int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
        int (*open) (struct inode *, struct file *);
+       int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, struct dentry *);
        int (*fasync) (int, struct file *, int);
@@ -670,7 +671,6 @@ asmlinkage int sys_close(unsigned int);             /* yes, it's really unsigned */
 extern int do_truncate(struct dentry *, unsigned long);
 extern int get_unused_fd(void);
 extern void put_unused_fd(unsigned int);
-extern int __fput(struct file *);
 extern int close_fp(struct file *, fl_owner_t id);
 
 extern char * getname(const char * filename);
index ba9649294453593b960656e9f3cc59a00b534ba8..907039e42621bba487f26785f49405b19ef98640 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: pci.h,v 1.80 1998/07/21 10:06:40 mj Exp $
+ *     $Id: pci.h,v 1.84 1998/08/17 23:06:43 cort Exp $
  *
  *     PCI defines and function prototypes
  *     Copyright 1994, Drew Eckhardt
 #define PCI_DEVICE_ID_IBM_82351                0x0022
 #define PCI_DEVICE_ID_IBM_SERVERAID    0x002e
 #define PCI_DEVICE_ID_IBM_TR_WAKE      0x003e
+#define PCI_DEVICE_ID_IBM_MPIC         0x0046
 #define PCI_DEVICE_ID_IBM_3780IDSP     0x007d
+#define PCI_DEVICE_ID_IBM_MPIC_2       0xffff
 
 #define PCI_VENDOR_ID_WD               0x101c
 #define PCI_DEVICE_ID_WD_7197          0x3296
 #define PCI_DEVICE_ID_DATABOOK_87144   0xb106
 
 #define PCI_VENDOR_ID_PLX              0x10b5
+#define PCI_DEVICE_ID_PLX_9060         0x9060
+#define PCI_DEVICE_ID_PLX_9060ES       0x906E
+#define PCI_DEVICE_ID_PLX_9060SD       0x906D
 #define PCI_DEVICE_ID_PLX_9080         0x9080
 
 #define PCI_VENDOR_ID_MADGE            0x10b6
index f890c73563a93c40d9b41ab8cd6a2cad72a38866..50a7b772cb2f3561a8860fd4c57d9556c7aefb18 100644 (file)
@@ -64,6 +64,7 @@ asmlinkage int sys_shmget (key_t key, int size, int flag);
 asmlinkage int sys_shmat (int shmid, char *shmaddr, int shmflg, unsigned long *addr);
 asmlinkage int sys_shmdt (char *shmaddr);
 asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf);
+extern void shm_unuse(unsigned long entry, unsigned long page);
 
 #endif /* __KERNEL__ */
 
index 11943bcd71263be358bb5cd2f60f173db4a8f73d..e089d607ef5f26244a9e76a3ec56dad751bf22bf 100644 (file)
@@ -216,7 +216,7 @@ struct video_unit
 
 #define VIDIOCGCAP             _IOR('v',1,struct video_capability)     /* Get capabilities */
 #define VIDIOCGCHAN            _IOWR('v',2,struct video_channel)       /* Get channel info (sources) */
-#define VIDIOCSCHAN            _IOW('v',3,int)                         /* Set channel  */
+#define VIDIOCSCHAN            _IOW('v',3,struct video_channel)        /* Set channel  */
 #define VIDIOCGTUNER           _IOWR('v',4,struct video_tuner)         /* Get tuner abilities */
 #define VIDIOCSTUNER           _IOW('v',5,struct video_tuner)          /* Tune the tuner for the current channel */
 #define VIDIOCGPICT            _IOR('v',6,struct video_picture)        /* Get picture properties */
index 554665535175dc41f47454809b16be2f8b1b9400..4b37834628b539f46d67f20fdddf661f77382e3d 100644 (file)
@@ -469,7 +469,7 @@ static struct dev_name_struct {
        { NULL, 0 }
 };
 
-__initfunc(kdev_t name_to_kdev_t(char *line))
+kdev_t __init name_to_kdev_t(char *line)
 {
        int base = 0;
        if (strncmp(line,"/dev/",5) == 0) {
@@ -488,7 +488,7 @@ __initfunc(kdev_t name_to_kdev_t(char *line))
        return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
 }
 
-__initfunc(static void root_dev_setup(char *line, int *num))
+static void __init root_dev_setup(char *line, int *num)
 {
        ROOT_DEV = name_to_kdev_t(line);
 }
@@ -816,32 +816,32 @@ static struct kernel_param raw_params[] __initdata = {
 };
 
 #ifdef CONFIG_BLK_DEV_RAM
-__initfunc(static void ramdisk_start_setup(char *str, int *ints))
+static void __init ramdisk_start_setup(char *str, int *ints)
 {
    if (ints[0] > 0 && ints[1] >= 0)
       rd_image_start = ints[1];
 }
 
-__initfunc(static void load_ramdisk(char *str, int *ints))
+static void __init load_ramdisk(char *str, int *ints)
 {
    if (ints[0] > 0 && ints[1] >= 0)
       rd_doload = ints[1] & 1;
 }
 
-__initfunc(static void prompt_ramdisk(char *str, int *ints))
+static void __init prompt_ramdisk(char *str, int *ints)
 {
    if (ints[0] > 0 && ints[1] >= 0)
       rd_prompt = ints[1] & 1;
 }
 
-__initfunc(static void ramdisk_size(char *str, int *ints))
+static void __init ramdisk_size(char *str, int *ints)
 {
        if (ints[0] > 0 && ints[1] >= 0)
                rd_size = ints[1];
 }
 #endif
 
-__initfunc(static int checksetup(char *line))
+static int __init checksetup(char *line)
 {
        int i, ints[11];
 
@@ -878,7 +878,7 @@ unsigned long loops_per_sec = (1<<12);
    better than 1% */
 #define LPS_PREC 8
 
-__initfunc(void calibrate_delay(void))
+void __init calibrate_delay(void)
 {
        unsigned long ticks, loopbit;
        int lps_precision = LPS_PREC;
@@ -930,7 +930,7 @@ __initfunc(void calibrate_delay(void))
  * This routine also checks for options meant for the kernel.
  * These options are not given to init - they are for internal kernel use only.
  */
-__initfunc(static void parse_options(char *line))
+static void __init parse_options(char *line)
 {
        char *next;
        int args, envs;
@@ -1014,7 +1014,7 @@ int cpu_idle(void *unused)
 extern int cpu_idle(void * unused);
 
 /* Called by boot processor to activate the rest. */
-__initfunc(static void smp_init(void))
+static void __init smp_init(void)
 {
        /* Get other processors into their bootup holding patterns. */
        smp_boot_cpus();
@@ -1026,7 +1026,7 @@ __initfunc(static void smp_init(void))
  *     they are finished.
  */
  
-__initfunc(static void smp_begin(void))
+static void __init smp_begin(void)
 {
        smp_threads_ready=1;
        smp_commence();
@@ -1040,7 +1040,7 @@ extern void initialize_secondary(void);
  *     Activate the first processor.
  */
  
-__initfunc(asmlinkage void start_kernel(void))
+asmlinkage void __init start_kernel(void)
 {
        char * command_line;
 
@@ -1188,7 +1188,7 @@ static int do_linuxrc(void * shell)
        return execve(shell, argv, envp_init);
 }
 
-__initfunc(static void no_initrd(char *s,int *ints))
+static void __init no_initrd(char *s,int *ints)
 {
        mount_initrd = 0;
 }
index 0ab5785846979f8c47138d97a217dfd70c29d5d7..8e8ce2c44dddbcc8566a972344b61c5297d1dbea 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -56,7 +56,7 @@ static int max_semid = 0;
 
 static unsigned short sem_seq = 0;
 
-__initfunc(void sem_init (void))
+void __init sem_init (void)
 {
        int i;
 
index c7568b784fe457643848251d7a11157168a8ab71..0ec61b1e3bfac58c9485a4a6b6d4d7da383c557b 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -3,6 +3,7 @@
  * Copyright (C) 1992, 1993 Krishna Balasubramanian
  *         Many improvements/fixes by Bruno Haible.
  * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994.
+ * Fixed the shm swap deallocation (shm_unuse()), August 1998 Andrea Arcangeli.
  */
 
 #include <linux/errno.h>
@@ -45,7 +46,7 @@ static ulong swap_attempts = 0;
 static ulong swap_successes = 0;
 static ulong used_segs = 0;
 
-__initfunc(void shm_init (void))
+void __init shm_init (void)
 {
        int id;
 
@@ -837,3 +838,38 @@ int shm_swap (int prio, int gfp_mask)
        shm_rss--;
        return 1;
 }
+
+/*
+ * Free the swap entry and set the new pte for the shm page.
+ */
+static void shm_unuse_page(struct shmid_ds *shp, unsigned long idx,
+                          unsigned long page, unsigned long entry)
+{
+       pte_t pte;
+
+       pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
+       shp->shm_pages[idx] = pte_val(pte);
+       atomic_inc(&mem_map[MAP_NR(page)].count);
+       shm_rss++;
+
+       swap_free(entry);
+       shm_swp--;
+}
+
+/*
+ * unuse_shm() search for an eventually swapped out shm page.
+ */
+void shm_unuse(unsigned long entry, unsigned long page)
+{
+       int i, n;
+
+       for (i = 0; i < SHMMNI; i++)
+               if (shm_segs[i] != IPC_UNUSED && shm_segs[i] != IPC_NOID)
+                       for (n = 0; n < shm_segs[i]->shm_npages; n++)
+                               if (shm_segs[i]->shm_pages[n] == entry)
+                               {
+                                       shm_unuse_page(shm_segs[i], n,
+                                                      page, entry);
+                                       return;
+                               }
+}
index c7933273ad9b24e8f4cae6fab83b9145d6605c26..1938d0be3f85aa5e49275da7febfddbaf8294b16 100644 (file)
@@ -24,7 +24,7 @@
 
 extern void sem_init (void), msg_init (void), shm_init (void);
 
-__initfunc(void ipc_init (void))
+void __init ipc_init (void)
 {
        sem_init();
        msg_init();
index 60d4ed6b52d500f79360907d571974ff74c058c7..b2a8d43a1f0d01362117f19a29e96990f357495a 100644 (file)
@@ -147,7 +147,6 @@ asmlinkage int sys_capset(cap_user_header_t header, const cap_user_data_t data)
              return -EINVAL;
      }
 
-     /* may want to set other processes at some point -- for now demand 0 */
      if (get_user(pid, &header->pid))
             return -EFAULT; 
 
index 6035d7a5009aa308291a936f5125dbfefb1d317f..e9508bda979c15d252d8a6bc8bd3576fff412a66 100644 (file)
@@ -125,7 +125,7 @@ int alloc_uid(struct task_struct *p)
        return 0;
 }
 
-__initfunc(void uidcache_init(void))
+void __init uidcache_init(void)
 {
        int i;
 
@@ -641,7 +641,7 @@ bad_fork_free:
        goto bad_fork;
 }
 
-__initfunc(void filescache_init(void))
+void __init filescache_init(void)
 {
        files_cachep = kmem_cache_create("files_cache", 
                                         sizeof(struct files_struct),
index ec0d85d32a9857d01cde1d68a40f393e13a7cb0d..4a7e3ebdabbd88a99d419a7868aa95a6c166a59c 100644 (file)
@@ -116,7 +116,7 @@ int request_module(const char * module_name)
        /* Block everything but SIGKILL/SIGSTOP */
        spin_lock_irq(&current->sigmask_lock);
        tmpsig = current->blocked;
-       siginitset(&current->blocked, ~(sigmask(SIGKILL)|sigmask(SIGSTOP)));
+       siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
        recalc_sigpending(current);
        spin_unlock_irq(&current->sigmask_lock);
 
index 3a81eb08820980a7faab3261c5e597cf39c40a38..a102a9598f664414c90c458e3c88564f4ba9851f 100644 (file)
@@ -25,7 +25,7 @@ extern int C_A_D;
 
 int panic_timeout = 0;
 
-__initfunc(void panic_setup(char *str, int *ints))
+void __init panic_setup(char *str, int *ints)
 {
        if (ints[0] == 1)
                panic_timeout = ints[1];
index 2998dbedebf4523211ff51143a9880416a7c2bec..0d8287fefaeeb1b5cac118f3e6429baa10a59032 100644 (file)
@@ -58,7 +58,7 @@ static int preferred_console = -1;
 /*
  *     Setup a list of consoles. Called from init/main.c
  */
-__initfunc(void console_setup(char *str, int *ints))
+void __init console_setup(char *str, int *ints)
 {
        struct console_cmdline *c;
        char name[sizeof(c->name)];
index dc23b159b994cfb6c3a2d584f7d4e521717e95c7..2d6b56eb0fd49158515be7f81a6250a83509e027 100644 (file)
@@ -182,7 +182,7 @@ unsigned long occupy_region(unsigned long base, unsigned long end,
 #endif
 
 /* Called from init/main.c to reserve IO ports. */
-__initfunc(void reserve_setup(char *str, int *ints))
+void __init reserve_setup(char *str, int *ints)
 {
        int i;
 
index ace9d0f130f28a7f9125f6a90c7d61895254c7db..228a397eb324b1d463987ac4fd7b707cd3660273 100644 (file)
@@ -1675,7 +1675,7 @@ void show_state(void)
        read_unlock(&tasklist_lock);
 }
 
-__initfunc(void sched_init(void))
+void __init sched_init(void)
 {
        /*
         *      We have to do a little magic to get the first
index b1e0a642c51804128a821975ce88b9588041f184..7469c0d0824306b663f6ca47cd9b9d6d69db4522 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 
@@ -38,8 +39,7 @@ static kmem_cache_t *signal_queue_cachep;
 static int nr_queued_signals;
 static int max_queued_signals = 1024;
 
-void
-signals_init(void)
+void __init signals_init(void)
 {
        signal_queue_cachep =
                kmem_cache_create("signal_queue",
index 20798b239f41bf02f97d3d2eba6ae1f2cd84b2a6..132739310866f7629e427c9f007993cdd4c1d698 100644 (file)
@@ -95,6 +95,7 @@ struct file_operations proc_sys_file_operations =
        NULL,           /* ioctl   */
        NULL,           /* mmap    */
        NULL,           /* no special open code    */
+       NULL,           /* no special flush code */
        NULL,           /* no special release code */
        NULL            /* can't fsync */
 };
@@ -251,7 +252,7 @@ static ctl_table dev_table[] = {
 };  
 
 
-__initfunc(void sysctl_init(void))
+void __init sysctl_init(void)
 {
 #ifdef CONFIG_PROC_FS
        register_proc_table(root_table, &proc_sys_root);
index 172bcd8f11e62d083081a192b173b74db4b40a8e..77b0c5d6266e038bcc7aeae31be57d09da431706 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -688,7 +688,7 @@ void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned l
        mm->mmap_cache = NULL;          /* Kill the cache. */
 }
 
-__initfunc(void vma_init(void))
+void __init vma_init(void)
 {
        vm_area_cachep = kmem_cache_create("vm_area_struct",
                                           sizeof(struct vm_area_struct),
index 70766c353caa39773b7f283b2b7074ab0118f770..2db2a66e3de09244bd95586c4a977586e742621d 100644 (file)
@@ -318,7 +318,7 @@ void show_free_areas(void)
  *   - mark all memory queues empty
  *   - clear the memory bitmaps
  */
-__initfunc(unsigned long free_area_init(unsigned long start_mem, unsigned long end_mem))
+unsigned long __init free_area_init(unsigned long start_mem, unsigned long end_mem)
 {
        mem_map_t * p;
        unsigned long mask = PAGE_MASK;
index 35433b3b88651d88503b2bf88e76386e481ecc85..5a00becdb5ccb772e6fff37dc654fea87c239a9f 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -406,7 +406,7 @@ static kmem_cache_t *cache_slabp = NULL;
 static unsigned long bufctl_limit = 0;
 
 /* Initialisation - setup the `cache' cache. */
-__initfunc(long kmem_cache_init(long start, long end))
+long __init kmem_cache_init(long start, long end)
 {
        size_t size, i;
 
@@ -460,7 +460,7 @@ __initfunc(long kmem_cache_init(long start, long end))
 /* Initialisation - setup remaining internal and general caches.
  * Called after the gfp() functions have been enabled, and before smp_init().
  */
-__initfunc(void kmem_cache_sizes_init(void))
+void __init kmem_cache_sizes_init(void)
 {
        unsigned int    found = 0;
 
index 0df60f6f0c0bbcd08b166953595fe3cbd24bc192..b644b06800a1002c365b1a29d12a4c5d535a72e3 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/blkdev.h> /* for blk_size */
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
+#include <linux/shm.h>
 
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
@@ -325,6 +326,7 @@ static int try_to_unuse(unsigned int type)
                for_each_task(p)
                        unuse_process(p->mm, entry, page);
                read_unlock(&tasklist_lock);
+               shm_unuse(entry, page);
                /* Now get rid of the extra reference to the temporary
                    page we've been using. */
                if (PageSwapCache(page_map))
index 63faf546583f1278c545c67e7b8c951c512c6206..961b27022e0af6e3a1fc0f8d66f170f2943fb98f 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/dcache.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
+#include <linux/init.h>
 
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
@@ -491,7 +492,7 @@ static int do_try_to_free_page(int gfp_mask)
  * may be printed in the middle of another driver's init 
  * message).  It looks very bad when that happens.
  */
-void kswapd_setup(void)
+void __init kswapd_setup(void)
 {
        int i;
        char *revision="$Revision: 1.5 $", *s, *e;
index 94be0069b917728f6a962acf315130370be73ea6..288cfd9a9f251171bc27dac1b727b77518155a6f 100644 (file)
@@ -185,6 +185,7 @@ static struct file_operations netlink_fops = {
        netlink_ioctl,
        NULL,           /* netlink_mmap */
        netlink_open,
+       NULL,           /* flush */
        netlink_release
 };
 
index 1d905854d48d4108dbc35adaabefc93b58a94630..4ddb606f2d92b1acb5812093827db69c487f6aa1 100644 (file)
@@ -122,6 +122,7 @@ static struct file_operations socket_file_ops = {
        sock_ioctl,
        NULL,                   /* mmap */
        NULL,                   /* no special open code... */
+       NULL,                   /* flush */
        sock_close,
        NULL,                   /* no fsync */
        sock_fasync
@@ -1441,7 +1442,7 @@ int sock_unregister(int family)
        return 0;
 }
 
-__initfunc(void proto_init(void))
+void __init proto_init(void)
 {
        extern struct net_proto protocols[];    /* Network protocols */
        struct net_proto *pro;
@@ -1461,7 +1462,7 @@ extern void sk_init(void);
 extern void wanrouter_init(void);
 #endif
 
-__initfunc(void sock_init(void))
+void __init sock_init(void)
 {
        int i;
 
index c2690684644be43ff5a3a806d9f18b1a5ee0a3a7..9380ff4a45f9df28db3610fcdba83c2a63a1f84d 100644 (file)
@@ -413,7 +413,7 @@ call_allocate(struct rpc_task *task)
                return;
        printk("RPC: buffer allocation failed for task %p\n", task); 
 
-       if (1 || !signalled()) {
+       if (!signalled()) {
                xprt_release(task);
                task->tk_action = call_reserve;
                rpc_delay(task, HZ);
index 222f905da87fa8e06a8582d2eca946e940e8b086..c2dcac0e9193c218fb52cec7fc81fe5f0cbef9dc 100644 (file)
@@ -128,7 +128,7 @@ rpc_add_timer(struct rpc_task *task, rpc_action timer)
        if (!timer)
                timer = __rpc_default_timer;
        if (expires < jiffies) {
-               printk("RPC: bad timeout value %ld - setting to 10 sec!\n",
+               printk(KERN_ERR "RPC: bad timeout value %ld - setting to 10 sec!\n",
                                        task->tk_timeout);
                expires = jiffies + 10 * HZ;
        }
@@ -164,7 +164,7 @@ static inline void
 rpc_make_runnable(struct rpc_task *task)
 {
        if (task->tk_timeout) {
-               printk("RPC: task w/ running timer in rpc_make_runnable!!\n");
+               printk(KERN_ERR "RPC: task w/ running timer in rpc_make_runnable!!\n");
                return;
        }
        if (RPC_IS_ASYNC(task)) {
@@ -242,7 +242,7 @@ __rpc_wake_up(struct rpc_task *task)
 
 #ifdef RPC_DEBUG
        if (task->tk_magic != 0xf00baa) {
-               printk("RPC: attempt to wake up non-existing task!\n");
+               printk(KERN_ERR "RPC: attempt to wake up non-existing task!\n");
                rpc_debug = ~0;
                return;
        }
@@ -352,7 +352,6 @@ __rpc_atrun(struct rpc_task *task)
 /*
  * This is the RPC `scheduler' (or rather, the finite state machine).
  */
-
 static int
 __rpc_execute(struct rpc_task *task)
 {
@@ -363,7 +362,7 @@ __rpc_execute(struct rpc_task *task)
                                task->tk_pid, task->tk_flags);
 
        if (!RPC_IS_RUNNING(task)) {
-               printk("RPC: rpc_execute called for sleeping task!!\n");
+               printk(KERN_WARNING "RPC: rpc_execute called for sleeping task!!\n");
                return 0;
        }
 
@@ -413,18 +412,12 @@ __rpc_execute(struct rpc_task *task)
                        dprintk("RPC: %4d sync task going to sleep\n",
                                                        task->tk_pid);
                        if (current->pid == rpciod_pid)
-                               printk("RPC: rpciod waiting on sync task!\n");
+                               printk(KERN_ERR "RPC: rpciod waiting on sync task!\n");
                        current->timeout = 0;
                        sleep_on(&task->tk_wait);
-                       
+
                        /* When the task received a signal, remove from
-                        * any queues etc, and make runnable again.
-                        *
-                        * The "intr" property isnt handled here. rpc_do_call
-                        * has changed the signal mask of the process for
-                        * a synchronous rpc call. If a signal gets through
-                        * this then its real.
-                        */
+                        * any queues etc, and make runnable again. */
                        if (signalled())
                                __rpc_wake_up(task);
 
@@ -467,11 +460,11 @@ rpc_execute(struct rpc_task *task)
 
        if (incr) {
                if (rpc_inhibit) {
-                       printk("RPC: execution inhibited!\n");
+                       printk(KERN_INFO "RPC: execution inhibited!\n");
                        return;
                }
                if (executing)
-                       printk("RPC: %d tasks executed\n", executing);
+                       printk(KERN_WARNING "RPC: %d tasks executed\n", executing);
        }
        
        executing += incr;
@@ -770,6 +763,8 @@ rpc_killall_tasks(struct rpc_clnt *clnt)
        rpc_inhibit--;
 }
 
+static struct semaphore rpciod_running = MUTEX_LOCKED;
+
 /*
  * This is the rpciod kernel thread
  */
@@ -786,11 +781,16 @@ rpciod(void *ptr)
         * Let our maker know we're running ...
         */
        rpciod_pid = current->pid;
-       wake_up(&rpciod_idle);
+       up(&rpciod_running);
 
        exit_files(current);
        exit_mm(current);
+
+       spin_lock_irq(&current->sigmask_lock);
        siginitsetinv(&current->blocked, sigmask(SIGKILL));
+       recalc_sigpending(current);
+       spin_unlock_irq(&current->sigmask_lock);
+
        current->session = 1;
        current->pgrp = 1;
        sprintf(current->comm, "rpciod");
@@ -798,12 +798,7 @@ rpciod(void *ptr)
        dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid);
        while (rpciod_users) {
                if (signalled()) {
-                       if (sigismember(&current->signal, SIGKILL)) {
-                               rpciod_killall();
-                       } else {
-                               printk("rpciod: ignoring signal (%d users)\n",
-                                       rpciod_users);
-                       }
+                       rpciod_killall();
                        flush_signals(current);
                }
                __rpc_schedule();
@@ -825,7 +820,7 @@ rpciod(void *ptr)
 
        dprintk("RPC: rpciod shutdown commences\n");
        if (all_tasks) {
-               printk("rpciod: active tasks at shutdown?!\n");
+               printk(KERN_ERR "rpciod: active tasks at shutdown?!\n");
                rpciod_killall();
        }
 
@@ -847,7 +842,7 @@ rpciod_killall(void)
                rpc_killall_tasks(NULL);
                __rpc_schedule();
                if (all_tasks) {
-printk("rpciod_killall: waiting for tasks to exit\n");
+                       dprintk("rpciod_killall: waiting for tasks to exit\n");
                        current->state = TASK_INTERRUPTIBLE;
                        current->timeout = jiffies + 1;
                        schedule();
@@ -878,16 +873,17 @@ rpciod_up(void)
         * If there's no pid, we should be the first user.
         */
        if (rpciod_users > 1)
-               printk("rpciod_up: no pid, %d users??\n", rpciod_users);
+               printk(KERN_WARNING "rpciod_up: no pid, %d users??\n", rpciod_users);
        /*
         * Create the rpciod thread and wait for it to start.
         */
        error = kernel_thread(rpciod, &rpciod_killer, 0);
        if (error < 0) {
-               printk("rpciod_up: create thread failed, error=%d\n", error);
+               printk(KERN_WARNING "rpciod_up: create thread failed, error=%d\n", error);
+               rpciod_users--;
                goto out;
        }
-       sleep_on(&rpciod_idle);
+       down(&rpciod_running);
        error = 0;
 out:
        up(&rpciod_sema);
@@ -907,10 +903,10 @@ rpciod_down(void)
                if (--rpciod_users)
                        goto out;
        } else
-               printk("rpciod_down: pid=%d, no users??\n", rpciod_pid);
+               printk(KERN_WARNING "rpciod_down: pid=%d, no users??\n", rpciod_pid);
 
        if (!rpciod_pid) {
-               printk("rpciod_down: Nothing to do!\n");
+               dprintk("rpciod_down: Nothing to do!\n");
                goto out;
        }
 
@@ -928,9 +924,9 @@ rpciod_down(void)
         * Display a message if we're going to wait longer.
         */
        while (rpciod_pid) {
-               printk("rpciod_down: waiting for pid %d to exit\n", rpciod_pid);
+               dprintk("rpciod_down: waiting for pid %d to exit\n", rpciod_pid);
                if (signalled()) {
-                       printk("rpciod_down: caught signal\n");
+                       dprintk("rpciod_down: caught signal\n");
                        break;
                }
                interruptible_sleep_on(&rpciod_killer);
index 518703d070facef86f1d3b984fd2eed9eb3e0657..4566ce5d2b7aa40332e9109cf864c97a57aee559 100644 (file)
@@ -140,9 +140,8 @@ xprt_from_sock(struct sock *sk)
  *     Adjust the iovec to move on 'n' bytes
  */
  
-extern inline void xprt_move_iov(struct msghdr *msg, int amount)
+extern inline void xprt_move_iov(struct msghdr *msg, struct iovec *niv, int amount)
 {
-       struct iovec niv[MAX_IOVEC];
        struct iovec *iv=msg->msg_iov;
        
        /*
@@ -187,6 +186,7 @@ xprt_sendmsg(struct rpc_xprt *xprt)
        struct msghdr   msg;
        mm_segment_t    oldfs;
        int             result;
+       struct iovec    niv[MAX_IOVEC];
 
        xprt_pktdump("packet data:",
                                xprt->snd_buf.io_vec->iov_base,
@@ -202,7 +202,7 @@ xprt_sendmsg(struct rpc_xprt *xprt)
        /* Dont repeat bytes */
        
        if(xprt->snd_sent)
-               xprt_move_iov(&msg, xprt->snd_sent);
+               xprt_move_iov(&msg, niv, xprt->snd_sent);
                
        oldfs = get_fs(); set_fs(get_ds());
        result = sock_sendmsg(sock, &msg, xprt->snd_buf.io_len);
index 088487077e67a07f40c4a56eace1b7586f1b8c5d..b619e1daebdc633f2647a1c4d369201273fcadee 100644 (file)
@@ -102,6 +102,7 @@ static struct file_operations router_fops =
        NULL,                   /* ioctl   */
        NULL,                   /* mmap    */
        NULL,                   /* no special open code    */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };
@@ -141,6 +142,7 @@ static struct file_operations wandev_fops =
        wanrouter_ioctl,        /* ioctl   */
        NULL,                   /* mmap    */
        NULL,                   /* no special open code    */
+       NULL,                   /* flush */
        NULL,                   /* no special release code */
        NULL                    /* can't fsync */
 };