]> git.neil.brown.name Git - history.git/commitdiff
v2.4.12.3 -> v2.4.12.4
authorLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:24:41 +0000 (20:24 -0800)
committerLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:24:41 +0000 (20:24 -0800)
  - Al Viro: mnt_list init
  - Jeff Garzik: network driver update (license tags, tulip driver)
  - David Miller: sparc, net updates
  - Ben Collins: firewire update
  - Gerd Knorr: btaudio/bttv update
  - Tim Hockin: MD cleanups
  - Greg KH, Petko Manolov: USB updates
  - Leonard Zubkoff: DAC960 driver update

150 files changed:
CREDITS
Documentation/Configure.help
Documentation/README.DAC960
Documentation/usb/error-codes.txt
Documentation/usb/philips.txt
Documentation/video4linux/bttv/CARDLIST
Documentation/video4linux/bttv/Cards [new file with mode: 0644]
Documentation/video4linux/bttv/Insmod-options
Documentation/video4linux/bttv/README.quirks [new file with mode: 0644]
Documentation/video4linux/bttv/Sound-FAQ
Documentation/video4linux/bttv/Tuners [new file with mode: 0644]
MAINTAINERS
Makefile
arch/i386/defconfig
arch/i386/kernel/entry.S
arch/i386/kernel/ldt.c
arch/i386/kernel/pci-irq.c
arch/ppc/8xx_io/enet.c
arch/ppc/8xx_io/fec.c
arch/ppc/kernel/m8xx_setup.c
arch/sparc64/Makefile
arch/sparc64/kernel/dtlb_base.S
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/rtrap.S
arch/sparc64/kernel/setup.c
drivers/acpi/include/platform/acgcc.h
drivers/block/DAC960.c
drivers/block/DAC960.h
drivers/block/genhd.c
drivers/block/loop.c
drivers/char/drm/drm_vm.h
drivers/ieee1394/Makefile
drivers/ieee1394/ieee1394.h
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_types.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.h
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid5.c
drivers/media/video/bttv-cards.c
drivers/media/video/bttv-driver.c
drivers/media/video/bttv-if.c
drivers/media/video/bttv.h
drivers/media/video/bttvp.h
drivers/media/video/id.h
drivers/media/video/msp3400.c
drivers/media/video/tda7432.c
drivers/media/video/tda9875.c
drivers/media/video/tuner.c
drivers/media/video/tuner.h
drivers/media/video/tvaudio.c
drivers/media/video/tvaudio.h
drivers/media/video/tvmixer.c
drivers/net/a2065.c
drivers/net/atari_bionet.c
drivers/net/atari_pamsnet.c
drivers/net/atarilance.c
drivers/net/bagetlance.c
drivers/net/bmac.c
drivers/net/fealnx.c
drivers/net/fmv18x.c
drivers/net/gmac.c
drivers/net/gt96100eth.c
drivers/net/hplance.c
drivers/net/hydra.c
drivers/net/ibmlana.c
drivers/net/ioc3-eth.c
drivers/net/isa-skeleton.c
drivers/net/lasi_82596.c
drivers/net/mac89x0.c
drivers/net/mace.c
drivers/net/macsonic.c
drivers/net/mvme147.c
drivers/net/ne2.c
drivers/net/oaknet.c
drivers/net/pci-skeleton.c
drivers/net/pcmcia/xircom_tulip_cb.c
drivers/net/saa9730.c
drivers/net/seeq8005.c
drivers/net/sk_g16.c
drivers/net/sk_mca.c
drivers/net/smc-mca.c
drivers/net/smc9194.c
drivers/net/stnic.c
drivers/net/sun3lance.c
drivers/net/sunqe.c
drivers/net/tulip/interrupt.c
drivers/net/tulip/tulip_core.c
drivers/net/wireless/airport.c
drivers/sbus/audio/amd7930.c
drivers/sbus/char/aurora.c
drivers/sbus/char/sab82532.c
drivers/sbus/char/su.c
drivers/sbus/char/zs.c
drivers/scsi/scsi.c
drivers/scsi/sd.c
drivers/scsi/sym53c8xx.c
drivers/sound/btaudio.c
drivers/usb/Config.in
drivers/usb/pegasus.h
drivers/usb/pwc-ctrl.c
drivers/usb/pwc-if.c
drivers/usb/pwc-ioctl.h
drivers/usb/pwc.h
drivers/usb/serial/Config.in
drivers/usb/uhci.c
drivers/usb/uhci.h
drivers/usb/ultracam.c
drivers/usb/usb-uhci.c
drivers/video/cgsixfb.c
drivers/video/creatorfb.c
drivers/video/leofb.c
fs/buffer.c
fs/hfs/catalog.c
fs/namei.c
fs/namespace.c
fs/nfsd/nfsproc.c
fs/nfsd/nfssvc.c
fs/nfsd/nfsxdr.c
fs/udf/udfdecl.h
include/asm-i386/system.h
include/asm-i386/unistd.h
include/asm-sparc/highmem.h
include/asm-sparc64/cache.h
include/asm-sparc64/hardirq.h
include/linux/ethtool.h
include/linux/pci_ids.h
include/linux/swap.h
include/net/route.h
ipc/shm.c
kernel/ksyms.c
kernel/sched.c
mm/filemap.c
mm/page_alloc.c
mm/shmem.c
mm/swap.c
mm/vmscan.c
net/bridge/br.c
net/ipv4/ip_output.c
net/ipv4/ipconfig.c
net/ipv4/ipip.c
net/ipv4/route.c
net/ipv4/syncookies.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/af_inet6.c
net/ipv6/tcp_ipv6.c
net/socket.c

diff --git a/CREDITS b/CREDITS
index 4f5c1b0a2279f7a41b1f5c334f84383f48a247bf..81ab2f0d5fd02220190a36427c5ecd45d891b887 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -2057,10 +2057,11 @@ S: Richardson, Texas 75081
 S: USA
 
 N: Patrick Mochel
-E: mochel@transmeta.com
+E: pat@osdl.org
+E: mochelp@infinity.powertie.org
 D: PCI Power Management, ACPI work
-S: 3940 Freedom Circle
-S: Santa Clara, CA 95054
+S: 15275 SW Koll Parkway, Suite H
+S: Beaverton, OR 97006 
 S: USA
 
 N: Eberhard Moenkeberg
index f7329b8129d27484ab89b6d332cd59b67005b8a3..b789f72ec0427f279a6d4cf0b8fedf7109fcb47b 100644 (file)
@@ -11609,26 +11609,14 @@ CONFIG_USB_SE401
   The module will be called se401.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
-USB ADMtek Pegasus-based ethernet device support
+Pegasus/Pegasus II based USB-Ethernet device support
 CONFIG_USB_PEGASUS
-  Say Y if you want to use your USB ethernet device. Supported
-  cards until now are:
-    ADMtek AN986 Pegasus (eval. board)
-    ADMtek ADM8511 Pegasus II (eval. board)
-    Accton 10/100
-    Billington USB-100
-    Corega FEter USB-TX
-    MELCO/BUFFALO LUA-TX
-    D-Link DSB-650TX, DSB-650TX-PNA, DSB-650, DU-E10, DU-E100
-    Linksys USB100TX, USB10TX
-    LANEED Ethernet LD-USB/TX
-    SMC 202
-    SOHOware NUB Ethernet
-    
-  Any Pegasus II based board also are supported.
-  If you have devices with vendor IDs other than noted above
-  you should add them in the driver code and send a message
-  to me (petkan@dce.bg) for update.
+  Say Y here if you know you have Pegasus or Pegasus II based adapter.
+  If in doubt then look at linux/drivers/usb/pegasus.h for the complete
+  list of supported devices.
+  If your particular adapter is not in the list and you are _sure_ it
+  is Pegasus or Pegasus II based then send me (pmanolov@lnxw.com) vendor
+  and device IDs.
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
index 4c0832e79e1526074a1c9e7856e70da9d83ad984..b6b770ee8dd6f784fbf869b78f686dcdf4e8e988 100644 (file)
@@ -1,17 +1,17 @@
    Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
-                       Version 2.2.9 for Linux 2.2.17
-                       Version 2.4.9 for Linux 2.4.0
+                       Version 2.2.11 for Linux 2.2.19
+                       Version 2.4.11 for Linux 2.4.12
 
                              PRODUCTION RELEASE
 
-                              7 September 2000
+                               11 October 2001
 
                               Leonard N. Zubkoff
                               Dandelion Digital
                               lnz@dandelion.com
 
-        Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>
+        Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>
 
 
                                 INTRODUCTION
@@ -20,7 +20,7 @@ Mylex, Inc. designs and manufactures a variety of high performance PCI RAID
 controllers.  Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont,
 California 94555, USA and can be reached at 510.796.6100 or on the World Wide
 Web at http://www.mylex.com.  Mylex Technical Support can be reached by
-electronic mail at support@mylex.com, by voice at 510.608.2400, or by FAX at
+electronic mail at mylexsup@us.ibm.com, by voice at 510.608.2400, or by FAX at
 510.745.7715.  Contact information for offices in Europe and Japan is available
 on their Web site.
 
@@ -120,7 +120,7 @@ AcceleRAID 170
            100MHz Intel i960RM RISC Processor
            16MB/32MB/64MB ECC SDRAM Memory
 
-AcceleRAID 160
+AcceleRAID 160 (AcceleRAID 170LP)
            1 Wide Ultra-160 LVD SCSI channel
            100MHz Intel i960RS RISC Processor
            Built in 16M ECC SDRAM Memory
@@ -170,6 +170,10 @@ DAC960PL    1/2/3 Wide Fast SCSI-2 Channels
            Intel i960 RISC Processor
            2MB/4MB/8MB/16MB/32MB DRAM Memory
 
+DAC960P            1/2/3 Wide Fast SCSI-2 Channels
+           Intel i960 RISC Processor
+           2MB/4MB/8MB/16MB/32MB DRAM Memory
+
 For the eXtremeRAID 2000/3000 and AcceleRAID 352/170/160, firmware version
 6.00-01 or above is required.
 
@@ -180,36 +184,29 @@ required.
 
 For the DAC960PJ and DAC960PG, firmware version 4.06-0-00 or above is required.
 
-For the DAC960PU, DAC960PD, and DAC960PL, firmware version 3.51-0-04 or above
-is required.
-
-Note that earlier revisions of the DAC960PU, DAC960PD, and DAC960PL controllers
-were delivered with version 2.xx firmware.  Version 2.xx firmware is not
-supported by this driver and no support is envisioned.  Contact Mylex RAID
-Technical Support to inquire about upgrading controllers with version 2.xx
-firmware to version 3.51-0-04.  Upgrading to version 3.xx firmware requires
-installation of higher capacity Flash ROM chips, and not all DAC960PD and
-DAC960PL controllers can be upgraded.
+For the DAC960PU, DAC960PD, DAC960PL, and DAC960P, either firmware version
+3.51-0-04 or above is required (for dual Flash ROM controllers), or firmware
+version 2.73-0-00 or above is required (for single Flash ROM controllers)
 
 Please note that not all SCSI disk drives are suitable for use with DAC960
 controllers, and only particular firmware versions of any given model may
 actually function correctly.  Similarly, not all motherboards have a BIOS that
 properly initializes the AcceleRAID 250, AcceleRAID 200, AcceleRAID 150,
 DAC960PJ, and DAC960PG because the Intel i960RD/RP is a multi-function device.
-If in doubt, contact Mylex RAID Technical Support (support@mylex.com) to verify
-compatibility.  Mylex makes available a hard disk compatibility list by FTP at
-ftp://ftp.mylex.com/pub/dac960/diskcomp.html.
+If in doubt, contact Mylex RAID Technical Support (mylexsup@us.ibm.com) to
+verify compatibility.  Mylex makes available a hard disk compatibility list at
+http://www.mylex.com/support/hdcomp/hd-lists.html.
 
 
                              DRIVER INSTALLATION
 
-This distribution was prepared for Linux kernel version 2.2.17 or 2.4.0.
+This distribution was prepared for Linux kernel version 2.2.19 or 2.4.12.
 
 To install the DAC960 RAID driver, you may use the following commands,
 replacing "/usr/src" with wherever you keep your Linux kernel source tree:
 
   cd /usr/src
-  tar -xvzf DAC960-2.2.9.tar.gz (or DAC960-2.4.9.tar.gz)
+  tar -xvzf DAC960-2.2.11.tar.gz (or DAC960-2.4.11.tar.gz)
   mv README.DAC960 linux/Documentation
   mv DAC960.[ch] linux/drivers/block
   patch -p0 < DAC960.patch (if DAC960.patch is included)
@@ -374,11 +371,14 @@ commands are:
 
     The "make-online" command changes the physical drive <channel>:<target-id>
     from status DEAD to status ONLINE.  In cases where multiple physical drives
-    have been killed simultaneously, this command may be used to bring them
-    back online, after which a consistency check is advisable.
+    have been killed simultaneously, this command may be used to bring all but
+    one of them back online, after which a rebuild to the final drive is
+    necessary.
 
     Warning: make-online should only be used on a dead physical drive that is
-    an active part of a drive group, never on a standby drive.
+    an active part of a drive group, never on a standby drive.  The command
+    should never be used on a dead drive that is part of a critical logical
+    drive; rebuild should be used if only a single drive is dead.
 
   make-standby <channel>:<target-id>
 
index 964af3033decf28c953935415cd6f0935f0a7c94..a89dce8cc994a70f86e7c27002e062dd202cdc73 100644 (file)
@@ -79,8 +79,7 @@ USB_ST_CRC
 -EILSEQ                        CRC mismatch
 
 USB_ST_STALL
--EPIPE                 a) babble detect
-                       b) endpoint stalled
+-EPIPE                 endpoint stalled
 
 USB_ST_BUFFEROVERRUN
 -ECOMM                 During an IN transfer, the host controller
@@ -95,7 +94,7 @@ USB_ST_BUFFERUNDERRUN
 USB_ST_DATAOVERRUN
 -EOVERFLOW             The amount of data returned by the endpoint was
                        greater than either the max packet size of the
-                       endpoint or the remaining buffer size
+                       endpoint or the remaining buffer size.  "Babble".
 
 USB_ST_DATAUNDERRUN
 -EREMOTEIO             The endpoint returned less than max packet size
index 2691c9ba09160a57575e1620b28ae466f1177af4..d48df51c3c1870e23a7211655abe8d77630cf9d5 100644 (file)
@@ -22,21 +22,12 @@ options are:
 size
    Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
    'vga', for an image size of resp. 128x96, 160x120, 176x144,
-   320x240, 352x288 and 640x480 (of course, only for those cameras that support these resolutions).
+   320x240, 352x288 and 640x480 (of course, only for those cameras that 
+   support these resolutions).
 
 fps
    Specifies the desired framerate. Is an integer in the range of 4-30.
 
-palette
-   Specifies the desired colour order that should be delivered by read() and
-   mmap(). The string can be one of yuv420 or yuv420p; however, yuv420 will
-   be phased out, leaving only yuv420p, so this option will disappear
-   entirely.
-
-   Only the native yuv420/yuv420p format is supported by the in kernel driver. 
-   If you want to use other formats with in-kernel conversion download the
-   driver from the URL given. [Alan]
-
 fbufs
    This paramter specifies the number of internal buffers to use for storing 
    frames from the cam. This will help if the process that reads images from 
@@ -89,6 +80,26 @@ compression (only useful with the plugin)
    The compression parameter only applies to the Vesta & ToUCam cameras.
    The 645 and 646 have fixed compression parameters.      
 
+leds
+   This settings takes 2 integers, that define the on/off time for the LED
+   (in milliseconds). One of the interesting things that you can do with
+   this is let the LED blink while the camera is in use. This:
+
+     leds=500,500
+      
+   will blink the LED once every second. But with:
+
+     leds=0,0
+
+   the LED never goes on, making it suitable for silent survaillance.
+
+   By default the camera's LED is on solid while in use, and turned off
+   when the camera is not used anymore.
+
+   This parameter works only with the ToUCam range of cameras (730, 740,
+   750). For other cameras this command is silently ignored, and the LED
+   cannot be controlled.
+
 trace
    In order to better detect problems, it is now possible to turn on a
    'trace' of some of the calls the module makes; it logs all items in your
index 8b7f0369e51297804473a6d85f920037155971e0..6a023e5d3a14fb64ecea8a0b4a1834ee061e695f 100644 (file)
@@ -1,15 +1,15 @@
 bttv.o
-  card=0 -  *** UNKNOWN *** 
+  card=0 -  *** UNKNOWN/GENERIC *** 
   card=1 - MIRO PCTV
-  card=2 - Hauppauge old
+  card=2 - Hauppauge (bt848)
   card=3 - STB
   card=4 - Intel
   card=5 - Diamond DTV2000
   card=6 - AVerMedia TVPhone
   card=7 - MATRIX-Vision MV-Delta
-  card=8 - Fly Video II
+  card=8 - Fly Video II (Bt848)
   card=9 - TurboTV
-  card=10 - Hauppauge new (bt878)
+  card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
   card=12 - ADS Technologies Channel Surfer TV
   card=13 - AVerMedia TVCapture 98
@@ -23,7 +23,7 @@ bttv.o
   card=21 - Lucky Star Image World ConferenceTV
   card=22 - Phoebe Tv Master + FM
   card=23 - Modular Technology MM205 PCTV, bt878
-  card=24 - Askey/Typhoon/Anubis Magic TView CPH051/061 (bt878)
+  card=24 - [many vendors] CPH05X/06X (bt878)
   card=25 - Terratec/Vobis TV-Boostar
   card=26 - Newer Hauppauge WinCam (bt878)
   card=27 - MAXI TV Video PCI2
@@ -34,10 +34,10 @@ bttv.o
   card=32 - Intel Create and Share PCI
   card=33 - Terratec TerraTValue
   card=34 - Leadtek WinFast 2000
-  card=35 - Chronos Video Shuttle II
-  card=36 - Typhoon TView TV/FM Tuner
+  card=35 - Flyvideo 98 (LR50Q) / Chronos Video Shuttle II
+  card=36 - Flyvideo 98FM (LR50Q) / Typhoon TView TV/FM Tuner
   card=37 - PixelView PlayTV pro
-  card=38 - TView99 CPH063
+  card=38 - TView99 CPH06X
   card=39 - Pinnacle PCTV Studio/Rave
   card=40 - STB2
   card=41 - AVerMedia TVPhone 98
@@ -49,11 +49,11 @@ bttv.o
   card=47 - Terratec TV/Radio+
   card=48 - Dynalink Magic TView 
   card=49 - GV-BCTV3
-  card=50 - Prolink PV-BT878P+4E (PixelView PlayTV PAK)
+  card=50 - Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP
   card=51 - Eagle Wireless Capricorn2 (bt878A)
   card=52 - Pinnacle PCTV Studio Pro
-  card=53 - Typhoon TView RDS / FM Stereo
-  card=54 - Lifetec LT 9415 TV
+  card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
+  card=54 - Lifetec LT 9415 TV (LR90 Rev.F)
   card=55 - BESTBUY Easy TV
   card=56 - FlyVideo '98/FM
   card=57 - GrandTec 'Grand Video Capture'
@@ -66,6 +66,12 @@ bttv.o
   card=64 - ATI TV-Wonder VE
   card=65 - FlyVideo 2000S
   card=66 - Terratec TValueRadio
+  card=67 - GV-BCTV4/PCI
+  card=68 - 3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)
+  card=69 - Active Imaging AIMMS
+  card=70 - PV-BT878P+
+  card=71 - Flyvideo 98EZ (capture only)
+  card=72 - Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
@@ -82,7 +88,7 @@ tuner.o
   type=11 - Alps TSBB5
   type=12 - Alps TSBE5
   type=13 - Alps TSBC5
-  type=14 - Temic PAL_I (4006FH5)
+  type=14 - Temic PAL_BG (4006FH5)
   type=15 - Alps TSCH6
   type=16 - Temic PAL_DK (4016 FY5)
   type=17 - Philips NTSC_M (MK2)
@@ -99,3 +105,10 @@ tuner.o
   type=28 - LG PAL_BG+FM (TPI8PSB01D)
   type=29 - LG PAL_BG (TPI8PSB11D)
   type=30 - Temic PAL* auto + FM (4009 FN5)
+  type=31 - SHARP NTSC_JP (2U5JF5540)
+  type=32 - Samsung PAL TCPM9091PD27
+  type=33 - MT2032 universal
+  type=34 - Temic PAL_BG (4106 FH5)
+  type=35 - Temic PAL_DK/SECAM_L (4012 FY5)
+  type=36 - Temic NTSC (4136 FY5)
+  type=37 - LG PAL (newer TAPC series)
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
new file mode 100644 (file)
index 0000000..63170f9
--- /dev/null
@@ -0,0 +1,210 @@
+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) for ALL cards via VBI sample 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 ...
+
+
+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
+- 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) 
+
+
+CPH-Series (CPH050, ...)
+------------------------
+Developed by TelSignal(?), OEMed by many vendors (Askey, Typhoon, 
+  Anubis, Dynalink)
+
+  Card series:
+    CPH01x: BT848 capture only
+    CPH03x: BT848
+    CPH05x: BT878 with FM
+    CPH06x: BT878 (w/o FM)
+    CPH07x: BT878 capture only
+  TV standards:
+     CPH0x0: NTSC-M/M
+     CPH0x1: PAL-B/G
+     CPH0x2: PAL-I/I
+     CPH0x3: PAL-D/K
+     CPH0x4: SECAM-L/L 
+     CPH0x5: SECAM-B/G 
+     CPH0x6: SECAM-D/K 
+     CPH0x7: PAL-N/N 
+     CPH0x8: PAL-B/H 
+     CPH0x9: PAL-M/M
+
+  CPH03x was often sold as "TV capturer".
+
+  Identifying:
+  1) 878 cards can be identified by PCI Subsystem-ID:
+      144f:3000 = CPH06x
+      144F:3002 = CPH05x w/ FM
+      144F:3005 = CPH06x_LC (w/o remote control)
+  1) The cards have a sticker with "CPH"-model on the back.
+  2) These cards have a number printed on the PCB just above the tuner metal box:
+      "80-CP2000300-x" = CPH03X
+      "80-CP2000500-x" = CPH05X
+      "80-CP2000600-x" = CPH06X / CPH06x_LC
+
+  Askey sells these cards as "Magic TView series", Brand "MagicXpress".
+  Other OEM often call these "Tview", "TView99" or else.
+
+Lifeview Flyvideo Series:
+-------------------------
+  The naming of these series differs in time and space.
+
+  Identifying:
+  1) Some models can be identified by PCI subsystem ID:
+      1852:1852 = Flyvideo 98 FM
+      1851:1850 = Flyvideo 98
+      1851:1851 = Flyvideo 98 EZ (capture only)
+  2) There is a print on the PCB:
+      LR25       = Flyvideo (Zoran)
+      LR37 Rev.C = Capture only (ZR36120 + SAA7110)
+      LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
+      LR50 Rev.W = Flyvideo 98 (no eeprom)
+      LR51 Rev.E = Flyvideo 98 EZ (capture only)
+      LR90       = Flyvideo 2000 series
+      LR90 Rev.F = Lifetec/Medion LT 9815
+      LR97       = Flyvideo DVBS
+
+  "Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
+  this name is re-used for LR50 Rev.W.
+  The Lifeview website has even more names: Flyvideo III,2100,3000,3100.
+  These cards are sold by many OEMs too.
+
+
+Typhoon TV card series:
+-----------------------
+  These can be CPH, Flyvideo, Pixelview or KNC1 series.
+  Typhoon is the brand of Anubis.
+  Model 50680 got re-used, some model no. had different contents over time.
+
+  Models:
+  50680 "TV Tuner PCI Pal BG"(old,red package)=can be CPH03x(bt848) or CPH06x(bt878)
+  50680 "TV Tuner Pal BG" (blue package)= Pixelview PV-BT878P+ (Rev 9B)
+  50681 "TV Tuner PCI Pal I" (variant of 50680)
+  50682 "TView TV/FM Tuner Pal BG"       = Flyvideo 98FM (LR50 Rev.Q)
+         Note: The package has a picture of CPH05x (which would be a real TView)
+  50683 "TV Tuner PCI SECAM" (variant of 50680)
+  50684 "TV Tuner Pal BG"                = Pixelview 878TV(Rev.3D)
+  50686 "TV Tuner"                       = KNC1 TV Station
+  50687 "TV Tuner stereo"                = KNC1 TV Station pro
+  50688 "TV Tuner RDS" (black package)   = KNC1 TV Station RDS
+  50692 "TV/FM Tuner" (small PCB)
+  50868 "TV/FM Tuner Pal I" (variant of 50682)
+  50999 "TV/FM Tuner Secam" (variant of 50682)
+
+
+Guillemot
+---------
+  Maxi TV Video 2 = LR50 Rev.Q (FI1216MF, PAL BG+SECAM)
+  Maxi TV Video 3 = CPH064 (PAL BG + SECAM)
+
+Mentor
+------
+  Mentor TV card ("55-878TV-U1") = Pixelview 878TV(Rev.3F) (w/FM w/Remote)
+
+Prolink
+-------
+   Pixelview Play TV Pro:
+     PV-BT878P+rev.9B (Play TV Pro w/FM w/NICAM)
+     PV-BT878P+rev.8X 
+     PV-BT878P+rev.4C (Play TV Pro) 
+     PV-BT878P+rev.4E (Play TV Pak) 
+     PV-BT878P+rev.2F 
+     PV-BT878TV 
+
+   PixelView Play TV 
+     PV-BT848P+
+
+Dynalink
+--------
+   These are CPH series.
+
+Phoebemicro
+-----------
+   TV Master    = CPH030 or CPH060
+   TV Master FM = CPH050
+
+Genius/Kye
+----------
+   Video Wonder/Genius Internet Video Kit = LR37 Rev.C
index 6ea97c4c3ea3798904b3cae55fae0c9978b2638f..4738e0c0b58d5dc4be162748a3049d4a40937e00 100644 (file)
@@ -1,6 +1,6 @@
 
 bttv.o
-       the bt848 (grabber chip) driver
+       the bt848/878 (grabber chip) driver
 
        insmod args:
                card=n          card type, see CARDLIST for a list.
@@ -10,12 +10,11 @@ bttv.o
                        0: don't use PLL
                        1: 28 MHz crystal installed
                        2: 35 MHz crystal installed
-               triton1=0/1     for Triton1 compatibility
-                               Triton1 is automatically recognized
-                               but this might also help with other chipsets
-               vsfx=0/1        yet another chipset bug compatibility flag
-                               (bt878 docs mentiones via+sis, but no
-                               specific chipsets with that problem).
+
+               triton1=0/1     for Triton1 (+others) compatibility
+               vsfx=0/1        yet another chipset bug compatibility bit
+                               see README.quirks for details on these two.
+
                bigendian=n     Set the endianness of the gfx framebuffer.
                                Default is native endian.
                fieldnr=0/1     Count fields.  Some TV descrambling software
@@ -23,8 +22,8 @@ bttv.o
                                50 useless IRQs/sec.  default is 0 (off).
                autoload=0/1    autoload helper modules (tuner, audio).
                                default is 1 (on).
-               bttv_verbose=0/1/2  verbose level (at insmod time, while looking
-                               at the hardware).  default is 1.
+               bttv_verbose=0/1/2  verbose level (at insmod time, while
+                               looking at the hardware).  default is 1.
                bttv_debug=0/1  debug messages (for capture).
                                default is 0 (off).
                irq_debug=0/1   irq handler debug messages.
@@ -80,13 +79,33 @@ tvaudio.o
                tda9850  = 1    The tea6300 can't be autodetected and is
                tda9855  = 1    therefore off by default, if you have
                tda9873  = 1    this one on your card (STB uses these)
-               tea6300  = 0    you have to enable it explicitly.
-               tea6420  = 1    The two tda985x chips use the same i2c
-               pic16c54 = 1    address and can't be disturgished from
-                               each other, you might have to disable
+               tda9874a = 1    you have to enable it explicitly.
+               tea6300  = 0    The two tda985x chips use the same i2c
+               tea6420  = 1    address and can't be disturgished from
+               pic16c54 = 1    each other, you might have to disable
                                the wrong one.
                debug = 1       print debug messages
 
+       insmod args for tda9874a:
+               tda9874a_SIF=1/2        select sound IF input pin (1 or 2)
+                                       (default is pin 1)
+               tda9874a_STD=n          select TV sound standard (0..8):
+                                       0 - A2, B/G
+                                       1 - A2, M (Korea)
+                                       2 - A2, D/K (1)
+                                       3 - A2, D/K (2)
+                                       4 - A2, D/K (3)
+                                       5 - NICAM, I
+                                       6 - NICAM, B/G
+                                       7 - NICAM, D/K (default)
+                                       8 - NICAM, L
+
+       Note: tda9874a is very similar to tda9874 (without 'A'-suffix), but
+       this driver will not work for the latter device (will not load).
+       Note: tda9874a and tda9875 (which is supported separately by
+       tda9875.o) use the same i2c address so both modules should not be
+       used at the same time.
+
 msp3400.o
        The driver for the msp34xx sound processor chips. If you have a
        stereo card, you probably want to insmod this one.
diff --git a/Documentation/video4linux/bttv/README.quirks b/Documentation/video4linux/bttv/README.quirks
new file mode 100644 (file)
index 0000000..e8edb87
--- /dev/null
@@ -0,0 +1,83 @@
+
+Below is what the bt878 data book says about the PCI bug compatibility
+modes of the bt878 chip.
+
+The triton1 insmod option sets the EN_TBFX bit in the control register.
+The vsfx insmod option does the same for EN_VSFX bit.  If you have
+stability problems you can try if one of these options makes your box
+work solid.
+
+drivers/pci/quirks.c knows about these issues, this way these bits are
+enabled automagically for known-buggy chipsets (look at the kernel
+messages, bttv tells you).
+
+HTH,
+
+  Gerd
+
+---------------------------- cut here --------------------------
+
+Normal PCI Mode
+---------------
+
+The PCI REQ signal is the logical-or of the incoming function requests.
+The inter-nal GNT[0:1] signals are gated asynchronously with GNT and
+demultiplexed by the audio request signal. Thus the arbiter defaults to
+the video function at power-up and parks there during no requests for
+bus access. This is desirable since the video will request the bus more
+often. However, the audio will have highest bus access priority. Thus
+the audio will have first access to the bus even when issuing a request
+after the video request but before the PCI external arbiter has granted
+access to the Bt879. Neither function can preempt the other once on the
+bus. The duration to empty the entire video PCI FIFO onto the PCI bus is
+very short compared to the bus access latency the audio PCI FIFO can
+tolerate.
+
+
+430FX Compatibility Mode
+------------------------
+
+When using the 430FX PCI, the following rules will ensure
+compatibility: 
+
+ (1) Deassert REQ at the same time as asserting FRAME. 
+ (2) Do not reassert REQ to request another bus transaction until after
+     finish-ing the previous transaction.
+
+Since the individual bus masters do not have direct control of REQ, a
+simple logical-or of video and audio requests would violate the rules.
+Thus, both the arbiter and the initiator contain 430FX compatibility
+mode logic. To enable 430FX mode, set the EN_TBFX bit as indicated in
+Device Control Register on page 104.
+
+When EN_TBFX is enabled, the arbiter ensures that the two compatibility
+rules are satisfied. Before GNT is asserted by the PCI arbiter, this
+internal arbiter may still logical-or the two requests. However, once
+the GNT is issued, this arbiter must lock in its decision and now route
+only the granted request to the REQ pin. The arbiter decision lock
+happens regardless of the state of FRAME because it does not know when
+FRAME will be asserted (typically - each initiator will assert FRAME on
+the cycle following GNT). When FRAME is asserted, it is the initiator s
+responsibility to remove its request at the same time. It is the
+arbiters responsibility to allow this request to flow through to REQ and
+not allow the other request to hold REQ asserted. The decision lock may
+be removed at the end of the transaction: for example, when the bus is
+idle (FRAME and IRDY). The arbiter decision may then continue
+asynchronously until GNT is again asserted.
+
+
+Interfacing with Non-PCI 2.1 Compliant Core Logic
+-------------------------------------------------
+
+A small percentage of core logic devices may start a bus transaction
+during the same cycle that GNT is de-asserted. This is non PCI 2.1
+compliant. To ensure compatibility when using PCs with these PCI
+controllers, the EN_VSFX bit must be enabled (refer to Device Control
+Register on page 104). When in this mode, the arbiter does not pass GNT
+to the internal functions unless REQ is asserted. This prevents a bus
+transaction from starting the same cycle as GNT is de-asserted. This
+also has the side effect of not being able to take advantage of bus
+parking, thus lowering arbitration performance. The Bt879 drivers must
+query for these non-compliant devices, and set the EN_VSFX bit only if
+required.
+
index 1fbcd42a79c73a1ac0722ba2d2c96d8217c01d0e..2c0bfa2e925d112ee0c83a15182cdfee83ba041f 100644 (file)
@@ -126,6 +126,7 @@ pll             - same as pll= insmod option
 tuner_type      - same as tuner= insmod option
 *_modulename    - hint whenever some card needs this or that audio
                   module loaded to work properly.
+has_radio      - whenever this TV card has a radio tuner.
 
 If some config item is specified both from the tvcards array and as
 insmod option, the insmod option takes precedence.
diff --git a/Documentation/video4linux/bttv/Tuners b/Documentation/video4linux/bttv/Tuners
new file mode 100644 (file)
index 0000000..d2de455
--- /dev/null
@@ -0,0 +1,88 @@
+
+SAMSUNG Tuner identification: (e.g. TCPM9091PD27)
+  TCP [ABCJLMNQ] 90[89][125] [DP] [ACD] 27 [ABCD]
+ [ABCJLMNQ]:
+   A= BG+DK
+   B= BG
+   C= I+DK
+   J= NTSC-Japan
+   L= Secam LL
+   M= BG+I+DK
+   N= NTSC 
+   Q= BG+I+DK+LL
+ [125]:
+   2: No FM
+   5: With FM
+ [DP]:
+   D= NTSC
+   P= PAL
+ [ACD]:
+   A= F-connector
+   C= Phono connector
+   D= Din Jack
+ [ABCD]:
+   3-wire/I2C tuning, 2-band/3-band
+
+Philips Tuner identification: (e.g. FM1216MF)
+  F[IRMQ]12[1345]{MF|ME|MP}
+  [IRMQ]:
+   I: Tuner Series
+   R: Tuner + Radio IF
+   M: Tuner + FM
+   Q,MR: specials
+   TD15xx: Digital Tuner ATSC
+  [1345]
+   1: PAL BG
+   3: NTSC
+   4: PAL I
+   5: Pal DK
+  {MF|ME|MP}
+   MF: w/ Secam
+   ME: BD DK I LL
+   MP: BG DK I
+   MR: BG DK M (?)
+   MG: BG DKI M (?)
+
+Temic Tuner identification: (.e.g 4006FH5)
+   4[01][0136][269]F[HYNR]5
+    40x2: Tuner (5V/33V), different I2C programming from Philips !
+    40x6: Tuner 5V
+    41xx: Tuner compact
+    40x9: Tuner+FM compact
+   [0136]
+    0: PAL BG
+    1: Pal DK, Secam LL
+    3: NTSC
+    6: PAL I
+   F[HYNR]5
+    FH5: Pal BG
+    FY5: others
+    FN5: multistandard
+    FR5: w/ FM radio
+   3X xxxx: order number with specific connector
+
+LG Innotek Tuner:
+  TPI8NSR11 : NTSC J/M    (TPI8NSR01 w/FM)  (P,210/497)
+  TPI8PSB11 : PAL B/G     (TPI8PSB01 w/FM)  (P,170/450)
+  TAPC-I701 : PAL I       (TAPC-I001 w/FM)  (P,170/450)
+  TPI8PSB12 : PAL D/K+B/G (TPI8PSB02 w/FM)  (P,170/450)
+  TAPC-H701P: NTSC_JP     (TAPC-H001P w/FM) (L,170/450)
+  TAPC-G701P: PAL B/G     (TAPC-G001P w/FM) (L,170/450)
+  TAPC-W701P: PAL I       (TAPC-W001P w/FM) (L,170/450)
+  TAPC-Q703P: PAL D/K     (TAPC-Q001P w/FM) (L,170/450)
+  TAPC-Q704P: PAL D/K+I   (L,170/450)
+  TAPC-G702P: PAL D/K+B/G (L,170/450)
+
+  TADC-H002F: NTSC (L,175/410?; 2-B, C-W+11, W+12-69)
+  TADC-M201D: PAL D/K+B/G+I (L,143/425)  (sound control at I2C address 0xc8)
+  TADC-T003F: NTSC Taiwan  (L,175/410?; 2-B, C-W+11, W+12-69)
+
+  (API,Lo-Hi-takeover/Hi-UHF-takeover)
+   I2C APIs:
+    L= LG programming (VHF_LO=0x01, VHF_HI=0x02, UHF=0x08, radio=0x04)
+    P= Philips progr. (VHF_LO=0xA0, VHF_HI=0x90, UHF=0x30, radio=0x04)
+    T= Temic progr.   (VHF_LO=0x02, VHF_HI=0x04, UHF=0x01)
+  Suffix: 
+    P= Standard phono female socket
+    D= IEC female socket
+    F= F-connector
index cce4a64295ba5fbe3f14519fa6a33296c4e52027..3eb69af564ae8272ec35f850d0426561019bba22 100644 (file)
@@ -1121,6 +1121,12 @@ L:       linux-parport@torque.net
 W:     http://www.torque.net/linux-pp.html
 S:     Maintained
 
+PERSONALITY HANDLING
+P:     Christoph Hellwig
+M:     hch@caldera.de
+L:     linux-abi-devel@lists.sourceforge.net
+S:     Supported
+
 PCI ID DATABASE
 P:     Jens Maurer
 M:     jmaurer@cck.uni-kl.de
index e01920bb07f120bd35fad0260939173c12d152b5..282423721d6c433d175ada61d86b1cdd4b9714eb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 13
-EXTRAVERSION =-pre3
+EXTRAVERSION =-pre4
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
index b65a636bcbf6832a22a016b2040b8ce9cb64ab85..8e9a1b2e29fdba6cb9d1ff2959dfe8f77fa93fb9 100644 (file)
@@ -704,6 +704,8 @@ CONFIG_USB=y
 #
 # CONFIG_USB_DEVICEFS is not set
 # CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_LARGE_CONFIG is not set
 
 #
 # USB Controllers
@@ -718,9 +720,13 @@ CONFIG_USB_UHCI_ALT=y
 # CONFIG_USB_BLUETOOTH is not set
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
@@ -744,20 +750,18 @@ CONFIG_USB_STORAGE=y
 #
 # USB Multimedia devices
 #
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
 
 #
 # USB Network adaptors
 #
 # CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_USBNET is not set
 
 #
@@ -769,9 +773,33 @@ CONFIG_USB_STORAGE=y
 # USB Serial Converter support
 #
 # CONFIG_USB_SERIAL is not set
-
-#
-# USB misc drivers
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
 
index 582c0d5b240d1be600b554193cee6bbcee876a7f..bdca486b6de2c967310fa49d266e7e9dfdbfb3a2 100644 (file)
@@ -621,6 +621,7 @@ ENTRY(sys_call_table)
        .long SYMBOL_NAME(sys_ni_syscall)       /* reserved for TUX */
        .long SYMBOL_NAME(sys_ni_syscall)       /* Reserved for Security */
        .long SYMBOL_NAME(sys_gettid)
+       .long SYMBOL_NAME(sys_readahead)        /* 225 */
 
        .rept NR_syscalls-(.-sys_call_table)/4
                .long SYMBOL_NAME(sys_ni_syscall)
index df70730d7a804439e2c5e22bf6365fa4dffcc2f4..a7ae70cb93e30599494e9a77084d195fe59a2592 100644 (file)
@@ -45,6 +45,25 @@ out:
        return err;
 }
 
+static int read_default_ldt(void * ptr, unsigned long bytecount)
+{
+       int err;
+       unsigned long size;
+       void *address;
+
+       err = 0;
+       address = &default_ldt[0];
+       size = sizeof(struct desc_struct);
+       if (size > bytecount)
+               size = bytecount;
+
+       err = size;
+       if (copy_to_user(ptr, address, size))
+               err = -EFAULT;
+
+       return err;
+}
+
 static int write_ldt(void * ptr, unsigned long bytecount, int oldmode)
 {
        struct mm_struct * mm = current->mm;
@@ -140,6 +159,9 @@ asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
        case 1:
                ret = write_ldt(ptr, bytecount, 1);
                break;
+       case 2:
+               ret = read_default_ldt(ptr, bytecount);
+               break;
        case 0x11:
                ret = write_ldt(ptr, bytecount, 0);
                break;
index 22bcc1ea732ee1050224b398f6339c24fd1dea5d..b5519558ab15df78e7fe2dfd06cb5868f53fc1b0 100644 (file)
@@ -458,6 +458,8 @@ static struct irq_router pirq_routers[] = {
        { "VLSI 82C534", PCI_VENDOR_ID_VLSI, PCI_DEVICE_ID_VLSI_82C534, pirq_vlsi_get, pirq_vlsi_set },
        { "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4,
          pirq_serverworks_get, pirq_serverworks_set },
+       { "ServerWorks", PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5,
+         pirq_serverworks_get, pirq_serverworks_set },
        { "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
                pirq_amd756_get, pirq_amd756_set },
 
index d446ad907aaa40291391b285e0349731f01cf5c2..8e1e2331a08dde39bfde0f19eb63883a3639914b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.enet.c 1.15 09/14/01 18:01:16 trini
+ * BK Id: SCCS/s.enet.c 1.17 10/11/01 11:55:47 trini
  */
 /*
  * Ethernet driver for Motorola MPC8xx.
@@ -147,7 +147,7 @@ struct scc_enet_private {
 static int scc_enet_open(struct net_device *dev);
 static int scc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int scc_enet_rx(struct net_device *dev);
-static void scc_enet_interrupt(void *dev_id);
+static void scc_enet_interrupt(void *dev_id, struct pt_regs *regs);
 static int scc_enet_close(struct net_device *dev);
 static struct net_device_stats *scc_enet_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
@@ -303,7 +303,7 @@ scc_enet_timeout(struct net_device *dev)
  * This is called from the CPM handler, not the MPC core interrupt.
  */
 static void
-scc_enet_interrupt(void *dev_id)
+scc_enet_interrupt(void *dev_id, struct pt_regs *regs)
 {
        struct  net_device *dev = dev_id;
        volatile struct scc_enet_private *cep;
@@ -805,22 +805,10 @@ int __init scc_enet_init(void)
        ep->sen_iaddr4 = 0;
 
        /* Set Ethernet station address.
-        *
-        * If we performed a MBX diskless boot, the Ethernet controller
-        * has been initialized and we copy the address out into our
-        * own structure.
-        *
-        * All other types of boards supply the address in the board
-        * information structure, so we copy that into the controller.
         */
        eap = (unsigned char *)&(ep->sen_paddrh);
-#ifndef CONFIG_MBX
        for (i=5; i>=0; i--)
                *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
-#else
-       for (i=5; i>=0; i--)
-               dev->dev_addr[i] = *eap++;
-#endif
 
        ep->sen_pper = 0;       /* 'cause the book says so */
        ep->sen_taddrl = 0;     /* temp address (LSB) */
@@ -943,6 +931,14 @@ int __init scc_enet_init(void)
        immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
 #endif
 
+#ifdef CONFIG_FADS
+       cp->cp_pbpar |= PB_ENET_TENA;
+       cp->cp_pbdir |= PB_ENET_TENA;
+
+       /* Enable the EEST PHY.
+       */
+       *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
+#endif
 
        dev->base_addr = (unsigned long)ep;
        dev->priv = cep;
@@ -970,5 +966,3 @@ int __init scc_enet_init(void)
 
        return 0;
 }
-
-
index 89f493278cfba9d4fd3b6a46dc27cb954f0abd9a..736c3657200e11e9f735a130053d0e66af520b55 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.fec.c 1.18 09/22/01 09:12:32 trini
+ * BK Id: SCCS/s.fec.c 1.20 10/11/01 11:55:47 trini
  */
 /*
  * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
@@ -868,6 +868,8 @@ static void mii_parse_sr(uint mii_reg, struct net_device *dev)
                *s |= PHY_STAT_FAULT;
        if (mii_reg & 0x0020)
                *s |= PHY_STAT_ANC;
+
+       fep->link = (*s & PHY_STAT_LINK) ? 1 : 0;
 }
 
 static void mii_parse_cr(uint mii_reg, struct net_device *dev)
@@ -1650,11 +1652,11 @@ int __init fec_enet_init(void)
 #endif
 
 #ifdef PHY_INTERRUPT
-       if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0)
-               panic("Could not allocate MII IRQ!");
-
        ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel |=
                (0x80000000 >> PHY_INTERRUPT);
+
+       if (request_8xxirq(PHY_INTERRUPT, mii_link_interrupt, 0, "mii", dev) != 0)
+               panic("Could not allocate MII IRQ!");
 #endif
 
        dev->base_addr = (unsigned long)fecp;
index 97953011464743a1bef797f43e7f2f5e1b9df092..742a3522bad2c525523b8659f480e68676b6566f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * BK Id: SCCS/s.m8xx_setup.c 1.32 09/27/01 09:01:12 trini
+ * BK Id: SCCS/s.m8xx_setup.c 1.35 10/11/01 11:55:47 trini
  *
  *  linux/arch/ppc/kernel/setup.c
  *
@@ -52,7 +52,7 @@ void m8xx_calibrate_decr(void);
 
 unsigned char __res[sizeof(bd_t)];
 
-extern void m8xx_ide_init();
+extern void m8xx_ide_init(void);
 
 #ifdef CONFIG_BLK_DEV_RAM
 extern int rd_doload;          /* 1 = load ramdisk, 0 = don't load */
@@ -164,9 +164,9 @@ void __init m8xx_calibrate_decr(void)
        ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = ~KAPWR_KEY;
        ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = ~KAPWR_KEY;
        ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = ~KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk = KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck = KAPWR_KEY;
-       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    = KAPWR_KEY;
+       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbscrk =  KAPWR_KEY;
+       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck =  KAPWR_KEY;
+       ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk    =  KAPWR_KEY;
 
        /* Disable the RTC one second and alarm interrupts. */
        ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc &=
index 31d37fa19bed7594c60be08991a52d70513f07b0..ea4a664958c1524a9f63c39bc694f2b7022e34e5 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.47 2001/07/27 09:42:22 davem Exp $
+# $Id: Makefile,v 1.48 2001/10/15 09:24:51 davem Exp $
 # sparc64/Makefile
 #
 # Makefile for the architecture dependent flags and dependencies on the
@@ -15,7 +15,7 @@ SHELL  =/bin/bash
 CC             := $(shell if gcc -m64 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo gcc; else echo sparc64-linux-gcc; fi )
 
 NEW_GCC := $(shell if $(CC) -m64 -mcmodel=medlow -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo y; else echo n; fi; )
-NEW_GAS := $(shell if $(LD) --version 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
+NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
 UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
 
 export NEW_GCC
index d0a35e7d9f3e8cc3bc124b050a1eccec6f42c933..a8f44fdffb32456118877c96081f219160c1eff1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: dtlb_base.S,v 1.16 2001/10/09 04:02:11 davem Exp $
+/* $Id: dtlb_base.S,v 1.17 2001/10/11 22:33:52 davem Exp $
  * dtlb_base.S:        Front end to DTLB miss replacement strategy.
  *              This is included directly into the trap table.
  *
@@ -71,8 +71,8 @@ from_tl1_trap:
        be,pn           %xcc, 3f                        ! Yep, special processing
         CREATE_VPTE_OFFSET2(%g4, %g6)                  ! Create VPTE offset
        cmp             %g5, 3                          ! Last trap level?
-       be,a,pn         %xcc, 1f                        ! Yep, use non-faulting load
-        ldxa           [%g3 + %g6] ASI_SNF, %g5        ! Load VPTE (no-VPTE-fault)
+       be,pn           %xcc, longpath                  ! Yep, cannot risk VPTE miss
+        nop                                            ! delay slot
 
 /* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses        */
        ldxa            [%g3 + %g6] ASI_S, %g5          ! Load VPTE
index ce82309ca7a50fb2846a9fce9ad32064cfee38a3..4137fd99dc8652aedde605b8d66db9dba470c5b3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.134 2001/08/27 18:42:07 kanoj Exp $
+/* $Id: entry.S,v 1.135 2001/10/13 23:04:09 kanoj Exp $
  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -725,19 +725,14 @@ netbsd_syscall:
 __do_data_access_exception_tl1:
        rdpr            %pstate, %g4
        wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
-       rdpr            %tl, %g3
-       cmp             %g3, 1
        mov             TLB_SFSR, %g3
        mov             DMMU_SFAR, %g5
        ldxa            [%g3] ASI_DMMU, %g4     ! Get SFSR
        ldxa            [%g5] ASI_DMMU, %g5     ! Get SFAR
        stxa            %g0, [%g3] ASI_DMMU     ! Clear SFSR.FaultValid bit
        membar          #Sync
-       bgu,pn          %icc, winfix_dax
+       ba,pt           %xcc, winfix_dax
         rdpr           %tpc, %g3
-       sethi           %hi(109f), %g7
-       ba,pt           %xcc, etraptl1
-        or             %g7, %lo(109f), %g7     ! Merge in below
 __do_data_access_exception:
        rdpr            %pstate, %g4
        wrpr            %g4, PSTATE_MG|PSTATE_AG, %pstate
@@ -1186,7 +1181,7 @@ do_mna:
        ldxa            [%g3] ASI_DMMU, %g5
        stxa            %g0, [%g3] ASI_DMMU     ! Clear FaultValid bit
        membar          #Sync
-       bgu,pn          %icc, winfix_dax
+       bgu,pn          %icc, winfix_mna
         rdpr           %tpc, %g3
 
 1:     sethi           %hi(109f), %g7
index ced3c3482c03b3ad302dced6b44a061d930a8436..20cd9a582fb3d3382afd3828a95b4566e4620bcf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.55 2001/06/05 09:56:06 davem Exp $
+/* $Id: rtrap.S,v 1.56 2001/10/13 00:14:34 kanoj Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -82,12 +82,12 @@ __handle_signal:
                 andn                   %l1, %l4, %l1
 
                .align                  64
-               .globl                  rtrap_clr_l6, rtrap
+               .globl                  rtrap_clr_l6, rtrap, irqsz_patchme
 rtrap_clr_l6:  clr                     %l6
 rtrap:         lduw                    [%g6 + AOFF_task_processor], %l0
                sethi                   %hi(irq_stat), %l2      ! &softirq_active
                or                      %l2, %lo(irq_stat), %l2 ! &softirq_active
-               sllx                    %l0, 6, %l0
+irqsz_patchme: sllx                    %l0, 0, %l0
                lduw                    [%l2 + %l0], %l1        ! softirq_pending
                cmp                     %l1, 0
 
index 5830873d8f02da21b997158f62d6151fdf711183..7c1344f2b3b19ae62fe99caac3ba6d27cc778658 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.67 2001/09/21 03:17:06 kanoj Exp $
+/*  $Id: setup.c,v 1.68 2001/10/13 00:14:34 kanoj Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
@@ -480,6 +480,18 @@ void __init setup_arch(char **cmdline_p)
        conswitchp = &prom_con;
 #endif
 
+#ifdef CONFIG_SMP
+       i = (unsigned long)&irq_stat[1] - (unsigned long)&irq_stat[0];
+       if ((i == SMP_CACHE_BYTES) || (i == (2 * SMP_CACHE_BYTES))) {
+               extern unsigned int irqsz_patchme[1];
+               irqsz_patchme[0] |= ((i == SMP_CACHE_BYTES) ? SMP_CACHE_BYTES_SHIFT : \
+                                                       SMP_CACHE_BYTES_SHIFT + 1);
+               flushi((long)&irqsz_patchme[1]);
+       } else {
+               prom_printf("Unexpected size of irq_stat[] elements\n");
+               prom_halt();
+       }
+#endif
        /* Work out if we are starfire early on */
        check_if_starfire();
 
index a6b62c9694bc165252a8e439e39b9155fb8a4cf9..f03eed261d6142a895e27d34ca83069e6380906a 100644 (file)
@@ -39,7 +39,6 @@
 #define BREAKPOINT3
 #define disable() __cli()
 #define enable()  __sti()
-#define wbinvd()
 
 /*! [Begin] no source code translation */
 
index f77ca63e4be1fa78e2682b57ef564645cc78a254..8ead560c54a65fb91927bd782265a0032e6742f0 100644 (file)
@@ -19,8 +19,8 @@
 */
 
 
-#define DAC960_DriverVersion                   "2.4.10"
-#define DAC960_DriverDate                      "23 July 2001"
+#define DAC960_DriverVersion                   "2.4.11"
+#define DAC960_DriverDate                      "11 October 2001"
 
 
 #include <linux/version.h>
@@ -42,6 +42,7 @@
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/uaccess.h>
@@ -99,7 +100,7 @@ static PROC_DirectoryEntry_T
 */
 
 static NotifierBlock_T
-  DAC960_NotifierBlock =    { DAC960_Finalize, NULL, 0 };
+  DAC960_NotifierBlock =    { DAC960_Notifier, NULL, 0 };
 
 
 /*
@@ -269,7 +270,9 @@ static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command)
 
 /*
   DAC960_AllocateCommand allocates a Command structure from Controller's
-  free list.
+  free list.  During driver initialization, a special initialization command
+  has been placed on the free list to guarantee that command allocation can
+  never fail.
 */
 
 static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T
@@ -479,6 +482,52 @@ static void DAC960_PD_QueueCommand(DAC960_Command_T *Command)
 }
 
 
+/*
+  DAC960_P_QueueCommand queues Command for DAC960 P Series Controllers.
+*/
+
+static void DAC960_P_QueueCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  switch (CommandMailbox->Common.CommandOpcode)
+    {
+    case DAC960_V1_Enquiry:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_Enquiry_Old;
+      break;
+    case DAC960_V1_GetDeviceState:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_GetDeviceState_Old;
+      break;
+    case DAC960_V1_Read:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_Read_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    case DAC960_V1_Write:
+      CommandMailbox->Common.CommandOpcode = DAC960_V1_Write_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    case DAC960_V1_ReadWithScatterGather:
+      CommandMailbox->Common.CommandOpcode =
+       DAC960_V1_ReadWithScatterGather_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    case DAC960_V1_WriteWithScatterGather:
+      CommandMailbox->Common.CommandOpcode =
+       DAC960_V1_WriteWithScatterGather_Old;
+      DAC960_PD_To_P_TranslateReadWriteCommand(CommandMailbox);
+      break;
+    default:
+      break;
+    }
+  while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
+    udelay(1);
+  DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
+  DAC960_PD_NewCommand(ControllerBaseAddress);
+}
+
+
 /*
   DAC960_ExecuteCommand executes Command and waits for completion.
 */
@@ -521,6 +570,32 @@ static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
 }
 
 
+/*
+  DAC960_V1_ExecuteTypeB executes a DAC960 V1 Firmware Controller Type 3B
+  Command and waits for completion.  It returns true on success and false
+  on failure.
+*/
+
+static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
+                                      DAC960_V1_CommandOpcode_T CommandOpcode,
+                                      unsigned char CommandOpcode2,
+                                      void *DataPointer)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  DAC960_V1_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->Type3B.CommandOpcode = CommandOpcode;
+  CommandMailbox->Type3B.CommandOpcode2 = CommandOpcode2;
+  CommandMailbox->Type3B.BusAddress = Virtual_to_Bus32(DataPointer);
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V1.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V1_NormalCompletion);
+}
+
+
 /*
   DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
   Command and waits for completion.  It returns true on success and false
@@ -1055,7 +1130,17 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
     DAC1164P               5.06 and above
     DAC960PTL/PRL/PJ/PG            4.06 and above
     DAC960PU/PD/PL         3.51 and above
+    DAC960PU/PD/PL/P       2.73 and above
   */
+  if (Enquiry2.FirmwareID.MajorVersion == 0)
+    {
+      Enquiry2.FirmwareID.MajorVersion =
+       Controller->V1.Enquiry.MajorFirmwareVersion;
+      Enquiry2.FirmwareID.MinorVersion =
+       Controller->V1.Enquiry.MinorFirmwareVersion;
+      Enquiry2.FirmwareID.FirmwareType = '0';
+      Enquiry2.FirmwareID.TurnID = 0;
+    }
   sprintf(Controller->FirmwareVersion, "%d.%02d-%c-%02d",
          Enquiry2.FirmwareID.MajorVersion, Enquiry2.FirmwareID.MinorVersion,
          Enquiry2.FirmwareID.FirmwareType, Enquiry2.FirmwareID.TurnID);
@@ -1064,7 +1149,9 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
        (Controller->FirmwareVersion[0] == '4' &&
         strcmp(Controller->FirmwareVersion, "4.06") >= 0) ||
        (Controller->FirmwareVersion[0] == '3' &&
-        strcmp(Controller->FirmwareVersion, "3.51") >= 0)))
+        strcmp(Controller->FirmwareVersion, "3.51") >= 0) ||
+       (Controller->FirmwareVersion[0] == '2' &&
+        strcmp(Controller->FirmwareVersion, "2.73") >= 0)))
     {
       DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
       DAC960_Error("Firmware Version = '%s'\n", Controller,
@@ -1119,6 +1206,20 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
     default:
       return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
     }
+  /*
+    Initialize the Background Initialization Status.
+  */
+  if ((Controller->FirmwareVersion[0] == '4' &&
+      strcmp(Controller->FirmwareVersion, "4.08") >= 0) ||
+      (Controller->FirmwareVersion[0] == '5' &&
+       strcmp(Controller->FirmwareVersion, "5.08") >= 0))
+    {
+      Controller->V1.BackgroundInitializationStatusSupported = true;
+      DAC960_V1_ExecuteType3B(Controller,
+                             DAC960_V1_BackgroundInitializationControl, 0x20,
+                             &Controller->
+                              V1.LastBackgroundInitializationStatus);
+    }
   /*
     Initialize the Logical Drive Initially Accessible flag.
   */
@@ -1573,7 +1674,7 @@ static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
            DeviceState->DeviceType == DAC960_V1_DiskType)
          {
            if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
-             DAC960_Info("         Disk Status: %s, %d blocks, %d resets\n",
+             DAC960_Info("         Disk Status: %s, %u blocks, %d resets\n",
                          Controller,
                          (DeviceState->DeviceState == DAC960_V1_Device_Dead
                           ? "Dead"
@@ -1586,7 +1687,7 @@ static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
                          DeviceState->DiskSize,
                          Controller->V1.DeviceResetCount[Channel][TargetID]);
            else
-             DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
+             DAC960_Info("         Disk Status: %s, %u blocks\n", Controller,
                          (DeviceState->DeviceState == DAC960_V1_Device_Dead
                           ? "Dead"
                           : DeviceState->DeviceState
@@ -1615,7 +1716,7 @@ static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
     {
       DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
        &Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
-      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
+      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %u blocks, %s\n",
                  Controller, Controller->ControllerNumber, LogicalDriveNumber,
                  LogicalDriveInformation->RAIDLevel,
                  (LogicalDriveInformation->LogicalDriveState
@@ -1681,18 +1782,32 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
       if (PhysicalDeviceInfo->PhysicalDeviceState ==
          DAC960_V2_Device_Unconfigured)
        continue;
-      DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
+      DAC960_Info("         Disk Status: %s, %u blocks\n", Controller,
                  (PhysicalDeviceInfo->PhysicalDeviceState
                   == DAC960_V2_Device_Online
                   ? "Online"
                   : PhysicalDeviceInfo->PhysicalDeviceState
-                    == DAC960_V2_Device_WriteOnly
-                    ? "Write-Only"
+                    == DAC960_V2_Device_Rebuild
+                    ? "Rebuild"
                     : PhysicalDeviceInfo->PhysicalDeviceState
-                      == DAC960_V2_Device_Dead
-                      ? "Dead" : "Standby"),
-                 PhysicalDeviceInfo
-                 ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+                      == DAC960_V2_Device_Missing
+                      ? "Missing"
+                      : PhysicalDeviceInfo->PhysicalDeviceState
+                        == DAC960_V2_Device_Critical
+                        ? "Critical"
+                        : PhysicalDeviceInfo->PhysicalDeviceState
+                          == DAC960_V2_Device_Dead
+                          ? "Dead"
+                          : PhysicalDeviceInfo->PhysicalDeviceState
+                            == DAC960_V2_Device_SuspectedDead
+                            ? "Suspected-Dead"
+                            : PhysicalDeviceInfo->PhysicalDeviceState
+                              == DAC960_V2_Device_CommandedOffline
+                              ? "Commanded-Offline"
+                              : PhysicalDeviceInfo->PhysicalDeviceState
+                                == DAC960_V2_Device_Standby
+                                ? "Standby" : "Unknown"),
+                 PhysicalDeviceInfo->ConfigurableDeviceSize);
       if (PhysicalDeviceInfo->ParityErrors == 0 &&
          PhysicalDeviceInfo->SoftErrors == 0 &&
          PhysicalDeviceInfo->HardErrors == 0 &&
@@ -1734,7 +1849,7 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
                                            "-", "-", "-", "-" };
       unsigned char *GeometryTranslation;
       if (LogicalDeviceInfo == NULL) continue;
-      switch(LogicalDeviceInfo->DriveGeometry)
+      switch (LogicalDeviceInfo->DriveGeometry)
        {
        case DAC960_V2_Geometry_128_32:
          GeometryTranslation = "128/32";
@@ -1748,7 +1863,7 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
                       Controller, LogicalDeviceInfo->DriveGeometry);
          break;
        }
-      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
+      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %u blocks\n",
                  Controller, Controller->ControllerNumber, LogicalDriveNumber,
                  LogicalDeviceInfo->RAIDLevel,
                  (LogicalDeviceInfo->LogicalDeviceState
@@ -1757,7 +1872,7 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
                   : LogicalDeviceInfo->LogicalDeviceState
                     == DAC960_V2_LogicalDevice_Critical
                     ? "Critical" : "Offline"),
-                 LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+                 LogicalDeviceInfo->ConfigurableDeviceSize);
       DAC960_Info("                  Logical Device %s, BIOS Geometry: %s\n",
                  Controller,
                  (LogicalDeviceInfo->LogicalDeviceControl
@@ -1907,15 +2022,11 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
   RequestQueue->queuedata = Controller;
   Controller->RequestQueue = RequestQueue;
   /*
-    Initialize the Disk Partitions array, Partition Sizes array, Block Sizes
-    array, and Max Sectors per Request array.
+    Initialize the Max Sectors per Request array.
   */
   for (MinorNumber = 0; MinorNumber < DAC960_MinorCount; MinorNumber++)
-    {
-      Controller->BlockSizes[MinorNumber] = BLOCK_SIZE;
-      Controller->MaxSectorsPerRequest[MinorNumber] =
-       Controller->MaxBlocksPerCommand;
-    }
+    Controller->MaxSectorsPerRequest[MinorNumber] =
+      Controller->MaxBlocksPerCommand;
   Controller->GenericDiskInfo.part = Controller->DiskPartitions;
   Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
   blksize_size[MajorNumber] = Controller->BlockSizes;
@@ -1931,7 +2042,8 @@ static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
   Controller->GenericDiskInfo.major_name = "rd";
   Controller->GenericDiskInfo.minor_shift = DAC960_MaxPartitionsBits;
   Controller->GenericDiskInfo.max_p = DAC960_MaxPartitions;
-  Controller->GenericDiskInfo.nr_real = Controller->LogicalDriveCount;
+  Controller->GenericDiskInfo.nr_real = DAC960_MaxLogicalDrives;
+  Controller->GenericDiskInfo.real_devices = Controller;
   Controller->GenericDiskInfo.next = NULL;
   Controller->GenericDiskInfo.fops = &DAC960_BlockDeviceOperations;
   /*
@@ -1977,6 +2089,46 @@ static void DAC960_UnregisterBlockDevice(DAC960_Controller_T *Controller)
 }
 
 
+/*
+  DAC960_ComputeGenericDiskInfo computes the values for the Generic Disk
+  Information Partition Sector Counts and Block Sizes.
+*/
+
+static void DAC960_ComputeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
+{
+  DAC960_Controller_T *Controller =
+    (DAC960_Controller_T *) GenericDiskInfo->real_devices;
+  int LogicalDriveNumber, i;
+  for (LogicalDriveNumber = 0;
+       LogicalDriveNumber < DAC960_MaxLogicalDrives;
+       LogicalDriveNumber++)
+    {
+      int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber, 0);
+      if (Controller->FirmwareType == DAC960_V1_Controller)
+       {
+         if (LogicalDriveNumber < Controller->LogicalDriveCount)
+           GenericDiskInfo->part[MinorNumber].nr_sects =
+             Controller->V1.LogicalDriveInformation
+                            [LogicalDriveNumber].LogicalDriveSize;
+         else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
+       }
+      else
+       {
+         DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+           Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+         if (LogicalDeviceInfo != NULL)
+           GenericDiskInfo->part[MinorNumber].nr_sects =
+             LogicalDeviceInfo->ConfigurableDeviceSize;
+         else GenericDiskInfo->part[MinorNumber].nr_sects = 0;
+       }
+      for (i = 0; i < DAC960_MaxPartitions; i++)
+       if (GenericDiskInfo->part[MinorNumber].nr_sects > 0)
+         Controller->BlockSizes[MinorNumber + i] = BLOCK_SIZE;
+       else Controller->BlockSizes[MinorNumber + i] = 0;
+    }
+}
+
+
 /*
   DAC960_RegisterDisk registers the DAC960 Logical Disk Device for Logical
   Drive Number if it exists.
@@ -1991,7 +2143,8 @@ static void DAC960_RegisterDisk(DAC960_Controller_T *Controller,
       register_disk(&Controller->GenericDiskInfo,
                    DAC960_KernelDevice(Controller->ControllerNumber,
                                        LogicalDriveNumber, 0),
-                   DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
+                   DAC960_MaxPartitions,
+                   &DAC960_BlockDeviceOperations,
                    Controller->V1.LogicalDriveInformation
                                   [LogicalDriveNumber].LogicalDriveSize);
     }
@@ -2003,9 +2156,9 @@ static void DAC960_RegisterDisk(DAC960_Controller_T *Controller,
       register_disk(&Controller->GenericDiskInfo,
                    DAC960_KernelDevice(Controller->ControllerNumber,
                                        LogicalDriveNumber, 0),
-                   DAC960_MaxPartitions, &DAC960_BlockDeviceOperations,
-                   LogicalDeviceInfo
-                   ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+                   DAC960_MaxPartitions,
+                   &DAC960_BlockDeviceOperations,
+                   LogicalDeviceInfo->ConfigurableDeviceSize);
     }
 }
 
@@ -2116,6 +2269,13 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
       InterruptHandler = DAC960_PD_InterruptHandler;
       MemoryWindowSize = DAC960_PD_RegisterWindowSize;
       break;
+    case DAC960_P_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_P;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_P_InterruptHandler;
+      MemoryWindowSize = DAC960_PD_RegisterWindowSize;
+      break;
     }
   while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
     {
@@ -2151,6 +2311,10 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
          IO_Address = pci_resource_start(PCI_Device, 0);
          PCI_Address = pci_resource_start(PCI_Device, 1);
          break;
+       case DAC960_P_Controller:
+         IO_Address = pci_resource_start(PCI_Device, 0);
+         PCI_Address = pci_resource_start(PCI_Device, 1);
+         break;
        }
       if (DAC960_ControllerCount == DAC960_MaxControllers)
        {
@@ -2348,6 +2512,32 @@ static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
          Controller->QueueReadWriteCommand =
            DAC960_V1_QueueReadWriteCommand;
          break;
+       case DAC960_P_Controller:
+         request_region(Controller->IO_Address, 0x80,
+                        Controller->FullModelName);
+         DAC960_PD_DisableInterrupts(BaseAddress);
+         DAC960_PD_AcknowledgeStatus(BaseAddress);
+         udelay(1000);
+         while (DAC960_PD_InitializationInProgressP(BaseAddress))
+           {
+             if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
+                                           &Parameter0, &Parameter1) &&
+                 DAC960_ReportErrorStatus(Controller, ErrorStatus,
+                                          Parameter0, Parameter1))
+               goto Failure;
+             udelay(10);
+           }
+         DAC960_PD_EnableInterrupts(Controller->BaseAddress);
+         Controller->QueueCommand = DAC960_P_QueueCommand;
+         Controller->ReadControllerConfiguration =
+           DAC960_V1_ReadControllerConfiguration;
+         Controller->ReadDeviceConfiguration =
+           DAC960_V1_ReadDeviceConfiguration;
+         Controller->ReportDeviceConfiguration =
+           DAC960_V1_ReportDeviceConfiguration;
+         Controller->QueueReadWriteCommand =
+           DAC960_V1_QueueReadWriteCommand;
+         break;
        }
       /*
        Acquire shared access to the IRQ Channel.
@@ -2519,7 +2709,7 @@ static void DAC960_FinalizeController(DAC960_Controller_T *Controller)
   DAC960_Initialize initializes the DAC960 Driver.
 */
 
-void DAC960_Initialize(void)
+static int DAC960_Initialize(void)
 {
   int ControllerNumber;
   DAC960_DetectControllers(DAC960_BA_Controller);
@@ -2527,8 +2717,9 @@ void DAC960_Initialize(void)
   DAC960_DetectControllers(DAC960_LA_Controller);
   DAC960_DetectControllers(DAC960_PG_Controller);
   DAC960_DetectControllers(DAC960_PD_Controller);
+  DAC960_DetectControllers(DAC960_P_Controller);
   DAC960_SortControllers();
-  if (DAC960_ActiveControllerCount == 0) return;
+  if (DAC960_ActiveControllerCount == 0) return -ENODEV;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
@@ -2537,6 +2728,7 @@ void DAC960_Initialize(void)
       int LogicalDriveNumber;
       if (Controller == NULL) continue;
       DAC960_InitializeController(Controller);
+      DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
       for (LogicalDriveNumber = 0;
           LogicalDriveNumber < DAC960_MaxLogicalDrives;
           LogicalDriveNumber++)
@@ -2544,6 +2736,7 @@ void DAC960_Initialize(void)
     }
   DAC960_CreateProcEntries();
   register_reboot_notifier(&DAC960_NotifierBlock);
+  return 0;
 }
 
 
@@ -2551,14 +2744,10 @@ void DAC960_Initialize(void)
   DAC960_Finalize finalizes the DAC960 Driver.
 */
 
-static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
-                          unsigned long Event,
-                          void *Buffer)
+static void DAC960_Finalize(void)
 {
   int ControllerNumber;
-  if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
-    return NOTIFY_DONE;
-  if (DAC960_ActiveControllerCount == 0) return NOTIFY_OK;
+  if (DAC960_ActiveControllerCount == 0) return;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
@@ -2566,6 +2755,20 @@ static int DAC960_Finalize(NotifierBlock_T *NotifierBlock,
       DAC960_FinalizeController(DAC960_Controllers[ControllerNumber]);
   DAC960_DestroyProcEntries();
   unregister_reboot_notifier(&DAC960_NotifierBlock);
+}
+
+
+/*
+  DAC960_Notifier is the notifier for the DAC960 Driver.
+*/
+
+static int DAC960_Notifier(NotifierBlock_T *NotifierBlock,
+                          unsigned long Event,
+                          void *Buffer)
+{
+  if (!(Event == SYS_RESTART || Event == SYS_HALT || Event == SYS_POWER_OFF))
+    return NOTIFY_DONE;
+  DAC960_Finalize();
   return NOTIFY_OK;
 }
 
@@ -2599,11 +2802,9 @@ static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
       char *LastDataEndPointer = NULL;
       int SegmentNumber = 0;
       if (Command->CommandType == DAC960_ReadCommand)
-       CommandMailbox->Type5.CommandOpcode =
-         DAC960_V1_ReadWithOldScatterGather;
+       CommandMailbox->Type5.CommandOpcode = DAC960_V1_ReadWithScatterGather;
       else
-       CommandMailbox->Type5.CommandOpcode =
-         DAC960_V1_WriteWithOldScatterGather;
+       CommandMailbox->Type5.CommandOpcode = DAC960_V1_WriteWithScatterGather;
       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
@@ -2865,12 +3066,12 @@ static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
                   Controller, Command->V1.CommandStatus, CommandName);
       break;
     }
-  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
+  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%u\n",
               Controller, Controller->ControllerNumber,
               Command->LogicalDriveNumber, Command->BlockNumber,
               Command->BlockNumber + Command->BlockCount - 1);
   if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
-    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
                 Controller, Controller->ControllerNumber,
                 Command->LogicalDriveNumber,
                 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
@@ -3027,6 +3228,8 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
                                LogicalDriveNumber,
                                Controller->ControllerNumber,
                                LogicalDriveNumber);
+             Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
+             DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
            }
          if (NewEnquiry->NumberOfLogicalDrives < Controller->LogicalDriveCount)
            {
@@ -3037,8 +3240,9 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
                                LogicalDriveNumber,
                                Controller->ControllerNumber,
                                LogicalDriveNumber);
+             Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
+             DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
            }
-         Controller->LogicalDriveCount = NewEnquiry->NumberOfLogicalDrives;
          if (NewEnquiry->StatusFlags.DeferredWriteError !=
              OldEnquiry->StatusFlags.DeferredWriteError)
            DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
@@ -3064,6 +3268,8 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
              Controller->V1.NeedErrorTableInformation = true;
              Controller->V1.NeedDeviceStateInformation = true;
              Controller->V1.StartDeviceStateScan = true;
+             Controller->V1.NeedBackgroundInitializationStatus =
+               Controller->V1.BackgroundInitializationStatusSupported;
              Controller->SecondaryMonitoringTime = jiffies;
            }
          if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
@@ -3186,7 +3392,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
                           AdditionalSenseCodeQualifier == 0x02))))
                {
                  DAC960_Critical("Physical Device %d:%d Error Log: "
-                                 "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+                                 "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
                                  Controller,
                                  EventLogEntry->Channel,
                                  EventLogEntry->TargetID,
@@ -3396,6 +3602,77 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
              Controller->EphemeralProgressMessage = false;
            }
        }
+      else if (CommandOpcode == DAC960_V1_BackgroundInitializationControl)
+       {
+         unsigned int LogicalDriveNumber =
+           Controller->V1.BackgroundInitializationStatus.LogicalDriveNumber;
+         unsigned int LogicalDriveSize =
+           Controller->V1.BackgroundInitializationStatus.LogicalDriveSize;
+         unsigned int BlocksCompleted =
+           Controller->V1.BackgroundInitializationStatus.BlocksCompleted;
+         switch (CommandStatus)
+           {
+           case DAC960_V1_NormalCompletion:
+             switch (Controller->V1.BackgroundInitializationStatus.Status)
+               {
+               case DAC960_V1_BackgroundInitializationInvalid:
+                 break;
+               case DAC960_V1_BackgroundInitializationStarted:
+                 DAC960_Progress("Background Initialization Started\n",
+                                 Controller);
+                 break;
+               case DAC960_V1_BackgroundInitializationInProgress:
+                 if (BlocksCompleted ==
+                     Controller->V1.LastBackgroundInitializationStatus
+                                   .BlocksCompleted &&
+                     LogicalDriveNumber ==
+                     Controller->V1.LastBackgroundInitializationStatus
+                                   .LogicalDriveNumber)
+                   break;
+                 Controller->EphemeralProgressMessage = true;
+                 DAC960_Progress("Background Initialization in Progress: "
+                                 "Logical Drive %d (/dev/rd/c%dd%d) "
+                                 "%d%% completed\n",
+                                 Controller, LogicalDriveNumber,
+                                 Controller->ControllerNumber,
+                                 LogicalDriveNumber,
+                                 (100 * (BlocksCompleted >> 7))
+                                 / (LogicalDriveSize >> 7));
+                 Controller->EphemeralProgressMessage = false;
+                 break;
+               case DAC960_V1_BackgroundInitializationSuspended:
+                 DAC960_Progress("Background Initialization Suspended\n",
+                                 Controller);
+                 break;
+               case DAC960_V1_BackgroundInitializationCancelled:
+                 DAC960_Progress("Background Initialization Cancelled\n",
+                                 Controller);
+                 break;
+               }
+             memcpy(&Controller->V1.LastBackgroundInitializationStatus,
+                    &Controller->V1.BackgroundInitializationStatus,
+                    sizeof(DAC960_V1_BackgroundInitializationStatus_T));
+             break;
+           case DAC960_V1_BackgroundInitSuccessful:
+             if (Controller->V1.BackgroundInitializationStatus.Status ==
+                 DAC960_V1_BackgroundInitializationInProgress)
+               DAC960_Progress("Background Initialization "
+                               "Completed Successfully\n", Controller);
+             Controller->V1.BackgroundInitializationStatus.Status =
+               DAC960_V1_BackgroundInitializationInvalid;
+             break;
+           case DAC960_V1_BackgroundInitAborted:
+             if (Controller->V1.BackgroundInitializationStatus.Status ==
+                 DAC960_V1_BackgroundInitializationInProgress)
+               DAC960_Progress("Background Initialization Aborted\n",
+                               Controller);
+             Controller->V1.BackgroundInitializationStatus.Status =
+               DAC960_V1_BackgroundInitializationInvalid;
+             break;
+           case DAC960_V1_NoBackgroundInitInProgress:
+             break;
+           }
+       }
     }
   if (CommandType == DAC960_MonitoringCommand)
     {
@@ -3562,6 +3839,17 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
          DAC960_QueueCommand(Command);
          return;
        }
+      if (Controller->V1.NeedBackgroundInitializationStatus)
+       {
+         Controller->V1.NeedBackgroundInitializationStatus = false;
+         Command->V1.CommandMailbox.Type3B.CommandOpcode =
+           DAC960_V1_BackgroundInitializationControl;
+         Command->V1.CommandMailbox.Type3B.CommandOpcode2 = 0x20;
+         Command->V1.CommandMailbox.Type3B.BusAddress =
+           Virtual_to_Bus32(&Controller->V1.BackgroundInitializationStatus);
+         DAC960_QueueCommand(Command);
+         return;
+       }
       Controller->MonitoringTimerCount++;
       Controller->MonitoringTimer.expires =
        jiffies + DAC960_MonitoringTimerInterval;
@@ -3642,12 +3930,12 @@ static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
     }
   DAC960_Error("Error Condition %s on %s:\n", Controller,
               SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
-  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
+  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %u..%u\n",
               Controller, Controller->ControllerNumber,
               Command->LogicalDriveNumber, Command->BlockNumber,
               Command->BlockNumber + Command->BlockCount - 1);
   if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
-    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %u..%u\n",
                 Controller, Controller->ControllerNumber,
                 Command->LogicalDriveNumber,
                 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
@@ -3680,11 +3968,14 @@ static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
       { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
       { 0x000C, "S Offline" },
       { 0x000D, "P Found" },
-      { 0x000E, "P Gone" },
+      { 0x000E, "P Removed" },
       { 0x000F, "P Unconfigured" },
       { 0x0010, "P Expand Capacity Started" },
       { 0x0011, "P Expand Capacity Completed" },
       { 0x0012, "P Expand Capacity Failed" },
+      { 0x0013, "P Command Timed Out" },
+      { 0x0014, "P Command Aborted" },
+      { 0x0015, "P Command Retried" },
       { 0x0016, "P Parity Error" },
       { 0x0017, "P Soft Error" },
       { 0x0018, "P Miscellaneous Error" },
@@ -3715,6 +4006,8 @@ static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
       { 0x0031, "P Failed because BDT Write Operation Failed" },
       { 0x0039, "P Missing at Startup" },
       { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
+      { 0x003C, "P Temporarily Offline Device Automatically Made Online" },
+      { 0x003D, "P Standby Rebuild Started" },
       /* Logical Device Events (0x0080 - 0x00FF) */
       { 0x0080, "M Consistency Check Started" },
       { 0x0081, "M Consistency Check Completed" },
@@ -3737,7 +4030,7 @@ static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
       { 0x0092, "M Initialization Cancelled" },
       { 0x0093, "M Initialization Failed" },
       { 0x0094, "L Found" },
-      { 0x0095, "L Gone" },
+      { 0x0095, "L Deleted" },
       { 0x0096, "M Expand Capacity Started" },
       { 0x0097, "M Expand Capacity Completed" },
       { 0x0098, "M Expand Capacity Failed" },
@@ -3747,6 +4040,9 @@ static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
       { 0x009C, "L Bad Data Block Found" },
       { 0x009E, "L Read of Data Block in BDT" },
       { 0x009F, "L Write Back Data for Disk Block Lost" },
+      { 0x00A0, "L Temporarily Offline RAID-5/3 Drive Made Online" },
+      { 0x00A1, "L Temporarily Offline RAID-6/1/0/7 Drive Made Online" },
+      { 0x00A2, "L Standby Rebuild Started" },
       /* Fault Management Events (0x0100 - 0x017F) */
       { 0x0140, "E Fan %d Failed" },
       { 0x0141, "E Fan %d OK" },
@@ -3754,24 +4050,31 @@ static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
       { 0x0143, "E Power Supply %d Failed" },
       { 0x0144, "E Power Supply %d OK" },
       { 0x0145, "E Power Supply %d Not Present" },
-      { 0x0146, "E Temperature Sensor %d Failed" },
-      { 0x0147, "E Temperature Sensor %d Critical" },
-      { 0x0148, "E Temperature Sensor %d OK" },
+      { 0x0146, "E Temperature Sensor %d Temperature Exceeds Safe Limit" },
+      { 0x0147, "E Temperature Sensor %d Temperature Exceeds Working Limit" },
+      { 0x0148, "E Temperature Sensor %d Temperature Normal" },
       { 0x0149, "E Temperature Sensor %d Not Present" },
-      { 0x014A, "E Unit %d Access Critical" },
-      { 0x014B, "E Unit %d Access OK" },
-      { 0x014C, "E Unit %d Access Offline" },
+      { 0x014A, "E Enclosure Management Unit %d Access Critical" },
+      { 0x014B, "E Enclosure Management Unit %d Access OK" },
+      { 0x014C, "E Enclosure Management Unit %d Access Offline" },
       /* Controller Events (0x0180 - 0x01FF) */
       { 0x0181, "C Cache Write Back Error" },
       { 0x0188, "C Battery Backup Unit Found" },
       { 0x0189, "C Battery Backup Unit Charge Level Low" },
       { 0x018A, "C Battery Backup Unit Charge Level OK" },
       { 0x0193, "C Installation Aborted" },
-      { 0x0195, "C Mirror Race Recovery In Progress" },
-      { 0x0196, "C Mirror Race on Critical Drive" },
-      { 0x019E, "C Memory Soft ECC Error" },
-      { 0x019F, "C Memory Hard ECC Error" },
+      { 0x0195, "C Battery Backup Unit Physically Removed" },
+      { 0x0196, "C Memory Error During Warm Boot" },
+      { 0x019E, "C Memory Soft ECC Error Corrected" },
+      { 0x019F, "C Memory Hard ECC Error Corrected" },
       { 0x01A2, "C Battery Backup Unit Failed" },
+      { 0x01AB, "C Mirror Race Recovery Failed" },
+      { 0x01AC, "C Mirror Race on Critical Drive" },
+      /* Controller Internal Processor Events */
+      { 0x0380, "C Internal Controller Hung" },
+      { 0x0381, "C Internal Controller Firmware Breakpoint" },
+      { 0x0390, "C Internal Controller i960 Processor Specific Error" },
+      { 0x03A0, "C Internal Controller StrongARM Processor Specific Error" },
       { 0, "" } };
   int EventListIndex = 0, EventCode;
   unsigned char EventType, *EventMessage;
@@ -3821,7 +4124,7 @@ static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
       DAC960_Critical("Physical Device %d:%d %s\n", Controller,
                      Event->Channel, Event->TargetID, EventMessage);
       DAC960_Critical("Physical Device %d:%d Request Sense: "
-                     "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+                     "Sense Key = %X, ASC = %02X, ASCQ = %02X\n",
                      Controller,
                      Event->Channel,
                      Event->TargetID,
@@ -4142,22 +4445,34 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
            {
              if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
                  PhysicalDeviceInfo->PhysicalDeviceState)
-               DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
-                               NewPhysicalDeviceInfo->Channel,
-                               NewPhysicalDeviceInfo->TargetID,
-                               (NewPhysicalDeviceInfo->PhysicalDeviceState
-                                == DAC960_V2_Device_Unconfigured
-                                ? "UNCONFIGURED"
-                                : NewPhysicalDeviceInfo->PhysicalDeviceState
-                                  == DAC960_V2_Device_Online
-                                  ? "ONLINE"
-                                  : NewPhysicalDeviceInfo->PhysicalDeviceState
-                                    == DAC960_V2_Device_WriteOnly
-                                    ? "WRITE-ONLY"
-                                    : NewPhysicalDeviceInfo
-                                      ->PhysicalDeviceState
-                                      == DAC960_V2_Device_Dead
-                                      ? "DEAD" : "STANDBY"));
+               DAC960_Critical(
+                 "Physical Device %d:%d is now %s\n", Controller,
+                 NewPhysicalDeviceInfo->Channel,
+                 NewPhysicalDeviceInfo->TargetID,
+                 (NewPhysicalDeviceInfo->PhysicalDeviceState
+                  == DAC960_V2_Device_Online
+                  ? "ONLINE"
+                  : NewPhysicalDeviceInfo->PhysicalDeviceState
+                    == DAC960_V2_Device_Rebuild
+                    ? "REBUILD"
+                    : NewPhysicalDeviceInfo->PhysicalDeviceState
+                      == DAC960_V2_Device_Missing
+                      ? "MISSING"
+                      : NewPhysicalDeviceInfo->PhysicalDeviceState
+                        == DAC960_V2_Device_Critical
+                        ? "CRITICAL"
+                        : NewPhysicalDeviceInfo->PhysicalDeviceState
+                          == DAC960_V2_Device_Dead
+                          ? "DEAD"
+                          : NewPhysicalDeviceInfo->PhysicalDeviceState
+                            == DAC960_V2_Device_SuspectedDead
+                            ? "SUSPECTED-DEAD"
+                            : NewPhysicalDeviceInfo->PhysicalDeviceState
+                              == DAC960_V2_Device_CommandedOffline
+                              ? "COMMANDED-OFFLINE"
+                              : NewPhysicalDeviceInfo->PhysicalDeviceState
+                                == DAC960_V2_Device_Standby
+                                ? "STANDBY" : "UNKNOWN"));
              if ((NewPhysicalDeviceInfo->ParityErrors !=
                   PhysicalDeviceInfo->ParityErrors) ||
                  (NewPhysicalDeviceInfo->SoftErrors !=
@@ -4263,13 +4578,16 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
                              (LogicalDeviceInfo != NULL
                               ? "" : " - Allocation Failed"));
              if (LogicalDeviceInfo != NULL)
-               memset(LogicalDeviceInfo, 0,
-                      sizeof(DAC960_V2_LogicalDeviceInfo_T));
+               {
+                 memset(LogicalDeviceInfo, 0,
+                        sizeof(DAC960_V2_LogicalDeviceInfo_T));
+                 DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
+               }
            }
          if (LogicalDeviceInfo != NULL)
            {
              unsigned long LogicalDeviceSize =
-               NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+               NewLogicalDeviceInfo->ConfigurableDeviceSize;
              if (NewLogicalDeviceInfo->LogicalDeviceState !=
                  LogicalDeviceInfo->LogicalDeviceState)
                DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -4380,6 +4698,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
              kfree(LogicalDeviceInfo);
              Controller->LogicalDriveInitiallyAccessible
                          [LogicalDriveNumber] = false;
+             DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
            }
          Controller->V2.NeedLogicalDeviceInformation = false;
        }
@@ -4784,6 +5103,85 @@ static void DAC960_PD_InterruptHandler(int IRQ_Channel,
 }
 
 
+/*
+  DAC960_P_InterruptHandler handles hardware interrupts from DAC960 P Series
+  Controllers.
+*/
+
+static void DAC960_P_InterruptHandler(int IRQ_Channel,
+                                     void *DeviceIdentifier,
+                                     Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
+    {
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+       DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+      DAC960_V1_CommandOpcode_T CommandOpcode =
+       CommandMailbox->Common.CommandOpcode;
+      Command->V1.CommandStatus =
+       DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
+      switch (CommandOpcode)
+       {
+       case DAC960_V1_Enquiry_Old:
+         Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Enquiry;
+         DAC960_P_To_PD_TranslateEnquiry(
+           Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+         break;
+       case DAC960_V1_GetDeviceState_Old:
+         Command->V1.CommandMailbox.Common.CommandOpcode =
+           DAC960_V1_GetDeviceState;
+         DAC960_P_To_PD_TranslateDeviceState(
+           Bus32_to_Virtual(CommandMailbox->Type3.BusAddress));
+         break;
+       case DAC960_V1_Read_Old:
+         Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Read;
+         DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+         break;
+       case DAC960_V1_Write_Old:
+         Command->V1.CommandMailbox.Common.CommandOpcode = DAC960_V1_Write;
+         DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+         break;
+       case DAC960_V1_ReadWithScatterGather_Old:
+         Command->V1.CommandMailbox.Common.CommandOpcode =
+           DAC960_V1_ReadWithScatterGather;
+         DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+         break;
+       case DAC960_V1_WriteWithScatterGather_Old:
+         Command->V1.CommandMailbox.Common.CommandOpcode =
+           DAC960_V1_WriteWithScatterGather;
+         DAC960_P_To_PD_TranslateReadWriteCommand(CommandMailbox);
+         break;
+       default:
+         break;
+       }
+      DAC960_V1_ProcessCompletedCommand(Command);
+    }
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
 /*
   DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
   Firmware Controllers.
@@ -4881,8 +5279,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
                Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
              if (LogicalDeviceInfo == NULL) continue;
              if (!LogicalDeviceInfo->LogicalDeviceControl
-                                    .LogicalDeviceInitialized &&
-                 Controller->LogicalDriveUsageCount[LogicalDriveNumber] > 0)
+                                    .LogicalDeviceInitialized)
                {
                  ForceMonitoringCommand = true;
                  break;
@@ -4970,6 +5367,7 @@ static int DAC960_Open(Inode_T *Inode, File_T *File)
   if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
     {
       Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
+      DAC960_ComputeGenericDiskInfo(&Controller->GenericDiskInfo);
       DAC960_RegisterDisk(Controller, LogicalDriveNumber);
     }
   if (Controller->GenericDiskInfo.sizes[MINOR(Inode->i_rdev)] == 0)
@@ -5049,7 +5447,7 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
            Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
          if (LogicalDeviceInfo == NULL)
            return -EINVAL;
-         switch(LogicalDeviceInfo->DriveGeometry)
+         switch (LogicalDeviceInfo->DriveGeometry)
            {
            case DAC960_V2_Geometry_128_32:
              Geometry.heads = 128;
@@ -5065,7 +5463,7 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
              return -EINVAL;
            }
          Geometry.cylinders =
-           LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
+           LogicalDeviceInfo->ConfigurableDeviceSize
            / (Geometry.heads * Geometry.sectors);
        }
       Geometry.start =
@@ -5074,19 +5472,22 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
                           sizeof(DiskGeometry_T)) ? -EFAULT : 0);
     case BLKGETSIZE:
       /* Get Device Size. */
+      if ((unsigned long *) Argument == NULL) return -EINVAL;
       return put_user(Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
                                                 .nr_sects,
-                     (long *) Argument);
+                     (unsigned long *) Argument);
     case BLKGETSIZE64:
-      return put_user((u64)Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].nr_sects << 9,
+      if ((u64 *) Argument == NULL) return -EINVAL;
+      return put_user((u64) Controller->GenericDiskInfo
+                                      .part[MINOR(Inode->i_rdev)]
+                                      .nr_sects << 9,
                      (u64 *) Argument);
     case BLKRAGET:
     case BLKRASET:
     case BLKFLSBUF:
     case BLKBSZGET:
     case BLKBSZSET:
-      return blk_ioctl (Inode->i_rdev, Request, Argument);
-
+      return blk_ioctl(Inode->i_rdev, Request, Argument);
     case BLKRRPART:
       /* Re-Read Partition Table. */
       if (!capable(CAP_SYS_ADMIN)) return -EACCES;
@@ -5120,20 +5521,7 @@ static int DAC960_IOCTL(Inode_T *Inode, File_T *File,
          */
          set_blocksize(Device, BLOCK_SIZE);
        }
-      if (Controller->FirmwareType == DAC960_V1_Controller)
-       grok_partitions(&Controller->GenericDiskInfo,
-                       LogicalDriveNumber,
-                       DAC960_MaxPartitions,
-                       Controller->V1.LogicalDriveInformation
-                                      [LogicalDriveNumber]
-                                      .LogicalDriveSize);
-      else
-       grok_partitions(
-         &Controller->GenericDiskInfo,
-         LogicalDriveNumber,
-         DAC960_MaxPartitions,
-         Controller->V2.LogicalDeviceInformation[LogicalDriveNumber]
-                        ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+      DAC960_RegisterDisk(Controller, LogicalDriveNumber);
       return 0;
     }
   return -EINVAL;
@@ -6365,6 +6753,43 @@ static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
                           == DAC960_V2_NormalCompletion
                           ? "Cancelled" : "Not Cancelled"));
     }
+  else if (strcmp(UserCommand, "perform-discovery") == 0)
+    {
+      CommandMailbox->Common.IOCTL_Opcode = DAC960_V2_StartDiscovery;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Discovery %s\n", Controller,
+                         (Command->V2.CommandStatus
+                          == DAC960_V2_NormalCompletion
+                          ? "Initiated" : "Not Initiated"));
+      if (Command->V2.CommandStatus == DAC960_V2_NormalCompletion)
+       {
+         CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+         CommandMailbox->ControllerInfo.CommandControlBits
+                                       .DataTransferControllerToHost = true;
+         CommandMailbox->ControllerInfo.CommandControlBits
+                                       .NoAutoRequestSense = true;
+         CommandMailbox->ControllerInfo.DataTransferSize =
+           sizeof(DAC960_V2_ControllerInfo_T);
+         CommandMailbox->ControllerInfo.ControllerNumber = 0;
+         CommandMailbox->ControllerInfo.IOCTL_Opcode =
+           DAC960_V2_GetControllerInfo;
+         CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+                                       .ScatterGatherSegments[0]
+                                       .SegmentDataPointer =
+           Virtual_to_Bus64(&Controller->V2.NewControllerInformation);
+         CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+                                       .ScatterGatherSegments[0]
+                                       .SegmentByteCount =
+           CommandMailbox->ControllerInfo.DataTransferSize;
+         DAC960_ExecuteCommand(Command);
+         while (Controller->V2.NewControllerInformation.PhysicalScanActive)
+           {
+             DAC960_ExecuteCommand(Command);
+             sleep_on_timeout(&Controller->CommandWaitQueue, HZ);
+           }
+         DAC960_UserCritical("Discovery Completed\n", Controller);
+       }
+    }
   else if (strcmp(UserCommand, "suppress-enclosure-messages") == 0)
     Controller->SuppressEnclosureMessages = true;
   else DAC960_UserCritical("Illegal User Command: '%s'\n",
@@ -6587,24 +7012,5 @@ static void DAC960_DestroyProcEntries(void)
 }
 
 
-/*
-  Include Module support if requested.
-*/
-
-#ifdef MODULE
-
-
-int init_module(void)
-{
-  DAC960_Initialize();
-  return (DAC960_ActiveControllerCount > 0 ? 0 : -1);
-}
-
-
-void cleanup_module(void)
-{
-  DAC960_Finalize(&DAC960_NotifierBlock, SYS_RESTART, NULL);
-}
-
-
-#endif
+module_init(DAC960_Initialize);
+module_exit(DAC960_Finalize);
index fa1361541e688008882c71bddbe8a7bd02a2cf73..98a937f66f9950f908db30416b5aa8ad90a892ed 100644 (file)
@@ -224,9 +224,9 @@ typedef enum
   DAC960_V1_ReadExtendedWithScatterGather =    0xB3,
   DAC960_V1_WriteExtendedWithScatterGather =   0xB4,
   DAC960_V1_Read =                             0x36,
-  DAC960_V1_ReadWithOldScatterGather =         0xB6,
+  DAC960_V1_ReadWithScatterGather =            0xB6,
   DAC960_V1_Write =                            0x37,
-  DAC960_V1_WriteWithOldScatterGather =                0xB7,
+  DAC960_V1_WriteWithScatterGather =           0xB7,
   DAC960_V1_DCDB =                             0x04,
   DAC960_V1_DCDBWithScatterGather =            0x84,
   DAC960_V1_Flush =                            0x0A,
@@ -280,7 +280,14 @@ typedef enum
   DAC960_V1_RunDiagnostic =                    0x32,
   /* Subsystem Service Commands */
   DAC960_V1_GetSubsystemData =                 0x70,
-  DAC960_V1_SetSubsystemParameters =           0x71
+  DAC960_V1_SetSubsystemParameters =           0x71,
+  /* Version 2.xx Firmware Commands */
+  DAC960_V1_Enquiry_Old =                      0x05,
+  DAC960_V1_GetDeviceState_Old =               0x14,
+  DAC960_V1_Read_Old =                         0x02,
+  DAC960_V1_Write_Old =                                0x03,
+  DAC960_V1_ReadWithScatterGather_Old =                0x82,
+  DAC960_V1_WriteWithScatterGather_Old =       0x83
 }
 __attribute__ ((packed))
 DAC960_V1_CommandOpcode_T;
@@ -327,6 +334,9 @@ typedef unsigned char DAC960_V1_CommandIdentifier_T;
 #define DAC960_V1_RebuildFailed_NewDriveFailed 0x0004  /* Consistency */
 #define DAC960_V1_RebuildSuccessful            0x0100  /* Consistency */
 #define DAC960_V1_RebuildSuccessfullyTerminated        0x0107  /* Consistency */
+#define DAC960_V1_BackgroundInitSuccessful     0x0100  /* Consistency */
+#define DAC960_V1_BackgroundInitAborted                0x0005  /* Consistency */
+#define DAC960_V1_NoBackgroundInitInProgress   0x0105  /* Consistency */
 #define DAC960_V1_AddCapacityInProgress                0x0004  /* Consistency */
 #define DAC960_V1_AddCapacityFailedOrSuspended 0x00F4  /* Consistency */
 #define DAC960_V1_Config2ChecksumError         0x0002  /* Configuration */
@@ -634,6 +644,8 @@ DAC960_V1_PhysicalDeviceState_T;
 
 /*
   Define the DAC960 V1 Firmware Get Device State Command reply structure.
+  The structure is padded by 2 bytes for compatibility with Version 2.xx
+  Firmware.
 */
 
 typedef struct DAC960_V1_DeviceState
@@ -658,6 +670,7 @@ typedef struct DAC960_V1_DeviceState
   unsigned char SynchronousOffset:5;                   /* Byte 5 Bits 0-4 */
   unsigned char :3;                                    /* Byte 5 Bits 5-7 */
   unsigned int DiskSize __attribute__ ((packed));      /* Bytes 6-9 */
+  unsigned short :16;                                  /* Bytes 10-11 */
 }
 DAC960_V1_DeviceState_T;
 
@@ -675,6 +688,30 @@ typedef struct DAC960_V1_RebuildProgress
 DAC960_V1_RebuildProgress_T;
 
 
+/*
+  Define the DAC960 V1 Firmware Background Initialization Status Command
+  reply structure.
+*/
+
+typedef struct DAC960_V1_BackgroundInitializationStatus
+{
+  unsigned int LogicalDriveSize;                       /* Bytes 0-3 */
+  unsigned int BlocksCompleted;                                /* Bytes 4-7 */
+  unsigned char Reserved1[12];                         /* Bytes 8-19 */
+  unsigned int LogicalDriveNumber;                     /* Bytes 20-23 */
+  unsigned char RAIDLevel;                             /* Byte 24 */
+  enum {
+    DAC960_V1_BackgroundInitializationInvalid =            0x00,
+    DAC960_V1_BackgroundInitializationStarted =            0x02,
+    DAC960_V1_BackgroundInitializationInProgress =  0x04,
+    DAC960_V1_BackgroundInitializationSuspended =   0x05,
+    DAC960_V1_BackgroundInitializationCancelled =   0x06
+  } __attribute__ ((packed)) Status;                   /* Byte 25 */
+  unsigned char Reserved2[6];                          /* Bytes 26-31 */
+}
+DAC960_V1_BackgroundInitializationStatus_T;
+
+
 /*
   Define the DAC960 V1 Firmware Error Table Entry structure.
 */
@@ -850,6 +887,14 @@ typedef union DAC960_V1_CommandMailbox
     DAC960_BusAddress32_T BusAddress;                  /* Bytes 8-11 */
     unsigned char Dummy2[4];                           /* Bytes 12-15 */
   } __attribute__ ((packed)) Type3;
+  struct {
+    DAC960_V1_CommandOpcode_T CommandOpcode;           /* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;   /* Byte 1 */
+    unsigned char CommandOpcode2;                      /* Byte 2 */
+    unsigned char Dummy1[5];                           /* Bytes 3-7 */
+    DAC960_BusAddress32_T BusAddress;                  /* Bytes 8-11 */
+    unsigned char Dummy2[4];                           /* Bytes 12-15 */
+  } __attribute__ ((packed)) Type3B;
   struct {
     DAC960_V1_CommandOpcode_T CommandOpcode;           /* Byte 0 */
     DAC960_V1_CommandIdentifier_T CommandIdentifier;   /* Byte 1 */
@@ -956,6 +1001,7 @@ typedef enum
   DAC960_V2_GetPhysicalDeviceInfoValid =       0x05,
   DAC960_V2_GetHealthStatus =                  0x11,
   DAC960_V2_GetEvent =                         0x15,
+  DAC960_V2_StartDiscovery =                   0x81,
   DAC960_V2_SetDeviceState =                   0x82,
   DAC960_V2_RebuildDeviceStart =               0x88,
   DAC960_V2_RebuildDeviceStop =                        0x89,
@@ -982,7 +1028,10 @@ typedef unsigned short DAC960_V2_CommandIdentifier_T;
 
 #define DAC960_V2_NormalCompletion             0x00
 #define DAC960_V2_AbormalCompletion            0x02
+#define DAC960_V2_DeviceBusy                   0x08
 #define DAC960_V2_DeviceNonresponsive          0x0E
+#define DAC960_V2_DeviceNonresponsive2         0x0F
+#define DAC960_V2_DeviceRevervationConflict    0x18
 
 typedef unsigned char DAC960_V2_CommandStatus_T;
 
@@ -1056,7 +1105,8 @@ typedef struct DAC960_V2_ControllerInfo
     DAC960_V2_EXR2000P =                       0x1C,
     DAC960_V2_EXR3000P =                       0x1D,
     DAC960_V2_AcceleRAID352 =                  0x1E,
-    DAC960_V2_AcceleRAID351 =                  0x1F,
+    DAC960_V2_AcceleRAID170 =                  0x1F,
+    DAC960_V2_AcceleRAID160 =                  0x20,
     DAC960_V2_DAC960S =                                0x60,
     DAC960_V2_DAC960SU =                       0x61,
     DAC960_V2_DAC960SX =                       0x62,
@@ -1073,7 +1123,9 @@ typedef struct DAC960_V2_ControllerInfo
   unsigned char :8;                                    /* Byte 3 */
   unsigned short BusInterfaceSpeedMHz;                 /* Bytes 4-5 */
   unsigned char BusWidthBits;                          /* Byte 6 */
-  unsigned char Reserved1[9];                          /* Bytes 7-15 */
+  unsigned char FlashCodeTypeOrProductID;              /* Byte 7 */
+  unsigned char NumberOfHostPortsPresent;              /* Byte 8 */
+  unsigned char Reserved1[7];                          /* Bytes 9-15 */
   unsigned char BusInterfaceName[16];                  /* Bytes 16-31 */
   unsigned char ControllerName[16];                    /* Bytes 32-47 */
   unsigned char Reserved2[16];                         /* Bytes 48-63 */
@@ -1102,17 +1154,17 @@ typedef struct DAC960_V2_ControllerInfo
   unsigned char HardwareManufacturingMonth;            /* Byte 85 */
   unsigned char HardwareManufacturingYearHigh2Digits;  /* Byte 86 */
   unsigned char HardwareManufacturingYearLow2Digits;   /* Byte 87 */
-  unsigned char MaximumNumberOfPDDperXLDD;             /* Byte 88 */
-  unsigned char MaximumNumberOfILDDperXLDD;            /* Byte 89 */
+  unsigned char MaximumNumberOfPDDperXLD             /* Byte 88 */
+  unsigned char MaximumNumberOfILDperXLD;              /* Byte 89 */
   unsigned short NonvolatileMemorySizeKB;              /* Bytes 90-91 */
-  unsigned char MaximumNumberOfXLDD;                   /* Byte 92 */
+  unsigned char MaximumNumberOfXLD                   /* Byte 92 */
   unsigned int :24;                                    /* Bytes 93-95 */
   /* Unique Information per Controller */
   unsigned char ControllerSerialNumber[16];            /* Bytes 96-111 */
   unsigned char Reserved3[16];                         /* Bytes 112-127 */
   /* Vendor Information */
   unsigned int :24;                                    /* Bytes 128-130 */
-  unsigned char OEM_Information;                       /* Byte 131 */
+  unsigned char OEM_Code;                              /* Byte 131 */
   unsigned char VendorName[16];                                /* Bytes 132-147 */
   /* Other Physical/Controller/Operation Information */
   boolean BBU_Present:1;                               /* Byte 148 Bit 0 */
@@ -1193,12 +1245,14 @@ typedef struct DAC960_V2_ControllerInfo
   unsigned short PhysicalDeviceHostCommandAbortsDone;  /* Bytes 370-371 */
   unsigned short PhysicalDevicePredictedFailuresDetected; /* Bytes 372-373 */
   unsigned short PhysicalDeviceHostCommandsFailed;     /* Bytes 374-375 */
-  unsigned char Reserved9[8];                          /* Bytes 376-383 */
+  unsigned short PhysicalDeviceHardErrors;             /* Bytes 376-377 */
+  unsigned char Reserved9[6];                          /* Bytes 378-383 */
   /* Error Counters on Logical Devices */
   unsigned short LogicalDeviceSoftErrors;              /* Bytes 384-385 */
   unsigned short LogicalDeviceCommandsFailed;          /* Bytes 386-387 */
   unsigned short LogicalDeviceHostCommandAbortsDone;   /* Bytes 388-389 */
   unsigned short :16;                                  /* Bytes 390-391 */
+  /* Error Counters on Controller */
   unsigned short ControllerMemoryErrors;               /* Bytes 392-393 */
   unsigned short ControllerHostCommandAbortsDone;      /* Bytes 394-395 */
   unsigned int :32;                                    /* Bytes 396-399 */
@@ -1210,8 +1264,7 @@ typedef struct DAC960_V2_ControllerInfo
   unsigned short RebuildsActive;                       /* Bytes 408-409 */
   unsigned short OnlineExpansionsActive;               /* Bytes 410-411 */
   unsigned short PatrolActivitiesActive;               /* Bytes 412-413 */
-  unsigned char LongOperationStatus;                   /* Byte 414 */
-  unsigned char :8;                                    /* Byte 415 */
+  unsigned short :16;                                  /* Bytes 414-415 */
   /* Flash ROM Information */
   unsigned char FlashType;                             /* Byte 416 */
   unsigned char :8;                                    /* Byte 417 */
@@ -1234,8 +1287,7 @@ typedef struct DAC960_V2_ControllerInfo
   unsigned short NumberOfConfigurationGroups;          /* Bytes 474-475 */
   boolean InstallationAbortStatus:1;                   /* Byte 476 Bit 0 */
   boolean MaintenanceModeStatus:1;                     /* Byte 476 Bit 1 */
-  unsigned int :6;                                     /* Byte 476 Bits 2-7 */
-  unsigned int :24;                                    /* Bytes 477-479 */
+  unsigned int :24;                                    /* Bytes 476-479 */
   unsigned char Reserved10[32];                                /* Bytes 480-511 */
   unsigned char Reserved11[512];                       /* Bytes 512-1023 */
 }
@@ -1311,7 +1363,7 @@ typedef struct DAC960_V2_LogicalDeviceInfo
     DAC960_V2_Geometry_Reserved1 =             0x2,
     DAC960_V2_Geometry_Reserved2 =             0x3
   } __attribute__ ((packed)) DriveGeometry:2;          /* Byte 14 Bits 5-6 */
-  unsigned char :1;                                    /* Byte 14 Bit 7 */
+  boolean SuperReadAheadEnabled:1;                     /* Byte 14 Bit 7 */
   unsigned char :8;                                    /* Byte 15 */
   /* Error Counters */
   unsigned short SoftErrors;                           /* Bytes 16-17 */
@@ -1323,8 +1375,8 @@ typedef struct DAC960_V2_LogicalDeviceInfo
   /* Device Size Information */
   unsigned short :16;                                  /* Bytes 32-33 */
   unsigned short DeviceBlockSizeInBytes;               /* Bytes 34-35 */
-  unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;  /* Bytes 36-39 */
-  unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 40-43 */
+  unsigned int OriginalDeviceSize;                     /* Bytes 36-39 */
+  unsigned int ConfigurableDeviceSize;                 /* Bytes 40-43 */
   unsigned int :32;                                    /* Bytes 44-47 */
   unsigned char LogicalDeviceName[32];                 /* Bytes 48-79 */
   unsigned char SCSI_InquiryData[36];                  /* Bytes 80-115 */
@@ -1350,8 +1402,12 @@ typedef enum
 {
     DAC960_V2_Device_Unconfigured =            0x00,
     DAC960_V2_Device_Online =                  0x01,
-    DAC960_V2_Device_WriteOnly =               0x03,
+    DAC960_V2_Device_Rebuild =                 0x03,
+    DAC960_V2_Device_Missing =                 0x04,
+    DAC960_V2_Device_Critical =                        0x05,
     DAC960_V2_Device_Dead =                    0x08,
+    DAC960_V2_Device_SuspectedDead =           0x0C,
+    DAC960_V2_Device_CommandedOffline =                0x10,
     DAC960_V2_Device_Standby =                 0x21,
     DAC960_V2_Device_InvalidState =            0xFF
 }
@@ -1371,7 +1427,7 @@ typedef struct DAC960_V2_PhysicalDeviceInfo
   unsigned char LogicalUnit;                           /* Byte 3 */
   /* Configuration Status Bits */
   boolean PhysicalDeviceFaultTolerant:1;               /* Byte 4 Bit 0 */
-  boolean :1;                                          /* Byte 4 Bit 1 */
+  boolean PhysicalDeviceConnected:1;                   /* Byte 4 Bit 1 */
   boolean PhysicalDeviceLocalToController:1;           /* Byte 4 Bit 2 */
   unsigned char :5;                                    /* Byte 4 Bits 3-7 */
   /* Multiple Host/Controller Status Bits */
@@ -1407,15 +1463,15 @@ typedef struct DAC960_V2_PhysicalDeviceInfo
   unsigned int :32;                                    /* Bytes 44-47 */
   unsigned short :16;                                  /* Bytes 48-49 */
   unsigned short DeviceBlockSizeInBytes;               /* Bytes 50-51 */
-  unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;  /* Bytes 52-55 */
-  unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 56-59 */
+  unsigned int OriginalDeviceSize;                     /* Bytes 52-55 */
+  unsigned int ConfigurableDeviceSize;                 /* Bytes 56-59 */
   unsigned int :32;                                    /* Bytes 60-63 */
   unsigned char PhysicalDeviceName[16];                        /* Bytes 64-79 */
   unsigned char Reserved1[16];                         /* Bytes 80-95 */
   unsigned char Reserved2[32];                         /* Bytes 96-127 */
   unsigned char SCSI_InquiryData[36];                  /* Bytes 128-163 */
-  unsigned char Reserved3[12];                         /* Bytes 164-175 */
-  unsigned char Reserved4[16];                         /* Bytes 176-191 */
+  unsigned char Reserved3[20];                         /* Bytes 164-183 */
+  unsigned char Reserved4[8];                          /* Bytes 184-191 */
   DAC960_ByteCount64_T LastReadBlockNumber;            /* Bytes 192-199 */
   DAC960_ByteCount64_T LastWrittenBlockNumber;         /* Bytes 200-207 */
   DAC960_ByteCount64_T ConsistencyCheckBlockNumber;    /* Bytes 208-215 */
@@ -1549,7 +1605,8 @@ typedef enum
   DAC960_V2_RAID_Channel =                     0x03,
   DAC960_V2_Physical_Controller =              0x04,
   DAC960_V2_RAID_Controller =                  0x05,
-  DAC960_V2_Configuration_Group =              0x10
+  DAC960_V2_Configuration_Group =              0x10,
+  DAC960_V2_Enclosure =                                0x11
 }
 __attribute__ ((packed))
 DAC960_V2_OperationDevice_T;
@@ -1630,8 +1687,7 @@ typedef union DAC960_V2_CommandMailbox
     DAC960_V2_CommandIdentifier_T CommandIdentifier;   /* Bytes 0-1 */
     DAC960_V2_CommandOpcode_T CommandOpcode;           /* Byte 2 */
     DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */
-    DAC960_ByteCount32_T DataTransferSize:24;          /* Bytes 4-6 */
-    unsigned char DataTransferPageNumber;              /* Byte 7 */
+    DAC960_ByteCount32_T DataTransferSize;             /* Bytes 4-7 */
     DAC960_BusAddress64_T RequestSenseBusAddress;      /* Bytes 8-15 */
     DAC960_V2_PhysicalDevice_T PhysicalDevice;         /* Bytes 16-18 */
     DAC960_V2_CommandTimeout_T CommandTimeout;         /* Byte 19 */
@@ -1645,8 +1701,7 @@ typedef union DAC960_V2_CommandMailbox
     DAC960_V2_CommandIdentifier_T CommandIdentifier;   /* Bytes 0-1 */
     DAC960_V2_CommandOpcode_T CommandOpcode;           /* Byte 2 */
     DAC960_V2_CommandControlBits_T CommandControlBits; /* Byte 3 */
-    DAC960_ByteCount32_T DataTransferSize:24;          /* Bytes 4-6 */
-    unsigned char DataTransferPageNumber;              /* Byte 7 */
+    DAC960_ByteCount32_T DataTransferSize;             /* Bytes 4-7 */
     DAC960_BusAddress64_T RequestSenseBusAddress;      /* Bytes 8-15 */
     DAC960_V2_PhysicalDevice_T PhysicalDevice;         /* Bytes 16-18 */
     DAC960_V2_CommandTimeout_T CommandTimeout;         /* Byte 19 */
@@ -1795,7 +1850,6 @@ typedef union DAC960_V2_CommandMailbox
       DataTransferMemoryAddress;                       /* Bytes 32-63 */
   } DeviceOperation;
 }
-__attribute__ ((packed))
 DAC960_V2_CommandMailbox_T;
 
 
@@ -2074,7 +2128,8 @@ typedef enum
   DAC960_LP_Controller =                       2,      /* AcceleRAID 352 */
   DAC960_LA_Controller =                       3,      /* DAC1164P */
   DAC960_PG_Controller =                       4,      /* DAC960PTL/PJ/PG */
-  DAC960_PD_Controller =                       5       /* DAC960PU/PD/PL */
+  DAC960_PD_Controller =                       5,      /* DAC960PU/PD/PL/P */
+  DAC960_P_Controller =                                6       /* DAC960PU/PD/PL/P */
 }
 DAC960_HardwareType_T;
 
@@ -2336,6 +2391,7 @@ typedef struct DAC960_Controller
       unsigned short DeviceStateChannel;
       unsigned short DeviceStateTargetID;
       boolean DualModeMemoryMailboxInterface;
+      boolean BackgroundInitializationStatusSupported;
       boolean SAFTE_EnclosureManagementEnabled;
       boolean NeedLogicalDriveInformation;
       boolean NeedErrorTableInformation;
@@ -2344,6 +2400,7 @@ typedef struct DAC960_Controller
       boolean NeedDeviceSerialNumberInformation;
       boolean NeedRebuildProgress;
       boolean NeedConsistencyCheckProgress;
+      boolean NeedBackgroundInitializationStatus;
       boolean StartDeviceStateScan;
       boolean RebuildProgressFirst;
       boolean RebuildFlagPending;
@@ -2367,6 +2424,10 @@ typedef struct DAC960_Controller
       DAC960_V1_CommandStatus_T PendingRebuildStatus;
       DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation;
       DAC960_V1_LogicalDriveInformationArray_T NewLogicalDriveInformation;
+      DAC960_V1_BackgroundInitializationStatus_T
+        BackgroundInitializationStatus;
+      DAC960_V1_BackgroundInitializationStatus_T
+        LastBackgroundInitializationStatus;
       DAC960_V1_DeviceState_T
        DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
       DAC960_V1_DeviceState_T NewDeviceState;
@@ -4143,13 +4204,46 @@ DAC960_PD_ReadErrorStatus(void *ControllerBaseAddress,
   return true;
 }
 
+static inline void DAC960_P_To_PD_TranslateEnquiry(void *Enquiry)
+{
+  memcpy(Enquiry + 132, Enquiry + 36, 64);
+  memset(Enquiry + 36, 0, 96);
+}
+
+static inline void DAC960_P_To_PD_TranslateDeviceState(void *DeviceState)
+{
+  memcpy(DeviceState + 2, DeviceState + 3, 1);
+  memcpy(DeviceState + 4, DeviceState + 5, 2);
+  memcpy(DeviceState + 6, DeviceState + 8, 4);
+}
+
+static inline
+void DAC960_PD_To_P_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T
+                                             *CommandMailbox)
+{
+  int LogicalDriveNumber = CommandMailbox->Type5.LD.LogicalDriveNumber;
+  CommandMailbox->Bytes[3] &= 0x7;
+  CommandMailbox->Bytes[3] |= CommandMailbox->Bytes[7] << 6;
+  CommandMailbox->Bytes[7] = LogicalDriveNumber;
+}
+
+static inline
+void DAC960_P_To_PD_TranslateReadWriteCommand(DAC960_V1_CommandMailbox_T
+                                             *CommandMailbox)
+{
+  int LogicalDriveNumber = CommandMailbox->Bytes[7];
+  CommandMailbox->Bytes[7] = CommandMailbox->Bytes[3] >> 6;
+  CommandMailbox->Bytes[3] &= 0x7;
+  CommandMailbox->Bytes[3] |= LogicalDriveNumber << 3;
+}
+
 
 /*
   Define prototypes for the forward referenced DAC960 Driver Internal Functions.
 */
 
 static void DAC960_FinalizeController(DAC960_Controller_T *);
-static int DAC960_Finalize(NotifierBlock_T *, unsigned long, void *);
+static int DAC960_Notifier(NotifierBlock_T *, unsigned long, void *);
 static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
 static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *);
 static void DAC960_RequestFunction(RequestQueue_T *);
@@ -4158,6 +4252,7 @@ static void DAC960_LP_InterruptHandler(int, void *, Registers_T *);
 static void DAC960_LA_InterruptHandler(int, void *, Registers_T *);
 static void DAC960_PG_InterruptHandler(int, void *, Registers_T *);
 static void DAC960_PD_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_P_InterruptHandler(int, void *, Registers_T *);
 static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *);
 static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *);
 static void DAC960_MonitoringTimerFunction(unsigned long);
index 36de551e6beb50bdc33851bf78fa7cee7cdf1b2b..12e19a164e3228d66734557b275543fc2d69f6e1 100644 (file)
@@ -161,9 +161,6 @@ out:
 
 
 extern int blk_dev_init(void);
-#ifdef CONFIG_BLK_DEV_DAC960
-extern void DAC960_Initialize(void);
-#endif
 #ifdef CONFIG_FUSION_BOOT
 extern int fusion_init(void);
 #endif
@@ -182,9 +179,6 @@ int __init device_init(void)
 #ifdef CONFIG_I2O
        i2o_init();
 #endif
-#ifdef CONFIG_BLK_DEV_DAC960
-       DAC960_Initialize();
-#endif
 #ifdef CONFIG_FUSION_BOOT
        fusion_init();
 #endif
index 4b9a6febe48dc086cf7bdbec94c496c71635dfc6..a861f2adc8bfb38299fd54440fb9f1aaef5da2db 100644 (file)
@@ -77,7 +77,7 @@
 
 static int max_loop = 8;
 static struct loop_device *loop_dev;
-static unsigned long *loop_sizes;
+static int *loop_sizes;
 static int *loop_blksizes;
 static devfs_handle_t devfs_handle;      /*  For the directory */
 
@@ -865,7 +865,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
                        err = -ENXIO;
                        break;
                }
-               err = put_user(loop_sizes[lo->lo_number] << 1, (unsigned long *) arg);
+               err = put_user((unsigned long)loop_sizes[lo->lo_number] << 1, (unsigned long *) arg);
                break;
        case BLKGETSIZE64:
                if (lo->lo_state != Lo_bound) {
@@ -1007,7 +1007,7 @@ int __init loop_init(void)
        if (!loop_dev)
                return -ENOMEM;
 
-       loop_sizes = kmalloc(max_loop * sizeof(unsigned long), GFP_KERNEL);
+       loop_sizes = kmalloc(max_loop * sizeof(int), GFP_KERNEL);
        if (!loop_sizes)
                goto out_sizes;
 
@@ -1027,7 +1027,7 @@ int __init loop_init(void)
                spin_lock_init(&lo->lo_lock);
        }
 
-       memset(loop_sizes, 0, max_loop * sizeof(unsigned long));
+       memset(loop_sizes, 0, max_loop * sizeof(int));
        memset(loop_blksizes, 0, max_loop * sizeof(int));
        blk_size[MAJOR_NR] = loop_sizes;
        blksize_size[MAJOR_NR] = loop_blksizes;
index ef30f94ad4f3f235d047b6ef7ff0c2d3b06fd451..fe68fc97eb640ab4a33c46866e3700e150488e5a 100644 (file)
@@ -175,7 +175,7 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
        page = pte_page(*pte);
        get_page(page);
 
-       DRM_DEBUG("0x%08lx => 0x%08x\n", address, page_to_bus(page));
+       DRM_DEBUG("shm_nopage 0x%lx\n", address);
 #if LINUX_VERSION_CODE < 0x020317
        return page_address(page);
 #else
@@ -299,8 +299,7 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
 
        get_page(page);
 
-       DRM_DEBUG("0x%08lx (page %lu) => 0x%08x\n", address, page_nr, 
-                 page_to_bus(page));
+       DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr); 
 #if LINUX_VERSION_CODE < 0x020317
        return page_address(page);
 #else
index 52fa23e91cb9d4ff2efc3595d8e84454f4b05643..b6cdcb6bf0a4427d84a7ed78749ea1c791ce8a31 100644 (file)
@@ -4,11 +4,11 @@
 
 O_TARGET := ieee1394drv.o
 
-export-objs := ieee1394_syms.o ohci1394.o
+export-objs := ieee1394_core.o ohci1394.o
 
 list-multi := ieee1394.o
 ieee1394-objs := ieee1394_core.o ieee1394_transactions.o hosts.o \
-                highlevel.o csr.o nodemgr.o ieee1394_syms.o
+                highlevel.o csr.o nodemgr.o
 
 obj-$(CONFIG_IEEE1394) += ieee1394.o
 obj-$(CONFIG_IEEE1394_PCILYNX) += pcilynx.o
index c9f42373e3274b6338d3c859e0a4c9250381a1ff..485b1657bda168f559f46839a2bb539e9cd9eafd 100644 (file)
 
 #define SPEED_100                0x0
 #define SPEED_200                0x1
-#define SPEED_400                0x2 
+#define SPEED_400                0x2
+
+/* Maps speed values above to a string representation */
+extern const char *hpsb_speedto_str[];
 
 #define SELFID_PWRCL_NO_POWER    0x0
 #define SELFID_PWRCL_PROVIDE_15W 0x1
index b19bd5d439091cccdb76a6a1251920d4c7e046ed..95ec4af660fe1d1635df782bcedce1c9fbd9e151 100644 (file)
@@ -30,6 +30,7 @@
 #include "ieee1394_transactions.h"
 #include "csr.h"
 #include "nodemgr.h"
+#include "ieee1394_hotplug.h"
 
 /*
  * Disable the nodemgr detection and config rom reading functionality.
@@ -38,8 +39,13 @@ MODULE_PARM(disable_nodemgr, "i");
 MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
 static int disable_nodemgr = 0;
 
+/* We are GPL, so treat us special */
+MODULE_LICENSE("GPL");
+
 static kmem_cache_t *hpsb_packet_cache;
 
+/* Some globals used */
+const char *hpsb_speedto_str[] = { "S100", "S200", "S400" };
 
 static void dump_packet(const char *text, quadlet_t *data, int size)
 {
@@ -805,3 +811,68 @@ static void __exit ieee1394_cleanup(void)
 
 module_init(ieee1394_init);
 module_exit(ieee1394_cleanup);
+
+/* Exported symbols */
+EXPORT_SYMBOL(hpsb_register_lowlevel);
+EXPORT_SYMBOL(hpsb_unregister_lowlevel);
+EXPORT_SYMBOL(hpsb_get_host);
+EXPORT_SYMBOL(hpsb_inc_host_usage);
+EXPORT_SYMBOL(hpsb_dec_host_usage);
+EXPORT_SYMBOL(hpsb_speedto_str);
+
+EXPORT_SYMBOL(alloc_hpsb_packet);
+EXPORT_SYMBOL(free_hpsb_packet);
+EXPORT_SYMBOL(hpsb_send_packet);
+EXPORT_SYMBOL(hpsb_reset_bus);
+EXPORT_SYMBOL(hpsb_bus_reset);
+EXPORT_SYMBOL(hpsb_selfid_received);
+EXPORT_SYMBOL(hpsb_selfid_complete);
+EXPORT_SYMBOL(hpsb_packet_sent);
+EXPORT_SYMBOL(hpsb_packet_received);
+
+EXPORT_SYMBOL(get_tlabel);
+EXPORT_SYMBOL(free_tlabel);
+EXPORT_SYMBOL(fill_async_readquad);
+EXPORT_SYMBOL(fill_async_readquad_resp);
+EXPORT_SYMBOL(fill_async_readblock);
+EXPORT_SYMBOL(fill_async_readblock_resp);
+EXPORT_SYMBOL(fill_async_writequad);
+EXPORT_SYMBOL(fill_async_writeblock);
+EXPORT_SYMBOL(fill_async_write_resp);
+EXPORT_SYMBOL(fill_async_lock);
+EXPORT_SYMBOL(fill_async_lock_resp);
+EXPORT_SYMBOL(fill_iso_packet);
+EXPORT_SYMBOL(fill_phy_packet);
+EXPORT_SYMBOL(hpsb_make_readqpacket);
+EXPORT_SYMBOL(hpsb_make_readbpacket);
+EXPORT_SYMBOL(hpsb_make_writeqpacket);
+EXPORT_SYMBOL(hpsb_make_writebpacket);
+EXPORT_SYMBOL(hpsb_make_lockpacket);
+EXPORT_SYMBOL(hpsb_make_phypacket);
+EXPORT_SYMBOL(hpsb_packet_success);
+EXPORT_SYMBOL(hpsb_make_packet);
+EXPORT_SYMBOL(hpsb_read);
+EXPORT_SYMBOL(hpsb_write);
+EXPORT_SYMBOL(hpsb_lock);
+
+EXPORT_SYMBOL(hpsb_register_highlevel);
+EXPORT_SYMBOL(hpsb_unregister_highlevel);
+EXPORT_SYMBOL(hpsb_register_addrspace);
+EXPORT_SYMBOL(hpsb_listen_channel);
+EXPORT_SYMBOL(hpsb_unlisten_channel);
+EXPORT_SYMBOL(highlevel_read);
+EXPORT_SYMBOL(highlevel_write);
+EXPORT_SYMBOL(highlevel_lock);
+EXPORT_SYMBOL(highlevel_lock64);
+EXPORT_SYMBOL(highlevel_add_host);
+EXPORT_SYMBOL(highlevel_remove_host);
+EXPORT_SYMBOL(highlevel_host_reset);
+EXPORT_SYMBOL(highlevel_add_one_host);
+
+EXPORT_SYMBOL(hpsb_guid_get_entry);
+EXPORT_SYMBOL(hpsb_nodeid_get_entry);
+EXPORT_SYMBOL(hpsb_get_host_by_ne);
+EXPORT_SYMBOL(hpsb_guid_fill_packet);
+EXPORT_SYMBOL(hpsb_register_protocol);
+EXPORT_SYMBOL(hpsb_unregister_protocol);
+EXPORT_SYMBOL(hpsb_release_unit_directory);
index 185cecacb444ae9b73a8e33e0013ff1227efa46e..cbeaf43958c58d55e33fd09250f56dfa272894d0 100644 (file)
 #define INIT_TQ_HEAD(tq) INIT_LIST_HEAD(&(tq))
 #endif
 
+/* This showed up around this time */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,12)
+
+# ifndef MODULE_LICENSE
+# define MODULE_LICENSE(x)
+# endif
+
+# ifndef min
+# define min(x,y) ({ \
+       const typeof(x) _x = (x);       \
+       const typeof(y) _y = (y);       \
+       (void) (&_x == &_y);            \
+       _x < _y ? _x : _y; })
+# endif
+
+#endif /* Linux version < 2.4.12 */
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,18)
 #include <asm/spinlock.h>
 #else
@@ -50,6 +67,10 @@ typedef u16 nodeid_t;
 #define LOCAL_BUS 0xffc0
 #define ALL_NODES 0x003f
 
+#define NODE_BUS_FMT    "%d:%d"
+#define NODE_BUS_ARGS(nodeid) \
+       (nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
+
 #define HPSB_PRINT(level, fmt, args...) printk(level "ieee1394: " fmt "\n" , ## args)
 
 #define HPSB_DEBUG(fmt, args...) HPSB_PRINT(KERN_DEBUG, fmt , ## args)
index 7b1ee818652a0e64b51239d1b757d38192c13855..d32219154426837b123a2ee49a76c3677c4f5690 100644 (file)
 #include "nodemgr.h"
 
 
-#define NODE_BUS_FMT   "%d:%d"
-#define NODE_BUS_ARGS(nodeid) \
-       (nodeid & NODE_MASK), ((nodeid & BUS_MASK) >> 6)
-
-/* Basically what we do here is start off retrieving the bus_info block.
+/* 
+ * Basically what we do here is start off retrieving the bus_info block.
  * From there will fill in some info about the node, verify it is of IEEE
  * 1394 type, and that the crc checks out ok. After that we start off with
  * the root directory, and subdirectories. To do this, we retrieve the
@@ -42,9 +39,7 @@
  * We verify CRC's along the way for each directory/block/leaf. The
  * entire node structure is generic, and simply stores the information in
  * a way that's easy to parse by the protocol interface.
- *
- * XXX: Most of this isn't done yet :)  */
-
+ */
 
 static LIST_HEAD(node_list);
 static rwlock_t node_lock = RW_LOCK_UNLOCKED;
index 594680253913c792e7ae15feb2edb3d96352dac5..888e918e51d8de924345bb7403f4a0fce22e2e3f 100644 (file)
  *       add some init code to the kernel to support this... and modules are much
  *       more flexible anyway.   ;-)
  *
+ *     - The scsi stack in recent kernels pass down the data transfer
+ *       direction as scsicmd->sc_data_direction, which we should use
+ *       instead of the sbp2scsi_direction_table.
+ *
  *
  * History:
  *
@@ -355,23 +359,23 @@ static u32 global_outstanding_dmas = 0;
 
 
 #if CONFIG_IEEE1394_SBP2_DEBUG >= 2
-#define SBP2_DEBUG(fmt, args...)       HPSB_ERR(fmt, ## args)  
-#define SBP2_INFO(fmt, args...)                HPSB_ERR(fmt, ## args)  
-#define SBP2_NOTICE(fmt, args...)      HPSB_ERR(fmt, ## args)  
-#define SBP2_WARN(fmt, args...)                HPSB_ERR(fmt, ## args)
+#define SBP2_DEBUG(fmt, args...)       HPSB_ERR("sbp2: "fmt, ## args)
+#define SBP2_INFO(fmt, args...)                HPSB_ERR("sbp2: "fmt, ## args)
+#define SBP2_NOTICE(fmt, args...)      HPSB_ERR("sbp2: "fmt, ## args)
+#define SBP2_WARN(fmt, args...)                HPSB_ERR("sbp2: "fmt, ## args)
 #elif CONFIG_IEEE1394_SBP2_DEBUG == 1
-#define SBP2_DEBUG(fmt, args...)       HPSB_DEBUG(fmt, ## args)
-#define SBP2_INFO(fmt, args...)                HPSB_INFO(fmt, ## args)
-#define SBP2_NOTICE(fmt, args...)      HPSB_NOTICE(fmt, ## args)
-#define SBP2_WARN(fmt, args...)                HPSB_WARN(fmt, ## args)
+#define SBP2_DEBUG(fmt, args...)       HPSB_DEBUG("sbp2: "fmt, ## args)
+#define SBP2_INFO(fmt, args...)                HPSB_INFO("sbp2: "fmt, ## args)
+#define SBP2_NOTICE(fmt, args...)      HPSB_NOTICE("sbp2: "fmt, ## args)
+#define SBP2_WARN(fmt, args...)                HPSB_WARN("sbp2: "fmt, ## args)
 #else 
-#define SBP2_DEBUG(fmt, args...)       
-#define SBP2_INFO(fmt, args...)        
-#define SBP2_NOTICE(fmt, args...)      
-#define SBP2_WARN(fmt, args...)        
+#define SBP2_DEBUG(fmt, args...)
+#define SBP2_INFO(fmt, args...)
+#define SBP2_NOTICE(fmt, args...)
+#define SBP2_WARN(fmt, args...)
 #endif
 
-#define SBP2_ERR(fmt, args...)         HPSB_ERR(fmt, ## args)
+#define SBP2_ERR(fmt, args...)         HPSB_ERR("sbp2: "fmt, ## args)
 
 /*
  * Spinlock debugging stuff. I'm playing it safe until the driver has been
@@ -393,6 +397,8 @@ static spinlock_t sbp2_host_info_lock = SPIN_LOCK_UNLOCKED;
 
 Scsi_Host_Template *global_scsi_tpnt = NULL;
 
+static u8 sbp2_speedto_maxrec[] = { 0x7, 0x8, 0x9 };
+
 static LIST_HEAD(sbp2_host_info_list);
 static int sbp2_host_count = 0;
 
@@ -477,7 +483,7 @@ static int sbp2util_create_request_packet_pool(struct sbp2scsi_host_info *hi)
                packet = alloc_hpsb_packet(8);
 
                if (!packet) {
-                       SBP2_ERR("sbp2: sbp2util_create_request_packet_pool - packet allocation failed!");
+                       SBP2_ERR("sbp2util_create_request_packet_pool - packet allocation failed!");
                        return(-ENOMEM);
                }
 
@@ -593,7 +599,7 @@ sbp2util_allocate_write_request_packet(struct sbp2scsi_host_info *hi,
                list_add_tail(&request_packet->list, &hi->sbp2_req_inuse);
 
        } else {
-               SBP2_ERR("sbp2: sbp2util_allocate_request_packet - no packets available!");
+               SBP2_ERR("sbp2util_allocate_request_packet - no packets available!");
        }
        sbp2_spin_unlock(&hi->sbp2_request_packet_lock, flags);
 
@@ -766,7 +772,7 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
                command->linked = 0;
                list_add_tail(&command->list, &scsi_id->sbp2_command_orb_inuse);
        } else {
-               SBP2_ERR("sbp2: sbp2util_allocate_command_orb - No orbs available!");
+               SBP2_ERR("sbp2util_allocate_command_orb - No orbs available!");
        }
        sbp2_spin_unlock(&scsi_id->sbp2_command_orb_lock, flags);
        return (command);
@@ -825,7 +831,7 @@ static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_i
  */
 int sbp2_init(void)
 {
-       SBP2_DEBUG("sbp2: sbp2_init");
+       SBP2_DEBUG("sbp2_init");
 
        /*
         * Register our high level driver with 1394 stack
@@ -833,7 +839,7 @@ int sbp2_init(void)
        sbp2_hl_handle = hpsb_register_highlevel(SBP2_DEVICE_NAME, &sbp2_hl_ops);
 
        if (sbp2_hl_handle == NULL) {
-               SBP2_ERR("sbp2: sbp2 failed to register with ieee1394 highlevel");
+               SBP2_ERR("sbp2 failed to register with ieee1394 highlevel");
                return(-ENOMEM);
        }
 
@@ -854,7 +860,7 @@ int sbp2_init(void)
  */
 void sbp2_cleanup(void)
 {
-       SBP2_DEBUG("sbp2: sbp2_cleanup");
+       SBP2_DEBUG("sbp2_cleanup");
 
        hpsb_unregister_protocol(&sbp2_driver);
 
@@ -869,7 +875,7 @@ static int sbp2_probe(struct unit_directory *ud)
 {
        struct sbp2scsi_host_info *hi;
 
-       SBP2_DEBUG("sbp2: sbp2_probe");
+       SBP2_DEBUG("sbp2_probe");
        hi = sbp2_find_host_info(ud->ne->host);
 
        return sbp2_start_device(hi, ud);
@@ -880,7 +886,7 @@ static void sbp2_disconnect(struct unit_directory *ud)
        struct sbp2scsi_host_info *hi;
        struct scsi_id_instance_data *scsi_id = ud->driver_data;
 
-       SBP2_DEBUG("sbp2: sbp2_disconnect");
+       SBP2_DEBUG("sbp2_disconnect");
        hi = sbp2_find_host_info(ud->ne->host);
 
        if (hi != NULL)
@@ -893,7 +899,7 @@ static void sbp2_update(struct unit_directory *ud)
        struct scsi_id_instance_data *scsi_id = ud->driver_data;
        unsigned long flags;
 
-       SBP2_DEBUG("sbp2: sbp2_update");
+       SBP2_DEBUG("sbp2_update");
        hi = sbp2_find_host_info(ud->ne->host);
 
        if (sbp2_reconnect_device(hi, scsi_id)) {
@@ -907,7 +913,7 @@ static void sbp2_update(struct unit_directory *ud)
                         * unvalidated, so that he gets cleaned up
                         * later.
                         */
-                       SBP2_ERR("sbp2: sbp2_reconnect_device failed!");
+                       SBP2_ERR("sbp2_reconnect_device failed!");
                        sbp2_remove_device(hi, scsi_id);
                        return;
                }
@@ -940,14 +946,14 @@ static void sbp2_add_host(struct hpsb_host *host)
        struct sbp2scsi_host_info *hi;
        unsigned long flags;
 
-       SBP2_DEBUG("sbp2: sbp2_add_host");
+       SBP2_DEBUG("sbp2_add_host");
 
        /* Allocate some memory for our host info structure */
        hi = (struct sbp2scsi_host_info *)kmalloc(sizeof(struct sbp2scsi_host_info),
                                                  GFP_KERNEL);
 
        if (hi == NULL) {
-               SBP2_ERR("sbp2: out of memory in sbp2_add_host");
+               SBP2_ERR("out of memory in sbp2_add_host");
                return;
        }
 
@@ -962,7 +968,7 @@ static void sbp2_add_host(struct hpsb_host *host)
 
        /* Create our request packet pool (pool of packets for use in I/O) */
        if (sbp2util_create_request_packet_pool(hi)) {
-               SBP2_ERR("sbp2: sbp2util_create_request_packet_pool failed!");
+               SBP2_ERR("sbp2util_create_request_packet_pool failed!");
                return;
        }
 
@@ -1005,7 +1011,7 @@ static void sbp2_remove_host(struct hpsb_host *host)
        unsigned long flags;
        int i;
 
-       SBP2_DEBUG("sbp2: sbp2_remove_host");
+       SBP2_DEBUG("sbp2_remove_host");
 
        sbp2_spin_lock(&sbp2_host_info_lock, flags);
 
@@ -1030,7 +1036,7 @@ static void sbp2_remove_host(struct hpsb_host *host)
                kfree(hi);
        }
        else
-               SBP2_ERR("sbp2: attempt to remove unknown host %p", host);
+               SBP2_ERR("attempt to remove unknown host %p", host);
 
        sbp2_spin_unlock(&sbp2_host_info_lock, flags);
 }
@@ -1045,7 +1051,7 @@ static int sbp2_start_device(struct sbp2scsi_host_info *hi, struct unit_director
        struct node_entry *ne;
        int i;
 
-       SBP2_DEBUG("sbp2: sbp2_start_device");
+       SBP2_DEBUG("sbp2_start_device");
        ne = ud->ne;
 
        /*
@@ -1114,7 +1120,7 @@ alloc_fail:
 
                kfree(scsi_id);
 alloc_fail_first:
-               SBP2_ERR ("sbp2: Could not allocate memory for scsi_id");
+               SBP2_ERR ("Could not allocate memory for scsi_id");
                return(-ENOMEM);
        }
        SBP2_DMA_ALLOC("consistent DMA region for login ORB");
@@ -1125,7 +1131,7 @@ alloc_fail_first:
        scsi_id->ne = ne;
        scsi_id->ud = ud;
        scsi_id->speed_code = SPEED_100;
-       scsi_id->max_payload_size = MAX_PAYLOAD_S100;
+       scsi_id->max_payload_size = sbp2_speedto_maxrec[SPEED_100];
        ud->driver_data = scsi_id;
 
        init_waitqueue_head(&scsi_id->sbp2_login_wait);
@@ -1169,7 +1175,7 @@ alloc_fail_first:
                if (!hi->scsi_id[i]) {
                        hi->scsi_id[i] = scsi_id;
                        scsi_id->id = i;
-                       SBP2_DEBUG("sbp2: New SBP-2 device inserted, SCSI ID = %x", (unsigned int) i);
+                       SBP2_DEBUG("New SBP-2 device inserted, SCSI ID = %x", (unsigned int) i);
                        break;
                }
        }
@@ -1178,7 +1184,7 @@ alloc_fail_first:
         * Create our command orb pool
         */
        if (sbp2util_create_command_orb_pool(scsi_id, hi)) {
-               SBP2_ERR("sbp2: sbp2util_create_command_orb_pool failed!");
+               SBP2_ERR("sbp2util_create_command_orb_pool failed!");
                sbp2_remove_device(hi, scsi_id);
                return -ENOMEM;
        }
@@ -1187,7 +1193,7 @@ alloc_fail_first:
         * Make sure we are not out of space
         */
        if (i == SBP2SCSI_MAX_SCSI_IDS) {
-               SBP2_ERR("sbp2: No slots left for SBP-2 device");
+               SBP2_ERR("No slots left for SBP-2 device");
                sbp2_remove_device(hi, scsi_id);
                return -EBUSY;
        }
@@ -1201,7 +1207,7 @@ alloc_fail_first:
                 * Login failed... so, just mark him as unvalidated, so
                 * that he gets cleaned up later.
                 */
-               SBP2_ERR("sbp2: sbp2_login_device failed");
+               SBP2_ERR("sbp2_login_device failed");
                sbp2_remove_device(hi, scsi_id);
                return -EBUSY;
        }
@@ -1270,7 +1276,7 @@ static void sbp2_remove_device(struct sbp2scsi_host_info *hi,
                SBP2_DMA_FREE("single logout orb");
        }
 
-       SBP2_DEBUG("sbp2: Unvalidated SBP-2 device removed, SCSI ID = %d", 
+       SBP2_DEBUG("Unvalidated SBP-2 device removed, SCSI ID = %d", 
                   scsi_id->id);
        hi->scsi_id[scsi_id->id] = NULL;
        kfree(scsi_id);
@@ -1291,43 +1297,43 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
        quadlet_t data[2];
        unsigned long flags;
 
-       SBP2_DEBUG("sbp2: sbp2_login_device");
+       SBP2_DEBUG("sbp2_login_device");
 
        if (!scsi_id->login_orb) {
-               SBP2_DEBUG("sbp2: sbp2_login_device: login_orb not alloc'd!");
+               SBP2_DEBUG("sbp2_login_device: login_orb not alloc'd!");
                return(-EIO);
        }
 
        /* Set-up login ORB, assume no password */
        scsi_id->login_orb->password_hi = 0; 
        scsi_id->login_orb->password_lo = 0;
-       SBP2_DEBUG("sbp2: sbp2_login_device: password_hi/lo initialized");
+       SBP2_DEBUG("sbp2_login_device: password_hi/lo initialized");
 
        scsi_id->login_orb->login_response_lo = scsi_id->login_response_dma;
        scsi_id->login_orb->login_response_hi = ORB_SET_NODE_ID(hi->host->node_id);
-       SBP2_DEBUG("sbp2: sbp2_login_device: login_response_hi/lo initialized");
+       SBP2_DEBUG("sbp2_login_device: login_response_hi/lo initialized");
 
        scsi_id->login_orb->lun_misc = ORB_SET_FUNCTION(LOGIN_REQUEST);
        scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0);   /* One second reconnect time */
        scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(1);   /* Exclusive access to device */
        scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1);              /* Notify us of login complete */
-       SBP2_DEBUG("sbp2: sbp2_login_device: lun_misc initialized");
+       SBP2_DEBUG("sbp2_login_device: lun_misc initialized");
 
        scsi_id->login_orb->passwd_resp_lengths =
                ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response));
-       SBP2_DEBUG("sbp2: sbp2_login_device: passwd_resp_lengths initialized");
+       SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized");
 
        scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO;
        scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) |
                                              SBP2_STATUS_FIFO_ADDRESS_HI);
-       SBP2_DEBUG("sbp2: sbp2_login_device: status FIFO initialized");
+       SBP2_DEBUG("sbp2_login_device: status FIFO initialized");
 
        /*
         * Byte swap ORB if necessary
         */
        sbp2util_cpu_to_be32_buffer(scsi_id->login_orb, sizeof(struct sbp2_login_orb));
 
-       SBP2_DEBUG("sbp2: sbp2_login_device: orb byte-swapped");
+       SBP2_DEBUG("sbp2_login_device: orb byte-swapped");
 
        /*
         * Initialize login response and status fifo
@@ -1335,7 +1341,7 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
        memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response));
        memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
 
-       SBP2_DEBUG("sbp2: sbp2_login_device: login_response/status FIFO memset");
+       SBP2_DEBUG("sbp2_login_device: login_response/status FIFO memset");
 
        /*
         * Ok, let's write to the target's management agent register
@@ -1344,9 +1350,9 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
        data[1] = scsi_id->login_orb_dma;
        sbp2util_cpu_to_be32_buffer(data, 8);
 
-       SBP2_DEBUG("sbp2: sbp2_login_device: prepared to write");
+       SBP2_DEBUG("sbp2_login_device: prepared to write");
        hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, scsi_id->sbp2_management_agent_addr, data, 8);
-       SBP2_DEBUG("sbp2: sbp2_login_device: written");
+       SBP2_DEBUG("sbp2_login_device: written");
 
        /*
         * Wait for login status... but, only if the device has not
@@ -1360,18 +1366,18 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
                sleep_on_timeout(&scsi_id->sbp2_login_wait, 10*HZ);
        restore_flags(flags);
 
-       SBP2_DEBUG("sbp2: sbp2_login_device: initial check");
+       SBP2_DEBUG("sbp2_login_device: initial check");
 
        /*
         * Match status to the login orb. If they do not match, it's
         * probably because the login timed-out.
         */
        if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
-               SBP2_ERR("sbp2: Error logging into SBP-2 device - login timed-out");
+               SBP2_ERR("Error logging into SBP-2 device - login timed-out");
                return(-EIO);
        }
 
-       SBP2_DEBUG("sbp2: sbp2_login_device: second check");
+       SBP2_DEBUG("sbp2_login_device: second check");
 
        /*
         * Check status
@@ -1380,7 +1386,7 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
            STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) ||
            STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
 
-               SBP2_ERR("sbp2: Error logging into SBP-2 device - login failed");
+               SBP2_ERR("Error logging into SBP-2 device - login failed");
                return(-EIO);
        }
 
@@ -1393,9 +1399,9 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
        /*
         * Grab our command block agent address from the login response.
         */
-       SBP2_DEBUG("sbp2: command_block_agent_hi = %x",
+       SBP2_DEBUG("command_block_agent_hi = %x",
                   (unsigned int)scsi_id->login_response->command_block_agent_hi);
-       SBP2_DEBUG("sbp2: command_block_agent_lo = %x",
+       SBP2_DEBUG("command_block_agent_lo = %x",
                   (unsigned int)scsi_id->login_response->command_block_agent_lo);
 
        scsi_id->sbp2_command_block_agent_addr =
@@ -1403,7 +1409,7 @@ static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_insta
        scsi_id->sbp2_command_block_agent_addr |= ((u64)scsi_id->login_response->command_block_agent_lo);
        scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL;
 
-       SBP2_INFO("sbp2: Logged into SBP-2 device");
+       SBP2_INFO("Logged into SBP-2 device");
 
        return(0);
 
@@ -1417,7 +1423,7 @@ static int sbp2_logout_device(struct sbp2scsi_host_info *hi, struct scsi_id_inst
 {
        quadlet_t data[2];
 
-       SBP2_DEBUG("sbp2: sbp2_logout_device");
+       SBP2_DEBUG("sbp2_logout_device");
 
        /*
         * Set-up logout ORB
@@ -1455,7 +1461,7 @@ static int sbp2_logout_device(struct sbp2scsi_host_info *hi, struct scsi_id_inst
        /* Wait for device to logout...1 second. */
        sleep_on_timeout(&scsi_id->sbp2_login_wait, HZ);
 
-       SBP2_INFO("sbp2: Logged out of SBP-2 device");
+       SBP2_INFO("Logged out of SBP-2 device");
 
        return(0);
 
@@ -1470,7 +1476,7 @@ static int sbp2_reconnect_device(struct sbp2scsi_host_info *hi, struct scsi_id_i
        quadlet_t data[2];
        unsigned long flags;
 
-       SBP2_DEBUG("sbp2: sbp2_reconnect_device");
+       SBP2_DEBUG("sbp2_reconnect_device");
 
        /*
         * Set-up reconnect ORB
@@ -1527,7 +1533,7 @@ static int sbp2_reconnect_device(struct sbp2scsi_host_info *hi, struct scsi_id_i
         * probably because the reconnect timed-out.
         */
        if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
-               SBP2_ERR("sbp2: Error reconnecting to SBP-2 device - reconnect timed-out");
+               SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
                return(-EIO);
        }
 
@@ -1538,11 +1544,11 @@ static int sbp2_reconnect_device(struct sbp2scsi_host_info *hi, struct scsi_id_i
            STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) ||
            STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
 
-               SBP2_ERR("sbp2: Error reconnecting to SBP-2 device - reconnect failed");
+               SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed");
                return(-EIO);
        }
 
-       SBP2_INFO("sbp2: Reconnected to SBP-2 device");
+       SBP2_INFO("Reconnected to SBP-2 device");
 
        return(0);
 
@@ -1556,7 +1562,7 @@ static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_i
 {      
        quadlet_t data;
 
-       SBP2_DEBUG("sbp2: sbp2_set_busy_timeout");
+       SBP2_DEBUG("sbp2_set_busy_timeout");
 
        /*
         * Ok, let's write to the target's busy timeout register
@@ -1564,7 +1570,7 @@ static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_i
        data = cpu_to_be32(SBP2_BUSY_TIMEOUT_VALUE);
 
        if (hpsb_write(hi->host, LOCAL_BUS | scsi_id->ne->nodeid, SBP2_BUSY_TIMEOUT_ADDRESS, &data, 4)) {
-               SBP2_ERR("sbp2: sbp2_set_busy_timeout error");
+               SBP2_ERR("sbp2_set_busy_timeout error");
        }
 
        return(0);
@@ -1580,7 +1586,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
        struct unit_directory *ud;
        int i;
 
-       SBP2_DEBUG("sbp2: sbp2_parse_unit_directory");
+       SBP2_DEBUG("sbp2_parse_unit_directory");
 
        ud = scsi_id->ud;
 
@@ -1593,21 +1599,21 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
                                CONFIG_ROM_INITIAL_MEMORY_SPACE + 
                                (ud->arb_values[i] << 2);
 
-                       SBP2_DEBUG("sbp2: sbp2_management_agent_addr = %x",
+                       SBP2_DEBUG("sbp2_management_agent_addr = %x",
                                   (unsigned int) scsi_id->sbp2_management_agent_addr);
                        break;
 
                case SBP2_COMMAND_SET_SPEC_ID_KEY:
                        /* Command spec organization */
                        scsi_id->sbp2_command_set_spec_id = ud->arb_values[i];
-                       SBP2_DEBUG("sbp2: sbp2_command_set_spec_id = %x",
+                       SBP2_DEBUG("sbp2_command_set_spec_id = %x",
                                   (unsigned int) scsi_id->sbp2_command_set_spec_id);
                        break;
 
                case SBP2_COMMAND_SET_KEY:
                        /* Command set used by sbp2 device */
                        scsi_id->sbp2_command_set = ud->arb_values[i];
-                       SBP2_DEBUG("sbp2: sbp2_command_set = %x",
+                       SBP2_DEBUG("sbp2_command_set = %x",
                                   (unsigned int) scsi_id->sbp2_command_set);
                        break;
 
@@ -1617,7 +1623,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
                         * that I'm not yet paying attention to)
                         */
                        scsi_id->sbp2_unit_characteristics = ud->arb_values[i];
-                       SBP2_DEBUG("sbp2: sbp2_unit_characteristics = %x",
+                       SBP2_DEBUG("sbp2_unit_characteristics = %x",
                                   (unsigned int) scsi_id->sbp2_unit_characteristics);
                        break;
 
@@ -1627,7 +1633,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
                         * detemining type of sbp2 device)
                         */
                        scsi_id->sbp2_device_type_and_lun = ud->arb_values[i];
-                       SBP2_DEBUG("sbp2: sbp2_device_type_and_lun = %x",
+                       SBP2_DEBUG("sbp2_device_type_and_lun = %x",
                                   (unsigned int) scsi_id->sbp2_device_type_and_lun);
                        break;
 
@@ -1642,7 +1648,7 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
                        scsi_id->sbp2_firmware_revision = ud->arb_values[i];
                        if (scsi_id->sbp2_firmware_revision ==
                            SBP2_128KB_BROKEN_FIRMWARE) {
-                               SBP2_WARN("sbp2: warning: Bridge chipset supports 128KB max transfer size");
+                               SBP2_WARN("warning: Bridge chipset supports 128KB max transfer size");
                        }
                        break;
 
@@ -1654,40 +1660,37 @@ static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id)
 
 /*
  * This function is called in order to determine the max speed and packet
- * size we can use in our ORBs. 
+ * size we can use in our ORBs. Note, that we (the driver and host) only
+ * initiate the transaction. The SBP-2 device actually transfers the data
+ * (by reading from the DMA area we tell it). This means that the SBP-2
+ * device decides the actual maximum data it can transfer. We just tell it
+ * the speed that it needs to use, and the max_rec the host supports, and
+ * it takes care of the rest.
  */
 static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id)
 {
-       u8 speed_code;
-       unsigned int max_rec;
-
-       SBP2_DEBUG("sbp2: sbp2_max_speed_and_size");
-
-       speed_code = scsi_id->ne->busopt.lnkspd;
-       max_rec = scsi_id->ne->busopt.max_rec;
-
-       /* Bump down our speed if there is a module parameter forcing us slower */
-       if (speed_code > max_speed) {
-               speed_code = max_speed;
-               SBP2_ERR("sbp2: Reducing SBP-2 max speed allowed (%x)", max_speed); 
-       }
-
-       /* Support the devices max_rec and max speed. We choose a setting
-        * that fits both values, since they may differ.  */
-       if (speed_code >= SPEED_400 && max_rec >= MAX_REC_S400) {
-               HPSB_INFO("sbp2: SBP-2 device max speed S400 and payload 2KB");
-               scsi_id->speed_code = SPEED_400;
-               scsi_id->max_payload_size = MAX_PAYLOAD_S400;
-       } else if (speed_code >= SPEED_200 && max_rec >= MAX_REC_S200) {
-               HPSB_INFO("sbp2: SBP-2 device max speed S200 and payload 1KB");
-               scsi_id->speed_code = SPEED_200;
-               scsi_id->max_payload_size = MAX_PAYLOAD_S200;
-       } else {
-               HPSB_INFO("sbp2: SBP-2 device max speed S100 and payload 512 bytes");
-               scsi_id->speed_code = SPEED_100;
-               scsi_id->max_payload_size = MAX_PAYLOAD_S100;
+       SBP2_DEBUG("sbp2_max_speed_and_size");
+
+       /* Initial setting comes from the hosts speed map */
+       scsi_id->speed_code = hi->host->speed_map[(hi->host->node_id & NODE_MASK) * 64
+                                                 + (scsi_id->ne->nodeid & NODE_MASK)];
+
+       /* Bump down our speed if the user requested it */
+       if (scsi_id->speed_code > max_speed) {
+               scsi_id->speed_code = max_speed;
+               SBP2_ERR("Forcing SBP-2 max speed down to %s",
+                        hpsb_speedto_str[scsi_id->speed_code]);
        }
 
+       /* Payload size is the lesser of what our speed supports and what
+        * our host supports.  */
+       scsi_id->max_payload_size = min(sbp2_speedto_maxrec[scsi_id->speed_code],
+                                       (u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
+
+       SBP2_ERR("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [0x%02x/%u]",
+                NODE_BUS_ARGS(scsi_id->ne->nodeid), hpsb_speedto_str[scsi_id->speed_code],
+                scsi_id->max_payload_size, 1 << ((u32)scsi_id->max_payload_size + 2));
+
        return(0);
 }
 
@@ -1698,7 +1701,7 @@ static int sbp2_agent_reset(struct sbp2scsi_host_info *hi, struct scsi_id_instan
 {
        struct sbp2_request_packet *agent_reset_request_packet;
 
-       SBP2_DEBUG("sbp2: sbp2_agent_reset");
+       SBP2_DEBUG("sbp2_agent_reset");
 
        /*
         * Ok, let's write to the target's management agent register
@@ -1710,12 +1713,12 @@ static int sbp2_agent_reset(struct sbp2scsi_host_info *hi, struct scsi_id_instan
                                                       0, ntohl(SBP2_AGENT_RESET_DATA));
 
        if (!agent_reset_request_packet) {
-               SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
+               SBP2_ERR("sbp2util_allocate_write_request_packet failed");
                return(-EIO);
        }
 
        if (!hpsb_send_packet(agent_reset_request_packet->packet)) {
-               SBP2_ERR("sbp2: hpsb_send_packet failed");
+               SBP2_ERR("hpsb_send_packet failed");
                sbp2util_free_request_packet(agent_reset_request_packet); 
                return(-EIO);
        }
@@ -1774,7 +1777,7 @@ static int sbp2_create_command_orb(struct sbp2scsi_host_info *hi,
         */
        if (sbp2scsi_direction_table[*scsi_cmd] == ORB_DIRECTION_NO_DATA_TRANSFER) {
 
-               SBP2_DEBUG("sbp2: No data transfer");
+               SBP2_DEBUG("No data transfer");
 
                /*
                 * Handle no data transfer
@@ -1785,14 +1788,14 @@ static int sbp2_create_command_orb(struct sbp2scsi_host_info *hi,
 
        } else if (scsi_use_sg) {
 
-               SBP2_DEBUG("sbp2: Use scatter/gather");
+               SBP2_DEBUG("Use scatter/gather");
 
                /*
                 * Special case if only one element (and less than 64KB in size)
                 */
                if ((scsi_use_sg == 1) && (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
 
-                       SBP2_DEBUG("sbp2: Only one s/g element");
+                       SBP2_DEBUG("Only one s/g element");
                        command->dma_dir = dma_dir;
                        command->dma_size = sgpnt[0].length;
                        command->cmd_dma = pci_map_single (hi->host->pdev, sgpnt[0].address,
@@ -1856,7 +1859,7 @@ static int sbp2_create_command_orb(struct sbp2scsi_host_info *hi,
 
        } else {
 
-               SBP2_DEBUG("sbp2: No scatter/gather");
+               SBP2_DEBUG("No scatter/gather");
 
                command->dma_dir = dma_dir;
                command->dma_size = scsi_request_bufflen;
@@ -1977,7 +1980,7 @@ static int sbp2_link_orb_command(struct sbp2scsi_host_info *hi, struct scsi_id_i
                                                                SBP2_ORB_POINTER_OFFSET, 8, 0);
                
                        if (!command_request_packet) {
-                               SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
+                               SBP2_ERR("sbp2util_allocate_write_request_packet failed");
                                return(-EIO);
                        }
                
@@ -1988,7 +1991,7 @@ static int sbp2_link_orb_command(struct sbp2scsi_host_info *hi, struct scsi_id_i
                        SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb);
 
                        if (!hpsb_send_packet(command_request_packet->packet)) {
-                               SBP2_ERR("sbp2: hpsb_send_packet failed");
+                               SBP2_ERR("hpsb_send_packet failed");
                                sbp2util_free_request_packet(command_request_packet); 
                                return(-EIO);
                        }
@@ -2024,14 +2027,14 @@ static int sbp2_link_orb_command(struct sbp2scsi_host_info *hi, struct scsi_id_i
                                0, cpu_to_be32(command->command_orb_dma));
        
                        if (!command_request_packet) {
-                               SBP2_ERR("sbp2: sbp2util_allocate_write_request_packet failed");
+                               SBP2_ERR("sbp2util_allocate_write_request_packet failed");
                                return(-EIO);
                        }
 
                        SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb);
 
                        if (!hpsb_send_packet(command_request_packet->packet)) {
-                               SBP2_ERR("sbp2: hpsb_send_packet failed");
+                               SBP2_ERR("hpsb_send_packet failed");
                                sbp2util_free_request_packet(command_request_packet);
                                return(-EIO);
                        }
@@ -2053,10 +2056,10 @@ static int sbp2_send_command(struct sbp2scsi_host_info *hi, struct scsi_id_insta
        u32 device_type = (scsi_id->sbp2_device_type_and_lun & 0x00ff0000) >> 16;
        struct sbp2_command_info *command;
 
-       SBP2_DEBUG("sbp2: sbp2_send_command");
-       SBP2_DEBUG("sbp2: SCSI command = %02x", *cmd);
-       SBP2_DEBUG("sbp2: SCSI transfer size = %x", SCpnt->request_bufflen);
-       SBP2_DEBUG("sbp2: SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg);
+       SBP2_DEBUG("sbp2_send_command");
+       SBP2_DEBUG("SCSI command = %02x", *cmd);
+       SBP2_DEBUG("SCSI transfer size = %x", SCpnt->request_bufflen);
+       SBP2_DEBUG("SCSI s/g elements = %x", (unsigned int)SCpnt->use_sg);
 
        /*
         * Check for broken devices that can't handle greater than 128K
@@ -2236,13 +2239,13 @@ static void sbp2_check_sbp2_command(unchar *cmd)
 {
        unchar new_cmd[16];
 
-       SBP2_DEBUG("sbp2: sbp2_check_sbp2_command");
+       SBP2_DEBUG("sbp2_check_sbp2_command");
 
        switch (*cmd) {
                
                case READ_6:
 
-                       SBP2_DEBUG("sbp2: Convert READ_6 to READ_10");
+                       SBP2_DEBUG("Convert READ_6 to READ_10");
 
                        /*
                         * Need to turn read_6 into read_10
@@ -2264,7 +2267,7 @@ static void sbp2_check_sbp2_command(unchar *cmd)
 
                case WRITE_6:
 
-                       SBP2_DEBUG("sbp2: Convert WRITE_6 to WRITE_10");
+                       SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
 
                        /*
                         * Need to turn write_6 into write_10
@@ -2286,7 +2289,7 @@ static void sbp2_check_sbp2_command(unchar *cmd)
 
                case MODE_SENSE:
 
-                       SBP2_DEBUG("sbp2: Convert MODE_SENSE_6 to MOSE_SENSE_10");
+                       SBP2_DEBUG("Convert MODE_SENSE_6 to MOSE_SENSE_10");
 
                        /*
                         * Need to turn mode_sense_6 into mode_sense_10
@@ -2324,7 +2327,7 @@ static void sbp2_check_sbp2_command(unchar *cmd)
  */
 static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data)
 {
-       SBP2_DEBUG("sbp2: sbp2_status_to_sense_data");
+       SBP2_DEBUG("sbp2_status_to_sense_data");
 
        /*
         * Ok, it's pretty ugly...   ;-)
@@ -2360,19 +2363,19 @@ static void sbp2_check_sbp2_response(struct sbp2scsi_host_info *hi,
        u8 *scsi_buf = SCpnt->request_buffer;
        u32 device_type = (scsi_id->sbp2_device_type_and_lun & 0x00ff0000) >> 16;
         
-       SBP2_DEBUG("sbp2: sbp2_check_sbp2_response");
+       SBP2_DEBUG("sbp2_check_sbp2_response");
 
        switch (SCpnt->cmnd[0]) {
                
                case INQUIRY:
 
-                       SBP2_DEBUG("sbp2: Check Inquiry data");
+                       SBP2_DEBUG("Check Inquiry data");
 
                        /*
                         * Check for Simple Direct Access Device and change it to TYPE_DISK
                         */
                        if ((scsi_buf[0] & 0x1f) == TYPE_SDAD) {
-                               SBP2_DEBUG("sbp2: Changing TYPE_SDAD to TYPE_DISK");
+                               SBP2_DEBUG("Changing TYPE_SDAD to TYPE_DISK");
                                scsi_buf[0] &= 0xe0;
                        }
 
@@ -2390,7 +2393,7 @@ static void sbp2_check_sbp2_response(struct sbp2scsi_host_info *hi,
                            (device_type == TYPE_SDAD) ||
                            (device_type == TYPE_ROM)) {
 
-                               SBP2_DEBUG("sbp2: Modify mode sense response (10 byte version)");
+                               SBP2_DEBUG("Modify mode sense response (10 byte version)");
        
                                scsi_buf[0] = scsi_buf[1];      /* Mode data length */
                                scsi_buf[1] = scsi_buf[2];      /* Medium type */
@@ -2428,10 +2431,10 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
        u32 scsi_status = SBP2_SCSI_STATUS_GOOD;
        struct sbp2_command_info *command;
 
-       SBP2_DEBUG("sbp2: sbp2_handle_status_write");
+       SBP2_DEBUG("sbp2_handle_status_write");
 
        if (!host) {
-               SBP2_ERR("sbp2: host is NULL - this is bad!");
+               SBP2_ERR("host is NULL - this is bad!");
                return(RCODE_ADDRESS_ERROR);
        }
 
@@ -2440,7 +2443,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
        sbp2_spin_unlock(&sbp2_host_info_lock, flags);
 
        if (!hi) {
-               SBP2_ERR("sbp2: host info is NULL - this is bad!");
+               SBP2_ERR("host info is NULL - this is bad!");
                return(RCODE_ADDRESS_ERROR);
        }
 
@@ -2453,14 +2456,14 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
                if (hi->scsi_id[i]) {
                        if ((hi->scsi_id[i]->ne->nodeid & NODE_MASK) == (nodeid & NODE_MASK)) {
                                scsi_id = hi->scsi_id[i];
-                               SBP2_DEBUG("sbp2: SBP-2 status write from node %x", scsi_id->ne->nodeid);
+                               SBP2_DEBUG("SBP-2 status write from node %x", scsi_id->ne->nodeid);
                                break;
                        }
                }
        }
 
        if (!scsi_id) {
-               SBP2_ERR("sbp2: scsi_id is NULL - device is gone?");
+               SBP2_ERR("scsi_id is NULL - device is gone?");
                sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
                return(RCODE_ADDRESS_ERROR);
        }
@@ -2481,7 +2484,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
        command = sbp2util_find_command_for_orb(scsi_id, scsi_id->status_block.ORB_offset_lo);
        if (command) {
 
-               SBP2_DEBUG("sbp2: Found status for command ORB");
+               SBP2_DEBUG("Found status for command ORB");
 
                SBP2_ORB_DEBUG("matched command orb %p", &command->command_orb);
                outstanding_orb_decr;
@@ -2499,7 +2502,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
                         */
                        if (STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
 
-                               SBP2_DEBUG("sbp2: CHECK CONDITION");
+                               SBP2_DEBUG("CHECK CONDITION");
 
                                /*
                                 * Translate SBP-2 status to SCSI sense data
@@ -2518,7 +2521,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
                        /*
                         * Complete the SCSI command
                         */
-                       SBP2_DEBUG("sbp2: Completing SCSI command");
+                       SBP2_DEBUG("Completing SCSI command");
                        sbp2scsi_complete_command(hi, scsi_id, scsi_status, SCpnt, command->Current_done);
                        SBP2_ORB_DEBUG("command orb completed");
                }
@@ -2555,7 +2558,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        struct scsi_id_instance_data *scsi_id = NULL;
        unsigned long flags;
 
-       SBP2_DEBUG("sbp2: sbp2scsi_queuecommand");
+       SBP2_DEBUG("sbp2scsi_queuecommand");
 
        /*
         * Pull our host info and scsi id instance data from the scsi command
@@ -2563,7 +2566,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
        hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
 
        if (!hi) {
-               SBP2_ERR("sbp2: sbp2scsi_host_info is NULL - this is bad!");
+               SBP2_ERR("sbp2scsi_host_info is NULL - this is bad!");
                SCpnt->result = DID_NO_CONNECT << 16;
                done (SCpnt);
                return(0);
@@ -2596,7 +2599,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
         * (autorequest sense)
         */
        if (SCpnt->cmnd[0] == REQUEST_SENSE) {
-               SBP2_DEBUG("sbp2: REQUEST_SENSE");
+               SBP2_DEBUG("REQUEST_SENSE");
                memcpy(SCpnt->request_buffer, SCpnt->sense_buffer, SCpnt->request_bufflen);
                memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
                sbp2scsi_complete_command(hi, scsi_id, SBP2_SCSI_STATUS_GOOD, SCpnt, done);
@@ -2608,7 +2611,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
         * busy (to be queued later)
         */
        if (!hpsb_node_entry_valid(scsi_id->ne)) {
-               SBP2_ERR("sbp2: Bus reset in progress - rejecting command");
+               SBP2_ERR("Bus reset in progress - rejecting command");
                SCpnt->result = DID_BUS_BUSY << 16;
                done (SCpnt);
                return(0);
@@ -2619,7 +2622,7 @@ static int sbp2scsi_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
         */
        sbp2_spin_lock(&hi->sbp2_command_lock, flags);
        if (sbp2_send_command(hi, scsi_id, SCpnt, done)) {
-               SBP2_ERR("sbp2: Error sending SCSI command");
+               SBP2_ERR("Error sending SCSI command");
                sbp2scsi_complete_command(hi, scsi_id, SBP2_SCSI_STATUS_SELECTION_TIMEOUT, SCpnt, done);
        }
        sbp2_spin_unlock(&hi->sbp2_command_lock, flags);
@@ -2638,10 +2641,10 @@ static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi,
        struct list_head *lh;
        struct sbp2_command_info *command;
 
-       SBP2_DEBUG("sbp2: sbp2_complete_all_commands");
+       SBP2_DEBUG("sbp2_complete_all_commands");
 
        while (!list_empty(&scsi_id->sbp2_command_orb_inuse)) {
-               SBP2_DEBUG("sbp2: Found pending command to complete");
+               SBP2_DEBUG("Found pending command to complete");
                lh = scsi_id->sbp2_command_orb_inuse.next;
                command = list_entry(lh, struct sbp2_command_info, list);
                sbp2util_mark_command_completed(scsi_id, command);
@@ -2661,13 +2664,13 @@ static void sbp2scsi_complete_all_commands(struct sbp2scsi_host_info *hi,
 static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, u32 scsi_status,
                                      Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
-       SBP2_DEBUG("sbp2: sbp2scsi_complete_command");
+       SBP2_DEBUG("sbp2scsi_complete_command");
 
        /*
         * Sanity
         */
        if (!SCpnt) {
-               SBP2_ERR("sbp2: SCpnt is NULL");
+               SBP2_ERR("SCpnt is NULL");
                return;
        }
 
@@ -2677,7 +2680,7 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
         * bus reset.
         */
        if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
-               SBP2_ERR("sbp2: Bus reset in progress - retry command later");
+               SBP2_ERR("Bus reset in progress - retry command later");
                return;
        }
         
@@ -2690,12 +2693,12 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
                        break;
 
                case SBP2_SCSI_STATUS_BUSY:
-                       SBP2_ERR("sbp2: SBP2_SCSI_STATUS_BUSY");
+                       SBP2_ERR("SBP2_SCSI_STATUS_BUSY");
                        SCpnt->result = DID_BUS_BUSY << 16;
                        break;
 
                case SBP2_SCSI_STATUS_CHECK_CONDITION:
-                       SBP2_DEBUG("sbp2: SBP2_SCSI_STATUS_CHECK_CONDITION");
+                       SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION");
                        SCpnt->result = CHECK_CONDITION << 1;
 
                        /*
@@ -2706,19 +2709,19 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
                        break;
 
                case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
-                       SBP2_ERR("sbp2: SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
+                       SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
                        SCpnt->result = DID_NO_CONNECT << 16;
                        break;
 
                case SBP2_SCSI_STATUS_CONDITION_MET:
                case SBP2_SCSI_STATUS_RESERVATION_CONFLICT:
                case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
-                       SBP2_ERR("sbp2: Bad SCSI status = %x", scsi_status);
+                       SBP2_ERR("Bad SCSI status = %x", scsi_status);
                        SCpnt->result = DID_ERROR << 16;
                        break;
 
                default:
-                       SBP2_ERR("sbp2: Unsupported SCSI status = %x", scsi_status);
+                       SBP2_ERR("Unsupported SCSI status = %x", scsi_status);
                        SCpnt->result = DID_ERROR << 16;
        }
 
@@ -2736,7 +2739,7 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
         * can mount the device rw).
         */
        if (mode_sense_hack && SCpnt->result != DID_OK && SCpnt->cmnd[0] == MODE_SENSE) {
-               SBP2_INFO("sbp2: Returning success to mode sense command");
+               SBP2_INFO("Returning success to mode sense command");
                SCpnt->result = DID_OK;
                SCpnt->sense_buffer[0] = 0;
                memset (SCpnt->request_buffer, 0, 8);
@@ -2747,7 +2750,7 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
         * the command as busy so that it will get retried.
         */
        if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
-               SBP2_ERR("sbp2: Completing command with busy (bus reset)");
+               SBP2_ERR("Completing command with busy (bus reset)");
                SCpnt->result = DID_BUS_BUSY << 16;
        }
 
@@ -2757,7 +2760,7 @@ static void sbp2scsi_complete_command(struct sbp2scsi_host_info *hi, struct scsi
         * or hot-plug...
         */
        if ((scsi_status == SBP2_SCSI_STATUS_CHECK_CONDITION) && (SCpnt->sense_buffer[2] == UNIT_ATTENTION)) {
-               SBP2_INFO("sbp2: UNIT ATTENTION - return busy");
+               SBP2_INFO("UNIT ATTENTION - return busy");
                SCpnt->result = DID_BUS_BUSY << 16;
        }
 
@@ -2780,7 +2783,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
        struct sbp2_command_info *command;
        unsigned long flags;
 
-       SBP2_ERR("sbp2: aborting sbp2 command");
+       SBP2_ERR("aborting sbp2 command");
 
        if (scsi_id) {
 
@@ -2793,7 +2796,7 @@ static int sbp2scsi_abort (Scsi_Cmnd *SCpnt)
                do {
                        command = sbp2util_find_command_for_SCpnt(scsi_id, SCpnt);
                        if (command) {
-                               SBP2_DEBUG("sbp2: Found command to abort");
+                               SBP2_DEBUG("Found command to abort");
                                sbp2util_mark_command_completed(scsi_id, command);
                                if (command->Current_SCpnt && !command->linked) {
                                        void (*done)(Scsi_Cmnd *) = command->Current_done;
@@ -2821,10 +2824,10 @@ static int sbp2scsi_reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
 {
        struct sbp2scsi_host_info *hi = (struct sbp2scsi_host_info *) SCpnt->host->hostdata[0];
 
-       SBP2_ERR("sbp2: reset requested");
+       SBP2_ERR("reset requested");
 
        if (hi) {
-               SBP2_ERR("sbp2: generating IEEE-1394 bus reset");
+               SBP2_ERR("Generating IEEE-1394 bus reset");
                hpsb_reset_bus(hi->host, LONG_RESET);
        }
 
@@ -2838,7 +2841,7 @@ static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[])
 {
        int heads, sectors, cylinders;
 
-       SBP2_DEBUG("sbp2: request for bios parameters");
+       SBP2_DEBUG("Request for bios parameters");
 
        heads = 64;
        sectors = 32;
@@ -2862,7 +2865,7 @@ static int sbp2scsi_biosparam (Scsi_Disk *disk, kdev_t dev, int geom[])
  */
 void sbp2scsi_setup( char *str, int *ints) 
 {
-       SBP2_DEBUG("sbp2: sbp2scsi_setup");
+       SBP2_DEBUG("sbp2scsi_setup");
        return;
 }
 
@@ -2871,7 +2874,7 @@ void sbp2scsi_setup( char *str, int *ints)
  */
 static int sbp2scsi_detect (Scsi_Host_Template *tpnt) 
 {
-       SBP2_DEBUG("sbp2: sbp2scsi_detect");
+       SBP2_DEBUG("sbp2scsi_detect");
 
        global_scsi_tpnt = tpnt;
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,26)
@@ -2881,7 +2884,7 @@ static int sbp2scsi_detect (Scsi_Host_Template *tpnt)
         * Module load option for force one command at a time
         */
        if (serialize_io) {
-               SBP2_ERR("sbp2: Driver forced to serialize I/O (serialize_io = 1)");
+               SBP2_ERR("Driver forced to serialize I/O (serialize_io = 1)");
                global_scsi_tpnt->can_queue = 1;
                global_scsi_tpnt->cmd_per_lun = 1;
        }
@@ -2890,19 +2893,19 @@ static int sbp2scsi_detect (Scsi_Host_Template *tpnt)
         * Module load option to limit max size of requests from the scsi drivers
         */
        if (no_large_packets) {
-               SBP2_ERR("sbp2: Driver forced to limit max transfer size (no_large_packets = 1)");
+               SBP2_ERR("Driver forced to limit max transfer size (no_large_packets = 1)");
                global_scsi_tpnt->sg_tablesize = 0x1f;
                global_scsi_tpnt->use_clustering = DISABLE_CLUSTERING;
        }
 
        if (mode_sense_hack) {
-               SBP2_ERR("sbp2: Mode sense emulation enabled (mode_sense_hack = 1)");
+               SBP2_ERR("Mode sense emulation enabled (mode_sense_hack = 1)");
        }
 
        sbp2_init();
 
        if (!sbp2_host_count) {
-               SBP2_ERR("sbp2: Please load the lower level IEEE-1394 driver (e.g. ohci1394) before sbp2...");
+               SBP2_ERR("Please load the lower level IEEE-1394 driver (e.g. ohci1394) before sbp2...");
                sbp2_cleanup();
        }
 
@@ -2921,8 +2924,8 @@ static void sbp2scsi_register_scsi_host(struct sbp2scsi_host_info *hi)
 {
        struct Scsi_Host *shpnt = NULL;
 
-       SBP2_DEBUG("sbp2: sbp2scsi_register_scsi_host");
-       SBP2_DEBUG("sbp2: sbp2scsi_host_info = %p", hi);
+       SBP2_DEBUG("sbp2scsi_register_scsi_host");
+       SBP2_DEBUG("sbp2scsi_host_info = %p", hi);
 
        /*
         * Let's register with the scsi stack
@@ -2946,7 +2949,7 @@ static void sbp2scsi_register_scsi_host(struct sbp2scsi_host_info *hi)
 /* Called when our module is released */
 static int sbp2scsi_release(struct Scsi_Host *host)
 {
-       SBP2_DEBUG("sbp2: sbp2scsi_release");
+       SBP2_DEBUG("sbp2scsi_release");
        sbp2_cleanup();
        return(0);
 }
@@ -2960,6 +2963,7 @@ static const char *sbp2scsi_info (struct Scsi_Host *host)
 MODULE_AUTHOR("James Goodwin <jamesg@filanet.com>");
 MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
+MODULE_LICENSE("GPL");
 
 /* SCSI host template */
 static Scsi_Host_Template driver_template = {
index c1fc8dd29fe36e7d9c1f3453da4efe07744d1ce2..505c65a7564462e1f32c573a1a31ca7de1e457a0 100644 (file)
 #define ORB_DIRECTION_READ_FROM_MEDIA   0x1
 #define ORB_DIRECTION_NO_DATA_TRANSFER  0x2
 
-/* 2^(MAX_PAYLOAD+1) = Maximum data transfer length */
-#define MAX_PAYLOAD_S100               0x7
-#define MAX_PAYLOAD_S200               0x8
-#define MAX_PAYLOAD_S400               0x9
-
-/* Max rec matches node_entry values */
-#define MAX_REC_S100                   512
-#define MAX_REC_S200                   1024
-#define MAX_REC_S400                   2048
-
 #define ORB_SET_NOTIFY(value)                   ((value & 0x1) << 31)
 #define ORB_SET_RQ_FMT(value)                   ((value & 0x3) << 29)
 #define ORB_SET_NODE_ID(value)                 ((value & 0xffff) << 16)
@@ -268,6 +258,9 @@ struct sbp2_status_block {
  * DOU = OUT data direction
  * DNO = No data transfer
  * DUN = Unknown data direction
+ *
+ * Opcode 0xec (Teac specific "opc execute") possibly should be DNO,
+ * but we'll change it when somebody reports a problem with this.
  */
 #define DIN                            ORB_DIRECTION_READ_FROM_MEDIA
 #define DOU                            ORB_DIRECTION_WRITE_TO_MEDIA
@@ -280,7 +273,7 @@ static unchar sbp2scsi_direction_table[0x100] = {
        DIN,DUN,DIN,DIN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU,
        DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU,
        DOU,DOU,DIN,DIN,DIN,DNO,DIN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DNO,DUN,
-       DUN,DIN,DIN,DNO,DOU,DOU,DUN,DUN,DNO,DIN,DIN,DNO,DIN,DOU,DUN,DUN,
+       DUN,DIN,DIN,DNO,DNO,DOU,DUN,DUN,DNO,DIN,DIN,DNO,DIN,DOU,DUN,DUN,
        DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
        DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
        DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
index d34a2534a291ec1e6c71672455fafa931487c48c..cae03abdaed62e65375c0a1d735ea6eb41ec4c39 100644 (file)
@@ -542,8 +542,10 @@ static int check_disk_sb(mdk_rdev_t * rdev)
                goto abort;
        }
 
-       if (calc_sb_csum(sb) != sb->sb_csum)
+       if (calc_sb_csum(sb) != sb->sb_csum) {
                printk(BAD_CSUM, partition_name(rdev->dev));
+               goto abort;
+       }
        ret = 0;
 abort:
        return ret;
index e4d0577e3e117f66a041cbdbc01e710b5a439d5a..6c8a5bf21112f13c313f99274ffdca44dae349a8 100644 (file)
@@ -1690,7 +1690,8 @@ static int raid1_run (mddev_t *mddev)
                }
        }
 
-       if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {
+       if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN)) &&
+           (conf->working_disks > 1)) {
                const char * name = "raid1syncd";
 
                conf->resync_thread = md_register_thread(raid1syncd, conf,name);
index e4c7fd38d83e55c22b9bc910440ed744da1def46..913b46f8ecd3b4700646e6fbcc78a30fa06efefe 100644 (file)
@@ -487,22 +487,24 @@ static int raid5_error (mddev_t *mddev, kdev_t dev)
        PRINTK("raid5_error called\n");
 
        for (i = 0, disk = conf->disks; i < conf->raid_disks; i++, disk++) {
-               if (disk->dev == dev && disk->operational) {
-                       disk->operational = 0;
-                       mark_disk_faulty(sb->disks+disk->number);
-                       mark_disk_nonsync(sb->disks+disk->number);
-                       mark_disk_inactive(sb->disks+disk->number);
-                       sb->active_disks--;
-                       sb->working_disks--;
-                       sb->failed_disks++;
-                       mddev->sb_dirty = 1;
-                       conf->working_disks--;
-                       conf->failed_disks++;
-                       md_wakeup_thread(conf->thread);
-                       printk (KERN_ALERT
-                               "raid5: Disk failure on %s, disabling device."
-                               " Operation continuing on %d devices\n",
-                               partition_name (dev), conf->working_disks);
+               if (disk->dev == dev) {
+                       if (disk->operational) {
+                               disk->operational = 0;
+                               mark_disk_faulty(sb->disks+disk->number);
+                               mark_disk_nonsync(sb->disks+disk->number);
+                               mark_disk_inactive(sb->disks+disk->number);
+                               sb->active_disks--;
+                               sb->working_disks--;
+                               sb->failed_disks++;
+                               mddev->sb_dirty = 1;
+                               conf->working_disks--;
+                               conf->failed_disks++;
+                               md_wakeup_thread(conf->thread);
+                               printk (KERN_ALERT
+                                       "raid5: Disk failure on %s, disabling device."
+                                       " Operation continuing on %d devices\n",
+                                       partition_name (dev), conf->working_disks);
+                       }
                        return 0;
                }
        }
index 45d5b8de55ea54af1967656d114ce32ba42d6a8b..67677ae5b8cbb7089be868456ee1dac7be4cb219 100644 (file)
@@ -40,6 +40,8 @@
 
 /* fwd decl */
 static void hauppauge_eeprom(struct bttv *btv);
+static void avermedia_eeprom(struct bttv *btv);
+
 static void init_PXC200(struct bttv *btv);
 #if 0
 static void init_tea5757(struct bttv *btv);
@@ -52,6 +54,7 @@ static void avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v,
 static void terratv_audio(struct bttv *btv, struct video_audio *v, int set);
 static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set);
 static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set);
+static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
 
 /* config variables */
 static int triton1=0;
@@ -71,6 +74,10 @@ static unsigned int audiomux[5] = { -1, -1, -1, -1, -1 };
 
 /* insmod options */
 MODULE_PARM(triton1,"i");
+MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
+                "[enable bug compatibility for triton1 + others]");
+MODULE_PARM(vsfx,"i");
+MODULE_PARM_DESC(vsfx,"set VSFX pci config bit [yet another chipset flaw workaround]");
 MODULE_PARM(no_overlay,"i");
 MODULE_PARM(card,"1-4i");
 MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
@@ -83,7 +90,6 @@ MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default
 MODULE_PARM(gpiomask,"i");
 MODULE_PARM(audioall,"i");
 MODULE_PARM(audiomux,"1-5i");
-MODULE_LICENSE("GPL");
 
 /* kernel args */
 #ifndef MODULE
@@ -127,13 +133,18 @@ static struct CARD {
        { 0x6606107d, BTTV_WINFAST2000,   "Leadtek WinFast TV 2000" },
        { 0x263610b4, BTTV_STB2,          "STB TV PCI FM, P/N 6000704" },
        { 0x402010fc, BTTV_GVBCTV3PCI,    "I-O Data Co. GV-BCV3/PCI" },
-       { 0x405010fc, BTTV_GVBCTV3PCI,    "I-O Data Co. GV-BCV4/PCI" },
-       { 0x001211bd, BTTV_PINNACLE,      "Pinnacle PCTV" },
-       { 0x3000121a, 0/* no entry yet */,"VoodooTV 200" },
+       { 0x405010fc, BTTV_GVBCTV4PCI,    "I-O Data Co. GV-BCV4/PCI" },
 
-       { 0x3000144f, BTTV_MAGICTVIEW063, "TView 99 (CPH063)" },
-       { 0x3002144f, BTTV_MAGICTVIEW061, "Askey Magic TView" },
+       { 0x1200bd11, BTTV_PINNACLE,      "Pinnacle PCTV" },
+       { 0x001211bd, BTTV_PINNACLE,      "Pinnacle PCTV" },
+       { 0x001c11bd, BTTV_PINNACLE,      "Pinnacle PCTV Sat" },
 
+       { 0x3000121a, BTTV_VOODOOTV_FM,   "3Dfx VoodooTV FM/ VoodooTV 200" },
+       
+       { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
+       { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
+       { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
+       
        { 0x00011461, BTTV_AVPHONE98,     "AVerMedia TVPhone98" },
        { 0x00021461, BTTV_AVERMEDIA98,   "AVermedia TVCapture 98" },
        { 0x00031461, BTTV_AVPHONE98,     "AVerMedia TVPhone98" },
@@ -154,15 +165,15 @@ static struct CARD {
        { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
        { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
        { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
+       { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
 
        { 0x010115cb, BTTV_GMV1,          "AG GMV1" },
-       { 0x010114c7, 16 /* FIXME */,     "Modular Technology PCTV" },
-       { 0x18501851, BTTV_CHRONOS_VS2,   "Chronos Video Shuttle II" },
-       { 0x18511851, 0 /* FIXME */,      "CyberMail AV" },
-       { 0x18521852, BTTV_TYPHOON_TVIEW, "Typhoon TView TV/FM Tuner" },
+       { 0x010114c7, BTTV_MODTEC_205,    "Modular Technology PCTV" },
+       { 0x18501851, BTTV_CHRONOS_VS2,   "Flyvideo 98 (LR50)/ Chronos Video Shuttle II" },
+       { 0x18511851, BTTV_FLYVIDEO98EZ,  "Flyvideo 98EZ (LR51)/ CyberMail AV" },
+       { 0x18521852, BTTV_TYPHOON_TVIEW, "Flyvideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
        { 0x10b42636, BTTV_HAUPPAUGE878,  "STB ???" },
        { 0x217d6606, BTTV_WINFAST2000,   "Leadtek WinFast TV 2000" },
-       { 0x1200bd11, BTTV_PINNACLE,      "Pinnacle PCTV" },
 
        { 0, -1, NULL }
 };
@@ -173,7 +184,7 @@ static struct CARD {
 struct tvcard bttv_tvcards[] = {
 {
 /* ---- card 0x00 ---------------------------------- */
-       name:           " *** UNKNOWN *** ",
+       name:           " *** UNKNOWN/GENERIC *** ",
        video_inputs:   4,
        audio_inputs:   1,
        tuner:          0,
@@ -192,7 +203,7 @@ struct tvcard bttv_tvcards[] = {
        needs_tvaudio:  1,
        tuner_type:     -1,
 },{
-       name:           "Hauppauge old",
+       name:           "Hauppauge (bt848)",
        video_inputs:   4,
        audio_inputs:   1,
        tuner:          0,
@@ -265,7 +276,7 @@ struct tvcard bttv_tvcards[] = {
 },{
 
 /* ---- card 0x08 ---------------------------------- */
-       name:           "Fly Video II",
+       name:           "Fly Video II (Bt848)",
        video_inputs:   3,
        audio_inputs:   1,
        tuner:          0,
@@ -287,12 +298,12 @@ struct tvcard bttv_tvcards[] = {
        needs_tvaudio:  1,
        tuner_type:     -1,
 },{
-       name:           "Hauppauge new (bt878)",
+       name:           "Hauppauge (bt878)",
        video_inputs:   4,
        audio_inputs:   1,
        tuner:          0,
        svhs:           2,
-       gpiomask:       7,
+       gpiomask:       0x0f, /* old: 7 */
        muxsel:         { 2, 0, 1, 1},
        audiomux:       { 0, 1, 2, 3, 4},
        needs_tvaudio:  1,
@@ -333,7 +344,7 @@ struct tvcard bttv_tvcards[] = {
        audiomux:       { 13, 14, 11, 7, 0, 0},
        needs_tvaudio:  1,
        pll:            PLL_28,
-       tuner_type:     5,
+       tuner_type:     -1,
 },{
        name:           "Aimslab VHX",
        video_inputs:   3,
@@ -452,14 +463,14 @@ struct tvcard bttv_tvcards[] = {
 },{
 
 /* ---- card 0x18 ---------------------------------- */
-       name:           "Askey/Typhoon/Anubis Magic TView CPH051/061 (bt878)",
+       name:           "[many vendors] CPH05X/06X (bt878)",
        video_inputs:   3,
        audio_inputs:   1,
        tuner:          0,
        svhs:           2,
        gpiomask:       0xe00,
        muxsel:         { 2, 3, 1, 1},
-       audiomux:       {0x400, 0x400, 0x400, 0x400, 0},
+       audiomux:       {0x400, 0x400, 0x400, 0x400, 0xc00},
        needs_tvaudio:  1,
        pll:            PLL_28,
        tuner_type:     -1,
@@ -528,9 +539,9 @@ struct tvcard bttv_tvcards[] = {
        audio_inputs:   1,
        tuner:          0,
        svhs:           2,
-       gpiomask:       0x8dfe00,
+       gpiomask:       0x1800,  //0x8dfe00
        muxsel:         {2, 3, 1, 1},
-       audiomux:       { 0, 0x8dff00, 0x8df700, 0x8de700, 0x8dff00, 0 },
+       audiomux:       { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
        needs_tvaudio:  1,
        tuner_type:     -1,
 },{
@@ -582,31 +593,32 @@ struct tvcard bttv_tvcards[] = {
        tuner_type:     -1,
        audio_hook:     winfast2000_audio,
 },{
-       name:           "Chronos Video Shuttle II",
+       name:           "Flyvideo 98 (LR50Q) / Chronos Video Shuttle II",
        video_inputs:   3,
        audio_inputs:   3,
        tuner:          0,
        svhs:           2,
        gpiomask:       0x1800,
        muxsel:         { 2, 3, 1, 1},
-       audiomux:       { 0, 0, 0x1000, 0x1000, 0x0800},
+       audiomux:       { 0, 0x800, 0x1000, 0x1000, 0x1800},
        needs_tvaudio:  1,
        pll:            PLL_28,
        tuner_type:     -1,
 },{
 
 /* ---- card 0x24 ---------------------------------- */
-       name:           "Typhoon TView TV/FM Tuner",
+       name:           "Flyvideo 98FM (LR50Q) / Typhoon TView TV/FM Tuner",
        video_inputs:   3,
        audio_inputs:   3,
        tuner:          0,
        svhs:           2,
        gpiomask:       0x1800,
        muxsel:         { 2, 3, 1, 1},
-       audiomux:       { 0, 0x800, 00, 0x1800, 0 },
+       audiomux:       { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
        needs_tvaudio:  1,
        pll:            PLL_28,
        tuner_type:     -1,
+       has_radio:      1,
 },{
        name:           "PixelView PlayTV pro",
        video_inputs:   3,
@@ -620,14 +632,14 @@ struct tvcard bttv_tvcards[] = {
        pll:            PLL_28,
        tuner_type:     -1,
 },{
-       name:           "TView99 CPH063",
+       name:           "TView99 CPH06X",
        video_inputs:   4,
        audio_inputs:   1,
        tuner:          0,
        svhs:           2,
        gpiomask:       0x551e00,
        muxsel:         { 2, 3, 1, 0},
-       audiomux:       { 0x551400, 0x551200, 0, 0, 0, 0x551200 },
+       audiomux:       { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
        needs_tvaudio:  1,
        pll:            PLL_28,
        tuner_type:     -1,
@@ -668,7 +680,8 @@ struct tvcard bttv_tvcards[] = {
        audiomux:       { 13, 4, 11, 7, 0, 0},
        needs_tvaudio:  1,
        pll:            PLL_28,
-       tuner_type:     5,
+       tuner_type:     -1,
+       has_radio:      1,
 },{
        name:           "ProVideo PV951", /* pic16c54 */
        video_inputs:   3,
@@ -742,6 +755,7 @@ struct tvcard bttv_tvcards[] = {
        no_msp34xx:     1,
        pll:            PLL_35,
        tuner_type:     1,
+       has_radio:      1,
 },{
 
 /* ---- card 0x30 ---------------------------------- */
@@ -770,7 +784,7 @@ struct tvcard bttv_tvcards[] = {
        tuner_type:     TUNER_ALPS_TSHC6_NTSC,
        audio_hook:     gvbctv3pci_audio,
 },{
-       name:           "Prolink PV-BT878P+4E (PixelView PlayTV PAK)",
+       name:           "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
        video_inputs:   4,
        audio_inputs:   1,
        tuner:          0,
@@ -810,7 +824,7 @@ struct tvcard bttv_tvcards[] = {
 },{
        /* Claas Langbehn <claas@bigfoot.com>,
           Sven Grothklags <sven@upb.de> */
-       name:           "Typhoon TView RDS / FM Stereo",
+       name:           "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
        video_inputs:   3,
        audio_inputs:   3,
        tuner:          0,
@@ -821,13 +835,14 @@ struct tvcard bttv_tvcards[] = {
        needs_tvaudio:  1,
        pll:            PLL_28,
        tuner_type:     TUNER_PHILIPS_PAL_I,
+       has_radio:      1,
 },{
        /* Tim Röstermundt <rosterm@uni-muenster.de>
           in de.comp.os.unix.linux.hardware:
                options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
                audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
                options tuner type=5 */
-       name:           "Lifetec LT 9415 TV",
+       name:           "Lifetec LT 9415 TV (LR90 Rev.F)",
        video_inputs:   4,
        audio_inputs:   1,
        tuner:          0,
@@ -841,6 +856,7 @@ struct tvcard bttv_tvcards[] = {
        pll:            PLL_28,
        tuner_type:     TUNER_PHILIPS_PAL,
        audio_hook:     lt9415_audio,
+       has_radio:      1,
 },{
        /* Miguel Angel Alvarez <maacruz@navegalia.com>
           old Easy TV BT848 version (model CPH031) */
@@ -866,7 +882,7 @@ struct tvcard bttv_tvcards[] = {
        svhs:           2,
        gpiomask:       0x1800,
        muxsel:         { 2, 3, 0, 1},
-       audiomux:       { 0, 0x800, 00, 0x1800, 0 },
+       audiomux:       { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
        needs_tvaudio:  1,
        pll:            PLL_28,
        tuner_type:     5,
@@ -893,7 +909,7 @@ struct tvcard bttv_tvcards[] = {
         audio_inputs:   1,
         tuner:          0,
         svhs:           2,
-        gpiomask:       0x0e00,
+        gpiomask:       0xe00,
         muxsel:         { 2, 3, 1, 1},
         audiomux:       { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
         needs_tvaudio:  1,
@@ -1005,7 +1021,93 @@ struct tvcard bttv_tvcards[] = {
        needs_tvaudio:  1,
        pll:            PLL_28,
        tuner_type:     TUNER_PHILIPS_PAL,
-}};
+       has_radio:      1,
+},{
+       /* TANAKA Kei <peg00625@nifty.com> */
+       name:           "GV-BCTV4/PCI",
+       video_inputs:   3,
+       audio_inputs:   1,
+       tuner:          0,
+       svhs:           2,
+       gpiomask:       0x010f00,
+       muxsel:         {2, 3, 0, 0},
+       audiomux:       {0x10000, 0, 0x10000, 0, 0, 0},
+       no_msp34xx:     1,
+       pll:            PLL_28,
+       tuner_type:     TUNER_SHARP_2U5JF5540_NTSC,
+       audio_hook:     gvbctv3pci_audio,
+},{
+
+/* ---- card 0x44 ---------------------------------- */
+        name:           "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
+       // try "insmod msp3400 simple=0" if you have
+       // sound problems with this card.
+        video_inputs:   4,
+        audio_inputs:   1,
+        tuner:          0,
+        svhs:           -1,
+        gpiomask:       0x4f8a00,
+                       // 0x100000: 1=MSP enabled (0=disable again)
+                       // 0x010000: somehow influences tuner picture quality (?)
+        audiomux:       {0x947fff, 0x987fff,0x947fff,0x947fff},
+                        //tvtuner, radio,   external,internal,mute,stereo
+        muxsel:         { 2, 3 ,0 ,1}, /* tuner, Composit, SVid, Composit-on-Svid-adapter*/
+        tuner_type:     TUNER_MT2032,
+       pll:            PLL_28,
+       has_radio:      1,
+},{
+       /* Philip Blundell <pb@nexus.co.uk> */
+       name:           "Active Imaging AIMMS",
+       video_inputs:   1,
+       audio_inputs:   0,
+       tuner:          -1,
+       tuner_type:     -1,
+       pll:            PLL_28,
+       muxsel:         { 2 },
+       gpiomask:       0
+},{
+        /* Tomasz Pyra <hellfire@sedez.iq.pl> */
+        name:           "PV-BT878P+",
+        video_inputs:   3,
+        audio_inputs:   4,
+        tuner:          0,
+        svhs:           2,
+        gpiomask:       15,
+        muxsel:         { 2, 3, 1, 1},
+        audiomux:       { 0, 0, 11, 7, 13, 0},
+        needs_tvaudio:  1,
+        pll:            PLL_28,
+        tuner_type:     25,
+},{
+       name:           "Flyvideo 98EZ (capture only)",
+       video_inputs:   4,
+       audio_inputs:   0,
+       tuner:          -1,
+       svhs:           2,
+       muxsel:         { 2, 3, 1, 1}, // AV1, AV2, SVHS, CVid adapter on SVHS
+       pll:            PLL_28,
+       no_msp34xx:     1,
+},{
+
+/* ---- card 0x48 ---------------------------------- */
+       /* Dariusz Kowalewski <darekk@automex.pl> */
+       name:           "Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
+       video_inputs:   3,
+       audio_inputs:   1,
+       tuner:          0,
+       svhs:           2,
+       gpiomask:       0x3f,
+       muxsel:         { 2, 3, 0, 1 },
+       audiomux:       { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
+       needs_tvaudio:  1,
+       no_msp34xx:     1,
+       no_tda9875:     1,
+       pll:            PLL_28,
+       tuner_type:     -1,
+       audio_hook:     pvbt878p9b_audio,
+       has_radio:      1,
+}
+};
 
 const int bttv_num_tvcards = (sizeof(bttv_tvcards)/sizeof(struct tvcard));
 
@@ -1036,17 +1138,17 @@ void __devinit bttv_idcard(struct bttv *btv)
                
                if (type != -1) {
                        /* found it */
-                       printk(KERN_INFO "bttv%d: subsystem: %04x:%04x  =>  %s  =>  card=%d\n",
-                              btv->nr, btv->cardid & 0xffff, btv->cardid >> 16,
-                              cards[type].name,cards[type].cardnr);
+                       printk(KERN_INFO "bttv%d: detected: %s [card=%d], "
+                              "PCI subsystem ID is %04x:%04x\n",
+                              btv->nr,cards[type].name,cards[type].cardnr,
+                              btv->cardid & 0xffff, btv->cardid >> 16);
                        btv->type = cards[type].cardnr;
                } else {
                        /* 404 */
                        printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n",
                               btv->nr, btv->cardid&0xffff, btv->cardid>>16);
                        printk(KERN_DEBUG "please mail id, board name and "
-                              "the correct card= insmod option to "
-                              "kraxel@goldbach.in-berlin.de\n");
+                              "the correct card= insmod option to kraxel@bytesex.org\n");
                }
        }
 
@@ -1059,7 +1161,8 @@ void __devinit bttv_idcard(struct bttv *btv)
                btv->id,
                (btv->id==848 && btv->revision==0x12) ? "A" : "",
                bttv_tvcards[btv->type].name);
-       printk(KERN_INFO "bttv%d: model: %s [%s]\n",btv->nr,btv->video_dev.name,
+       printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->nr,
+              btv->video_dev.name,btv->type,
               (card[btv->nr] >= 0 && card[btv->nr] < bttv_num_tvcards) ?
               "insmod option" : "autodetected");
 
@@ -1128,7 +1231,8 @@ void __devinit bttv_init_card(struct bttv *btv)
                                btv->type = BTTV_PINNACLEPRO;
                }
                if (bttv_verbose)
-                       printk("bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
+                       printk(KERN_INFO "bttv%d: miro: id=%d tuner=%d "
+                              "radio=%s stereo=%s\n",
                               btv->nr, id+1, btv->tuner_type,
                               !btv->has_radio ? "no" :
                                   (btv->has_matchbox ? "matchbox" : "fmtuner"),
@@ -1148,6 +1252,11 @@ void __devinit bttv_init_card(struct bttv *btv)
                 hauppauge_eeprom(btv);
         }
 
+       if (btv->type == BTTV_AVERMEDIA98 || btv->type == BTTV_AVPHONE98) {
+               bttv_readee(btv,eeprom_data,0xa0);
+               avermedia_eeprom(btv);
+       }
+
        if (btv->type == BTTV_PXC200)
                init_PXC200(btv);
 
@@ -1166,7 +1275,13 @@ void __devinit bttv_init_card(struct bttv *btv)
                        printk("bttv%d: lifetec: tv mono/fm stereo card\n", btv->nr);
                else
                        printk("bttv%d: lifetec: stereo(TDA9821) card\n",btv->nr);
-               btv->has_radio=1;
+       }
+
+       if (btv->type == BTTV_MAGICTVIEW061) {
+               if(btv->cardid == 0x4002144f) {
+                       btv->has_radio=1;
+                       printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->nr);
+               }
        }
 
        /* pll configuration */
@@ -1210,6 +1325,9 @@ void __devinit bttv_init_card(struct bttv *btv)
        if (btv->tuner_type != -1)
                bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
 
+       if (bttv_tvcards[btv->type].has_radio)
+               btv->has_radio=1;
+
        /* try to detect audio/fader chips */
        if (!bttv_tvcards[btv->type].no_msp34xx &&
            bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx") >=0) {
@@ -1217,7 +1335,8 @@ void __devinit bttv_init_card(struct bttv *btv)
                        request_module("msp3400");
        }
 
-       if (bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) {
+       if (!bttv_tvcards[btv->type].no_tda9875 &&
+           bttv_I2CRead(btv, I2C_TDA9875, "TDA9875") >=0) {
                if (autoload)
                        request_module("tda9875");
        }
@@ -1307,7 +1426,8 @@ static void __devinit hauppauge_eeprom(struct bttv *btv)
        int blk2,tuner,radio,model;
 
        if (eeprom_data[0] != 0x84 || eeprom_data[2] != 0)
-               printk("bttv%d: Hauppauge eeprom: invalid\n",btv->nr);
+               printk(KERN_WARNING "bttv%d: Hauppauge eeprom: invalid\n",
+                      btv->nr);
 
        /* Block 2 starts after len+3 bytes header */
        blk2 = eeprom_data[1] + 3;
@@ -1323,24 +1443,83 @@ static void __devinit hauppauge_eeprom(struct bttv *btv)
                btv->has_radio = 1;
        
        if (bttv_verbose)
-               printk("bttv%d: Hauppauge eeprom: model=%d, tuner=%s (%d), radio=%s\n",
+               printk(KERN_INFO "bttv%d: Hauppauge eeprom: model=%d, "
+                      "tuner=%s (%d), radio=%s\n",
                       btv->nr, model, hauppauge_tuner[tuner].name,
                       btv->tuner_type, radio ? "yes" : "no");
 }
 
-void __devinit bttv_hauppauge_boot_msp34xx(struct bttv *btv)
+// AVermedia specific stuff...
+// from  bktr_card.c
+int tuner_0_table[] = {
+        TUNER_PHILIPS_NTSC,  TUNER_PHILIPS_PAL,
+        TUNER_PHILIPS_PAL,   TUNER_PHILIPS_PAL,
+        TUNER_PHILIPS_PAL,   TUNER_PHILIPS_PAL,
+        TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
+        TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL};
+/*
+int tuner_0_fm_table[] = {
+        PHILIPS_FR1236_NTSC,  PHILIPS_FR1216_PAL,
+        PHILIPS_FR1216_PAL,   PHILIPS_FR1216_PAL,
+        PHILIPS_FR1216_PAL,   PHILIPS_FR1216_PAL,
+        PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM,
+        PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
+*/
+
+int tuner_1_table[] = {
+        TUNER_TEMIC_NTSC,  TUNER_TEMIC_PAL,
+       TUNER_TEMIC_PAL,   TUNER_TEMIC_PAL,
+       TUNER_TEMIC_PAL,   TUNER_TEMIC_PAL,
+        TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, //TUNER_TEMIC_SECAM
+        TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
+
+static void __devinit avermedia_eeprom(struct bttv *btv)
+{
+        int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
+
+       tuner_make   = (eeprom_data[0x41] & 0x7);
+        tuner_tv_fm  = (eeprom_data[0x41] & 0x18) >> 3;
+        tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
+
+       if (tuner_make == 0 || tuner_make == 2)
+               if(tuner_format <=9)
+                       tuner = tuner_0_table[tuner_format];
+       if (tuner_make == 1)
+               if(tuner_format <=9)
+                       tuner = tuner_1_table[tuner_format];
+       
+       printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
+               btv->nr,eeprom_data[0x41],eeprom_data[0x42]);
+       if(tuner) {
+               btv->tuner_type=tuner;
+               printk("%d\n",tuner);
+       } else
+               printk("Unknown type\n");
+}
+
+
+
+/*
+ * reset/enable the MSP on some Hauppauge cards
+ * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
+ *
+ * Hauppauge:  pin  5
+ * Voodoo:     pin 20
+ */
+void __devinit bttv_boot_msp34xx(struct bttv *btv, int pin)
 {
-        /* reset/enable the MSP on some Hauppauge cards */
-        /* Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! */
-        btaor(32, ~32, BT848_GPIO_OUT_EN);
-        btaor(0, ~32, BT848_GPIO_DATA);
+       int mask = (1 << pin);
+
+        btaor(mask, ~mask, BT848_GPIO_OUT_EN);
+        btaor(0, ~mask, BT848_GPIO_DATA);
         udelay(2500);
-        btaor(32, ~32, BT848_GPIO_DATA);
+        btaor(mask, ~mask, BT848_GPIO_DATA);
        if (bttv_gpio)
                bttv_gpio_tracking(btv,"msp34xx");
 
        if (bttv_verbose)
-               printk("bttv%d: Hauppauge msp34xx: reset line init\n",btv->nr);
+               printk(KERN_INFO "bttv%d: Hauppauge/Voodoo msp34xx: reset line "
+                      "init [%d]\n", btv->nr, pin);
 }
 
 
@@ -1352,9 +1531,9 @@ void __devinit bttv_hauppauge_boot_msp34xx(struct bttv *btv)
 
 static void __devinit init_PXC200(struct bttv *btv)
 {
-       static const int vals[] = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
-                                   0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-                                   0x00 };
+       static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
+                                           0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+                                           0x00 };
        int i,tmp;
 
        /* Initialise GPIO-connevted stuff */
@@ -1465,7 +1644,7 @@ static int tea5757_read(struct bttv *btv)
            BUS_IN(btv->mbox_data) && time_before(jiffies, timeout);
            schedule());        /* 10 s */
        if (BUS_IN(btv->mbox_data)) {
-               printk("bttv%d: tea5757: read timeout\n",btv->nr);
+               printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->nr);
                return -1;
        }
        for(timeout = jiffies + HZ/5;
@@ -1706,6 +1885,43 @@ winfast2000_audio(struct bttv *btv, struct video_audio *v, int set)
        }
 }
 
+/*
+ * Dariusz Kowalewski <darekk@automex.pl>
+ * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
+ * revision 9B has on-board TDA9874A sound decoder).
+ */
+static void
+pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
+{
+       unsigned int val = 0;
+
+#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
+       if (btv->radio_user)
+               return;
+#else
+       if (btv->radio)
+               return;
+#endif
+
+       if (set) {
+               if (v->mode & VIDEO_SOUND_MONO) {
+                       val = 0x01;
+               }
+               if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
+                   || (v->mode & VIDEO_SOUND_STEREO)) {
+                       val = 0x02;
+               }
+               if (val) {
+                       btaor(val, ~0x03, BT848_GPIO_DATA);
+                       if (bttv_gpio)
+                               bttv_gpio_tracking(btv,"pvbt878p9b");
+               }
+       } else {
+               v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
+                         VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+       }
+}
+
 /* ----------------------------------------------------------------------- */
 /* motherboard chipset specific stuff                                      */
 
@@ -1717,13 +1933,16 @@ void __devinit bttv_check_chipset(void)
        /* for 2.4.x we'll use the pci quirks (drivers/pci/quirks.c) */
        if (pci_pci_problems & PCIPCI_FAIL)
                pcipci_fail = 1;
-
        if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
                triton1 = 1;
-       while ((dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, dev)))
+       if (pci_pci_problems & PCIPCI_VSFX)
                vsfx = 1;
 
-       /* print warnings about quirks found */
+       /* print which chipset we have */
+       while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
+               printk(KERN_INFO "bttv: Host bridge is %s\n",dev->name);
+
+       /* print warnings about any quirks found */
        if (triton1)
                printk(KERN_INFO "bttv: Host bridge needs ETBF enabled.\n");
        if (vsfx)
index 06f7e4d01375b194a1df7daf0c62256076f0792d..86b14cd87891b05d2696db77f258e870a0b934c7 100644 (file)
@@ -104,7 +104,7 @@ MODULE_PARM(radio_nr,"i");
 MODULE_PARM(vbi_nr,"i");
 
 MODULE_DESCRIPTION("bttv - v4l driver module for bt848/878 based cards");
-MODULE_AUTHOR("Ralph  Metzler & Marcus Metzler & Gerd Knorr");
+MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
 MODULE_LICENSE("GPL");
 
 /* kernel args */
@@ -209,9 +209,11 @@ static void * rvmalloc(signed long size)
        unsigned long adr, page;
 
        mem=vmalloc_32(size);
-       if (mem) 
-       {
-               memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+       if (NULL == mem)
+               printk(KERN_INFO "bttv: vmalloc_32(%ld) failed\n",size);
+       else {
+               /* Clear the ram out, no junk to the user */
+               memset(mem, 0, size);
                adr=(unsigned long) mem;
                while (size > 0) 
                 {
@@ -475,7 +477,13 @@ static struct tvnorm tvnorms[] = {
        /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
         { 35468950,
           924, 576, 1135, 0x7f, 0x72, (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
-          1135, 186, 924, 0x20, 255},
+          1135, 186, 924,
+#ifdef VIDEODAT_HACK
+         VBI_MAXLINES*2,
+#else
+         0x20,
+#endif
+         255},
 
        /* NTSC */
        { 28636363,
@@ -526,7 +534,7 @@ static void make_vbitab(struct bttv *btv)
                       btv->nr,virt_to_bus(po), virt_to_bus(pe));
         
        *(po++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(po++)=0;
-       for (i=0; i<16; i++) 
+       for (i=0; i<VBI_MAXLINES; i++) 
        {
                *(po++)=cpu_to_le32(VBI_RISC);
                *(po++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
@@ -535,7 +543,7 @@ static void make_vbitab(struct bttv *btv)
        *(po++)=cpu_to_le32(virt_to_bus(btv->risc_jmp+4));
 
        *(pe++)=cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); *(pe++)=0;
-       for (i=16; i<32; i++) 
+       for (i=VBI_MAXLINES; i<VBI_MAXLINES*2; i++) 
        {
                *(pe++)=cpu_to_le32(VBI_RISC);
                *(pe++)=cpu_to_le32(kvirt_to_bus((unsigned long)btv->vbibuf+i*2048));
@@ -553,23 +561,23 @@ static int fmtbppx2[16] = {
 };
 
 static int palette2fmt[] = {
-       0,
-       BT848_COLOR_FMT_Y8,
-       BT848_COLOR_FMT_RGB8,
-       BT848_COLOR_FMT_RGB16,
-       BT848_COLOR_FMT_RGB24,
-       BT848_COLOR_FMT_RGB32,
-       BT848_COLOR_FMT_RGB15,
-       BT848_COLOR_FMT_YUY2,
-       BT848_COLOR_FMT_BtYUV,
-       -1,
-       -1,
-       -1,
-       BT848_COLOR_FMT_RAW,
-       BT848_COLOR_FMT_YCrCb422,
-       BT848_COLOR_FMT_YCrCb411,
-       BT848_COLOR_FMT_YCrCb422,
-       BT848_COLOR_FMT_YCrCb411,
+       0,
+       BT848_COLOR_FMT_Y8,
+       BT848_COLOR_FMT_RGB8,
+       BT848_COLOR_FMT_RGB16,
+       BT848_COLOR_FMT_RGB24,
+       BT848_COLOR_FMT_RGB32,
+       BT848_COLOR_FMT_RGB15,
+       BT848_COLOR_FMT_YUY2,
+       BT848_COLOR_FMT_YUY2,
+       -1,
+       -1,
+       -1,
+       BT848_COLOR_FMT_RAW,
+       BT848_COLOR_FMT_YCrCb422,
+       BT848_COLOR_FMT_YCrCb411,
+       BT848_COLOR_FMT_YCrCb422,
+       BT848_COLOR_FMT_YCrCb411,
 };
 #define PALETTEFMT_MAX (sizeof(palette2fmt)/sizeof(int))
 
@@ -2626,7 +2634,9 @@ static int __devinit init_bt848(struct bttv *btv)
 
        /* needs to be done before i2c is registered */
         if (btv->type == BTTV_HAUPPAUGE || btv->type == BTTV_HAUPPAUGE878)
-                bttv_hauppauge_boot_msp34xx(btv);
+                bttv_boot_msp34xx(btv,5);
+       if (btv->type == BTTV_VOODOOTV_FM)
+               bttv_boot_msp34xx(btv,20);
 
        /* register i2c */
         btv->tuner_type=-1;
index 3e8d84ebf8f0e9854d493814741ae6849779af6e..3a1a4c04b2711b6e079d1c97f1441c4c1161ddcb 100644 (file)
@@ -209,7 +209,8 @@ static int attach_inform(struct i2c_client *client)
        if (btv->tuner_type != -1)
                bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
         if (bttv_verbose)
-               printk("bttv%d: i2c attach [%s]\n",btv->nr,client->name);
+               printk("bttv%d: i2c attach [client=%s,%s]\n",btv->nr,
+                      client->name, (i < I2C_CLIENTS_MAX) ?  "ok" : "failed");
         return 0;
 }
 
@@ -218,14 +219,15 @@ static int detach_inform(struct i2c_client *client)
         struct bttv *btv = (struct bttv*)client->adapter->data;
        int i;
 
-        if (bttv_verbose)
-               printk("bttv%d: i2c detach [%s]\n",btv->nr,client->name);
        for (i = 0; i < I2C_CLIENTS_MAX; i++) {
                if (btv->i2c_clients[i] == client) {
                        btv->i2c_clients[i] = NULL;
                        break;
                }
        }
+        if (bttv_verbose)
+               printk("bttv%d: i2c detach [client=%s,%s]\n",btv->nr,
+                      client->name, (i < I2C_CLIENTS_MAX) ?  "ok" : "failed");
         return 0;
 }
 
@@ -351,7 +353,6 @@ int __devinit init_bttv_i2c(struct bttv *btv)
        btv->i2c_rc = i2c_bit_add_bus(&btv->i2c_adap);
        return btv->i2c_rc;
 }
-MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
index 513c855a45b9cee0278ebb0004d893004a378187..ce3dc51db593846e9324ebdb5f61e5919e66c5ac 100644 (file)
 #define BTTV_ATI_TVWONDERVE 0x40
 #define BTTV_FLYVIDEO2000   0x41
 #define BTTV_TERRATVALUER   0x42
+#define BTTV_GVBCTV4PCI     0x43
+#define BTTV_VOODOOTV_FM    0x44
+#define BTTV_AIMMS          0x45
+#define BTTV_PV_BT878P_PLUS 0x46
+#define BTTV_FLYVIDEO98EZ   0x47
+#define BTTV_PV_BT878P_9B   0x48
+
 
 /* i2c address list */
 #define I2C_TSA5522        0xc2
@@ -88,6 +95,7 @@
 #define I2C_TDA8425        0x82
 #define I2C_TDA9840        0x84
 #define I2C_TDA9850        0xb6 /* also used by 9855,9873 */
+#define I2C_TDA9874A       0xb0 /* also used by 9875 */
 #define I2C_TDA9875        0xb0
 #define I2C_HAUPEE         0xa0
 #define I2C_STBEE          0xae
@@ -121,6 +129,7 @@ struct tvcard
 
        /* i2c audio flags */
        int no_msp34xx:1;
+       int no_tda9875:1;
        int needs_tvaudio:1;
 
        /* other settings */
@@ -130,6 +139,7 @@ struct tvcard
 #define PLL_35   2
 
        int tuner_type;
+       int has_radio;
        void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
 };
 
@@ -142,7 +152,7 @@ extern void bttv_init_card(struct bttv *btv);
 
 /* card-specific funtions */
 extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void bttv_hauppauge_boot_msp34xx(struct bttv *btv);
+extern void bttv_boot_msp34xx(struct bttv *btv, int pin);
 
 /* kernel cmd line parse helper */
 extern int bttv_parse(char *str, int max, int *vals);
@@ -195,7 +205,7 @@ extern int bttv_write_gpio(unsigned int card,
 extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
 
 /* i2c */
-#define I2C_CLIENTS_MAX 8
+#define I2C_CLIENTS_MAX 16
 extern void bttv_bit_setscl(void *data, int state);
 extern void bttv_bit_setsda(void *data, int state);
 extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
@@ -205,3 +215,8 @@ extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
 extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
 
 #endif /* _BTTV_H_ */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
index 5dd21de8a642b5ae36513d3dce1d1f3afbcb1231..15745818877ad206da78ef4b7ceea19ceb55150a 100644 (file)
@@ -25,7 +25,7 @@
 #ifndef _BTTVP_H_
 #define _BTTVP_H_
 
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,72)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,83)
 
 
 #include <linux/types.h>
@@ -62,10 +62,14 @@ extern struct bttv bttvs[BTTV_MAX];
 #define O_NONCAP       O_TRUNC
 #endif
 
+#ifdef VIDEODAT_HACK
+# define VBI_MAXLINES   19
+#else
+# define VBI_MAXLINES   16
+#endif
+#define VBIBUF_SIZE     (2048*VBI_MAXLINES*2)
 #define MAX_GBUFFERS   64
 #define RISCMEM_LEN    (32744*2)
-#define VBI_MAXLINES    16
-#define VBIBUF_SIZE     (2048*VBI_MAXLINES*2)
 
 #define BTTV_MAX_FBUF  0x208000
 
index d1f99ee062417022523df27edd1a877aead094a1..0c9acfc41c63557994a681a1c820858d4bdffc07 100644 (file)
@@ -24,3 +24,6 @@
 #ifndef  I2C_DRIVERID_TDA7432
 # define I2C_DRIVERID_TDA7432 I2C_DRIVERID_EXP0+6
 #endif
+#ifndef  I2C_DRIVERID_TDA9874A
+# define I2C_DRIVERID_TDA9874A I2C_DRIVERID_EXP0+7
+#endif
index 25b95895e804dfdb8338d99ad18c0797c326e3aa..ef24cd617da06caf9640c82fdb98dc331dac34ee 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * programming the msp34* sound processor family
  *
- * (c) 1997-2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
  *
  * what works and what doesn't:
  *
@@ -97,7 +97,6 @@ struct msp3400c {
        int nicam_on;
        int acb;
        int main, second;       /* sound carrier */
-       int scart;              /* input is scart (extern) */
 
        int muted;
        int left, right;        /* volume */
@@ -131,8 +130,10 @@ MODULE_PARM(debug,"i");
 MODULE_PARM(simple,"i");
 MODULE_PARM(amsound,"i");
 MODULE_PARM(dolby,"i");
-MODULE_LICENSE("GPL");
 
+MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
 
 /* ---------------------------------------------------------------------- */
 
@@ -231,6 +232,7 @@ msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
 #define MSP_MODE_FM_NICAM2   6
 #define MSP_MODE_AM_NICAM    7
 #define MSP_MODE_BTSC        8
+#define MSP_MODE_EXTERN      9
 
 static struct MSP_INIT_DATA_DEM {
        int fir1[6];
@@ -443,6 +445,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
                               msp_init_data[type].dfp_src);
                msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
                               msp_init_data[type].dfp_src);
+               msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
+                              msp_init_data[type].dfp_src);
        }
        msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
                       msp_init_data[type].dfp_src);
@@ -507,6 +511,13 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode)
                dprintk("msp3400: BTSC setstereo: %d\n",mode);
                nicam=0x0300;
                break;
+       case MSP_MODE_EXTERN:
+               dprintk("msp3400: extern setstereo: %d\n", mode);
+               nicam = 0x0200;
+               break;
+       case MSP_MODE_FM_RADIO:
+               dprintk("msp3400: FM-Radio setstereo: %d\n", mode);
+               break;
        default:
                dprintk("msp3400: mono setstereo\n");
                return;
@@ -537,8 +548,8 @@ static void msp3400c_setstereo(struct i2c_client *client, int mode)
                src = 0x0010 | nicam;
                break;
        }
-       if (msp->scart)
-               src |= 0x0200;
+       dprintk("msp3400: setstereo final source/matrix = 0x%x\n", src);
+
        if (dolby) {
                msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
                msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
@@ -727,14 +738,14 @@ static int msp3400c_thread(void *data)
 {
        struct i2c_client *client = data;
        struct msp3400c *msp = client->data;
-    
+       
        struct CARRIER_DETECT *cd;
-       int                   count, max1,max2,val1,val2, val,this;
-    
+       int count, max1,max2,val1,val2, val,this;
+       
 #ifdef CONFIG_SMP
        lock_kernel();
 #endif
-    
+       
        daemonize();
        sigfillset(&current->blocked);
        strcpy(current->comm,"msp3400");
@@ -748,7 +759,7 @@ static int msp3400c_thread(void *data)
        printk("msp3400: daemon started\n");
        if(msp->notify != NULL)
                up(msp->notify);
-               
+
        for (;;) {
                if (msp->rmmod)
                        goto done;
@@ -760,9 +771,8 @@ static int msp3400c_thread(void *data)
                if (msp->rmmod || signal_pending(current))
                        goto done;
 
-               if (VIDEO_MODE_RADIO == msp->norm)
-                       continue;  /* nothing to do */
-               if (msp->scart)
+               if (VIDEO_MODE_RADIO == msp->norm ||
+                   MSP_MODE_EXTERN  == msp->mode)
                        continue;  /* nothing to do */
        
                msp->active = 1;
@@ -780,10 +790,9 @@ static int msp3400c_thread(void *data)
                        goto done;
                
        restart:
-               if (msp->scart)
-                       continue;
-               if (VIDEO_MODE_RADIO == msp->norm)
-                       continue;
+               if (VIDEO_MODE_RADIO == msp->norm ||
+                   MSP_MODE_EXTERN  == msp->mode)
+                       continue;  /* nothing to do */
                msp->restart = 0;
                msp3400c_setvolume(client, msp->muted, 0, 0);
                msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
@@ -1018,7 +1027,7 @@ static int msp3410d_thread(void *data)
                if (msp->rmmod || signal_pending(current))
                        goto done;
 
-               if (msp->scart)
+               if (msp->mode == MSP_MODE_EXTERN)
                        continue;
                
                msp->active = 1;
@@ -1036,7 +1045,7 @@ static int msp3410d_thread(void *data)
                        goto done;
 
        restart:
-               if (msp->scart)
+               if (msp->mode == MSP_MODE_EXTERN)
                        continue;
                msp->restart = 0;
                del_timer(&msp->wake_stereo);
@@ -1159,6 +1168,8 @@ static int msp3410d_thread(void *data)
                        /* scart routing */
                        msp3400c_set_scart(client,SCART_IN2,0);
                        msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
+                       msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
+                       msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
                        break;
                case 0x0003:
                        msp->mode   = MSP_MODE_FM_TERRA;
@@ -1353,7 +1364,19 @@ static int msp_probe(struct i2c_adapter *adap)
        return 0;
 }
 
-static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
+static void msp_wake_thread(struct i2c_client *client)
+{
+       struct msp3400c *msp  = (struct msp3400c*)client->data;
+
+       msp3400c_setvolume(client,msp->muted,0,0);
+       msp->watch_stereo=0;
+       del_timer(&msp->wake_stereo);
+       if (msp->active)
+               msp->restart = 1;
+       wake_up_interruptible(&msp->wq);
+}
+
+static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
        struct msp3400c *msp  = (struct msp3400c*)client->data;
         __u16           *sarg = arg;
@@ -1368,21 +1391,24 @@ static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
                     - IN1 is often used for external input
                     - Hauppauge uses IN2 for the radio */
                dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg);
-               msp->scart = 0;
                switch (*sarg) {
                case AUDIO_RADIO:
+                       msp->mode   = MSP_MODE_FM_RADIO;
+                       msp->stereo = VIDEO_SOUND_STEREO;
                        msp3400c_set_scart(client,SCART_IN2,0);
                        msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
                        msp3400c_setstereo(client,msp->stereo);
                        break;
                case AUDIO_EXTERN:
-                       msp->scart = 1;
+                       msp->mode   = MSP_MODE_EXTERN;
+                       msp->stereo = VIDEO_SOUND_STEREO;
                        msp3400c_set_scart(client,SCART_IN1,0);
                        msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
                        msp3400c_setstereo(client,msp->stereo);
                        break;
                case AUDIO_TUNER:
-                       msp3400c_setstereo(client,msp->stereo);
+                       msp->mode   = -1;
+                       msp_wake_thread(client);
                        break;
                default:
                        if (*sarg & AUDIO_MUTE)
@@ -1400,8 +1426,7 @@ static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
                dprintk("msp34xx: switching to radio mode\n");
                if (msp->simple) {
                        /* the thread will do for us */
-                       msp3400c_setvolume(client,msp->muted,0,0);
-                       wake_up_interruptible(&msp->wq);
+                       msp_wake_thread(client);
                } else {
                        /* set msp3400 to FM radio mode */
                        msp3400c_setmode(client,MSP_MODE_FM_RADIO);
@@ -1457,6 +1482,8 @@ static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
                        (va->volume ? va->volume : 1);
                va->balance=(msp->left<msp->right)?
                        (65535-va->balance) : va->balance;
+               if (0 == va->volume)
+                       va->balance = 32768;
                va->bass = msp->bass;
                va->treble = msp->treble;
 
@@ -1500,12 +1527,7 @@ static int msp_command(struct i2c_client *client,unsigned int cmd, void *arg)
        case VIDIOCSFREQ:
        {
                /* new channel -- kick audio carrier scan */
-               msp3400c_setvolume(client,msp->muted,0,0);
-               msp->watch_stereo=0;
-               del_timer(&msp->wake_stereo);
-               if (msp->active)
-                       msp->restart = 1;
-               wake_up_interruptible(&msp->wq);
+               msp_wake_thread(client);
                break;
        }
 
index dc5a5e35cc827638243b374ca0bd53f45b472f06..2a5581ed051b8503f7862c1430292992e7bef957 100644 (file)
@@ -52,7 +52,6 @@ MODULE_AUTHOR("Eric Sandeen <eric_sandeen@bigfoot.com>");
 MODULE_DESCRIPTION("bttv driver for the tda7432 audio processor chip");
 MODULE_LICENSE("GPL");
 
-
 MODULE_PARM(debug,"i");
 MODULE_PARM(loudness,"i");
 static int loudness = 0; /* disable loudness by default */
index e9dcdac77a5b6f78b80e7ef90451647956d72b8a..92503bdf97a889a950a40849b23abcf8f911d4f4 100644 (file)
@@ -36,7 +36,6 @@
 MODULE_PARM(debug,"i");
 MODULE_LICENSE("GPL");
 
-
 static int debug = 0;  /* insmod parameter */
 
 /* Addresses to scan */
index 4bd6f17b574d3500f90f7edcbda94cea2f37a7df..d3b1237d5558faa8571a2c968e2e23b4f189c089 100644 (file)
@@ -30,25 +30,29 @@ static struct i2c_client_address_data addr_data = {
        force
 };
 
-static int debug =  0; /* insmod parameter */
-static int type  = -1; /* insmod parameter */
-
+/* insmod options */
+static int debug =  0;
+static int type  = -1;
 static int addr  =  0;
 static char *pal =  "b";
-static int this_adap;
 static int tv_range[2]    = { 44, 958 };
 static int radio_range[2] = { 65, 108 };
-
-#define dprintk     if (debug) printk
-
 MODULE_PARM(debug,"i");
 MODULE_PARM(type,"i");
 MODULE_PARM(addr,"i");
 MODULE_PARM(tv_range,"2i");
 MODULE_PARM(radio_range,"2i");
 MODULE_PARM(pal,"s");
+
+#define optimize_vco 1
+
+MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
+MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
 MODULE_LICENSE("GPL");
 
+static int this_adap;
+#define dprintk     if (debug) printk
+
 struct tuner
 {
        int type;            /* chip type */
@@ -56,12 +60,15 @@ struct tuner
        int std;
 
        int radio;
-       int mode;            /* PAL(0)/SECAM(1) mode (PHILIPS_SECAM only) */
+       int mode;            /* current norm for multi-norm tuners */
+       int xogc;            // only for MT2032
 };
 
 static struct i2c_driver driver;
 static struct i2c_client client_template;
 
+/* ---------------------------------------------------------------------- */
+
 /* tv standard selection for Temic 4046 FM5
    this value takes the low bits of control byte 2
    from datasheet Rev.01, Feb.00 
@@ -154,13 +161,13 @@ static struct tunertype tuners[] = {
          16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
         { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
          16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
-       { "Temic PAL_I (4006FH5)", TEMIC, PAL_I,
+       { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
          16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 
        { "Alps TSCH6",Alps,NTSC,
          16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
 
        { "Temic PAL_DK (4016 FY5)",TEMIC,PAL,
-         16*136.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
+         16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
        { "Philips NTSC_M (MK2)",Philips,NTSC,
          16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
         { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
@@ -191,7 +198,24 @@ static struct tunertype tuners[] = {
        { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
          16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
        { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
-         16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}
+         16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
+       { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
+         16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940},
+
+       { "Samsung PAL TCPM9091PD27", Samsung, PAL,  /* from sourceforge v3tv */
+          16*169,16*464,0xA0,0x90,0x30,0x8e,623},
+       { "MT2032 universal", Microtune,PAL|NTSC,
+               0,0,0,0,0,0,0},
+       { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
+          16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
+       { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
+          16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
+
+       { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
+          16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
+        { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
+          16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
+       
 };
 #define TUNERS (sizeof(tuners)/sizeof(struct tunertype))
 
@@ -201,6 +225,11 @@ static int tuner_getstatus(struct i2c_client *c)
 {
        unsigned char byte;
 
+       struct tuner *t = (struct tuner*)c->data;
+
+        if (t->type == TUNER_MT2032)
+               return 0;
+
        if (1 != i2c_master_recv(c,&byte,1))
                return 0;
        return byte;
@@ -241,6 +270,315 @@ static int tuner_mode (struct i2c_client *c)
         return (tuner_getstatus (c) & TUNER_MODE) >> 3;
 }
 #endif
+// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
+int mt2032_init(struct i2c_client *c)
+{
+        unsigned char buf[21];
+        int ret,xogc,xok=0;
+       struct tuner *t = (struct tuner*)c->data;
+
+        buf[0]=0;
+        ret=i2c_master_send(c,buf,1);
+        i2c_master_recv(c,buf,21);
+
+        printk("MT2032: Companycode=%02x%02x Part=%02x Revision=%02x\n",
+                buf[0x11],buf[0x12],buf[0x13],buf[0x14]);
+
+        if(debug) {
+                int i;
+                printk("MT2032 hexdump:\n");
+                for(i=0;i<21;i++) {
+                        printk(" %02x",buf[i]);
+                        if(((i+1)%8)==0) printk(" ");
+                        if(((i+1)%16)==0) printk("\n ");
+                }
+                printk("\n ");
+        }
+
+        // Initialize Registers per spec.
+        buf[1]=2; // Index to register 2
+        buf[2]=0xff;
+        buf[3]=0x0f;
+        buf[4]=0x1f;
+        ret=i2c_master_send(c,buf+1,4);
+
+        buf[5]=6; // Index register 6
+        buf[6]=0xe4;
+        buf[7]=0x8f;
+        buf[8]=0xc3;
+        buf[9]=0x4e;
+        buf[10]=0xec;
+        ret=i2c_master_send(c,buf+5,6);
+
+        buf[12]=13;  // Index register 13
+        buf[13]=0x32;
+        ret=i2c_master_send(c,buf+12,2);
+
+        // Adjust XOGC (register 7), wait for XOK
+        xogc=7;
+        do {
+               dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
+                mdelay(10);
+                buf[0]=0x0e;
+                i2c_master_send(c,buf,1);
+                i2c_master_recv(c,buf,1);
+                xok=buf[0]&0x01;
+                dprintk("mt2032: xok = 0x%02x\n",xok);
+                if (xok == 1) break;
+
+                xogc--;
+                dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
+                if (xogc == 3) {
+                        xogc=4; // min. 4 per spec
+                        break;
+                }
+                buf[0]=0x07;
+                buf[1]=0x88 + xogc;
+                ret=i2c_master_send(c,buf,2);
+                if (ret!=2)
+                        printk("mt2032_init failed with %d\n",ret);
+        } while (xok != 1 );
+       t->xogc=xogc;
+
+        return(1);
+}
+
+
+// IsSpurInBand()?
+int mt2032_spurcheck(int f1, int f2, int spectrum_from,int spectrum_to)
+{
+       int n1=1,n2,f;
+
+       f1=f1/1000; //scale to kHz to avoid 32bit overflows
+       f2=f2/1000;
+       spectrum_from/=1000;
+       spectrum_to/=1000;
+
+       dprintk("spurcheck f1=%d f2=%d  from=%d to=%d\n",f1,f2,spectrum_from,spectrum_to);
+
+       do {
+           n2=-n1;
+           f=n1*(f1-f2);
+           do {
+               n2--;
+               f=f-f2;
+               dprintk(" spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
+
+               if( (f>spectrum_from) && (f<spectrum_to))
+                       printk("mt2032 spurcheck triggered: %d\n",n1);
+           } while ( (f>(f2-spectrum_to)) || (n2>-5));
+           n1++;
+       } while (n1<5);
+
+       return 1;
+}
+
+int mt2032_compute_freq(int rfin, int if1, int if2, int spectrum_from,
+       int spectrum_to, unsigned char *buf, int *ret_sel, int xogc) //all in Hz
+{
+        int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
+               desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
+
+        fref= 5250 *1000; //5.25MHz
+       desired_lo1=rfin+if1;
+
+       lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
+        lo1n=lo1/8;
+        lo1a=lo1-(lo1n*8);
+
+        s=rfin/1000/1000+1090;
+
+       if(optimize_vco) {
+               if(s>1890) sel=0;
+               else if(s>1720) sel=1;
+               else if(s>1530) sel=2;
+               else if(s>1370) sel=3;
+               else sel=4; // >1090
+       }
+       else {
+               if(s>1790) sel=0; // <1958
+               else if(s>1617) sel=1;
+               else if(s>1449) sel=2;
+               else if(s>1291) sel=3;
+               else sel=4; // >1090
+       }
+       *ret_sel=sel;
+
+        lo1freq=(lo1a+8*lo1n)*fref;
+
+        dprintk("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
+               rfin,lo1,lo1n,lo1a,sel,lo1freq);
+
+        desired_lo2=lo1freq-rfin-if2;
+        lo2=(desired_lo2)/fref;
+        lo2n=lo2/8;
+        lo2a=lo2-(lo2n*8);
+        lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
+        lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
+
+        dprintk("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
+               rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
+
+        if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
+                printk("mt2032: frequency parameters out of range: %d %d %d %d\n",
+                      lo1a, lo1n, lo2a,lo2n);
+                return(-1);
+        }
+
+       mt2032_spurcheck(lo1freq, desired_lo2,  spectrum_from, spectrum_to);
+       // should recalculate lo1 (one step up/down)
+
+       // set up MT2032 register map for transfer over i2c
+       buf[0]=lo1n-1;
+       buf[1]=lo1a | (sel<<4);
+       buf[2]=0x86; // LOGC
+       buf[3]=0x0f; //reserved
+       buf[4]=0x1f;
+       buf[5]=(lo2n-1) | (lo2a<<5);
+       if(rfin >400*1000*1000)
+                buf[6]=0xe4;
+        else
+                buf[6]=0xf4; // set PKEN per rev 1.2 
+       buf[7]=8+xogc;
+       buf[8]=0xc3; //reserved
+       buf[9]=0x4e; //reserved
+       buf[10]=0xec; //reserved
+       buf[11]=(lo2num&0xff);
+       buf[12]=(lo2num>>8) |0x80; // Lo2RST
+
+       return 0;
+}
+
+int mt2032_check_lo_lock(struct i2c_client *c)
+{
+       int try,lock=0;
+       unsigned char buf[2];
+       for(try=0;try<10;try++) {
+               buf[0]=0x0e;
+               i2c_master_send(c,buf,1);
+               i2c_master_recv(c,buf,1);
+               dprintk("mt2032 Reg.E=0x%02x\n",buf[0]);
+               lock=buf[0] &0x06;
+               
+               if (lock==6)
+                       break;
+               
+               dprintk("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
+               udelay(1000);
+       }
+        return lock;
+}
+
+int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
+{
+       unsigned char buf[2];
+       int tad1;
+
+       buf[0]=0x0f;
+       i2c_master_send(c,buf,1);
+       i2c_master_recv(c,buf,1);
+       dprintk("mt2032 Reg.F=0x%02x\n",buf[0]);
+       tad1=buf[0]&0x07;
+
+       if(tad1 ==0) return lock;
+       if(tad1 ==1) return lock;
+
+       if(tad1==2) {
+               if(sel==0) 
+                       return lock;
+               else sel--;
+       }
+       else {
+               if(sel<4)
+                       sel++;
+               else
+                       return lock;
+       }
+
+       dprintk("mt2032 optimize_vco: sel=%d\n",sel);
+
+       buf[0]=0x0f;
+       buf[1]=sel;
+        i2c_master_send(c,buf,2);
+       lock=mt2032_check_lo_lock(c);
+       return lock;
+}
+
+
+void mt2032_set_if_freq(struct i2c_client *c,int rfin, int if1, int if2, int from, int to)
+{
+       unsigned char buf[21];
+       int lint_try,ret,sel,lock=0;
+       struct tuner *t = (struct tuner*)c->data;
+
+       dprintk("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",rfin,if1,if2,from,to);
+
+        buf[0]=0;
+        ret=i2c_master_send(c,buf,1);
+        i2c_master_recv(c,buf,21);
+
+       buf[0]=0;
+       ret=mt2032_compute_freq(rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
+       if (ret<0)
+               return;
+
+        // send only the relevant registers per Rev. 1.2
+        buf[0]=0;
+        ret=i2c_master_send(c,buf,4);
+        buf[5]=5;
+        ret=i2c_master_send(c,buf+5,4);
+        buf[11]=11;
+        ret=i2c_master_send(c,buf+11,3);
+        if(ret!=3)
+                printk("mt2032_set_if_freq failed with %d\n",ret);
+
+       // wait for PLLs to lock (per manual), retry LINT if not.
+       for(lint_try=0; lint_try<2; lint_try++) {
+               lock=mt2032_check_lo_lock(c);
+               
+               if(optimize_vco)
+                       lock=mt2032_optimize_vco(c,sel,lock);
+               if(lock==6) break;
+               
+               printk("mt2032: re-init PLLs by LINT\n"); 
+               buf[0]=7; 
+               buf[1]=0x80 +8+t->xogc; // set LINT to re-init PLLs
+               i2c_master_send(c,buf,2);
+               mdelay(10);
+               buf[1]=8+t->xogc;
+               i2c_master_send(c,buf,2);
+        }
+
+       if (lock!=6)
+               printk("MT2032 Fatal Error: PLLs didn't lock.\n");
+
+       buf[0]=2;
+       buf[1]=0x20; // LOGC for optimal phase noise
+       ret=i2c_master_send(c,buf,2);
+       if (ret!=2)
+               printk("mt2032_set_if_freq2 failed with %d\n",ret);
+}
+
+
+void mt2032_set_tv_freq(struct i2c_client *c, int freq, int norm)
+{
+       int if2,from,to;
+
+       // signal bandwidth and picture carrier
+       if(norm==VIDEO_MODE_NTSC) {
+               from=40750*1000;
+               to=46750*1000;
+               if2=45750*1000; 
+       }
+       else {  // Pal 
+               from=32900*1000;
+               to=39900*1000;
+               if2=38900*1000;
+       }
+
+        mt2032_set_if_freq(c,freq* 1000*1000/16, 1090*1000*1000, if2, from, to);
+}
+
 
 // Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz
 static void set_tv_freq(struct i2c_client *c, int freq)
@@ -252,6 +590,15 @@ static void set_tv_freq(struct i2c_client *c, int freq)
         unsigned char buffer[4];
        int rc;
 
+       if (t->type == -1) {
+               printk("tuner: tuner type not set\n");
+               return;
+       }
+       if (t->type == TUNER_MT2032) {
+               mt2032_set_tv_freq(c,freq,t->mode);
+               return;
+       }
+
        if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
                /* FIXME: better do that chip-specific, but
                   right now we don't have that in the config
@@ -259,10 +606,6 @@ static void set_tv_freq(struct i2c_client *c, int freq)
                   check at all */
                printk("tuner: TV freq (%d.%02d) out of range (%d-%d)\n",
                       freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
-       }
-
-       if (t->type == -1) {
-               printk("tuner: tuner type not set\n");
                return;
        }
 
@@ -282,7 +625,7 @@ static void set_tv_freq(struct i2c_client *c, int freq)
                /* 0x02 -> PAL BDGHI / SECAM L */
                /* 0x04 -> ??? PAL others / SECAM others ??? */
                config &= ~0x02;
-               if (t->mode)
+               if (t->mode == VIDEO_MODE_SECAM)
                        config |= 0x02;
                break;
 
@@ -366,6 +709,15 @@ static void set_tv_freq(struct i2c_client *c, int freq)
 
 }
 
+static void mt2032_set_radio_freq(struct i2c_client *c,int freq)
+{               
+        int if2;
+
+        if2=10700*1000; //  10.7MHz FM intermediate frequency
+
+        mt2032_set_if_freq(c,freq* 1000*1000/16, 1085*1000*1000,if2,if2,if2);
+}
+
 static void set_radio_freq(struct i2c_client *c, int freq)
 {
        u8 config;
@@ -386,6 +738,11 @@ static void set_radio_freq(struct i2c_client *c, int freq)
                return;
        }
 
+        if (t->type == TUNER_MT2032) {
+                mt2032_set_radio_freq(c,freq);
+               return;
+       }
+
        tun=&tuners[t->type];
        config = 0xa4 /* 0xa5 */; /* bit 0 is AFC (set) vs. RF-Signal (clear) */
        div=freq + (int)(16*10.7);
@@ -448,6 +805,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr,
                t->type = -1;
        }
         i2c_attach_client(client);
+        if (t->type == TUNER_MT2032)
+                 mt2032_init(client);
+
        MOD_INC_USE_COUNT;
 
        return 0;
@@ -497,6 +857,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                dprintk("tuner: type set to %d (%s)\n",
                         t->type,tuners[t->type].name);
                strncpy(client->name, tuners[t->type].name, sizeof(client->name));
+               if (t->type == TUNER_MT2032)
+                        mt2032_init(client);
                break;
        case AUDC_SET_RADIO:
                t->radio = 1;
@@ -508,12 +870,11 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
        case VIDIOCSCHAN:
        {
                struct video_channel *vc = arg;
-               
+
                t->radio = 0;
-               if (t->type == TUNER_PHILIPS_SECAM) {
-                       t->mode = (vc->norm == VIDEO_MODE_SECAM) ? 1 : 0;
+               t->mode = vc->norm;
+               if (t->freq)
                        set_tv_freq(client,t->freq);
-               }
                return 0;
        }
        case VIDIOCSFREQ:
index 591ae3e7bc20e0f78a5bf551aeac75b981b1e7d2..11539174b262e04712db4f79343b35a985eb616a 100644 (file)
 #ifndef _TUNER_H
 #define _TUNER_H
 
-#define TUNER_TEMIC_PAL     0        /* 4002 FH5_9483 */
+#define TUNER_TEMIC_PAL     0        /* 4002 FH5 (3X 7756, 9483) */
 #define TUNER_PHILIPS_PAL_I 1
 #define TUNER_PHILIPS_NTSC  2
 #define TUNER_PHILIPS_SECAM 3          /* you must actively select B/G, L, L` */
 #define TUNER_ABSENT        4
 #define TUNER_PHILIPS_PAL   5
-#define TUNER_TEMIC_NTSC    6        /* 4032 FY5_7004 */
-#define TUNER_TEMIC_PAL_I   7        /* 4062 FY5_9957 */
-#define TUNER_TEMIC_4036FY5_NTSC 8   /* 4036 FY5      */
+#define TUNER_TEMIC_NTSC    6        /* 4032 FY5 (3X 7004, 9498, 9789)  */
+#define TUNER_TEMIC_PAL_I   7        /* 4062 FY5 (3X 8501, 9957)        */
+#define TUNER_TEMIC_4036FY5_NTSC 8   /* 4036 FY5 (3X 1223, 1981, 7686)  */
 #define TUNER_ALPS_TSBH1_NTSC   9
 #define TUNER_ALPS_TSBE1_PAL   10
 #define TUNER_ALPS_TSBB5_PAL_I         11
 #define TUNER_ALPS_TSBE5_PAL   12
 #define TUNER_ALPS_TSBC5_PAL   13
-#define TUNER_TEMIC_4006FH5_PAL        14   /* 4006 FH5      */
+#define TUNER_TEMIC_4006FH5_PAL        14   /* 4006 FH5 (3X 9500, 9501, 7291)     */
 #define TUNER_ALPS_TSHC6_NTSC  15
-#define TUNER_TEMIC_PAL_DK     16   /* 4016 FY5      */
+#define TUNER_TEMIC_PAL_DK     16   /* 4016 FY5 (3X 1392, 1393)     */
 #define TUNER_PHILIPS_NTSC_M   17
-#define TUNER_TEMIC_4066FY5_PAL_I       18
-#define TUNER_TEMIC_4006FN5_MULTI_PAL   19  /* B/G, I and D/K autodetected */
-#define TUNER_TEMIC_4009FR5_PAL         20  /* incl. FM radio */
-#define TUNER_TEMIC_4039FR5_NTSC        21  /* incl. FM radio */
-#define TUNER_TEMIC_4046FM5             22  /* you must actively select B/G, D/K, I, L, L` !  */
+#define TUNER_TEMIC_4066FY5_PAL_I       18  /* 4066 FY5 (3X 7032, 7035) */
+#define TUNER_TEMIC_4006FN5_MULTI_PAL   19  /* B/G, I and D/K autodetected (3X 7595, 7606, 7657)*/
+#define TUNER_TEMIC_4009FR5_PAL         20  /* incl. FM radio (3X 7607, 7488, 7711)*/
+#define TUNER_TEMIC_4039FR5_NTSC        21  /* incl. FM radio (3X 7246, 7578, 7732)*/
+#define TUNER_TEMIC_4046FM5             22  /* you must actively select B/G, D/K, I, L, L` !  (3X 7804, 7806, 8103, 8104)*/
 #define TUNER_PHILIPS_PAL_DK           23
 #define TUNER_PHILIPS_FQ1216ME         24  /* you must actively select B/G/D/K, I, L, L` */
 #define TUNER_LG_PAL_I_FM      25
 #define TUNER_LG_NTSC_FM       27
 #define TUNER_LG_PAL_FM                28
 #define TUNER_LG_PAL           29
-#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM       30  /* B/G, I and D/K autodetected */
+#define TUNER_TEMIC_4009FN5_MULTI_PAL_FM       30  /* B/G, I and D/K autodetected (3X 8155, 8160, 8163)*/
+#define TUNER_SHARP_2U5JF5540_NTSC  31
+#define TUNER_Samsung_PAL_TCPM9091PD27 32
+#define TUNER_MT2032 33
+#define TUNER_TEMIC_4106FH5    34      /* 4106 FH5 (3X 7808, 7865)*/
+#define TUNER_TEMIC_4012FY5    35      /* 4012 FY5 (3X 0971, 1099)*/
+#define TUNER_TEMIC_4136FY5    36      /* 4136 FY5 (3X 7708, 7746)*/
+#define TUNER_LG_PAL_NEW_TAPC   37
+
 
 
 #define NOTUNER 0
@@ -67,6 +75,9 @@
 #define Sony    3
 #define Alps    4
 #define LGINNOTEK 5
+#define SHARP   6
+#define Samsung 7
+#define Microtune 8
 
 #define TUNER_SET_TYPE               _IOW('t',1,int)    /* set tuner type */
 #define TUNER_SET_TVFREQ             _IOW('t',2,int)    /* set tv freq */
index 8984e67720908b2826d3c99b576a9b2b0356bfcc..a622e23ed3fae5206c71e655704ac5e5800eb4f0 100644 (file)
@@ -42,6 +42,9 @@ static int debug = 0; /* insmod parameter */
 
 #define dprintk  if (debug) printk
 
+MODULE_DESCRIPTION("device driver for various i2c TV sound decoder / audiomux chips");
+MODULE_AUTHOR("Eric Sandeen, Steve VanDeBogart, Greg Alexander, Gerd Knorr");
+MODULE_LICENSE("GPL");
 
 /* ---------------------------------------------------------------------- */
 /* our structs                                                            */
@@ -51,6 +54,7 @@ static int debug = 0; /* insmod parameter */
 struct CHIPSTATE;
 typedef int  (*getvalue)(int);
 typedef int  (*checkit)(struct CHIPSTATE*);
+typedef int  (*initialize)(struct CHIPSTATE*);
 typedef int  (*getmode)(struct CHIPSTATE*);
 typedef void (*setmode)(struct CHIPSTATE*, int mode);
 typedef void (*checkmode)(struct CHIPSTATE*);
@@ -70,6 +74,7 @@ struct CHIPDESC {
 
        int        *insmodopt;
        checkit    checkit;
+       initialize initialize;
        int        flags;
 #define CHIP_HAS_VOLUME      1
 #define CHIP_HAS_BASSTREBLE  2
@@ -134,6 +139,7 @@ static unsigned short normal_i2c[] = {
        I2C_TDA9840   >> 1,
        I2C_TDA985x_L >> 1,
        I2C_TDA985x_H >> 1,
+       I2C_TDA9874A  >> 1,
        I2C_PIC16C54  >> 1,
        I2C_CLIENT_END };
 static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
@@ -216,7 +222,7 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr)
                 { chip->c.addr, 0,        1, write },
                 { chip->c.addr, I2C_M_RD, 1, read  }
         };
-        write[1] = subaddr;
+        write[0] = subaddr;
 
        if (2 != i2c_transfer(chip->c.adapter,msgs,2)) {
                printk(KERN_WARNING "%s: I/O error (read2)\n",
@@ -323,6 +329,8 @@ void generic_checkmode(struct CHIPSTATE *chip)
 
        if (mode & VIDEO_SOUND_LANG1)
                desc->setmode(chip,VIDEO_SOUND_LANG1);
+       else if (mode & VIDEO_SOUND_LANG2)
+               desc->setmode(chip,VIDEO_SOUND_LANG2);
        else if (mode & VIDEO_SOUND_STEREO)
                desc->setmode(chip,VIDEO_SOUND_STEREO);
        else
@@ -695,6 +703,7 @@ void tda9873_setmode(struct CHIPSTATE *chip, int mode)
                return;
        }
 
+       chip_write(chip, TDA9873_SW, sw_data);
        dprintk("tda9873_setmode(): req. mode %d; chip_write: %d\n",
                mode, sw_data);
 }
@@ -709,6 +718,181 @@ int tda9873_checkit(struct CHIPSTATE *chip)
 }
 
 
+/* ---------------------------------------------------------------------- */
+/* audio chip description - defines+functions for tda9874a                */
+/* Dariusz Kowalewski <darekk@automex.pl>                                 */
+
+/* Subaddresses for TDA9874A (slave rx) */
+#define TDA9874A_AGCGR         0x00    /* AGC gain */
+#define TDA9874A_GCONR         0x01    /* general config */
+#define TDA9874A_MSR           0x02    /* monitor select */
+#define TDA9874A_C1FRA         0x03    /* carrier 1 freq. */
+#define TDA9874A_C1FRB         0x04    /* carrier 1 freq. */
+#define TDA9874A_C1FRC         0x05    /* carrier 1 freq. */
+#define TDA9874A_C2FRA         0x06    /* carrier 2 freq. */
+#define TDA9874A_C2FRB         0x07    /* carrier 2 freq. */
+#define TDA9874A_C2FRC         0x08    /* carrier 2 freq. */
+#define TDA9874A_DCR           0x09    /* demodulator config */
+#define TDA9874A_FMER          0x0a    /* FM de-emphasis */
+#define TDA9874A_FMMR          0x0b    /* FM dematrix */
+#define TDA9874A_C1OLAR                0x0c    /* ch.1 output level adj. */
+#define TDA9874A_C2OLAR                0x0d    /* ch.2 output level adj. */
+#define TDA9874A_NCONR         0x0e    /* NICAM config */
+#define TDA9874A_NOLAR         0x0f    /* NICAM output level adj. */
+#define TDA9874A_NLELR         0x10    /* NICAM lower error limit */
+#define TDA9874A_NUELR         0x11    /* NICAM upper error limit */
+#define TDA9874A_AMCONR                0x12    /* audio mute control */
+#define TDA9874A_SDACOSR       0x13    /* stereo DAC output select */
+#define TDA9874A_AOSR          0x14    /* analog output select */
+#define TDA9874A_DAICONR       0x15    /* digital audio interface config */
+#define TDA9874A_I2SOSR                0x16    /* I2S-bus output select */
+#define TDA9874A_I2SOLAR       0x17    /* I2S-bus output level adj. */
+#define TDA9874A_MDACOSR       0x18    /* mono DAC output select */
+#define TDA9874A_ESP           0xFF    /* easy standard progr. */
+
+/* Subaddresses for TDA9874A (slave tx) */
+#define TDA9874A_DSR           0x00    /* device status */
+#define TDA9874A_NSR           0x01    /* NICAM status */
+#define TDA9874A_NECR          0x02    /* NICAM error count */
+#define TDA9874A_DR1           0x03    /* add. data LSB */
+#define TDA9874A_DR2           0x04    /* add. data MSB */
+#define TDA9874A_LLRA          0x05    /* monitor level read-out LSB */
+#define TDA9874A_LLRB          0x06    /* monitor level read-out MSB */
+#define TDA9874A_SIFLR         0x07    /* SIF level */
+#define TDA9874A_TR2           252     /* test reg. 2 */
+#define TDA9874A_TR1           253     /* test reg. 1 */
+#define TDA9874A_DIC           254     /* device id. code */
+#define TDA9874A_SIC           255     /* software id. code */
+
+
+static int tda9874a_mode = 1;          /* 0: A2, 1: NICAM */
+static int tda9874a_GCONR = 0xc0;      /* default config. input pin: SIFSEL=0 */
+static int tda9874a_ESP = 0x07;                /* default standard: NICAM D/K */
+
+/* insmod options for tda9874a */
+static int tda9874a_SIF = -1;
+static int tda9874a_STD = -1;
+MODULE_PARM(tda9874a_SIF,"i");
+MODULE_PARM(tda9874a_STD,"i");
+
+
+static int tda9874a_setup(struct CHIPSTATE *chip)
+{
+       chip_write(chip, TDA9874A_AGCGR, 0x00); /* 0 dB */
+       chip_write(chip, TDA9874A_GCONR, tda9874a_GCONR);
+       chip_write(chip, TDA9874A_MSR, (tda9874a_mode) ? 0x03:0x02);
+       chip_write(chip, TDA9874A_FMMR, 0x80);
+       chip_write(chip, TDA9874A_C1OLAR, 0x00); /* 0 dB */
+       chip_write(chip, TDA9874A_C2OLAR, 0x00); /* 0 dB */
+       chip_write(chip, TDA9874A_NCONR, 0x00); /* not 0x04 as doc. table 10 says! */
+       chip_write(chip, TDA9874A_NOLAR, 0x00); /* 0 dB */
+       chip_write(chip, TDA9874A_AMCONR, 0xf9);
+       chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); /* 0x81 */
+       chip_write(chip, TDA9874A_AOSR, 0x80);
+       chip_write(chip, TDA9874A_MDACOSR, (tda9874a_mode) ? 0x82:0x80);
+       chip_write(chip, TDA9874A_ESP, tda9874a_ESP);
+
+       return 1;
+}
+
+int tda9874a_getmode(struct CHIPSTATE *chip)
+{
+       int dsr,nsr,mode;
+
+       mode = VIDEO_SOUND_MONO;
+
+       if(-1 == (dsr = chip_read2(chip,TDA9874A_DSR)))
+               return mode;
+       if(-1 == (nsr = chip_read2(chip,TDA9874A_NSR)))
+               return mode;
+
+       if(tda9874a_mode) {
+               /* check also DSR.RSSF and DSR.AMSTAT bits? */
+               if(nsr & 0x02) /* NSR.S/MB */
+                       mode |= VIDEO_SOUND_STEREO;
+               if(nsr & 0x01) /* NSR.D/SB */ 
+                       mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+       } else {
+               if(dsr & 0x02) /* DSR.IDSTE */
+                       mode |= VIDEO_SOUND_STEREO;
+               if(dsr & 0x04) /* DSR.IDDUA */
+                       mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
+       }
+
+       dprintk("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, return: %d.\n",
+                dsr, nsr, mode);
+       return mode;
+}
+
+void tda9874a_setmode(struct CHIPSTATE *chip, int mode)
+{
+       int aosr=0x80,mdacosr=0x82;
+
+       /* note: TDA9874A has auto-select function for audio output */
+       switch(mode) {
+       case VIDEO_SOUND_MONO:
+       case VIDEO_SOUND_STEREO:
+               break;
+       case VIDEO_SOUND_LANG1:
+               aosr = 0x80; /* dual A/A */
+               mdacosr = (tda9874a_mode) ? 0x82:0x80;
+               break;
+       case VIDEO_SOUND_LANG2:
+               aosr = 0xa0; /* dual B/B */
+               mdacosr = (tda9874a_mode) ? 0x83:0x81;
+               break;
+       default:
+               chip->mode = 0;
+               return;
+       }
+
+       chip_write(chip, TDA9874A_AOSR, aosr);
+       chip_write(chip, TDA9874A_MDACOSR, mdacosr);
+
+       dprintk("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n",
+               mode, aosr, mdacosr);
+}
+
+int tda9874a_checkit(struct CHIPSTATE *chip)
+{
+       int dic,sic;    /* device id. and software id. codes */
+
+       if(-1 == (dic = chip_read2(chip,TDA9874A_DIC)))
+               return 0;
+       if(-1 == (sic = chip_read2(chip,TDA9874A_SIC)))
+               return 0;
+
+       dprintk("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic);
+
+       return((dic & 0xff) == 0x11);
+}
+
+int tda9874a_initialize(struct CHIPSTATE *chip)
+{
+       if(tda9874a_SIF != -1) {
+               if(tda9874a_SIF == 1)
+                       tda9874a_GCONR = 0xc0;  /* sound IF input 1 */
+               else if(tda9874a_SIF == 2)
+                       tda9874a_GCONR = 0xc1;  /* sound IF input 2 */
+               else
+                       printk(KERN_WARNING "tda9874a: SIF parameter must be 1 or 2.\n");
+       }
+
+       if(tda9874a_STD != -1) {
+               if((tda9874a_STD >= 0)&&(tda9874a_STD <= 8)) {
+                       tda9874a_ESP = tda9874a_STD;
+                       tda9874a_mode = (tda9874a_STD < 5) ? 0 : 1;
+               } else {
+                       printk(KERN_WARNING "tda9874a: STD parameter must be between 0 and 8.\n");
+               }
+       }
+
+       tda9874a_setup(chip);
+
+       return 0;
+}
+
+
 /* ---------------------------------------------------------------------- */
 /* audio chip descriptions - defines+functions for tea6420                */
 
@@ -779,6 +963,7 @@ int tda9840  = 1;
 int tda9850  = 1;
 int tda9855  = 1;
 int tda9873  = 1;
+int tda9874a = 1;
 int tea6300  = 0;
 int tea6420  = 1;
 int pic16c54 = 1;
@@ -787,6 +972,7 @@ MODULE_PARM(tda9840,"i");
 MODULE_PARM(tda9850,"i");
 MODULE_PARM(tda9855,"i");
 MODULE_PARM(tda9873,"i");
+MODULE_PARM(tda9874a,"i");
 MODULE_PARM(tea6300,"i");
 MODULE_PARM(tea6420,"i");
 MODULE_PARM(pic16c54,"i");
@@ -828,6 +1014,19 @@ static struct CHIPDESC chiplist[] = {
                inputmask:  TDA9873_INP_MASK | TDA9873_MUTE | TDA9873_AUTOMUTE
                
        },
+       {
+               name:       "tda9874a",
+               id:         I2C_DRIVERID_TDA9874A,
+               checkit:    tda9874a_checkit,
+               initialize: tda9874a_initialize,
+               insmodopt:  &tda9874a,
+               addr_lo:    I2C_TDA9874A >> 1,
+               addr_hi:    I2C_TDA9874A >> 1,
+
+               getmode:    tda9874a_getmode,
+               setmode:    tda9874a_setmode,
+               checkmode:  generic_checkmode,
+       },
        {
                name:       "tda9850",
                id:         I2C_DRIVERID_TDA9850,
@@ -991,7 +1190,11 @@ static int chip_attach(struct i2c_adapter *adap, int addr,
        i2c_attach_client(&chip->c);
 
        /* initialization  */
-       chip_cmd(chip,"init",&desc->init);
+       if (desc->initialize != NULL)
+               desc->initialize(chip);
+       else
+               chip_cmd(chip,"init",&desc->init);
+
        if (desc->flags & CHIP_HAS_VOLUME) {
                chip->left   = desc->leftinit   ? desc->leftinit   : 65536;
                chip->right  = desc->rightinit  ? desc->rightinit  : 65536;
@@ -1168,7 +1371,6 @@ void audiochip_cleanup_module(void)
 
 module_init(audiochip_init_module);
 module_exit(audiochip_cleanup_module);
-MODULE_LICENSE("GPL");
 
 /*
  * Local variables:
index 702d2492d2df2626642818485088b0b6eb2bfc0f..b8deadcb1fb9c7dc73056df2bc499540ad0b926e 100644 (file)
@@ -6,6 +6,7 @@
 #define I2C_TDA9840        0x84
 #define I2C_TDA985x_L      0xb4 /* also used by 9873 */
 #define I2C_TDA985x_H      0xb6
+#define I2C_TDA9874A       0xb0 /* also used by 9875 */
 
 #define I2C_TEA6300        0x80
 #define I2C_TEA6420       0x98
index 0e7e71ae61602005d8e5e5bf3dcb1676dc500e07..60686c7d122e2fc976a7cbabf23ebc0cc9f12860 100644 (file)
@@ -26,6 +26,9 @@ static int devnr = -1;
 MODULE_PARM(debug,"i");
 MODULE_PARM(devnr,"i");
 
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
+
 /* ----------------------------------------------------------------------- */
 
 struct TVMIXER {
@@ -39,27 +42,6 @@ static struct TVMIXER devices[DEV_MAX];
 static int tvmixer_adapters(struct i2c_adapter *adap);
 static int tvmixer_clients(struct i2c_client *client);
 
-static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-static int tvmixer_open(struct inode *inode, struct file *file);
-static int tvmixer_release(struct inode *inode, struct file *file);
-
-
-static struct i2c_driver driver = {
-       name:            "tv card mixer driver",
-        id:              I2C_DRIVERID_TVMIXER,
-       flags:           I2C_DF_DUMMY,
-        attach_adapter:  tvmixer_adapters,
-        detach_client:   tvmixer_clients,
-};
-
-static struct file_operations tvmixer_fops = {
-       owner:          THIS_MODULE,
-       llseek:         no_llseek,
-       ioctl:          tvmixer_ioctl,
-       open:           tvmixer_open,
-       release:        tvmixer_release,
-};
-
 /* ----------------------------------------------------------------------- */
 
 static int mix_to_v4l(int i)
@@ -232,6 +214,23 @@ static int tvmixer_release(struct inode *inode, struct file *file)
        return 0;
 }
 
+
+static struct i2c_driver driver = {
+       name:            "tv card mixer driver",
+        id:              I2C_DRIVERID_TVMIXER,
+       flags:           I2C_DF_DUMMY,
+        attach_adapter:  tvmixer_adapters,
+        detach_client:   tvmixer_clients,
+};
+
+static struct file_operations tvmixer_fops = {
+       owner:          THIS_MODULE,
+       llseek:         no_llseek,
+       ioctl:          tvmixer_ioctl,
+       open:           tvmixer_open,
+       release:        tvmixer_release,
+};
+
 /* ----------------------------------------------------------------------- */
 
 static int tvmixer_adapters(struct i2c_adapter *adap)
@@ -355,4 +354,3 @@ module_exit(tvmixer_cleanup_module);
  * c-basic-offset: 8
  * End:
  */
-MODULE_LICENSE("GPL");
index 58bd41123996d6e8adf1c0a3cc54ba845ac4c0f2..e00dee5c48cce095f39815f7d8c6508c46329e9e 100644 (file)
@@ -837,3 +837,4 @@ static void __exit a2065_cleanup(void)
 
 module_init(a2065_probe);
 module_exit(a2065_cleanup);
+MODULE_LICENSE("GPL");
index 3f5ce581c60344e2ee242778d0714194d1cdd933..2994d6f73099147db01cfab861036a6d7f70fe7a 100644 (file)
@@ -128,6 +128,7 @@ extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_priva
 unsigned int bionet_debug = NET_DEBUG;
 MODULE_PARM(bionet_debug, "i");
 MODULE_PARM_DESC(bionet_debug, "bionet debug level (0-2)");
+MODULE_LICENSE("GPL");
 
 static unsigned int bionet_min_poll_time = 2;
 
index cc571fdf1843dd3230c104f48a6d90eebb59fbac..175c23466a73652efbfb3d7a7071f9552a8cf2c1 100644 (file)
@@ -124,6 +124,7 @@ extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_priva
 unsigned int pamsnet_debug = NET_DEBUG;
 MODULE_PARM(pamsnet_debug, "i");
 MODULE_PARM_DESC(pamsnet_debug, "pamsnet debug enable (0-1)");
+MODULE_LICENSE("GPL");
 
 static unsigned int pamsnet_min_poll_time = 2;
 
index 4cde2eb04602eb027efc4692695f1bacdc216905..15a9c90cb4ccb6e096fc4a20cd6908d5d3ea1227 100644 (file)
@@ -84,6 +84,7 @@ static int lance_debug = 1;
 #endif
 MODULE_PARM(lance_debug, "i");
 MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)");
+MODULE_LICENSE("GPL");
 
 /* Print debug messages on probing? */
 #undef LANCE_DEBUG_PROBE
index 4fe99b68500f0ca1c252d912cc1759538228b629..2167d6910aad03969fbbf842ab3a007eeb5df68d 100644 (file)
@@ -60,6 +60,7 @@ static int lance_debug = 1;
 #endif
 MODULE_PARM(lance_debug, "i");
 MODULE_PARM_DESC(lance_debug, "Lance debug level (0-3)");
+MODULE_LICENSE("GPL");
 
 /* Print debug messages on probing? */
 #undef LANCE_DEBUG_PROBE
index bafad186bf3eae61f85c79f6e76e7731be2be56c..b326541e4b781a2433aaff762390c01d58eef067 100644 (file)
@@ -1658,6 +1658,7 @@ bmac_proc_info(char *buffer, char **start, off_t offset, int length)
 
 MODULE_AUTHOR("Randy Gobbel/Paul Mackerras");
 MODULE_DESCRIPTION("PowerMac BMAC ethernet driver.");
+MODULE_LICENSE("GPL");
 
 
 static void __exit bmac_cleanup (void)
index afb46d51a0ba764c90f5d51d1e0b87b36b0ccecb..d5b0da42a4cad04563c4c179215146b9d4026286 100644 (file)
@@ -109,6 +109,7 @@ KERN_INFO "fealnx.c:v2.50 1/17/2001\n";
 
 MODULE_AUTHOR("Myson or whoever");
 MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(max_interrupt_work, "i");
 //MODULE_PARM(min_pci_latency, "i");
 MODULE_PARM(debug, "i");
index b171843b360f7beae4590bfe49305b575cfd1e7b..cad2a831c22d7f24c9b00a4db0fe1c5dade63bed 100644 (file)
@@ -632,6 +632,7 @@ MODULE_PARM(net_debug, "i");
 MODULE_PARM_DESC(io, "FMV-18X I/O address");
 MODULE_PARM_DESC(irq, "FMV-18X IRQ number");
 MODULE_PARM_DESC(net_debug, "FMV-18X debug level (0-1,5-6)");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
index 21a638ecd2862f424acebcf20a90f32bcdb956f2..8d3e0b2d45412740f6f839809f64de9fcfb12d67 100644 (file)
@@ -1676,6 +1676,7 @@ out_txdesc:
 
 MODULE_AUTHOR("Paul Mackerras/Ben Herrenschmidt");
 MODULE_DESCRIPTION("PowerMac GMAC driver.");
+MODULE_LICENSE("GPL");
 
 static void __exit gmac_cleanup_module(void)
 {
index 38f448bf3ea837170138074945159a85f8d4eed1..e736e16052bdb9a12ccfccfbbe44f86affaa1877 100644 (file)
@@ -1250,3 +1250,4 @@ static struct net_device_stats *gt96100_get_stats(struct net_device *dev)
 }
 
 module_init(gt96100_probe);
+MODULE_LICENSE("GPL");
index 7b4e6536adaba80437dfbb439d2d59462401a8a0..035e29cfeef5d325d1fdb8507fcbbbc2978132eb 100644 (file)
@@ -226,6 +226,7 @@ static int hplance_close(struct net_device *dev)
 }
 
 #ifdef MODULE
+MODULE_LICENSE("GPL");
 int init_module(void)
 {
         root_lance_dev = NULL;
index 6eb7200c6bc9497306f0ecb12df6073a6be8f536..6de426318f86085692dc5acea8755b5eab1060b0 100644 (file)
@@ -254,3 +254,4 @@ static void __exit hydra_cleanup(void)
 
 module_init(hydra_probe);
 module_exit(hydra_cleanup);
+MODULE_LICENSE("GPL");
index a945f84a8440df4a20eec847737727ee05355163..ca7f616feb8ea28517d331404d340061660e025a 100644 (file)
@@ -1199,6 +1199,7 @@ MODULE_PARM(irq, "i");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
 MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
index e0cc882810be2ad69544d179ba1adcbea71454de..dc1667b240cef790aae53fb15d6ff5a3fd6e9d7c 100644 (file)
@@ -1817,6 +1817,7 @@ static void ioc3_set_multicast_list(struct net_device *dev)
 
 MODULE_AUTHOR("Ralf Baechle <ralf@oss.sgi.com>");
 MODULE_DESCRIPTION("SGI IOC3 Ethernet driver");
+MODULE_LICENSE("GPL");
 
 module_init(ioc3_init_module);
 module_exit(ioc3_cleanup_module);
index bee3b7fb319384b6fc0d38c9db6a46167efb3996..bf3fcbb0053f92e6f2b9cdb06556c80c1fc16951 100644 (file)
@@ -636,6 +636,7 @@ static int io = 0x300;
 static int irq;
 static int dma;
 static int mem;
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
index 7bcb7f6e19c5cf30b948d70050d458bf8d0b303c..54d5c958de0f50308fe68c0cee1ecdabfd1bf48a 100644 (file)
@@ -180,6 +180,7 @@ static int i596_debug = (DEB_SERIOUS|DEB_PROBE);
 
 MODULE_AUTHOR("Richard Hirst");
 MODULE_DESCRIPTION("i82596 driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(i596_debug, "i");
 MODULE_PARM_DESC(i596_debug, "lasi_82596 debug mask");
 
index ec0912034773c84895949a281bd19dbb77007c0e..258d705d5acfb9c8ee597426874d323dc47015d3 100644 (file)
@@ -627,6 +627,7 @@ static int debug;
 
 MODULE_PARM(debug, "i");
 MODULE_PARM_DESC(debug, "CS89[02]0 debug level (0-5)");
+MODULE_LICENSE("GPL");
 
 EXPORT_NO_SYMBOLS;
 
index 083616e27814dba551488541a4c02f5de4f1473c..04ca3c75ad16af864193c77b985524723238504a 100644 (file)
@@ -913,6 +913,7 @@ static void mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs)
 
 MODULE_AUTHOR("Paul Mackerras");
 MODULE_DESCRIPTION("PowerMac MACE driver.");
+MODULE_LICENSE("GPL");
 
 static void __exit mace_cleanup (void)
 {
index ef2705176acc8ee6a1e7a9d28c5be674aae2c968..3cd9741856bfbd23645212741d6c0aa89d4e3475 100644 (file)
@@ -584,6 +584,7 @@ static struct net_device dev_macsonic;
 
 MODULE_PARM(sonic_debug, "i");
 MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)");
+MODULE_LICENSE("GPL");
 
 EXPORT_NO_SYMBOLS;
 
index 3af60247e080dc5c735efa63489748a6cd3d1506..eebdb555d4ef80ddf1c419fea874337002b328b2 100644 (file)
@@ -188,6 +188,8 @@ static int m147lance_close(struct net_device *dev)
 }
 
 #ifdef MODULE
+MODULE_LICENSE("GPL");
+
 int init_module(void)
 {
        root_lance_dev = NULL;
index 29d4450e211ff94529c88bed6b3fece9eb400528..722392bc21ad130c5cd052e11a95a4012e95f6cb 100644 (file)
@@ -744,6 +744,7 @@ static struct net_device dev_ne[MAX_NE_CARDS];
 static int io[MAX_NE_CARDS];
 static int irq[MAX_NE_CARDS];
 static int bad[MAX_NE_CARDS];  /* 0xbad = bad sig or no reset ack */
+MODULE_LICENSE("GPL");
 
 #ifdef MODULE_PARM
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
index 1a5a539818a0bfa4af17e7e0021560fb6c982396..0029c3c54f3c82ac596c18db7deef9ccc0d10004 100644 (file)
@@ -696,3 +696,4 @@ static void __exit oaknet_cleanup_module (void)
 
 module_init(oaknet_init_module);
 module_exit(oaknet_cleanup_module);
+MODULE_LICENSE("GPL");
index 26c1a4964796e52c59e5009a9b8b809a8fa0aee1..e94d6c3cb3a2ceae03445e8861b3bf0e9043f88d 100644 (file)
@@ -484,6 +484,7 @@ struct netdrv_private {
 
 MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
 MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM (multicast_filter_limit, "i");
 MODULE_PARM (max_interrupt_work, "i");
 MODULE_PARM (debug, "i");
index 19ff5c6384d1d50665665efb088740ba6d8cae66..4de966127d2a0f3d37d7049a35c99e96203b441a 100644 (file)
@@ -9,11 +9,25 @@
        Scyld Computing Corporation
        410 Severn Ave., Suite 210
        Annapolis MD 21403
+
+       -----------------------------------------------------------
+
+       Linux kernel-specific changes:
+
+       LK1.0 (Ion Badulescu)
+       - Major cleanup
+       - Use 2.4 PCI API
+       - Support ethtool
+       - Rewrite perfect filter/hash code
+       - Use interrupts for media changes
+
+       LK1.1 (Ion Badulescu)
+       - Disallow negotiation of unsupported full-duplex modes
 */
 
 #define DRV_NAME       "xircom_tulip_cb"
-#define DRV_VERSION    "0.91+LK"
-#define DRV_RELDATE    "July 19, 2001"
+#define DRV_VERSION    "0.91+LK1.1"
+#define DRV_RELDATE    "October 11, 2001"
 
 #define CARDBUS 1
 
@@ -94,7 +108,6 @@ static int csr0 = 0x00A00000 | 0x4800;
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
 KERN_INFO DRV_NAME ".c derived from tulip.c:v0.91 4/14/99 becker@scyld.com\n"
-KERN_INFO " modified by danilo@cs.uni-magdeburg.de for XIRCOM CBE, fixed by Doug Ledford\n"
 KERN_INFO " unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE "\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
@@ -238,7 +251,7 @@ static struct xircom_chip_table {
        int valid_intrs;                        /* CSR7 interrupt enable settings */
        int flags;
 } xircom_tbl[] = {
-  { "Xircom Cardbus Adapter (DEC 21143 compatible mode)",
+  { "Xircom Cardbus Adapter",
        LinkChange | NormalIntr | AbnormalIntr | BusErrorIntr |
        RxDied | RxNoBuf | RxIntr | TxFIFOUnderflow | TxNoBuf | TxDied | TxIntr,
        HAS_MII | HAS_ACPI, },
@@ -425,12 +438,22 @@ static void __devinit read_mac_address(struct net_device *dev)
 
 /*
  * locate the MII interfaces and initialize them.
+ * we disable full-duplex modes here,
+ * because we don't know how to handle them.
  */
 static void find_mii_transceivers(struct net_device *dev)
 {
        struct xircom_private *tp = dev->priv;
        int phy, phy_idx;
 
+       if (media_cap[tp->default_port] & MediaIsMII) {
+               u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
+               tp->to_advertise = media2advert[tp->default_port - 9];
+       } else
+               tp->to_advertise =
+                       /*ADVERTISE_100BASE4 | ADVERTISE_100FULL |*/ ADVERTISE_100HALF |
+                       /*ADVERTISE_10FULL |*/ ADVERTISE_10HALF | ADVERTISE_CSMA;
+
        /* Find the connected MII xcvrs.
           Doing this in open() would allow detecting external xcvrs later,
           but takes much time. */
@@ -447,17 +470,6 @@ static void find_mii_transceivers(struct net_device *dev)
                        printk(KERN_INFO "%s:  MII transceiver #%d "
                                   "config %4.4x status %4.4x advertising %4.4x.\n",
                                   dev->name, phy, mii_reg0, mii_status, mii_advert);
-                       /* Fixup for DLink with miswired PHY. */
-                       if (mii_advert != reg4) {
-                               printk(KERN_DEBUG "%s:  Advertising %4.4x on PHY %d,"
-                                          " previously advertising %4.4x.\n",
-                                          dev->name, reg4, phy, mii_advert);
-                               mdio_write(dev, phy, MII_ADVERTISE, reg4);
-                       }
-                       /* Enable autonegotiation: some boards default to off. */
-                       mdio_write(dev, phy, MII_BMCR, mii_reg0 | BMCR_ANENABLE |
-                                          (tp->full_duplex ? BMCR_FULLDPLX : 0) |
-                                          (media_cap[tp->default_port]&MediaIs100 ? BMCR_SPEED100 : 0));
                }
        }
        tp->mii_cnt = phy_idx;
@@ -529,7 +541,7 @@ static int __devinit xircom_init_one(struct pci_dev *pdev, const struct pci_devi
                printk(version);
 #endif
 
-       printk(KERN_INFO "xircom_init_one(%s)\n", pdev->slot_name);
+       //printk(KERN_INFO "xircom_init_one(%s)\n", pdev->slot_name);
 
        board_idx++;
 
@@ -1696,7 +1708,6 @@ static int xircom_suspend(struct pci_dev *pdev, u32 state)
 }
 
 
-/* XXX: resume isn't able to power up the MII/PHY! */
 static int xircom_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pdev->driver_data;
index bf6dcec698209761869907903641b2fc68b7789a..31ce83f8015440af93b09287c1c738410321e245 100644 (file)
@@ -1080,3 +1080,4 @@ static int __init saa9730_probe(void)
 }
 
 module_init(saa9730_probe);
+MODULE_LICENSE("GPL");
index 1fc1788944d0118cd6fa86a9575edae0d265ac49..e6e6efc4e181fb2bef57519d64e4d1dc84be26fc 100644 (file)
@@ -711,6 +711,7 @@ inline void wait_for_buffer(struct net_device * dev)
 static struct net_device dev_seeq = { init: seeq8005_probe };
 static int io = 0x320;
 static int irq = 10;
+MODULE_LICENSE("GPL");
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
index 240dd00f1dff4d47f968cdfadfef7666f16d5da2..21ab6e3af3dafddc25d63103ee17d6b29f6d564d 100644 (file)
@@ -616,6 +616,7 @@ int __init SK_init(struct net_device *dev)
 
 MODULE_AUTHOR("Patrick J.D. Weichmann");
 MODULE_DESCRIPTION("Schneider & Koch G16 Ethernet Device Driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "0 to probe common ports (unsafe), or the I/O base of the board");
 
index 4b3a464ddc7e36913fe49a4c9108ee667943c421..5886a04d6c3ec754713f99ad016cbcb356a5a551 100644 (file)
@@ -1229,6 +1229,7 @@ int __init skmca_probe(struct SKMCA_NETDEV *dev)
  * ------------------------------------------------------------------------ */
 
 #ifdef MODULE
+MODULE_LICENSE("GPL");
 
 #define DEVMAX 5
 
index 6f5a859a80a6790940d2aae96755045814b00da0..50baaf26db69304f294dda7b87f391e18e9298f7 100644 (file)
@@ -437,6 +437,7 @@ static int ultramca_close_card(struct net_device *dev)
 static struct net_device dev_ultra[MAX_ULTRAMCA_CARDS];
 static int io[MAX_ULTRAMCA_CARDS];
 static int irq[MAX_ULTRAMCA_CARDS];
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ULTRAMCA_CARDS) "i");
index bb0334c2a1883546c457c6dad4943b33694958b2..c40f7dc8b041015f0351f13e58d87c9d4d797c9e 100644 (file)
@@ -1558,6 +1558,7 @@ static struct net_device devSMC9194;
 static int io;
 static int irq;
 static int ifport;
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
index d55ed16788993ebefcdbfbc5012b62bb70109942..f505bc26fd2cb98b2cb6e93b92d872f5f67ea43f 100644 (file)
@@ -316,3 +316,4 @@ do_stnic_intr (int irq, void *dev_id, struct pt_regs *regs)
 
 module_init(stnic_probe);
 /* No cleanup routine. */
+MODULE_LICENSE("GPL");
index 6721aa18269ac86d62619dd0c6c90f65294599a2..a14bcaff9cc9d216d801f355cddcc11eb3ac7217 100644 (file)
@@ -71,6 +71,7 @@ static int lance_debug = 1;
 #endif
 MODULE_PARM(lance_debug, "i");
 MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)");
+MODULE_LICENSE("GPL");
 
 #define        DPRINTK(n,a) \
        do {  \
index 170e9abeba1647e5403c1709ee2bfbe4dd25a113..8dd4ff072f58509c192678d6d53f142434d7d8f7 100644 (file)
@@ -1041,3 +1041,4 @@ static void __exit qec_cleanup(void)
 
 module_init(qec_probe);
 module_exit(qec_cleanup);
+MODULE_LICENSE("GPL");
index 053fdc3bdd0659ce22d38ae8011afb0580b8bd30..797e1d83281c21d3f6cba35830858d8eb1f5eb49 100644 (file)
@@ -301,7 +301,7 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        long ioaddr = dev->base_addr;
        int csr5;
        int entry;
-       int csr8;
+       int missed;
        int rx = 0;
        int tx = 0;
        int oi = 0;
@@ -434,6 +434,7 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                                }
                        }
                        if (csr5 & RxDied) {            /* Missed a Rx frame. */
+                                tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
 #ifdef CONFIG_NET_HW_FLOWCONTROL
                                if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
                                        tp->stats.rx_errors++;
@@ -547,8 +548,9 @@ void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                }
        }
 
-       csr8 = inl(ioaddr + CSR8);
-       tp->stats.rx_dropped += (csr8 & 0x1ffff) + ((csr8 >> 17) & 0xfff);
+       if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
+               tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
+       }
 
        if (tulip_debug > 4)
                printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
index 810ceaad146a7e27fea70ad0d2d6d265d81ddaa2..92ecf91b31f2b4d16d7729bf3800d287a2fc4e5d 100644 (file)
@@ -15,8 +15,8 @@
 */
 
 #define DRV_NAME       "tulip"
-#define DRV_VERSION    "0.9.15-pre7"
-#define DRV_RELDATE    "Oct 2, 2001"
+#define DRV_VERSION    "0.9.15-pre8"
+#define DRV_RELDATE    "Oct 11, 2001"
 
 #include <linux/config.h>
 #include <linux/module.h>
index cac9085d4b0562b456c8ce91a876bc766fe6d6d1..9e0d1a6cd8d332db5d948ea06379d50a04b5f8f1 100644 (file)
@@ -43,6 +43,7 @@ static char version[] __initdata = "airport.c 0.06f (Benjamin Herrenschmidt <ben
 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
+EXPORT_NO_SYMBOLS;
 
 typedef struct dldwd_card {
        struct device_node* node;
index 27def25fa0caf802c2b07be795eff638f8144b00..e2eece1727a17cf68c190f5876e64719aa83bee2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: amd7930.c,v 1.27 2001/05/21 01:25:22 davem Exp $
+/* $Id: amd7930.c,v 1.28 2001/10/13 01:47:29 davem Exp $
  * drivers/sbus/audio/amd7930.c
  *
  * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
index a4730d2a5e882e140a4c632be2eba296bf6e945c..4ad1060fdd8b8eb0346515115348961480f49da1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: aurora.c,v 1.16 2001/10/08 22:19:51 davem Exp $
+/*     $Id: aurora.c,v 1.17 2001/10/13 08:27:50 davem Exp $
  *     linux/drivers/sbus/char/aurora.c -- Aurora multiport driver
  *
  *     Copyright (c) 1999 by Oliver Aldulea (oli at bv dot ro)
  *     read that file before reading this one.
  *
  *     Several parts of the code do not have comments yet.
+ * 
+ * n.b.  The board can support 115.2 bit rates, but only on a few
+ * ports. The total badwidth of one chip (ports 0-7 or 8-15) is equal
+ * to OSC_FREQ div 16. In case of my board, each chip can take 6
+ * channels of 115.2 kbaud.  This information is not well-tested.
+ * 
+ * Fixed to use tty_get_baud_rate().
+ *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
  */
 
 #include <linux/module.h>
@@ -100,16 +108,6 @@ static struct termios * aurora_termios_locked[AURORA_TNPORTS] = { NULL, };
 
 DECLARE_TASK_QUEUE(tq_aurora);
 
-/* Yes, the board can support 115.2 bit rates, but only on a few ports. The
- * total badwidth of one chip (ports 0-7 or 8-15) is equal to OSC_FREQ div
- * 16. In case of my board, each chip can take 6 channels of 115.2 kbaud.
- * This information is not well-tested.
- */
-static unsigned long baud_table[] =  {
-        0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-        9600, 19200, 38400, 57600, 115200, 0,
-};
-
 static inline int aurora_paranoia_check(struct Aurora_port const * port,
                                    kdev_t device, const char *routine)
 {
@@ -1030,28 +1028,14 @@ static void aurora_change_speed(struct Aurora_board *bp, struct Aurora_port *por
        port->COR2 = 0;
        port->MSVR = MSVR_RTS|MSVR_DTR;
        
-       baud = C_BAUD(tty);
-       
-       if (baud & CBAUDEX) {
-               baud &= ~CBAUDEX;
-               if (baud < 1 || baud > 2) 
-                       port->tty->termios->c_cflag &= ~CBAUDEX;
-               else
-                       baud += 15;
-       }
-       if (baud == 15)  {
-               if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-                       baud ++;
-               if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-                       baud += 2;
-       }
+       baud = tty_get_baud_rate(tty);
        
        /* Select port on the board */
        sbus_writeb(port_No(port) & 7,
                    &bp->r[chip]->r[CD180_CAR]);
        udelay(1);
        
-       if (!baud_table[baud])  {
+       if (!baud)  {
                /* Drop DTR & exit */
                port->MSVR &= ~(bp->DTR|bp->RTS);
                sbus_writeb(port->MSVR,
@@ -1067,10 +1051,10 @@ static void aurora_change_speed(struct Aurora_board *bp, struct Aurora_port *por
        /* Now we must calculate some speed dependant things. */
        
        /* Set baud rate for port. */
-       tmp = (((bp->oscfreq + baud_table[baud]/2) / baud_table[baud] +
+       tmp = (((bp->oscfreq + baud/2) / baud +
                CD180_TPC/2) / CD180_TPC);
 
-/*     tmp = (bp->oscfreq/7)/baud_table[baud];
+/*     tmp = (bp->oscfreq/7)/baud;
        if((tmp%10)>4)tmp=tmp/10+1;else tmp=tmp/10;*/
 /*     printk("Prescaler period: %d\n",tmp);*/
 
@@ -1081,7 +1065,7 @@ static void aurora_change_speed(struct Aurora_board *bp, struct Aurora_port *por
        sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_RBPRL]);
        sbus_writeb(tmp & 0xff, &bp->r[chip]->r[CD180_TBPRL]);
        
-       baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
+       baud = (baud + 5) / 10;   /* Estimated CPS */
        
        /* Two timer ticks seems enough to wakeup something like SLIP driver */
        tmp = ((baud + HZ/2) / HZ) * 2 - CD180_NFIFO;           
index 893b2d2871fab69a4efa325f68c792c9d9f06625..db20baea3c9e08da8e9f9a6a42c6725c40254cf2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.64 2001/10/08 22:19:51 davem Exp $
+/* $Id: sab82532.c,v 1.65 2001/10/13 08:27:50 davem Exp $
  * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -6,6 +6,10 @@
  * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
  *   Maxim Krasnyanskiy <maxk@qualcomm.com>
  *
+ * Fixed to use tty_get_baud_rate, and to allow for arbitrary baud
+ * rates to be programmed into the UART.  Also eliminated a lot of
+ * duplicated code in the console setup.
+ *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
  */
 
 #include <linux/config.h>
@@ -147,45 +151,47 @@ static inline int serial_paranoia_check(struct sab82532 *info,
  * The formula is:    Baud = BASE_BAUD / ((N + 1) * (1 << M)),
  *
  * with               0 <= N < 64 and 0 <= M < 16
- *
- * XXX:        Speeds with M = 0 might not work properly for XTAL frequencies
- *      above 10 MHz.
+ * 
+ * 12-Oct-2001 - Replaced table driven approach with code written by
+ * Theodore Ts'o <tytso@alum.mit.edu> which exactly replicates the
+ * table.  (Modulo bugs for the 307200 and 61440 baud rates, which
+ * were clearly incorrectly calculated in the original table.  This is
+ * why tables filled with magic constants are evil.)
  */
-struct ebrg_struct {
-       int     baud;
-       int     n;
-       int     m;
-};
 
-static struct ebrg_struct ebrg_table[] = {
-       {       0,      0,       0 },
-       {      50,      35,     10 },
-       {      75,      47,      9 },
-       {     110,      32,      9 },
-       {     134,      53,      8 },
-       {     150,      47,      8 },
-       {     200,      35,      8 },
-       {     300,      47,      7 },
-       {     600,      47,      6 },
-       {    1200,      47,      5 },
-       {    1800,      31,      5 },
-       {    2400,      47,      4 },
-       {    4800,      47,      3 },
-       {    9600,      47,      2 },
-       {   19200,      47,      1 },
-       {   38400,      23,      1 },
-       {   57600,      15,      1 },
-       {  115200,       7,      1 },
-       {  230400,       3,      1 },
-       {  460800,       1,      1 },
-       {   76800,      11,      1 },
-       {  153600,       5,      1 },
-       {  307200,       3,      1 },
-       {  614400,       3,      0 },
-       {  921600,       0,      1 },
-};
+static void calc_ebrg(int baud, int *n_ret, int *m_ret)
+{
+       int     n, m;
 
-#define NR_EBRG_VALUES (sizeof(ebrg_table)/sizeof(struct ebrg_struct))
+       if (baud == 0) {
+               *n_ret = 0;
+               *m_ret = 0;
+               return;
+       }
+     
+       /*
+        * We scale numbers by 10 so that we get better accuracy
+        * without having to use floating point.  Here we increment m
+        * until n is within the valid range.
+        */
+       n = (BASE_BAUD*10) / baud;
+       m = 0;
+       while (n >= 640) {
+               n = n / 2;
+               m++;
+       }
+       n = (n+5) / 10;
+       /*
+        * We try very hard to avoid speeds with M == 0 since they may
+        * not work correctly for XTAL frequences above 10 MHz.
+        */
+       if ((m == 0) && ((n & 1) == 0)) {
+               n = n / 2;
+               m++;
+       }
+       *n_ret = n - 1;
+       *m_ret = m;
+}
 
 #define SAB82532_MAX_TEC_TIMEOUT 200000        /* 1 character time (at 50 baud) */
 #define SAB82532_MAX_CEC_TIMEOUT  50000        /* 2.5 TX CLKs (at 50 baud) */
@@ -939,7 +945,7 @@ static void change_speed(struct sab82532 *info)
        unsigned int    ebrg;
        tcflag_t        cflag;
        unsigned char   dafo;
-       int             i, bits;
+       int             bits, n, m;
 
        if (!info->tty || !info->tty->termios)
                return;
@@ -982,18 +988,11 @@ static void change_speed(struct sab82532 *info)
        }
 
        /* Determine EBRG values based on baud rate */
-       i = cflag & CBAUD;
-       if (i & CBAUDEX) {
-               i &= ~(CBAUDEX);
-               if ((i < 1) || ((i + 15) >= NR_EBRG_VALUES))
-                       info->tty->termios->c_cflag &= ~CBAUDEX;
-               else
-                       i += 15;
-       }
-       ebrg = ebrg_table[i].n;
-       ebrg |= (ebrg_table[i].m << 6);
+       info->baud = tty_get_baud_rate(info->tty);
+       calc_ebrg(info->baud, &n, &m);
+       
+       ebrg = n | (m << 6);
 
-       info->baud = ebrg_table[i].baud;
        if (info->baud) {
                info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud;
                info->tec_timeout = (10 * 1000000) / info->baud;
@@ -2205,7 +2204,7 @@ static void __init sab82532_kgdb_hook(int line)
 
 static inline void __init show_serial_version(void)
 {
-       char *revision = "$Revision: 1.64 $";
+       char *revision = "$Revision: 1.65 $";
        char *version, *p;
 
        version = strchr(revision, ' ');
@@ -2558,12 +2557,11 @@ sab82532_console_device(struct console *con)
 static int
 sab82532_console_setup(struct console *con, char *options)
 {
+       static struct tty_struct c_tty;
+       static struct termios c_termios;
        struct sab82532 *info;
-       unsigned int    ebrg;
        tcflag_t        cflag;
-       unsigned char   dafo;
-       int             i, bits;
-       unsigned long   flags;
+       int             i;
 
        info = sab82532_chain;
        for (i = con->index; i; i--) {
@@ -2595,92 +2593,28 @@ sab82532_console_setup(struct console *con, char *options)
        sunserial_console_termios(con);
        cflag = con->cflag;
 
-       /* Byte size and parity */
-       switch (cflag & CSIZE) {
-             case CS5: dafo = SAB82532_DAFO_CHL5; bits = 7; break;
-             case CS6: dafo = SAB82532_DAFO_CHL6; bits = 8; break;
-             case CS7: dafo = SAB82532_DAFO_CHL7; bits = 9; break;
-             case CS8: dafo = SAB82532_DAFO_CHL8; bits = 10; break;
-             /* Never happens, but GCC is too dumb to figure it out */
-             default:  dafo = SAB82532_DAFO_CHL5; bits = 7; break;
-       }
-
-       if (cflag & CSTOPB) {
-               dafo |= SAB82532_DAFO_STOP;
-               bits++;
-       }
-
-       if (cflag & PARENB) {
-               dafo |= SAB82532_DAFO_PARE;
-               bits++;
-       }
-
-       if (cflag & PARODD) {
-#ifdef CMSPAR
-               if (cflag & CMSPAR)
-                       dafo |= SAB82532_DAFO_PAR_MARK;
-               else
-#endif
-                       dafo |= SAB82532_DAFO_PAR_ODD;
-       } else {
-#ifdef CMSPAR
-               if (cflag & CMSPAR)
-                       dafo |= SAB82532_DAFO_PAR_SPACE;
-               else
-#endif
-                       dafo |= SAB82532_DAFO_PAR_EVEN;
+       /*
+        * Fake up the tty and tty->termios structures so we can use
+        * change_speed (and eliminate a lot of duplicate code).
+        */
+       if (!info->tty) {
+               memset(&c_tty, 0, sizeof(c_tty));
+               info->tty = &c_tty;
        }
-
-       /* Determine EBRG values based on baud rate */
-       i = cflag & CBAUD;
-       if (i & CBAUDEX) {
-               i &= ~(CBAUDEX);
-               if ((i < 1) || ((i + 15) >= NR_EBRG_VALUES))
-                       cflag &= ~CBAUDEX;
-               else
-                       i += 15;
+       if (!info->tty->termios) {
+               memset(&c_termios, 0, sizeof(c_termios));
+               info->tty->termios = &c_termios;
        }
-       ebrg = ebrg_table[i].n;
-       ebrg |= (ebrg_table[i].m << 6);
-
-       info->baud = ebrg_table[i].baud;
-       if (info->baud)
-               info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud;
-       else
-               info->timeout = 0;
-       info->timeout += HZ / 50;               /* Add .02 seconds of slop */
-
-       /* CTS flow control flags */
-       if (cflag & CRTSCTS)
-               info->flags |= ASYNC_CTS_FLOW;
-       else
-               info->flags &= ~(ASYNC_CTS_FLOW);
-
-       if (cflag & CLOCAL)
-               info->flags &= ~(ASYNC_CHECK_CD);
-       else
-               info->flags |= ASYNC_CHECK_CD;
+       info->tty->termios->c_cflag = con->cflag;
 
-       save_flags(flags); cli();
-       sab82532_cec_wait(info);
-       sab82532_tec_wait(info);
-       writeb(dafo, &info->regs->w.dafo);
-       writeb(ebrg & 0xff, &info->regs->w.bgr);
-       writeb(readb(&info->regs->rw.ccr2) & ~(0xc0), &info->regs->rw.ccr2);
-       writeb(readb(&info->regs->rw.ccr2) | ((ebrg >> 2) & 0xc0), &info->regs->rw.ccr2);
-       if (info->flags & ASYNC_CTS_FLOW) {
-               writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_RTS), &info->regs->rw.mode);
-               writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
-               writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FCTS), &info->regs->rw.mode);
-       } else {
-               writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-               writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FRTS), &info->regs->rw.mode);
-               writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FCTS, &info->regs->rw.mode);
-       }
-       writeb(~(info->pvr_dtr_bit), &info->regs->rw.pvr);
-       writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RAC, &info->regs->rw.mode);
-       restore_flags(flags);
+       change_speed(info);
 
+       /* Now take out the pointers to static structures if necessary */
+       if (info->tty->termios == &c_termios)
+               info->tty->termios = 0;
+       if (info->tty == &c_tty)
+               info->tty = 0;
+       
        return 0;
 }
 
index 912a17ce1fc2fa606d3c34784bc33d0502ae3a85..aa08f537cf437dae373787f78c2408dd979b6c37 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.52 2001/06/29 21:54:32 davem Exp $
+/* $Id: su.c,v 1.53 2001/10/13 08:27:50 davem Exp $
  * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -6,6 +6,9 @@
  *
  * This is mainly a variation of drivers/char/serial.c,
  * credits go to authors mentioned therein.
+ *
+ * Fixed to use tty_get_baud_rate().
+ *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
  */
 
 /*
@@ -935,24 +938,18 @@ shutdown(struct su_struct *info)
 static int
 su_get_baud_rate(struct su_struct *info)
 {
-       static int baud_table[] = {
-               0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
-               4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0
-       };
-       int i;
+       static struct tty_struct c_tty;
+       static struct termios c_termios;
 
        if (info->tty)
                return tty_get_baud_rate(info->tty);
 
-       i = info->cflag & CBAUD;
-       if (i & CBAUDEX) {
-               i &= ~(CBAUDEX);
-               if (i < 1 || i > 4)
-                       info->cflag &= ~(CBAUDEX);
-               else
-                       i += 15;
-       }
-       return baud_table[i];
+       memset(&c_tty, 0, sizeof(c_tty));
+       memset(&c_termios, 0, sizeof(c_termios));
+       c_tty.termios = &c_termios;
+       c_termios.c_cflag = info->cflag;
+
+       return tty_get_baud_rate(&c_tty);
 }
 
 /*
@@ -1168,7 +1165,7 @@ su_change_mouse_baud(int baud)
        if (info->port_type != SU_PORT_MS)
                return;
 
-       info->cflag &= ~(CBAUDEX | CBAUD);
+       info->cflag &= ~CBAUD;
        switch (baud) {
                case 1200:
                        info->cflag |= B1200;
@@ -2255,7 +2252,7 @@ done:
  */
 static __inline__ void __init show_su_version(void)
 {
-       char *revision = "$Revision: 1.52 $";
+       char *revision = "$Revision: 1.53 $";
        char *version, *p;
 
        version = strchr(revision, ' ');
index c4d4bc50dcebc82dd265b4eac79075790a8a86d3..aefea3d09bf1e8c3b3231ee3035c00d455b776fc 100644 (file)
@@ -1,9 +1,12 @@
-/* $Id: zs.c,v 1.66 2001/06/29 21:33:22 davem Exp $
+/* $Id: zs.c,v 1.67 2001/10/13 08:27:50 davem Exp $
  * zs.c: Zilog serial port driver for the Sparc.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  * Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
  * Fixes by Pete A. Zaitcev <zaitcev@yahoo.com>.
+ *
+ * Fixed to use tty_get_baud_rate().
+ *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
  */
 
 #include <linux/errno.h>
@@ -241,12 +244,6 @@ static inline int serial_paranoia_check(struct sun_serial *info,
        return 0;
 }
 
-/* This is used to figure out the divisor speeds and the timeouts. */
-static int baud_table[] = {
-       0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-       9600, 19200, 38400, 76800, 0
-};
-
 /* Reading and writing Zilog8530 registers.  The delays are to make this
  * driver work on the Sun4 which needs a settling delay after each chip
  * register access, other machines handle this in hardware via auxiliary
@@ -944,8 +941,7 @@ static void shutdown(struct sun_serial * info)
 static void change_speed(struct sun_serial *info)
 {
        unsigned cflag;
-       int     quot = 0;
-       int     i;
+       int     baud, quot = 0;
        int     brg;
 
        if (!info->tty || !info->tty->termios)
@@ -953,20 +949,12 @@ static void change_speed(struct sun_serial *info)
        cflag = info->tty->termios->c_cflag;
        if (!info->port)
                return;
-       i = cflag & CBAUD;
-       if (cflag & CBAUDEX) {
-               i &= ~CBAUDEX;
-               if (i != 5)
-                       info->tty->termios->c_cflag &= ~CBAUDEX;
-               else
-                       i = 16;
-       }
-       if (i == 15) {
-               if ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_HI)
-                       i += 1;
-               if ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_CUST)
-                       quot = info->custom_divisor;
-       }
+       baud = tty_get_baud_rate(info->tty);
+       
+       if ((baud == 38400) && 
+           ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_CUST))
+               quot = info->custom_divisor;
+
        if (quot) {
                info->zs_baud = info->baud_base / quot;
                info->clk_divisor = 16;
@@ -978,8 +966,8 @@ static void change_speed(struct sun_serial *info)
                info->curregs[13] = ((brg >> 8) & 255);
                info->curregs[14] = BRSRC | BRENAB;
                zs_rtsdtr(info, 1);
-       } else if (baud_table[i]) {
-               info->zs_baud = baud_table[i];
+       } else if (baud) {
+               info->zs_baud = baud;
                info->clk_divisor = 16;
 
                info->curregs[4] = X16CLK;
@@ -1945,7 +1933,7 @@ int zs_open(struct tty_struct *tty, struct file * filp)
 
 static void show_serial_version(void)
 {
-       char *revision = "$Revision: 1.66 $";
+       char *revision = "$Revision: 1.67 $";
        char *version, *p;
 
        version = strchr(revision, ' ');
@@ -2796,22 +2784,23 @@ static kdev_t zs_console_device(struct console *con)
 
 static int __init zs_console_setup(struct console *con, char *options)
 {
+       static struct tty_struct c_tty;
+       static struct termios c_termios;
        struct sun_serial *info;
-       int i, brg, baud;
+       int brg, baud;
 
        info = zs_soft + con->index;
        info->is_cons = 1;
 
        printk("Console: ttyS%d (Zilog8530)\n", info->line);
-
+       
        sunserial_console_termios(con);
+       memset(&c_tty, 0, sizeof(c_tty));
+       memset(&c_termios, 0, sizeof(c_termios));
+       c_tty.termios = &c_termios;
+       c_termios.c_cflag = con->cflag;
+       baud = tty_get_baud_rate(&c_tty);
 
-       i = con->cflag & CBAUD;
-       if (con->cflag & CBAUDEX) {
-               i &= ~CBAUDEX;
-               con->cflag &= ~CBAUDEX;
-       }
-       baud = baud_table[i];
        info->zs_baud = baud;
 
        switch (con->cflag & CSIZE) {
index 59f04bcfea8de1a86fb981a73958873020568c4c..59eb00ae4375781ba493f67315aaf5eac898748d 100644 (file)
@@ -1837,6 +1837,8 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
 
        pcount = next_scsi_host;
 
+       MOD_INC_USE_COUNT;
+
        /* The detect routine must carefully spinunlock/spinlock if 
           it enables interrupts, since all interrupt handlers do 
           spinlock as well.
@@ -1967,8 +1969,6 @@ static int scsi_register_host(Scsi_Host_Template * tpnt)
               (scsi_memory_upper_value - scsi_init_memory_start) / 1024);
 #endif
 
-       MOD_INC_USE_COUNT;
-
        if (out_of_space) {
                scsi_unregister_host(tpnt);     /* easiest way to clean up?? */
                return 1;
index 4a78e9a8f520f0561cabb52a83d176443021ea17..b3bf7e3c42f7180bf2eb97d94c8dfe1506f1588d 100644 (file)
@@ -152,6 +152,9 @@ static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
        int diskinfo[4];
     
        SDev = rscsi_disks[DEVICE_NR(dev)].device;
+       if (!SDev)
+               return -ENODEV;
+
        /*
         * If we are in the middle of error recovery, don't let anyone
         * else try and use this device.  Also, if error recovery fails, it
@@ -533,6 +536,8 @@ static int sd_release(struct inode *inode, struct file *file)
 
        target = DEVICE_NR(inode->i_rdev);
        SDev = rscsi_disks[target].device;
+       if (!SDev)
+               return -ENODEV;
 
        SDev->access_count--;
 
index 1c1e9cbe5a519c0ebcbd138f9b5030db8a3f5acb..1c9a1be83d95c37b6bea2abf2a259c155837cf69 100644 (file)
@@ -13168,14 +13168,14 @@ sym53c8xx_pci_init(Scsi_Host_Template *tpnt, pcidev_t pdev, ncr_device *device)
        ** in the size field.  We use normal 32-bit PCI addresses for
        ** descriptors.
        */
-       if (chip->features & FE_DAC) {
+       if (chip && (chip->features & FE_DAC)) {
                if (pci_set_dma_mask(pdev, (u64) 0xffffffffff))
                        chip->features &= ~FE_DAC_IN_USE;
                else
                        chip->features |= FE_DAC_IN_USE;
        }
 
-       if (!(chip->features & FE_DAC_IN_USE)) {
+       if (chip && !(chip->features & FE_DAC_IN_USE)) {
                if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
                        printk(KERN_WARNING NAME53C8XX
                               "32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
index 9d229a77e5e2ec59c4c9ed892a24ab19a6e7694e..341fc042046848be90554ab67b57a270c047bf50 100644 (file)
@@ -748,6 +748,24 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
         case SNDCTL_DSP_SYNC:
                /* NOP */
                return 0;
+       case SNDCTL_DSP_GETISPACE:
+       {
+               audio_buf_info info;
+               if (!bta->recording)
+                       return -EINVAL;
+               info.fragsize = bta->block_bytes>>bta->sampleshift;
+               info.fragstotal = bta->block_count;
+               info.bytes = bta->read_count;
+               info.fragments = info.bytes / info.fragsize;
+               if (debug)
+                       printk(KERN_DEBUG "btaudio: SNDCTL_DSP_GETISPACE "
+                              "returns %d/%d/%d/%d\n",
+                              info.fragsize, info.fragstotal,
+                              info.bytes, info.fragments);
+               if (copy_to_user((void *)arg, &info, sizeof(info)))
+                       return -EFAULT;
+               return 0;
+       }
 #if 0 /* TODO */
         case SNDCTL_DSP_GETTRIGGER:
         case SNDCTL_DSP_SETTRIGGER:
index 2299f1919527727d5c16aa13e83fd7d91d10bd63..400d11555629101961ba43de56b231c1d5445aa8 100644 (file)
@@ -4,8 +4,8 @@
 mainmenu_option next_comment
 comment 'USB support'
 
-tristate 'Support for USB' CONFIG_USB
-if [ ! "$CONFIG_USB" = "n" ]; then
+dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI
+if [ "$CONFIG_USB" = "y" -o  "$CONFIG_USB" = "m" ]; then
    bool '  USB verbose debug messages' CONFIG_USB_DEBUG
 
 comment 'Miscellaneous USB options'
@@ -15,73 +15,84 @@ comment 'Miscellaneous USB options'
    else
       define_bool CONFIG_USB_BANDWIDTH n
    fi
+   bool '  Long timeout for slow-responding devices (some MGE Ellipse UPSes)' CONFIG_USB_LONG_TIMEOUT
+   bool '  Large report fetching for "broken" devices (some APC UPSes)' CONFIG_USB_LARGE_CONFIG
+fi
 
 comment 'USB Controllers'
-   if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then
-      dep_tristate '  UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB
-   fi
-   if [ "$CONFIG_USB_UHCI" != "y" ]; then
-      dep_tristate '  UHCI Alternate Driver (JE) support' CONFIG_USB_UHCI_ALT $CONFIG_USB
-   fi
-   dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
+if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then
+   dep_tristate '  UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB
+fi
+if [ "$CONFIG_USB_UHCI" != "y" ]; then
+   dep_tristate '  UHCI Alternate Driver (JE) support' CONFIG_USB_UHCI_ALT $CONFIG_USB
+else
+   define_bool CONFIG_USB_UHCI_ALT n
+fi
+dep_tristate '  OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
 
-   comment 'USB Device Class drivers'
-   dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
-   dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
-   if [ "$CONFIG_USB_STORAGE" != "n" ]; then
-      bool '    USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG
-      bool '    Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM
-      bool '    ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200
-      bool '    Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM
-      if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-         bool '    HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e
-         bool '    SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09
-      fi
-   fi
-   dep_tristate '  USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
-   dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
+comment 'USB Device Class drivers'
+dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
+dep_tristate '  USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Mass Storage support' CONFIG_USB_STORAGE $CONFIG_USB $CONFIG_SCSI
+   dep_mbool '    USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG $CONFIG_USB_STORAGE
+   dep_mbool '    Datafab MDCFE-B Compact Flash Reader support' CONFIG_USB_STORAGE_DATAFAB $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+   dep_mbool '    Freecom USB/ATAPI Bridge support' CONFIG_USB_STORAGE_FREECOM  $CONFIG_USB_STORAGE
+   dep_mbool '    ISD-200 USB/ATA Bridge support' CONFIG_USB_STORAGE_ISD200 $CONFIG_USB_STORAGE
+   dep_mbool '    Microtech CompactFlash/SmartMedia support' CONFIG_USB_STORAGE_DPCM $CONFIG_USB_STORAGE
+   dep_mbool '    HP CD-Writer 82xx support' CONFIG_USB_STORAGE_HP8200e $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+   dep_mbool '    SanDisk SDDR-09 (and other SmartMedia) support' CONFIG_USB_STORAGE_SDDR09 $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+   dep_mbool '    Lexar Jumpshot Compact Flash Reader' CONFIG_USB_STORAGE_JUMPSHOT $CONFIG_USB_STORAGE $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Modem (CDC ACM) support' CONFIG_USB_ACM $CONFIG_USB
+dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
 
-   comment 'USB Human Interface Devices (HID)'
-   if [ "$CONFIG_INPUT" = "n" ]; then
-      comment '  Input core support is needed for USB HID'
-   else
-      dep_tristate '  USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT
-      if [ "$CONFIG_USB_HID" != "y" ]; then
-         dep_tristate '  USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
-         dep_tristate '  USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
-      fi
-      dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
+comment 'USB Human Interface Devices (HID)'
+if [ "$CONFIG_INPUT" = "n" ]; then
+   comment '  Input core support is needed for USB HID'
+else
+   dep_tristate '  USB Human Interface Device (full HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT
+      dep_mbool '    /dev/hiddev raw HID device support (EXPERIMENTAL)' CONFIG_USB_HIDDEV $CONFIG_USB_HID
+   if [ "$CONFIG_USB_HID" != "y" ]; then
+      dep_tristate '  USB HIDBP Keyboard (basic) support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
+      dep_tristate '  USB HIDBP Mouse (basic) support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
    fi
+   dep_tristate '  Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
+fi
 
-   comment 'USB Imaging devices'
-   dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
-   dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
-   dep_tristate '  Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
-   dep_tristate '  HP53xx USB scanner support (EXPERIMENTAL)' CONFIG_USB_HPUSBSCSI $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
+comment 'USB Imaging devices'
+dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
+dep_tristate '  USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB
+dep_tristate '  Microtek X6USB scanner support' CONFIG_USB_MICROTEK $CONFIG_USB $CONFIG_SCSI
+dep_tristate '  HP53xx USB scanner support (EXPERIMENTAL)' CONFIG_USB_HPUSBSCSI $CONFIG_USB $CONFIG_SCSI $CONFIG_EXPERIMENTAL
 
-   comment 'USB Multimedia devices'
+comment 'USB Multimedia devices'
+if [ "$CONFIG_VIDEO_DEV" = "n" ]; then
+   comment '  Video4Linux support is needed for USB Multimedia device support'
+else
    dep_tristate '  USB IBM (Xirlink) C-it Camera support' CONFIG_USB_IBMCAM $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  USB OV511 Camera support' CONFIG_USB_OV511 $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  USB Philips Cameras' CONFIG_USB_PWC $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  USB SE401 Camera support' CONFIG_USB_SE401 $CONFIG_USB $CONFIG_VIDEO_DEV
    dep_tristate '  D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL
    dep_tristate '  DABUSB driver' CONFIG_USB_DABUSB $CONFIG_USB
+fi
 
-   comment 'USB Network adaptors'
+comment 'USB Network adaptors'
+if [ "$CONFIG_NET" = "n" ]; then
+   comment '  Networking support is needed for USB Networking device support'
+else
    dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB CATC NetMate-based Ethernet driver (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB CDC Ethernet class (USB cable modem) support (EXPERIMENTAL)' CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
-   dep_tristate '  USB-to-USB Networking (NetChip, Prolific, ...) (EXPERIMENTAL)' CONFIG_USB_USBNET $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB Communication Class Ethernet device support (EXPERIMENTAL)' CONFIG_USB_CDCETHER $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB-to-USB Networking cable device support (EXPERIMENTAL)' CONFIG_USB_USBNET $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+fi
 
-   comment 'USB port drivers'
-   dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
-   source drivers/usb/serial/Config.in
+comment 'USB port drivers'
+dep_tristate '  USS720 parport driver' CONFIG_USB_USS720 $CONFIG_USB $CONFIG_PARPORT
+source drivers/usb/serial/Config.in
 
-   comment 'USB misc drivers'
-   dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
-fi
+comment 'USB Miscellaneous drivers'
+dep_tristate '  USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB $CONFIG_EXPERIMENTAL
 
 endmenu
index 8104c0cc56bfaa48969ebef89934e7d0f855ac32..9ef3801f31a4c8f70d67c425764495a153298262 100644 (file)
@@ -131,6 +131,8 @@ struct usb_eth_dev {
 #define        VENDOR_ABOCOM           0x07b8
 #define        VENDOR_ACCTON           0x083a
 #define        VENDOR_ADMTEK           0x07a6
+#define        VENDOR_ALLIEDTEL        0x07c9
+#define        VENDOR_BELKIN           0x050d
 #define        VENDOR_BILLIONTON       0x08dd
 #define        VENDOR_COREGA           0x07aa
 #define        VENDOR_DLINK            0x2001
@@ -142,7 +144,7 @@ struct usb_eth_dev {
 #define        VENDOR_SMARTBRIDGES     0x08d1
 #define        VENDOR_SMC              0x0707
 #define        VENDOR_SOHOWARE         0x15e8
-#define        VENDOR_BELKIN           0x050d
+
 
 #else  /* PEGASUS_DEV */
 
@@ -176,6 +178,10 @@ PEGASUS_DEV( "ADMtek ADM8511 \"Pegasus II\" USB Ethernet",
 PEGASUS_DEV( "ADMtek AN986 \"Pegasus\" USB Ethernet (eval. board)",
                VENDOR_ADMTEK, 0x0986,
                DEFAULT_GPIO_RESET | HAS_HOME_PNA )
+PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
+               DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121,
+               DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
                DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "Billionton USBLP-100", VENDOR_BILLIONTON, 0x0987,
@@ -236,8 +242,6 @@ PEGASUS_DEV( "SMC 202 USB Ethernet", VENDOR_SMC, 0x0200,
                DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "SOHOware NUB100 Ethernet", VENDOR_SOHOWARE, 0x9100,
                DEFAULT_GPIO_RESET )
-PEGASUS_DEV( "Belkin F5D5050 USB Ethernet",
-               VENDOR_BELKIN, 0x0121,
-               DEFAULT_GPIO_RESET | PEGASUS_II )
+
 
 #endif /* PEGASUS_DEV */
index 8c20d5f37c66c1a08757221930201cbae9e30542..ed729fdc6666b94f68216c3c4651a00e96cc1007 100644 (file)
@@ -495,7 +495,7 @@ void pwc_set_image_buffer_size(struct pwc_device *pdev)
 }
 
 
-#ifdef __KERNEL__
+
 /* BRIGHTNESS */
 
 int pwc_get_brightness(struct pwc_device *pdev)
@@ -983,6 +983,7 @@ static inline int pwc_read_red_gain(struct pwc_device *pdev)
        
        return (buf << 8);
 }
+
 static inline int pwc_read_blue_gain(struct pwc_device *pdev)
 {
        unsigned char buf;
@@ -1001,43 +1002,55 @@ static inline int pwc_read_blue_gain(struct pwc_device *pdev)
        return (buf << 8);
 }
 
-/* still unused (it doesn't work yet...) */
-static inline int pwc_set_led(struct pwc_device *pdev, int value)
+int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
 {
-       unsigned char buf;
-
-       if (value < 0)
-               value = 0;
-       if (value > 0xffff)
-               value = 0xffff;
-
-       buf = (value >> 8);
+       unsigned char buf[2];
+
+       if (pdev->type < 730)
+               return 0;
+       if (on_value < 0)
+               on_value = 0;
+       if (on_value > 0xff)
+               on_value = 0xff;
+       if (off_value < 0)
+               off_value = 0;
+       if (off_value > 0xff)
+               off_value = 0xff;
+
+       buf[0] = on_value;
+       buf[1] = off_value;
 
        return usb_control_msg(pdev->udev, usb_sndctrlpipe(pdev->udev, 0),
                SET_STATUS_CTL,
                USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                LED_FORMATTER,
                pdev->vcinterface,
-               &buf, 1, HZ / 2);
+               &buf, 2, HZ / 2);
 }
 
-/* still unused (it doesn't work yet...) */
-static inline int pwc_get_led(struct pwc_device *pdev)
+int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value)
 {
-       unsigned char buf;
+       unsigned char buf[2];
        int ret;
        
+       if (pdev->type < 730) {
+               *on_value = -1;
+               *off_value = -1;
+               return 0;
+       }
+
        ret = usb_control_msg(pdev->udev, usb_rcvctrlpipe(pdev->udev, 0),
                GET_STATUS_CTL,
                USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
                LED_FORMATTER,
                pdev->vcinterface,
-               &buf, 1, HZ / 2);
+               &buf, 2, HZ / 2);
 
        if (ret < 0)
-           return ret;
-       
-       return (buf << 8);
+               return ret;
+       *on_value = buf[0];
+       *off_value = buf[1];
+       return 0;
 }
 
  /* End of Add-Ons                                    */
@@ -1167,15 +1180,15 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
 
         case VIDIOCPWCSLED:
        {
-           int led, ret;
-           if (copy_from_user(&led,arg,sizeof(led)))
-               return -EFAULT;
-           else {
-               /* ret = pwc_set_led(pdev, led); */
-               ret = 0;
+               int ret;
+               struct pwc_leds leds;
+
+               if (copy_from_user(&leds, arg, sizeof(leds)))
+                       return -EFAULT;
+
+               ret = pwc_set_leds(pdev, leds.led_on, leds.led_off);
                if (ret<0)
                    return ret;
-           }
            break;
        }
 
@@ -1184,11 +1197,12 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
        case VIDIOCPWCGLED:
        {
                int led;
+               struct pwc_leds leds;
                
-               led = pwc_get_led(pdev); 
+               led = pwc_get_leds(pdev, &leds.led_on, &leds.led_off); 
                if (led < 0)
                        return -EINVAL;
-               if (copy_to_user(arg, &led, sizeof(led)))
+               if (copy_to_user(arg, &leds, sizeof(leds)))
                        return -EFAULT;
                break;
        }
@@ -1203,8 +1217,5 @@ int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
        return 0;
 }
 
-#endif
-
-
 
 
index f33d427417cdb88f04d03c7083e1a2e7deb8cc39..5325cafa1a11ee26859950cc45dfe48f3e2a5a5f 100644 (file)
@@ -73,7 +73,9 @@ static __devinitdata struct usb_device_id pwc_device_table [] = {
        { USB_DEVICE(0x0471, 0x0311) },
        { USB_DEVICE(0x0471, 0x0312) },
        { USB_DEVICE(0x069A, 0x0001) },
-       { USB_DEVICE(0x046D, 0x0b80) },
+       { USB_DEVICE(0x046D, 0x08b0) },
+       { USB_DEVICE(0x055D, 0x9000) },
+       { USB_DEVICE(0x055D, 0x9001) },
        { }
 };
 MODULE_DEVICE_TABLE(usb, pwc_device_table);
@@ -96,6 +98,7 @@ static int default_fbufs = 3;   /* Default number of frame buffers */
 static int default_mbufs = 2;  /* Default number of mmap() buffers */
        int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
 static int power_save = 0;
+static int led_on = 1, led_off = 0; /* defaults to LED that is on while in use */
 int pwc_preferred_compression = 2; /* 0..3 = uncompressed..high */
 
 static struct semaphore mem_lock;
@@ -592,7 +595,8 @@ static inline void pwc_next_image(struct pwc_device *pdev)
        pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
 }
 
-/* XXX: 2001-06-17: The YUV420 palette will be phased out soon */
+/* 2001-10-14: The YUV420 is still there, but you can only set it from within 
+   a program (YUV420P being the default) */
 static int pwc_set_palette(struct pwc_device *pdev, int pal)
 {
        if (   pal == VIDEO_PALETTE_YUV420
@@ -947,14 +951,16 @@ static int pwc_video_open(struct video_device *vdev, int mode)
                        Info("Failed to set alternate interface to 0.\n");
                pdev->usb_init = 1;
        }
-       else {
-               /* Turn on camera */
-               if (power_save) {
-                       i = pwc_camera_power(pdev, 1);
-                       if (i < 0)
-                               Info("Failed to restore power to the camera! (%d)\n", i);
-               }
+
+       /* Turn on camera */
+       if (power_save) {
+               i = pwc_camera_power(pdev, 1);
+               if (i < 0)
+                       Info("Failed to restore power to the camera! (%d)\n", i);
        }
+       /* Set LED on/off time */
+       if (pwc_set_leds(pdev, led_on, led_off) < 0)
+               Info("Failed to set LED on/off time.\n");
 
        /* Find our decompressor, if any */
        pdev->decompressor = pwc_find_decompressor(pdev->type);
@@ -1007,6 +1013,7 @@ static int pwc_video_open(struct video_device *vdev, int mode)
                up(&pdev->modlock);
                return i;
        }
+       
        i = usb_set_interface(pdev->udev, 0, pdev->valternate);
        if (i) {
                Trace(TRACE_OPEN, "Failed to set alternate interface = %d.\n", i);
@@ -1066,7 +1073,10 @@ static void pwc_video_close(struct video_device *vdev)
                Trace(TRACE_OPEN, "Normal close(): setting interface to 0.\n");
                usb_set_interface(pdev->udev, 0, 0);
 
-               /* Turn off LED by powering down camera */
+               /* Turn LEDs off */
+               if (pwc_set_leds(pdev, 0, 0) < 0)
+                       Info("Failed to set LED on/off time..\n");
+               /* Power down camere to save energy */
                if (power_save) {
                        i = pwc_camera_power(pdev, 0);
                        if (i < 0) 
@@ -1121,19 +1131,19 @@ static long pwc_video_read(struct video_device *vdev, char *buf, unsigned long c
                while (pdev->full_frames == NULL) {
                        if (noblock) {
                                remove_wait_queue(&pdev->frameq, &wait);
-                               current->state = TASK_RUNNING;
+                               set_current_state(TASK_RUNNING);
                                return -EWOULDBLOCK;
                        }
                        if (signal_pending(current)) {
                                remove_wait_queue(&pdev->frameq, &wait);
-                               current->state = TASK_RUNNING;
+                               set_current_state(TASK_RUNNING);
                                return -ERESTARTSYS;
                        }
                        schedule();
-                       current->state = TASK_INTERRUPTIBLE;
+                       set_current_state(TASK_INTERRUPTIBLE);
                }
                remove_wait_queue(&pdev->frameq, &wait);
-               current->state = TASK_RUNNING;
+               set_current_state(TASK_RUNNING);
                                                                                                                                                                                        
                /* Decompress [, convert] and release frame */
                if (pwc_handle_frame(pdev))
@@ -1473,14 +1483,14 @@ static int pwc_video_ioctl(struct video_device *vdev, unsigned int cmd, void *ar
                        while (pdev->full_frames == NULL) {
                                if (signal_pending(current)) {
                                        remove_wait_queue(&pdev->frameq, &wait);
-                                       current->state = TASK_RUNNING;
+                                       set_current_state(TASK_RUNNING);
                                        return -ERESTARTSYS;
                                }
                                schedule();
-                               current->state = TASK_INTERRUPTIBLE;
+                               set_current_state(TASK_INTERRUPTIBLE);
                        }
                        remove_wait_queue(&pdev->frameq, &wait);
-                       current->state = TASK_RUNNING;
+                       set_current_state(TASK_RUNNING);
                                
                        /* The frame is ready. Expand in the image buffer 
                           requested by the user. I don't care if you 
@@ -1656,18 +1666,37 @@ static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const st
                        break;
                }
        }
-        else if (vendor_id == 0x046d) {
-               switch(product_id) {
-               case 0x08b0:
-                       Info("Logitech QuickCam 3000 Pro detected.\n");
-                       type_id = 730;
+       else if (vendor_id == 0x046d) {
+               switch(product_id) {
+               case 0x08b0:
+                       Info("Logitech QuickCam 3000 Pro detected.\n");
+                       type_id = 730;
                        break;
                default:
                        return NULL;
                        break;
                }
         }
-        else return NULL; /* Not Philips or Askey, for sure. */
+       else if (vendor_id == 0x055d) {
+               /* I don't know the difference between the C10 and the C30;
+                  I suppose the difference is the sensor, but both cameras
+                  work equally well with a type_id of 675
+                */
+               switch(product_id) {
+               case 0x9000:
+                       Info("Samsung MPC-C10 USB webcam detected.\n");
+                       type_id = 675;
+                       break;
+               case 0x9001:
+                       Info("Samsung MPC-C30 USB webcam detected.\n");
+                       type_id = 675;
+                       break;
+               default:
+                       return NULL;
+                       break;
+               }
+       }
+       else return NULL; /* Not Philips, Askey, Logitech or Samsung, for sure. */
 
        if (udev->descriptor.bNumConfigurations > 1)
                Info("Warning: more than 1 configuration available.\n");
@@ -1799,19 +1828,17 @@ static void usb_pwc_disconnect(struct usb_device *udev, void *ptr)
 
 static char *size = NULL;
 static int fps = 0;
-static char *palette = NULL;
 static int fbufs = 0;
 static int mbufs = 0;
 static int trace = -1;
 static int compression = -1;
+static int leds[2] = { -1, -1 };
 
 MODULE_PARM(video_nr, "i");
 MODULE_PARM(size, "s");
 MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
 MODULE_PARM(fps, "i");
 MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
-MODULE_PARM(palette, "s");
-MODULE_PARM_DESC(palette, "Initial colour format of images. One of yuv420, yuv420p");
 MODULE_PARM(fbufs, "i");
 MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
 MODULE_PARM(mbufs, "i");
@@ -1822,7 +1849,8 @@ MODULE_PARM(power_save, "i");
 MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
 MODULE_PARM(compression, "i");
 MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
-
+MODULE_PARM(leds, "2i");
+MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
 MODULE_DESCRIPTION("Philips USB webcam driver");
 MODULE_AUTHOR("Nemosoft Unv. <nemosoft@smcc.demon.nl>");
 MODULE_LICENSE("GPL");
@@ -1833,7 +1861,7 @@ static int __init usb_pwc_init(void)
        char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
 
        Info("Philips PCA645/646 + PCVC675/680/690 + PCVC730/740/750 webcam module version " PWC_VERSION " loaded.\n");
-       Info("Also supports Askey VC010 cam.\n");
+       Info("Also supports the Askey VC010, Logitech Quickcam 3000 Pro and the Samsung MPC-C10 and MPC-C30.\n");
 
        if (fps) {
                if (fps < 5 || fps > 30) {
@@ -1858,18 +1886,6 @@ static int __init usb_pwc_init(void)
                }
                Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
        }
-       if (palette) {
-               /* Determine default palette */
-               if (!strcmp(palette, "yuv420"))
-                       default_palette = VIDEO_PALETTE_YUV420;
-               else if (!strcmp(palette, "yuv420p"))
-                       default_palette = VIDEO_PALETTE_YUV420P;
-               else {
-                       Err("Palette not recognized: try palette=yuv420 or yuv420p.\n");
-                       return -EINVAL;
-               }
-               Info("Default palette set to %d.\n", default_palette);
-       }
        if (mbufs) {
                if (mbufs < 1 || mbufs > MAX_IMAGES) {
                        Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
@@ -1900,6 +1916,10 @@ static int __init usb_pwc_init(void)
        }
        if (power_save)
                Info("Enabling power save on open/close.\n");
+       if (leds[0] >= 0)
+               led_on = leds[0] / 100;
+       if (leds[1] >= 0)
+               led_off = leds[1] / 100;
 
        init_MUTEX(&mem_lock);
        Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
index 8a84b437a757c2aeee047f8b850bc85520807d06..19b267a4cdd11b38e4144e4c7e852b55caeffa94 100644 (file)
@@ -76,6 +76,15 @@ struct pwc_whitebalance
 };
 
 
+/* Used with VIDIOCPWC[SG]LED */
+struct pwc_leds
+{
+       int led_on;                     /* Led on-time; range = 0..255 */
+       int led_off;                    /*  */
+};
+
+
+
  /* Restore user settings */
 #define VIDIOCPWCRUSER         _IO('v', 192)
  /* Save user settings */
@@ -107,9 +116,8 @@ struct pwc_whitebalance
 #define VIDIOCPWCGAWB           _IOR('v', 202, struct pwc_whitebalance)
 
  /* Turn LED on/off ; int range 0..65535 */
-#define VIDIOCPWCSLED           _IOW('v', 205, int)
-
+#define VIDIOCPWCSLED           _IOW('v', 205, struct pwc_leds)
  /* Get state of LED; int range 0..65535 */
-#define VIDIOCPWCGLED           _IOR('v', 205, int)
+#define VIDIOCPWCGLED           _IOR('v', 205, struct pwc_leds)
 
 #endif
index a8404a4ac240455d56200c9493635a257533406d..054d369db4e51802c6218368bbd57a22a9494d5a 100644 (file)
@@ -60,8 +60,8 @@
 
 /* Version block */
 #define PWC_MAJOR      8
-#define PWC_MINOR      2
-#define PWC_VERSION    "8.2"
+#define PWC_MINOR      3
+#define PWC_VERSION    "8.3"
 #define PWC_NAME       "pwc"
 
 /* Turn certain features on/off */
@@ -245,6 +245,8 @@ extern int pwc_get_gamma(struct pwc_device *pdev);
 extern int pwc_set_gamma(struct pwc_device *pdev, int value);
 extern int pwc_get_saturation(struct pwc_device *pdev);
 extern int pwc_set_saturation(struct pwc_device *pdev, int value);
+extern int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value);
+extern int pwc_get_leds(struct pwc_device *pdev, int *on_value, int *off_value);
 
 /* Power down or up the camera; not supported by all models */
 extern int pwc_camera_power(struct pwc_device *pdev, int power);
index 8cc4bb2d64e78d32103bfa6a472b63b2458b0f8e..62176c43682a5e4d24871c46b689309b4b80b877 100644 (file)
@@ -5,36 +5,32 @@ mainmenu_option next_comment
 comment 'USB Serial Converter support'
 
 dep_tristate 'USB Serial Converter support' CONFIG_USB_SERIAL $CONFIG_USB
-if [ "$CONFIG_USB_SERIAL" != "n" ]; then
-  if [ "$CONFIG_USB_SERIAL" = "y" ]; then
-     bool '  USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG
-  fi
-  bool '  USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC
-  dep_tristate '  USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
-  dep_tristate '  USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
-  dep_tristate '  USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB Inside Out Edgeport Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  if [ "$CONFIG_USB_SERIAL_KEYSPAN" != "n" ]; then
-     bool '    USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28
-     bool '    USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X
-     bool '    USB Keyspan USA-28XA Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XA
-     bool '    USB Keyspan USA-28XB Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XB
-     bool '    USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19
-     bool '    USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X
-     bool '    USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W
-     bool '    USB Keyspan USA-49W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA49W
-  fi
-  dep_tristate '  USB MCT Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_MCT_U232 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB Prolific 2303 Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_PL2303 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)' CONFIG_USB_SERIAL_CYBERJACK $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB Xircom / Entregra Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_XIRCOM $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
-  dep_tristate '  USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+if [ "$CONFIG_USB_SERIAL" = "y" ]; then
+  dep_mbool '  USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG $CONFIG_USB_SERIAL
 fi
+dep_mbool '  USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC $CONFIG_USB_SERIAL
+dep_tristate '  USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Digi International AccelePort USB Serial Driver' CONFIG_USB_SERIAL_DIGI_ACCELEPORT $CONFIG_USB_SERIAL
+dep_tristate '  USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
+dep_tristate '  USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Inside Out Edgeport Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Keyspan USA-xxx Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+   dep_mbool '    USB Keyspan USA-28 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28 $CONFIG_USB_SERIAL_KEYSPAN
+   dep_mbool '    USB Keyspan USA-28X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28X $CONFIG_USB_SERIAL_KEYSPAN
+   dep_mbool '    USB Keyspan USA-28XA Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XA $CONFIG_USB_SERIAL_KEYSPAN
+   dep_mbool '    USB Keyspan USA-28XB Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA28XB $CONFIG_USB_SERIAL_KEYSPAN
+   dep_mbool '    USB Keyspan USA-19 Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19 $CONFIG_USB_SERIAL_KEYSPAN
+   dep_mbool '    USB Keyspan USA-18X Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA18X $CONFIG_USB_SERIAL_KEYSPAN
+   dep_mbool '    USB Keyspan USA-19W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA19W $CONFIG_USB_SERIAL_KEYSPAN
+   dep_mbool '    USB Keyspan USA-49W Firmware' CONFIG_USB_SERIAL_KEYSPAN_USA49W $CONFIG_USB_SERIAL_KEYSPAN
+dep_tristate '  USB MCT Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_MCT_U232 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Prolific 2303 Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_PL2303 $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB REINER SCT cyberJack pinpad/e-com chipcard reader (EXPERIMENTAL)' CONFIG_USB_SERIAL_CYBERJACK $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB Xircom / Entregra Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_XIRCOM $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
+dep_tristate '  USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_OMNINET $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
 
 endmenu
index d928e72bd0680d69471df4c513f5f2e822e0773b..511df4453efe7c7e95092785981c2487b6be02b5 100644 (file)
@@ -159,7 +159,7 @@ static inline void uhci_set_next_interrupt(struct uhci *uhci)
        unsigned long flags;
 
        spin_lock_irqsave(&uhci->frame_list_lock, flags);
-       uhci->skel_term_td->status |= TD_CTRL_IOC;
+       set_bit(TD_CTRL_IOC_BIT, &uhci->skel_term_td->status);
        spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
 }
 
@@ -168,7 +168,7 @@ static inline void uhci_clear_next_interrupt(struct uhci *uhci)
        unsigned long flags;
 
        spin_lock_irqsave(&uhci->frame_list_lock, flags);
-       uhci->skel_term_td->status &= ~TD_CTRL_IOC;
+       clear_bit(TD_CTRL_IOC_BIT, &uhci->skel_term_td->status);
        spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
 }
 
@@ -796,7 +796,7 @@ static int uhci_map_status(int status, int dir_out)
        if (status & TD_CTRL_NAK)                       /* NAK */
                return -ETIMEDOUT;
        if (status & TD_CTRL_BABBLE)                    /* Babble */
-               return -EPIPE;
+               return -EOVERFLOW;
        if (status & TD_CTRL_DBUFERR)                   /* Buffer error */
                return -ENOSR;
        if (status & TD_CTRL_STALLED)                   /* Stalled */
@@ -961,7 +961,7 @@ static int uhci_result_control(struct urb *urb)
                    !(td->status & TD_CTRL_ACTIVE)) {
                        uhci_inc_fsbr(urb->dev->bus->hcpriv, urb);
                        urbp->fsbr_timeout = 0;
-                       td->status &= ~TD_CTRL_IOC;
+                       clear_bit(TD_CTRL_IOC_BIT, &td->status);
                }
 
                status = uhci_status_bits(td->status);
@@ -1134,7 +1134,7 @@ static int uhci_result_interrupt(struct urb *urb)
                    !(td->status & TD_CTRL_ACTIVE)) {
                        uhci_inc_fsbr(urb->dev->bus->hcpriv, urb);
                        urbp->fsbr_timeout = 0;
-                       td->status &= ~TD_CTRL_IOC;
+                       clear_bit(TD_CTRL_IOC_BIT, &td->status);
                }
 
                status = uhci_status_bits(td->status);
@@ -1796,7 +1796,7 @@ static int uhci_fsbr_timeout(struct uhci *uhci, struct urb *urb)
                tmp = tmp->next;
 
                if (td->status & TD_CTRL_ACTIVE) {
-                       td->status |= TD_CTRL_IOC;
+                       set_bit(TD_CTRL_IOC_BIT, &td->status);
                        break;
                }
        }
index 0955c37f3fdce9afd8a956fbb3b24283cc2b78f2..d9e728b299633e348e650ebe6a58bd0681161a9f 100644 (file)
@@ -100,6 +100,7 @@ struct uhci_qh {
 #define TD_CTRL_C_ERR_SHIFT    27
 #define TD_CTRL_LS             (1 << 26)       /* Low Speed Device */
 #define TD_CTRL_IOS            (1 << 25)       /* Isochronous Select */
+#define TD_CTRL_IOC_BIT                24
 #define TD_CTRL_IOC            (1 << 24)       /* Interrupt on Complete */
 #define TD_CTRL_ACTIVE         (1 << 23)       /* TD Active */
 #define TD_CTRL_STALLED                (1 << 22)       /* TD Stalled */
index 815ae2060c97fdf3eb13a38c123446ca24a6531c..94b261d3855134691fa60ea0ea08d870bef86a79 100644 (file)
@@ -537,11 +537,7 @@ static void ultracam_configure_video(uvd_t *uvd)
  * 12-Nov-2000 Reworked to comply with new probe() signature.
  * 23-Jan-2001 Added compatibility with 2.2.x kernels.
  */
-static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum
-#if defined(usb_device_id_ver)
-       ,const struct usb_device_id *devid
-#endif
-       )
+static void *ultracam_probe(struct usb_device *dev, unsigned int ifnum ,const struct usb_device_id *devid)
 {
        uvd_t *uvd = NULL;
        int i, nas;
index 542086dde76749caad5446a6e256d0dac6187a99..73524b31c25367c2ab30c556567185eb218c7aa4 100644 (file)
@@ -2193,7 +2193,7 @@ _static int uhci_map_status (int status, int dir_out)
        if (status & TD_CTRL_NAK)       /* NAK */
                return -ETIMEDOUT;
        if (status & TD_CTRL_BABBLE)    /* Babble */
-               return -EPIPE;
+               return -EOVERFLOW;
        if (status & TD_CTRL_DBUFERR)   /* Buffer error */
                return -ENOSR;
        if (status & TD_CTRL_STALLED)   /* Stalled */
index 02fffe207d641fffa530993456fade183d82a21a..2e4024b7d81d9a8e5607087aa7bc2ddb9119a6c9 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.25 2001/09/19 00:04:33 davem Exp $
+/* $Id: cgsixfb.c,v 1.26 2001/10/16 05:44:44 davem Exp $
  * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
  *
  * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
index ebee285381bcafff0114d1d55b73951bf30883ac..b5071d2d3360ce71fa705b26fc9e289d0cee3719 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.36 2001/09/19 00:04:33 davem Exp $
+/* $Id: creatorfb.c,v 1.37 2001/10/16 05:44:44 davem Exp $
  * creatorfb.c: Creator/Creator3D frame buffer driver
  *
  * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
index aabe26b92ab413612741cfa4fa701fd203b895b8..1bd5cfa0d0f2258e787ec1290be0772fffb8340f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: leofb.c,v 1.13 2001/09/19 00:04:33 davem Exp $
+/* $Id: leofb.c,v 1.14 2001/10/16 05:44:44 davem Exp $
  * leofb.c: Leo (ZX) 24/8bit frame buffer driver
  *
  * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
index 4f1deb1d7debe4c351358fca2cae7dd47786805e..42ba99f03e3c5f178a2fc52b8ee9b6c13bf0fa74 100644 (file)
@@ -508,11 +508,13 @@ static void __insert_into_lru_list(struct buffer_head * bh, int blist)
        size_buffers_type[blist] += bh->b_size;
 }
 
-static void __remove_from_lru_list(struct buffer_head * bh, int blist)
+static void __remove_from_lru_list(struct buffer_head * bh)
 {
        struct buffer_head *next = bh->b_next_free;
        if (next) {
                struct buffer_head *prev = bh->b_prev_free;
+               int blist = bh->b_list;
+
                prev->b_next_free = next;
                next->b_prev_free = prev;
                if (lru_list[blist] == bh) {
@@ -532,7 +534,7 @@ static void __remove_from_lru_list(struct buffer_head * bh, int blist)
 static void __remove_from_queues(struct buffer_head *bh)
 {
        __hash_unlink(bh);
-       __remove_from_lru_list(bh, bh->b_list);
+       __remove_from_lru_list(bh);
 }
 
 struct buffer_head * get_hash_table(kdev_t dev, int block, int size)
@@ -1101,7 +1103,7 @@ static void __refile_buffer(struct buffer_head *bh)
        if (buffer_dirty(bh))
                dispose = BUF_DIRTY;
        if (dispose != bh->b_list) {
-               __remove_from_lru_list(bh, bh->b_list);
+               __remove_from_lru_list(bh);
                bh->b_list = dispose;
                if (dispose == BUF_CLEAN)
                        remove_inode_queue(bh);
@@ -1134,8 +1136,26 @@ void __brelse(struct buffer_head * buf)
  */
 void __bforget(struct buffer_head * buf)
 {
-       /* mark_buffer_clean(bh); */
-       __brelse(buf);
+       /* grab the lru lock here so that "b_count" is stable */
+       spin_lock(&lru_list_lock);
+       write_lock(&hash_table_lock);
+       if (!atomic_dec_and_test(&buf->b_count) || buffer_locked(buf))
+               goto in_use;
+
+       /* Mark it clean */
+       clear_bit(BH_Dirty, &buf->b_state);
+       write_unlock(&hash_table_lock);
+
+       /* After which we can remove it from all queues */
+       remove_inode_queue(buf);
+       __remove_from_lru_list(buf);
+       buf->b_list = BUF_CLEAN;
+       spin_unlock(&lru_list_lock);
+       return;
+
+in_use:
+       write_unlock(&hash_table_lock);
+       spin_unlock(&lru_list_lock);
 }
 
 /**
index 85134f0b369b8a4f229188984e23baad7ffde6f6..3bcdaae4e024e8daba829bbdead37d2830242559 100644 (file)
@@ -100,7 +100,7 @@ static LIST_HEAD(entry_in_use);
 static LIST_HEAD(entry_unused);
 static struct list_head hash_table[C_HASHSIZE];
 
-spinlock_t entry_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t entry_lock = SPIN_LOCK_UNLOCKED;
 
 static struct {
         int nr_entries;
index 42bbfef9b1160542f187a3784f6af237d4352e54..c00e8c22c5dcb5ccc6cd04c44872469eddd5d8a4 100644 (file)
@@ -646,10 +646,14 @@ int path_walk(const char * name, struct nameidata *nd)
 static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
 {
        if (path_walk(name, nd))
-               return 0;
+               return 0;               /* something went wrong... */
 
-       if (!nd->dentry->d_inode) {
+       if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) {
                struct nameidata nd_root;
+               /*
+                * NAME was not found in alternate root or it's a directory.  Try to find
+                * it in the normal root:
+                */
                nd_root.last_type = LAST_ROOT;
                nd_root.flags = nd->flags;
                read_lock(&current->fs->lock);
index d1101b4438ef78f2886cf5618a2a0e8e4c44bb75..c15de9f71aea3ce7c60ae6dd0470b87da0acef62 100644 (file)
@@ -153,6 +153,8 @@ clone_mnt(struct vfsmount *old, struct dentry *root)
                atomic_inc(&sb->s_active);
                mnt->mnt_sb = sb;
                mnt->mnt_root = dget(root);
+               mnt->mnt_mountpoint = mnt->mnt_root;
+               mnt->mnt_parent = mnt;
        }
        return mnt;
 }
@@ -1086,7 +1088,7 @@ int __init change_root(kdev_t new_root_dev,const char *put_old)
                printk(KERN_NOTICE "Trying to unmount old root ... ");
                if (!blivet) {
                        spin_lock(&dcache_lock);
-                       list_del(&old_rootmnt->mnt_list);
+                       list_del_init(&old_rootmnt->mnt_list);
                        spin_unlock(&dcache_lock);
                        mntput(old_rootmnt);
                        mntput(old_rootmnt);
index 1086f684ab4267efe900128ddc198740fa4659df..1badebc153727a2373efdf3127b00a4bccd1a112 100644 (file)
@@ -86,8 +86,8 @@ nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
 {
        int     nfserr;
 
-       dprintk("nfsd: LOOKUP   %s %s\n",
-               SVCFH_fmt(&argp->fh), argp->name);
+       dprintk("nfsd: LOOKUP   %s %.*s\n",
+               SVCFH_fmt(&argp->fh), argp->len, argp->name);
 
        fh_init(&resp->fh, NFS_FHSIZE);
        nfserr = nfsd_lookup(rqstp, &argp->fh, argp->name, argp->len,
@@ -199,8 +199,8 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
        int             nfserr, type, mode;
        dev_t           rdev = NODEV;
 
-       dprintk("nfsd: CREATE   %s %s\n",
-               SVCFH_fmt(dirfhp), argp->name);
+       dprintk("nfsd: CREATE   %s %*.s\n",
+               SVCFH_fmt(dirfhp), argp->len, argp->name);
 
        /* First verify the parent file handle */
        nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, MAY_EXEC);
@@ -349,7 +349,8 @@ nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
 {
        int     nfserr;
 
-       dprintk("nfsd: REMOVE   %s %s\n", SVCFH_fmt(&argp->fh), argp->name);
+       dprintk("nfsd: REMOVE   %s %.*s\n", SVCFH_fmt(&argp->fh),
+               argp->len, argp->name);
 
        /* Unlink. -SIFDIR means file must not be a directory */
        nfserr = nfsd_unlink(rqstp, &argp->fh, -S_IFDIR, argp->name, argp->len);
@@ -363,10 +364,10 @@ nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp,
 {
        int     nfserr;
 
-       dprintk("nfsd: RENAME   %s %s -> \n",
-               SVCFH_fmt(&argp->ffh), argp->fname);
-       dprintk("nfsd:        ->  %s %s\n",
-               SVCFH_fmt(&argp->tfh), argp->tname);
+       dprintk("nfsd: RENAME   %s %.*s -> \n",
+               SVCFH_fmt(&argp->ffh), argp->flen, argp->fname);
+       dprintk("nfsd:        ->  %s %.*s\n",
+               SVCFH_fmt(&argp->tfh), argp->tlen, argp->tname);
 
        nfserr = nfsd_rename(rqstp, &argp->ffh, argp->fname, argp->flen,
                                    &argp->tfh, argp->tname, argp->tlen);
@@ -383,8 +384,9 @@ nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp,
 
        dprintk("nfsd: LINK     %s ->\n",
                SVCFH_fmt(&argp->ffh));
-       dprintk("nfsd:    %s %s\n",
+       dprintk("nfsd:    %s %.*s\n",
                SVCFH_fmt(&argp->tfh),
+               argp->tlen,
                argp->tname);
 
        nfserr = nfsd_link(rqstp, &argp->tfh, argp->tname, argp->tlen,
@@ -401,8 +403,9 @@ nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp,
        struct svc_fh   newfh;
        int             nfserr;
 
-       dprintk("nfsd: SYMLINK  %s %s -> %s\n",
-               SVCFH_fmt(&argp->ffh), argp->fname, argp->tname);
+       dprintk("nfsd: SYMLINK  %s %.*s -> %.*s\n",
+               SVCFH_fmt(&argp->ffh), argp->flen, argp->fname,
+               argp->tlen, argp->tname);
 
        fh_init(&newfh, NFS_FHSIZE);
        /*
@@ -428,7 +431,7 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp,
 {
        int     nfserr;
 
-       dprintk("nfsd: MKDIR    %s %s\n", SVCFH_fmt(&argp->fh), argp->name);
+       dprintk("nfsd: MKDIR    %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
 
        if (resp->fh.fh_dentry) {
                printk(KERN_WARNING
@@ -452,7 +455,7 @@ nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp,
 {
        int     nfserr;
 
-       dprintk("nfsd: RMDIR    %s %s\n", SVCFH_fmt(&argp->fh), argp->name);
+       dprintk("nfsd: RMDIR    %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name);
 
        nfserr = nfsd_unlink(rqstp, &argp->fh, S_IFDIR, argp->name, argp->len);
        fh_put(&argp->fh);
index 46663c428aeef553ad8514616b10542babc271ce..6cc44031e4e00bbf631083e7b7cc0500f64a0126 100644 (file)
@@ -162,7 +162,7 @@ nfsd(struct svc_rqst *rqstp)
        lock_kernel();
        daemonize();
        sprintf(current->comm, "nfsd");
-       current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; 
+       current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 
        nfsdstats.th_cnt++;
        /* Let svc_process check client's authentication. */
index 8d25e5095f130ccdfda708e88bce25828ee151db..0ee659ed43d853c25c4ee7cac0220e586b287e6e 100644 (file)
@@ -86,7 +86,6 @@ decode_pathname(u32 *p, char **namp, int *lenp)
                        if (*name == '\0')
                                return NULL;
                }
-               *name = '\0';
        }
 
        return p;
index ac4539946a29f40edd87fc4664cdcbe17675a8c0..97dabb0ba6734d756cbe4e76490c138b1b338cf4 100644 (file)
@@ -150,7 +150,7 @@ extern void udf_release_data(struct buffer_head *);
 
 /* lowlevel.c */
 extern unsigned int udf_get_last_session(struct super_block *);
-extern unsigned int udf_get_last_block(struct super_block *);
+extern unsigned long udf_get_last_block(struct super_block *);
 
 /* partition.c */
 extern Uint32 udf_get_pblock(struct super_block *, Uint32, Uint16, Uint32);
index 481f324e36ddb527cc9730ccf03ec20708e8466c..cfcaa64f00fd3ccdf80620379233b2fd561f6c33 100644 (file)
@@ -349,4 +349,6 @@ extern void __global_restore_flags(unsigned long);
 void disable_hlt(void);
 void enable_hlt(void);
 
+extern int is_sony_vaio_laptop;
+
 #endif
index ebd216dd490d5195415f7220704ba723e3113883..36de103c240a293cd9b75d0b37bc55724a7cba8e 100644 (file)
 #define __NR_fcntl64           221
 #define __NR_security          223     /* syscall for security modules */
 #define __NR_gettid            224
+#define __NR_readahead         225
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
index 9945bcb7e820cfe4acf9f44801fdd5ba70181095..f50ecef0abda147432b3e3d2bfe766b028f12ae7 100644 (file)
@@ -111,14 +111,11 @@ static inline void *kmap_atomic(struct page *page, enum km_type type)
 
 static inline void kunmap_atomic(void *kvaddr, enum km_type type)
 {
-#if HIGHMEM_DEBUG
        unsigned long vaddr = (unsigned long) kvaddr;
        unsigned long idx = type + KM_TYPE_NR*smp_processor_id();
 
-#if 0
-       if (vaddr < FIXADDR_START) // FIXME
+       if (vaddr < FIX_KMAP_BEGIN) // FIXME
                return;
-#endif
 
        if (vaddr != FIX_KMAP_BEGIN + idx * PAGE_SIZE)
                BUG();
@@ -130,6 +127,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type)
        flush_cache_all();
 #endif
 
+#ifdef HIGHMEM_DEBUG
        /*
         * force other mappings to Oops if they'll try to access
         * this pte without first remap it
index 216b665f2d61d6f8976928bef6e34a0ec4980a2e..7fab7580e31acff63d3c1366b906205ad76ee83c 100644 (file)
@@ -9,7 +9,8 @@
 
 #define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 
-#define        SMP_CACHE_BYTES         64 /* L2 cache line size. */
+#define        SMP_CACHE_BYTES_SHIFT   6
+#define        SMP_CACHE_BYTES         (1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */
 
 #ifdef MODULE
 #define __cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
index 1be21d47143da59b7f6d122eb21050d7c4fb138c..62bfae557ad05fc8827cc567d4a17418a89ffdde 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 
 /* entry.S is sensitive to the offsets of these fields */
+/* rtrap.S is sensitive to the size of this structure */
 typedef struct {
        unsigned int __softirq_pending;
        unsigned int __unused_1;
index 8f4f261eebca5d560ae059758373c959d6a2cf93..bac34263ade07155cc4cb00a76028a994713db68 100644 (file)
@@ -53,7 +53,10 @@ struct ethtool_wolinfo {
 #define ETHTOOL_GDRVINFO       0x00000003 /* Get driver info. */
 #define ETHTOOL_GREGS          0x00000004 /* Get NIC registers, privileged. */
 #define ETHTOOL_GWOL           0x00000005 /* Get wake-on-lan options. */
-#define ETHTOOL_SWOL           0x00000006 /* Set wake-on-lan options. */
+#define ETHTOOL_SWOL           0x00000006 /* Set wake-on-lan options, priv. */
+#define ETHTOOL_GMSGLVL                0x00000007 /* Get driver message level */
+#define ETHTOOL_SMSGLVL                0x00000008 /* Set driver msg level, priv. */
+#define ETHTOOL_NWAY_RST       0X00000009 /* Restart autonegotiation, priv. */
 
 /* compatibility with older code */
 #define SPARC_ETH_GSET         ETHTOOL_GSET
@@ -71,6 +74,7 @@ struct ethtool_wolinfo {
 #define SUPPORTED_AUI                  (1 << 8)
 #define SUPPORTED_MII                  (1 << 9)
 #define SUPPORTED_FIBRE                        (1 << 10)
+#define SUPPORTED_10base2              (1 << 11)
 
 /* Indicates what features are advertised by the interface. */
 #define ADVERTISED_10baseT_Half                (1 << 0)
@@ -84,6 +88,7 @@ struct ethtool_wolinfo {
 #define ADVERTISED_AUI                 (1 << 8)
 #define ADVERTISED_MII                 (1 << 9)
 #define ADVERTISED_FIBRE               (1 << 10)
+#define ADVERTISED_10base2             (1 << 11)
 
 /* The following are all involved in forcing a particular link
  * mode for the device for setting things.  When getting the
index f39bcabdf7c016422681e778ac78774c654bcc34..383d72b35ed8c3b60156a737e815a1d1d642b44f 100644 (file)
 #define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
 #define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
 #define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
+#define PCI_DEVICE_ID_INTEL_80310      0x530d
 #define PCI_DEVICE_ID_INTEL_82810_MC1  0x7120
 #define PCI_DEVICE_ID_INTEL_82810_IG1  0x7121
 #define PCI_DEVICE_ID_INTEL_82810_MC3  0x7122
index fd148822857f2132b9ff94cdaaca8dd4aad5efe2..e8268cb67b74ab62134c9101522262f3618e08dd 100644 (file)
@@ -110,7 +110,7 @@ extern void swap_setup(void);
 
 /* linux/mm/vmscan.c */
 extern wait_queue_head_t kswapd_wait;
-extern int FASTCALL(try_to_free_pages(zone_t *, unsigned int, unsigned int));
+extern int FASTCALL(try_to_free_pages(unsigned int, unsigned int));
 
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, struct page *);
index 887237f6439c9368da974f1ee1f86b70acafbb6b..f35af58074444fbf99be7b12e658470c04b0875d 100644 (file)
 #endif
 
 #define RTO_ONLINK     0x01
-#define RTO_TPROXY     0x80000000
 
 #define RTO_CONN       0
+/* RTO_CONN is not used (being alias for 0), but preserved not to break
+ * some modules referring to it. */
+
+#define RT_CONN_FLAGS(sk)   (RT_TOS(sk->protinfo.af_inet.tos) | sk->localroute)
 
 struct rt_key
 {
index 1c8c5c5cdd25ed79d72c07c00c0a20fa3f8319bf..fb2ba9d0ba8bfa3fd41f93ec7c885962aea1b33a 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -348,6 +348,7 @@ static inline unsigned long copy_shminfo_to_user(void *buf, struct shminfo64 *in
 
 static void shm_get_stat (unsigned long *rss, unsigned long *swp) 
 {
+       struct shmem_inode_info *info;
        int i;
 
        *rss = 0;
@@ -361,10 +362,11 @@ static void shm_get_stat (unsigned long *rss, unsigned long *swp)
                if(shp == NULL)
                        continue;
                inode = shp->shm_file->f_dentry->d_inode;
-               spin_lock (&inode->u.shmem_i.lock);
+               info = SHMEM_I(inode);
+               spin_lock (&info->lock);
                *rss += inode->i_mapping->nrpages;
-               *swp += inode->u.shmem_i.swapped;
-               spin_unlock (&inode->u.shmem_i.lock);
+               *swp += info->swapped;
+               spin_unlock (&info->lock);
        }
 }
 
index 80882368e8eaaf769e8f6cc1905679367f29759a..f3e76ac75df551a8e8c67352b732a03d38c8085c 100644 (file)
@@ -59,7 +59,7 @@ extern void set_device_ro(kdev_t dev,int flag);
 
 extern void *sys_call_table;
 
-extern int sys_tz;
+extern struct timezone sys_tz;
 extern int request_dma(unsigned int dmanr, char * deviceID);
 extern void free_dma(unsigned int dmanr);
 extern spinlock_t dma_spin_lock;
index e35da10e63e28978d5defd391b56c6833852e152..250f11d0147fe5dc3f6ab5e54b5575c37b5f21ac 100644 (file)
@@ -1297,6 +1297,7 @@ void daemonize(void)
 
        current->session = 1;
        current->pgrp = 1;
+       current->tty = NULL;
 
        /* Become as one with the init task */
 
index 87a566030ee52336ab25ea004d82c4433394248f..35fb1b73b968f7cbe658c258efab00c880406e4c 100644 (file)
@@ -1520,6 +1520,53 @@ out:
        return retval;
 }
 
+static ssize_t do_readahead(struct file *file, unsigned long index, unsigned long nr)
+{
+       struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+       unsigned long max;
+
+       if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage)
+               return -EINVAL;
+
+       /* Limit it to the size of the file.. */
+       max = (mapping->host->i_size + ~PAGE_CACHE_MASK) >> PAGE_CACHE_SHIFT;
+       if (index > max)
+               return 0;
+       max -= index;
+       if (nr > max)
+               nr = max;
+
+       /* And limit it to a sane percentage of the inactive list.. */
+       max = nr_inactive_pages / 2;
+       if (nr > max)
+               nr = max;
+
+       while (nr) {
+               page_cache_read(file, index);
+               index++;
+               nr--;
+       }
+       return 0;
+}
+
+asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count)
+{
+       ssize_t ret;
+       struct file *file;
+
+       ret = -EBADF;
+       file = fget(fd);
+       if (file) {
+               if (file->f_mode & FMODE_READ) {
+                       unsigned long start = offset >> PAGE_CACHE_SHIFT;
+                       unsigned long len = (count + ((long)offset & ~PAGE_CACHE_MASK)) >> PAGE_CACHE_SHIFT;
+                       ret = do_readahead(file, start, len);
+               }
+               fput(file);
+       }
+       return ret;
+}
+
 /*
  * Read-ahead and flush behind for MADV_SEQUENTIAL areas.  Since we are
  * sure this is sequential access, we don't need a flexible read-ahead
@@ -2312,7 +2359,7 @@ static unsigned char mincore_page(struct vm_area_struct * vma,
        unsigned long pgoff)
 {
        unsigned char present = 0;
-       struct address_space * as = &vma->vm_file->f_dentry->d_inode->i_mapping;
+       struct address_space * as = vma->vm_file->f_dentry->d_inode->i_mapping;
        struct page * page, ** hash = page_hash(as, pgoff);
 
        spin_lock(&pagecache_lock);
index ec974923b3cf1ac05fb9837b250f033e1ac30399..f92e13e8d8210b12da5032f33f70166e88cbd5a0 100644 (file)
@@ -242,7 +242,7 @@ static struct page * balance_classzone(zone_t * classzone, unsigned int gfp_mask
        current->allocation_order = order;
        current->flags |= PF_MEMALLOC | PF_FREE_PAGES;
 
-       __freed = try_to_free_pages(classzone, gfp_mask, order);
+       __freed = try_to_free_pages(gfp_mask, order);
 
        current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES);
 
index 6c6a505ed26516403619be28e5b38c20a3964de5..37576b2d4d121d86ad6a2bb1ce913851f50b898e 100644 (file)
@@ -1235,45 +1235,54 @@ static struct inode_operations shmem_symlink_inode_operations = {
 
 static int shmem_parse_options(char *options, int *mode, unsigned long * blocks, unsigned long *inodes)
 {
-       char *this_char, *value;
+       char *this_char, *value, *rest;
 
        this_char = NULL;
        if ( options )
                this_char = strtok(options,",");
        for ( ; this_char; this_char = strtok(NULL,",")) {
-               if ((value = strchr(this_char,'=')) != NULL)
+               if ((value = strchr(this_char,'=')) != NULL) {
                        *value++ = 0;
+               } else {
+                       printk(KERN_ERR 
+                           "shmem_parse_options: No value for option '%s'\n", 
+                           this_char);
+                       return 1;
+               }
+
                if (!strcmp(this_char,"size")) {
                        unsigned long long size;
-                       if (!value || !*value || !blocks)
-                               return 1;
-                       size = memparse(value,&value);
-                       if (*value)
-                               return 1;
+                       size = memparse(value,&rest);
+                       if (*rest)
+                               goto bad_val;
                        *blocks = size >> PAGE_CACHE_SHIFT;
                } else if (!strcmp(this_char,"nr_blocks")) {
-                       if (!value || !*value || !blocks)
-                               return 1;
-                       *blocks = memparse(value,&value);
-                       if (*value)
-                               return 1;
+                       *blocks = memparse(value,&rest);
+                       if (*rest)
+                               goto bad_val;
                } else if (!strcmp(this_char,"nr_inodes")) {
-                       if (!value || !*value || !inodes)
-                               return 1;
-                       *inodes = memparse(value,&value);
-                       if (*value)
-                               return 1;
+                       *inodes = memparse(value,&rest);
+                       if (*rest)
+                               goto bad_val;
                } else if (!strcmp(this_char,"mode")) {
-                       if (!value || !*value || !mode)
-                               return 1;
-                       *mode = simple_strtoul(value,&value,8);
-                       if (*value)
-                               return 1;
-               }
-               else
+                       if (!mode)
+                               continue;
+                       *mode = simple_strtoul(value,&rest,8);
+                       if (*rest)
+                               goto bad_val;
+               } else {
+                       printk(KERN_ERR "shmem_parse_options: Bad option %s\n",
+                              this_char);
                        return 1;
+               }
        }
        return 0;
+
+bad_val:
+       printk(KERN_ERR "shmem_parse_options: Bad value '%s' for option '%s'\n", 
+              value, this_char);
+       return 1;
+
 }
 
 static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
index 1dd936ec97a1190c12c3d7699cfdaf01a6c016b9..e7e544b3b93801ce991612272e9fd95a33469f04 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -135,12 +135,10 @@ void __init swap_setup(void)
        /* Use a smaller cluster for small-memory machines */
        if (megs < 16)
                page_cluster = 2;
-       else if (megs < 32)
-               page_cluster = 3;
-       else if (megs < 64)
-               page_cluster = 4;
-       else if (megs < 128)
-               page_cluster = 5;
        else
-               page_cluster = 6;
+               page_cluster = 3;
+       /*
+        * Right now other parts of the system means that we
+        * _really_ don't want to cluster much more
+        */
 }
index efd19294ad754c1f2118e98f68d48d4f83a4b77b..41d651f6720fbb8b53392d64273e5b1e2159f94b 100644 (file)
@@ -33,6 +33,8 @@
  */
 #define DEF_PRIORITY (6)
 
+#define page_zone_plenty(page) ((page)->zone->free_pages > (page)->zone->pages_high)
+
 /*
  * The swap-out function returns 1 if it successfully
  * scanned all the pages it was asked to (`count').
  */
 
 /* mm->page_table_lock is held. mmap_sem is not held */
-static inline int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, struct page *page, zone_t * classzone)
+static inline int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, struct page *page)
 {
        pte_t pte;
        swp_entry_t entry;
-       int right_classzone;
 
        /* Don't look at this pte if it's been accessed recently. */
        if (ptep_test_and_clear_young(page_table)) {
@@ -55,12 +56,12 @@ static inline int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct*
                return 0;
        }
 
-       if (TryLockPage(page))
+       /* Don't bother replenishing zones that have tons of memory */
+       if (page_zone_plenty(page))
                return 0;
 
-       right_classzone = 1;
-       if (!memclass(page->zone, classzone))
-               right_classzone = 0;
+       if (TryLockPage(page))
+               return 0;
 
        /* From this point on, the odds are that we're going to
         * nuke this pte, so read and clear the pte.  This hook
@@ -89,7 +90,7 @@ drop_pte:
                {
                        int freeable = page_count(page) - !!page->buffers <= 2;
                        page_cache_release(page);
-                       return freeable & right_classzone;
+                       return freeable;
                }
        }
 
@@ -145,7 +146,7 @@ drop_pte:
 }
 
 /* mm->page_table_lock is held. mmap_sem is not held */
-static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone)
+static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int count)
 {
        pte_t * pte;
        unsigned long pmd_end;
@@ -169,7 +170,7 @@ static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vm
                        struct page *page = pte_page(*pte);
 
                        if (VALID_PAGE(page) && !PageReserved(page)) {
-                               count -= try_to_swap_out(mm, vma, address, pte, page, classzone);
+                               count -= try_to_swap_out(mm, vma, address, pte, page);
                                if (!count) {
                                        address += PAGE_SIZE;
                                        break;
@@ -184,7 +185,7 @@ static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vm
 }
 
 /* mm->page_table_lock is held. mmap_sem is not held */
-static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone)
+static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int count)
 {
        pmd_t * pmd;
        unsigned long pgd_end;
@@ -204,7 +205,7 @@ static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vm
                end = pgd_end;
        
        do {
-               count = swap_out_pmd(mm, vma, pmd, address, end, count, classzone);
+               count = swap_out_pmd(mm, vma, pmd, address, end, count);
                if (!count)
                        break;
                address = (address + PMD_SIZE) & PMD_MASK;
@@ -214,7 +215,7 @@ static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vm
 }
 
 /* mm->page_table_lock is held. mmap_sem is not held */
-static inline int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, int count, zone_t * classzone)
+static inline int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, int count)
 {
        pgd_t *pgdir;
        unsigned long end;
@@ -229,7 +230,7 @@ static inline int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vm
        if (address >= end)
                BUG();
        do {
-               count = swap_out_pgd(mm, vma, pgdir, address, end, count, classzone);
+               count = swap_out_pgd(mm, vma, pgdir, address, end, count);
                if (!count)
                        break;
                address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -244,7 +245,7 @@ struct mm_struct *swap_mm = &init_mm;
 /*
  * Returns remaining count of pages to be swapped out by followup call.
  */
-static inline int swap_out_mm(struct mm_struct * mm, int count, int * mmcounter, zone_t * classzone)
+static inline int swap_out_mm(struct mm_struct * mm, int count, int * mmcounter)
 {
        unsigned long address;
        struct vm_area_struct* vma;
@@ -266,7 +267,7 @@ static inline int swap_out_mm(struct mm_struct * mm, int count, int * mmcounter,
                        address = vma->vm_start;
 
                for (;;) {
-                       count = swap_out_vma(mm, vma, address, count, classzone);
+                       count = swap_out_vma(mm, vma, address, count);
                        vma = vma->vm_next;
                        if (!vma)
                                break;
@@ -283,8 +284,8 @@ out_unlock:
        return count;
 }
 
-static int FASTCALL(swap_out(unsigned int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages));
-static int swap_out(unsigned int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages)
+static int FASTCALL(swap_out(unsigned int priority, unsigned int gfp_mask, int nr_pages));
+static int swap_out(unsigned int priority, unsigned int gfp_mask, int nr_pages)
 {
        int counter;
        struct mm_struct *mm;
@@ -311,7 +312,7 @@ static int swap_out(unsigned int priority, zone_t * classzone, unsigned int gfp_
                atomic_inc(&mm->mm_users);
                spin_unlock(&mmlist_lock);
 
-               nr_pages = swap_out_mm(mm, nr_pages, &counter, classzone);
+               nr_pages = swap_out_mm(mm, nr_pages, &counter);
 
                mmput(mm);
 
@@ -326,8 +327,8 @@ empty:
        return 0;
 }
 
-static int FASTCALL(shrink_cache(int nr_pages, int max_scan, zone_t * classzone, unsigned int gfp_mask));
-static int shrink_cache(int nr_pages, int max_scan, zone_t * classzone, unsigned int gfp_mask)
+static int FASTCALL(shrink_cache(int nr_pages, int max_scan, unsigned int gfp_mask));
+static int shrink_cache(int nr_pages, int max_scan, unsigned int gfp_mask)
 {
        struct list_head * entry;
 
@@ -348,28 +349,45 @@ static int shrink_cache(int nr_pages, int max_scan, zone_t * classzone, unsigned
                if (unlikely(!PageInactive(page) && !PageActive(page)))
                        BUG();
 
+               /* Mapping-less page on LRU-list? */
+               if (unlikely(!page->mapping))
+                       BUG();
+
                list_del(entry);
                list_add(entry, &inactive_list);
                if (PageTestandClearReferenced(page))
                        continue;
 
                max_scan--;
-
-               if (unlikely(!memclass(page->zone, classzone)))
+               if (unlikely(page_zone_plenty(page)))
                        continue;
 
                /* Racy check to avoid trylocking when not worthwhile */
-               if (!page->buffers && page_count(page) != 1)
+               if (!is_page_cache_freeable(page))
+                       continue;
+
+               if (unlikely(TryLockPage(page))) {
+                       if (gfp_mask & __GFP_FS) {
+                               page_cache_get(page);
+                               spin_unlock(&pagemap_lru_lock);
+                               wait_on_page(page);
+                               page_cache_release(page);
+                               spin_lock(&pagemap_lru_lock);
+                       }
                        continue;
+               }
 
                /*
-                * The page is locked. IO in progress?
-                * Move it to the back of the list.
+                * Still strictly racy - we don't own the pagecache lock,
+                * so somebody might look up the page while we do this.
+                * It's just a heuristic, though.
                 */
-               if (unlikely(TryLockPage(page)))
+               if (!is_page_cache_freeable(page)) {
+                       UnlockPage(page);
                        continue;
+               }
 
-               if (PageDirty(page) && is_page_cache_freeable(page)) {
+               if (PageDirty(page)) {
                        /*
                         * It is not critical here to write it only if
                         * the page is unmapped beause any direct writer
@@ -443,9 +461,6 @@ static int shrink_cache(int nr_pages, int max_scan, zone_t * classzone, unsigned
                        }
                }
 
-               if (unlikely(!page->mapping))
-                       BUG();
-
                if (unlikely(!spin_trylock(&pagecache_lock))) {
                        /* we hold the page lock so the page cannot go away from under us */
                        spin_unlock(&pagemap_lru_lock);
@@ -522,8 +537,8 @@ static void refill_inactive(int nr_pages)
        spin_unlock(&pagemap_lru_lock);
 }
 
-static int FASTCALL(shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages));
-static int shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages)
+static int FASTCALL(shrink_caches(int priority, unsigned int gfp_mask, int nr_pages));
+static int shrink_caches(int priority, unsigned int gfp_mask, int nr_pages)
 {
        int max_scan;
        int chunk_size = nr_pages;
@@ -537,9 +552,9 @@ static int shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask
        /* try to keep the active list 2/3 of the size of the cache */
        ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2);
        refill_inactive(ratio);
-  
+
        max_scan = nr_inactive_pages / priority;
-       nr_pages = shrink_cache(nr_pages, max_scan, classzone, gfp_mask);
+       nr_pages = shrink_cache(nr_pages, max_scan, gfp_mask);
        if (nr_pages <= 0)
                return 0;
 
@@ -552,18 +567,18 @@ static int shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask
        return nr_pages;
 }
 
-int try_to_free_pages(zone_t * classzone, unsigned int gfp_mask, unsigned int order)
+int try_to_free_pages(unsigned int gfp_mask, unsigned int order)
 {
        int ret = 0;
        int priority = DEF_PRIORITY;
        int nr_pages = SWAP_CLUSTER_MAX;
 
        do {
-               nr_pages = shrink_caches(priority, classzone, gfp_mask, nr_pages);
+               nr_pages = shrink_caches(priority, gfp_mask, nr_pages);
                if (nr_pages <= 0)
                        return 1;
 
-               ret |= swap_out(priority, classzone, gfp_mask, SWAP_CLUSTER_MAX << 2);
+               ret |= swap_out(priority, gfp_mask, SWAP_CLUSTER_MAX << 2);
        } while (--priority);
 
        return ret;
@@ -595,7 +610,7 @@ static int kswapd_balance_pgdat(pg_data_t * pgdat)
                        schedule();
                if (!zone->need_balance)
                        continue;
-               if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) {
+               if (!try_to_free_pages(GFP_KSWAPD, 0)) {
                        zone->need_balance = 0;
                        __set_current_state(TASK_INTERRUPTIBLE);
                        schedule_timeout(HZ);
index 80f6807afd2033e9276b28973f3dbb3261b625d5..f91d8fa6d200c1f8e2f13962620e5b14ef5aa8f4 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Lennert Buytenhek               <buytenh@gnu.org>
  *
- *     $Id: br.c,v 1.45 2000/10/22 18:26:07 davem Exp $
+ *     $Id: br.c,v 1.46 2001/10/02 02:22:36 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
index 69412c30cd2c6ff6b3f71650bd9bedda33dd4836..629aee1a117244435bd00e0dddf03d7807da6722 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The Internet Protocol (IP) output module.
  *
- * Version:    $Id: ip_output.c,v 1.98 2001/09/01 00:31:50 davem Exp $
+ * Version:    $Id: ip_output.c,v 1.99 2001/10/15 12:34:50 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -367,7 +367,7 @@ int ip_queue_xmit(struct sk_buff *skb)
                 * out.
                 */
                if (ip_route_output(&rt, daddr, sk->saddr,
-                                   RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
+                                   RT_CONN_FLAGS(sk),
                                    sk->bound_dev_if))
                        goto no_route;
                __sk_dst_set(sk, &rt->u.dst);
index a5c004adf7df2df6796671b95d563048522327c6..b149b54ee457fa6b542303acccf059da1883dc5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  $Id: ipconfig.c,v 1.38 2001/09/25 23:23:07 davem Exp $
+ *  $Id: ipconfig.c,v 1.39 2001/10/13 01:47:31 davem Exp $
  *
  *  Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
  *  user-supplied information to configure own IP address and routes.
index 29b6f50102fb037c70b909da0fab6148a3f9d18c..87ad2a5a65c611f37e0e303999fb137bbe469d83 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     Linux NET3:     IP/IP protocol decoder. 
  *
- *     Version: $Id: ipip.c,v 1.49 2001/09/25 22:35:47 davem Exp $
+ *     Version: $Id: ipip.c,v 1.50 2001/10/02 02:22:36 davem Exp $
  *
  *     Authors:
  *             Sam Lantinga (slouken@cs.ucdavis.edu)  02/01/95
index d0b0ed7f7a934c7988d285e9426766cf55b5a41c..b68ceaa0a3f229b8ac6c0781a02b5d12eb7aee5e 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             ROUTE - implementation of the IP router.
  *
- * Version:    $Id: route.c,v 1.99 2001/09/18 22:29:09 davem Exp $
+ * Version:    $Id: route.c,v 1.100 2001/10/15 12:34:50 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -2002,9 +2002,7 @@ int ip_route_output_key(struct rtable **rp, const struct rt_key *key)
                    rth->key.fwmark == key->fwmark &&
 #endif
                    !((rth->key.tos ^ key->tos) &
-                           (IPTOS_RT_MASK | RTO_ONLINK)) &&
-                   ((key->tos & RTO_TPROXY) ||
-                    !(rth->rt_flags & RTCF_TPROXY))) {
+                           (IPTOS_RT_MASK | RTO_ONLINK))) {
                        rth->u.dst.lastuse = jiffies;
                        dst_hold(&rth->u.dst);
                        rth->u.dst.__use++;
index 3e6ecf67fb78016ed66861d89dbf8612f13909a8..8d2c80ca3cde2b7a119cf7d97afd98de64516cde 100644 (file)
@@ -9,7 +9,7 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  * 
- *  $Id: syncookies.c,v 1.14 2001/05/05 01:01:55 davem Exp $
+ *  $Id: syncookies.c,v 1.15 2001/10/15 12:34:50 davem Exp $
  *
  *  Missing: IPv6 support. 
  */
@@ -178,7 +178,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
                            opt && 
                            opt->srr ? opt->faddr : req->af.v4_req.rmt_addr,
                            req->af.v4_req.loc_addr,
-                           sk->protinfo.af_inet.tos | RTO_CONN,
+                           RT_CONN_FLAGS(sk),
                            0)) { 
                tcp_openreq_free(req);
                goto out; 
index 69455b35eabd945a843ff5d8c5b860876bde2244..311e40d1171ae7da07bf32d08ddbe14349bc8a0e 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_ipv4.c,v 1.231 2001/09/26 23:38:47 davem Exp $
+ * Version:    $Id: tcp_ipv4.c,v 1.232 2001/10/15 12:34:50 davem Exp $
  *
  *             IPv4 specific functions
  *
@@ -660,7 +660,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        }
 
        tmp = ip_route_connect(&rt, nexthop, sk->saddr,
-                              RT_TOS(sk->protinfo.af_inet.tos)|RTO_CONN|sk->localroute, sk->bound_dev_if);
+                              RT_CONN_FLAGS(sk), sk->bound_dev_if);
        if (tmp < 0)
                return tmp;
 
@@ -676,7 +676,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                daddr = rt->rt_dst;
 
        err = -ENOBUFS;
-       buff = alloc_skb(MAX_TCP_HEADER + 15, GFP_KERNEL);
+       buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation);
 
        if (buff == NULL)
                goto failure;
@@ -1147,8 +1147,7 @@ static struct dst_entry* tcp_v4_route_req(struct sock *sk, struct open_request *
                                 opt->faddr :
                                 req->af.v4_req.rmt_addr),
                           req->af.v4_req.loc_addr,
-                          RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
-                          sk->bound_dev_if)) {
+                          RT_CONN_FLAGS(sk), sk->bound_dev_if)) {
                IP_INC_STATS_BH(IpOutNoRoutes);
                return NULL;
        }
@@ -1776,8 +1775,7 @@ int tcp_v4_rebuild_header(struct sock *sk)
                daddr = sk->protinfo.af_inet.opt->faddr;
 
        err = ip_route_output(&rt, daddr, sk->saddr,
-                             RT_TOS(sk->protinfo.af_inet.tos) | RTO_CONN | sk->localroute,
-                             sk->bound_dev_if);
+                             RT_CONN_FLAGS(sk), sk->bound_dev_if);
        if (!err) {
                __sk_dst_set(sk, &rt->u.dst);
                sk->route_caps = rt->u.dst.dev->features;
index 095955c0c6341721ef1f949ad7873b6064a70818..b123ff97a4f258eee4f686061c8ac32842cae97e 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The User Datagram Protocol (UDP).
  *
- * Version:    $Id: udp.c,v 1.99 2001/09/01 00:31:50 davem Exp $
+ * Version:    $Id: udp.c,v 1.100 2001/10/15 12:34:50 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -724,7 +724,7 @@ int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
        sk_dst_reset(sk);
 
        err = ip_route_connect(&rt, usin->sin_addr.s_addr, sk->saddr,
-                              sk->protinfo.af_inet.tos|sk->localroute, sk->bound_dev_if);
+                              RT_CONN_FLAGS(sk), sk->bound_dev_if);
        if (err)
                return err;
        if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) {
index 2c297fd633f92ddaa77a204ac410a3a57b7318bf..bd8f698466d22df8aae479370b6a672e7b8cdab8 100644 (file)
@@ -7,7 +7,7 @@
  *
  *     Adapted from linux/net/ipv4/af_inet.c
  *
- *     $Id: af_inet6.c,v 1.64 2001/06/13 16:25:03 davem Exp $
+ *     $Id: af_inet6.c,v 1.65 2001/10/02 02:22:36 davem Exp $
  *
  *     Fixes:
  *     piggy, Karl Knutson     :       Socket protocol table
index 899f658575a2b1018dd5b1b425d107261f04d9dc..738a3e5d220ed59612105b54a0ce04a49e51eb18 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: tcp_ipv6.c,v 1.139 2001/09/26 23:38:47 davem Exp $
+ *     $Id: tcp_ipv6.c,v 1.140 2001/10/15 12:34:50 davem Exp $
  *
  *     Based on: 
  *     linux/net/ipv4/tcp.c
@@ -339,13 +339,18 @@ static inline struct sock *__tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
        return tcp_v6_lookup_listener(daddr, hnum, dif);
 }
 
-#define tcp_v6_lookup(sa, sp, da, dp, dif) \
-({     struct sock *___sk; \
-       local_bh_disable(); \
-       ___sk = __tcp_v6_lookup((sa),(sp),(da),ntohs(dp),(dif)); \
-       local_bh_enable(); \
-       ___sk; \
-})
+__inline__ struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
+                                     struct in6_addr *daddr, u16 dport,
+                                     int dif)
+{
+       struct sock *sk;
+
+       local_bh_disable();
+       sk = __tcp_v6_lookup(saddr, sport, daddr, ntohs(dport), dif);
+       local_bh_enable();
+
+       return sk;
+}
 
 
 /*
@@ -656,7 +661,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
        err = -ENOBUFS;
-       buff = alloc_skb(MAX_TCP_HEADER + 15, GFP_KERNEL);
+       buff = alloc_skb(MAX_TCP_HEADER + 15, sk->allocation);
 
        if (buff == NULL)
                goto failure;
index e0416b466c33849fd18cf1668f613d90441e2db1..e9d6000cc83dff0d5c04b8d953b4aedc69337167 100644 (file)
@@ -440,10 +440,11 @@ struct socket *sock_alloc(void)
        struct inode * inode;
        struct socket * sock;
 
-       inode = new_inode(sock_mnt->mnt_sb);
+       inode = get_empty_inode();
        if (!inode)
                return NULL;
 
+       inode->i_sb = sock_mnt->mnt_sb;
        sock = socki_lookup(inode);
 
        inode->i_mode = S_IFSOCK|S_IRWXUGO;