summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 20:24:41 -0800
committerLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 20:24:41 -0800
commit96c4fbbe32bf8aaace615f5ad2469f5531dae781 (patch)
treeb3b3bd990d8a19c595f810b508a4262d1b9973db
parent975675b97f86323933d8f15b83660a60255988f7 (diff)
v2.4.12.3 -> v2.4.12.4
- 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
-rw-r--r--CREDITS7
-rw-r--r--Documentation/Configure.help26
-rw-r--r--Documentation/README.DAC96048
-rw-r--r--Documentation/usb/error-codes.txt5
-rw-r--r--Documentation/usb/philips.txt33
-rw-r--r--Documentation/video4linux/bttv/CARDLIST37
-rw-r--r--Documentation/video4linux/bttv/Cards210
-rw-r--r--Documentation/video4linux/bttv/Insmod-options45
-rw-r--r--Documentation/video4linux/bttv/README.quirks83
-rw-r--r--Documentation/video4linux/bttv/Sound-FAQ1
-rw-r--r--Documentation/video4linux/bttv/Tuners88
-rw-r--r--MAINTAINERS6
-rw-r--r--Makefile2
-rw-r--r--arch/i386/defconfig48
-rw-r--r--arch/i386/kernel/entry.S1
-rw-r--r--arch/i386/kernel/ldt.c22
-rw-r--r--arch/i386/kernel/pci-irq.c2
-rw-r--r--arch/ppc/8xx_io/enet.c28
-rw-r--r--arch/ppc/8xx_io/fec.c10
-rw-r--r--arch/ppc/kernel/m8xx_setup.c10
-rw-r--r--arch/sparc64/Makefile4
-rw-r--r--arch/sparc64/kernel/dtlb_base.S6
-rw-r--r--arch/sparc64/kernel/entry.S11
-rw-r--r--arch/sparc64/kernel/rtrap.S6
-rw-r--r--arch/sparc64/kernel/setup.c14
-rw-r--r--drivers/acpi/include/platform/acgcc.h1
-rw-r--r--drivers/block/DAC960.c652
-rw-r--r--drivers/block/DAC960.h157
-rw-r--r--drivers/block/genhd.c6
-rw-r--r--drivers/block/loop.c8
-rw-r--r--drivers/char/drm/drm_vm.h5
-rw-r--r--drivers/ieee1394/Makefile4
-rw-r--r--drivers/ieee1394/ieee1394.h5
-rw-r--r--drivers/ieee1394/ieee1394_core.c71
-rw-r--r--drivers/ieee1394/ieee1394_types.h21
-rw-r--r--drivers/ieee1394/nodemgr.c11
-rw-r--r--drivers/ieee1394/sbp2.c328
-rw-r--r--drivers/ieee1394/sbp2.h15
-rw-r--r--drivers/md/md.c4
-rw-r--r--drivers/md/raid1.c3
-rw-r--r--drivers/md/raid5.c34
-rw-r--r--drivers/media/video/bttv-cards.c337
-rw-r--r--drivers/media/video/bttv-driver.c60
-rw-r--r--drivers/media/video/bttv-if.c9
-rw-r--r--drivers/media/video/bttv.h19
-rw-r--r--drivers/media/video/bttvp.h10
-rw-r--r--drivers/media/video/id.h3
-rw-r--r--drivers/media/video/msp3400.c84
-rw-r--r--drivers/media/video/tda7432.c1
-rw-r--r--drivers/media/video/tda9875.c1
-rw-r--r--drivers/media/video/tuner.c401
-rw-r--r--drivers/media/video/tuner.h35
-rw-r--r--drivers/media/video/tvaudio.c208
-rw-r--r--drivers/media/video/tvaudio.h1
-rw-r--r--drivers/media/video/tvmixer.c42
-rw-r--r--drivers/net/a2065.c1
-rw-r--r--drivers/net/atari_bionet.c1
-rw-r--r--drivers/net/atari_pamsnet.c1
-rw-r--r--drivers/net/atarilance.c1
-rw-r--r--drivers/net/bagetlance.c1
-rw-r--r--drivers/net/bmac.c1
-rw-r--r--drivers/net/fealnx.c1
-rw-r--r--drivers/net/fmv18x.c1
-rw-r--r--drivers/net/gmac.c1
-rw-r--r--drivers/net/gt96100eth.c1
-rw-r--r--drivers/net/hplance.c1
-rw-r--r--drivers/net/hydra.c1
-rw-r--r--drivers/net/ibmlana.c1
-rw-r--r--drivers/net/ioc3-eth.c1
-rw-r--r--drivers/net/isa-skeleton.c1
-rw-r--r--drivers/net/lasi_82596.c1
-rw-r--r--drivers/net/mac89x0.c1
-rw-r--r--drivers/net/mace.c1
-rw-r--r--drivers/net/macsonic.c1
-rw-r--r--drivers/net/mvme147.c2
-rw-r--r--drivers/net/ne2.c1
-rw-r--r--drivers/net/oaknet.c1
-rw-r--r--drivers/net/pci-skeleton.c1
-rw-r--r--drivers/net/pcmcia/xircom_tulip_cb.c45
-rw-r--r--drivers/net/saa9730.c1
-rw-r--r--drivers/net/seeq8005.c1
-rw-r--r--drivers/net/sk_g16.c1
-rw-r--r--drivers/net/sk_mca.c1
-rw-r--r--drivers/net/smc-mca.c1
-rw-r--r--drivers/net/smc9194.c1
-rw-r--r--drivers/net/stnic.c1
-rw-r--r--drivers/net/sun3lance.c1
-rw-r--r--drivers/net/sunqe.c1
-rw-r--r--drivers/net/tulip/interrupt.c8
-rw-r--r--drivers/net/tulip/tulip_core.c4
-rw-r--r--drivers/net/wireless/airport.c1
-rw-r--r--drivers/sbus/audio/amd7930.c2
-rw-r--r--drivers/sbus/char/aurora.c44
-rw-r--r--drivers/sbus/char/sab82532.c206
-rw-r--r--drivers/sbus/char/su.c31
-rw-r--r--drivers/sbus/char/zs.c57
-rw-r--r--drivers/scsi/scsi.c4
-rw-r--r--drivers/scsi/sd.c5
-rw-r--r--drivers/scsi/sym53c8xx.c4
-rw-r--r--drivers/sound/btaudio.c18
-rw-r--r--drivers/usb/Config.in115
-rw-r--r--drivers/usb/pegasus.h12
-rw-r--r--drivers/usb/pwc-ctrl.c73
-rw-r--r--drivers/usb/pwc-if.c100
-rw-r--r--drivers/usb/pwc-ioctl.h14
-rw-r--r--drivers/usb/pwc.h6
-rw-r--r--drivers/usb/serial/Config.in56
-rw-r--r--drivers/usb/uhci.c12
-rw-r--r--drivers/usb/uhci.h1
-rw-r--r--drivers/usb/ultracam.c6
-rw-r--r--drivers/usb/usb-uhci.c2
-rw-r--r--drivers/video/cgsixfb.c2
-rw-r--r--drivers/video/creatorfb.c2
-rw-r--r--drivers/video/leofb.c2
-rw-r--r--fs/buffer.c30
-rw-r--r--fs/hfs/catalog.c2
-rw-r--r--fs/namei.c8
-rw-r--r--fs/namespace.c4
-rw-r--r--fs/nfsd/nfsproc.c31
-rw-r--r--fs/nfsd/nfssvc.c2
-rw-r--r--fs/nfsd/nfsxdr.c1
-rw-r--r--fs/udf/udfdecl.h2
-rw-r--r--include/asm-i386/system.h2
-rw-r--r--include/asm-i386/unistd.h1
-rw-r--r--include/asm-sparc/highmem.h6
-rw-r--r--include/asm-sparc64/cache.h3
-rw-r--r--include/asm-sparc64/hardirq.h1
-rw-r--r--include/linux/ethtool.h7
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/swap.h2
-rw-r--r--include/net/route.h5
-rw-r--r--ipc/shm.c8
-rw-r--r--kernel/ksyms.c2
-rw-r--r--kernel/sched.c1
-rw-r--r--mm/filemap.c49
-rw-r--r--mm/page_alloc.c2
-rw-r--r--mm/shmem.c57
-rw-r--r--mm/swap.c12
-rw-r--r--mm/vmscan.c91
-rw-r--r--net/bridge/br.c2
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/ipconfig.c2
-rw-r--r--net/ipv4/ipip.c2
-rw-r--r--net/ipv4/route.c6
-rw-r--r--net/ipv4/syncookies.c4
-rw-r--r--net/ipv4/tcp_ipv4.c12
-rw-r--r--net/ipv4/udp.c4
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/tcp_ipv6.c23
-rw-r--r--net/socket.c3
150 files changed, 3295 insertions, 1253 deletions
diff --git a/CREDITS b/CREDITS
index 4f5c1b0a2279..81ab2f0d5fd0 100644
--- 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
diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index f7329b8129d2..b789f72ec042 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -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).
diff --git a/Documentation/README.DAC960 b/Documentation/README.DAC960
index 4c0832e79e15..b6b770ee8dd6 100644
--- a/Documentation/README.DAC960
+++ b/Documentation/README.DAC960
@@ -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>
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
index 964af3033dec..a89dce8cc994 100644
--- a/Documentation/usb/error-codes.txt
+++ b/Documentation/usb/error-codes.txt
@@ -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
diff --git a/Documentation/usb/philips.txt b/Documentation/usb/philips.txt
index 2691c9ba0916..d48df51c3c18 100644
--- a/Documentation/usb/philips.txt
+++ b/Documentation/usb/philips.txt
@@ -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
diff --git a/Documentation/video4linux/bttv/CARDLIST b/Documentation/video4linux/bttv/CARDLIST
index 8b7f0369e512..6a023e5d3a14 100644
--- a/Documentation/video4linux/bttv/CARDLIST
+++ b/Documentation/video4linux/bttv/CARDLIST
@@ -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
index 000000000000..63170f9f46d7
--- /dev/null
+++ b/Documentation/video4linux/bttv/Cards
@@ -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
diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options
index 6ea97c4c3ea3..4738e0c0b58d 100644
--- a/Documentation/video4linux/bttv/Insmod-options
+++ b/Documentation/video4linux/bttv/Insmod-options
@@ -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
index 000000000000..e8edb87df711
--- /dev/null
+++ b/Documentation/video4linux/bttv/README.quirks
@@ -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.
+
diff --git a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ
index 1fbcd42a79c7..2c0bfa2e925d 100644
--- a/Documentation/video4linux/bttv/Sound-FAQ
+++ b/Documentation/video4linux/bttv/Sound-FAQ
@@ -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
index 000000000000..d2de455adf19
--- /dev/null
+++ b/Documentation/video4linux/bttv/Tuners
@@ -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
diff --git a/MAINTAINERS b/MAINTAINERS
index cce4a64295ba..3eb69af564ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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
diff --git a/Makefile b/Makefile
index e01920bb07f1..282423721d6c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 13
-EXTRAVERSION =-pre3
+EXTRAVERSION =-pre4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index b65a636bcbf6..8e9a1b2e29fd 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -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
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 582c0d5b240d..bdca486b6de2 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -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)
diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c
index df70730d7a80..a7ae70cb93e3 100644
--- a/arch/i386/kernel/ldt.c
+++ b/arch/i386/kernel/ldt.c
@@ -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;
diff --git a/arch/i386/kernel/pci-irq.c b/arch/i386/kernel/pci-irq.c
index 22bcc1ea732e..b5519558ab15 100644
--- a/arch/i386/kernel/pci-irq.c
+++ b/arch/i386/kernel/pci-irq.c
@@ -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 },
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index d446ad907aaa..8e1e2331a08d 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -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;
}
-
-
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
index 89f493278cfb..736c3657200e 100644
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -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;
diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c
index 979530114647..742a3522bad2 100644
--- a/arch/ppc/kernel/m8xx_setup.c
+++ b/arch/ppc/kernel/m8xx_setup.c
@@ -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 &=
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 31d37fa19bed..ea4a664958c1 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -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
diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
index d0a35e7d9f3e..a8f44fdffb32 100644
--- a/arch/sparc64/kernel/dtlb_base.S
+++ b/arch/sparc64/kernel/dtlb_base.S
@@ -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
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index ce82309ca7a5..4137fd99dc86 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -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
diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
index ced3c3482c03..20cd9a582fb3 100644
--- a/arch/sparc64/kernel/rtrap.S
+++ b/arch/sparc64/kernel/rtrap.S
@@ -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
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 5830873d8f02..7c1344f2b3b1 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -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();
diff --git a/drivers/acpi/include/platform/acgcc.h b/drivers/acpi/include/platform/acgcc.h
index a6b62c9694bc..f03eed261d61 100644
--- a/drivers/acpi/include/platform/acgcc.h
+++ b/drivers/acpi/include/platform/acgcc.h
@@ -39,7 +39,6 @@
#define BREAKPOINT3
#define disable() __cli()
#define enable() __sti()
-#define wbinvd()
/*! [Begin] no source code translation */
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index f77ca63e4be1..8ead560c54a6 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -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
@@ -480,6 +483,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.
*/
@@ -522,6 +571,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
on failure.
@@ -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,
@@ -1120,6 +1207,20 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
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.
*/
for (LogicalDriveNumber = 0;
@@ -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;
/*
@@ -1978,6 +2090,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;
}
@@ -4785,6 +5104,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);
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index fa1361541e68..98a937f66f99 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -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;
@@ -676,6 +689,30 @@ 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.
*/
@@ -853,6 +890,14 @@ typedef union DAC960_V1_CommandMailbox
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 */
unsigned char Dummy1[5]; /* Bytes 2-6 */
unsigned char LogicalDriveNumber:6; /* Byte 7 Bits 0-6 */
boolean AutoRestore:1; /* Byte 7 Bit 7 */
@@ -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);
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 36de551e6beb..12e19a164e32 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -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
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 4b9a6febe48d..a861f2adc8bf 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -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;
diff --git a/drivers/char/drm/drm_vm.h b/drivers/char/drm/drm_vm.h
index ef30f94ad4f3..fe68fc97eb64 100644
--- a/drivers/char/drm/drm_vm.h
+++ b/drivers/char/drm/drm_vm.h
@@ -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
diff --git a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile
index 52fa23e91cb9..b6cdcb6bf0a4 100644
--- a/drivers/ieee1394/Makefile
+++ b/drivers/ieee1394/Makefile
@@ -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
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
index c9f42373e327..485b1657bda1 100644
--- a/drivers/ieee1394/ieee1394.h
+++ b/drivers/ieee1394/ieee1394.h
@@ -47,7 +47,10 @@
#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
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index b19bd5d43909..95ec4af660fe 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -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);
diff --git a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h
index 185cecacb444..cbeaf43958c5 100644
--- a/drivers/ieee1394/ieee1394_types.h
+++ b/drivers/ieee1394/ieee1394_types.h
@@ -20,6 +20,23 @@
#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)
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 7b1ee818652a..d32219154426 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -27,11 +27,8 @@
#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;
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 594680253913..888e918e51d8 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -130,6 +130,10 @@
* 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 = {
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index c1fc8dd29fe3..505c65a75644 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -36,16 +36,6 @@
#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,
diff --git a/drivers/md/md.c b/drivers/md/md.c
index d34a2534a291..cae03abdaed6 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -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;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e4d0577e3e11..6c8a5bf21112 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -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);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e4c7fd38d83e..913b46f8ecd3 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -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;
}
}
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 45d5b8de55ea..67677ae5b8cb 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -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, 0, 0, 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, 0, 0, 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)
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 06f7e4d01375..86b14cd87891 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -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;
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index 3e8d84ebf8f0..3a1a4c04b271 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -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:
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index 513c855a45b9..ce3dc51db593 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -81,6 +81,13 @@
#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:
+ */
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 5dd21de8a642..15745818877a 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -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
diff --git a/drivers/media/video/id.h b/drivers/media/video/id.h
index d1f99ee06241..0c9acfc41c63 100644
--- a/drivers/media/video/id.h
+++ b/drivers/media/video/id.h
@@ -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
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index 25b95895e804..ef24cd617da0 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -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;
}
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index dc5a5e35cc82..2a5581ed051b 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -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 */
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index e9dcdac77a5b..92503bdf97a8 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -36,7 +36,6 @@
MODULE_PARM(debug,"i");
MODULE_LICENSE("GPL");
-
static int debug = 0; /* insmod parameter */
/* Addresses to scan */
diff --git a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c
index 4bd6f17b574d..d3b1237d5558 100644
--- a/drivers/media/video/tuner.c
+++ b/drivers/media/video/tuner.c
@@ -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:
diff --git a/drivers/media/video/tuner.h b/drivers/media/video/tuner.h
index 591ae3e7bc20..11539174b262 100644
--- a/drivers/media/video/tuner.h
+++ b/drivers/media/video/tuner.h
@@ -22,29 +22,29 @@
#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
@@ -52,7 +52,15 @@
#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 */
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 8984e6772090..a622e23ed3fa 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -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);
}
@@ -710,6 +719,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 */
#define TEA6300_VL 0x00 /* volume left */
@@ -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");
@@ -829,6 +1015,19 @@ static struct CHIPDESC chiplist[] = {
},
{
+ 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,
insmodopt: &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:
diff --git a/drivers/media/video/tvaudio.h b/drivers/media/video/tvaudio.h
index 702d2492d2df..b8deadcb1fb9 100644
--- a/drivers/media/video/tvaudio.h
+++ b/drivers/media/video/tvaudio.h
@@ -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
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index 0e7e71ae6160..60686c7d122e 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -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");
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 58bd41123996..e00dee5c48cc 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -837,3 +837,4 @@ static void __exit a2065_cleanup(void)
module_init(a2065_probe);
module_exit(a2065_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/atari_bionet.c b/drivers/net/atari_bionet.c
index 3f5ce581c603..2994d6f73099 100644
--- a/drivers/net/atari_bionet.c
+++ b/drivers/net/atari_bionet.c
@@ -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;
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index cc571fdf1843..175c23466a73 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -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;
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 4cde2eb04602..15a9c90cb4cc 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -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
diff --git a/drivers/net/bagetlance.c b/drivers/net/bagetlance.c
index 4fe99b68500f..2167d6910aad 100644
--- a/drivers/net/bagetlance.c
+++ b/drivers/net/bagetlance.c
@@ -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
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index bafad186bf3e..b326541e4b78 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -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)
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index afb46d51a0ba..d5b0da42a4ca 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -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");
diff --git a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c
index b171843b360f..cad2a831c22d 100644
--- a/drivers/net/fmv18x.c
+++ b/drivers/net/fmv18x.c
@@ -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)
{
diff --git a/drivers/net/gmac.c b/drivers/net/gmac.c
index 21a638ecd286..8d3e0b2d4541 100644
--- a/drivers/net/gmac.c
+++ b/drivers/net/gmac.c
@@ -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)
{
diff --git a/drivers/net/gt96100eth.c b/drivers/net/gt96100eth.c
index 38f448bf3ea8..e736e16052bd 100644
--- a/drivers/net/gt96100eth.c
+++ b/drivers/net/gt96100eth.c
@@ -1250,3 +1250,4 @@ static struct net_device_stats *gt96100_get_stats(struct net_device *dev)
}
module_init(gt96100_probe);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/hplance.c b/drivers/net/hplance.c
index 7b4e6536adab..035e29cfeef5 100644
--- a/drivers/net/hplance.c
+++ b/drivers/net/hplance.c
@@ -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;
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index 6eb7200c6bc9..6de426318f86 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -254,3 +254,4 @@ static void __exit hydra_cleanup(void)
module_init(hydra_probe);
module_exit(hydra_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index a945f84a8440..ca7f616feb8e 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -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)
{
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index e0cc882810be..dc1667b240ce 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -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);
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c
index bee3b7fb3193..bf3fcbb0053f 100644
--- a/drivers/net/isa-skeleton.c
+++ b/drivers/net/isa-skeleton.c
@@ -636,6 +636,7 @@ static int io = 0x300;
static int irq;
static int dma;
static int mem;
+MODULE_LICENSE("GPL");
int init_module(void)
{
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index 7bcb7f6e19c5..54d5c958de0f 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -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");
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index ec0912034773..258d705d5acf 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -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;
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 083616e27814..04ca3c75ad16 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -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)
{
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index ef2705176acc..3cd9741856bf 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -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;
diff --git a/drivers/net/mvme147.c b/drivers/net/mvme147.c
index 3af60247e080..eebdb555d4ef 100644
--- a/drivers/net/mvme147.c
+++ b/drivers/net/mvme147.c
@@ -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;
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index 29d4450e211f..722392bc21ad 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -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");
diff --git a/drivers/net/oaknet.c b/drivers/net/oaknet.c
index 1a5a539818a0..0029c3c54f3c 100644
--- a/drivers/net/oaknet.c
+++ b/drivers/net/oaknet.c
@@ -696,3 +696,4 @@ static void __exit oaknet_cleanup_module (void)
module_init(oaknet_init_module);
module_exit(oaknet_cleanup_module);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 26c1a4964796..e94d6c3cb3a2 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -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");
diff --git a/drivers/net/pcmcia/xircom_tulip_cb.c b/drivers/net/pcmcia/xircom_tulip_cb.c
index 19ff5c6384d1..4de966127d2a 100644
--- a/drivers/net/pcmcia/xircom_tulip_cb.c
+++ b/drivers/net/pcmcia/xircom_tulip_cb.c
@@ -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;
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index bf6dcec69820..31ce83f80154 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -1080,3 +1080,4 @@ static int __init saa9730_probe(void)
}
module_init(saa9730_probe);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
index 1fc1788944d0..e6e6efc4e181 100644
--- a/drivers/net/seeq8005.c
+++ b/drivers/net/seeq8005.c
@@ -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");
diff --git a/drivers/net/sk_g16.c b/drivers/net/sk_g16.c
index 240dd00f1dff..21ab6e3af3da 100644
--- a/drivers/net/sk_g16.c
+++ b/drivers/net/sk_g16.c
@@ -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");
diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
index 4b3a464ddc7e..5886a04d6c3e 100644
--- a/drivers/net/sk_mca.c
+++ b/drivers/net/sk_mca.c
@@ -1229,6 +1229,7 @@ int __init skmca_probe(struct SKMCA_NETDEV *dev)
* ------------------------------------------------------------------------ */
#ifdef MODULE
+MODULE_LICENSE("GPL");
#define DEVMAX 5
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index 6f5a859a80a6..50baaf26db69 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -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");
diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c
index bb0334c2a188..c40f7dc8b041 100644
--- a/drivers/net/smc9194.c
+++ b/drivers/net/smc9194.c
@@ -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");
diff --git a/drivers/net/stnic.c b/drivers/net/stnic.c
index d55ed1678899..f505bc26fd2c 100644
--- a/drivers/net/stnic.c
+++ b/drivers/net/stnic.c
@@ -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");
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 6721aa18269a..a14bcaff9cc9 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -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 { \
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 170e9abeba16..8dd4ff072f58 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -1041,3 +1041,4 @@ static void __exit qec_cleanup(void)
module_init(qec_probe);
module_exit(qec_cleanup);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
index 053fdc3bdd06..797e1d83281c 100644
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -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",
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 810ceaad146a..92ecf91b31f2 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -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>
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
index cac9085d4b05..9e0d1a6cd8d3 100644
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/airport.c
@@ -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;
diff --git a/drivers/sbus/audio/amd7930.c b/drivers/sbus/audio/amd7930.c
index 27def25fa0ca..e2eece1727a1 100644
--- a/drivers/sbus/audio/amd7930.c
+++ b/drivers/sbus/audio/amd7930.c
@@ -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)
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
index a4730d2a5e88..4ad1060fdd8b 100644
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -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)
@@ -33,6 +33,14 @@
* 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;
diff --git a/drivers/sbus/char/sab82532.c b/drivers/sbus/char/sab82532.c
index 893b2d2871fa..db20baea3c9e 100644
--- a/drivers/sbus/char/sab82532.c
+++ b/drivers/sbus/char/sab82532.c
@@ -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;
}
diff --git a/drivers/sbus/char/su.c b/drivers/sbus/char/su.c
index 912a17ce1fc2..aa08f537cf43 100644
--- a/drivers/sbus/char/su.c
+++ b/drivers/sbus/char/su.c
@@ -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, ' ');
diff --git a/drivers/sbus/char/zs.c b/drivers/sbus/char/zs.c
index c4d4bc50dceb..aefea3d09bf1 100644
--- a/drivers/sbus/char/zs.c
+++ b/drivers/sbus/char/zs.c
@@ -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) {
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 59f04bcfea8d..59eb00ae4375 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -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;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 4a78e9a8f520..b3bf7e3c42f7 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -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--;
diff --git a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c
index 1c1e9cbe5a51..1c9a1be83d95 100644
--- a/drivers/scsi/sym53c8xx.c
+++ b/drivers/scsi/sym53c8xx.c
@@ -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");
diff --git a/drivers/sound/btaudio.c b/drivers/sound/btaudio.c
index 9d229a77e5e2..341fc0420468 100644
--- a/drivers/sound/btaudio.c
+++ b/drivers/sound/btaudio.c
@@ -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:
diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in
index 2299f1919527..400d11555629 100644
--- a/drivers/usb/Config.in
+++ b/drivers/usb/Config.in
@@ -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
diff --git a/drivers/usb/pegasus.h b/drivers/usb/pegasus.h
index 8104c0cc56bf..9ef3801f31a4 100644
--- a/drivers/usb/pegasus.h
+++ b/drivers/usb/pegasus.h
@@ -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 */
diff --git a/drivers/usb/pwc-ctrl.c b/drivers/usb/pwc-ctrl.c
index 8c20d5f37c66..ed729fdc6666 100644
--- a/drivers/usb/pwc-ctrl.c
+++ b/drivers/usb/pwc-ctrl.c
@@ -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
-
-
diff --git a/drivers/usb/pwc-if.c b/drivers/usb/pwc-if.c
index f33d427417cd..5325cafa1a11 100644
--- a/drivers/usb/pwc-if.c
+++ b/drivers/usb/pwc-if.c
@@ -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);
diff --git a/drivers/usb/pwc-ioctl.h b/drivers/usb/pwc-ioctl.h
index 8a84b437a757..19b267a4cdd1 100644
--- a/drivers/usb/pwc-ioctl.h
+++ b/drivers/usb/pwc-ioctl.h
@@ -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
diff --git a/drivers/usb/pwc.h b/drivers/usb/pwc.h
index a8404a4ac240..054d369db4e5 100644
--- a/drivers/usb/pwc.h
+++ b/drivers/usb/pwc.h
@@ -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);
diff --git a/drivers/usb/serial/Config.in b/drivers/usb/serial/Config.in
index 8cc4bb2d64e7..62176c43682a 100644
--- a/drivers/usb/serial/Config.in
+++ b/drivers/usb/serial/Config.in
@@ -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
diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c
index d928e72bd068..511df4453efe 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/uhci.c
@@ -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;
}
}
diff --git a/drivers/usb/uhci.h b/drivers/usb/uhci.h
index 0955c37f3fdc..d9e728b29963 100644
--- a/drivers/usb/uhci.h
+++ b/drivers/usb/uhci.h
@@ -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 */
diff --git a/drivers/usb/ultracam.c b/drivers/usb/ultracam.c
index 815ae2060c97..94b261d38551 100644
--- a/drivers/usb/ultracam.c
+++ b/drivers/usb/ultracam.c
@@ -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;
diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
index 542086dde767..73524b31c253 100644
--- a/drivers/usb/usb-uhci.c
+++ b/drivers/usb/usb-uhci.c
@@ -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 */
diff --git a/drivers/video/cgsixfb.c b/drivers/video/cgsixfb.c
index 02fffe207d64..2e4024b7d81d 100644
--- a/drivers/video/cgsixfb.c
+++ b/drivers/video/cgsixfb.c
@@ -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)
diff --git a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c
index ebee285381bc..b5071d2d3360 100644
--- a/drivers/video/creatorfb.c
+++ b/drivers/video/creatorfb.c
@@ -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)
diff --git a/drivers/video/leofb.c b/drivers/video/leofb.c
index aabe26b92ab4..1bd5cfa0d0f2 100644
--- a/drivers/video/leofb.c
+++ b/drivers/video/leofb.c
@@ -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)
diff --git a/fs/buffer.c b/fs/buffer.c
index 4f1deb1d7deb..42ba99f03e3c 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -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);
}
/**
diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
index 85134f0b369b..3bcdaae4e024 100644
--- a/fs/hfs/catalog.c
+++ b/fs/hfs/catalog.c
@@ -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;
diff --git a/fs/namei.c b/fs/namei.c
index 42bbfef9b116..c00e8c22c5dc 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -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);
diff --git a/fs/namespace.c b/fs/namespace.c
index d1101b4438ef..c15de9f71aea 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -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);
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 1086f684ab42..1badebc15372 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -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);
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 46663c428aee..6cc44031e4e0 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -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. */
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 8d25e5095f13..0ee659ed43d8 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -86,7 +86,6 @@ decode_pathname(u32 *p, char **namp, int *lenp)
if (*name == '\0')
return NULL;
}
- *name = '\0';
}
return p;
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index ac4539946a29..97dabb0ba673 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -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);
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 481f324e36dd..cfcaa64f00fd 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -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
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index ebd216dd490d..36de103c240a 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -229,6 +229,7 @@
#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> */
diff --git a/include/asm-sparc/highmem.h b/include/asm-sparc/highmem.h
index 9945bcb7e820..f50ecef0abda 100644
--- a/include/asm-sparc/highmem.h
+++ b/include/asm-sparc/highmem.h
@@ -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
diff --git a/include/asm-sparc64/cache.h b/include/asm-sparc64/cache.h
index 216b665f2d61..7fab7580e31a 100644
--- a/include/asm-sparc64/cache.h
+++ b/include/asm-sparc64/cache.h
@@ -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)))
diff --git a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
index 1be21d47143d..62bfae557ad0 100644
--- a/include/asm-sparc64/hardirq.h
+++ b/include/asm-sparc64/hardirq.h
@@ -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;
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 8f4f261eebca..bac34263ade0 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -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
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index f39bcabdf7c0..383d72b35ed8 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1604,6 +1604,7 @@
#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
diff --git a/include/linux/swap.h b/include/linux/swap.h
index fd148822857f..e8268cb67b74 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -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 *);
diff --git a/include/net/route.h b/include/net/route.h
index 887237f6439c..f35af5807444 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -37,9 +37,12 @@
#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
{
diff --git a/ipc/shm.c b/ipc/shm.c
index 1c8c5c5cdd25..fb2ba9d0ba8b 100644
--- 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);
}
}
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 80882368e8ea..f3e76ac75df5 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -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;
diff --git a/kernel/sched.c b/kernel/sched.c
index e35da10e63e2..250f11d0147f 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1297,6 +1297,7 @@ void daemonize(void)
current->session = 1;
current->pgrp = 1;
+ current->tty = NULL;
/* Become as one with the init task */
diff --git a/mm/filemap.c b/mm/filemap.c
index 87a566030ee5..35fb1b73b968 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -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);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ec974923b3cf..f92e13e8d821 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -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);
diff --git a/mm/shmem.c b/mm/shmem.c
index 6c6a505ed265..37576b2d4d12 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -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)
diff --git a/mm/swap.c b/mm/swap.c
index 1dd936ec97a1..e7e544b3b938 100644
--- 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
+ */
}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index efd19294ad75..41d651f6720f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -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').
@@ -43,11 +45,10 @@
*/
/* 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);
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 80f6807afd20..f91d8fa6d200 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -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
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 69412c30cd2c..629aee1a1172 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -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);
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index a5c004adf7df..b149b54ee457 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -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.
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 29b6f50102fb..87ad2a5a65c6 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -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
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d0b0ed7f7a93..b68ceaa0a3f2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -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++;
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 3e6ecf67fb78..8d2c80ca3cde 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -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;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 69455b35eabd..311e40d1171a 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -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;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 095955c0c634..b123ff97a4f2 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -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) {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 2c297fd633f9..bd8f698466d2 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -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
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 899f658575a2..738a3e5d220e 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -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;
diff --git a/net/socket.c b/net/socket.c
index e0416b466c33..e9d6000cc83d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -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;